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* realtek8180.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* realtek8180.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 /****** realtek8180.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 /****** realtek8180.device/CMD_WRITE ***************************************
371 * CMD_WRITE -- Write data.
394 ****************************************************************************
398 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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 /****** realtek8180.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
;
1057 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1058 CopyMem(&unit
->stats
, request
->ios2_StatData
,
1059 sizeof(struct Sana2DeviceStats
));
1068 /****** realtek8180.device/S2_ONEVENT **************************************
1090 ****************************************************************************
1094 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
)
1096 struct DevUnit
*unit
;
1097 ULONG events
, wanted_events
;
1098 BOOL complete
= FALSE
;
1100 /* Check if we understand the event types */
1102 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1103 wanted_events
= request
->ios2_WireError
;
1104 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
1106 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
1107 events
= S2WERR_BAD_EVENT
;
1111 if((unit
->flags
& UNITF_ONLINE
) != 0)
1112 events
= S2EVENT_ONLINE
;
1114 events
= S2EVENT_OFFLINE
;
1116 events
&= wanted_events
;
1119 /* Reply request if a wanted event has already occurred */
1123 request
->ios2_WireError
= events
;
1127 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1136 /****** realtek8180.device/S2_READORPHAN ***********************************
1151 * ios2_PacketType - A copy of the packet's type field.
1166 ****************************************************************************
1170 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1171 struct DevBase
*base
)
1173 struct DevUnit
*unit
;
1176 BOOL complete
= FALSE
;
1178 /* Check request is valid */
1180 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1181 if((unit
->flags
& UNITF_ONLINE
) == 0)
1183 error
= S2ERR_OUTOFSERVICE
;
1184 wire_error
= S2WERR_UNIT_OFFLINE
;
1190 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1193 request
->ios2_Req
.io_Error
= error
;
1194 request
->ios2_WireError
= wire_error
;
1205 /****** realtek8180.device/S2_ONLINE ***************************************
1227 ****************************************************************************
1231 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1233 struct DevUnit
*unit
;
1238 /* Check request is valid */
1240 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1241 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
1243 error
= S2ERR_BAD_STATE
;
1244 wire_error
= S2WERR_NOT_CONFIGURED
;
1246 if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
1248 error
= S2ERR_OUTOFSERVICE
;
1249 wire_error
= S2WERR_RCVREL_HDW_ERR
;
1252 /* Clear global and special stats and put adapter back online */
1254 if((error
== 0) && ((unit
->flags
& UNITF_ONLINE
) == 0))
1256 unit
->stats
.PacketsReceived
= 0;
1257 unit
->stats
.PacketsSent
= 0;
1258 unit
->stats
.BadData
= 0;
1259 unit
->stats
.Overruns
= 0;
1260 unit
->stats
.UnknownTypesReceived
= 0;
1261 unit
->stats
.Reconfigurations
= 0;
1263 for(i
= 0; i
< STAT_COUNT
; i
++)
1264 unit
->special_stats
[i
] = 0;
1266 GoOnline(unit
, base
);
1271 request
->ios2_Req
.io_Error
= error
;
1272 request
->ios2_WireError
= wire_error
;
1278 /****** realtek8180.device/S2_OFFLINE **************************************
1300 ****************************************************************************
1304 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
)
1306 struct DevUnit
*unit
;
1308 /* Put adapter offline */
1310 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1311 if((unit
->flags
& UNITF_ONLINE
) != 0)
1312 GoOffline(unit
, base
);
1321 /****** realtek8180.device/NSCMD_DEVICEQUERY *******************************
1324 * NSCMD_DEVICEQUERY -- Query device capabilities.
1330 * io_Data - pointer to NSDeviceQueryResult structure.
1334 * io_Actual - size of structure device can handle.
1344 ****************************************************************************
1346 * Note that we have to pretend the request structure is an IOStdReq.
1350 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
1351 struct DevBase
*base
)
1353 struct NSDeviceQueryResult
*info
;
1355 /* Set structure size twice */
1357 info
= request
->io_Data
;
1358 request
->io_Actual
= info
->SizeAvailable
=
1359 (ULONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
1361 /* Report device details */
1363 info
->DeviceType
= NSDEVTYPE_SANA2
;
1364 info
->DeviceSubType
= 0;
1366 info
->SupportedCommands
= (APTR
)supported_commands
;
1375 /****** realtek8180.device/S2_ADDMULTICASTADDRESS **************************
1378 * S2_ADDMULTICASTADDRESS
1383 * ios2_SrcAddr - multicast address.
1397 ****************************************************************************
1401 /****** realtek8180.device/S2_ADDMULTICASTADDRESSES ************************
1404 * S2_ADDMULTICASTADDRESSES
1409 * ios2_SrcAddr - lower bound.
1410 * ios2_DstAddr - upper bound.
1424 ****************************************************************************
1428 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
1429 struct DevBase
*base
)
1431 struct DevUnit
*unit
;
1432 UBYTE
*lower_bound
, *upper_bound
;
1434 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1436 lower_bound
= request
->ios2_SrcAddr
;
1437 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
1438 upper_bound
= lower_bound
;
1440 upper_bound
= request
->ios2_DstAddr
;
1442 if(!AddMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1444 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1445 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
1455 /****** realtek8180.device/S2_DELMULTICASTADDRESS **************************
1458 * S2_DELMULTICASTADDRESS
1463 * ios2_SrcAddr - multicast address.
1477 ****************************************************************************
1481 /****** realtek8180.device/S2_DELMULTICASTADDRESSES ************************
1484 * S2_DELMULTICASTADDRESSES
1489 * ios2_SrcAddr - lower bound.
1490 * ios2_DstAddr - upper bound.
1504 ****************************************************************************
1508 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
1509 struct DevBase
*base
)
1511 struct DevUnit
*unit
;
1512 UBYTE
*lower_bound
, *upper_bound
;
1514 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1516 lower_bound
= request
->ios2_SrcAddr
;
1517 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
1518 upper_bound
= lower_bound
;
1520 upper_bound
= request
->ios2_DstAddr
;
1522 if(!RemMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1524 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
1525 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;
1535 /****** realtek8180.device/S2_SETOPTIONS ***********************************
1538 * S2_SETOPTIONS -- Set network options.
1541 * Set various parameters for the network interface. This command
1542 * should be called before going online to set any essential parameters
1543 * not covered elsewhere.
1546 * ios2_Data - Pointer to taglist that specifies the network and
1547 * parameters to use.
1550 * io_Error - Zero if successful; non-zero otherwise.
1551 * ios2_WireError - More specific error code.
1553 ****************************************************************************
1557 static BOOL
CmdSetOptions(struct IOSana2Req
*request
, struct DevBase
*base
)
1559 struct DevUnit
*unit
;
1564 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1565 reconfigure
= SetOptions(unit
, request
->ios2_Data
, base
);
1566 if(reconfigure
&& (unit
->flags
& UNITF_ONLINE
) != 0)
1567 ConfigureAdapter(unit
, base
);
1568 unit
->stats
.Reconfigurations
++;
1577 /****** realtek8180.device/S2_SETKEY ***************************************
1580 * S2_SETKEY -- Set an encryption key.
1585 * ios2_WireError - Key index.
1586 * ios2_PacketType - Encryption type (e.g. S2ENC_WEP).
1587 * ios2_DataLength - Key length.
1589 * ios2_StatData - RX counter number (NULL if unused).
1602 ****************************************************************************
1606 static BOOL
CmdSetKey(struct IOSana2Req
*request
, struct DevBase
*base
)
1608 struct DevUnit
*unit
;
1610 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1611 SetKey(unit
, request
->ios2_WireError
, request
->ios2_PacketType
,
1612 request
->ios2_Data
, request
->ios2_DataLength
, request
->ios2_StatData
,
1622 /****** realtek8180.device/S2_WRITEMGMT ************************************
1625 * S2_WRITEMGMT -- Write a management frame.
1630 * ios2_DataLength - full frame length.
1631 * ios2_Data - pointer to a complete IEEE 802.11 management frame.
1645 ****************************************************************************
1649 static BOOL
CmdWriteMgmt(struct IOSana2Req
*request
, struct DevBase
*base
)
1651 struct DevUnit
*unit
;
1654 BOOL complete
= FALSE
;
1656 /* Check request is valid */
1658 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1659 if((unit
->flags
& UNITF_ONLINE
) == 0)
1661 error
= S2ERR_OUTOFSERVICE
;
1662 wire_error
= S2WERR_UNIT_OFFLINE
;
1665 /* Queue request for sending */
1668 PutRequest(unit
->request_ports
[MGMT_QUEUE
], (APTR
)request
, base
);
1671 request
->ios2_Req
.io_Error
= error
;
1672 request
->ios2_WireError
= wire_error
;
1683 /****** realtek8180.device/S2_READMGMT *************************************
1686 * S2_READMGMT -- Read a management frame.
1691 * ios2_DataLength - size of frame buffer.
1692 * ios2_Data - pointer to a frame buffer.
1697 * ios2_DataLength - actual size of received frame.
1708 ****************************************************************************
1712 static BOOL
CmdReadMgmt(struct IOSana2Req
*request
, struct DevBase
*base
)
1714 struct DevUnit
*unit
;
1715 struct Opener
*opener
;
1716 BOOL complete
= FALSE
;
1718 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1720 if((unit
->flags
& UNITF_ONLINE
) != 0)
1722 opener
= request
->ios2_BufferManagement
;
1723 PutRequest(&opener
->mgmt_port
, (APTR
)request
, base
);
1727 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
1728 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
1739 /****i* realtek8180.device/PutRequest **************************************
1745 * PutRequest(port, request)
1747 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1758 ****************************************************************************
1762 VOID
PutRequest(struct MsgPort
*port
, struct IORequest
*request
,
1763 struct DevBase
*base
)
1765 request
->io_Flags
&= ~IOF_QUICK
;
1766 PutMsg(port
, (APTR
)request
);