store the pre-alphacomposit hook and allow it to be queried.
[AROS.git] / workbench / devs / networks / realtek8180 / request.c
blob4f083a96f33e768a9b038ed8f6fa80cc435cc34f
1 /*
3 Copyright (C) 2001-2012 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,
18 MA 02111-1307, USA.
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>
31 #include "device.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 \
40 | S2EVENT_CONNECT)
43 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base);
44 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base);
45 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base);
46 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base);
48 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
49 struct DevBase *base);
50 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
51 struct DevBase *base);
52 static BOOL CmdConfigInterface(struct IOSana2Req *request,
53 struct DevBase *base);
54 static BOOL CmdBroadcast(struct IOSana2Req *request,
55 struct DevBase *base);
56 static BOOL CmdTrackType(struct IOSana2Req *request,
57 struct DevBase *base);
58 static BOOL CmdUntrackType(struct IOSana2Req *request,
59 struct DevBase *base);
60 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
61 struct DevBase *base);
62 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
63 struct DevBase *base);
64 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
65 struct DevBase *base);
66 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base);
67 static BOOL CmdReadOrphan(struct IOSana2Req *request,
68 struct DevBase *base);
69 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base);
70 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base);
71 static BOOL CmdDeviceQuery(struct IOStdReq *request,
72 struct DevBase *base);
73 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
74 struct DevBase *base);
75 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
76 struct DevBase *base);
77 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base);
78 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base);
79 static BOOL CmdWriteMgmt(struct IOSana2Req *request, struct DevBase *base);
80 static BOOL CmdReadMgmt(struct IOSana2Req *request, struct DevBase *base);
83 static const UWORD supported_commands[] =
85 CMD_READ,
86 CMD_WRITE,
87 CMD_FLUSH,
88 S2_DEVICEQUERY,
89 S2_GETSTATIONADDRESS,
90 S2_CONFIGINTERFACE,
91 S2_ADDMULTICASTADDRESS,
92 S2_DELMULTICASTADDRESS,
93 S2_MULTICAST,
94 S2_BROADCAST,
95 S2_TRACKTYPE,
96 S2_UNTRACKTYPE,
97 S2_GETTYPESTATS,
98 S2_GETSPECIALSTATS,
99 S2_GETGLOBALSTATS,
100 S2_ONEVENT,
101 S2_READORPHAN,
102 S2_ONLINE,
103 S2_OFFLINE,
104 NSCMD_DEVICEQUERY,
105 S2_ADDMULTICASTADDRESSES,
106 S2_DELMULTICASTADDRESSES,
107 S2_SETOPTIONS,
108 S2_SETKEY,
109 S2_READMGMT,
110 S2_WRITEMGMT,
115 static const struct Sana2DeviceQuery sana2_info =
121 ETH_ADDRESSSIZE * 8,
122 ETH_MTU,
124 S2WireType_Ethernet
128 const TEXT badmulticast_name[] = "Bad multicasts";
129 const TEXT retries_name[] = "Retries";
130 const TEXT fifo_underruns_name[] = "Underruns";
133 const TEXT *const special_stat_names[] =
135 badmulticast_name,
136 retries_name,
137 fifo_underruns_name
142 /****i* realtek8180.device/ServiceRequest **********************************
144 * NAME
145 * ServiceRequest -- Attempt to service a device request.
147 * SYNOPSIS
148 * ServiceRequest(request)
150 * VOID ServiceRequest(struct IORequest *);
152 * FUNCTION
153 * Attempts to carry out a request. The relevant unit's semaphore must
154 * be obtained before calling this function. This function releases the
155 * semaphore before returning.
157 * INPUTS
158 * request
160 * RESULT
161 * None.
163 * EXAMPLE
165 * NOTES
167 * BUGS
169 * SEE ALSO
171 ****************************************************************************
175 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
177 BOOL complete;
179 switch(request->ios2_Req.io_Command)
181 case CMD_READ:
182 complete = CmdRead(request, base);
183 break;
184 case CMD_WRITE:
185 complete = CmdWrite(request, base);
186 break;
187 case CMD_FLUSH:
188 complete = CmdFlush((APTR)request, base);
189 break;
190 case S2_DEVICEQUERY:
191 complete = CmdS2DeviceQuery(request, base);
192 break;
193 case S2_GETSTATIONADDRESS:
194 complete = CmdGetStationAddress(request, base);
195 break;
196 case S2_CONFIGINTERFACE:
197 complete = CmdConfigInterface(request, base);
198 break;
199 case S2_ADDMULTICASTADDRESS:
200 complete = CmdAddMulticastAddresses(request, base);
201 break;
202 case S2_DELMULTICASTADDRESS:
203 complete = CmdDelMulticastAddresses(request, base);
204 break;
205 case S2_MULTICAST:
206 complete = CmdWrite(request, base);
207 break;
208 case S2_BROADCAST:
209 complete = CmdBroadcast(request, base);
210 break;
211 case S2_TRACKTYPE:
212 complete = CmdTrackType(request, base);
213 break;
214 case S2_UNTRACKTYPE:
215 complete = CmdUntrackType(request, base);
216 break;
217 case S2_GETTYPESTATS:
218 complete = CmdGetTypeStats(request, base);
219 break;
220 case S2_GETSPECIALSTATS:
221 complete = CmdGetSpecialStats(request, base);
222 break;
223 case S2_GETGLOBALSTATS:
224 complete = CmdGetGlobalStats(request, base);
225 break;
226 case S2_ONEVENT:
227 complete = CmdOnEvent(request, base);
228 break;
229 case S2_READORPHAN:
230 complete = CmdReadOrphan(request, base);
231 break;
232 case S2_ONLINE:
233 complete = CmdOnline(request, base);
234 break;
235 case S2_OFFLINE:
236 complete = CmdOffline(request, base);
237 break;
238 case NSCMD_DEVICEQUERY:
239 complete = CmdDeviceQuery((APTR)request, base);
240 break;
241 case S2_ADDMULTICASTADDRESSES:
242 complete = CmdAddMulticastAddresses(request, base);
243 break;
244 case S2_DELMULTICASTADDRESSES:
245 complete = CmdDelMulticastAddresses(request, base);
246 break;
247 case S2_SETOPTIONS:
248 complete = CmdSetOptions(request, base);
249 break;
250 case S2_SETKEY:
251 complete = CmdSetKey(request, base);
252 break;
253 case S2_WRITEMGMT:
254 complete = CmdWriteMgmt(request, base);
255 break;
256 case S2_READMGMT:
257 complete = CmdReadMgmt(request, base);
258 break;
259 default:
260 complete = CmdInvalid(request, base);
263 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
264 ReplyMsg((APTR)request);
266 ReleaseSemaphore(
267 &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock);
268 return;
273 /****i* realtek8180.device/CMD_INVALID *************************************
275 * NAME
276 * CMD_INVALID -- Reject an invalid command.
278 * FUNCTION
280 * INPUTS
281 * None.
283 * RESULTS
284 * io_Error - IOERR_NOCMD.
286 * EXAMPLE
288 * NOTES
290 * BUGS
292 * SEE ALSO
294 ****************************************************************************
298 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
300 request->ios2_Req.io_Error = IOERR_NOCMD;
301 request->ios2_WireError = S2WERR_GENERIC_ERROR;
303 return TRUE;
308 /****** realtek8180.device/CMD_READ ****************************************
310 * NAME
311 * CMD_READ -- Read data.
313 * FUNCTION
315 * INPUTS
316 * io_Flags
317 * ios2_PacketType
318 * ios2_Data
320 * RESULTS
321 * io_Flags
322 * io_Error
323 * ios2_WireError
324 * ios2_SrcAddr
325 * ios2_DstAddr
326 * ios2_DataLength
327 * ios2_Data
329 * EXAMPLE
331 * NOTES
333 * BUGS
335 * SEE ALSO
337 ****************************************************************************
341 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
343 struct DevUnit *unit;
344 struct Opener *opener;
345 BOOL complete = FALSE;
347 unit = (APTR)request->ios2_Req.io_Unit;
349 if((unit->flags & UNITF_ONLINE) != 0)
351 opener = request->ios2_BufferManagement;
352 PutRequest(&opener->read_port, (APTR)request, base);
354 else
356 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
357 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
358 complete = TRUE;
361 /* Return */
363 return complete;
368 /****** realtek8180.device/CMD_WRITE ***************************************
370 * NAME
371 * CMD_WRITE -- Write data.
373 * FUNCTION
375 * INPUTS
376 * io_Flags
377 * ios2_DstAddr
378 * ios2_PacketType
379 * ios2_DataLength
380 * ios2_Data
382 * RESULTS
383 * io_Error
384 * ios2_WireError
386 * EXAMPLE
388 * NOTES
390 * BUGS
392 * SEE ALSO
394 ****************************************************************************
398 /****** realtek8180.device/S2_MULTICAST ************************************
400 * NAME
401 * S2_MULTICAST
403 * FUNCTION
405 * INPUTS
406 * io_Flags
407 * ios2_DstAddr - multicast address.
408 * ios2_PacketType
409 * ios2_DataLength
410 * ios2_Data
412 * RESULTS
413 * io_Error
414 * ios2_WireError
416 * EXAMPLE
418 * NOTES
420 * BUGS
422 * SEE ALSO
424 ****************************************************************************
428 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
430 struct DevUnit *unit;
431 BYTE error = 0;
432 ULONG wire_error;
433 BOOL complete = FALSE;
435 /* Check request is valid */
437 unit = (APTR)request->ios2_Req.io_Unit;
438 if((unit->flags & UNITF_ONLINE) == 0)
440 error = S2ERR_OUTOFSERVICE;
441 wire_error = S2WERR_UNIT_OFFLINE;
443 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
444 ((request->ios2_DstAddr[0] & 0x1) == 0))
446 error = S2ERR_BAD_ADDRESS;
447 wire_error = S2WERR_BAD_MULTICAST;
450 /* Queue request for sending */
452 if(error == 0)
453 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
454 else
456 request->ios2_Req.io_Error = error;
457 request->ios2_WireError = wire_error;
458 complete = TRUE;
461 /* Return */
463 return complete;
468 /****** realtek8180.device/CMD_FLUSH ***************************************
470 * NAME
471 * CMD_FLUSH
473 * FUNCTION
475 * INPUTS
476 * None.
478 * RESULTS
479 * io_Error
481 * EXAMPLE
483 * NOTES
485 * BUGS
487 * SEE ALSO
489 ****************************************************************************
493 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
495 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
497 return TRUE;
502 /****** realtek8180.device/S2_DEVICEQUERY **********************************
504 * NAME
505 * S2_DEVICEQUERY -- Query device capabilities.
507 * FUNCTION
509 * INPUTS
510 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
512 * RESULTS
513 * io_Error
514 * ios2_WireError
516 * EXAMPLE
518 * NOTES
520 * BUGS
522 * SEE ALSO
524 ****************************************************************************
528 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
529 struct DevBase *base)
531 struct DevUnit *unit;
532 struct Sana2DeviceQuery *info;
533 ULONG size_available, size;
535 /* Copy device info */
537 unit = (APTR)request->ios2_Req.io_Unit;
538 info = request->ios2_StatData;
539 size = size_available = info->SizeAvailable;
540 if(size > sizeof(struct Sana2DeviceQuery))
541 size = sizeof(struct Sana2DeviceQuery);
543 CopyMem(&sana2_info, info, size);
544 info->BPS = unit->speed;
546 info->SizeAvailable = size_available;
547 info->SizeSupplied = size;
549 /* Return */
551 return TRUE;
556 /****** realtek8180.device/S2_GETSTATIONADDDRESS ***************************
558 * NAME
559 * S2_GETSTATIONADDDRESS
561 * FUNCTION
563 * INPUTS
564 * None.
566 * RESULTS
567 * io_Error
568 * ios2_WireError
569 * ios2_SrcAddr - current address.
570 * ios2_DstAddr - default address (zero if none?).
572 * EXAMPLE
574 * NOTES
576 * BUGS
578 * SEE ALSO
580 ****************************************************************************
584 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
585 struct DevBase *base)
587 struct DevUnit *unit;
589 /* Copy addresses */
591 unit = (APTR)request->ios2_Req.io_Unit;
592 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
593 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
595 /* Return */
597 return TRUE;
602 /****** realtek8180.device/S2_CONFIGINTERFACE ******************************
604 * NAME
605 * S2_CONFIGINTERFACE
607 * FUNCTION
609 * INPUTS
610 * ios2_SrcAddr - address to use.
612 * RESULTS
613 * io_Error
614 * ios2_WireError
615 * ios2_SrcAddr - address used.
617 * EXAMPLE
619 * NOTES
621 * BUGS
623 * SEE ALSO
625 ****************************************************************************
629 static BOOL CmdConfigInterface(struct IOSana2Req *request,
630 struct DevBase *base)
632 struct DevUnit *unit;
633 BYTE error = 0;
634 ULONG wire_error;
636 /* Configure adapter */
638 unit = (APTR)request->ios2_Req.io_Unit;
639 if((unit->flags & UNITF_CONFIGURED) != 0)
641 error = S2ERR_BAD_STATE;
642 wire_error = S2WERR_IS_CONFIGURED;
644 else if((unit->flags & UNITF_HAVEADAPTER) == 0)
646 error = S2ERR_BAD_STATE;
647 wire_error = S2WERR_GENERIC_ERROR;
650 if(error == 0)
652 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
653 ConfigureAdapter(unit, base);
654 GoOnline(unit, base);
655 unit->flags |= UNITF_CONFIGURED;
657 else
659 request->ios2_Req.io_Error = error;
660 request->ios2_WireError = wire_error;
663 /* Return */
665 return TRUE;
670 /****** realtek8180.device/S2_BROADCAST ************************************
672 * NAME
673 * S2_BROADCAST
675 * FUNCTION
677 * INPUTS
678 * io_Flags
679 * ios2_PacketType
680 * ios2_DataLength
681 * ios2_Data
683 * RESULTS
684 * io_Error
685 * ios2_WireError
687 * EXAMPLE
689 * NOTES
691 * BUGS
693 * SEE ALSO
695 ****************************************************************************
699 static BOOL CmdBroadcast(struct IOSana2Req *request,
700 struct DevBase *base)
702 UWORD i;
704 /* Fill in the broadcast address as destination */
706 for(i = 0; i < ETH_ADDRESSSIZE; i++)
707 request->ios2_DstAddr[i] = 0xff;
709 /* Queue the write as normal */
711 return CmdWrite(request, base);
716 /****** realtek8180.device/S2_TRACKTYPE ************************************
718 * NAME
719 * S2_TRACKTYPE
721 * FUNCTION
723 * INPUTS
724 * ios2_PacketType - packet type to start tracking.
726 * RESULTS
727 * io_Error
728 * ios2_WireError
730 * EXAMPLE
732 * NOTES
734 * BUGS
736 * SEE ALSO
738 ****************************************************************************
742 static BOOL CmdTrackType(struct IOSana2Req *request,
743 struct DevBase *base)
745 struct DevUnit *unit;
746 struct Opener *opener;
747 ULONG packet_type, wire_error;
748 struct TypeTracker *tracker;
749 struct TypeStats *initial_stats;
750 BYTE error = 0;
752 unit = (APTR)request->ios2_Req.io_Unit;
753 packet_type = request->ios2_PacketType;
754 if(packet_type <= ETH_MTU)
755 packet_type = ETH_MTU;
757 /* Get global tracker */
759 tracker = (struct TypeTracker *)
760 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
762 if(tracker != NULL)
763 tracker->user_count++;
764 else
766 tracker =
767 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
768 if(tracker != NULL)
770 tracker->packet_type = packet_type;
771 tracker->user_count = 1;
773 Disable();
774 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
775 Enable();
779 /* Store initial figures for this opener */
781 opener = request->ios2_BufferManagement;
782 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
783 base);
785 if(initial_stats != NULL)
787 error = S2ERR_BAD_STATE;
788 wire_error = S2WERR_ALREADY_TRACKED;
791 if(error == 0)
793 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
794 if(initial_stats == NULL)
796 error = S2ERR_NO_RESOURCES;
797 wire_error = S2WERR_GENERIC_ERROR;
801 if(error == 0)
803 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
804 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
807 /* Return */
809 request->ios2_Req.io_Error = error;
810 request->ios2_WireError = wire_error;
811 return TRUE;
816 /****** realtek8180.device/S2_UNTRACKTYPE **********************************
818 * NAME
819 * S2_UNTRACKTYPE
821 * FUNCTION
823 * INPUTS
824 * ios2_PacketType - packet type to stop tracking.
826 * RESULTS
827 * io_Error
828 * ios2_WireError
830 * EXAMPLE
832 * NOTES
834 * BUGS
836 * SEE ALSO
838 ****************************************************************************
842 static BOOL CmdUntrackType(struct IOSana2Req *request,
843 struct DevBase *base)
845 struct DevUnit *unit;
846 struct Opener *opener;
847 ULONG packet_type;
848 struct TypeTracker *tracker;
849 struct TypeStats *initial_stats;
851 unit = (APTR)request->ios2_Req.io_Unit;
852 packet_type = request->ios2_PacketType;
853 if(packet_type <= ETH_MTU)
854 packet_type = ETH_MTU;
856 /* Get global tracker and initial figures */
858 tracker = (struct TypeTracker *)
859 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
860 opener = request->ios2_BufferManagement;
861 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
862 base);
864 /* Decrement tracker usage and free unused structures */
866 if(initial_stats != NULL)
868 if((--tracker->user_count) == 0)
870 Disable();
871 Remove((APTR)tracker);
872 Enable();
873 FreeMem(tracker, sizeof(struct TypeTracker));
876 Remove((APTR)initial_stats);
877 FreeMem(initial_stats, sizeof(struct TypeStats));
879 else
881 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
882 request->ios2_WireError = S2WERR_NOT_TRACKED;
885 /* Return */
887 return TRUE;
892 /****** realtek8180.device/S2_GETTYPESTATS *********************************
894 * NAME
895 * S2_GETTYPESTATS
897 * FUNCTION
899 * INPUTS
900 * ios2_PacketType - packet type to get statistics on.
901 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
903 * RESULTS
904 * io_Error
905 * ios2_WireError
907 * EXAMPLE
909 * NOTES
911 * BUGS
913 * SEE ALSO
915 ****************************************************************************
919 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
920 struct DevBase *base)
922 struct DevUnit *unit;
923 struct Opener *opener;
924 ULONG packet_type;
925 struct TypeStats *initial_stats, *tracker;
926 struct Sana2PacketTypeStats *stats;
928 unit = (APTR)request->ios2_Req.io_Unit;
929 packet_type = request->ios2_PacketType;
931 /* Get global tracker and initial figures */
933 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
934 opener = request->ios2_BufferManagement;
935 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
936 base);
938 /* Copy and adjust figures */
940 if(initial_stats != NULL)
942 stats = request->ios2_StatData;
943 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
944 stats->PacketsSent -= initial_stats->stats.PacketsSent;
945 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
946 stats->BytesSent -= initial_stats->stats.BytesSent;
947 stats->BytesReceived -= initial_stats->stats.BytesReceived;
948 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
950 else
952 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
953 request->ios2_WireError = S2WERR_NOT_TRACKED;
956 /* Return */
958 return TRUE;
963 /****** realtek8180.device/S2_GETSPECIALSTATS ******************************
965 * NAME
966 * S2_GETSPECIALSTATS
968 * FUNCTION
970 * INPUTS
971 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
973 * RESULTS
974 * io_Error
975 * ios2_WireError
977 * EXAMPLE
979 * NOTES
981 * BUGS
983 * SEE ALSO
985 ****************************************************************************
989 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
990 struct DevBase *base)
992 struct DevUnit *unit;
993 UWORD i, stat_count;
994 struct Sana2SpecialStatHeader *header;
995 struct Sana2SpecialStatRecord *record;
997 /* Fill in stats */
999 unit = (APTR)request->ios2_Req.io_Unit;
1000 header = request->ios2_StatData;
1001 record = (APTR)(header + 1);
1003 stat_count = header->RecordCountMax;
1004 if(stat_count > STAT_COUNT)
1005 stat_count = STAT_COUNT;
1007 for(i = 0; i < stat_count; i++)
1009 record->Type = (S2WireType_Ethernet << 16) + i;
1010 record->Count = unit->special_stats[i];
1011 record->String = special_stat_names[i];
1012 record++;
1015 header->RecordCountSupplied = stat_count;
1017 /* Return */
1019 return TRUE;
1024 /****** realtek8180.device/S2_GETGLOBALSTATS *******************************
1026 * NAME
1027 * S2_GETGLOBALSTATS
1029 * FUNCTION
1031 * INPUTS
1032 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1034 * RESULTS
1035 * io_Error
1036 * ios2_WireError
1038 * EXAMPLE
1040 * NOTES
1042 * BUGS
1044 * SEE ALSO
1046 ****************************************************************************
1050 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
1051 struct DevBase *base)
1053 struct DevUnit *unit;
1055 /* Copy stats */
1057 unit = (APTR)request->ios2_Req.io_Unit;
1058 CopyMem(&unit->stats, request->ios2_StatData,
1059 sizeof(struct Sana2DeviceStats));
1061 /* Return */
1063 return TRUE;
1068 /****** realtek8180.device/S2_ONEVENT **************************************
1070 * NAME
1071 * S2_ONEVENT
1073 * FUNCTION
1075 * INPUTS
1076 * ios2_WireError
1078 * RESULTS
1079 * io_Error
1080 * ios2_WireError
1082 * EXAMPLE
1084 * NOTES
1086 * BUGS
1088 * SEE ALSO
1090 ****************************************************************************
1094 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1096 struct DevUnit *unit;
1097 ULONG events, wanted_events;
1098 BOOL complete = FALSE;
1100 /* Check if we understand the event types */
1102 unit = (APTR)request->ios2_Req.io_Unit;
1103 wanted_events = request->ios2_WireError;
1104 if((wanted_events & ~KNOWN_EVENTS) != 0)
1106 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1107 events = S2WERR_BAD_EVENT;
1109 else
1111 if((unit->flags & UNITF_ONLINE) != 0)
1112 events = S2EVENT_ONLINE;
1113 else
1114 events = S2EVENT_OFFLINE;
1116 events &= wanted_events;
1119 /* Reply request if a wanted event has already occurred */
1121 if(events != 0)
1123 request->ios2_WireError = events;
1124 complete = TRUE;
1126 else
1127 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1129 /* Return */
1131 return complete;
1136 /****** realtek8180.device/S2_READORPHAN ***********************************
1138 * NAME
1139 * S2_READORPHAN
1141 * FUNCTION
1143 * INPUTS
1144 * io_Flags
1145 * ios2_Data
1147 * RESULTS
1148 * io_Flags
1149 * io_Error
1150 * ios2_WireError
1151 * ios2_PacketType - A copy of the packet's type field.
1152 * ios2_SrcAddr
1153 * ios2_DstAddr
1154 * ios2_DataLength
1155 * ios2_Data
1158 * EXAMPLE
1160 * NOTES
1162 * BUGS
1164 * SEE ALSO
1166 ****************************************************************************
1170 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1171 struct DevBase *base)
1173 struct DevUnit *unit;
1174 BYTE error = 0;
1175 ULONG wire_error;
1176 BOOL complete = FALSE;
1178 /* Check request is valid */
1180 unit = (APTR)request->ios2_Req.io_Unit;
1181 if((unit->flags & UNITF_ONLINE) == 0)
1183 error = S2ERR_OUTOFSERVICE;
1184 wire_error = S2WERR_UNIT_OFFLINE;
1187 /* Queue request */
1189 if(error == 0)
1190 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1191 else
1193 request->ios2_Req.io_Error = error;
1194 request->ios2_WireError = wire_error;
1195 complete = TRUE;
1198 /* Return */
1200 return complete;
1205 /****** realtek8180.device/S2_ONLINE ***************************************
1207 * NAME
1208 * S2_ONLINE
1210 * FUNCTION
1212 * INPUTS
1213 * None.
1215 * RESULTS
1216 * io_Error
1217 * ios2_WireError
1219 * EXAMPLE
1221 * NOTES
1223 * BUGS
1225 * SEE ALSO
1227 ****************************************************************************
1231 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1233 struct DevUnit *unit;
1234 BYTE error = 0;
1235 ULONG wire_error;
1236 UWORD i;
1238 /* Check request is valid */
1240 unit = (APTR)request->ios2_Req.io_Unit;
1241 if((unit->flags & UNITF_CONFIGURED) == 0)
1243 error = S2ERR_BAD_STATE;
1244 wire_error = S2WERR_NOT_CONFIGURED;
1246 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1248 error = S2ERR_OUTOFSERVICE;
1249 wire_error = S2WERR_RCVREL_HDW_ERR;
1252 /* Clear global and special stats and put adapter back online */
1254 if((error == 0) && ((unit->flags & UNITF_ONLINE) == 0))
1256 unit->stats.PacketsReceived = 0;
1257 unit->stats.PacketsSent = 0;
1258 unit->stats.BadData = 0;
1259 unit->stats.Overruns = 0;
1260 unit->stats.UnknownTypesReceived = 0;
1261 unit->stats.Reconfigurations = 0;
1263 for(i = 0; i < STAT_COUNT; i++)
1264 unit->special_stats[i] = 0;
1266 GoOnline(unit, base);
1269 /* Return */
1271 request->ios2_Req.io_Error = error;
1272 request->ios2_WireError = wire_error;
1273 return TRUE;
1278 /****** realtek8180.device/S2_OFFLINE **************************************
1280 * NAME
1281 * S2_OFFLINE
1283 * FUNCTION
1285 * INPUTS
1286 * None.
1288 * RESULTS
1289 * io_Error
1290 * ios2_WireError
1292 * EXAMPLE
1294 * NOTES
1296 * BUGS
1298 * SEE ALSO
1300 ****************************************************************************
1304 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1306 struct DevUnit *unit;
1308 /* Put adapter offline */
1310 unit = (APTR)request->ios2_Req.io_Unit;
1311 if((unit->flags & UNITF_ONLINE) != 0)
1312 GoOffline(unit, base);
1314 /* Return */
1316 return TRUE;
1321 /****** realtek8180.device/NSCMD_DEVICEQUERY *******************************
1323 * NAME
1324 * NSCMD_DEVICEQUERY -- Query device capabilities.
1326 * FUNCTION
1328 * INPUTS
1329 * io_Length - ???.
1330 * io_Data - pointer to NSDeviceQueryResult structure.
1332 * RESULTS
1333 * io_Error
1334 * io_Actual - size of structure device can handle.
1336 * EXAMPLE
1338 * NOTES
1340 * BUGS
1342 * SEE ALSO
1344 ****************************************************************************
1346 * Note that we have to pretend the request structure is an IOStdReq.
1350 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1351 struct DevBase *base)
1353 struct NSDeviceQueryResult *info;
1355 /* Set structure size twice */
1357 info = request->io_Data;
1358 request->io_Actual = info->SizeAvailable =
1359 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1361 /* Report device details */
1363 info->DeviceType = NSDEVTYPE_SANA2;
1364 info->DeviceSubType = 0;
1366 info->SupportedCommands = (APTR)supported_commands;
1368 /* Return */
1370 return TRUE;
1375 /****** realtek8180.device/S2_ADDMULTICASTADDRESS **************************
1377 * NAME
1378 * S2_ADDMULTICASTADDRESS
1380 * FUNCTION
1382 * INPUTS
1383 * ios2_SrcAddr - multicast address.
1385 * RESULTS
1386 * io_Error
1387 * ios2_WireError
1389 * EXAMPLE
1391 * NOTES
1393 * BUGS
1395 * SEE ALSO
1397 ****************************************************************************
1401 /****** realtek8180.device/S2_ADDMULTICASTADDRESSES ************************
1403 * NAME
1404 * S2_ADDMULTICASTADDRESSES
1406 * FUNCTION
1408 * INPUTS
1409 * ios2_SrcAddr - lower bound.
1410 * ios2_DstAddr - upper bound.
1412 * RESULTS
1413 * io_Error
1414 * ios2_WireError
1416 * EXAMPLE
1418 * NOTES
1420 * BUGS
1422 * SEE ALSO
1424 ****************************************************************************
1428 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1429 struct DevBase *base)
1431 struct DevUnit *unit;
1432 UBYTE *lower_bound, *upper_bound;
1434 unit = (APTR)request->ios2_Req.io_Unit;
1436 lower_bound = request->ios2_SrcAddr;
1437 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1438 upper_bound = lower_bound;
1439 else
1440 upper_bound = request->ios2_DstAddr;
1442 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1444 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1445 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1448 /* Return */
1450 return TRUE;
1455 /****** realtek8180.device/S2_DELMULTICASTADDRESS **************************
1457 * NAME
1458 * S2_DELMULTICASTADDRESS
1460 * FUNCTION
1462 * INPUTS
1463 * ios2_SrcAddr - multicast address.
1465 * RESULTS
1466 * io_Error
1467 * ios2_WireError
1469 * EXAMPLE
1471 * NOTES
1473 * BUGS
1475 * SEE ALSO
1477 ****************************************************************************
1481 /****** realtek8180.device/S2_DELMULTICASTADDRESSES ************************
1483 * NAME
1484 * S2_DELMULTICASTADDRESSES
1486 * FUNCTION
1488 * INPUTS
1489 * ios2_SrcAddr - lower bound.
1490 * ios2_DstAddr - upper bound.
1492 * RESULTS
1493 * io_Error
1494 * ios2_WireError
1496 * EXAMPLE
1498 * NOTES
1500 * BUGS
1502 * SEE ALSO
1504 ****************************************************************************
1508 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1509 struct DevBase *base)
1511 struct DevUnit *unit;
1512 UBYTE *lower_bound, *upper_bound;
1514 unit = (APTR)request->ios2_Req.io_Unit;
1516 lower_bound = request->ios2_SrcAddr;
1517 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1518 upper_bound = lower_bound;
1519 else
1520 upper_bound = request->ios2_DstAddr;
1522 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1524 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1525 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1528 /* Return */
1530 return TRUE;
1535 /****** realtek8180.device/S2_SETOPTIONS ***********************************
1537 * NAME
1538 * S2_SETOPTIONS -- Set network options.
1540 * FUNCTION
1541 * Set various parameters for the network interface. This command
1542 * should be called before going online to set any essential parameters
1543 * not covered elsewhere.
1545 * INPUTS
1546 * ios2_Data - Pointer to taglist that specifies the network and
1547 * parameters to use.
1549 * RESULTS
1550 * io_Error - Zero if successful; non-zero otherwise.
1551 * ios2_WireError - More specific error code.
1553 ****************************************************************************
1557 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base)
1559 struct DevUnit *unit;
1560 BOOL reconfigure;
1562 /* */
1564 unit = (APTR)request->ios2_Req.io_Unit;
1565 reconfigure = SetOptions(unit, request->ios2_Data, base);
1566 if(reconfigure && (unit->flags & UNITF_ONLINE) != 0)
1567 ConfigureAdapter(unit, base);
1568 unit->stats.Reconfigurations++;
1570 /* Return */
1572 return TRUE;
1577 /****** realtek8180.device/S2_SETKEY ***************************************
1579 * NAME
1580 * S2_SETKEY -- Set an encryption key.
1582 * FUNCTION
1584 * INPUTS
1585 * ios2_WireError - Key index.
1586 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1587 * ios2_DataLength - Key length.
1588 * ios2_Data - Key.
1589 * ios2_StatData - RX counter number (NULL if unused).
1591 * RESULTS
1592 * io_Error
1594 * EXAMPLE
1596 * NOTES
1598 * BUGS
1600 * SEE ALSO
1602 ****************************************************************************
1606 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base)
1608 struct DevUnit *unit;
1610 unit = (APTR)request->ios2_Req.io_Unit;
1611 SetKey(unit, request->ios2_WireError, request->ios2_PacketType,
1612 request->ios2_Data, request->ios2_DataLength, request->ios2_StatData,
1613 base);
1615 /* Return */
1617 return TRUE;
1622 /****** realtek8180.device/S2_WRITEMGMT ************************************
1624 * NAME
1625 * S2_WRITEMGMT -- Write a management frame.
1627 * FUNCTION
1629 * INPUTS
1630 * ios2_DataLength - full frame length.
1631 * ios2_Data - pointer to a complete IEEE 802.11 management frame.
1633 * RESULTS
1634 * io_Error
1635 * ios2_WireError
1637 * EXAMPLE
1639 * NOTES
1641 * BUGS
1643 * SEE ALSO
1645 ****************************************************************************
1649 static BOOL CmdWriteMgmt(struct IOSana2Req *request, struct DevBase *base)
1651 struct DevUnit *unit;
1652 BYTE error = 0;
1653 ULONG wire_error;
1654 BOOL complete = FALSE;
1656 /* Check request is valid */
1658 unit = (APTR)request->ios2_Req.io_Unit;
1659 if((unit->flags & UNITF_ONLINE) == 0)
1661 error = S2ERR_OUTOFSERVICE;
1662 wire_error = S2WERR_UNIT_OFFLINE;
1665 /* Queue request for sending */
1667 if(error == 0)
1668 PutRequest(unit->request_ports[MGMT_QUEUE], (APTR)request, base);
1669 else
1671 request->ios2_Req.io_Error = error;
1672 request->ios2_WireError = wire_error;
1673 complete = TRUE;
1676 /* Return */
1678 return complete;
1683 /****** realtek8180.device/S2_READMGMT *************************************
1685 * NAME
1686 * S2_READMGMT -- Read a management frame.
1688 * FUNCTION
1690 * INPUTS
1691 * ios2_DataLength - size of frame buffer.
1692 * ios2_Data - pointer to a frame buffer.
1694 * RESULTS
1695 * io_Error
1696 * ios2_WireError
1697 * ios2_DataLength - actual size of received frame.
1698 * ios2_Data
1700 * EXAMPLE
1702 * NOTES
1704 * BUGS
1706 * SEE ALSO
1708 ****************************************************************************
1712 static BOOL CmdReadMgmt(struct IOSana2Req *request, struct DevBase *base)
1714 struct DevUnit *unit;
1715 struct Opener *opener;
1716 BOOL complete = FALSE;
1718 unit = (APTR)request->ios2_Req.io_Unit;
1720 if((unit->flags & UNITF_ONLINE) != 0)
1722 opener = request->ios2_BufferManagement;
1723 PutRequest(&opener->mgmt_port, (APTR)request, base);
1725 else
1727 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1728 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1729 complete = TRUE;
1732 /* Return */
1734 return complete;
1739 /****i* realtek8180.device/PutRequest **************************************
1741 * NAME
1742 * PutRequest
1744 * SYNOPSIS
1745 * PutRequest(port, request)
1747 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1749 * FUNCTION
1751 * INPUTS
1752 * port
1753 * request
1755 * RESULT
1756 * None.
1758 ****************************************************************************
1762 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1763 struct DevBase *base)
1765 request->io_Flags &= ~IOF_QUICK;
1766 PutMsg(port, (APTR)request);
1768 return;