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,
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 \
43 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
);
44 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
);
45 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
);
46 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
);
48 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
49 struct DevBase
*base
);
50 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
51 struct DevBase
*base
);
52 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
53 struct DevBase
*base
);
54 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
55 struct DevBase
*base
);
56 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
57 struct DevBase
*base
);
58 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
59 struct DevBase
*base
);
60 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
61 struct DevBase
*base
);
62 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
63 struct DevBase
*base
);
64 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
65 struct DevBase
*base
);
66 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
);
67 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
68 struct DevBase
*base
);
69 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
);
70 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
);
71 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
72 struct DevBase
*base
);
73 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
74 struct DevBase
*base
);
75 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
76 struct DevBase
*base
);
77 static BOOL
CmdSetOptions(struct IOSana2Req
*request
, struct DevBase
*base
);
78 static BOOL
CmdSetKey(struct IOSana2Req
*request
, struct DevBase
*base
);
79 static BOOL
CmdWriteMgmt(struct IOSana2Req
*request
, struct DevBase
*base
);
80 static BOOL
CmdReadMgmt(struct IOSana2Req
*request
, struct DevBase
*base
);
83 static const UWORD supported_commands
[] =
91 S2_ADDMULTICASTADDRESS
,
92 S2_DELMULTICASTADDRESS
,
105 S2_ADDMULTICASTADDRESSES
,
106 S2_DELMULTICASTADDRESSES
,
115 static const struct Sana2DeviceQuery sana2_info
=
128 const TEXT badmulticast_name
[] = "Bad multicasts";
129 const TEXT retries_name
[] = "Retries";
130 const TEXT fifo_underruns_name
[] = "Underruns";
133 const TEXT
*const special_stat_names
[] =
142 /****i* atheros5000.device/ServiceRequest **********************************
145 * ServiceRequest -- Attempt to service a device request.
148 * ServiceRequest(request)
150 * VOID ServiceRequest(struct IORequest *);
153 * Attempts to carry out a request. The relevant unit's semaphore must
154 * be obtained before calling this function. This function releases the
155 * semaphore before returning.
171 ****************************************************************************
175 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
179 switch(request
->ios2_Req
.io_Command
)
182 complete
= CmdRead(request
, base
);
185 complete
= CmdWrite(request
, base
);
188 complete
= CmdFlush((APTR
)request
, base
);
191 complete
= CmdS2DeviceQuery(request
, base
);
193 case S2_GETSTATIONADDRESS
:
194 complete
= CmdGetStationAddress(request
, base
);
196 case S2_CONFIGINTERFACE
:
197 complete
= CmdConfigInterface(request
, base
);
199 case S2_ADDMULTICASTADDRESS
:
200 complete
= CmdAddMulticastAddresses(request
, base
);
202 case S2_DELMULTICASTADDRESS
:
203 complete
= CmdDelMulticastAddresses(request
, base
);
206 complete
= CmdWrite(request
, base
);
209 complete
= CmdBroadcast(request
, base
);
212 complete
= CmdTrackType(request
, base
);
215 complete
= CmdUntrackType(request
, base
);
217 case S2_GETTYPESTATS
:
218 complete
= CmdGetTypeStats(request
, base
);
220 case S2_GETSPECIALSTATS
:
221 complete
= CmdGetSpecialStats(request
, base
);
223 case S2_GETGLOBALSTATS
:
224 complete
= CmdGetGlobalStats(request
, base
);
227 complete
= CmdOnEvent(request
, base
);
230 complete
= CmdReadOrphan(request
, base
);
233 complete
= CmdOnline(request
, base
);
236 complete
= CmdOffline(request
, base
);
238 case NSCMD_DEVICEQUERY
:
239 complete
= CmdDeviceQuery((APTR
)request
, base
);
241 case S2_ADDMULTICASTADDRESSES
:
242 complete
= CmdAddMulticastAddresses(request
, base
);
244 case S2_DELMULTICASTADDRESSES
:
245 complete
= CmdDelMulticastAddresses(request
, base
);
248 complete
= CmdSetOptions(request
, base
);
251 complete
= CmdSetKey(request
, base
);
254 complete
= CmdWriteMgmt(request
, base
);
257 complete
= CmdReadMgmt(request
, base
);
260 complete
= CmdInvalid(request
, base
);
263 if(complete
&& ((request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0))
264 ReplyMsg((APTR
)request
);
267 &((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->access_lock
);
273 /****i* atheros5000.device/CMD_INVALID *************************************
276 * CMD_INVALID -- Reject an invalid command.
284 * io_Error - IOERR_NOCMD.
294 ****************************************************************************
298 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
)
300 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
301 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
308 /****** atheros5000.device/CMD_READ ****************************************
311 * CMD_READ -- Read data.
337 ****************************************************************************
341 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
)
343 struct DevUnit
*unit
;
344 struct Opener
*opener
;
345 BOOL complete
= FALSE
;
347 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
349 if((unit
->flags
& UNITF_ONLINE
) != 0)
351 opener
= request
->ios2_BufferManagement
;
352 PutRequest(&opener
->read_port
, (APTR
)request
, base
);
356 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
357 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
368 /****** atheros5000.device/CMD_WRITE ***************************************
371 * CMD_WRITE -- Write data.
394 ****************************************************************************
398 /****** atheros5000.device/S2_MULTICAST ************************************
407 * ios2_DstAddr - multicast address.
424 ****************************************************************************
428 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
430 struct DevUnit
*unit
;
433 BOOL complete
= FALSE
;
435 /* Check request is valid */
437 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
438 if((unit
->flags
& UNITF_ONLINE
) == 0)
440 error
= S2ERR_OUTOFSERVICE
;
441 wire_error
= S2WERR_UNIT_OFFLINE
;
443 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
444 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
446 error
= S2ERR_BAD_ADDRESS
;
447 wire_error
= S2WERR_BAD_MULTICAST
;
450 /* Queue request for sending */
453 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
456 request
->ios2_Req
.io_Error
= error
;
457 request
->ios2_WireError
= wire_error
;
468 /****** atheros5000.device/CMD_FLUSH ***************************************
489 ****************************************************************************
493 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
495 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
502 /****** atheros5000.device/S2_DEVICEQUERY **********************************
505 * S2_DEVICEQUERY -- Query device capabilities.
510 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
524 ****************************************************************************
528 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
529 struct DevBase
*base
)
531 struct DevUnit
*unit
;
532 struct Sana2DeviceQuery
*info
;
533 ULONG size_available
, size
;
535 /* Copy device info */
537 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
538 info
= request
->ios2_StatData
;
539 size
= size_available
= info
->SizeAvailable
;
540 if(size
> sizeof(struct Sana2DeviceQuery
))
541 size
= sizeof(struct Sana2DeviceQuery
);
543 CopyMem(&sana2_info
, info
, size
);
544 info
->BPS
= unit
->speed
;
546 info
->SizeAvailable
= size_available
;
547 info
->SizeSupplied
= size
;
556 /****** atheros5000.device/S2_GETSTATIONADDDRESS ***************************
559 * S2_GETSTATIONADDDRESS
569 * ios2_SrcAddr - current address.
570 * ios2_DstAddr - default address (zero if none?).
580 ****************************************************************************
584 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
585 struct DevBase
*base
)
587 struct DevUnit
*unit
;
591 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
592 CopyMem(unit
->address
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
593 CopyMem(unit
->default_address
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
602 /****** atheros5000.device/S2_CONFIGINTERFACE ******************************
610 * ios2_SrcAddr - address to use.
615 * ios2_SrcAddr - address used.
625 ****************************************************************************
629 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
630 struct DevBase
*base
)
632 struct DevUnit
*unit
;
636 /* Configure adapter */
638 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
639 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
641 error
= S2ERR_BAD_STATE
;
642 wire_error
= S2WERR_IS_CONFIGURED
;
644 else if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
646 error
= S2ERR_BAD_STATE
;
647 wire_error
= S2WERR_GENERIC_ERROR
;
652 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
653 ConfigureAdapter(unit
, base
);
654 GoOnline(unit
, base
);
655 unit
->flags
|= UNITF_CONFIGURED
;
659 request
->ios2_Req
.io_Error
= error
;
660 request
->ios2_WireError
= wire_error
;
670 /****** atheros5000.device/S2_BROADCAST ************************************
695 ****************************************************************************
699 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
700 struct DevBase
*base
)
704 /* Fill in the broadcast address as destination */
706 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
707 request
->ios2_DstAddr
[i
] = 0xff;
709 /* Queue the write as normal */
711 return CmdWrite(request
, base
);
716 /****** atheros5000.device/S2_TRACKTYPE ************************************
724 * ios2_PacketType - packet type to start tracking.
738 ****************************************************************************
742 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
743 struct DevBase
*base
)
745 struct DevUnit
*unit
;
746 struct Opener
*opener
;
747 ULONG packet_type
, wire_error
;
748 struct TypeTracker
*tracker
;
749 struct TypeStats
*initial_stats
;
752 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
753 packet_type
= request
->ios2_PacketType
;
754 if(packet_type
<= ETH_MTU
)
755 packet_type
= ETH_MTU
;
757 /* Get global tracker */
759 tracker
= (struct TypeTracker
*)
760 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
763 tracker
->user_count
++;
767 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
770 tracker
->packet_type
= packet_type
;
771 tracker
->user_count
= 1;
774 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
779 /* Store initial figures for this opener */
781 opener
= request
->ios2_BufferManagement
;
782 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
785 if(initial_stats
!= NULL
)
787 error
= S2ERR_BAD_STATE
;
788 wire_error
= S2WERR_ALREADY_TRACKED
;
793 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
794 if(initial_stats
== NULL
)
796 error
= S2ERR_NO_RESOURCES
;
797 wire_error
= S2WERR_GENERIC_ERROR
;
803 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
804 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
809 request
->ios2_Req
.io_Error
= error
;
810 request
->ios2_WireError
= wire_error
;
816 /****** atheros5000.device/S2_UNTRACKTYPE **********************************
824 * ios2_PacketType - packet type to stop tracking.
838 ****************************************************************************
842 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
843 struct DevBase
*base
)
845 struct DevUnit
*unit
;
846 struct Opener
*opener
;
848 struct TypeTracker
*tracker
;
849 struct TypeStats
*initial_stats
;
851 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
852 packet_type
= request
->ios2_PacketType
;
853 if(packet_type
<= ETH_MTU
)
854 packet_type
= ETH_MTU
;
856 /* Get global tracker and initial figures */
858 tracker
= (struct TypeTracker
*)
859 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
860 opener
= request
->ios2_BufferManagement
;
861 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
864 /* Decrement tracker usage and free unused structures */
866 if(initial_stats
!= NULL
)
868 if((--tracker
->user_count
) == 0)
871 Remove((APTR
)tracker
);
873 FreeMem(tracker
, sizeof(struct TypeTracker
));
876 Remove((APTR
)initial_stats
);
877 FreeMem(initial_stats
, sizeof(struct TypeStats
));
881 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
882 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
892 /****** atheros5000.device/S2_GETTYPESTATS *********************************
900 * ios2_PacketType - packet type to get statistics on.
901 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
915 ****************************************************************************
919 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
920 struct DevBase
*base
)
922 struct DevUnit
*unit
;
923 struct Opener
*opener
;
925 struct TypeStats
*initial_stats
, *tracker
;
926 struct Sana2PacketTypeStats
*stats
;
928 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
929 packet_type
= request
->ios2_PacketType
;
931 /* Get global tracker and initial figures */
933 tracker
= FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
934 opener
= request
->ios2_BufferManagement
;
935 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
938 /* Copy and adjust figures */
940 if(initial_stats
!= NULL
)
942 stats
= request
->ios2_StatData
;
943 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
944 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
945 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
946 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
947 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
948 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
952 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
953 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
963 /****** atheros5000.device/S2_GETSPECIALSTATS ******************************
971 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
985 ****************************************************************************
989 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
990 struct DevBase
*base
)
992 struct DevUnit
*unit
;
994 struct Sana2SpecialStatHeader
*header
;
995 struct Sana2SpecialStatRecord
*record
;
999 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1000 header
= request
->ios2_StatData
;
1001 record
= (APTR
)(header
+ 1);
1003 stat_count
= header
->RecordCountMax
;
1004 if(stat_count
> STAT_COUNT
)
1005 stat_count
= STAT_COUNT
;
1007 for(i
= 0; i
< stat_count
; i
++)
1009 record
->Type
= (S2WireType_Ethernet
<< 16) + i
;
1010 record
->Count
= unit
->special_stats
[i
];
1011 record
->String
= special_stat_names
[i
];
1015 header
->RecordCountSupplied
= stat_count
;
1024 /****** atheros5000.device/S2_GETGLOBALSTATS *******************************
1032 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1046 ****************************************************************************
1050 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
1051 struct DevBase
*base
)
1053 struct DevUnit
*unit
;
1055 /* Update and copy stats */
1057 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1058 if((unit
->flags
& UNITF_ONLINE
) != 0)
1059 UpdateStats(unit
, base
);
1060 CopyMem(&unit
->stats
, request
->ios2_StatData
,
1061 sizeof(struct Sana2DeviceStats
));
1070 /****** atheros5000.device/S2_ONEVENT **************************************
1092 ****************************************************************************
1096 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
)
1098 struct DevUnit
*unit
;
1099 ULONG events
, wanted_events
;
1100 BOOL complete
= FALSE
;
1102 /* Check if we understand the event types */
1104 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1105 wanted_events
= request
->ios2_WireError
;
1106 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
1108 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
1109 events
= S2WERR_BAD_EVENT
;
1113 if((unit
->flags
& UNITF_ONLINE
) != 0)
1114 events
= S2EVENT_ONLINE
;
1116 events
= S2EVENT_OFFLINE
;
1118 events
&= wanted_events
;
1121 /* Reply request if a wanted event has already occurred */
1125 request
->ios2_WireError
= events
;
1129 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1138 /****** atheros5000.device/S2_READORPHAN ***********************************
1153 * ios2_PacketType - A copy of the packet's type field.
1168 ****************************************************************************
1172 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1173 struct DevBase
*base
)
1175 struct DevUnit
*unit
;
1178 BOOL complete
= FALSE
;
1180 /* Check request is valid */
1182 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1183 if((unit
->flags
& UNITF_ONLINE
) == 0)
1185 error
= S2ERR_OUTOFSERVICE
;
1186 wire_error
= S2WERR_UNIT_OFFLINE
;
1192 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1195 request
->ios2_Req
.io_Error
= error
;
1196 request
->ios2_WireError
= wire_error
;
1207 /****** atheros5000.device/S2_ONLINE ***************************************
1229 ****************************************************************************
1233 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1235 struct DevUnit
*unit
;
1240 /* Check request is valid */
1242 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1243 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
1245 error
= S2ERR_BAD_STATE
;
1246 wire_error
= S2WERR_NOT_CONFIGURED
;
1248 if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
1250 error
= S2ERR_OUTOFSERVICE
;
1251 wire_error
= S2WERR_RCVREL_HDW_ERR
;
1254 /* Clear global and special stats and put adapter back online */
1256 if((error
== 0) && ((unit
->flags
& UNITF_ONLINE
) == 0))
1258 unit
->stats
.PacketsReceived
= 0;
1259 unit
->stats
.PacketsSent
= 0;
1260 unit
->stats
.BadData
= 0;
1261 unit
->stats
.Overruns
= 0;
1262 unit
->stats
.UnknownTypesReceived
= 0;
1263 unit
->stats
.Reconfigurations
= 0;
1265 for(i
= 0; i
< STAT_COUNT
; i
++)
1266 unit
->special_stats
[i
] = 0;
1268 GoOnline(unit
, base
);
1273 request
->ios2_Req
.io_Error
= error
;
1274 request
->ios2_WireError
= wire_error
;
1280 /****** atheros5000.device/S2_OFFLINE **************************************
1302 ****************************************************************************
1306 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
)
1308 struct DevUnit
*unit
;
1310 /* Put adapter offline */
1312 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1313 if((unit
->flags
& UNITF_ONLINE
) != 0)
1314 GoOffline(unit
, base
);
1323 /****** atheros5000.device/NSCMD_DEVICEQUERY *******************************
1326 * NSCMD_DEVICEQUERY -- Query device capabilities.
1332 * io_Data - pointer to NSDeviceQueryResult structure.
1336 * io_Actual - size of structure device can handle.
1346 ****************************************************************************
1348 * Note that we have to pretend the request structure is an IOStdReq.
1352 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
1353 struct DevBase
*base
)
1355 struct NSDeviceQueryResult
*info
;
1357 /* Set structure size twice */
1359 info
= request
->io_Data
;
1360 request
->io_Actual
= info
->SizeAvailable
=
1361 (ULONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
1363 /* Report device details */
1365 info
->DeviceType
= NSDEVTYPE_SANA2
;
1366 info
->DeviceSubType
= 0;
1368 info
->SupportedCommands
= (APTR
)supported_commands
;
1377 /****** atheros5000.device/S2_ADDMULTICASTADDRESS **************************
1380 * S2_ADDMULTICASTADDRESS
1385 * ios2_SrcAddr - multicast address.
1399 ****************************************************************************
1403 /****** atheros5000.device/S2_ADDMULTICASTADDRESSES ************************
1406 * S2_ADDMULTICASTADDRESSES
1411 * ios2_SrcAddr - lower bound.
1412 * ios2_DstAddr - upper bound.
1426 ****************************************************************************
1430 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
1431 struct DevBase
*base
)
1433 struct DevUnit
*unit
;
1434 UBYTE
*lower_bound
, *upper_bound
;
1436 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1438 lower_bound
= request
->ios2_SrcAddr
;
1439 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
1440 upper_bound
= lower_bound
;
1442 upper_bound
= request
->ios2_DstAddr
;
1444 if(!AddMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1446 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1447 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
1457 /****** atheros5000.device/S2_DELMULTICASTADDRESS **************************
1460 * S2_DELMULTICASTADDRESS
1465 * ios2_SrcAddr - multicast address.
1479 ****************************************************************************
1483 /****** atheros5000.device/S2_DELMULTICASTADDRESSES ************************
1486 * S2_DELMULTICASTADDRESSES
1491 * ios2_SrcAddr - lower bound.
1492 * ios2_DstAddr - upper bound.
1506 ****************************************************************************
1510 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
1511 struct DevBase
*base
)
1513 struct DevUnit
*unit
;
1514 UBYTE
*lower_bound
, *upper_bound
;
1516 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1518 lower_bound
= request
->ios2_SrcAddr
;
1519 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
1520 upper_bound
= lower_bound
;
1522 upper_bound
= request
->ios2_DstAddr
;
1524 if(!RemMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1526 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
1527 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;
1537 /****** atheros5000.device/S2_SETOPTIONS ***********************************
1540 * S2_SETOPTIONS -- Set network options.
1543 * Set various parameters for the network interface. This command
1544 * should be called before going online to set any essential parameters
1545 * not covered elsewhere.
1548 * ios2_Data - Pointer to taglist that specifies the network and
1549 * parameters to use.
1552 * io_Error - Zero if successful; non-zero otherwise.
1553 * ios2_WireError - More specific error code.
1555 ****************************************************************************
1559 static BOOL
CmdSetOptions(struct IOSana2Req
*request
, struct DevBase
*base
)
1561 struct DevUnit
*unit
;
1566 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1567 reconfigure
= SetOptions(unit
, request
->ios2_Data
, base
);
1568 if(reconfigure
&& (unit
->flags
& UNITF_ONLINE
) != 0)
1569 ConfigureAdapter(unit
, base
);
1570 unit
->stats
.Reconfigurations
++;
1579 /****** atheros5000.device/S2_SETKEY ***************************************
1582 * S2_SETKEY -- Set an encryption key.
1587 * ios2_WireError - Key index.
1588 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1589 * ios2_DataLength - Key length.
1591 * ios2_StatData - RX counter number (NULL if unused).
1604 ****************************************************************************
1608 static BOOL
CmdSetKey(struct IOSana2Req
*request
, struct DevBase
*base
)
1610 struct DevUnit
*unit
;
1612 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1613 SetKey(unit
, request
->ios2_WireError
, request
->ios2_PacketType
,
1614 request
->ios2_Data
, request
->ios2_DataLength
, request
->ios2_StatData
,
1624 /****** atheros5000.device/S2_WRITEMGMT ************************************
1627 * S2_WRITEMGMT -- Write a management frame.
1632 * ios2_DataLength - full frame length.
1633 * ios2_Data - pointer to a complete IEEE 802.11 management frame.
1647 ****************************************************************************
1651 static BOOL
CmdWriteMgmt(struct IOSana2Req
*request
, struct DevBase
*base
)
1653 struct DevUnit
*unit
;
1656 BOOL complete
= FALSE
;
1658 /* Check request is valid */
1660 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1661 if((unit
->flags
& UNITF_ONLINE
) == 0)
1663 error
= S2ERR_OUTOFSERVICE
;
1664 wire_error
= S2WERR_UNIT_OFFLINE
;
1667 /* Queue request for sending */
1670 PutRequest(unit
->request_ports
[MGMT_QUEUE
], (APTR
)request
, base
);
1673 request
->ios2_Req
.io_Error
= error
;
1674 request
->ios2_WireError
= wire_error
;
1685 /****** atheros5000.device/S2_READMGMT *************************************
1688 * S2_READMGMT -- Read a management frame.
1693 * ios2_DataLength - size of frame buffer.
1694 * ios2_Data - pointer to a frame buffer.
1699 * ios2_DataLength - actual size of received frame.
1710 ****************************************************************************
1714 static BOOL
CmdReadMgmt(struct IOSana2Req
*request
, struct DevBase
*base
)
1716 struct DevUnit
*unit
;
1717 struct Opener
*opener
;
1718 BOOL complete
= FALSE
;
1720 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1722 if((unit
->flags
& UNITF_ONLINE
) != 0)
1724 opener
= request
->ios2_BufferManagement
;
1725 PutRequest(&opener
->mgmt_port
, (APTR
)request
, base
);
1729 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1730 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1741 /****i* atheros5000.device/PutRequest **************************************
1747 * PutRequest(port, request)
1749 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1760 ****************************************************************************
1764 VOID
PutRequest(struct MsgPort
*port
, struct IORequest
*request
,
1765 struct DevBase
*base
)
1767 request
->io_Flags
&= ~IOF_QUICK
;
1768 PutMsg(port
, (APTR
)request
);