revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / atheros5000 / request.c
blob2b23452562d8cb5105e16197948e40dd49f09f51
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* atheros5000.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* atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /****** atheros5000.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 /* Update and copy stats */
1057 unit = (APTR)request->ios2_Req.io_Unit;
1058 if((unit->flags & UNITF_ONLINE) != 0)
1059 UpdateStats(unit, base);
1060 CopyMem(&unit->stats, request->ios2_StatData,
1061 sizeof(struct Sana2DeviceStats));
1063 /* Return */
1065 return TRUE;
1070 /****** atheros5000.device/S2_ONEVENT **************************************
1072 * NAME
1073 * S2_ONEVENT
1075 * FUNCTION
1077 * INPUTS
1078 * ios2_WireError
1080 * RESULTS
1081 * io_Error
1082 * ios2_WireError
1084 * EXAMPLE
1086 * NOTES
1088 * BUGS
1090 * SEE ALSO
1092 ****************************************************************************
1096 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1098 struct DevUnit *unit;
1099 ULONG events, wanted_events;
1100 BOOL complete = FALSE;
1102 /* Check if we understand the event types */
1104 unit = (APTR)request->ios2_Req.io_Unit;
1105 wanted_events = request->ios2_WireError;
1106 if((wanted_events & ~KNOWN_EVENTS) != 0)
1108 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1109 events = S2WERR_BAD_EVENT;
1111 else
1113 if((unit->flags & UNITF_ONLINE) != 0)
1114 events = S2EVENT_ONLINE;
1115 else
1116 events = S2EVENT_OFFLINE;
1118 events &= wanted_events;
1121 /* Reply request if a wanted event has already occurred */
1123 if(events != 0)
1125 request->ios2_WireError = events;
1126 complete = TRUE;
1128 else
1129 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1131 /* Return */
1133 return complete;
1138 /****** atheros5000.device/S2_READORPHAN ***********************************
1140 * NAME
1141 * S2_READORPHAN
1143 * FUNCTION
1145 * INPUTS
1146 * io_Flags
1147 * ios2_Data
1149 * RESULTS
1150 * io_Flags
1151 * io_Error
1152 * ios2_WireError
1153 * ios2_PacketType - A copy of the packet's type field.
1154 * ios2_SrcAddr
1155 * ios2_DstAddr
1156 * ios2_DataLength
1157 * ios2_Data
1160 * EXAMPLE
1162 * NOTES
1164 * BUGS
1166 * SEE ALSO
1168 ****************************************************************************
1172 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1173 struct DevBase *base)
1175 struct DevUnit *unit;
1176 BYTE error = 0;
1177 ULONG wire_error;
1178 BOOL complete = FALSE;
1180 /* Check request is valid */
1182 unit = (APTR)request->ios2_Req.io_Unit;
1183 if((unit->flags & UNITF_ONLINE) == 0)
1185 error = S2ERR_OUTOFSERVICE;
1186 wire_error = S2WERR_UNIT_OFFLINE;
1189 /* Queue request */
1191 if(error == 0)
1192 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1193 else
1195 request->ios2_Req.io_Error = error;
1196 request->ios2_WireError = wire_error;
1197 complete = TRUE;
1200 /* Return */
1202 return complete;
1207 /****** atheros5000.device/S2_ONLINE ***************************************
1209 * NAME
1210 * S2_ONLINE
1212 * FUNCTION
1214 * INPUTS
1215 * None.
1217 * RESULTS
1218 * io_Error
1219 * ios2_WireError
1221 * EXAMPLE
1223 * NOTES
1225 * BUGS
1227 * SEE ALSO
1229 ****************************************************************************
1233 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1235 struct DevUnit *unit;
1236 BYTE error = 0;
1237 ULONG wire_error;
1238 UWORD i;
1240 /* Check request is valid */
1242 unit = (APTR)request->ios2_Req.io_Unit;
1243 if((unit->flags & UNITF_CONFIGURED) == 0)
1245 error = S2ERR_BAD_STATE;
1246 wire_error = S2WERR_NOT_CONFIGURED;
1248 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1250 error = S2ERR_OUTOFSERVICE;
1251 wire_error = S2WERR_RCVREL_HDW_ERR;
1254 /* Clear global and special stats and put adapter back online */
1256 if((error == 0) && ((unit->flags & UNITF_ONLINE) == 0))
1258 unit->stats.PacketsReceived = 0;
1259 unit->stats.PacketsSent = 0;
1260 unit->stats.BadData = 0;
1261 unit->stats.Overruns = 0;
1262 unit->stats.UnknownTypesReceived = 0;
1263 unit->stats.Reconfigurations = 0;
1265 for(i = 0; i < STAT_COUNT; i++)
1266 unit->special_stats[i] = 0;
1268 GoOnline(unit, base);
1271 /* Return */
1273 request->ios2_Req.io_Error = error;
1274 request->ios2_WireError = wire_error;
1275 return TRUE;
1280 /****** atheros5000.device/S2_OFFLINE **************************************
1282 * NAME
1283 * S2_OFFLINE
1285 * FUNCTION
1287 * INPUTS
1288 * None.
1290 * RESULTS
1291 * io_Error
1292 * ios2_WireError
1294 * EXAMPLE
1296 * NOTES
1298 * BUGS
1300 * SEE ALSO
1302 ****************************************************************************
1306 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1308 struct DevUnit *unit;
1310 /* Put adapter offline */
1312 unit = (APTR)request->ios2_Req.io_Unit;
1313 if((unit->flags & UNITF_ONLINE) != 0)
1314 GoOffline(unit, base);
1316 /* Return */
1318 return TRUE;
1323 /****** atheros5000.device/NSCMD_DEVICEQUERY *******************************
1325 * NAME
1326 * NSCMD_DEVICEQUERY -- Query device capabilities.
1328 * FUNCTION
1330 * INPUTS
1331 * io_Length - ???.
1332 * io_Data - pointer to NSDeviceQueryResult structure.
1334 * RESULTS
1335 * io_Error
1336 * io_Actual - size of structure device can handle.
1338 * EXAMPLE
1340 * NOTES
1342 * BUGS
1344 * SEE ALSO
1346 ****************************************************************************
1348 * Note that we have to pretend the request structure is an IOStdReq.
1352 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1353 struct DevBase *base)
1355 struct NSDeviceQueryResult *info;
1357 /* Set structure size twice */
1359 info = request->io_Data;
1360 request->io_Actual = info->SizeAvailable =
1361 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1363 /* Report device details */
1365 info->DeviceType = NSDEVTYPE_SANA2;
1366 info->DeviceSubType = 0;
1368 info->SupportedCommands = (APTR)supported_commands;
1370 /* Return */
1372 return TRUE;
1377 /****** atheros5000.device/S2_ADDMULTICASTADDRESS **************************
1379 * NAME
1380 * S2_ADDMULTICASTADDRESS
1382 * FUNCTION
1384 * INPUTS
1385 * ios2_SrcAddr - multicast address.
1387 * RESULTS
1388 * io_Error
1389 * ios2_WireError
1391 * EXAMPLE
1393 * NOTES
1395 * BUGS
1397 * SEE ALSO
1399 ****************************************************************************
1403 /****** atheros5000.device/S2_ADDMULTICASTADDRESSES ************************
1405 * NAME
1406 * S2_ADDMULTICASTADDRESSES
1408 * FUNCTION
1410 * INPUTS
1411 * ios2_SrcAddr - lower bound.
1412 * ios2_DstAddr - upper bound.
1414 * RESULTS
1415 * io_Error
1416 * ios2_WireError
1418 * EXAMPLE
1420 * NOTES
1422 * BUGS
1424 * SEE ALSO
1426 ****************************************************************************
1430 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1431 struct DevBase *base)
1433 struct DevUnit *unit;
1434 UBYTE *lower_bound, *upper_bound;
1436 unit = (APTR)request->ios2_Req.io_Unit;
1438 lower_bound = request->ios2_SrcAddr;
1439 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1440 upper_bound = lower_bound;
1441 else
1442 upper_bound = request->ios2_DstAddr;
1444 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1446 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1447 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1450 /* Return */
1452 return TRUE;
1457 /****** atheros5000.device/S2_DELMULTICASTADDRESS **************************
1459 * NAME
1460 * S2_DELMULTICASTADDRESS
1462 * FUNCTION
1464 * INPUTS
1465 * ios2_SrcAddr - multicast address.
1467 * RESULTS
1468 * io_Error
1469 * ios2_WireError
1471 * EXAMPLE
1473 * NOTES
1475 * BUGS
1477 * SEE ALSO
1479 ****************************************************************************
1483 /****** atheros5000.device/S2_DELMULTICASTADDRESSES ************************
1485 * NAME
1486 * S2_DELMULTICASTADDRESSES
1488 * FUNCTION
1490 * INPUTS
1491 * ios2_SrcAddr - lower bound.
1492 * ios2_DstAddr - upper bound.
1494 * RESULTS
1495 * io_Error
1496 * ios2_WireError
1498 * EXAMPLE
1500 * NOTES
1502 * BUGS
1504 * SEE ALSO
1506 ****************************************************************************
1510 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1511 struct DevBase *base)
1513 struct DevUnit *unit;
1514 UBYTE *lower_bound, *upper_bound;
1516 unit = (APTR)request->ios2_Req.io_Unit;
1518 lower_bound = request->ios2_SrcAddr;
1519 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1520 upper_bound = lower_bound;
1521 else
1522 upper_bound = request->ios2_DstAddr;
1524 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1526 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1527 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1530 /* Return */
1532 return TRUE;
1537 /****** atheros5000.device/S2_SETOPTIONS ***********************************
1539 * NAME
1540 * S2_SETOPTIONS -- Set network options.
1542 * FUNCTION
1543 * Set various parameters for the network interface. This command
1544 * should be called before going online to set any essential parameters
1545 * not covered elsewhere.
1547 * INPUTS
1548 * ios2_Data - Pointer to taglist that specifies the network and
1549 * parameters to use.
1551 * RESULTS
1552 * io_Error - Zero if successful; non-zero otherwise.
1553 * ios2_WireError - More specific error code.
1555 ****************************************************************************
1559 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base)
1561 struct DevUnit *unit;
1562 BOOL reconfigure;
1564 /* */
1566 unit = (APTR)request->ios2_Req.io_Unit;
1567 reconfigure = SetOptions(unit, request->ios2_Data, base);
1568 if(reconfigure && (unit->flags & UNITF_ONLINE) != 0)
1569 ConfigureAdapter(unit, base);
1570 unit->stats.Reconfigurations++;
1572 /* Return */
1574 return TRUE;
1579 /****** atheros5000.device/S2_SETKEY ***************************************
1581 * NAME
1582 * S2_SETKEY -- Set an encryption key.
1584 * FUNCTION
1586 * INPUTS
1587 * ios2_WireError - Key index.
1588 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1589 * ios2_DataLength - Key length.
1590 * ios2_Data - Key.
1591 * ios2_StatData - RX counter number (NULL if unused).
1593 * RESULTS
1594 * io_Error
1596 * EXAMPLE
1598 * NOTES
1600 * BUGS
1602 * SEE ALSO
1604 ****************************************************************************
1608 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base)
1610 struct DevUnit *unit;
1612 unit = (APTR)request->ios2_Req.io_Unit;
1613 SetKey(unit, request->ios2_WireError, request->ios2_PacketType,
1614 request->ios2_Data, request->ios2_DataLength, request->ios2_StatData,
1615 base);
1617 /* Return */
1619 return TRUE;
1624 /****** atheros5000.device/S2_WRITEMGMT ************************************
1626 * NAME
1627 * S2_WRITEMGMT -- Write a management frame.
1629 * FUNCTION
1631 * INPUTS
1632 * ios2_DataLength - full frame length.
1633 * ios2_Data - pointer to a complete IEEE 802.11 management frame.
1635 * RESULTS
1636 * io_Error
1637 * ios2_WireError
1639 * EXAMPLE
1641 * NOTES
1643 * BUGS
1645 * SEE ALSO
1647 ****************************************************************************
1651 static BOOL CmdWriteMgmt(struct IOSana2Req *request, struct DevBase *base)
1653 struct DevUnit *unit;
1654 BYTE error = 0;
1655 ULONG wire_error;
1656 BOOL complete = FALSE;
1658 /* Check request is valid */
1660 unit = (APTR)request->ios2_Req.io_Unit;
1661 if((unit->flags & UNITF_ONLINE) == 0)
1663 error = S2ERR_OUTOFSERVICE;
1664 wire_error = S2WERR_UNIT_OFFLINE;
1667 /* Queue request for sending */
1669 if(error == 0)
1670 PutRequest(unit->request_ports[MGMT_QUEUE], (APTR)request, base);
1671 else
1673 request->ios2_Req.io_Error = error;
1674 request->ios2_WireError = wire_error;
1675 complete = TRUE;
1678 /* Return */
1680 return complete;
1685 /****** atheros5000.device/S2_READMGMT *************************************
1687 * NAME
1688 * S2_READMGMT -- Read a management frame.
1690 * FUNCTION
1692 * INPUTS
1693 * ios2_DataLength - size of frame buffer.
1694 * ios2_Data - pointer to a frame buffer.
1696 * RESULTS
1697 * io_Error
1698 * ios2_WireError
1699 * ios2_DataLength - actual size of received frame.
1700 * ios2_Data
1702 * EXAMPLE
1704 * NOTES
1706 * BUGS
1708 * SEE ALSO
1710 ****************************************************************************
1714 static BOOL CmdReadMgmt(struct IOSana2Req *request, struct DevBase *base)
1716 struct DevUnit *unit;
1717 struct Opener *opener;
1718 BOOL complete = FALSE;
1720 unit = (APTR)request->ios2_Req.io_Unit;
1722 if((unit->flags & UNITF_ONLINE) != 0)
1724 opener = request->ios2_BufferManagement;
1725 PutRequest(&opener->mgmt_port, (APTR)request, base);
1727 else
1729 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1730 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1731 complete = TRUE;
1734 /* Return */
1736 return complete;
1741 /****i* atheros5000.device/PutRequest **************************************
1743 * NAME
1744 * PutRequest
1746 * SYNOPSIS
1747 * PutRequest(port, request)
1749 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1751 * FUNCTION
1753 * INPUTS
1754 * port
1755 * request
1757 * RESULT
1758 * None.
1760 ****************************************************************************
1764 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1765 struct DevBase *base)
1767 request->io_Flags &= ~IOF_QUICK;
1768 PutMsg(port, (APTR)request);
1770 return;