6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24 #include <exec/types.h>
25 #include <exec/resident.h>
27 #include <exec/ports.h>
28 #include <exec/errors.h>
30 #include <devices/sana2.h>
31 #include <devices/sana2specialstats.h>
32 #include <devices/newstyle.h>
34 #include <utility/utility.h>
35 #include <utility/tagitem.h>
36 #include <utility/hooks.h>
38 #include <proto/exec.h>
39 #include <proto/dos.h>
40 #include <proto/battclock.h>
46 #include LC_LIBDEFS_FILE
48 #define KNOWN_EVENTS \
49 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
50 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
52 static BOOL
CmdInvalid(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
53 static BOOL
CmdRead(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
54 static BOOL
CmdWrite(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
55 static BOOL
CmdFlush(LIBBASETYPEPTR LIBBASE
, struct IORequest
*request
);
56 static BOOL
CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
57 static BOOL
CmdGetStationAddress(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
58 static BOOL
CmdConfigInterface(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
59 static BOOL
CmdBroadcast(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
60 static BOOL
CmdTrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
61 static BOOL
CmdUntrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
62 static BOOL
CmdGetTypeStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
63 static BOOL
CmdGetSpecialStats(LIBBASETYPEPTR LIBBASE
,
64 struct IOSana2Req
*request
);
65 static BOOL
CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
66 static BOOL
CmdDeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOStdReq
*request
);
67 static BOOL
CmdOnEvent(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
68 static BOOL
CmdReadOrphan(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
69 static BOOL
CmdOnline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
70 static BOOL
CmdOffline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
71 static BOOL
CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
72 static BOOL
CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
74 static const UWORD supported_commands
[] =
82 S2_ADDMULTICASTADDRESS
,
83 S2_DELMULTICASTADDRESS
,
96 S2_ADDMULTICASTADDRESSES
,
97 S2_DELMULTICASTADDRESSES
,
101 const TEXT badmulticast_name
[] = "Bad multicasts";
102 const TEXT retries_name
[] = "Retries";
103 const TEXT fifo_underruns_name
[] = "Underruns";
105 static const TEXT
*const special_stat_names
[] =
112 void handle_request(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
116 switch(request
->ios2_Req
.io_Command
)
119 complete
= CmdRead(LIBBASE
, request
);
124 complete
= CmdWrite(LIBBASE
, request
);
128 complete
= CmdFlush(LIBBASE
, (struct IORequest
*)request
);
132 complete
= CmdS2DeviceQuery(LIBBASE
, request
);
135 case S2_GETSTATIONADDRESS
:
136 complete
= CmdGetStationAddress(LIBBASE
, request
);
139 case S2_CONFIGINTERFACE
:
140 complete
= CmdConfigInterface(LIBBASE
, request
);
144 complete
= CmdBroadcast(LIBBASE
, request
);
148 complete
= CmdTrackType(LIBBASE
, request
);
152 complete
= CmdUntrackType(LIBBASE
, request
);
155 case S2_GETTYPESTATS
:
156 complete
= CmdGetTypeStats(LIBBASE
, request
);
159 case S2_GETSPECIALSTATS
:
160 complete
= CmdGetSpecialStats(LIBBASE
, request
);
163 case S2_GETGLOBALSTATS
:
164 complete
= CmdGetGlobalStats(LIBBASE
, request
);
168 complete
= CmdOnEvent(LIBBASE
, request
);
172 complete
= CmdReadOrphan(LIBBASE
, request
);
176 complete
= CmdOnline(LIBBASE
, request
);
180 complete
= CmdOffline(LIBBASE
, request
);
183 case S2_ADDMULTICASTADDRESS
:
184 case S2_ADDMULTICASTADDRESSES
:
185 complete
= CmdAddMulticastAddresses(LIBBASE
, request
);
188 case S2_DELMULTICASTADDRESS
:
189 case S2_DELMULTICASTADDRESSES
:
190 complete
= CmdDelMulticastAddresses(LIBBASE
, request
);
193 case NSCMD_DEVICEQUERY
:
194 complete
= CmdDeviceQuery(LIBBASE
, (struct IOStdReq
*)request
);
198 complete
= CmdInvalid(LIBBASE
, request
);
201 if(complete
&& (request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0)
202 ReplyMsg((APTR
)request
);
204 ReleaseSemaphore(&((struct RTL8139Unit
*)request
->ios2_Req
.io_Unit
)->rtl8139u_unit_lock
);
207 static BOOL
CmdInvalid(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
209 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
210 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
215 static BOOL
CmdRead(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
217 struct RTL8139Unit
*unit
;
218 struct Opener
*opener
;
219 BOOL complete
= FALSE
;
221 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
223 RTLD(bug("[%s] S2CmdRead()\n", unit
->rtl8139u_name
))
225 if((unit
->rtl8139u_flags
& IFF_UP
) != 0)
227 opener
= request
->ios2_BufferManagement
;
228 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
229 PutMsg(&opener
->read_port
, (struct Message
*)request
);
233 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
234 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
243 static BOOL
CmdWrite(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
245 struct RTL8139Unit
*unit
;
247 ULONG wire_error
= S2WERR_GENERIC_ERROR
;
248 BOOL complete
= FALSE
;
250 /* Check request is valid */
252 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
254 RTLD(bug("[%s] S2CmdWrite()\n", unit
->rtl8139u_name
))
256 if((unit
->rtl8139u_flags
& IFF_UP
) == 0)
258 error
= S2ERR_OUTOFSERVICE
;
259 wire_error
= S2WERR_UNIT_OFFLINE
;
261 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
262 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
264 error
= S2ERR_BAD_ADDRESS
;
265 wire_error
= S2WERR_BAD_MULTICAST
;
268 /* Queue request for sending */
271 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
272 PutMsg(unit
->rtl8139u_request_ports
[WRITE_QUEUE
], (APTR
)request
);
276 request
->ios2_Req
.io_Error
= error
;
277 request
->ios2_WireError
= wire_error
;
286 static BOOL
CmdFlush(LIBBASETYPEPTR LIBBASE
, struct IORequest
*request
)
288 FlushUnit(LIBBASE
, (APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
);
292 static BOOL
CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
294 struct RTL8139Unit
*unit
= (APTR
)request
->ios2_Req
.io_Unit
;
295 // struct fe_priv *np = unit->rtl8139u_fe_priv;
296 struct Sana2DeviceQuery
*info
;
297 ULONG size_available
, size
;
299 RTLD(bug("[%s] S2CmdDeviceQuery()\n", unit
->rtl8139u_name
))
301 /* Copy device info */
303 info
= request
->ios2_StatData
;
304 size
= size_available
= info
->SizeAvailable
;
305 if(size
> sizeof(struct Sana2DeviceQuery
))
306 size
= sizeof(struct Sana2DeviceQuery
);
308 CopyMem(&unit
->rtl8139u_Sana2Info
, info
, size
);
310 info
->BPS
= unit
->rtl8139u_rtl_LinkSpeed
;
312 info
->HardwareType
= S2WireType_Ethernet
;
313 info
->SizeAvailable
= size_available
;
314 info
->SizeSupplied
= size
;
321 static BOOL
CmdGetStationAddress(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
323 struct RTL8139Unit
*unit
;
327 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
329 RTLD(bug("[%s] S2CmdGetStationAddress()\n", unit
->rtl8139u_name
))
331 CopyMem(unit
->rtl8139u_dev_addr
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
332 CopyMem(unit
->rtl8139u_org_addr
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
339 static BOOL
CmdConfigInterface(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
341 struct RTL8139Unit
*unit
;
343 /* Configure adapter */
345 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
347 RTLD(bug("[%s] S2CmdConfigInterface()\n", unit
->rtl8139u_name
))
349 if((unit
->rtl8139u_flags
& IFF_CONFIGURED
) == 0)
351 CopyMem(request
->ios2_SrcAddr
, unit
->rtl8139u_dev_addr
, ETH_ADDRESSSIZE
);
352 unit
->set_mac_address(unit
);
353 unit
->rtl8139u_flags
|= IFF_CONFIGURED
;
357 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
358 request
->ios2_WireError
= S2WERR_IS_CONFIGURED
;
366 static BOOL
CmdBroadcast(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
368 /* Fill in the broadcast address as destination */
370 memset(request
->ios2_DstAddr
, 0xff, 6);
372 /* Queue the write as normal */
374 return CmdWrite(LIBBASE
, request
);
377 static BOOL
CmdTrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
379 struct RTL8139Unit
*unit
;
380 struct Opener
*opener
;
381 ULONG packet_type
, wire_error
=0;
382 struct TypeTracker
*tracker
;
383 struct TypeStats
*initial_stats
;
386 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
388 RTLD(bug("[%s] S2CmdTrackType()\n", unit
->rtl8139u_name
))
390 packet_type
= request
->ios2_PacketType
;
392 /* Get global tracker */
394 tracker
= (struct TypeTracker
*)
395 FindTypeStats(LIBBASE
, unit
, &unit
->rtl8139u_type_trackers
, packet_type
);
398 tracker
->user_count
++;
402 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
|MEMF_CLEAR
);
405 tracker
->packet_type
= packet_type
;
406 tracker
->user_count
= 1;
409 AddTail((APTR
)&unit
->rtl8139u_type_trackers
, (APTR
)tracker
);
414 /* Store initial figures for this opener */
416 opener
= request
->ios2_BufferManagement
;
417 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
419 if(initial_stats
!= NULL
)
421 error
= S2ERR_BAD_STATE
;
422 wire_error
= S2WERR_ALREADY_TRACKED
;
427 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
428 if(initial_stats
== NULL
)
430 error
= S2ERR_NO_RESOURCES
;
431 wire_error
= S2WERR_GENERIC_ERROR
;
437 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
438 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
443 request
->ios2_Req
.io_Error
= error
;
444 request
->ios2_WireError
= wire_error
;
448 static BOOL
CmdUntrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
450 struct RTL8139Unit
*unit
;
451 struct Opener
*opener
;
453 struct TypeTracker
*tracker
;
454 struct TypeStats
*initial_stats
;
456 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
458 RTLD(bug("[%s] S2CmdUntrackType()\n", unit
->rtl8139u_name
))
460 packet_type
= request
->ios2_PacketType
;
462 /* Get global tracker and initial figures */
464 tracker
= (struct TypeTracker
*)
465 FindTypeStats(LIBBASE
, unit
, &unit
->rtl8139u_type_trackers
, packet_type
);
466 opener
= request
->ios2_BufferManagement
;
467 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
469 /* Decrement tracker usage and free unused structures */
471 if(initial_stats
!= NULL
)
473 if((--tracker
->user_count
) == 0)
476 Remove((APTR
)tracker
);
478 FreeMem(tracker
, sizeof(struct TypeTracker
));
481 Remove((APTR
)initial_stats
);
482 FreeMem(initial_stats
, sizeof(struct TypeStats
));
486 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
487 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
495 static BOOL
CmdGetTypeStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
497 struct RTL8139Unit
*unit
;
498 struct Opener
*opener
;
500 struct TypeStats
*initial_stats
, *tracker
;
501 struct Sana2PacketTypeStats
*stats
;
503 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
505 RTLD(bug("[%s] S2CmdGetTypeStats()\n", unit
->rtl8139u_name
))
507 packet_type
= request
->ios2_PacketType
;
509 /* Get global tracker and initial figures */
511 tracker
= FindTypeStats(LIBBASE
, unit
, &unit
->rtl8139u_type_trackers
, packet_type
);
512 opener
= request
->ios2_BufferManagement
;
513 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
515 /* Copy and adjust figures */
516 if(initial_stats
!= NULL
)
518 stats
= request
->ios2_StatData
;
519 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
520 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
521 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
522 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
523 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
524 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
528 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
529 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
537 static BOOL
CmdGetSpecialStats(LIBBASETYPEPTR LIBBASE
,
538 struct IOSana2Req
*request
)
540 struct RTL8139Unit
*unit
;
542 struct Sana2SpecialStatHeader
*header
;
543 struct Sana2SpecialStatRecord
*record
;
547 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
548 header
= request
->ios2_StatData
;
549 record
= (APTR
)(header
+ 1);
551 stat_count
= header
->RecordCountMax
;
552 if(stat_count
> STAT_COUNT
)
553 stat_count
= STAT_COUNT
;
555 for(i
= 0; i
< stat_count
; i
++)
557 record
->Type
= (S2WireType_Ethernet
<< 16) + i
;
558 record
->Count
= unit
->rtl8139u_special_stats
[i
];
559 record
->String
= special_stat_names
[i
];
563 header
->RecordCountSupplied
= stat_count
;
570 static BOOL
CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
572 struct RTL8139Unit
*unit
;
574 /* Update and copy stats */
576 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
578 RTLD(bug("[%s] S2CmdGetGlobalStats()\n", unit
->rtl8139u_name
))
580 CopyMem(&unit
->rtl8139u_stats
, request
->ios2_StatData
,
581 sizeof(struct Sana2DeviceStats
));
588 static BOOL
CmdDeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOStdReq
*request
)
590 struct NSDeviceQueryResult
*info
;
592 /* Set structure size twice */
594 info
= request
->io_Data
;
595 request
->io_Actual
= info
->SizeAvailable
=
596 offsetof(struct NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
598 /* Report device details */
600 info
->DeviceType
= NSDEVTYPE_SANA2
;
601 info
->DeviceSubType
= 0;
603 info
->SupportedCommands
= (APTR
)supported_commands
;
610 static BOOL
CmdOnEvent(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
612 struct RTL8139Unit
*unit
;
613 ULONG events
, wanted_events
;
614 BOOL complete
= FALSE
;
616 /* Check if we understand the event types */
618 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
620 RTLD(bug("[%s] S2CmdOnEvent()\n", unit
->rtl8139u_name
))
622 wanted_events
= request
->ios2_WireError
;
623 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
625 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
626 events
= S2WERR_BAD_EVENT
;
630 if((unit
->rtl8139u_flags
& IFF_UP
) != 0)
631 events
= S2EVENT_ONLINE
;
633 events
= S2EVENT_OFFLINE
;
635 events
&= wanted_events
;
638 /* Reply request if a wanted event has already occurred */
642 request
->ios2_WireError
= events
;
647 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
648 PutMsg(unit
->rtl8139u_request_ports
[EVENT_QUEUE
], (APTR
)request
);
656 static BOOL
CmdReadOrphan(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
658 struct RTL8139Unit
*unit
;
661 BOOL complete
= FALSE
;
663 /* Check request is valid */
665 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
666 RTLD(bug("[%s] S2CmdReadOrphan()\n", unit
->rtl8139u_name
))
668 if((unit
->rtl8139u_flags
& IFF_UP
) == 0)
670 error
= S2ERR_OUTOFSERVICE
;
671 wire_error
= S2WERR_UNIT_OFFLINE
;
678 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
679 PutMsg(unit
->rtl8139u_request_ports
[ADOPT_QUEUE
], (struct Message
*)request
);
683 request
->ios2_Req
.io_Error
= error
;
684 request
->ios2_WireError
= wire_error
;
693 static BOOL
CmdOnline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
695 // struct RTL8139Unit *unit = (struct RTL8139Unit *)request->ios2_Req.io_Unit;
697 ULONG wire_error
= 0;
700 #if 0 // FIXME: some of what's done here is duplicated in device init
701 RTLD(bug("[%s] S2CmdOnline()\n", unit
->rtl8139u_name
))
703 /* Check request is valid */
704 if((unit
->rtl8139u_flags
& IFF_CONFIGURED
) == 0)
706 error
= S2ERR_BAD_STATE
;
707 wire_error
= S2WERR_NOT_CONFIGURED
;
710 /* Clear global and special stats and put adapter back online */
712 if((error
== 0) && ((unit
->rtl8139u_flags
& IFF_UP
) == 0))
714 unit
->rtl8139u_stats
.PacketsReceived
= 0;
715 unit
->rtl8139u_stats
.PacketsSent
= 0;
716 unit
->rtl8139u_stats
.BadData
= 0;
717 unit
->rtl8139u_stats
.Overruns
= 0;
718 unit
->rtl8139u_stats
.UnknownTypesReceived
= 0;
719 unit
->rtl8139u_stats
.Reconfigurations
= 0;
721 for(i
= 0; i
< STAT_COUNT
; i
++)
722 unit
->rtl8139u_special_stats
[i
] = 0;
724 if (unit
->start(unit
))
726 error
= S2ERR_OUTOFSERVICE
;
727 wire_error
= S2WERR_GENERIC_ERROR
;
734 request
->ios2_Req
.io_Error
= error
;
735 request
->ios2_WireError
= wire_error
;
739 static BOOL
CmdOffline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
741 // struct RTL8139Unit *unit;
743 #if 0 // FIXME: some of what's done here is duplicated in device de-init
744 /* Put adapter offline */
746 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
748 RTLD(bug("[%s] S2CmdOffline()\n", unit
->rtl8139u_name
))
750 if((unit
->rtl8139u_flags
& IFF_UP
) != 0)
758 static BOOL
CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
760 struct RTL8139Unit
*unit
;
761 UBYTE
*lower_bound
, *upper_bound
;
763 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
765 RTLD(bug("[%s] S2CmdAddMulticastAddresses()\n", unit
->rtl8139u_name
))
767 lower_bound
= request
->ios2_SrcAddr
;
768 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
769 upper_bound
= lower_bound
;
771 upper_bound
= request
->ios2_DstAddr
;
773 if(!AddMulticastRange(LIBBASE
, unit
, lower_bound
, upper_bound
))
775 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
776 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
784 static BOOL
CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
786 struct RTL8139Unit
*unit
;
787 UBYTE
*lower_bound
, *upper_bound
;
789 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
791 RTLD(bug("[%s] S2CmdDelMulticastAddresses()\n", unit
->rtl8139u_name
))
793 lower_bound
= request
->ios2_SrcAddr
;
794 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
795 upper_bound
= lower_bound
;
797 upper_bound
= request
->ios2_DstAddr
;
799 if(!RemMulticastRange(LIBBASE
, unit
, lower_bound
, upper_bound
))
801 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
802 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;