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,
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>
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
[] =
96 S2_ADDMULTICASTADDRESS
,
97 S2_DELMULTICASTADDRESS
,
110 S2_ADDMULTICASTADDRESSES
,
111 S2_DELMULTICASTADDRESSES
,
122 static const struct Sana2DeviceQuery sana2_info
=
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
[] =
149 /****i* prism2.device/ServiceRequest ***************************************
152 * ServiceRequest -- Attempt to service a device request.
155 * ServiceRequest(request)
157 * VOID ServiceRequest(struct IORequest *);
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.
178 ****************************************************************************
182 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
186 switch(request
->ios2_Req
.io_Command
)
189 complete
= CmdRead(request
, base
);
192 complete
= CmdWrite(request
, base
);
195 complete
= CmdFlush((APTR
)request
, base
);
198 complete
= CmdS2DeviceQuery(request
, base
);
200 case S2_GETSTATIONADDRESS
:
201 complete
= CmdGetStationAddress(request
, base
);
203 case S2_CONFIGINTERFACE
:
204 complete
= CmdConfigInterface(request
, base
);
206 case S2_ADDMULTICASTADDRESS
:
207 complete
= CmdAddMulticastAddresses(request
, base
);
209 case S2_DELMULTICASTADDRESS
:
210 complete
= CmdDelMulticastAddresses(request
, base
);
213 complete
= CmdWrite(request
, base
);
216 complete
= CmdBroadcast(request
, base
);
219 complete
= CmdTrackType(request
, base
);
222 complete
= CmdUntrackType(request
, base
);
224 case S2_GETTYPESTATS
:
225 complete
= CmdGetTypeStats(request
, base
);
227 case S2_GETSPECIALSTATS
:
228 complete
= CmdGetSpecialStats(request
, base
);
230 case S2_GETGLOBALSTATS
:
231 complete
= CmdGetGlobalStats(request
, base
);
234 complete
= CmdOnEvent(request
, base
);
237 complete
= CmdReadOrphan(request
, base
);
240 complete
= CmdOnline(request
, base
);
243 complete
= CmdOffline(request
, base
);
245 case NSCMD_DEVICEQUERY
:
246 complete
= CmdDeviceQuery((APTR
)request
, base
);
248 case S2_ADDMULTICASTADDRESSES
:
249 complete
= CmdAddMulticastAddresses(request
, base
);
251 case S2_DELMULTICASTADDRESSES
:
252 complete
= CmdDelMulticastAddresses(request
, base
);
254 case S2_GETSIGNALQUALITY
:
255 complete
= CmdGetSignalQuality(request
, base
);
258 complete
= CmdGetNetworks(request
, base
);
261 complete
= CmdSetOptions(request
, base
);
264 complete
= CmdSetKey(request
, base
);
266 case S2_GETNETWORKINFO
:
267 complete
= CmdGetNetworkInfo(request
, base
);
269 case S2_GETCRYPTTYPES
:
270 complete
= CmdGetCryptTypes(request
, base
);
273 complete
= CmdInvalid(request
, base
);
276 if(complete
&& ((request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0))
277 ReplyMsg((APTR
)request
);
280 &((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->access_lock
);
286 /****i* prism2.device/CMD_INVALID ******************************************
289 * CMD_INVALID -- Reject an invalid command.
297 * io_Error - IOERR_NOCMD.
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
;
321 /****** prism2.device/CMD_READ *********************************************
324 * CMD_READ -- Read data.
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
);
369 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
370 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
381 /****** prism2.device/CMD_WRITE ********************************************
384 * CMD_WRITE -- Write data.
407 ****************************************************************************
411 /****** prism2.device/S2_MULTICAST *****************************************
420 * ios2_DstAddr - multicast address.
437 ****************************************************************************
441 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
443 struct DevUnit
*unit
;
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 */
466 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
469 request
->ios2_Req
.io_Error
= error
;
470 request
->ios2_WireError
= wire_error
;
481 /****** prism2.device/CMD_FLUSH ********************************************
502 ****************************************************************************
506 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
508 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
515 /****** prism2.device/S2_DEVICEQUERY ***************************************
518 * S2_DEVICEQUERY -- Query device capabilities.
523 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
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
;
569 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
572 * S2_GETSTATIONADDDRESS
582 * ios2_SrcAddr - current address.
583 * ios2_DstAddr - default address (zero if none?).
593 ****************************************************************************
597 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
598 struct DevBase
*base
)
600 struct DevUnit
*unit
;
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
);
615 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
623 * ios2_SrcAddr - address to use.
628 * ios2_SrcAddr - address used.
638 ****************************************************************************
642 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
643 struct DevBase
*base
)
645 struct DevUnit
*unit
;
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
;
664 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
665 ConfigureAdapter(unit
, base
);
666 GoOnline(unit
, base
);
667 unit
->flags
|= UNITF_CONFIGURED
;
671 request
->ios2_Req
.io_Error
= error
;
672 request
->ios2_WireError
= wire_error
;
682 /****** prism2.device/S2_BROADCAST *****************************************
707 ****************************************************************************
711 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
712 struct DevBase
*base
)
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 *****************************************
736 * ios2_PacketType - packet type to start tracking.
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
;
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
);
775 tracker
->user_count
++;
779 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
782 tracker
->packet_type
= packet_type
;
783 tracker
->user_count
= 1;
786 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
791 /* Store initial figures for this opener */
793 opener
= request
->ios2_BufferManagement
;
794 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
797 if(initial_stats
!= NULL
)
799 error
= S2ERR_BAD_STATE
;
800 wire_error
= S2WERR_ALREADY_TRACKED
;
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
;
815 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
816 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
821 request
->ios2_Req
.io_Error
= error
;
822 request
->ios2_WireError
= wire_error
;
828 /****** prism2.device/S2_UNTRACKTYPE ***************************************
836 * ios2_PacketType - packet type to stop tracking.
850 ****************************************************************************
854 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
855 struct DevBase
*base
)
857 struct DevUnit
*unit
;
858 struct Opener
*opener
;
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
,
876 /* Decrement tracker usage and free unused structures */
878 if(initial_stats
!= NULL
)
880 if((--tracker
->user_count
) == 0)
883 Remove((APTR
)tracker
);
885 FreeMem(tracker
, sizeof(struct TypeTracker
));
888 Remove((APTR
)initial_stats
);
889 FreeMem(initial_stats
, sizeof(struct TypeStats
));
893 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
894 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
904 /****** prism2.device/S2_GETTYPESTATS **************************************
912 * ios2_PacketType - packet type to get statistics on.
913 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
927 ****************************************************************************
931 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
932 struct DevBase
*base
)
934 struct DevUnit
*unit
;
935 struct Opener
*opener
;
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
,
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
;
964 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
965 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
975 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
983 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
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
;
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
];
1027 header
->RecordCountSupplied
= stat_count
;
1036 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1044 * ios2_StatData - Pointer to Sana2DeviceStats structure.
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
));
1082 /****** prism2.device/S2_ONEVENT *******************************************
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
;
1125 if((unit
->flags
& UNITF_ONLINE
) != 0)
1126 events
= S2EVENT_ONLINE
;
1128 events
= S2EVENT_OFFLINE
;
1130 events
&= wanted_events
;
1133 /* Reply request if a wanted event has already occurred */
1137 request
->ios2_WireError
= events
;
1141 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1150 /****** prism2.device/S2_READORPHAN ****************************************
1165 * ios2_PacketType - A copy of the packet's type field.
1180 ****************************************************************************
1184 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1185 struct DevBase
*base
)
1187 struct DevUnit
*unit
;
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
;
1204 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1207 request
->ios2_Req
.io_Error
= error
;
1208 request
->ios2_WireError
= wire_error
;
1219 /****** prism2.device/S2_ONLINE ********************************************
1241 ****************************************************************************
1245 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1247 struct DevUnit
*unit
;
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
);
1285 request
->ios2_Req
.io_Error
= error
;
1286 request
->ios2_WireError
= wire_error
;
1292 /****** prism2.device/S2_OFFLINE *******************************************
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
);
1335 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1338 * NSCMD_DEVICEQUERY -- Query device capabilities.
1344 * io_Data - pointer to NSDeviceQueryResult structure.
1348 * io_Actual - size of structure device can handle.
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
;
1389 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1392 * S2_ADDMULTICASTADDRESS
1397 * ios2_SrcAddr - multicast address.
1411 ****************************************************************************
1415 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1418 * S2_ADDMULTICASTADDRESSES
1423 * ios2_SrcAddr - lower bound.
1424 * ios2_DstAddr - upper bound.
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
;
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
;
1469 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1472 * S2_DELMULTICASTADDRESS
1477 * ios2_SrcAddr - multicast address.
1491 ****************************************************************************
1495 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1498 * S2_DELMULTICASTADDRESSES
1503 * ios2_SrcAddr - lower bound.
1504 * ios2_DstAddr - upper bound.
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
;
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
;
1549 /****** prism2.device/S2_GETSIGNALQUALITY **********************************
1552 * S2_GETSIGNALQUALITY -- Get signal quality statistics.
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.
1560 * ios2_StatData - Pointer to Sana2SignalQuality structure.
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
));
1586 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1587 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1597 /****** prism2.device/S2_GETNETWORKS ***************************************
1600 * S2_GETNETWORKS -- Scan for available networks.
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.
1617 * ios2_Data - Pointer to an Exec memory pool.
1618 * ios2_StatData - Pointer to taglist that specifies parameters to use.
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
;
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
);
1651 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1652 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1663 /****** prism2.device/S2_SETOPTIONS ****************************************
1666 * S2_SETOPTIONS -- Set network options.
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.
1674 * ios2_Data - Pointer to taglist that specifies the parameters to use.
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
++;
1703 /****** prism2.device/S2_SETKEY ********************************************
1706 * S2_SETKEY -- Set an encryption key.
1711 * ios2_WireError - Key index.
1712 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1713 * ios2_DataLength - Key length.
1715 * ios2_StatData - RX counter number (NULL if unused).
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
,
1748 /****** prism2.device/S2_GETNETWORKINFO ************************************
1751 * S2_GETNETWORKINFO -- Get information on current network.
1756 * ios2_Data - Pointer to an Exec memory pool.
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
;
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
;
1786 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1787 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1797 /****** prism2.device/S2_GETCRYPTTYPES *************************************
1800 * S2_GETCRYPTTYPES -- Get encryption capabilities.
1803 * This command returns a list of encryption types supported by the
1804 * device (including S2ENC_NONE).
1807 * ios2_Data - Pointer to an Exec memory pool.
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
;
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
));
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
;
1847 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1856 /****i* prism2.device/PutRequest *******************************************
1862 * PutRequest(port, request)
1864 * VOID PutRequest(struct MsgPort *, struct IORequest *);
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
);