revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / rtl8169 / handler.c
blobad017490db773b1a74fbdf1de6d5a1442e91cf51
1 /*
2 * $Id$
3 */
5 /*
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,
19 MA 02111-1307, USA.
22 #include <string.h>
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/io.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>
42 #include <stdlib.h>
44 #include "rtl8169.h"
45 #include "unit.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 CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
64 static BOOL CmdDeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOStdReq *request);
65 static BOOL CmdOnEvent(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
66 static BOOL CmdReadOrphan(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
67 static BOOL CmdOnline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
68 static BOOL CmdOffline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
69 static BOOL CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
70 static BOOL CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
72 static const UWORD supported_commands[] =
74 CMD_READ,
75 CMD_WRITE,
76 CMD_FLUSH,
77 S2_DEVICEQUERY,
78 S2_GETSTATIONADDRESS,
79 S2_CONFIGINTERFACE,
80 S2_ADDMULTICASTADDRESS,
81 S2_DELMULTICASTADDRESS,
82 S2_MULTICAST,
83 S2_BROADCAST,
84 S2_TRACKTYPE,
85 S2_UNTRACKTYPE,
86 S2_GETTYPESTATS,
87 // S2_GETSPECIALSTATS,
88 S2_GETGLOBALSTATS,
89 S2_ONEVENT,
90 S2_READORPHAN,
91 S2_ONLINE,
92 S2_OFFLINE,
93 NSCMD_DEVICEQUERY,
94 S2_ADDMULTICASTADDRESSES,
95 S2_DELMULTICASTADDRESSES,
99 void handle_request(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
101 BOOL complete;
103 switch(request->ios2_Req.io_Command)
105 case CMD_READ:
106 complete = CmdRead(LIBBASE, request);
107 break;
109 case CMD_WRITE:
110 case S2_MULTICAST:
111 complete = CmdWrite(LIBBASE, request);
112 break;
114 case CMD_FLUSH:
115 complete = CmdFlush(LIBBASE, (struct IORequest *)request);
116 break;
118 case S2_DEVICEQUERY:
119 complete = CmdS2DeviceQuery(LIBBASE, request);
120 break;
122 case S2_GETSTATIONADDRESS:
123 complete = CmdGetStationAddress(LIBBASE, request);
124 break;
126 case S2_CONFIGINTERFACE:
127 complete = CmdConfigInterface(LIBBASE, request);
128 break;
130 case S2_BROADCAST:
131 complete = CmdBroadcast(LIBBASE, request);
132 break;
134 case S2_TRACKTYPE:
135 complete = CmdTrackType(LIBBASE, request);
136 break;
138 case S2_UNTRACKTYPE:
139 complete = CmdUntrackType(LIBBASE, request);
140 break;
142 case S2_GETTYPESTATS:
143 complete = CmdGetTypeStats(LIBBASE, request);
144 break;
146 case S2_GETGLOBALSTATS:
147 complete = CmdGetGlobalStats(LIBBASE, request);
148 break;
150 case S2_ONEVENT:
151 complete = CmdOnEvent(LIBBASE, request);
152 break;
154 case S2_READORPHAN:
155 complete = CmdReadOrphan(LIBBASE, request);
156 break;
158 case S2_ONLINE:
159 complete = CmdOnline(LIBBASE, request);
160 break;
162 case S2_OFFLINE:
163 complete = CmdOffline(LIBBASE, request);
164 break;
166 case S2_ADDMULTICASTADDRESS:
167 case S2_ADDMULTICASTADDRESSES:
168 complete = CmdAddMulticastAddresses(LIBBASE, request);
169 break;
171 case S2_DELMULTICASTADDRESS:
172 case S2_DELMULTICASTADDRESSES:
173 complete = CmdDelMulticastAddresses(LIBBASE, request);
174 break;
176 case NSCMD_DEVICEQUERY:
177 complete = CmdDeviceQuery(LIBBASE, (struct IOStdReq *)request);
178 break;
180 default:
181 complete = CmdInvalid(LIBBASE, request);
184 if(complete && (request->ios2_Req.io_Flags & IOF_QUICK) == 0)
186 ReplyMsg((APTR)request);
188 ReleaseSemaphore(&((struct RTL8169Unit *)request->ios2_Req.io_Unit)->rtl8169u_unit_lock);
191 static BOOL CmdInvalid(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
193 request->ios2_Req.io_Error = IOERR_NOCMD;
194 request->ios2_WireError = S2WERR_GENERIC_ERROR;
196 return TRUE;
199 static BOOL CmdRead(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
201 struct RTL8169Unit *unit;
202 struct Opener *opener;
203 // BYTE error = 0;
204 // ULONG wire_error = S2WERR_GENERIC_ERROR;
205 BOOL complete = FALSE;
207 unit = (APTR) request->ios2_Req.io_Unit;
209 RTLD(bug("[%s] S2CmdRead()\n", unit->rtl8169u_name))
211 if((unit->rtl8169u_flags & IFF_UP) != 0)
213 opener = request->ios2_BufferManagement;
214 request->ios2_Req.io_Flags &= ~IOF_QUICK;
215 PutMsg(&opener->read_port, (struct Message *) request);
217 else
219 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
220 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
221 complete = TRUE;
224 /* Return */
226 return complete;
229 static BOOL CmdWrite(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
231 struct RTL8169Unit *unit;
232 BYTE error = 0;
233 ULONG wire_error = S2WERR_GENERIC_ERROR;
234 BOOL complete = FALSE;
236 /* Check request is valid */
238 unit = (APTR) request->ios2_Req.io_Unit;
240 RTLD(bug("[%s] S2CmdWrite()\n", unit->rtl8169u_name))
242 if((unit->rtl8169u_flags & IFF_UP) == 0)
244 error = S2ERR_OUTOFSERVICE;
245 wire_error = S2WERR_UNIT_OFFLINE;
247 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
248 ((request->ios2_DstAddr[0] & 0x1) == 0))
250 error = S2ERR_BAD_ADDRESS;
251 wire_error = S2WERR_BAD_MULTICAST;
254 /* Queue request for sending */
256 if(error == 0)
258 request->ios2_Req.io_Flags &= ~IOF_QUICK;
259 PutMsg(unit->rtl8169u_request_ports[WRITE_QUEUE], (APTR)request);
261 else
263 request->ios2_Req.io_Error = error;
264 request->ios2_WireError = wire_error;
265 complete = TRUE;
268 /* Return */
270 return complete;
273 static BOOL CmdFlush(LIBBASETYPEPTR LIBBASE, struct IORequest *request)
275 FlushUnit(LIBBASE, (APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED);
276 return TRUE;
279 static BOOL CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
281 struct RTL8169Unit *unit = (APTR)request->ios2_Req.io_Unit;
282 // struct rtl8169_priv *np = unit->rtl8169u_priv;
283 struct Sana2DeviceQuery *info;
284 ULONG size_available, size;
286 RTLD(bug("[%s] S2CmdDeviceQuery()\n", unit->rtl8169u_name))
288 /* Copy device info */
290 info = request->ios2_StatData;
291 size = size_available = info->SizeAvailable;
292 if(size > sizeof(struct Sana2DeviceQuery))
293 size = sizeof(struct Sana2DeviceQuery);
295 CopyMem(&unit->rtl8169u_Sana2Info, info, size);
297 info->BPS = unit->rtl8169u_rtl_LinkSpeed;
298 info->MTU = ETH_MTU;
299 info->HardwareType = S2WireType_Ethernet;
300 info->SizeAvailable = size_available;
301 info->SizeSupplied = size;
303 /* Return */
305 return TRUE;
308 static BOOL CmdGetStationAddress(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
310 struct RTL8169Unit *unit;
312 /* Copy addresses */
314 unit = (APTR)request->ios2_Req.io_Unit;
316 RTLD(bug("[%s] S2CmdGetStationAddress()\n", unit->rtl8169u_name))
318 CopyMem(unit->rtl8169u_dev_addr, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
319 CopyMem(unit->rtl8169u_org_addr, request->ios2_DstAddr, ETH_ADDRESSSIZE);
321 /* Return */
323 return TRUE;
326 static BOOL CmdConfigInterface(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
328 struct RTL8169Unit *unit;
330 /* Configure adapter */
332 unit = (APTR)request->ios2_Req.io_Unit;
334 RTLD(bug("[%s] S2CmdConfigInterface()\n", unit->rtl8169u_name))
336 if((unit->rtl8169u_flags & IFF_CONFIGURED) == 0)
338 CopyMem(request->ios2_SrcAddr, unit->rtl8169u_dev_addr, ETH_ADDRESSSIZE);
339 unit->set_mac_address(unit);
340 unit->rtl8169u_flags |= IFF_CONFIGURED;
342 else
344 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
345 request->ios2_WireError = S2WERR_IS_CONFIGURED;
348 /* Return */
350 return TRUE;
353 static BOOL CmdBroadcast(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
355 /* Fill in the broadcast address as destination */
357 memset(request->ios2_DstAddr, 0xff, 6);
359 /* Queue the write as normal */
361 return CmdWrite(LIBBASE, request);
364 static BOOL CmdTrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
366 struct RTL8169Unit *unit;
367 struct Opener *opener;
368 ULONG packet_type, wire_error=0;
369 struct TypeTracker *tracker;
370 struct TypeStats *initial_stats;
371 BYTE error = 0;
373 unit = (APTR)request->ios2_Req.io_Unit;
375 RTLD(bug("[%s] S2CmdTrackType()\n", unit->rtl8169u_name))
377 packet_type = request->ios2_PacketType;
379 /* Get global tracker */
381 tracker = (struct TypeTracker *)
382 FindTypeStats(LIBBASE, unit, &unit->rtl8169u_type_trackers, packet_type);
384 if(tracker != NULL)
386 tracker->user_count++;
388 else
390 tracker = AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
391 if(tracker != NULL)
393 tracker->packet_type = packet_type;
394 tracker->user_count = 1;
396 Disable();
397 AddTail((APTR)&unit->rtl8169u_type_trackers, (APTR)tracker);
398 Enable();
402 /* Store initial figures for this opener */
404 opener = request->ios2_BufferManagement;
405 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
407 if(initial_stats != NULL)
409 error = S2ERR_BAD_STATE;
410 wire_error = S2WERR_ALREADY_TRACKED;
413 if(error == 0)
415 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
416 if(initial_stats == NULL)
418 error = S2ERR_NO_RESOURCES;
419 wire_error = S2WERR_GENERIC_ERROR;
423 if(error == 0)
425 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
426 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
429 /* Return */
431 request->ios2_Req.io_Error = error;
432 request->ios2_WireError = wire_error;
433 return TRUE;
436 static BOOL CmdUntrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
438 struct RTL8169Unit *unit;
439 struct Opener *opener;
440 ULONG packet_type;
441 struct TypeTracker *tracker;
442 struct TypeStats *initial_stats;
444 unit = (APTR)request->ios2_Req.io_Unit;
446 RTLD(bug("[%s] S2CmdUntrackType()\n", unit->rtl8169u_name))
448 packet_type = request->ios2_PacketType;
450 /* Get global tracker and initial figures */
452 tracker = (struct TypeTracker *)
453 FindTypeStats(LIBBASE, unit, &unit->rtl8169u_type_trackers, packet_type);
454 opener = request->ios2_BufferManagement;
455 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
457 /* Decrement tracker usage and free unused structures */
459 if(initial_stats != NULL)
461 if((--tracker->user_count) == 0)
463 Disable();
464 Remove((APTR)tracker);
465 Enable();
466 FreeMem(tracker, sizeof(struct TypeTracker));
469 Remove((APTR)initial_stats);
470 FreeMem(initial_stats, sizeof(struct TypeStats));
472 else
474 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
475 request->ios2_WireError = S2WERR_NOT_TRACKED;
478 /* Return */
480 return TRUE;
483 static BOOL CmdGetTypeStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
485 struct RTL8169Unit *unit;
486 struct Opener *opener;
487 ULONG packet_type;
488 struct TypeStats *initial_stats, *tracker;
489 struct Sana2PacketTypeStats *stats;
491 unit = (APTR)request->ios2_Req.io_Unit;
493 RTLD(bug("[%s] S2CmdGetTypeStats()\n", unit->rtl8169u_name))
495 packet_type = request->ios2_PacketType;
497 /* Get global tracker and initial figures */
499 tracker = FindTypeStats(LIBBASE, unit, &unit->rtl8169u_type_trackers, packet_type);
500 opener = request->ios2_BufferManagement;
501 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
503 /* Copy and adjust figures */
504 if(initial_stats != NULL)
506 stats = request->ios2_StatData;
507 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
508 stats->PacketsSent -= initial_stats->stats.PacketsSent;
509 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
510 stats->BytesSent -= initial_stats->stats.BytesSent;
511 stats->BytesReceived -= initial_stats->stats.BytesReceived;
512 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
514 else
516 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
517 request->ios2_WireError = S2WERR_NOT_TRACKED;
520 /* Return */
522 return TRUE;
525 static BOOL CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
527 struct RTL8169Unit *unit;
529 /* Update and copy stats */
531 unit = (APTR)request->ios2_Req.io_Unit;
533 RTLD(bug("[%s] S2CmdGetGlobalStats()\n", unit->rtl8169u_name))
535 CopyMem(&unit->rtl8169u_stats, request->ios2_StatData,
536 sizeof(struct Sana2DeviceStats));
538 /* Return */
540 return TRUE;
543 static BOOL CmdDeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOStdReq *request)
545 struct NSDeviceQueryResult *info;
547 /* Set structure size twice */
549 info = request->io_Data;
550 request->io_Actual = info->SizeAvailable =
551 offsetof(struct NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
553 /* Report device details */
555 info->DeviceType = NSDEVTYPE_SANA2;
556 info->DeviceSubType = 0;
558 info->SupportedCommands = (APTR)supported_commands;
560 /* Return */
562 return TRUE;
565 static BOOL CmdOnEvent(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
567 struct RTL8169Unit *unit;
568 ULONG events, wanted_events;
569 BOOL complete = FALSE;
571 /* Check if we understand the event types */
573 unit = (APTR)request->ios2_Req.io_Unit;
575 RTLD(bug("[%s] S2CmdOnEvent()\n", unit->rtl8169u_name))
577 wanted_events = request->ios2_WireError;
578 if((wanted_events & ~KNOWN_EVENTS) != 0)
580 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
581 events = S2WERR_BAD_EVENT;
583 else
585 if((unit->rtl8169u_flags & IFF_UP) != 0)
587 events = S2EVENT_ONLINE;
589 else
591 events = S2EVENT_OFFLINE;
594 events &= wanted_events;
597 /* Reply request if a wanted event has already occurred */
599 if(events != 0)
601 request->ios2_WireError = events;
602 complete = TRUE;
604 else
606 request->ios2_Req.io_Flags &= ~IOF_QUICK;
607 PutMsg(unit->rtl8169u_request_ports[EVENT_QUEUE], (APTR)request);
610 /* Return */
612 return complete;
615 static BOOL CmdReadOrphan(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
617 struct RTL8169Unit *unit;
618 BYTE error = 0;
619 ULONG wire_error;
620 BOOL complete = FALSE;
622 /* Check request is valid */
624 unit = (APTR)request->ios2_Req.io_Unit;
625 RTLD(bug("[%s] S2CmdReadOrphan()\n", unit->rtl8169u_name))
627 if((unit->rtl8169u_flags & IFF_UP) == 0)
629 error = S2ERR_OUTOFSERVICE;
630 wire_error = S2WERR_UNIT_OFFLINE;
633 /* Queue request */
635 if(error == 0)
637 request->ios2_Req.io_Flags &= ~IOF_QUICK;
638 PutMsg(unit->rtl8169u_request_ports[ADOPT_QUEUE], (struct Message *) request);
640 else
642 request->ios2_Req.io_Error = error;
643 request->ios2_WireError = wire_error;
644 complete = TRUE;
647 /* Return */
649 return complete;
652 static BOOL CmdOnline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
654 struct RTL8169Unit *unit = (struct RTL8169Unit *)request->ios2_Req.io_Unit;
655 BYTE error = 0;
656 ULONG wire_error = 0;
657 UWORD i;
659 RTLD(bug("[%s] S2CmdOnline()\n", unit->rtl8169u_name))
661 /* Check request is valid */
662 if((unit->rtl8169u_flags & IFF_CONFIGURED) == 0)
664 error = S2ERR_BAD_STATE;
665 wire_error = S2WERR_NOT_CONFIGURED;
668 /* Clear global and special stats and put adapter back online */
670 if((error == 0) && ((unit->rtl8169u_flags & IFF_UP) == 0))
672 unit->rtl8169u_stats.PacketsReceived = 0;
673 unit->rtl8169u_stats.PacketsSent = 0;
674 unit->rtl8169u_stats.BadData = 0;
675 unit->rtl8169u_stats.Overruns = 0;
676 unit->rtl8169u_stats.UnknownTypesReceived = 0;
677 unit->rtl8169u_stats.Reconfigurations = 0;
679 for(i = 0; i < STAT_COUNT; i++)
681 unit->rtl8169u_special_stats[i] = 0;
684 if (unit->start(unit))
686 error = S2ERR_OUTOFSERVICE;
687 wire_error = S2WERR_GENERIC_ERROR;
691 /* Return */
693 request->ios2_Req.io_Error = error;
694 request->ios2_WireError = wire_error;
695 return TRUE;
698 static BOOL CmdOffline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
700 struct RTL8169Unit *unit;
702 /* Put adapter offline */
704 unit = (APTR)request->ios2_Req.io_Unit;
706 RTLD(bug("[%s] S2CmdOffline()\n", unit->rtl8169u_name))
708 if((unit->rtl8169u_flags & IFF_UP) != 0)
710 unit->stop(unit);
713 /* Return */
714 return TRUE;
717 static BOOL CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
719 struct RTL8169Unit *unit;
720 UBYTE *lower_bound, *upper_bound;
722 unit = (APTR)request->ios2_Req.io_Unit;
724 RTLD(bug("[%s] S2CmdAddMulticastAddresses()\n", unit->rtl8169u_name))
726 lower_bound = request->ios2_SrcAddr;
727 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
728 upper_bound = lower_bound;
729 else
730 upper_bound = request->ios2_DstAddr;
732 if(!AddMulticastRange(LIBBASE, unit, lower_bound, upper_bound))
734 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
735 request->ios2_WireError = S2WERR_GENERIC_ERROR;
738 /* Return */
740 return TRUE;
743 static BOOL CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
745 struct RTL8169Unit *unit;
746 UBYTE *lower_bound, *upper_bound;
748 unit = (APTR)request->ios2_Req.io_Unit;
750 RTLD(bug("[%s] S2CmdDelMulticastAddresses()\n", unit->rtl8169u_name))
752 lower_bound = request->ios2_SrcAddr;
753 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
755 upper_bound = lower_bound;
757 else
759 upper_bound = request->ios2_DstAddr;
762 if(!RemMulticastRange(LIBBASE, unit, lower_bound, upper_bound))
764 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
765 request->ios2_WireError = S2WERR_BAD_MULTICAST;
768 /* Return */
770 return TRUE;