3 Copyright (C) 2001-2005 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 #include <exec/types.h>
25 #include <exec/errors.h>
26 #include <exec/initializers.h>
27 #include <devices/newstyle.h>
29 #include <proto/exec.h>
30 #include <proto/utility.h>
34 #include "request_protos.h"
35 #include "unit_protos.h"
38 #define KNOWN_EVENTS \
39 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
40 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
43 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
);
44 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
);
45 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
);
46 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
);
47 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
48 struct DevBase
*base
);
49 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
50 struct DevBase
*base
);
51 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
52 struct DevBase
*base
);
53 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
54 struct DevBase
*base
);
55 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
56 struct DevBase
*base
);
57 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
58 struct DevBase
*base
);
59 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
60 struct DevBase
*base
);
61 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
62 struct DevBase
*base
);
63 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
64 struct DevBase
*base
);
65 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
);
66 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
67 struct DevBase
*base
);
68 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
);
69 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
);
70 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
71 struct DevBase
*base
);
72 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
73 struct DevBase
*base
);
74 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
75 struct DevBase
*base
);
78 static const UWORD supported_commands
[] =
86 S2_ADDMULTICASTADDRESS
,
87 S2_DELMULTICASTADDRESS
,
100 S2_ADDMULTICASTADDRESSES
,
101 S2_DELMULTICASTADDRESSES
,
106 static const struct Sana2DeviceQuery sana2_info
=
120 const TEXT badmulticast_name
[] = "Bad multicasts";
121 const TEXT retries_name
[] = "Retries";
122 const TEXT fifo_underruns_name
[] = "Underruns";
125 static const TEXT
*const special_stat_names
[] =
134 /****i* etherlink3.device/ServiceRequest ***********************************
137 * ServiceRequest -- Attempt to service a device request.
140 * ServiceRequest(request)
142 * VOID ServiceRequest(struct IORequest *);
145 * Attempts to carry out a request. The relevant unit's semaphore must
146 * be obtained before calling this function. This function releases the
147 * semaphore before returning.
149 ****************************************************************************
153 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
157 switch(request
->ios2_Req
.io_Command
)
160 complete
= CmdRead(request
, base
);
163 complete
= CmdWrite(request
, base
);
166 complete
= CmdFlush((APTR
)request
, base
);
169 complete
= CmdS2DeviceQuery((APTR
)request
, base
);
171 case S2_GETSTATIONADDRESS
:
172 complete
= CmdGetStationAddress((APTR
)request
, base
);
174 case S2_CONFIGINTERFACE
:
175 complete
= CmdConfigInterface((APTR
)request
, base
);
177 case S2_ADDMULTICASTADDRESS
:
178 complete
= CmdAddMulticastAddresses((APTR
)request
, base
);
180 case S2_DELMULTICASTADDRESS
:
181 complete
= CmdDelMulticastAddresses((APTR
)request
, base
);
184 complete
= CmdWrite((APTR
)request
, base
);
187 complete
= CmdBroadcast((APTR
)request
, base
);
190 complete
= CmdTrackType((APTR
)request
, base
);
193 complete
= CmdUntrackType((APTR
)request
, base
);
195 case S2_GETTYPESTATS
:
196 complete
= CmdGetTypeStats((APTR
)request
, base
);
198 case S2_GETSPECIALSTATS
:
199 complete
= CmdGetSpecialStats((APTR
)request
, base
);
201 case S2_GETGLOBALSTATS
:
202 complete
= CmdGetGlobalStats((APTR
)request
, base
);
205 complete
= CmdOnEvent((APTR
)request
, base
);
208 complete
= CmdReadOrphan((APTR
)request
, base
);
211 complete
= CmdOnline((APTR
)request
, base
);
214 complete
= CmdOffline((APTR
)request
, base
);
216 case NSCMD_DEVICEQUERY
:
217 complete
= CmdDeviceQuery((APTR
)request
, base
);
219 case S2_ADDMULTICASTADDRESSES
:
220 complete
= CmdAddMulticastAddresses((APTR
)request
, base
);
222 case S2_DELMULTICASTADDRESSES
:
223 complete
= CmdDelMulticastAddresses((APTR
)request
, base
);
226 complete
= CmdInvalid((APTR
)request
, base
);
229 if(complete
&& (request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0)
230 ReplyMsg((APTR
)request
);
232 ReleaseSemaphore(&((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->
239 /****i* etherlink3.device/CMD_INVALID **************************************
242 * CMD_INVALID -- Reject invalid commands.
250 * io_Error - IOERR_NOCMD.
260 ****************************************************************************
264 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
)
266 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
267 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
274 /****** etherlink3.device/CMD_READ *****************************************
277 * CMD_READ -- Read data.
303 ****************************************************************************
307 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
)
309 struct DevUnit
*unit
;
310 struct Opener
*opener
;
311 BOOL complete
= FALSE
;
313 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
315 if((unit
->flags
& UNITF_ONLINE
) != 0)
317 opener
= request
->ios2_BufferManagement
;
318 PutRequest(&opener
->read_port
, (APTR
)request
, base
);
322 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
323 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
334 /****** etherlink3.device/CMD_WRITE ****************************************
337 * CMD_WRITE -- Write data.
360 ****************************************************************************
364 /****** etherlink3.device/S2_MULTICAST *************************************
373 * ios2_DstAddr - multicast address.
390 ****************************************************************************
394 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
396 struct DevUnit
*unit
;
399 BOOL complete
= FALSE
;
401 /* Check request is valid */
403 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
404 if((unit
->flags
& UNITF_ONLINE
) == 0)
406 error
= S2ERR_OUTOFSERVICE
;
407 wire_error
= S2WERR_UNIT_OFFLINE
;
409 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
410 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
412 error
= S2ERR_BAD_ADDRESS
;
413 wire_error
= S2WERR_BAD_MULTICAST
;
416 /* Queue request for sending */
419 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
422 request
->ios2_Req
.io_Error
= error
;
423 request
->ios2_WireError
= wire_error
;
434 /****** etherlink3.device/CMD_FLUSH ****************************************
455 ****************************************************************************
459 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
461 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
468 /****** etherlink3.device/S2_DEVICEQUERY ***********************************
471 * S2_DEVICEQUERY -- Query device capabilities.
476 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
490 ****************************************************************************
494 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
495 struct DevBase
*base
)
497 struct DevUnit
*unit
;
498 struct Sana2DeviceQuery
*info
;
499 ULONG size_available
, size
;
501 /* Copy device info */
503 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
504 info
= request
->ios2_StatData
;
505 size
= size_available
= info
->SizeAvailable
;
506 if(size
> sizeof(struct Sana2DeviceQuery
))
507 size
= sizeof(struct Sana2DeviceQuery
);
509 CopyMem(&sana2_info
, info
, size
);
510 info
->BPS
= unit
->speed
;
511 info
->SizeAvailable
= size_available
;
512 info
->SizeSupplied
= size
;
521 /****** etherlink3.device/S2_GETSTATIONADDDRESS ****************************
524 * S2_GETSTATIONADDDRESS --
534 * ios2_SrcAddr - current address.
535 * ios2_DstAddr - default address (zero if none?).
545 ****************************************************************************
549 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
550 struct DevBase
*base
)
552 struct DevUnit
*unit
;
556 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
557 CopyMem(unit
->address
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
558 CopyMem(unit
->default_address
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
567 /****** etherlink3.device/S2_CONFIGINTERFACE *******************************
570 * S2_CONFIGINTERFACE --
575 * ios2_SrcAddr - address to use.
580 * ios2_SrcAddr - address used.
590 ****************************************************************************
594 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
595 struct DevBase
*base
)
597 struct DevUnit
*unit
;
599 /* Configure adapter */
601 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
602 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
604 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
605 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
606 ConfigureAdapter(unit
, base
);
607 unit
->flags
|= UNITF_CONFIGURED
;
611 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
612 request
->ios2_WireError
= S2WERR_IS_CONFIGURED
;
622 /****** etherlink3.device/S2_BROADCAST *************************************
647 ****************************************************************************
651 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
652 struct DevBase
*base
)
654 /* Fill in the broadcast address as destination */
656 memset(request
->ios2_DstAddr
, 0xff, sizeof(request
->ios2_DstAddr
));
658 /* Queue the write as normal */
660 return CmdWrite(request
, base
);
665 /****** etherlink3.device/S2_TRACKTYPE *************************************
673 * ios2_PacketType - packet type to start tracking.
687 ****************************************************************************
691 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
692 struct DevBase
*base
)
694 struct DevUnit
*unit
;
695 struct Opener
*opener
;
696 ULONG packet_type
, wire_error
;
697 struct TypeTracker
*tracker
;
698 struct TypeStats
*initial_stats
;
701 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
702 packet_type
= request
->ios2_PacketType
;
704 /* Get global tracker */
706 tracker
= (struct TypeTracker
*)
707 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
710 tracker
->user_count
++;
714 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
717 tracker
->packet_type
= packet_type
;
718 tracker
->user_count
= 1;
721 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
726 /* Store initial figures for this opener */
728 opener
= request
->ios2_BufferManagement
;
729 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
732 if(initial_stats
!= NULL
)
734 error
= S2ERR_BAD_STATE
;
735 wire_error
= S2WERR_ALREADY_TRACKED
;
740 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
741 if(initial_stats
== NULL
)
743 error
= S2ERR_NO_RESOURCES
;
744 wire_error
= S2WERR_GENERIC_ERROR
;
750 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
751 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
756 request
->ios2_Req
.io_Error
= error
;
757 request
->ios2_WireError
= wire_error
;
763 /****** etherlink3.device/S2_UNTRACKTYPE ***********************************
771 * ios2_PacketType - packet type to stop tracking.
785 ****************************************************************************
789 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
790 struct DevBase
*base
)
792 struct DevUnit
*unit
;
793 struct Opener
*opener
;
795 struct TypeTracker
*tracker
;
796 struct TypeStats
*initial_stats
;
798 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
799 packet_type
= request
->ios2_PacketType
;
801 /* Get global tracker and initial figures */
803 tracker
= (struct TypeTracker
*)
804 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
805 opener
= request
->ios2_BufferManagement
;
806 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
809 /* Decrement tracker usage and free unused structures */
811 if(initial_stats
!= NULL
)
813 if((--tracker
->user_count
) == 0)
816 Remove((APTR
)tracker
);
818 FreeMem(tracker
, sizeof(struct TypeTracker
));
821 Remove((APTR
)initial_stats
);
822 FreeMem(initial_stats
, sizeof(struct TypeStats
));
826 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
827 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
837 /****** etherlink3.device/S2_GETTYPESTATS **********************************
845 * ios2_PacketType - packet type to get statistics on.
846 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
860 ****************************************************************************
864 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
865 struct DevBase
*base
)
867 struct DevUnit
*unit
;
868 struct Opener
*opener
;
870 struct TypeStats
*initial_stats
, *tracker
;
871 struct Sana2PacketTypeStats
*stats
;
873 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
874 packet_type
= request
->ios2_PacketType
;
876 /* Get global tracker and initial figures */
878 tracker
= FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
879 opener
= request
->ios2_BufferManagement
;
880 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
883 /* Copy and adjust figures */
885 if(initial_stats
!= NULL
)
887 stats
= request
->ios2_StatData
;
888 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
889 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
890 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
891 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
892 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
893 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
897 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
898 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
908 /****** etherlink3.device/S2_GETSPECIALSTATS *******************************
911 * S2_GETSPECIALSTATS --
916 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
930 ****************************************************************************
934 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
935 struct DevBase
*base
)
937 struct DevUnit
*unit
;
939 struct Sana2SpecialStatHeader
*header
;
940 struct Sana2SpecialStatRecord
*record
;
944 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
945 header
= request
->ios2_StatData
;
946 record
= (APTR
)(header
+ 1);
948 stat_count
= header
->RecordCountMax
;
949 if(stat_count
> STAT_COUNT
)
950 stat_count
= STAT_COUNT
;
952 for(i
= 0; i
< stat_count
; i
++)
954 record
->Type
= (S2WireType_Ethernet
<< 16) + i
;
955 record
->Count
= unit
->special_stats
[i
];
956 record
->String
= special_stat_names
[i
];
960 header
->RecordCountSupplied
= stat_count
;
969 /****** etherlink3.device/S2_GETGLOBALSTATS ********************************
972 * S2_GETGLOBALSTATS --
977 * ios2_StatData - Pointer to Sana2DeviceStats structure.
991 ****************************************************************************
995 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
996 struct DevBase
*base
)
998 struct DevUnit
*unit
;
1000 /* Update and copy stats */
1002 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1004 UpdateStats(unit
, base
);
1006 CopyMem(&unit
->stats
, request
->ios2_StatData
,
1007 sizeof(struct Sana2DeviceStats
));
1016 /****** etherlink3.device/S2_ONEVENT ***************************************
1038 ****************************************************************************
1042 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
)
1044 struct DevUnit
*unit
;
1045 ULONG events
, wanted_events
;
1046 BOOL complete
= FALSE
;
1048 /* Check if we understand the event types */
1050 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1051 wanted_events
= request
->ios2_WireError
;
1052 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
1054 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
1055 events
= S2WERR_BAD_EVENT
;
1059 if((unit
->flags
& UNITF_ONLINE
) != 0)
1060 events
= S2EVENT_ONLINE
;
1062 events
= S2EVENT_OFFLINE
;
1064 events
&= wanted_events
;
1067 /* Reply request if a wanted event has already occurred */
1071 request
->ios2_WireError
= events
;
1075 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1084 /****** etherlink3.device/S2_READORPHAN ************************************
1099 * ios2_PacketType - A copy of the packet's type field.
1114 ****************************************************************************
1118 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1119 struct DevBase
*base
)
1121 struct DevUnit
*unit
;
1124 BOOL complete
= FALSE
;
1126 /* Check request is valid */
1128 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1129 if((unit
->flags
& UNITF_ONLINE
) == 0)
1131 error
= S2ERR_OUTOFSERVICE
;
1132 wire_error
= S2WERR_UNIT_OFFLINE
;
1138 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1141 request
->ios2_Req
.io_Error
= error
;
1142 request
->ios2_WireError
= wire_error
;
1153 /****** etherlink3.device/S2_ONLINE ****************************************
1175 ****************************************************************************
1179 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1181 struct DevUnit
*unit
;
1186 /* Check request is valid */
1188 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1189 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
1191 error
= S2ERR_BAD_STATE
;
1192 wire_error
= S2WERR_NOT_CONFIGURED
;
1194 if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
1196 error
= S2ERR_OUTOFSERVICE
;
1197 wire_error
= S2WERR_RCVREL_HDW_ERR
;
1200 /* Clear global and special stats and put adapter back online */
1202 if(error
== 0 && (unit
->flags
& UNITF_ONLINE
) == 0)
1204 unit
->stats
.PacketsReceived
= 0;
1205 unit
->stats
.PacketsSent
= 0;
1206 unit
->stats
.BadData
= 0;
1207 unit
->stats
.Overruns
= 0;
1208 unit
->stats
.UnknownTypesReceived
= 0;
1209 unit
->stats
.Reconfigurations
= 0;
1211 for(i
= 0; i
< STAT_COUNT
; i
++)
1212 unit
->special_stats
[i
] = 0;
1214 GoOnline(unit
, base
);
1219 request
->ios2_Req
.io_Error
= error
;
1220 request
->ios2_WireError
= wire_error
;
1226 /****** etherlink3.device/S2_OFFLINE ***************************************
1248 ****************************************************************************
1252 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
)
1254 struct DevUnit
*unit
;
1256 /* Put adapter offline */
1258 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1259 if((unit
->flags
& UNITF_ONLINE
) != 0)
1260 GoOffline(unit
, base
);
1269 /****** etherlink3.device/NSCMD_DEVICEQUERY ********************************
1272 * NSCMD_DEVICEQUERY -- Query device capabilities.
1278 * io_Data - pointer to NSDeviceQueryResult structure.
1282 * io_Actual - size of structure device can handle.
1292 ****************************************************************************
1294 * Note that we have to pretend the request structure is an IOStdReq.
1298 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
1299 struct DevBase
*base
)
1301 struct NSDeviceQueryResult
*info
;
1303 /* Set structure size twice */
1305 info
= request
->io_Data
;
1306 request
->io_Actual
= info
->SizeAvailable
=
1307 (ULONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
1309 /* Report device details */
1311 info
->DeviceType
= NSDEVTYPE_SANA2
;
1312 info
->DeviceSubType
= 0;
1314 info
->SupportedCommands
= (APTR
)supported_commands
;
1323 /****** etherlink3.device/S2_ADDMULTICASTADDRESS ***************************
1326 * S2_ADDMULTICASTADDRESS --
1331 * ios2_SrcAddr - multicast address.
1345 ****************************************************************************
1349 /****** etherlink3.device/S2_ADDMULTICASTADDRESSES *************************
1352 * S2_ADDMULTICASTADDRESSES --
1357 * ios2_SrcAddr - lower bound.
1358 * ios2_DstAddr - upper bound.
1372 ****************************************************************************
1376 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
1377 struct DevBase
*base
)
1379 struct DevUnit
*unit
;
1380 UBYTE
*lower_bound
, *upper_bound
;
1382 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1384 lower_bound
= request
->ios2_SrcAddr
;
1385 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
1386 upper_bound
= lower_bound
;
1388 upper_bound
= request
->ios2_DstAddr
;
1390 if(!AddMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1392 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1393 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
1403 /****** etherlink3.device/S2_DELMULTICASTADDRESS ***************************
1406 * S2_DELMULTICASTADDRESS --
1411 * ios2_SrcAddr - multicast address.
1425 ****************************************************************************
1429 /****** etherlink3.device/S2_DELMULTICASTADDRESSES *************************
1432 * S2_DELMULTICASTADDRESSES --
1437 * ios2_SrcAddr - lower bound.
1438 * ios2_DstAddr - upper bound.
1452 ****************************************************************************
1456 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
1457 struct DevBase
*base
)
1459 struct DevUnit
*unit
;
1460 UBYTE
*lower_bound
, *upper_bound
;
1462 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1464 lower_bound
= request
->ios2_SrcAddr
;
1465 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
1466 upper_bound
= lower_bound
;
1468 upper_bound
= request
->ios2_DstAddr
;
1470 if(!RemMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1472 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
1473 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;
1483 /****i* etherlink3.device/PutRequest ***************************************
1489 * PutRequest(port, request)
1491 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1510 ****************************************************************************
1514 VOID
PutRequest(struct MsgPort
*port
, struct IORequest
*request
,
1515 struct DevBase
*base
)
1517 request
->io_Flags
&= ~IOF_QUICK
;
1518 PutMsg(port
, (APTR
)request
);