revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / prism2 / request.c
bloba75f32555cb77d316c06aee2361b28ceb3c58648
1 /*
3 Copyright (C) 2001-2013 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 | S2EVENT_DISCONNECT)
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);
47 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
48 struct DevBase *base);
49 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
50 struct DevBase *base);
51 static BOOL CmdConfigInterface(struct IOSana2Req *request,
52 struct DevBase *base);
53 static BOOL CmdBroadcast(struct IOSana2Req *request,
54 struct DevBase *base);
55 static BOOL CmdTrackType(struct IOSana2Req *request,
56 struct DevBase *base);
57 static BOOL CmdUntrackType(struct IOSana2Req *request,
58 struct DevBase *base);
59 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
60 struct DevBase *base);
61 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
62 struct DevBase *base);
63 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
64 struct DevBase *base);
65 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base);
66 static BOOL CmdReadOrphan(struct IOSana2Req *request,
67 struct DevBase *base);
68 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base);
69 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base);
70 static BOOL CmdDeviceQuery(struct IOStdReq *request,
71 struct DevBase *base);
72 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
73 struct DevBase *base);
74 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
75 struct DevBase *base);
76 static BOOL CmdGetSignalQuality(struct IOSana2Req *request,
77 struct DevBase *base);
78 static BOOL CmdGetNetworks(struct IOSana2Req *request,
79 struct DevBase *base);
80 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base);
81 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base);
82 static BOOL CmdGetNetworkInfo(struct IOSana2Req *request,
83 struct DevBase *base);
84 static BOOL CmdGetCryptTypes(struct IOSana2Req *request,
85 struct DevBase *base);
88 static const UWORD supported_commands[] =
90 CMD_READ,
91 CMD_WRITE,
92 CMD_FLUSH,
93 S2_DEVICEQUERY,
94 S2_GETSTATIONADDRESS,
95 S2_CONFIGINTERFACE,
96 S2_ADDMULTICASTADDRESS,
97 S2_DELMULTICASTADDRESS,
98 S2_MULTICAST,
99 S2_BROADCAST,
100 S2_TRACKTYPE,
101 S2_UNTRACKTYPE,
102 S2_GETTYPESTATS,
103 S2_GETSPECIALSTATS,
104 S2_GETGLOBALSTATS,
105 S2_ONEVENT,
106 S2_READORPHAN,
107 S2_ONLINE,
108 S2_OFFLINE,
109 NSCMD_DEVICEQUERY,
110 S2_ADDMULTICASTADDRESSES,
111 S2_DELMULTICASTADDRESSES,
112 S2_GETSIGNALQUALITY,
113 S2_GETNETWORKS,
114 S2_SETOPTIONS,
115 S2_SETKEY,
116 S2_GETNETWORKINFO,
117 S2_GETCRYPTTYPES,
122 static const struct Sana2DeviceQuery sana2_info =
128 ETH_ADDRESSSIZE * 8,
129 ETH_MTU,
131 S2WireType_Ethernet
135 const TEXT badmulticast_name[] = "Bad multicasts";
136 const TEXT retries_name[] = "Retries";
137 const TEXT fifo_underruns_name[] = "Underruns";
140 const TEXT *const special_stat_names[] =
142 badmulticast_name,
143 retries_name,
144 fifo_underruns_name
149 /****i* prism2.device/ServiceRequest ***************************************
151 * NAME
152 * ServiceRequest -- Attempt to service a device request.
154 * SYNOPSIS
155 * ServiceRequest(request)
157 * VOID ServiceRequest(struct IORequest *);
159 * FUNCTION
160 * Attempts to carry out a request. The relevant unit's semaphore must
161 * be obtained before calling this function. This function releases the
162 * semaphore before returning.
164 * INPUTS
165 * request
167 * RESULT
168 * None.
170 * EXAMPLE
172 * NOTES
174 * BUGS
176 * SEE ALSO
178 ****************************************************************************
182 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
184 BOOL complete;
186 switch(request->ios2_Req.io_Command)
188 case CMD_READ:
189 complete = CmdRead(request, base);
190 break;
191 case CMD_WRITE:
192 complete = CmdWrite(request, base);
193 break;
194 case CMD_FLUSH:
195 complete = CmdFlush((APTR)request, base);
196 break;
197 case S2_DEVICEQUERY:
198 complete = CmdS2DeviceQuery(request, base);
199 break;
200 case S2_GETSTATIONADDRESS:
201 complete = CmdGetStationAddress(request, base);
202 break;
203 case S2_CONFIGINTERFACE:
204 complete = CmdConfigInterface(request, base);
205 break;
206 case S2_ADDMULTICASTADDRESS:
207 complete = CmdAddMulticastAddresses(request, base);
208 break;
209 case S2_DELMULTICASTADDRESS:
210 complete = CmdDelMulticastAddresses(request, base);
211 break;
212 case S2_MULTICAST:
213 complete = CmdWrite(request, base);
214 break;
215 case S2_BROADCAST:
216 complete = CmdBroadcast(request, base);
217 break;
218 case S2_TRACKTYPE:
219 complete = CmdTrackType(request, base);
220 break;
221 case S2_UNTRACKTYPE:
222 complete = CmdUntrackType(request, base);
223 break;
224 case S2_GETTYPESTATS:
225 complete = CmdGetTypeStats(request, base);
226 break;
227 case S2_GETSPECIALSTATS:
228 complete = CmdGetSpecialStats(request, base);
229 break;
230 case S2_GETGLOBALSTATS:
231 complete = CmdGetGlobalStats(request, base);
232 break;
233 case S2_ONEVENT:
234 complete = CmdOnEvent(request, base);
235 break;
236 case S2_READORPHAN:
237 complete = CmdReadOrphan(request, base);
238 break;
239 case S2_ONLINE:
240 complete = CmdOnline(request, base);
241 break;
242 case S2_OFFLINE:
243 complete = CmdOffline(request, base);
244 break;
245 case NSCMD_DEVICEQUERY:
246 complete = CmdDeviceQuery((APTR)request, base);
247 break;
248 case S2_ADDMULTICASTADDRESSES:
249 complete = CmdAddMulticastAddresses(request, base);
250 break;
251 case S2_DELMULTICASTADDRESSES:
252 complete = CmdDelMulticastAddresses(request, base);
253 break;
254 case S2_GETSIGNALQUALITY:
255 complete = CmdGetSignalQuality(request, base);
256 break;
257 case S2_GETNETWORKS:
258 complete = CmdGetNetworks(request, base);
259 break;
260 case S2_SETOPTIONS:
261 complete = CmdSetOptions(request, base);
262 break;
263 case S2_SETKEY:
264 complete = CmdSetKey(request, base);
265 break;
266 case S2_GETNETWORKINFO:
267 complete = CmdGetNetworkInfo(request, base);
268 break;
269 case S2_GETCRYPTTYPES:
270 complete = CmdGetCryptTypes(request, base);
271 break;
272 default:
273 complete = CmdInvalid(request, base);
276 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
277 ReplyMsg((APTR)request);
279 ReleaseSemaphore(
280 &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock);
281 return;
286 /****i* prism2.device/CMD_INVALID ******************************************
288 * NAME
289 * CMD_INVALID -- Reject an invalid command.
291 * FUNCTION
293 * INPUTS
294 * None.
296 * RESULTS
297 * io_Error - IOERR_NOCMD.
299 * EXAMPLE
301 * NOTES
303 * BUGS
305 * SEE ALSO
307 ****************************************************************************
311 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
313 request->ios2_Req.io_Error = IOERR_NOCMD;
314 request->ios2_WireError = S2WERR_GENERIC_ERROR;
316 return TRUE;
321 /****** prism2.device/CMD_READ *********************************************
323 * NAME
324 * CMD_READ -- Read data.
326 * FUNCTION
328 * INPUTS
329 * io_Flags
330 * ios2_PacketType
331 * ios2_Data
333 * RESULTS
334 * io_Flags
335 * io_Error
336 * ios2_WireError
337 * ios2_SrcAddr
338 * ios2_DstAddr
339 * ios2_DataLength
340 * ios2_Data
342 * EXAMPLE
344 * NOTES
346 * BUGS
348 * SEE ALSO
350 ****************************************************************************
354 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
356 struct DevUnit *unit;
357 struct Opener *opener;
358 BOOL complete = FALSE;
360 unit = (APTR)request->ios2_Req.io_Unit;
362 if((unit->flags & UNITF_ONLINE) != 0)
364 opener = request->ios2_BufferManagement;
365 PutRequest(&opener->read_port, (APTR)request, base);
367 else
369 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
370 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
371 complete = TRUE;
374 /* Return */
376 return complete;
381 /****** prism2.device/CMD_WRITE ********************************************
383 * NAME
384 * CMD_WRITE -- Write data.
386 * FUNCTION
388 * INPUTS
389 * io_Flags
390 * ios2_DstAddr
391 * ios2_PacketType
392 * ios2_DataLength
393 * ios2_Data
395 * RESULTS
396 * io_Error
397 * ios2_WireError
399 * EXAMPLE
401 * NOTES
403 * BUGS
405 * SEE ALSO
407 ****************************************************************************
411 /****** prism2.device/S2_MULTICAST *****************************************
413 * NAME
414 * S2_MULTICAST
416 * FUNCTION
418 * INPUTS
419 * io_Flags
420 * ios2_DstAddr - multicast address.
421 * ios2_PacketType
422 * ios2_DataLength
423 * ios2_Data
425 * RESULTS
426 * io_Error
427 * ios2_WireError
429 * EXAMPLE
431 * NOTES
433 * BUGS
435 * SEE ALSO
437 ****************************************************************************
441 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
443 struct DevUnit *unit;
444 BYTE error = 0;
445 ULONG wire_error;
446 BOOL complete = FALSE;
448 /* Check request is valid */
450 unit = (APTR)request->ios2_Req.io_Unit;
451 if((unit->flags & UNITF_ONLINE) == 0)
453 error = S2ERR_OUTOFSERVICE;
454 wire_error = S2WERR_UNIT_OFFLINE;
456 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
457 ((request->ios2_DstAddr[0] & 0x1) == 0))
459 error = S2ERR_BAD_ADDRESS;
460 wire_error = S2WERR_BAD_MULTICAST;
463 /* Queue request for sending */
465 if(error == 0)
466 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
467 else
469 request->ios2_Req.io_Error = error;
470 request->ios2_WireError = wire_error;
471 complete = TRUE;
474 /* Return */
476 return complete;
481 /****** prism2.device/CMD_FLUSH ********************************************
483 * NAME
484 * CMD_FLUSH
486 * FUNCTION
488 * INPUTS
489 * None.
491 * RESULTS
492 * io_Error
494 * EXAMPLE
496 * NOTES
498 * BUGS
500 * SEE ALSO
502 ****************************************************************************
506 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
508 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
510 return TRUE;
515 /****** prism2.device/S2_DEVICEQUERY ***************************************
517 * NAME
518 * S2_DEVICEQUERY -- Query device capabilities.
520 * FUNCTION
522 * INPUTS
523 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
525 * RESULTS
526 * io_Error
527 * ios2_WireError
529 * EXAMPLE
531 * NOTES
533 * BUGS
535 * SEE ALSO
537 ****************************************************************************
541 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
542 struct DevBase *base)
544 struct DevUnit *unit;
545 struct Sana2DeviceQuery *info;
546 ULONG size_available, size;
548 /* Copy device info */
550 unit = (APTR)request->ios2_Req.io_Unit;
551 info = request->ios2_StatData;
552 size = size_available = info->SizeAvailable;
553 if(size > sizeof(struct Sana2DeviceQuery))
554 size = sizeof(struct Sana2DeviceQuery);
556 CopyMem(&sana2_info, info, size);
557 info->BPS = unit->speed;
559 info->SizeAvailable = size_available;
560 info->SizeSupplied = size;
562 /* Return */
564 return TRUE;
569 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
571 * NAME
572 * S2_GETSTATIONADDDRESS
574 * FUNCTION
576 * INPUTS
577 * None.
579 * RESULTS
580 * io_Error
581 * ios2_WireError
582 * ios2_SrcAddr - current address.
583 * ios2_DstAddr - default address (zero if none?).
585 * EXAMPLE
587 * NOTES
589 * BUGS
591 * SEE ALSO
593 ****************************************************************************
597 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
598 struct DevBase *base)
600 struct DevUnit *unit;
602 /* Copy addresses */
604 unit = (APTR)request->ios2_Req.io_Unit;
605 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
606 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
608 /* Return */
610 return TRUE;
615 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
617 * NAME
618 * S2_CONFIGINTERFACE
620 * FUNCTION
622 * INPUTS
623 * ios2_SrcAddr - address to use.
625 * RESULTS
626 * io_Error
627 * ios2_WireError
628 * ios2_SrcAddr - address used.
630 * EXAMPLE
632 * NOTES
634 * BUGS
636 * SEE ALSO
638 ****************************************************************************
642 static BOOL CmdConfigInterface(struct IOSana2Req *request,
643 struct DevBase *base)
645 struct DevUnit *unit;
646 BYTE error = 0;
647 ULONG wire_error = S2WERR_GENERIC_ERROR;
649 /* Configure adapter */
651 unit = (APTR)request->ios2_Req.io_Unit;
652 if((unit->flags & UNITF_CONFIGURED) != 0)
654 error = S2ERR_BAD_STATE;
655 wire_error = S2WERR_IS_CONFIGURED;
657 else if((unit->flags & UNITF_HAVEADAPTER) == 0)
659 error = S2ERR_BAD_STATE;
662 if(error == 0)
664 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
665 ConfigureAdapter(unit, base);
666 GoOnline(unit, base);
667 unit->flags |= UNITF_CONFIGURED;
669 else
671 request->ios2_Req.io_Error = error;
672 request->ios2_WireError = wire_error;
675 /* Return */
677 return TRUE;
682 /****** prism2.device/S2_BROADCAST *****************************************
684 * NAME
685 * S2_BROADCAST
687 * FUNCTION
689 * INPUTS
690 * io_Flags
691 * ios2_PacketType
692 * ios2_DataLength
693 * ios2_Data
695 * RESULTS
696 * io_Error
697 * ios2_WireError
699 * EXAMPLE
701 * NOTES
703 * BUGS
705 * SEE ALSO
707 ****************************************************************************
711 static BOOL CmdBroadcast(struct IOSana2Req *request,
712 struct DevBase *base)
714 UWORD i;
716 /* Fill in the broadcast address as destination */
718 for(i = 0; i < ETH_ADDRESSSIZE; i++)
719 request->ios2_DstAddr[i] = 0xff;
721 /* Queue the write as normal */
723 return CmdWrite(request, base);
728 /****** prism2.device/S2_TRACKTYPE *****************************************
730 * NAME
731 * S2_TRACKTYPE
733 * FUNCTION
735 * INPUTS
736 * ios2_PacketType - packet type to start tracking.
738 * RESULTS
739 * io_Error
740 * ios2_WireError
742 * EXAMPLE
744 * NOTES
746 * BUGS
748 * SEE ALSO
750 ****************************************************************************
754 static BOOL CmdTrackType(struct IOSana2Req *request,
755 struct DevBase *base)
757 struct DevUnit *unit;
758 struct Opener *opener;
759 ULONG packet_type, wire_error;
760 struct TypeTracker *tracker;
761 struct TypeStats *initial_stats;
762 BYTE error = 0;
764 unit = (APTR)request->ios2_Req.io_Unit;
765 packet_type = request->ios2_PacketType;
766 if(packet_type <= ETH_MTU)
767 packet_type = ETH_MTU;
769 /* Get global tracker */
771 tracker = (struct TypeTracker *)
772 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
774 if(tracker != NULL)
775 tracker->user_count++;
776 else
778 tracker =
779 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
780 if(tracker != NULL)
782 tracker->packet_type = packet_type;
783 tracker->user_count = 1;
785 Disable();
786 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
787 Enable();
791 /* Store initial figures for this opener */
793 opener = request->ios2_BufferManagement;
794 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
795 base);
797 if(initial_stats != NULL)
799 error = S2ERR_BAD_STATE;
800 wire_error = S2WERR_ALREADY_TRACKED;
803 if(error == 0)
805 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
806 if(initial_stats == NULL)
808 error = S2ERR_NO_RESOURCES;
809 wire_error = S2WERR_GENERIC_ERROR;
813 if(error == 0)
815 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
816 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
819 /* Return */
821 request->ios2_Req.io_Error = error;
822 request->ios2_WireError = wire_error;
823 return TRUE;
828 /****** prism2.device/S2_UNTRACKTYPE ***************************************
830 * NAME
831 * S2_UNTRACKTYPE
833 * FUNCTION
835 * INPUTS
836 * ios2_PacketType - packet type to stop tracking.
838 * RESULTS
839 * io_Error
840 * ios2_WireError
842 * EXAMPLE
844 * NOTES
846 * BUGS
848 * SEE ALSO
850 ****************************************************************************
854 static BOOL CmdUntrackType(struct IOSana2Req *request,
855 struct DevBase *base)
857 struct DevUnit *unit;
858 struct Opener *opener;
859 ULONG packet_type;
860 struct TypeTracker *tracker;
861 struct TypeStats *initial_stats;
863 unit = (APTR)request->ios2_Req.io_Unit;
864 packet_type = request->ios2_PacketType;
865 if(packet_type <= ETH_MTU)
866 packet_type = ETH_MTU;
868 /* Get global tracker and initial figures */
870 tracker = (struct TypeTracker *)
871 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
872 opener = request->ios2_BufferManagement;
873 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
874 base);
876 /* Decrement tracker usage and free unused structures */
878 if(initial_stats != NULL)
880 if((--tracker->user_count) == 0)
882 Disable();
883 Remove((APTR)tracker);
884 Enable();
885 FreeMem(tracker, sizeof(struct TypeTracker));
888 Remove((APTR)initial_stats);
889 FreeMem(initial_stats, sizeof(struct TypeStats));
891 else
893 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
894 request->ios2_WireError = S2WERR_NOT_TRACKED;
897 /* Return */
899 return TRUE;
904 /****** prism2.device/S2_GETTYPESTATS **************************************
906 * NAME
907 * S2_GETTYPESTATS
909 * FUNCTION
911 * INPUTS
912 * ios2_PacketType - packet type to get statistics on.
913 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
915 * RESULTS
916 * io_Error
917 * ios2_WireError
919 * EXAMPLE
921 * NOTES
923 * BUGS
925 * SEE ALSO
927 ****************************************************************************
931 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
932 struct DevBase *base)
934 struct DevUnit *unit;
935 struct Opener *opener;
936 ULONG packet_type;
937 struct TypeStats *initial_stats, *tracker;
938 struct Sana2PacketTypeStats *stats;
940 unit = (APTR)request->ios2_Req.io_Unit;
941 packet_type = request->ios2_PacketType;
943 /* Get global tracker and initial figures */
945 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
946 opener = request->ios2_BufferManagement;
947 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
948 base);
950 /* Copy and adjust figures */
952 if(initial_stats != NULL)
954 stats = request->ios2_StatData;
955 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
956 stats->PacketsSent -= initial_stats->stats.PacketsSent;
957 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
958 stats->BytesSent -= initial_stats->stats.BytesSent;
959 stats->BytesReceived -= initial_stats->stats.BytesReceived;
960 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
962 else
964 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
965 request->ios2_WireError = S2WERR_NOT_TRACKED;
968 /* Return */
970 return TRUE;
975 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
977 * NAME
978 * S2_GETSPECIALSTATS
980 * FUNCTION
982 * INPUTS
983 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
985 * RESULTS
986 * io_Error
987 * ios2_WireError
989 * EXAMPLE
991 * NOTES
993 * BUGS
995 * SEE ALSO
997 ****************************************************************************
1001 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
1002 struct DevBase *base)
1004 struct DevUnit *unit;
1005 UWORD i, stat_count;
1006 struct Sana2SpecialStatHeader *header;
1007 struct Sana2SpecialStatRecord *record;
1009 /* Fill in stats */
1011 unit = (APTR)request->ios2_Req.io_Unit;
1012 header = request->ios2_StatData;
1013 record = (APTR)(header + 1);
1015 stat_count = header->RecordCountMax;
1016 if(stat_count > STAT_COUNT)
1017 stat_count = STAT_COUNT;
1019 for(i = 0; i < stat_count; i++)
1021 record->Type = (S2WireType_Ethernet << 16) + i;
1022 record->Count = unit->special_stats[i];
1023 record->String = special_stat_names[i];
1024 record++;
1027 header->RecordCountSupplied = stat_count;
1029 /* Return */
1031 return TRUE;
1036 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1038 * NAME
1039 * S2_GETGLOBALSTATS
1041 * FUNCTION
1043 * INPUTS
1044 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1046 * RESULTS
1047 * io_Error
1048 * ios2_WireError
1050 * EXAMPLE
1052 * NOTES
1054 * BUGS
1056 * SEE ALSO
1058 ****************************************************************************
1062 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
1063 struct DevBase *base)
1065 struct DevUnit *unit;
1067 /* Update and copy stats */
1069 unit = (APTR)request->ios2_Req.io_Unit;
1070 if((unit->flags & UNITF_ONLINE) != 0)
1071 UpdateStats(unit, base);
1072 CopyMem(&unit->stats, request->ios2_StatData,
1073 sizeof(struct Sana2DeviceStats));
1075 /* Return */
1077 return TRUE;
1082 /****** prism2.device/S2_ONEVENT *******************************************
1084 * NAME
1085 * S2_ONEVENT
1087 * FUNCTION
1089 * INPUTS
1090 * ios2_WireError
1092 * RESULTS
1093 * io_Error
1094 * ios2_WireError
1096 * EXAMPLE
1098 * NOTES
1100 * BUGS
1102 * SEE ALSO
1104 ****************************************************************************
1108 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1110 struct DevUnit *unit;
1111 ULONG events, wanted_events;
1112 BOOL complete = FALSE;
1114 /* Check if we understand the event types */
1116 unit = (APTR)request->ios2_Req.io_Unit;
1117 wanted_events = request->ios2_WireError;
1118 if((wanted_events & ~KNOWN_EVENTS) != 0)
1120 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1121 events = S2WERR_BAD_EVENT;
1123 else
1125 if((unit->flags & UNITF_ONLINE) != 0)
1126 events = S2EVENT_ONLINE;
1127 else
1128 events = S2EVENT_OFFLINE;
1130 events &= wanted_events;
1133 /* Reply request if a wanted event has already occurred */
1135 if(events != 0)
1137 request->ios2_WireError = events;
1138 complete = TRUE;
1140 else
1141 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1143 /* Return */
1145 return complete;
1150 /****** prism2.device/S2_READORPHAN ****************************************
1152 * NAME
1153 * S2_READORPHAN
1155 * FUNCTION
1157 * INPUTS
1158 * io_Flags
1159 * ios2_Data
1161 * RESULTS
1162 * io_Flags
1163 * io_Error
1164 * ios2_WireError
1165 * ios2_PacketType - A copy of the packet's type field.
1166 * ios2_SrcAddr
1167 * ios2_DstAddr
1168 * ios2_DataLength
1169 * ios2_Data
1172 * EXAMPLE
1174 * NOTES
1176 * BUGS
1178 * SEE ALSO
1180 ****************************************************************************
1184 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1185 struct DevBase *base)
1187 struct DevUnit *unit;
1188 BYTE error = 0;
1189 ULONG wire_error;
1190 BOOL complete = FALSE;
1192 /* Check request is valid */
1194 unit = (APTR)request->ios2_Req.io_Unit;
1195 if((unit->flags & UNITF_ONLINE) == 0)
1197 error = S2ERR_OUTOFSERVICE;
1198 wire_error = S2WERR_UNIT_OFFLINE;
1201 /* Queue request */
1203 if(error == 0)
1204 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1205 else
1207 request->ios2_Req.io_Error = error;
1208 request->ios2_WireError = wire_error;
1209 complete = TRUE;
1212 /* Return */
1214 return complete;
1219 /****** prism2.device/S2_ONLINE ********************************************
1221 * NAME
1222 * S2_ONLINE
1224 * FUNCTION
1226 * INPUTS
1227 * None.
1229 * RESULTS
1230 * io_Error
1231 * ios2_WireError
1233 * EXAMPLE
1235 * NOTES
1237 * BUGS
1239 * SEE ALSO
1241 ****************************************************************************
1245 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1247 struct DevUnit *unit;
1248 BYTE error = 0;
1249 ULONG wire_error;
1250 UWORD i;
1252 /* Check request is valid */
1254 unit = (APTR)request->ios2_Req.io_Unit;
1255 if((unit->flags & UNITF_CONFIGURED) == 0)
1257 error = S2ERR_BAD_STATE;
1258 wire_error = S2WERR_NOT_CONFIGURED;
1260 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1262 error = S2ERR_OUTOFSERVICE;
1263 wire_error = S2WERR_RCVREL_HDW_ERR;
1266 /* Clear global and special stats and put adapter back online */
1268 if(error == 0 && (unit->flags & UNITF_ONLINE) == 0)
1270 unit->stats.PacketsReceived = 0;
1271 unit->stats.PacketsSent = 0;
1272 unit->stats.BadData = 0;
1273 unit->stats.Overruns = 0;
1274 unit->stats.UnknownTypesReceived = 0;
1275 unit->stats.Reconfigurations = 0;
1277 for(i = 0; i < STAT_COUNT; i++)
1278 unit->special_stats[i] = 0;
1280 GoOnline(unit, base);
1283 /* Return */
1285 request->ios2_Req.io_Error = error;
1286 request->ios2_WireError = wire_error;
1287 return TRUE;
1292 /****** prism2.device/S2_OFFLINE *******************************************
1294 * NAME
1295 * S2_OFFLINE
1297 * FUNCTION
1299 * INPUTS
1300 * None.
1302 * RESULTS
1303 * io_Error
1304 * ios2_WireError
1306 * EXAMPLE
1308 * NOTES
1310 * BUGS
1312 * SEE ALSO
1314 ****************************************************************************
1318 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1320 struct DevUnit *unit;
1322 /* Put adapter offline */
1324 unit = (APTR)request->ios2_Req.io_Unit;
1325 if((unit->flags & UNITF_ONLINE) != 0)
1326 GoOffline(unit, base);
1328 /* Return */
1330 return TRUE;
1335 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1337 * NAME
1338 * NSCMD_DEVICEQUERY -- Query device capabilities.
1340 * FUNCTION
1342 * INPUTS
1343 * io_Length - ???.
1344 * io_Data - pointer to NSDeviceQueryResult structure.
1346 * RESULTS
1347 * io_Error
1348 * io_Actual - size of structure device can handle.
1350 * EXAMPLE
1352 * NOTES
1354 * BUGS
1356 * SEE ALSO
1358 ****************************************************************************
1360 * Note that we have to pretend the request structure is an IOStdReq.
1364 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1365 struct DevBase *base)
1367 struct NSDeviceQueryResult *info;
1369 /* Set structure size twice */
1371 info = request->io_Data;
1372 request->io_Actual = info->SizeAvailable =
1373 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1375 /* Report device details */
1377 info->DeviceType = NSDEVTYPE_SANA2;
1378 info->DeviceSubType = 0;
1380 info->SupportedCommands = (APTR)supported_commands;
1382 /* Return */
1384 return TRUE;
1389 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1391 * NAME
1392 * S2_ADDMULTICASTADDRESS
1394 * FUNCTION
1396 * INPUTS
1397 * ios2_SrcAddr - multicast address.
1399 * RESULTS
1400 * io_Error
1401 * ios2_WireError
1403 * EXAMPLE
1405 * NOTES
1407 * BUGS
1409 * SEE ALSO
1411 ****************************************************************************
1415 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1417 * NAME
1418 * S2_ADDMULTICASTADDRESSES
1420 * FUNCTION
1422 * INPUTS
1423 * ios2_SrcAddr - lower bound.
1424 * ios2_DstAddr - upper bound.
1426 * RESULTS
1427 * io_Error
1428 * ios2_WireError
1430 * EXAMPLE
1432 * NOTES
1434 * BUGS
1436 * SEE ALSO
1438 ****************************************************************************
1442 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1443 struct DevBase *base)
1445 struct DevUnit *unit;
1446 UBYTE *lower_bound, *upper_bound;
1448 unit = (APTR)request->ios2_Req.io_Unit;
1450 lower_bound = request->ios2_SrcAddr;
1451 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1452 upper_bound = lower_bound;
1453 else
1454 upper_bound = request->ios2_DstAddr;
1456 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1458 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1459 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1462 /* Return */
1464 return TRUE;
1469 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1471 * NAME
1472 * S2_DELMULTICASTADDRESS
1474 * FUNCTION
1476 * INPUTS
1477 * ios2_SrcAddr - multicast address.
1479 * RESULTS
1480 * io_Error
1481 * ios2_WireError
1483 * EXAMPLE
1485 * NOTES
1487 * BUGS
1489 * SEE ALSO
1491 ****************************************************************************
1495 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1497 * NAME
1498 * S2_DELMULTICASTADDRESSES
1500 * FUNCTION
1502 * INPUTS
1503 * ios2_SrcAddr - lower bound.
1504 * ios2_DstAddr - upper bound.
1506 * RESULTS
1507 * io_Error
1508 * ios2_WireError
1510 * EXAMPLE
1512 * NOTES
1514 * BUGS
1516 * SEE ALSO
1518 ****************************************************************************
1522 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1523 struct DevBase *base)
1525 struct DevUnit *unit;
1526 UBYTE *lower_bound, *upper_bound;
1528 unit = (APTR)request->ios2_Req.io_Unit;
1530 lower_bound = request->ios2_SrcAddr;
1531 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1532 upper_bound = lower_bound;
1533 else
1534 upper_bound = request->ios2_DstAddr;
1536 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1538 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1539 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1542 /* Return */
1544 return TRUE;
1549 /****** prism2.device/S2_GETSIGNALQUALITY **********************************
1551 * NAME
1552 * S2_GETSIGNALQUALITY -- Get signal quality statistics.
1554 * FUNCTION
1555 * This command fills in the supplied Sana2SignalQuality structure with
1556 * current signal and noise levels. The unit for these figures is dBm.
1557 * Typically, they are negative values.
1559 * INPUTS
1560 * ios2_StatData - Pointer to Sana2SignalQuality structure.
1562 * RESULTS
1563 * io_Error - Zero if successful; non-zero otherwise.
1564 * ios2_WireError - More specific error code.
1566 ****************************************************************************
1570 static BOOL CmdGetSignalQuality(struct IOSana2Req *request,
1571 struct DevBase *base)
1573 struct DevUnit *unit;
1575 /* Update and copy stats */
1577 unit = (APTR)request->ios2_Req.io_Unit;
1578 if((unit->flags & UNITF_ONLINE) != 0)
1580 UpdateSignalQuality(unit, base);
1581 CopyMem(&unit->signal_quality, request->ios2_StatData,
1582 sizeof(struct Sana2SignalQuality));
1584 else
1586 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1587 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1590 /* Return */
1592 return TRUE;
1597 /****** prism2.device/S2_GETNETWORKS ***************************************
1599 * NAME
1600 * S2_GETNETWORKS -- Scan for available networks.
1602 * FUNCTION
1603 * This command supplies details of available networks. If the scan
1604 * should be limited to one specific network, the S2INFO_SSID tag
1605 * should specify its name.
1607 * If this command completes successfully, ios2_StatData will contain
1608 * an array of pointers to tag lists, each of which contains
1609 * information on a single network. The device will set ios2_DataLength
1610 * to the number of elements in this array.
1612 * The returned taglists are allocated from the supplied memory pool.
1613 * To discard the results of this command, the entire memory pool
1614 * should be destroyed.
1616 * INPUTS
1617 * ios2_Data - Pointer to an Exec memory pool.
1618 * ios2_StatData - Pointer to taglist that specifies parameters to use.
1620 * RESULTS
1621 * io_Error - Zero if successful; non-zero otherwise.
1622 * ios2_WireError - More specific error code.
1623 * ios2_DataLength - Number of tag lists returned.
1624 * ios2_Data - Remains unchanged.
1625 * ios2_StatData - Pointer to an array of tag lists.
1627 ****************************************************************************
1631 static BOOL CmdGetNetworks(struct IOSana2Req *request,
1632 struct DevBase *base)
1634 struct DevUnit *unit;
1635 BOOL complete = FALSE;
1636 const TEXT *ssid;
1637 const struct TagItem *tag_list;
1639 /* Request a new scan and queue request to receive results */
1641 unit = (APTR)request->ios2_Req.io_Unit;
1642 if((unit->flags & UNITF_ONLINE) != 0)
1644 PutRequest(unit->request_ports[SCAN_QUEUE], (APTR)request, base);
1645 tag_list = (const struct TagItem *)request->ios2_StatData;
1646 ssid = (const TEXT *)GetTagData(S2INFO_SSID, (UPINT)NULL, tag_list);
1647 StartScan(unit, ssid, base);
1649 else
1651 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1652 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1653 complete = TRUE;
1656 /* Return */
1658 return complete;
1663 /****** prism2.device/S2_SETOPTIONS ****************************************
1665 * NAME
1666 * S2_SETOPTIONS -- Set network options.
1668 * FUNCTION
1669 * Set various parameters for the network interface. This command
1670 * should be called before going online to set any essential parameters
1671 * not covered elsewhere.
1673 * INPUTS
1674 * ios2_Data - Pointer to taglist that specifies the parameters to use.
1676 * RESULTS
1677 * io_Error - Zero if successful; non-zero otherwise.
1678 * ios2_WireError - More specific error code.
1680 ****************************************************************************
1684 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base)
1686 struct DevUnit *unit;
1688 /* Set options, and reconfigure if already online */
1690 unit = (APTR)request->ios2_Req.io_Unit;
1691 SetOptions(unit, request->ios2_Data, base);
1692 if((unit->flags & UNITF_ONLINE) != 0)
1693 ConfigureAdapter(unit, base);
1694 unit->stats.Reconfigurations++;
1696 /* Return */
1698 return TRUE;
1703 /****** prism2.device/S2_SETKEY ********************************************
1705 * NAME
1706 * S2_SETKEY -- Set an encryption key.
1708 * FUNCTION
1710 * INPUTS
1711 * ios2_WireError - Key index.
1712 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1713 * ios2_DataLength - Key length.
1714 * ios2_Data - Key.
1715 * ios2_StatData - RX counter number (NULL if unused).
1717 * RESULTS
1718 * io_Error
1720 * EXAMPLE
1722 * NOTES
1724 * BUGS
1726 * SEE ALSO
1728 ****************************************************************************
1732 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base)
1734 struct DevUnit *unit;
1736 unit = (APTR)request->ios2_Req.io_Unit;
1737 SetKey(unit, request->ios2_WireError, request->ios2_PacketType,
1738 request->ios2_Data, request->ios2_DataLength, request->ios2_StatData,
1739 base);
1741 /* Return */
1743 return TRUE;
1748 /****** prism2.device/S2_GETNETWORKINFO ************************************
1750 * NAME
1751 * S2_GETNETWORKINFO -- Get information on current network.
1753 * FUNCTION
1755 * INPUTS
1756 * ios2_Data - Pointer to an Exec memory pool.
1758 * RESULTS
1759 * ios2_Data - Remains unchanged.
1760 * ios2_StatData - Pointer to a tag list.
1761 * io_Error - Zero if successful; non-zero otherwise.
1762 * ios2_WireError - More specific error code.
1764 ****************************************************************************
1768 static BOOL CmdGetNetworkInfo(struct IOSana2Req *request,
1769 struct DevBase *base)
1771 struct DevUnit *unit;
1772 APTR pool;
1774 /* Request information on current network */
1776 unit = (APTR)request->ios2_Req.io_Unit;
1777 pool = request->ios2_Data;
1778 if((unit->flags & UNITF_ONLINE) != 0)
1780 request->ios2_StatData = GetNetworkInfo(unit, pool, base);
1781 if(request->ios2_StatData == NULL)
1782 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1784 else
1786 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1787 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1790 /* Return */
1792 return TRUE;
1797 /****** prism2.device/S2_GETCRYPTTYPES *************************************
1799 * NAME
1800 * S2_GETCRYPTTYPES -- Get encryption capabilities.
1802 * FUNCTION
1803 * This command returns a list of encryption types supported by the
1804 * device (including S2ENC_NONE).
1806 * INPUTS
1807 * ios2_Data - Pointer to an Exec memory pool.
1809 * RESULTS
1810 * ios2_Data - Remains unchanged.
1811 * ios2_DataLength - Number of encryption types returned.
1812 * ios2_StatData - Pointer to a UBYTE array of encryption types.
1813 * io_Error - Zero if successful; non-zero otherwise.
1814 * ios2_WireError - More specific error code.
1816 ****************************************************************************
1820 static BOOL CmdGetCryptTypes(struct IOSana2Req *request,
1821 struct DevBase *base)
1823 struct DevUnit *unit;
1824 APTR pool;
1825 UBYTE *list;
1827 /* Allocate array and fill it with supported encryption types */
1829 unit = (APTR)request->ios2_Req.io_Unit;
1830 pool = request->ios2_Data;
1831 list = AllocPooled(pool, 4 * sizeof(UBYTE));
1833 if(list != NULL)
1835 request->ios2_StatData = list;
1836 *list++ = S2ENC_NONE;
1837 if((unit->flags & UNITF_HASWEP) != 0)
1838 *list++ = S2ENC_WEP;
1839 if((unit->flags & UNITF_HASTKIP) != 0)
1840 *list++ = S2ENC_TKIP;
1841 if((unit->flags & UNITF_HASCCMP) != 0)
1842 *list++ = S2ENC_CCMP;
1843 request->ios2_DataLength =
1844 (UPINT)list - (UPINT)request->ios2_StatData;
1846 else
1847 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1849 /* Return */
1851 return TRUE;
1856 /****i* prism2.device/PutRequest *******************************************
1858 * NAME
1859 * PutRequest
1861 * SYNOPSIS
1862 * PutRequest(port, request)
1864 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1866 * FUNCTION
1868 * INPUTS
1869 * port
1870 * request
1872 * RESULT
1873 * None.
1875 ****************************************************************************
1879 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1880 struct DevBase *base)
1882 request->io_Flags &= ~IOF_QUICK;
1883 PutMsg(port, (APTR)request);
1885 return;