Here's an idea: don't add interrupt handlers when they've already been
[AROS.git] / workbench / devs / networks / rtl8139 / handler.c
blob5e37bd64cc78504e036f6ad86cb37513c60e0c1c
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 "rtl8139.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 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[] =
76 CMD_READ,
77 CMD_WRITE,
78 CMD_FLUSH,
79 S2_DEVICEQUERY,
80 S2_GETSTATIONADDRESS,
81 S2_CONFIGINTERFACE,
82 S2_ADDMULTICASTADDRESS,
83 S2_DELMULTICASTADDRESS,
84 S2_MULTICAST,
85 S2_BROADCAST,
86 S2_TRACKTYPE,
87 S2_UNTRACKTYPE,
88 S2_GETTYPESTATS,
89 S2_GETSPECIALSTATS,
90 S2_GETGLOBALSTATS,
91 S2_ONEVENT,
92 S2_READORPHAN,
93 S2_ONLINE,
94 S2_OFFLINE,
95 NSCMD_DEVICEQUERY,
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[] =
107 badmulticast_name,
108 retries_name,
109 fifo_underruns_name,
112 void handle_request(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
114 BOOL complete;
116 switch(request->ios2_Req.io_Command)
118 case CMD_READ:
119 complete = CmdRead(LIBBASE, request);
120 break;
122 case CMD_WRITE:
123 case S2_MULTICAST:
124 complete = CmdWrite(LIBBASE, request);
125 break;
127 case CMD_FLUSH:
128 complete = CmdFlush(LIBBASE, (struct IORequest *)request);
129 break;
131 case S2_DEVICEQUERY:
132 complete = CmdS2DeviceQuery(LIBBASE, request);
133 break;
135 case S2_GETSTATIONADDRESS:
136 complete = CmdGetStationAddress(LIBBASE, request);
137 break;
139 case S2_CONFIGINTERFACE:
140 complete = CmdConfigInterface(LIBBASE, request);
141 break;
143 case S2_BROADCAST:
144 complete = CmdBroadcast(LIBBASE, request);
145 break;
147 case S2_TRACKTYPE:
148 complete = CmdTrackType(LIBBASE, request);
149 break;
151 case S2_UNTRACKTYPE:
152 complete = CmdUntrackType(LIBBASE, request);
153 break;
155 case S2_GETTYPESTATS:
156 complete = CmdGetTypeStats(LIBBASE, request);
157 break;
159 case S2_GETSPECIALSTATS:
160 complete = CmdGetSpecialStats(LIBBASE, request);
161 break;
163 case S2_GETGLOBALSTATS:
164 complete = CmdGetGlobalStats(LIBBASE, request);
165 break;
167 case S2_ONEVENT:
168 complete = CmdOnEvent(LIBBASE, request);
169 break;
171 case S2_READORPHAN:
172 complete = CmdReadOrphan(LIBBASE, request);
173 break;
175 case S2_ONLINE:
176 complete = CmdOnline(LIBBASE, request);
177 break;
179 case S2_OFFLINE:
180 complete = CmdOffline(LIBBASE, request);
181 break;
183 case S2_ADDMULTICASTADDRESS:
184 case S2_ADDMULTICASTADDRESSES:
185 complete = CmdAddMulticastAddresses(LIBBASE, request);
186 break;
188 case S2_DELMULTICASTADDRESS:
189 case S2_DELMULTICASTADDRESSES:
190 complete = CmdDelMulticastAddresses(LIBBASE, request);
191 break;
193 case NSCMD_DEVICEQUERY:
194 complete = CmdDeviceQuery(LIBBASE, (struct IOStdReq *)request);
195 break;
197 default:
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;
212 return TRUE;
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);
231 else
233 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
234 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
235 complete = TRUE;
238 /* Return */
240 return complete;
243 static BOOL CmdWrite(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
245 struct RTL8139Unit *unit;
246 BYTE error = 0;
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 */
270 if(error == 0) {
271 request->ios2_Req.io_Flags &= ~IOF_QUICK;
272 PutMsg(unit->rtl8139u_request_ports[WRITE_QUEUE], (APTR)request);
274 else
276 request->ios2_Req.io_Error = error;
277 request->ios2_WireError = wire_error;
278 complete = TRUE;
281 /* Return */
283 return complete;
286 static BOOL CmdFlush(LIBBASETYPEPTR LIBBASE, struct IORequest *request)
288 FlushUnit(LIBBASE, (APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED);
289 return TRUE;
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;
311 info->MTU = ETH_MTU;
312 info->HardwareType = S2WireType_Ethernet;
313 info->SizeAvailable = size_available;
314 info->SizeSupplied = size;
316 /* Return */
318 return TRUE;
321 static BOOL CmdGetStationAddress(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
323 struct RTL8139Unit *unit;
325 /* Copy addresses */
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);
334 /* Return */
336 return TRUE;
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;
355 else
357 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
358 request->ios2_WireError = S2WERR_IS_CONFIGURED;
361 /* Return */
363 return TRUE;
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;
384 BYTE error = 0;
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);
397 if(tracker != NULL)
398 tracker->user_count++;
399 else
401 tracker =
402 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC|MEMF_CLEAR);
403 if(tracker != NULL)
405 tracker->packet_type = packet_type;
406 tracker->user_count = 1;
408 Disable();
409 AddTail((APTR)&unit->rtl8139u_type_trackers, (APTR)tracker);
410 Enable();
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;
425 if(error == 0)
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;
435 if(error == 0)
437 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
438 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
441 /* Return */
443 request->ios2_Req.io_Error = error;
444 request->ios2_WireError = wire_error;
445 return TRUE;
448 static BOOL CmdUntrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
450 struct RTL8139Unit *unit;
451 struct Opener *opener;
452 ULONG packet_type;
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)
475 Disable();
476 Remove((APTR)tracker);
477 Enable();
478 FreeMem(tracker, sizeof(struct TypeTracker));
481 Remove((APTR)initial_stats);
482 FreeMem(initial_stats, sizeof(struct TypeStats));
484 else
486 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
487 request->ios2_WireError = S2WERR_NOT_TRACKED;
490 /* Return */
492 return TRUE;
495 static BOOL CmdGetTypeStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
497 struct RTL8139Unit *unit;
498 struct Opener *opener;
499 ULONG packet_type;
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;
526 else
528 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
529 request->ios2_WireError = S2WERR_NOT_TRACKED;
532 /* Return */
534 return TRUE;
537 static BOOL CmdGetSpecialStats(LIBBASETYPEPTR LIBBASE,
538 struct IOSana2Req *request)
540 struct RTL8139Unit *unit;
541 UWORD i, stat_count;
542 struct Sana2SpecialStatHeader *header;
543 struct Sana2SpecialStatRecord *record;
545 /* Fill in stats */
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];
560 record++;
563 header->RecordCountSupplied = stat_count;
565 /* Return */
567 return TRUE;
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));
583 /* Return */
585 return TRUE;
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;
605 /* Return */
607 return TRUE;
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;
628 else
630 if((unit->rtl8139u_flags & IFF_UP) != 0)
631 events = S2EVENT_ONLINE;
632 else
633 events = S2EVENT_OFFLINE;
635 events &= wanted_events;
638 /* Reply request if a wanted event has already occurred */
640 if(events != 0)
642 request->ios2_WireError = events;
643 complete = TRUE;
645 else
647 request->ios2_Req.io_Flags &= ~IOF_QUICK;
648 PutMsg(unit->rtl8139u_request_ports[EVENT_QUEUE], (APTR)request);
651 /* Return */
653 return complete;
656 static BOOL CmdReadOrphan(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
658 struct RTL8139Unit *unit;
659 BYTE error = 0;
660 ULONG wire_error;
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;
674 /* Queue request */
676 if(error == 0)
678 request->ios2_Req.io_Flags &= ~IOF_QUICK;
679 PutMsg(unit->rtl8139u_request_ports[ADOPT_QUEUE], (struct Message *)request);
681 else
683 request->ios2_Req.io_Error = error;
684 request->ios2_WireError = wire_error;
685 complete = TRUE;
688 /* Return */
690 return complete;
693 static BOOL CmdOnline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
695 // struct RTL8139Unit *unit = (struct RTL8139Unit *)request->ios2_Req.io_Unit;
696 BYTE error = 0;
697 ULONG wire_error = 0;
698 // UWORD i;
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;
730 #endif
732 /* Return */
734 request->ios2_Req.io_Error = error;
735 request->ios2_WireError = wire_error;
736 return TRUE;
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)
751 unit->stop(unit);
752 #endif
754 /* Return */
755 return TRUE;
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;
770 else
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;
779 /* Return */
781 return TRUE;
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;
796 else
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;
805 /* Return */
807 return TRUE;