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,
21 #include <exec/types.h>
22 #include <exec/resident.h>
24 #include <exec/ports.h>
25 #include <exec/errors.h>
27 #include <devices/sana2.h>
28 #include <devices/sana2specialstats.h>
29 #include <devices/newstyle.h>
31 #include <utility/utility.h>
32 #include <utility/tagitem.h>
33 #include <utility/hooks.h>
35 #include <proto/exec.h>
36 #include <proto/dos.h>
37 #include <proto/battclock.h>
41 #include "e1000_osdep.h"
43 #include "e1000_defines.h"
44 #include "e1000_api.h"
47 #include LC_LIBDEFS_FILE
49 #define KNOWN_EVENTS \
50 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
51 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
53 static BOOL
CmdInvalid(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
54 static BOOL
CmdRead(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
55 static BOOL
CmdWrite(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
56 static BOOL
CmdFlush(LIBBASETYPEPTR LIBBASE
, struct IORequest
*request
);
57 static BOOL
CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
58 static BOOL
CmdGetStationAddress(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
59 static BOOL
CmdConfigInterface(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
60 static BOOL
CmdBroadcast(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
61 static BOOL
CmdTrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
62 static BOOL
CmdUntrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
63 static BOOL
CmdGetTypeStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
64 static BOOL
CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
65 static BOOL
CmdDeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOStdReq
*request
);
66 static BOOL
CmdOnEvent(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
67 static BOOL
CmdReadOrphan(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
68 static BOOL
CmdOnline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
69 static BOOL
CmdOffline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
70 static BOOL
CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
71 static BOOL
CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
);
73 static const UWORD supported_commands
[] =
81 S2_ADDMULTICASTADDRESS
,
82 S2_DELMULTICASTADDRESS
,
88 // S2_GETSPECIALSTATS,
95 S2_ADDMULTICASTADDRESSES
,
96 S2_DELMULTICASTADDRESSES
,
100 void handle_request(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
104 switch(request
->ios2_Req
.io_Command
)
107 complete
= CmdRead(LIBBASE
, request
);
112 complete
= CmdWrite(LIBBASE
, request
);
116 complete
= CmdFlush(LIBBASE
, (struct IORequest
*)request
);
120 complete
= CmdS2DeviceQuery(LIBBASE
, request
);
123 case S2_GETSTATIONADDRESS
:
124 complete
= CmdGetStationAddress(LIBBASE
, request
);
127 case S2_CONFIGINTERFACE
:
128 complete
= CmdConfigInterface(LIBBASE
, request
);
132 complete
= CmdBroadcast(LIBBASE
, request
);
136 complete
= CmdTrackType(LIBBASE
, request
);
140 complete
= CmdUntrackType(LIBBASE
, request
);
143 case S2_GETTYPESTATS
:
144 complete
= CmdGetTypeStats(LIBBASE
, request
);
147 case S2_GETGLOBALSTATS
:
148 complete
= CmdGetGlobalStats(LIBBASE
, request
);
152 complete
= CmdOnEvent(LIBBASE
, request
);
156 complete
= CmdReadOrphan(LIBBASE
, request
);
160 complete
= CmdOnline(LIBBASE
, request
);
164 complete
= CmdOffline(LIBBASE
, request
);
167 case S2_ADDMULTICASTADDRESS
:
168 case S2_ADDMULTICASTADDRESSES
:
169 complete
= CmdAddMulticastAddresses(LIBBASE
, request
);
172 case S2_DELMULTICASTADDRESS
:
173 case S2_DELMULTICASTADDRESSES
:
174 complete
= CmdDelMulticastAddresses(LIBBASE
, request
);
177 case NSCMD_DEVICEQUERY
:
178 complete
= CmdDeviceQuery(LIBBASE
, (struct IOStdReq
*)request
);
182 complete
= CmdInvalid(LIBBASE
, request
);
185 if(complete
&& (request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0)
186 ReplyMsg((APTR
)request
);
188 ReleaseSemaphore(&((struct e1000Unit
*)request
->ios2_Req
.io_Unit
)->e1ku_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
;
199 static BOOL
CmdRead(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
201 struct e1000Unit
*unit
;
202 struct Opener
*opener
;
203 BOOL complete
= FALSE
;
205 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
207 D(bug("[%s]: CmdRead()\n", unit
->e1ku_name
));
209 if((unit
->e1ku_ifflags
& IFF_UP
) != 0)
211 opener
= request
->ios2_BufferManagement
;
212 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
213 PutMsg(&opener
->read_port
, (struct Message
*)request
);
217 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
218 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
227 static BOOL
CmdWrite(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
229 struct e1000Unit
*unit
;
231 ULONG wire_error
= S2WERR_GENERIC_ERROR
;
232 BOOL complete
= FALSE
;
234 /* Check request is valid */
236 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
238 D(bug("[%s]: CmdWrite()\n", unit
->e1ku_name
));
240 if((unit
->e1ku_ifflags
& IFF_UP
) == 0)
242 error
= S2ERR_OUTOFSERVICE
;
243 wire_error
= S2WERR_UNIT_OFFLINE
;
245 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
246 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
248 error
= S2ERR_BAD_ADDRESS
;
249 wire_error
= S2WERR_BAD_MULTICAST
;
252 /* Queue request for sending */
255 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
256 PutMsg(unit
->e1ku_request_ports
[WRITE_QUEUE
], (APTR
)request
);
260 request
->ios2_Req
.io_Error
= error
;
261 request
->ios2_WireError
= wire_error
;
270 static BOOL
CmdFlush(LIBBASETYPEPTR LIBBASE
, struct IORequest
*request
)
272 FlushUnit(LIBBASE
, (APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
);
276 static BOOL
CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
278 struct e1000Unit
*unit
= (APTR
)request
->ios2_Req
.io_Unit
;
279 struct Sana2DeviceQuery
*info
;
280 ULONG size_available
, size
;
281 UWORD lnk_speed
= 0, lnk_duplex
= 0;
282 D(bug("[%s]: CmdS2DeviceQuery()\n", unit
->e1ku_name
));
284 /* Copy device info */
285 info
= request
->ios2_StatData
;
286 size
= size_available
= info
->SizeAvailable
;
287 if(size
> sizeof(struct Sana2DeviceQuery
))
288 size
= sizeof(struct Sana2DeviceQuery
);
290 CopyMem(&unit
->e1ku_Sana2Info
, info
, size
);
292 e1000_get_speed_and_duplex((struct e1000_hw
*)unit
->e1ku_Private00
, &lnk_speed
, &lnk_duplex
);
294 info
->BPS
= (1000000 * lnk_speed
);
295 info
->MTU
= unit
->e1ku_mtu
;
296 info
->HardwareType
= S2WireType_Ethernet
;
297 info
->SizeAvailable
= size_available
;
298 info
->SizeSupplied
= size
;
305 static BOOL
CmdGetStationAddress(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
307 struct e1000Unit
*unit
;
311 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
313 D(bug("[%s]: CmdGetStationAddress()\n", unit
->e1ku_name
));
315 CopyMem(unit
->e1ku_dev_addr
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
316 CopyMem(unit
->e1ku_org_addr
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
323 static BOOL
CmdConfigInterface(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
325 struct e1000Unit
*unit
;
327 /* Configure adapter */
329 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
331 D(bug("[%s]: CmdConfigInterface()\n", unit
->e1ku_name
));
333 if((unit
->e1ku_ifflags
& IFF_CONFIGURED
) == 0)
335 CopyMem(request
->ios2_SrcAddr
, unit
->e1ku_dev_addr
, ETH_ADDRESSSIZE
);
336 e1000func_set_mac(unit
);
337 unit
->e1ku_ifflags
|= IFF_CONFIGURED
;
341 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
342 request
->ios2_WireError
= S2WERR_IS_CONFIGURED
;
350 static BOOL
CmdBroadcast(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
352 /* Fill in the broadcast address as destination */
354 *((ULONG
*)request
->ios2_DstAddr
) = 0xffffffff;
355 *((UWORD
*)(request
->ios2_DstAddr
+ 4)) = 0xffff;
357 /* Queue the write as normal */
359 return CmdWrite(LIBBASE
, request
);
362 static BOOL
CmdTrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
364 struct e1000Unit
*unit
;
365 struct Opener
*opener
;
366 ULONG packet_type
, wire_error
=0;
367 struct TypeTracker
*tracker
;
368 struct TypeStats
*initial_stats
;
371 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
373 D(bug("[%s]: CmdTrackType()\n", unit
->e1ku_name
));
375 packet_type
= request
->ios2_PacketType
;
377 /* Get global tracker */
379 tracker
= (struct TypeTracker
*)
380 FindTypeStats(LIBBASE
, unit
, &unit
->e1ku_type_trackers
, packet_type
);
383 tracker
->user_count
++;
387 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
|MEMF_CLEAR
);
390 tracker
->packet_type
= packet_type
;
391 tracker
->user_count
= 1;
394 AddTail((APTR
)&unit
->e1ku_type_trackers
, (APTR
)tracker
);
399 /* Store initial figures for this opener */
401 opener
= request
->ios2_BufferManagement
;
402 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
404 if(initial_stats
!= NULL
)
406 error
= S2ERR_BAD_STATE
;
407 wire_error
= S2WERR_ALREADY_TRACKED
;
412 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
413 if(initial_stats
== NULL
)
415 error
= S2ERR_NO_RESOURCES
;
416 wire_error
= S2WERR_GENERIC_ERROR
;
422 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
423 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
428 request
->ios2_Req
.io_Error
= error
;
429 request
->ios2_WireError
= wire_error
;
433 static BOOL
CmdUntrackType(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
435 struct e1000Unit
*unit
;
436 struct Opener
*opener
;
438 struct TypeTracker
*tracker
;
439 struct TypeStats
*initial_stats
;
441 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
443 D(bug("[%s]: CmdUntrackType()\n", unit
->e1ku_name
));
445 packet_type
= request
->ios2_PacketType
;
447 /* Get global tracker and initial figures */
449 tracker
= (struct TypeTracker
*)
450 FindTypeStats(LIBBASE
, unit
, &unit
->e1ku_type_trackers
, packet_type
);
451 opener
= request
->ios2_BufferManagement
;
452 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
454 /* Decrement tracker usage and free unused structures */
456 if(initial_stats
!= NULL
)
458 if((--tracker
->user_count
) == 0)
461 Remove((APTR
)tracker
);
463 FreeMem(tracker
, sizeof(struct TypeTracker
));
466 Remove((APTR
)initial_stats
);
467 FreeMem(initial_stats
, sizeof(struct TypeStats
));
471 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
472 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
480 static BOOL
CmdGetTypeStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
482 struct e1000Unit
*unit
;
483 struct Opener
*opener
;
485 struct TypeStats
*initial_stats
, *tracker
;
486 struct Sana2PacketTypeStats
*stats
;
488 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
490 D(bug("[%s]: CmdGetTypeStats()\n", unit
->e1ku_name
));
492 packet_type
= request
->ios2_PacketType
;
494 /* Get global tracker and initial figures */
496 tracker
= FindTypeStats(LIBBASE
, unit
, &unit
->e1ku_type_trackers
, packet_type
);
497 opener
= request
->ios2_BufferManagement
;
498 initial_stats
= FindTypeStats(LIBBASE
, unit
, &opener
->initial_stats
, packet_type
);
500 /* Copy and adjust figures */
501 if(initial_stats
!= NULL
)
503 stats
= request
->ios2_StatData
;
504 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
505 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
506 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
507 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
508 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
509 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
513 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
514 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
522 static BOOL
CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
524 struct e1000Unit
*unit
;
526 /* Update and copy stats */
528 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
530 D(bug("[%s]: CmdGetGlobalStats()\n", unit
->e1ku_name
));
532 CopyMem(&unit
->e1ku_stats
, request
->ios2_StatData
,
533 sizeof(struct Sana2DeviceStats
));
540 static BOOL
CmdDeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOStdReq
*request
)
542 struct NSDeviceQueryResult
*info
;
544 /* Set structure size twice */
546 info
= request
->io_Data
;
547 request
->io_Actual
= info
->SizeAvailable
=
548 offsetof(struct NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
550 /* Report device details */
552 info
->DeviceType
= NSDEVTYPE_SANA2
;
553 info
->DeviceSubType
= 0;
555 info
->SupportedCommands
= (APTR
)supported_commands
;
562 static BOOL
CmdOnEvent(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
564 struct e1000Unit
*unit
;
565 ULONG events
, wanted_events
;
566 BOOL complete
= FALSE
;
568 /* Check if we understand the event types */
570 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
572 D(bug("[%s]: CmdOnEvent()\n", unit
->e1ku_name
));
574 wanted_events
= request
->ios2_WireError
;
575 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
577 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
578 events
= S2WERR_BAD_EVENT
;
582 if((unit
->e1ku_ifflags
& IFF_UP
) != 0)
583 events
= S2EVENT_ONLINE
;
585 events
= S2EVENT_OFFLINE
;
587 events
&= wanted_events
;
590 /* Reply request if a wanted event has already occurred */
594 request
->ios2_WireError
= events
;
599 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
600 PutMsg(unit
->e1ku_request_ports
[EVENT_QUEUE
], (APTR
)request
);
608 static BOOL
CmdReadOrphan(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
610 struct e1000Unit
*unit
;
613 BOOL complete
= FALSE
;
615 /* Check request is valid */
617 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
618 D(bug("[%s]: CmdReadOrphan()\n", unit
->e1ku_name
));
620 if((unit
->e1ku_ifflags
& IFF_UP
) == 0)
622 error
= S2ERR_OUTOFSERVICE
;
623 wire_error
= S2WERR_UNIT_OFFLINE
;
630 request
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
631 PutMsg(unit
->e1ku_request_ports
[ADOPT_QUEUE
], (struct Message
*)request
);
635 request
->ios2_Req
.io_Error
= error
;
636 request
->ios2_WireError
= wire_error
;
645 static BOOL
CmdOnline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
647 struct e1000Unit
*unit
= (struct e1000Unit
*)request
->ios2_Req
.io_Unit
;
648 ULONG wire_error
= 0, rctl
, tctl
;
652 D(bug("[%s]: CmdOnline()\n", unit
->e1ku_name
));
654 /* Check request is valid */
655 if((unit
->e1ku_ifflags
& IFF_CONFIGURED
) == 0)
657 error
= S2ERR_BAD_STATE
;
658 wire_error
= S2WERR_NOT_CONFIGURED
;
661 /* Clear global and special stats and put adapter back online */
663 if((error
== 0) && ((unit
->e1ku_ifflags
& IFF_UP
) == 0))
665 unit
->e1ku_stats
.PacketsReceived
= 0;
666 unit
->e1ku_stats
.PacketsSent
= 0;
667 unit
->e1ku_stats
.BadData
= 0;
668 unit
->e1ku_stats
.Overruns
= 0;
669 unit
->e1ku_stats
.UnknownTypesReceived
= 0;
670 unit
->e1ku_stats
.Reconfigurations
= 0;
672 for(i
= 0; i
< SANA2_SPECIAL_STAT_COUNT
; i
++)
673 unit
->e1ku_special_stats
[i
] = 0;
675 tctl
= E1000_READ_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_TCTL
);
676 tctl
|= E1000_TCTL_EN
;
677 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_TCTL
, tctl
);
679 rctl
= E1000_READ_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_RCTL
);
680 rctl
|= E1000_RCTL_EN
;
681 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_RCTL
, rctl
);
683 e1000func_irq_enable(unit
);
685 /* fire a link status change interrupt to start the watchdog */
686 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_ICS
, E1000_ICS_LSC
);
688 unit
->e1ku_ifflags
|= IFF_UP
;
689 ReportEvents(LIBBASE
, unit
, S2EVENT_ONLINE
);
694 request
->ios2_Req
.io_Error
= error
;
695 request
->ios2_WireError
= wire_error
;
699 static BOOL
CmdOffline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
701 struct e1000Unit
*unit
;
703 /* Put adapter offline */
705 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
707 D(bug("[%s]: CmdOffline()\n", unit
->e1ku_name
));
709 if((unit
->e1ku_ifflags
& IFF_UP
) != 0)
711 unit
->e1ku_ifflags
&= ~IFF_UP
;
713 tctl
= E1000_READ_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_TCTL
);
714 tctl
&= ~E1000_TCTL_EN
;
715 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_TCTL
, tctl
);
717 rctl
= E1000_READ_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_RCTL
);
718 rctl
&= ~E1000_RCTL_EN
;
719 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_RCTL
, rctl
);
721 e1000func_irq_disable(unit
);
723 ReportEvents(LIBBASE
, unit
, S2EVENT_OFFLINE
);
730 static BOOL
CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
732 struct e1000Unit
*unit
;
733 UBYTE
*lower_bound
, *upper_bound
;
735 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
737 D(bug("[%s]: CmdAddMulticastAddresses()\n", unit
->e1ku_name
));
739 lower_bound
= request
->ios2_SrcAddr
;
740 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
741 upper_bound
= lower_bound
;
743 upper_bound
= request
->ios2_DstAddr
;
745 if(!AddMulticastRange(LIBBASE
, unit
, lower_bound
, upper_bound
))
747 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
748 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
756 static BOOL
CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*request
)
758 struct e1000Unit
*unit
;
759 UBYTE
*lower_bound
, *upper_bound
;
761 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
763 D(bug("[%s]: CmdDelMulticastAddresses()\n", unit
->e1ku_name
));
765 lower_bound
= request
->ios2_SrcAddr
;
766 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
767 upper_bound
= lower_bound
;
769 upper_bound
= request
->ios2_DstAddr
;
771 if(!RemMulticastRange(LIBBASE
, unit
, lower_bound
, upper_bound
))
773 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
774 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;