Reverted removal of 'const' from TagItem arrays/pointers in r50146
[AROS.git] / workbench / devs / networks / prism2 / request.c
blob8979aa894aaae8d3e66c30b3ec7cb2ff56036fef
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 | 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);
86 static const UWORD supported_commands[] =
88 CMD_READ,
89 CMD_WRITE,
90 CMD_FLUSH,
91 S2_DEVICEQUERY,
92 S2_GETSTATIONADDRESS,
93 S2_CONFIGINTERFACE,
94 S2_ADDMULTICASTADDRESS,
95 S2_DELMULTICASTADDRESS,
96 S2_MULTICAST,
97 S2_BROADCAST,
98 S2_TRACKTYPE,
99 S2_UNTRACKTYPE,
100 S2_GETTYPESTATS,
101 S2_GETSPECIALSTATS,
102 S2_GETGLOBALSTATS,
103 S2_ONEVENT,
104 S2_READORPHAN,
105 S2_ONLINE,
106 S2_OFFLINE,
107 NSCMD_DEVICEQUERY,
108 S2_ADDMULTICASTADDRESSES,
109 S2_DELMULTICASTADDRESSES,
110 S2_GETSIGNALQUALITY,
111 S2_GETNETWORKS,
112 S2_SETOPTIONS,
113 S2_SETKEY,
114 S2_GETNETWORKINFO,
115 // P2_DISASSOCIATE,
120 static const struct Sana2DeviceQuery sana2_info =
126 ETH_ADDRESSSIZE * 8,
127 ETH_MTU,
129 S2WireType_Ethernet
133 const TEXT badmulticast_name[] = "Bad multicasts";
134 const TEXT retries_name[] = "Retries";
135 const TEXT fifo_underruns_name[] = "Underruns";
138 const TEXT *const special_stat_names[] =
140 badmulticast_name,
141 retries_name,
142 fifo_underruns_name
147 /****i* prism2.device/ServiceRequest ***************************************
149 * NAME
150 * ServiceRequest -- Attempt to service a device request.
152 * SYNOPSIS
153 * ServiceRequest(request)
155 * VOID ServiceRequest(struct IORequest *);
157 * FUNCTION
158 * Attempts to carry out a request. The relevant unit's semaphore must
159 * be obtained before calling this function. This function releases the
160 * semaphore before returning.
162 * INPUTS
163 * request
165 * RESULT
166 * None.
168 * EXAMPLE
170 * NOTES
172 * BUGS
174 * SEE ALSO
176 ****************************************************************************
180 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
182 BOOL complete;
184 switch(request->ios2_Req.io_Command)
186 case CMD_READ:
187 complete = CmdRead(request, base);
188 break;
189 case CMD_WRITE:
190 complete = CmdWrite(request, base);
191 break;
192 case CMD_FLUSH:
193 complete = CmdFlush((APTR)request, base);
194 break;
195 case S2_DEVICEQUERY:
196 complete = CmdS2DeviceQuery(request, base);
197 break;
198 case S2_GETSTATIONADDRESS:
199 complete = CmdGetStationAddress(request, base);
200 break;
201 case S2_CONFIGINTERFACE:
202 complete = CmdConfigInterface(request, base);
203 break;
204 case S2_ADDMULTICASTADDRESS:
205 complete = CmdAddMulticastAddresses(request, base);
206 break;
207 case S2_DELMULTICASTADDRESS:
208 complete = CmdDelMulticastAddresses(request, base);
209 break;
210 case S2_MULTICAST:
211 complete = CmdWrite(request, base);
212 break;
213 case S2_BROADCAST:
214 complete = CmdBroadcast(request, base);
215 break;
216 case S2_TRACKTYPE:
217 complete = CmdTrackType(request, base);
218 break;
219 case S2_UNTRACKTYPE:
220 complete = CmdUntrackType(request, base);
221 break;
222 case S2_GETTYPESTATS:
223 complete = CmdGetTypeStats(request, base);
224 break;
225 case S2_GETSPECIALSTATS:
226 complete = CmdGetSpecialStats(request, base);
227 break;
228 case S2_GETGLOBALSTATS:
229 complete = CmdGetGlobalStats(request, base);
230 break;
231 case S2_ONEVENT:
232 complete = CmdOnEvent(request, base);
233 break;
234 case S2_READORPHAN:
235 complete = CmdReadOrphan(request, base);
236 break;
237 case S2_ONLINE:
238 complete = CmdOnline(request, base);
239 break;
240 case S2_OFFLINE:
241 complete = CmdOffline(request, base);
242 break;
243 case NSCMD_DEVICEQUERY:
244 complete = CmdDeviceQuery((APTR)request, base);
245 break;
246 case S2_ADDMULTICASTADDRESSES:
247 complete = CmdAddMulticastAddresses(request, base);
248 break;
249 case S2_DELMULTICASTADDRESSES:
250 complete = CmdDelMulticastAddresses(request, base);
251 break;
252 case S2_GETSIGNALQUALITY:
253 complete = CmdGetSignalQuality(request, base);
254 break;
255 case S2_GETNETWORKS:
256 complete = CmdGetNetworks(request, base);
257 break;
258 case S2_SETOPTIONS:
259 complete = CmdSetOptions(request, base);
260 break;
261 case S2_SETKEY:
262 complete = CmdSetKey(request, base);
263 break;
264 case S2_GETNETWORKINFO:
265 complete = CmdGetNetworkInfo(request, base);
266 break;
267 default:
268 complete = CmdInvalid(request, base);
271 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
272 ReplyMsg((APTR)request);
274 ReleaseSemaphore(
275 &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock);
276 return;
281 /****i* prism2.device/CMD_INVALID ******************************************
283 * NAME
284 * CMD_INVALID -- Reject an invalid command.
286 * FUNCTION
288 * INPUTS
289 * None.
291 * RESULTS
292 * io_Error - IOERR_NOCMD.
294 * EXAMPLE
296 * NOTES
298 * BUGS
300 * SEE ALSO
302 ****************************************************************************
306 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
308 request->ios2_Req.io_Error = IOERR_NOCMD;
309 request->ios2_WireError = S2WERR_GENERIC_ERROR;
311 return TRUE;
316 /****** prism2.device/CMD_READ *********************************************
318 * NAME
319 * CMD_READ -- Read data.
321 * FUNCTION
323 * INPUTS
324 * io_Flags
325 * ios2_PacketType
326 * ios2_Data
328 * RESULTS
329 * io_Flags
330 * io_Error
331 * ios2_WireError
332 * ios2_SrcAddr
333 * ios2_DstAddr
334 * ios2_DataLength
335 * ios2_Data
337 * EXAMPLE
339 * NOTES
341 * BUGS
343 * SEE ALSO
345 ****************************************************************************
349 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
351 struct DevUnit *unit;
352 struct Opener *opener;
353 BOOL complete = FALSE;
355 unit = (APTR)request->ios2_Req.io_Unit;
357 if((unit->flags & UNITF_ONLINE) != 0)
359 opener = request->ios2_BufferManagement;
360 PutRequest(&opener->read_port, (APTR)request, base);
362 else
364 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
365 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
366 complete = TRUE;
369 /* Return */
371 return complete;
376 /****** prism2.device/CMD_WRITE ********************************************
378 * NAME
379 * CMD_WRITE -- Write data.
381 * FUNCTION
383 * INPUTS
384 * io_Flags
385 * ios2_DstAddr
386 * ios2_PacketType
387 * ios2_DataLength
388 * ios2_Data
390 * RESULTS
391 * io_Error
392 * ios2_WireError
394 * EXAMPLE
396 * NOTES
398 * BUGS
400 * SEE ALSO
402 ****************************************************************************
406 /****** prism2.device/S2_MULTICAST *****************************************
408 * NAME
409 * S2_MULTICAST
411 * FUNCTION
413 * INPUTS
414 * io_Flags
415 * ios2_DstAddr - multicast address.
416 * ios2_PacketType
417 * ios2_DataLength
418 * ios2_Data
420 * RESULTS
421 * io_Error
422 * ios2_WireError
424 * EXAMPLE
426 * NOTES
428 * BUGS
430 * SEE ALSO
432 ****************************************************************************
436 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
438 struct DevUnit *unit;
439 BYTE error = 0;
440 ULONG wire_error;
441 BOOL complete = FALSE;
443 /* Check request is valid */
445 unit = (APTR)request->ios2_Req.io_Unit;
446 if((unit->flags & UNITF_ONLINE) == 0)
448 error = S2ERR_OUTOFSERVICE;
449 wire_error = S2WERR_UNIT_OFFLINE;
451 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
452 ((request->ios2_DstAddr[0] & 0x1) == 0))
454 error = S2ERR_BAD_ADDRESS;
455 wire_error = S2WERR_BAD_MULTICAST;
458 /* Queue request for sending */
460 //error = 1;
461 if(error == 0)
462 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
463 else
465 request->ios2_Req.io_Error = error;
466 request->ios2_WireError = wire_error;
467 complete = TRUE;
470 /* Return */
472 return complete;
477 /****** prism2.device/CMD_FLUSH ********************************************
479 * NAME
480 * CMD_FLUSH
482 * FUNCTION
484 * INPUTS
485 * None.
487 * RESULTS
488 * io_Error
490 * EXAMPLE
492 * NOTES
494 * BUGS
496 * SEE ALSO
498 ****************************************************************************
502 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
504 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
506 return TRUE;
511 /****** prism2.device/S2_DEVICEQUERY ***************************************
513 * NAME
514 * S2_DEVICEQUERY -- Query device capabilities.
516 * FUNCTION
518 * INPUTS
519 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
521 * RESULTS
522 * io_Error
523 * ios2_WireError
525 * EXAMPLE
527 * NOTES
529 * BUGS
531 * SEE ALSO
533 ****************************************************************************
537 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
538 struct DevBase *base)
540 struct DevUnit *unit;
541 struct Sana2DeviceQuery *info;
542 ULONG size_available, size;
544 /* Copy device info */
546 unit = (APTR)request->ios2_Req.io_Unit;
547 info = request->ios2_StatData;
548 size = size_available = info->SizeAvailable;
549 if(size > sizeof(struct Sana2DeviceQuery))
550 size = sizeof(struct Sana2DeviceQuery);
552 CopyMem(&sana2_info, info, size);
553 info->BPS = unit->speed;
555 info->SizeAvailable = size_available;
556 info->SizeSupplied = size;
558 /* Return */
560 return TRUE;
565 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
567 * NAME
568 * S2_GETSTATIONADDDRESS
570 * FUNCTION
572 * INPUTS
573 * None.
575 * RESULTS
576 * io_Error
577 * ios2_WireError
578 * ios2_SrcAddr - current address.
579 * ios2_DstAddr - default address (zero if none?).
581 * EXAMPLE
583 * NOTES
585 * BUGS
587 * SEE ALSO
589 ****************************************************************************
593 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
594 struct DevBase *base)
596 struct DevUnit *unit;
598 /* Copy addresses */
600 unit = (APTR)request->ios2_Req.io_Unit;
601 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
602 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
604 /* Return */
606 return TRUE;
611 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
613 * NAME
614 * S2_CONFIGINTERFACE
616 * FUNCTION
618 * INPUTS
619 * ios2_SrcAddr - address to use.
621 * RESULTS
622 * io_Error
623 * ios2_WireError
624 * ios2_SrcAddr - address used.
626 * EXAMPLE
628 * NOTES
630 * BUGS
632 * SEE ALSO
634 ****************************************************************************
638 static BOOL CmdConfigInterface(struct IOSana2Req *request,
639 struct DevBase *base)
641 struct DevUnit *unit;
642 BYTE error = 0;
643 ULONG wire_error = S2WERR_GENERIC_ERROR;
645 /* Configure adapter */
647 unit = (APTR)request->ios2_Req.io_Unit;
648 if((unit->flags & UNITF_CONFIGURED) != 0)
650 error = S2ERR_BAD_STATE;
651 wire_error = S2WERR_IS_CONFIGURED;
653 else if((unit->flags & UNITF_HAVEADAPTER) == 0)
655 error = S2ERR_BAD_STATE;
658 if(error == 0)
660 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
661 ConfigureAdapter(unit, base);
662 GoOnline(unit, base);
663 unit->flags |= UNITF_CONFIGURED;
665 else
667 request->ios2_Req.io_Error = error;
668 request->ios2_WireError = wire_error;
671 /* Return */
673 return TRUE;
678 /****** prism2.device/S2_BROADCAST *****************************************
680 * NAME
681 * S2_BROADCAST
683 * FUNCTION
685 * INPUTS
686 * io_Flags
687 * ios2_PacketType
688 * ios2_DataLength
689 * ios2_Data
691 * RESULTS
692 * io_Error
693 * ios2_WireError
695 * EXAMPLE
697 * NOTES
699 * BUGS
701 * SEE ALSO
703 ****************************************************************************
707 static BOOL CmdBroadcast(struct IOSana2Req *request,
708 struct DevBase *base)
710 UWORD i;
712 /* Fill in the broadcast address as destination */
714 for(i = 0; i < ETH_ADDRESSSIZE; i++)
715 request->ios2_DstAddr[i] = 0xff;
717 /* Queue the write as normal */
719 return CmdWrite(request, base);
724 /****** prism2.device/S2_TRACKTYPE *****************************************
726 * NAME
727 * S2_TRACKTYPE
729 * FUNCTION
731 * INPUTS
732 * ios2_PacketType - packet type to start tracking.
734 * RESULTS
735 * io_Error
736 * ios2_WireError
738 * EXAMPLE
740 * NOTES
742 * BUGS
744 * SEE ALSO
746 ****************************************************************************
750 static BOOL CmdTrackType(struct IOSana2Req *request,
751 struct DevBase *base)
753 struct DevUnit *unit;
754 struct Opener *opener;
755 ULONG packet_type, wire_error;
756 struct TypeTracker *tracker;
757 struct TypeStats *initial_stats;
758 BYTE error = 0;
760 unit = (APTR)request->ios2_Req.io_Unit;
761 packet_type = request->ios2_PacketType;
762 if(packet_type <= ETH_MTU)
763 packet_type = ETH_MTU;
765 /* Get global tracker */
767 tracker = (struct TypeTracker *)
768 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
770 if(tracker != NULL)
771 tracker->user_count++;
772 else
774 tracker =
775 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
776 if(tracker != NULL)
778 tracker->packet_type = packet_type;
779 tracker->user_count = 1;
781 Disable();
782 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
783 Enable();
787 /* Store initial figures for this opener */
789 opener = request->ios2_BufferManagement;
790 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
791 base);
793 if(initial_stats != NULL)
795 error = S2ERR_BAD_STATE;
796 wire_error = S2WERR_ALREADY_TRACKED;
799 if(error == 0)
801 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
802 if(initial_stats == NULL)
804 error = S2ERR_NO_RESOURCES;
805 wire_error = S2WERR_GENERIC_ERROR;
809 if(error == 0)
811 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
812 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
815 /* Return */
817 request->ios2_Req.io_Error = error;
818 request->ios2_WireError = wire_error;
819 return TRUE;
824 /****** prism2.device/S2_UNTRACKTYPE ***************************************
826 * NAME
827 * S2_UNTRACKTYPE
829 * FUNCTION
831 * INPUTS
832 * ios2_PacketType - packet type to stop tracking.
834 * RESULTS
835 * io_Error
836 * ios2_WireError
838 * EXAMPLE
840 * NOTES
842 * BUGS
844 * SEE ALSO
846 ****************************************************************************
850 static BOOL CmdUntrackType(struct IOSana2Req *request,
851 struct DevBase *base)
853 struct DevUnit *unit;
854 struct Opener *opener;
855 ULONG packet_type;
856 struct TypeTracker *tracker;
857 struct TypeStats *initial_stats;
859 unit = (APTR)request->ios2_Req.io_Unit;
860 packet_type = request->ios2_PacketType;
861 if(packet_type <= ETH_MTU)
862 packet_type = ETH_MTU;
864 /* Get global tracker and initial figures */
866 tracker = (struct TypeTracker *)
867 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
868 opener = request->ios2_BufferManagement;
869 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
870 base);
872 /* Decrement tracker usage and free unused structures */
874 if(initial_stats != NULL)
876 if((--tracker->user_count) == 0)
878 Disable();
879 Remove((APTR)tracker);
880 Enable();
881 FreeMem(tracker, sizeof(struct TypeTracker));
884 Remove((APTR)initial_stats);
885 FreeMem(initial_stats, sizeof(struct TypeStats));
887 else
889 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
890 request->ios2_WireError = S2WERR_NOT_TRACKED;
893 /* Return */
895 return TRUE;
900 /****** prism2.device/S2_GETTYPESTATS **************************************
902 * NAME
903 * S2_GETTYPESTATS
905 * FUNCTION
907 * INPUTS
908 * ios2_PacketType - packet type to get statistics on.
909 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
911 * RESULTS
912 * io_Error
913 * ios2_WireError
915 * EXAMPLE
917 * NOTES
919 * BUGS
921 * SEE ALSO
923 ****************************************************************************
927 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
928 struct DevBase *base)
930 struct DevUnit *unit;
931 struct Opener *opener;
932 ULONG packet_type;
933 struct TypeStats *initial_stats, *tracker;
934 struct Sana2PacketTypeStats *stats;
936 unit = (APTR)request->ios2_Req.io_Unit;
937 packet_type = request->ios2_PacketType;
939 /* Get global tracker and initial figures */
941 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
942 opener = request->ios2_BufferManagement;
943 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
944 base);
946 /* Copy and adjust figures */
948 if(initial_stats != NULL)
950 stats = request->ios2_StatData;
951 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
952 stats->PacketsSent -= initial_stats->stats.PacketsSent;
953 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
954 stats->BytesSent -= initial_stats->stats.BytesSent;
955 stats->BytesReceived -= initial_stats->stats.BytesReceived;
956 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
958 else
960 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
961 request->ios2_WireError = S2WERR_NOT_TRACKED;
964 /* Return */
966 return TRUE;
971 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
973 * NAME
974 * S2_GETSPECIALSTATS
976 * FUNCTION
978 * INPUTS
979 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
981 * RESULTS
982 * io_Error
983 * ios2_WireError
985 * EXAMPLE
987 * NOTES
989 * BUGS
991 * SEE ALSO
993 ****************************************************************************
997 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
998 struct DevBase *base)
1000 struct DevUnit *unit;
1001 UWORD i, stat_count;
1002 struct Sana2SpecialStatHeader *header;
1003 struct Sana2SpecialStatRecord *record;
1005 /* Fill in stats */
1007 unit = (APTR)request->ios2_Req.io_Unit;
1008 header = request->ios2_StatData;
1009 record = (APTR)(header + 1);
1011 stat_count = header->RecordCountMax;
1012 if(stat_count > STAT_COUNT)
1013 stat_count = STAT_COUNT;
1015 for(i = 0; i < stat_count; i++)
1017 record->Type = (S2WireType_Ethernet << 16) + i;
1018 record->Count = unit->special_stats[i];
1019 record->String = special_stat_names[i];
1020 record++;
1023 header->RecordCountSupplied = stat_count;
1025 /* Return */
1027 return TRUE;
1032 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1034 * NAME
1035 * S2_GETGLOBALSTATS
1037 * FUNCTION
1039 * INPUTS
1040 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1042 * RESULTS
1043 * io_Error
1044 * ios2_WireError
1046 * EXAMPLE
1048 * NOTES
1050 * BUGS
1052 * SEE ALSO
1054 ****************************************************************************
1058 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
1059 struct DevBase *base)
1061 struct DevUnit *unit;
1063 /* Update and copy stats */
1065 unit = (APTR)request->ios2_Req.io_Unit;
1066 if((unit->flags & UNITF_ONLINE) != 0)
1067 UpdateStats(unit, base);
1068 CopyMem(&unit->stats, request->ios2_StatData,
1069 sizeof(struct Sana2DeviceStats));
1071 /* Return */
1073 return TRUE;
1078 /****** prism2.device/S2_ONEVENT *******************************************
1080 * NAME
1081 * S2_ONEVENT
1083 * FUNCTION
1085 * INPUTS
1086 * ios2_WireError
1088 * RESULTS
1089 * io_Error
1090 * ios2_WireError
1092 * EXAMPLE
1094 * NOTES
1096 * BUGS
1098 * SEE ALSO
1100 ****************************************************************************
1104 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1106 struct DevUnit *unit;
1107 ULONG events, wanted_events;
1108 BOOL complete = FALSE;
1110 /* Check if we understand the event types */
1112 unit = (APTR)request->ios2_Req.io_Unit;
1113 wanted_events = request->ios2_WireError;
1114 if((wanted_events & ~KNOWN_EVENTS) != 0)
1116 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1117 events = S2WERR_BAD_EVENT;
1119 else
1121 if((unit->flags & UNITF_ONLINE) != 0)
1122 events = S2EVENT_ONLINE;
1123 else
1124 events = S2EVENT_OFFLINE;
1126 events &= wanted_events;
1129 /* Reply request if a wanted event has already occurred */
1130 //if(wanted_events & S2EVENT_CONNECT) unit->special_stats[8]++;
1132 if(events != 0)
1134 request->ios2_WireError = events;
1135 complete = TRUE;
1137 else
1138 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1140 /* Return */
1142 return complete;
1147 /****** prism2.device/S2_READORPHAN ****************************************
1149 * NAME
1150 * S2_READORPHAN
1152 * FUNCTION
1154 * INPUTS
1155 * io_Flags
1156 * ios2_Data
1158 * RESULTS
1159 * io_Flags
1160 * io_Error
1161 * ios2_WireError
1162 * ios2_PacketType - A copy of the packet's type field.
1163 * ios2_SrcAddr
1164 * ios2_DstAddr
1165 * ios2_DataLength
1166 * ios2_Data
1169 * EXAMPLE
1171 * NOTES
1173 * BUGS
1175 * SEE ALSO
1177 ****************************************************************************
1181 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1182 struct DevBase *base)
1184 struct DevUnit *unit;
1185 BYTE error = 0;
1186 ULONG wire_error;
1187 BOOL complete = FALSE;
1189 /* Check request is valid */
1191 unit = (APTR)request->ios2_Req.io_Unit;
1192 if((unit->flags & UNITF_ONLINE) == 0)
1194 error = S2ERR_OUTOFSERVICE;
1195 wire_error = S2WERR_UNIT_OFFLINE;
1198 /* Queue request */
1200 if(error == 0)
1201 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1202 else
1204 request->ios2_Req.io_Error = error;
1205 request->ios2_WireError = wire_error;
1206 complete = TRUE;
1209 /* Return */
1211 return complete;
1216 /****** prism2.device/S2_ONLINE ********************************************
1218 * NAME
1219 * S2_ONLINE
1221 * FUNCTION
1223 * INPUTS
1224 * None.
1226 * RESULTS
1227 * io_Error
1228 * ios2_WireError
1230 * EXAMPLE
1232 * NOTES
1234 * BUGS
1236 * SEE ALSO
1238 ****************************************************************************
1242 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1244 struct DevUnit *unit;
1245 BYTE error = 0;
1246 ULONG wire_error;
1247 UWORD i;
1249 /* Check request is valid */
1251 unit = (APTR)request->ios2_Req.io_Unit;
1252 if((unit->flags & UNITF_CONFIGURED) == 0)
1254 error = S2ERR_BAD_STATE;
1255 wire_error = S2WERR_NOT_CONFIGURED;
1257 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1259 error = S2ERR_OUTOFSERVICE;
1260 wire_error = S2WERR_RCVREL_HDW_ERR;
1263 /* Clear global and special stats and put adapter back online */
1265 if(error == 0 && (unit->flags & UNITF_ONLINE) == 0)
1267 unit->stats.PacketsReceived = 0;
1268 unit->stats.PacketsSent = 0;
1269 unit->stats.BadData = 0;
1270 unit->stats.Overruns = 0;
1271 unit->stats.UnknownTypesReceived = 0;
1272 unit->stats.Reconfigurations = 0;
1274 for(i = 0; i < STAT_COUNT; i++)
1275 unit->special_stats[i] = 0;
1277 GoOnline(unit, base);
1280 /* Return */
1282 request->ios2_Req.io_Error = error;
1283 request->ios2_WireError = wire_error;
1284 return TRUE;
1289 /****** prism2.device/S2_OFFLINE *******************************************
1291 * NAME
1292 * S2_OFFLINE
1294 * FUNCTION
1296 * INPUTS
1297 * None.
1299 * RESULTS
1300 * io_Error
1301 * ios2_WireError
1303 * EXAMPLE
1305 * NOTES
1307 * BUGS
1309 * SEE ALSO
1311 ****************************************************************************
1315 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1317 struct DevUnit *unit;
1319 /* Put adapter offline */
1321 unit = (APTR)request->ios2_Req.io_Unit;
1322 if((unit->flags & UNITF_ONLINE) != 0)
1323 GoOffline(unit, base);
1325 /* Return */
1327 return TRUE;
1332 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1334 * NAME
1335 * NSCMD_DEVICEQUERY -- Query device capabilities.
1337 * FUNCTION
1339 * INPUTS
1340 * io_Length - ???.
1341 * io_Data - pointer to NSDeviceQueryResult structure.
1343 * RESULTS
1344 * io_Error
1345 * io_Actual - size of structure device can handle.
1347 * EXAMPLE
1349 * NOTES
1351 * BUGS
1353 * SEE ALSO
1355 ****************************************************************************
1357 * Note that we have to pretend the request structure is an IOStdReq.
1361 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1362 struct DevBase *base)
1364 struct NSDeviceQueryResult *info;
1366 /* Set structure size twice */
1368 info = request->io_Data;
1369 request->io_Actual = info->SizeAvailable =
1370 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1372 /* Report device details */
1374 info->DeviceType = NSDEVTYPE_SANA2;
1375 info->DeviceSubType = 0;
1377 info->SupportedCommands = (APTR)supported_commands;
1379 /* Return */
1381 return TRUE;
1386 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1388 * NAME
1389 * S2_ADDMULTICASTADDRESS
1391 * FUNCTION
1393 * INPUTS
1394 * ios2_SrcAddr - multicast address.
1396 * RESULTS
1397 * io_Error
1398 * ios2_WireError
1400 * EXAMPLE
1402 * NOTES
1404 * BUGS
1406 * SEE ALSO
1408 ****************************************************************************
1412 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1414 * NAME
1415 * S2_ADDMULTICASTADDRESSES
1417 * FUNCTION
1419 * INPUTS
1420 * ios2_SrcAddr - lower bound.
1421 * ios2_DstAddr - upper bound.
1423 * RESULTS
1424 * io_Error
1425 * ios2_WireError
1427 * EXAMPLE
1429 * NOTES
1431 * BUGS
1433 * SEE ALSO
1435 ****************************************************************************
1439 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1440 struct DevBase *base)
1442 struct DevUnit *unit;
1443 UBYTE *lower_bound, *upper_bound;
1445 unit = (APTR)request->ios2_Req.io_Unit;
1447 lower_bound = request->ios2_SrcAddr;
1448 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1449 upper_bound = lower_bound;
1450 else
1451 upper_bound = request->ios2_DstAddr;
1453 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1455 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1456 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1459 /* Return */
1461 return TRUE;
1466 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1468 * NAME
1469 * S2_DELMULTICASTADDRESS
1471 * FUNCTION
1473 * INPUTS
1474 * ios2_SrcAddr - multicast address.
1476 * RESULTS
1477 * io_Error
1478 * ios2_WireError
1480 * EXAMPLE
1482 * NOTES
1484 * BUGS
1486 * SEE ALSO
1488 ****************************************************************************
1492 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1494 * NAME
1495 * S2_DELMULTICASTADDRESSES
1497 * FUNCTION
1499 * INPUTS
1500 * ios2_SrcAddr - lower bound.
1501 * ios2_DstAddr - upper bound.
1503 * RESULTS
1504 * io_Error
1505 * ios2_WireError
1507 * EXAMPLE
1509 * NOTES
1511 * BUGS
1513 * SEE ALSO
1515 ****************************************************************************
1519 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1520 struct DevBase *base)
1522 struct DevUnit *unit;
1523 UBYTE *lower_bound, *upper_bound;
1525 unit = (APTR)request->ios2_Req.io_Unit;
1527 lower_bound = request->ios2_SrcAddr;
1528 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1529 upper_bound = lower_bound;
1530 else
1531 upper_bound = request->ios2_DstAddr;
1533 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1535 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1536 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1539 /* Return */
1541 return TRUE;
1546 /****** prism2.device/S2_GETSIGNALQUALITY **********************************
1548 * NAME
1549 * S2_GETSIGNALQUALITY -- Get signal quality statistics.
1551 * FUNCTION
1552 * This command fills in the supplied Sana2SignalQuality structure with
1553 * current signal and noise levels. The unit for these figures is dBm.
1554 * Typically, they are negative values.
1556 * INPUTS
1557 * ios2_StatData - Pointer to Sana2SignalQuality structure.
1559 * RESULTS
1560 * io_Error - Zero if successful; non-zero otherwise.
1561 * ios2_WireError - More specific error code.
1563 ****************************************************************************
1567 static BOOL CmdGetSignalQuality(struct IOSana2Req *request,
1568 struct DevBase *base)
1570 struct DevUnit *unit;
1572 /* Update and copy stats */
1574 unit = (APTR)request->ios2_Req.io_Unit;
1575 if((unit->flags & UNITF_ONLINE) != 0)
1577 UpdateSignalQuality(unit, base);
1578 CopyMem(&unit->signal_quality, request->ios2_StatData,
1579 sizeof(struct Sana2SignalQuality));
1581 else
1583 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1584 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1587 /* Return */
1589 return TRUE;
1594 /****** prism2.device/S2_GETNETWORKS ***************************************
1596 * NAME
1597 * S2_GETNETWORKS -- Scan for available networks.
1599 * FUNCTION
1600 * This command supplies details of available networks. If the scan
1601 * should be limited to one specific network, the S2INFO_SSID tag
1602 * should specify its name.
1604 * If this command completes successfully, ios2_StatData will contain
1605 * an array of pointers to tag lists, each of which contains
1606 * information on a single network. The device will set ios2_DataLength
1607 * to the number of elements in this array.
1609 * The returned taglists are allocated from the supplied memory pool.
1610 * To discard the results of this command, the entire memory pool
1611 * should be destroyed.
1613 * INPUTS
1614 * ios2_Data - Pointer to an Exec memory pool.
1615 * ios2_StatData - Pointer to taglist that specifies parameters to use.
1617 * RESULTS
1618 * io_Error - Zero if successful; non-zero otherwise.
1619 * ios2_WireError - More specific error code.
1620 * ios2_DataLength - Number of tag lists returned.
1621 * ios2_Data - Remains unchanged.
1622 * ios2_StatData - Pointer to an array of tag lists.
1624 ****************************************************************************
1628 static BOOL CmdGetNetworks(struct IOSana2Req *request,
1629 struct DevBase *base)
1631 struct DevUnit *unit;
1632 BOOL complete = FALSE;
1633 const TEXT *ssid;
1634 const struct TagItem *tag_list;
1636 /* Request a new scan and queue request to receive results */
1638 unit = (APTR)request->ios2_Req.io_Unit;
1639 if((unit->flags & UNITF_ONLINE) != 0)
1641 PutRequest(unit->request_ports[SCAN_QUEUE], (APTR)request, base);
1642 tag_list = (const struct TagItem *)request->ios2_StatData;
1643 ssid = (const TEXT *)GetTagData(S2INFO_SSID, (UPINT)NULL, tag_list);
1644 StartScan(unit, ssid, base);
1646 else
1648 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1649 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1650 complete = TRUE;
1653 /* Return */
1655 return complete;
1660 /****** prism2.device/S2_SETOPTIONS ****************************************
1662 * NAME
1663 * S2_SETOPTIONS -- Associate with a network.
1665 * FUNCTION
1666 * Associate with a specified network using the parameters supplied.[?]
1667 * Set various parameters for the network interface. This command
1668 * should be called before going online to set any essential parameters
1669 * not covered elsewhere.
1671 * INPUTS
1672 * ios2_Data - Pointer to taglist that specifies the network and
1673 * parameters to use.
1675 * RESULTS
1676 * io_Error - Zero if successful; non-zero otherwise.
1677 * ios2_WireError - More specific error code.
1679 ****************************************************************************
1683 static BOOL CmdSetOptions(struct IOSana2Req *request, struct DevBase *base)
1685 struct DevUnit *unit;
1687 /* */
1689 unit = (APTR)request->ios2_Req.io_Unit;
1690 SetOptions(unit, request->ios2_Data, base);
1691 #if 1
1692 if((unit->flags & UNITF_ONLINE) != 0)
1693 //&& FindTagItem(P2OPT_Key, request->ios2_Data) == NULL)
1694 ConfigureAdapter(unit, base);
1695 #endif
1696 unit->stats.Reconfigurations++;
1698 /* Return */
1700 return TRUE;
1705 /****** prism2.device/S2_SETKEY ********************************************
1707 * NAME
1708 * S2_SETKEY -- Set an encryption key.
1710 * FUNCTION
1712 * INPUTS
1713 * ios2_WireError - Key index.
1714 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1715 * ios2_DataLength - Key length.
1716 * ios2_Data - Key.
1717 * ios2_StatData - RX counter number (NULL if unused).
1719 * RESULTS
1720 * io_Error
1722 * EXAMPLE
1724 * NOTES
1726 * BUGS
1728 * SEE ALSO
1730 ****************************************************************************
1734 static BOOL CmdSetKey(struct IOSana2Req *request, struct DevBase *base)
1736 struct DevUnit *unit;
1738 unit = (APTR)request->ios2_Req.io_Unit;
1739 SetKey(unit, request->ios2_WireError, request->ios2_PacketType,
1740 request->ios2_Data, request->ios2_DataLength, request->ios2_StatData,
1741 base);
1743 /* Return */
1745 return TRUE;
1750 /****** prism2.device/S2_GETNETWORKINFO ************************************
1752 * NAME
1753 * S2_GETNETWORKINFO -- Get information on current network.
1755 * FUNCTION
1757 * INPUTS
1758 * ios2_Data - Pointer to an Exec memory pool.
1760 * RESULTS
1761 * ios2_Data - Remains unchanged.
1762 * ios2_StatData - Pointer to a tag list.
1763 * io_Error - Zero if successful; non-zero otherwise.
1764 * ios2_WireError - More specific error code.
1766 ****************************************************************************
1770 static BOOL CmdGetNetworkInfo(struct IOSana2Req *request,
1771 struct DevBase *base)
1773 struct DevUnit *unit;
1774 APTR pool;
1776 /* Request information on current network */
1778 unit = (APTR)request->ios2_Req.io_Unit;
1779 pool = request->ios2_Data;
1780 if((unit->flags & UNITF_ONLINE) != 0)
1782 request->ios2_StatData = GetNetworkInfo(unit, pool, base);
1783 if(request->ios2_StatData == NULL)
1784 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1786 else
1788 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1789 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1792 /* Return */
1794 return TRUE;
1799 /****i* prism2.device/PutRequest *******************************************
1801 * NAME
1802 * PutRequest
1804 * SYNOPSIS
1805 * PutRequest(port, request)
1807 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1809 * FUNCTION
1811 * INPUTS
1812 * port
1813 * request
1815 * RESULT
1816 * None.
1818 ****************************************************************************
1822 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1823 struct DevBase *base)
1825 request->io_Flags &= ~IOF_QUICK;
1826 PutMsg(port, (APTR)request);
1828 return;