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,
23 #include <exec/types.h>
24 #include <exec/errors.h>
25 #include <exec/initializers.h>
26 #include <devices/newstyle.h>
28 #include <proto/exec.h>
29 #include <proto/utility.h>
33 #include "request_protos.h"
34 #include "unit_protos.h"
37 #define KNOWN_EVENTS \
38 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
39 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
42 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
);
43 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
);
44 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
);
45 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
);
46 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
47 struct DevBase
*base
);
48 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
49 struct DevBase
*base
);
50 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
51 struct DevBase
*base
);
52 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
53 struct DevBase
*base
);
54 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
55 struct DevBase
*base
);
56 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
57 struct DevBase
*base
);
58 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
59 struct DevBase
*base
);
60 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
61 struct DevBase
*base
);
62 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
63 struct DevBase
*base
);
64 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
);
65 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
66 struct DevBase
*base
);
67 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
);
68 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
);
69 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
70 struct DevBase
*base
);
71 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
72 struct DevBase
*base
);
73 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
74 struct DevBase
*base
);
77 static const UWORD supported_commands
[] =
85 S2_ADDMULTICASTADDRESS
,
86 S2_DELMULTICASTADDRESS
,
99 S2_ADDMULTICASTADDRESSES
,
100 S2_DELMULTICASTADDRESSES
,
105 static const struct Sana2DeviceQuery sana2_info
=
119 const TEXT badmulticast_name
[] = "Bad multicasts";
120 const TEXT retries_name
[] = "Retries";
121 const TEXT fifo_underruns_name
[] = "Underruns";
124 static const TEXT
*const special_stat_names
[] =
133 /****i* etherlink3.device/ServiceRequest ***********************************
136 * ServiceRequest -- Attempt to service a device request.
139 * ServiceRequest(request)
141 * VOID ServiceRequest(struct IORequest *);
144 * Attempts to carry out a request. The relevant unit's semaphore must
145 * be obtained before calling this function. This function releases the
146 * semaphore before returning.
148 ****************************************************************************
152 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
156 switch(request
->ios2_Req
.io_Command
)
159 complete
= CmdRead(request
, base
);
162 complete
= CmdWrite(request
, base
);
165 complete
= CmdFlush((APTR
)request
, base
);
168 complete
= CmdS2DeviceQuery((APTR
)request
, base
);
170 case S2_GETSTATIONADDRESS
:
171 complete
= CmdGetStationAddress((APTR
)request
, base
);
173 case S2_CONFIGINTERFACE
:
174 complete
= CmdConfigInterface((APTR
)request
, base
);
176 case S2_ADDMULTICASTADDRESS
:
177 complete
= CmdAddMulticastAddresses((APTR
)request
, base
);
179 case S2_DELMULTICASTADDRESS
:
180 complete
= CmdDelMulticastAddresses((APTR
)request
, base
);
183 complete
= CmdWrite((APTR
)request
, base
);
186 complete
= CmdBroadcast((APTR
)request
, base
);
189 complete
= CmdTrackType((APTR
)request
, base
);
192 complete
= CmdUntrackType((APTR
)request
, base
);
194 case S2_GETTYPESTATS
:
195 complete
= CmdGetTypeStats((APTR
)request
, base
);
197 case S2_GETSPECIALSTATS
:
198 complete
= CmdGetSpecialStats((APTR
)request
, base
);
200 case S2_GETGLOBALSTATS
:
201 complete
= CmdGetGlobalStats((APTR
)request
, base
);
204 complete
= CmdOnEvent((APTR
)request
, base
);
207 complete
= CmdReadOrphan((APTR
)request
, base
);
210 complete
= CmdOnline((APTR
)request
, base
);
213 complete
= CmdOffline((APTR
)request
, base
);
215 case NSCMD_DEVICEQUERY
:
216 complete
= CmdDeviceQuery((APTR
)request
, base
);
218 case S2_ADDMULTICASTADDRESSES
:
219 complete
= CmdAddMulticastAddresses((APTR
)request
, base
);
221 case S2_DELMULTICASTADDRESSES
:
222 complete
= CmdDelMulticastAddresses((APTR
)request
, base
);
225 complete
= CmdInvalid((APTR
)request
, base
);
228 if(complete
&& (request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0)
229 ReplyMsg((APTR
)request
);
231 ReleaseSemaphore(&((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->
238 /****i* etherlink3.device/CMD_INVALID **************************************
241 * CMD_INVALID -- Reject invalid commands.
249 * io_Error - IOERR_NOCMD.
259 ****************************************************************************
263 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
)
265 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
266 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
273 /****** etherlink3.device/CMD_READ *****************************************
276 * CMD_READ -- Read data.
302 ****************************************************************************
306 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
)
308 struct DevUnit
*unit
;
309 struct Opener
*opener
;
310 BOOL complete
= FALSE
;
312 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
314 if((unit
->flags
& UNITF_ONLINE
) != 0)
316 opener
= request
->ios2_BufferManagement
;
317 PutRequest(&opener
->read_port
, (APTR
)request
, base
);
321 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
322 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
333 /****** etherlink3.device/CMD_WRITE ****************************************
336 * CMD_WRITE -- Write data.
359 ****************************************************************************
363 /****** etherlink3.device/S2_MULTICAST *************************************
372 * ios2_DstAddr - multicast address.
389 ****************************************************************************
393 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
395 struct DevUnit
*unit
;
398 BOOL complete
= FALSE
;
400 /* Check request is valid */
402 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
403 if((unit
->flags
& UNITF_ONLINE
) == 0)
405 error
= S2ERR_OUTOFSERVICE
;
406 wire_error
= S2WERR_UNIT_OFFLINE
;
408 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
409 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
411 error
= S2ERR_BAD_ADDRESS
;
412 wire_error
= S2WERR_BAD_MULTICAST
;
415 /* Queue request for sending */
418 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
421 request
->ios2_Req
.io_Error
= error
;
422 request
->ios2_WireError
= wire_error
;
433 /****** etherlink3.device/CMD_FLUSH ****************************************
454 ****************************************************************************
458 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
460 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
467 /****** etherlink3.device/S2_DEVICEQUERY ***********************************
470 * S2_DEVICEQUERY -- Query device capabilities.
475 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
489 ****************************************************************************
493 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
494 struct DevBase
*base
)
496 struct DevUnit
*unit
;
497 struct Sana2DeviceQuery
*info
;
498 ULONG size_available
, size
;
500 /* Copy device info */
502 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
503 info
= request
->ios2_StatData
;
504 size
= size_available
= info
->SizeAvailable
;
505 if(size
> sizeof(struct Sana2DeviceQuery
))
506 size
= sizeof(struct Sana2DeviceQuery
);
508 CopyMem(&sana2_info
, info
, size
);
509 info
->BPS
= unit
->speed
;
510 info
->SizeAvailable
= size_available
;
511 info
->SizeSupplied
= size
;
520 /****** etherlink3.device/S2_GETSTATIONADDDRESS ****************************
523 * S2_GETSTATIONADDDRESS --
533 * ios2_SrcAddr - current address.
534 * ios2_DstAddr - default address (zero if none?).
544 ****************************************************************************
548 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
549 struct DevBase
*base
)
551 struct DevUnit
*unit
;
555 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
556 CopyMem(unit
->address
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
557 CopyMem(unit
->default_address
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
566 /****** etherlink3.device/S2_CONFIGINTERFACE *******************************
569 * S2_CONFIGINTERFACE --
574 * ios2_SrcAddr - address to use.
579 * ios2_SrcAddr - address used.
589 ****************************************************************************
593 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
594 struct DevBase
*base
)
596 struct DevUnit
*unit
;
598 /* Configure adapter */
600 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
601 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
603 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
604 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
605 ConfigureAdapter(unit
, base
);
606 unit
->flags
|= UNITF_CONFIGURED
;
610 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
611 request
->ios2_WireError
= S2WERR_IS_CONFIGURED
;
621 /****** etherlink3.device/S2_BROADCAST *************************************
646 ****************************************************************************
650 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
651 struct DevBase
*base
)
653 /* Fill in the broadcast address as destination */
655 *((ULONG
*)request
->ios2_DstAddr
) = 0xffffffff;
656 *((UWORD
*)(request
->ios2_DstAddr
+ 4)) = 0xffff;
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
);