5 Copyright (C) 2001-2006 Neil Cafferkey
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include <exec/types.h>
26 #include <exec/errors.h>
27 #include <exec/initializers.h>
28 #include <devices/newstyle.h>
30 #include <proto/exec.h>
31 #include <proto/utility.h>
35 #include "request_protos.h"
36 #include "unit_protos.h"
39 #define KNOWN_EVENTS \
40 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
41 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
44 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
);
45 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
);
46 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
);
47 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
CmdGetSignalQuality(struct IOSana2Req
*request
,
78 struct DevBase
*base
);
81 static const UWORD supported_commands
[] =
89 S2_ADDMULTICASTADDRESS
,
90 S2_DELMULTICASTADDRESS
,
103 S2_ADDMULTICASTADDRESSES
,
104 S2_DELMULTICASTADDRESSES
,
110 static const struct Sana2DeviceQuery sana2_info
=
123 const TEXT badmulticast_name
[] = "Bad multicasts";
124 const TEXT retries_name
[] = "Retries";
125 const TEXT fifo_underruns_name
[] = "Underruns";
128 const TEXT
*const special_stat_names
[] =
137 /****i* prism2.device/ServiceRequest ***************************************
140 * ServiceRequest -- Attempt to service a device request.
143 * ServiceRequest(request)
145 * VOID ServiceRequest(struct IORequest *);
148 * Attempts to carry out a request. The relevant unit's semaphore must
149 * be obtained before calling this function. This function releases the
150 * semaphore before returning.
166 ****************************************************************************
170 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
174 switch(request
->ios2_Req
.io_Command
)
177 complete
= CmdRead(request
, base
);
180 complete
= CmdWrite(request
, base
);
183 complete
= CmdFlush((APTR
)request
, base
);
186 complete
= CmdS2DeviceQuery(request
, base
);
188 case S2_GETSTATIONADDRESS
:
189 complete
= CmdGetStationAddress(request
, base
);
191 case S2_CONFIGINTERFACE
:
192 complete
= CmdConfigInterface(request
, base
);
194 case S2_ADDMULTICASTADDRESS
:
195 complete
= CmdAddMulticastAddresses(request
, base
);
197 case S2_DELMULTICASTADDRESS
:
198 complete
= CmdDelMulticastAddresses(request
, base
);
201 complete
= CmdWrite(request
, base
);
204 complete
= CmdBroadcast(request
, base
);
207 complete
= CmdTrackType(request
, base
);
210 complete
= CmdUntrackType(request
, base
);
212 case S2_GETTYPESTATS
:
213 complete
= CmdGetTypeStats(request
, base
);
215 case S2_GETSPECIALSTATS
:
216 complete
= CmdGetSpecialStats(request
, base
);
218 case S2_GETGLOBALSTATS
:
219 complete
= CmdGetGlobalStats(request
, base
);
222 complete
= CmdOnEvent(request
, base
);
225 complete
= CmdReadOrphan(request
, base
);
228 complete
= CmdOnline(request
, base
);
231 complete
= CmdOffline(request
, base
);
233 case NSCMD_DEVICEQUERY
:
234 complete
= CmdDeviceQuery((APTR
)request
, base
);
236 case S2_ADDMULTICASTADDRESSES
:
237 complete
= CmdAddMulticastAddresses(request
, base
);
239 case S2_DELMULTICASTADDRESSES
:
240 complete
= CmdDelMulticastAddresses(request
, base
);
242 case P2_GETSIGNALQUALITY
:
243 complete
= CmdGetSignalQuality(request
, base
);
246 complete
= CmdInvalid(request
, base
);
249 if(complete
&& ((request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0))
250 ReplyMsg((APTR
)request
);
253 &((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->access_lock
);
259 /****i* prism2.device/CMD_INVALID ******************************************
262 * CMD_INVALID -- Reject an invalid command.
270 * io_Error - IOERR_NOCMD.
280 ****************************************************************************
284 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
)
286 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
287 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
294 /****** prism2.device/CMD_READ *********************************************
297 * CMD_READ -- Read data.
323 ****************************************************************************
327 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
)
329 struct DevUnit
*unit
;
330 struct Opener
*opener
;
331 BOOL complete
= FALSE
;
333 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
335 if((unit
->flags
& UNITF_ONLINE
) != 0)
337 opener
= request
->ios2_BufferManagement
;
338 PutRequest(&opener
->read_port
, (APTR
)request
, base
);
342 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
343 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
354 /****** prism2.device/CMD_WRITE ********************************************
357 * CMD_WRITE -- Write data.
380 ****************************************************************************
384 /****** prism2.device/S2_MULTICAST *****************************************
393 * ios2_DstAddr - multicast address.
410 ****************************************************************************
414 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
416 struct DevUnit
*unit
;
419 BOOL complete
= FALSE
;
421 /* Check request is valid */
423 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
424 if((unit
->flags
& UNITF_ONLINE
) == 0)
426 error
= S2ERR_OUTOFSERVICE
;
427 wire_error
= S2WERR_UNIT_OFFLINE
;
429 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
430 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
432 error
= S2ERR_BAD_ADDRESS
;
433 wire_error
= S2WERR_BAD_MULTICAST
;
436 /* Queue request for sending */
439 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
442 request
->ios2_Req
.io_Error
= error
;
443 request
->ios2_WireError
= wire_error
;
454 /****** prism2.device/CMD_FLUSH ********************************************
475 ****************************************************************************
479 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
481 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
488 /****** prism2.device/S2_DEVICEQUERY ***************************************
491 * S2_DEVICEQUERY -- Query device capabilities.
496 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
510 ****************************************************************************
514 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
515 struct DevBase
*base
)
517 struct DevUnit
*unit
;
518 struct Sana2DeviceQuery
*info
;
519 ULONG size_available
, size
;
521 /* Copy device info */
523 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
524 info
= request
->ios2_StatData
;
525 size
= size_available
= info
->SizeAvailable
;
526 if(size
> sizeof(struct Sana2DeviceQuery
))
527 size
= sizeof(struct Sana2DeviceQuery
);
529 CopyMem(&sana2_info
, info
, size
);
530 info
->BPS
= unit
->speed
;
532 info
->SizeAvailable
= size_available
;
533 info
->SizeSupplied
= size
;
542 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
545 * S2_GETSTATIONADDDRESS
555 * ios2_SrcAddr - current address.
556 * ios2_DstAddr - default address (zero if none?).
566 ****************************************************************************
570 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
571 struct DevBase
*base
)
573 struct DevUnit
*unit
;
577 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
578 CopyMem(unit
->address
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
579 CopyMem(unit
->default_address
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
588 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
596 * ios2_SrcAddr - address to use.
601 * ios2_SrcAddr - address used.
611 ****************************************************************************
615 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
616 struct DevBase
*base
)
618 struct DevUnit
*unit
;
622 /* Configure adapter */
624 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
625 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
627 error
= S2ERR_BAD_STATE
;
628 wire_error
= S2WERR_IS_CONFIGURED
;
630 else if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
632 error
= S2ERR_BAD_STATE
;
633 wire_error
= S2WERR_GENERIC_ERROR
;
638 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
639 ConfigureAdapter(unit
, base
);
640 GoOnline(unit
, base
);
641 unit
->flags
|= UNITF_CONFIGURED
;
645 request
->ios2_Req
.io_Error
= error
;
646 request
->ios2_WireError
= S2WERR_IS_CONFIGURED
;
656 /****** prism2.device/S2_BROADCAST *****************************************
681 ****************************************************************************
685 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
686 struct DevBase
*base
)
688 /* Fill in the broadcast address as destination */
690 *((ULONG
*)request
->ios2_DstAddr
) = 0xffffffff;
691 *((UWORD
*)(request
->ios2_DstAddr
+ 4)) = 0xffff;
693 /* Queue the write as normal */
695 return CmdWrite(request
, base
);
700 /****** prism2.device/S2_TRACKTYPE *****************************************
708 * ios2_PacketType - packet type to start tracking.
722 ****************************************************************************
726 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
727 struct DevBase
*base
)
729 struct DevUnit
*unit
;
730 struct Opener
*opener
;
731 ULONG packet_type
, wire_error
;
732 struct TypeTracker
*tracker
;
733 struct TypeStats
*initial_stats
;
736 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
737 packet_type
= request
->ios2_PacketType
;
738 if(packet_type
<= ETH_MTU
)
739 packet_type
= ETH_MTU
;
741 /* Get global tracker */
743 tracker
= (struct TypeTracker
*)
744 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
747 tracker
->user_count
++;
751 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
754 tracker
->packet_type
= packet_type
;
755 tracker
->user_count
= 1;
758 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
763 /* Store initial figures for this opener */
765 opener
= request
->ios2_BufferManagement
;
766 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
769 if(initial_stats
!= NULL
)
771 error
= S2ERR_BAD_STATE
;
772 wire_error
= S2WERR_ALREADY_TRACKED
;
777 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
778 if(initial_stats
== NULL
)
780 error
= S2ERR_NO_RESOURCES
;
781 wire_error
= S2WERR_GENERIC_ERROR
;
787 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
788 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
793 request
->ios2_Req
.io_Error
= error
;
794 request
->ios2_WireError
= wire_error
;
800 /****** prism2.device/S2_UNTRACKTYPE ***************************************
808 * ios2_PacketType - packet type to stop tracking.
822 ****************************************************************************
826 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
827 struct DevBase
*base
)
829 struct DevUnit
*unit
;
830 struct Opener
*opener
;
832 struct TypeTracker
*tracker
;
833 struct TypeStats
*initial_stats
;
835 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
836 packet_type
= request
->ios2_PacketType
;
837 if(packet_type
<= ETH_MTU
)
838 packet_type
= ETH_MTU
;
840 /* Get global tracker and initial figures */
842 tracker
= (struct TypeTracker
*)
843 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
844 opener
= request
->ios2_BufferManagement
;
845 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
848 /* Decrement tracker usage and free unused structures */
850 if(initial_stats
!= NULL
)
852 if((--tracker
->user_count
) == 0)
855 Remove((APTR
)tracker
);
857 FreeMem(tracker
, sizeof(struct TypeTracker
));
860 Remove((APTR
)initial_stats
);
861 FreeMem(initial_stats
, sizeof(struct TypeStats
));
865 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
866 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
876 /****** prism2.device/S2_GETTYPESTATS **************************************
884 * ios2_PacketType - packet type to get statistics on.
885 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
899 ****************************************************************************
903 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
904 struct DevBase
*base
)
906 struct DevUnit
*unit
;
907 struct Opener
*opener
;
909 struct TypeStats
*initial_stats
, *tracker
;
910 struct Sana2PacketTypeStats
*stats
;
912 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
913 packet_type
= request
->ios2_PacketType
;
915 /* Get global tracker and initial figures */
917 tracker
= FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
918 opener
= request
->ios2_BufferManagement
;
919 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
922 /* Copy and adjust figures */
924 if(initial_stats
!= NULL
)
926 stats
= request
->ios2_StatData
;
927 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
928 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
929 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
930 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
931 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
932 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
936 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
937 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
947 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
955 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
969 ****************************************************************************
973 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
974 struct DevBase
*base
)
976 struct DevUnit
*unit
;
978 struct Sana2SpecialStatHeader
*header
;
979 struct Sana2SpecialStatRecord
*record
;
983 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
984 header
= request
->ios2_StatData
;
985 record
= (APTR
)(header
+ 1);
987 stat_count
= header
->RecordCountMax
;
988 if(stat_count
> STAT_COUNT
)
989 stat_count
= STAT_COUNT
;
991 for(i
= 0; i
< stat_count
; i
++)
993 record
->Type
= (S2WireType_Ethernet
<< 16) + i
;
994 record
->Count
= unit
->special_stats
[i
];
995 record
->String
= special_stat_names
[i
];
999 header
->RecordCountSupplied
= stat_count
;
1008 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1016 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1030 ****************************************************************************
1034 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
1035 struct DevBase
*base
)
1037 struct DevUnit
*unit
;
1039 /* Update and copy stats */
1041 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1042 if((unit
->flags
& UNITF_ONLINE
) != 0)
1043 UpdateStats(unit
, base
);
1044 CopyMem(&unit
->stats
, request
->ios2_StatData
,
1045 sizeof(struct Sana2DeviceStats
));
1054 /****** prism2.device/S2_ONEVENT *******************************************
1076 ****************************************************************************
1080 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
)
1082 struct DevUnit
*unit
;
1083 ULONG events
, wanted_events
;
1084 BOOL complete
= FALSE
;
1086 /* Check if we understand the event types */
1088 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1089 wanted_events
= request
->ios2_WireError
;
1090 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
1092 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
1093 events
= S2WERR_BAD_EVENT
;
1097 if((unit
->flags
& UNITF_ONLINE
) != 0)
1098 events
= S2EVENT_ONLINE
;
1100 events
= S2EVENT_OFFLINE
;
1102 events
&= wanted_events
;
1105 /* Reply request if a wanted event has already occurred */
1109 request
->ios2_WireError
= events
;
1113 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1122 /****** prism2.device/S2_READORPHAN ****************************************
1137 * ios2_PacketType - A copy of the packet's type field.
1152 ****************************************************************************
1156 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1157 struct DevBase
*base
)
1159 struct DevUnit
*unit
;
1162 BOOL complete
= FALSE
;
1164 /* Check request is valid */
1166 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1167 if((unit
->flags
& UNITF_ONLINE
) == 0)
1169 error
= S2ERR_OUTOFSERVICE
;
1170 wire_error
= S2WERR_UNIT_OFFLINE
;
1176 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1179 request
->ios2_Req
.io_Error
= error
;
1180 request
->ios2_WireError
= wire_error
;
1191 /****** prism2.device/S2_ONLINE ********************************************
1213 ****************************************************************************
1217 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1219 struct DevUnit
*unit
;
1224 /* Check request is valid */
1226 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1227 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
1229 error
= S2ERR_BAD_STATE
;
1230 wire_error
= S2WERR_NOT_CONFIGURED
;
1232 if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
1234 error
= S2ERR_OUTOFSERVICE
;
1235 wire_error
= S2WERR_RCVREL_HDW_ERR
;
1238 /* Clear global and special stats and put adapter back online */
1240 if((error
== 0) && ((unit
->flags
& UNITF_ONLINE
) == 0))
1242 unit
->stats
.PacketsReceived
= 0;
1243 unit
->stats
.PacketsSent
= 0;
1244 unit
->stats
.BadData
= 0;
1245 unit
->stats
.Overruns
= 0;
1246 unit
->stats
.UnknownTypesReceived
= 0;
1247 unit
->stats
.Reconfigurations
= 0;
1249 for(i
= 0; i
< STAT_COUNT
; i
++)
1250 unit
->special_stats
[i
] = 0;
1252 GoOnline(unit
, base
);
1257 request
->ios2_Req
.io_Error
= error
;
1258 request
->ios2_WireError
= wire_error
;
1264 /****** prism2.device/S2_OFFLINE *******************************************
1286 ****************************************************************************
1290 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
)
1292 struct DevUnit
*unit
;
1294 /* Put adapter offline */
1296 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1297 if((unit
->flags
& UNITF_ONLINE
) != 0)
1298 GoOffline(unit
, base
);
1307 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1310 * NSCMD_DEVICEQUERY -- Query device capabilities.
1316 * io_Data - pointer to NSDeviceQueryResult structure.
1320 * io_Actual - size of structure device can handle.
1330 ****************************************************************************
1332 * Note that we have to pretend the request structure is an IOStdReq.
1336 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
1337 struct DevBase
*base
)
1339 struct NSDeviceQueryResult
*info
;
1341 /* Set structure size twice */
1343 info
= request
->io_Data
;
1344 request
->io_Actual
= info
->SizeAvailable
=
1345 (ULONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
1347 /* Report device details */
1349 info
->DeviceType
= NSDEVTYPE_SANA2
;
1350 info
->DeviceSubType
= 0;
1352 info
->SupportedCommands
= (APTR
)supported_commands
;
1361 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1364 * S2_ADDMULTICASTADDRESS
1369 * ios2_SrcAddr - multicast address.
1383 ****************************************************************************
1387 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1390 * S2_ADDMULTICASTADDRESSES
1395 * ios2_SrcAddr - lower bound.
1396 * ios2_DstAddr - upper bound.
1410 ****************************************************************************
1414 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
1415 struct DevBase
*base
)
1417 struct DevUnit
*unit
;
1418 UBYTE
*lower_bound
, *upper_bound
;
1420 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1422 lower_bound
= request
->ios2_SrcAddr
;
1423 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
1424 upper_bound
= lower_bound
;
1426 upper_bound
= request
->ios2_DstAddr
;
1428 if(!AddMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1430 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1431 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
1441 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1444 * S2_DELMULTICASTADDRESS
1449 * ios2_SrcAddr - multicast address.
1463 ****************************************************************************
1467 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1470 * S2_DELMULTICASTADDRESSES
1475 * ios2_SrcAddr - lower bound.
1476 * ios2_DstAddr - upper bound.
1490 ****************************************************************************
1494 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
1495 struct DevBase
*base
)
1497 struct DevUnit
*unit
;
1498 UBYTE
*lower_bound
, *upper_bound
;
1500 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1502 lower_bound
= request
->ios2_SrcAddr
;
1503 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
1504 upper_bound
= lower_bound
;
1506 upper_bound
= request
->ios2_DstAddr
;
1508 if(!RemMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1510 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
1511 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;
1521 /****** prism2.device/P2_GETSIGNALQUALITY **********************************
1524 * P2_GETSIGNALQUALITY -- Get signal quality statistics.
1527 * This command fills in the supplied Sana2SignalQuality structure with
1528 * current signal and noise levels. The unit for these figures is dBm.
1529 * Typically, they are negative values.
1532 * ios2_StatData - Pointer to Sana2SignalQuality structure.
1535 * io_Error - Zero if successful; non-zero otherwise.
1536 * ios2_WireError - More specific error code.
1538 ****************************************************************************
1542 static BOOL
CmdGetSignalQuality(struct IOSana2Req
*request
,
1543 struct DevBase
*base
)
1545 struct DevUnit
*unit
;
1547 /* Update and copy stats */
1549 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1550 if((unit
->flags
& UNITF_ONLINE
) != 0)
1552 if((unit
->flags
& UNITF_ONLINE
) != 0)
1553 UpdateSignalQuality(unit
, base
);
1554 CopyMem(&unit
->signal_quality
, request
->ios2_StatData
,
1555 sizeof(struct Sana2SignalQuality
));
1559 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1560 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1571 /****i* prism2.device/PutRequest *******************************************
1577 * PutRequest(port, request)
1579 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1590 ****************************************************************************
1594 VOID
PutRequest(struct MsgPort
*port
, struct IORequest
*request
,
1595 struct DevBase
*base
)
1597 request
->io_Flags
&= ~IOF_QUICK
;
1598 PutMsg(port
, (APTR
)request
);