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 \
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
[] =
94 S2_ADDMULTICASTADDRESS
,
95 S2_DELMULTICASTADDRESS
,
108 S2_ADDMULTICASTADDRESSES
,
109 S2_DELMULTICASTADDRESSES
,
120 static const struct Sana2DeviceQuery sana2_info
=
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
[] =
147 /****i* prism2.device/ServiceRequest ***************************************
150 * ServiceRequest -- Attempt to service a device request.
153 * ServiceRequest(request)
155 * VOID ServiceRequest(struct IORequest *);
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.
176 ****************************************************************************
180 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
184 switch(request
->ios2_Req
.io_Command
)
187 complete
= CmdRead(request
, base
);
190 complete
= CmdWrite(request
, base
);
193 complete
= CmdFlush((APTR
)request
, base
);
196 complete
= CmdS2DeviceQuery(request
, base
);
198 case S2_GETSTATIONADDRESS
:
199 complete
= CmdGetStationAddress(request
, base
);
201 case S2_CONFIGINTERFACE
:
202 complete
= CmdConfigInterface(request
, base
);
204 case S2_ADDMULTICASTADDRESS
:
205 complete
= CmdAddMulticastAddresses(request
, base
);
207 case S2_DELMULTICASTADDRESS
:
208 complete
= CmdDelMulticastAddresses(request
, base
);
211 complete
= CmdWrite(request
, base
);
214 complete
= CmdBroadcast(request
, base
);
217 complete
= CmdTrackType(request
, base
);
220 complete
= CmdUntrackType(request
, base
);
222 case S2_GETTYPESTATS
:
223 complete
= CmdGetTypeStats(request
, base
);
225 case S2_GETSPECIALSTATS
:
226 complete
= CmdGetSpecialStats(request
, base
);
228 case S2_GETGLOBALSTATS
:
229 complete
= CmdGetGlobalStats(request
, base
);
232 complete
= CmdOnEvent(request
, base
);
235 complete
= CmdReadOrphan(request
, base
);
238 complete
= CmdOnline(request
, base
);
241 complete
= CmdOffline(request
, base
);
243 case NSCMD_DEVICEQUERY
:
244 complete
= CmdDeviceQuery((APTR
)request
, base
);
246 case S2_ADDMULTICASTADDRESSES
:
247 complete
= CmdAddMulticastAddresses(request
, base
);
249 case S2_DELMULTICASTADDRESSES
:
250 complete
= CmdDelMulticastAddresses(request
, base
);
252 case S2_GETSIGNALQUALITY
:
253 complete
= CmdGetSignalQuality(request
, base
);
256 complete
= CmdGetNetworks(request
, base
);
259 complete
= CmdSetOptions(request
, base
);
262 complete
= CmdSetKey(request
, base
);
264 case S2_GETNETWORKINFO
:
265 complete
= CmdGetNetworkInfo(request
, base
);
268 complete
= CmdInvalid(request
, base
);
271 if(complete
&& ((request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0))
272 ReplyMsg((APTR
)request
);
275 &((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->access_lock
);
281 /****i* prism2.device/CMD_INVALID ******************************************
284 * CMD_INVALID -- Reject an invalid command.
292 * io_Error - IOERR_NOCMD.
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
;
316 /****** prism2.device/CMD_READ *********************************************
319 * CMD_READ -- Read data.
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
);
364 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
365 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
376 /****** prism2.device/CMD_WRITE ********************************************
379 * CMD_WRITE -- Write data.
402 ****************************************************************************
406 /****** prism2.device/S2_MULTICAST *****************************************
415 * ios2_DstAddr - multicast address.
432 ****************************************************************************
436 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
438 struct DevUnit
*unit
;
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 */
462 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
465 request
->ios2_Req
.io_Error
= error
;
466 request
->ios2_WireError
= wire_error
;
477 /****** prism2.device/CMD_FLUSH ********************************************
498 ****************************************************************************
502 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
504 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
511 /****** prism2.device/S2_DEVICEQUERY ***************************************
514 * S2_DEVICEQUERY -- Query device capabilities.
519 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
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
;
565 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
568 * S2_GETSTATIONADDDRESS
578 * ios2_SrcAddr - current address.
579 * ios2_DstAddr - default address (zero if none?).
589 ****************************************************************************
593 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
594 struct DevBase
*base
)
596 struct DevUnit
*unit
;
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
);
611 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
619 * ios2_SrcAddr - address to use.
624 * ios2_SrcAddr - address used.
634 ****************************************************************************
638 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
639 struct DevBase
*base
)
641 struct DevUnit
*unit
;
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
;
660 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
661 ConfigureAdapter(unit
, base
);
662 GoOnline(unit
, base
);
663 unit
->flags
|= UNITF_CONFIGURED
;
667 request
->ios2_Req
.io_Error
= error
;
668 request
->ios2_WireError
= wire_error
;
678 /****** prism2.device/S2_BROADCAST *****************************************
703 ****************************************************************************
707 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
708 struct DevBase
*base
)
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 *****************************************
732 * ios2_PacketType - packet type to start tracking.
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
;
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
);
771 tracker
->user_count
++;
775 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
778 tracker
->packet_type
= packet_type
;
779 tracker
->user_count
= 1;
782 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
787 /* Store initial figures for this opener */
789 opener
= request
->ios2_BufferManagement
;
790 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
793 if(initial_stats
!= NULL
)
795 error
= S2ERR_BAD_STATE
;
796 wire_error
= S2WERR_ALREADY_TRACKED
;
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
;
811 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
812 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
817 request
->ios2_Req
.io_Error
= error
;
818 request
->ios2_WireError
= wire_error
;
824 /****** prism2.device/S2_UNTRACKTYPE ***************************************
832 * ios2_PacketType - packet type to stop tracking.
846 ****************************************************************************
850 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
851 struct DevBase
*base
)
853 struct DevUnit
*unit
;
854 struct Opener
*opener
;
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
,
872 /* Decrement tracker usage and free unused structures */
874 if(initial_stats
!= NULL
)
876 if((--tracker
->user_count
) == 0)
879 Remove((APTR
)tracker
);
881 FreeMem(tracker
, sizeof(struct TypeTracker
));
884 Remove((APTR
)initial_stats
);
885 FreeMem(initial_stats
, sizeof(struct TypeStats
));
889 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
890 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
900 /****** prism2.device/S2_GETTYPESTATS **************************************
908 * ios2_PacketType - packet type to get statistics on.
909 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
923 ****************************************************************************
927 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
928 struct DevBase
*base
)
930 struct DevUnit
*unit
;
931 struct Opener
*opener
;
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
,
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
;
960 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
961 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
971 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
979 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
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
;
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
];
1023 header
->RecordCountSupplied
= stat_count
;
1032 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1040 * ios2_StatData - Pointer to Sana2DeviceStats structure.
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
));
1078 /****** prism2.device/S2_ONEVENT *******************************************
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
;
1121 if((unit
->flags
& UNITF_ONLINE
) != 0)
1122 events
= S2EVENT_ONLINE
;
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]++;
1134 request
->ios2_WireError
= events
;
1138 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1147 /****** prism2.device/S2_READORPHAN ****************************************
1162 * ios2_PacketType - A copy of the packet's type field.
1177 ****************************************************************************
1181 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1182 struct DevBase
*base
)
1184 struct DevUnit
*unit
;
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
;
1201 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1204 request
->ios2_Req
.io_Error
= error
;
1205 request
->ios2_WireError
= wire_error
;
1216 /****** prism2.device/S2_ONLINE ********************************************
1238 ****************************************************************************
1242 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1244 struct DevUnit
*unit
;
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
);
1282 request
->ios2_Req
.io_Error
= error
;
1283 request
->ios2_WireError
= wire_error
;
1289 /****** prism2.device/S2_OFFLINE *******************************************
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
);
1332 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1335 * NSCMD_DEVICEQUERY -- Query device capabilities.
1341 * io_Data - pointer to NSDeviceQueryResult structure.
1345 * io_Actual - size of structure device can handle.
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
;
1386 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1389 * S2_ADDMULTICASTADDRESS
1394 * ios2_SrcAddr - multicast address.
1408 ****************************************************************************
1412 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1415 * S2_ADDMULTICASTADDRESSES
1420 * ios2_SrcAddr - lower bound.
1421 * ios2_DstAddr - upper bound.
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
;
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
;
1466 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1469 * S2_DELMULTICASTADDRESS
1474 * ios2_SrcAddr - multicast address.
1488 ****************************************************************************
1492 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1495 * S2_DELMULTICASTADDRESSES
1500 * ios2_SrcAddr - lower bound.
1501 * ios2_DstAddr - upper bound.
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
;
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
;
1546 /****** prism2.device/S2_GETSIGNALQUALITY **********************************
1549 * S2_GETSIGNALQUALITY -- Get signal quality statistics.
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.
1557 * ios2_StatData - Pointer to Sana2SignalQuality structure.
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
));
1583 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1584 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1594 /****** prism2.device/S2_GETNETWORKS ***************************************
1597 * S2_GETNETWORKS -- Scan for available networks.
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.
1614 * ios2_Data - Pointer to an Exec memory pool.
1615 * ios2_StatData - Pointer to taglist that specifies parameters to use.
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
;
1634 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
= (struct TagItem
*)request
->ios2_StatData
;
1643 ssid
= (const TEXT
*)GetTagData(S2INFO_SSID
, (UPINT
)NULL
, tag_list
);
1644 StartScan(unit
, ssid
, base
);
1648 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1649 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1660 /****** prism2.device/S2_SETOPTIONS ****************************************
1663 * S2_SETOPTIONS -- Associate with a network.
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.
1672 * ios2_Data - Pointer to taglist that specifies the network and
1673 * parameters to use.
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
;
1689 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1690 SetOptions(unit
, request
->ios2_Data
, base
);
1692 if((unit
->flags
& UNITF_ONLINE
) != 0)
1693 //&& FindTagItem(P2OPT_Key, request->ios2_Data) == NULL)
1694 ConfigureAdapter(unit
, base
);
1696 unit
->stats
.Reconfigurations
++;
1705 /****** prism2.device/S2_SETKEY ********************************************
1708 * S2_SETKEY -- Set an encryption key.
1713 * ios2_WireError - Key index.
1714 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1715 * ios2_DataLength - Key length.
1717 * ios2_StatData - RX counter number (NULL if unused).
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
,
1750 /****** prism2.device/S2_GETNETWORKINFO ************************************
1753 * S2_GETNETWORKINFO -- Get information on current network.
1758 * ios2_Data - Pointer to an Exec memory pool.
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
;
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
;
1788 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1789 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1799 /****i* prism2.device/PutRequest *******************************************
1805 * PutRequest(port, request)
1807 * VOID PutRequest(struct MsgPort *, struct IORequest *);
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
);