3 Copyright (C) 2001-2017 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/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
26 #include <exec/tasks.h>
28 #include <proto/exec.h>
30 #include <proto/alib.h>
32 #include <clib/alib_protos.h>
34 #include <proto/utility.h>
35 #include <proto/timer.h>
39 #include "realtek8187.h"
41 #include "unit_protos.h"
42 #include "request_protos.h"
43 #include "radio_protos.h"
44 #include "eeprom_protos.h"
45 #include "encryption_protos.h"
46 #include "timer_protos.h"
49 #define TASK_PRIORITY 0
50 #define STACK_SIZE 4096
51 #define INT_MASK 0xffff
55 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
);
56 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
57 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
58 UWORD upper_bound_right
, struct DevBase
*base
);
59 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
);
60 static UBYTE
*GetRXBuffer(struct DevUnit
*unit
, const UBYTE
*address
,
61 UWORD frag_no
, UWORD
*buffer_no
, struct DevBase
*base
);
62 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*frame
,
63 struct DevBase
*base
);
64 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
65 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
,
66 struct DevBase
*base
);
67 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
68 struct DevBase
*base
);
69 static VOID
DistributeMgmtFrame(struct DevUnit
*unit
, UBYTE
*frame
,
70 UWORD frame_size
, struct DevBase
*base
);
71 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
72 static VOID
MgmtTXInt(REG(a1
, struct DevUnit
*unit
),
73 REG(a6
, APTR int_code
));
74 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
75 struct DevBase
*base
);
76 static UWORD
GetDuration(struct DevUnit
*unit
, UWORD length
, UWORD rate
,
77 BOOL short_preamble
, struct DevBase
*base
);
78 static UWORD
AckRate(struct DevUnit
*unit
, UWORD data_rate
,
79 struct DevBase
*base
);
80 static VOID
UnitTask(struct DevUnit
*unit
);
83 static const UBYTE snap_template
[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
86 /****i* realtek8180.device/CreateUnit **************************************
89 * CreateUnit -- Create a unit.
92 * unit = CreateUnit(index, io_base, id, card,
95 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
96 * struct TagItem *, UWORD);
101 ****************************************************************************
105 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
106 const struct TagItem
*io_tags
, UWORD bus
, struct DevBase
*base
)
109 struct DevUnit
*unit
;
111 struct MsgPort
*port
;
115 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
121 /* Initialise lists etc. */
123 NewList((APTR
)&unit
->openers
);
124 NewList((APTR
)&unit
->type_trackers
);
125 NewList((APTR
)&unit
->multicast_ranges
);
131 unit
->generation
= RTL8187B1_GEN
;
133 unit
->tx_rate_code
= 3; /* 11 Mbps */
135 unit
->mgmt_rate_code
= 0; /* 1 Mbps */
138 /* Store I/O hooks */
141 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
143 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
145 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
147 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
149 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
151 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
153 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
155 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
157 (APTR
)GetTagData(IOTAG_SendFrame
, (UPINT
)NULL
, io_tags
);
159 (APTR
)GetTagData(IOTAG_ReceiveFrame
, (UPINT
)NULL
, io_tags
);
160 if(unit
->ByteIn
== NULL
161 || unit
->ByteOut
== NULL
162 || unit
->LEWordIn
== NULL
163 || unit
->LELongIn
== NULL
164 || unit
->LEWordOut
== NULL
165 || unit
->LELongOut
== NULL
166 || unit
->AllocDMAMem
== NULL
167 || unit
->FreeDMAMem
== NULL
168 || unit
->SendFrame
== NULL
169 || unit
->ReceiveFrame
== NULL
)
175 InitSemaphore(&unit
->access_lock
);
177 /* Create the message ports for queuing requests */
179 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
181 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
182 MEMF_PUBLIC
| MEMF_CLEAR
);
188 NewList(&port
->mp_MsgList
);
189 port
->mp_Flags
= PA_IGNORE
;
195 unit
->request_ports
[WRITE_QUEUE
]->mp_SigTask
= &unit
->tx_int
;
196 unit
->request_ports
[MGMT_QUEUE
]->mp_SigTask
= &unit
->mgmt_int
;
199 /* Allocate buffers and descriptors */
201 unit
->tx_buffer
= AllocVec(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
);
202 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
204 unit
->tx_descs
[i
] = unit
->AllocDMAMem(unit
->card
,
205 R8180_MAXDESCSIZE
+ FRAME_BUFFER_SIZE
, 4);
206 if(unit
->tx_descs
[i
] != NULL
)
207 unit
->tx_buffers
[i
] = unit
->tx_descs
[i
] + R8180_MAXDESCSIZE
;
211 unit
->rx_buffer
= AllocVec(FRAME_BUFFER_SIZE
, MEMF_PUBLIC
);
212 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
214 if(unit
->bus
!= USB_BUS
)
216 unit
->rx_descs
[i
] = unit
->AllocDMAMem(unit
->card
,
217 R8180_MAXDESCSIZE
, 4);
218 if(unit
->rx_descs
[i
] == NULL
)
221 unit
->rx_buffers
[i
] = unit
->AllocDMAMem(unit
->card
,
222 FRAME_BUFFER_SIZE
+ R8180_MAXDESCSIZE
, 4);
223 if(unit
->rx_buffers
[i
] == NULL
)
227 AllocVec(FRAME_BUFFER_SIZE
* FRAME_BUFFER_COUNT
, MEMF_PUBLIC
);
228 for(i
= 0; i
< FRAME_BUFFER_COUNT
; i
++)
229 unit
->rx_fragment_nos
[i
] = -1;
230 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
232 if(unit
->tx_buffer
== NULL
233 || unit
->rx_buffer
== NULL
234 || unit
->rx_frames
== NULL
235 || unit
->tx_requests
== NULL
)
241 /* Initialise network adapter hardware */
243 success
= InitialiseAdapter(unit
, FALSE
, base
);
244 unit
->flags
|= UNITF_HAVEADAPTER
;
249 /* Record maximum speed in BPS */
251 unit
->speed
= 54000000;
253 /* Initialise interrupts */
255 unit
->rx_int
.is_Node
.ln_Name
=
256 base
->device
.dd_Library
.lib_Node
.ln_Name
;
257 unit
->rx_int
.is_Code
= (APTR
)RXInt
;
258 unit
->rx_int
.is_Data
= unit
;
260 unit
->tx_int
.is_Node
.ln_Name
=
261 base
->device
.dd_Library
.lib_Node
.ln_Name
;
262 unit
->tx_int
.is_Code
= (APTR
)TXInt
;
263 unit
->tx_int
.is_Data
= unit
;
265 unit
->mgmt_int
.is_Node
.ln_Name
=
266 base
->device
.dd_Library
.lib_Node
.ln_Name
;
267 unit
->mgmt_int
.is_Code
= (APTR
)MgmtTXInt
;
268 unit
->mgmt_int
.is_Data
= unit
;
270 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
271 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
273 /* Create a new task */
276 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
283 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
290 /* Initialise and start task */
292 task
->tc_Node
.ln_Type
= NT_TASK
;
293 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
294 task
->tc_Node
.ln_Name
= base
->device
.dd_Library
.lib_Node
.ln_Name
;
295 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
296 task
->tc_SPLower
= stack
;
297 task
->tc_SPReg
= task
->tc_SPUpper
;
298 NewList(&task
->tc_MemEntry
);
300 if(AddUnitTask(task
, UnitTask
, unit
) != NULL
)
301 unit
->flags
|= UNITF_TASKADDED
;
308 /* Set default wireless options */
310 unit
->mode
= S2PORT_MANAGED
;
315 DeleteUnit(unit
, base
);
324 /****i* realtek8180.device/DeleteUnit **************************************
327 * DeleteUnit -- Delete a unit.
332 * VOID DeleteUnit(struct DevUnit *);
338 * unit - Device unit (may be NULL).
343 ****************************************************************************
347 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
357 if((unit
->flags
& UNITF_TASKADDED
) != 0)
360 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
362 FreeMem(task
, sizeof(struct Task
));
365 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
367 if(unit
->request_ports
[i
] != NULL
)
368 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
371 if((unit
->flags
& UNITF_ONLINE
) != 0) /* Needed! */
372 GoOffline(unit
, base
);
374 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
375 DeinitialiseAdapter(unit
, base
);
377 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
378 unit
->FreeDMAMem(unit
->card
, unit
->tx_descs
[i
]);
379 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
381 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffers
[i
]);
382 if(unit
->bus
!= USB_BUS
)
383 unit
->FreeDMAMem(unit
->card
, unit
->rx_descs
[i
]);
386 FreeVec(unit
->tx_buffer
);
387 FreeVec(unit
->rx_frames
);
388 FreeVec(unit
->tx_requests
);
389 FreeVec(unit
->rx_buffer
);
391 FreeMem(unit
, sizeof(struct DevUnit
));
399 /****i* realtek8180.device/InitialiseAdapter *******************************
405 * success = InitialiseAdapter(unit, reinsertion)
407 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
416 * success - Success indicator.
418 ****************************************************************************
422 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
423 struct DevBase
*base
)
425 BOOL success
= FALSE
;
426 UBYTE reg_62
, revision
;
430 /* Initialise EEPROM */
432 rx_conf
= unit
->LELongIn(unit
->card
, 0x100 + R8180REG_RXCONF
);
433 unit
->eeprom_addr_size
= ((rx_conf
& (1 << 6)) != 0) ? 8 : 6;
435 BusyMicroDelay(10, base
);
436 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
438 /* Get default MAC address */
440 p
= (UWORD
*)unit
->default_address
;
441 for(i
= 0; i
< ETH_ADDRESSSIZE
/ sizeof(UWORD
); i
++)
442 *p
++ = LEWord(ReadEEPROM(unit
, R8180ROM_ADDRESS0
+ i
, base
));
444 /* Refine main chip revision */
446 if(unit
->generation
== RTL8187B1_GEN
)
448 revision
= unit
->ByteIn(unit
->card
, 0x100 + 0xe1);
449 if(revision
== 1 || revision
== 2)
450 unit
->generation
= RTL8187B2_GEN
;
454 if((unit
->LELongIn(unit
->card
, 0x100 + R8180REG_TXCONF
)
455 & R8180REG_TXCONFF_HWVER
) == 6 << R8180REG_TXCONFB_HWVER
)
456 unit
->generation
= RTL8187B0_GEN
;
459 /* Set up power tables */
461 GetPower(unit
, base
);
465 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
466 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
467 | R8180REG_CONFIG3F_ANAPARAMWRITE
| R8180REG_CONFIG3F_GNTSELECT
);
468 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ANAPARAM2
, 0x727f3f52);
469 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ANAPARAM1
, 0x45090658);
470 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ANAPARAM3
, 0);
472 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
473 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
474 & ~R8180REG_CONFIG3F_ANAPARAMWRITE
);
476 /* Reset PLL sequence */
478 unit
->ByteOut(unit
->card
, 0x161, 0x10);
479 reg_62
= unit
->ByteIn(unit
->card
, 0x162);
480 unit
->ByteOut(unit
->card
, 0x162, reg_62
& ~(1 << 5));
481 unit
->ByteOut(unit
->card
, 0x162, reg_62
| (1 << 5));
483 /* Send reset command */
485 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
486 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_COMMAND
)
487 & 0x2 | R8180REG_COMMANDF_RESET
);
489 for(i
= 0; i
< 10 && !success
; i
++)
491 BusyMilliDelay(2, base
);
492 if((unit
->ByteIn(unit
->card
, 0x100 + R8180REG_COMMAND
)
493 & R8180REG_COMMANDF_RESET
) == 0)
497 if(success
&& unit
->generation
== RTL8187L_GEN
)
499 /* Reload registers from EEPROM */
501 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_LOAD
);
503 for(i
= 0, success
= FALSE
; i
< 10 && !success
; i
++)
505 BusyMilliDelay(4, base
);
506 if((unit
->ByteIn(unit
->card
, 0x100 + R8180REG_EEPROM
)
507 & R8180REG_EEPROMF_COMMAND
) == 0)
516 if(unit
->generation
== RTL8187L_GEN
)
517 unit
->LEWordOut(unit
->card
, 0x12d, 0xfff);
519 unit
->LEWordOut(unit
->card
, 0x134, 0xfff);
520 unit
->LEWordOut(unit
->card
, 0x12c, 0x1ff);
521 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CWCONF
,
522 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CWCONF
)
523 | R8180REG_CWCONFF_PPRETRYSHIFT
);
524 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXAGCCTL
,
525 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_TXAGCCTL
)
526 | R8180REG_TXAGCCTLF_PPGAINSHIFT
);
528 unit
->LEWordOut(unit
->card
, 0x1e0 | 1 << 16, 0xfff);
529 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_RATEFALLBACK
,
530 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_RATEFALLBACK
)
531 | R8180REG_RATEFALLBACKF_ENABLE
);
533 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
,
534 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
) & 0xf3);
535 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
,
536 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
)
537 | R8180REG_MSRF_ENEDCA
);
538 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ACMCONTROL
, 0);
540 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMWINDOW
, 2);
541 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL
, 100);
542 unit
->LEWordOut(unit
->card
, 0x1d4 | 1 << 16, 0xffff);
544 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
545 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG1
,
546 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG1
) & 0x3f | 0x80);
547 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, 0);
549 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_WPACONF
, 0);
551 unit
->ByteOut(unit
->card
, 0x1f0, 0x32);
552 unit
->ByteOut(unit
->card
, 0x1f1, 0x32);
553 unit
->ByteOut(unit
->card
, 0x1f2, 0x0);
554 unit
->ByteOut(unit
->card
, 0x1f3, 0x0);
555 unit
->ByteOut(unit
->card
, 0x1f4, 0x32);
556 unit
->ByteOut(unit
->card
, 0x1f5, 0x43);
557 unit
->ByteOut(unit
->card
, 0x1f6, 0x0);
558 unit
->ByteOut(unit
->card
, 0x1f7, 0x0);
559 unit
->ByteOut(unit
->card
, 0x1f8, 0x46);
560 unit
->ByteOut(unit
->card
, 0x1f9, 0xa4);
561 unit
->ByteOut(unit
->card
, 0x1fa, 0x0);
562 unit
->ByteOut(unit
->card
, 0x1fb, 0x0);
563 unit
->ByteOut(unit
->card
, 0x1fc, 0x96);
564 unit
->ByteOut(unit
->card
, 0x1fd, 0xa4);
565 unit
->ByteOut(unit
->card
, 0x1fe, 0x0);
566 unit
->ByteOut(unit
->card
, 0x1ff, 0x0);
568 unit
->ByteOut(unit
->card
, 0x158 | 1 << 16, 0x4b);
569 unit
->ByteOut(unit
->card
, 0x159 | 1 << 16, 0x0);
570 unit
->ByteOut(unit
->card
, 0x15a | 1 << 16, 0x4b);
571 unit
->ByteOut(unit
->card
, 0x15b | 1 << 16, 0x0);
572 unit
->ByteOut(unit
->card
, 0x160 | 1 << 16, 0x4b);
573 unit
->ByteOut(unit
->card
, 0x161 | 1 << 16, 0x9);
574 unit
->ByteOut(unit
->card
, 0x162 | 1 << 16, 0x4b);
575 unit
->ByteOut(unit
->card
, 0x163 | 1 << 16, 0x9);
576 unit
->ByteOut(unit
->card
, 0x1ce | 1 << 16, 0xf);
577 unit
->ByteOut(unit
->card
, 0x1cf | 1 << 16, 0x0);
578 unit
->ByteOut(unit
->card
, 0x1e0 | 1 << 16, 0xff);
579 unit
->ByteOut(unit
->card
, 0x1e1 | 1 << 16, 0xf);
580 unit
->ByteOut(unit
->card
, 0x1e2 | 1 << 16, 0x0);
581 unit
->ByteOut(unit
->card
, 0x1f0 | 1 << 16, 0x4e);
582 unit
->ByteOut(unit
->card
, 0x1f1 | 1 << 16, 0x1);
583 unit
->ByteOut(unit
->card
, 0x1f2 | 1 << 16, 0x2);
584 unit
->ByteOut(unit
->card
, 0x1f3 | 1 << 16, 0x3);
585 unit
->ByteOut(unit
->card
, 0x1f4 | 1 << 16, 0x4);
586 unit
->ByteOut(unit
->card
, 0x1f5 | 1 << 16, 0x5);
587 unit
->ByteOut(unit
->card
, 0x1f6 | 1 << 16, 0x6);
588 unit
->ByteOut(unit
->card
, 0x1f7 | 1 << 16, 0x7);
589 unit
->ByteOut(unit
->card
, 0x1f8 | 1 << 16, 0x8);
591 unit
->ByteOut(unit
->card
, 0x14e | 2 << 16, 0x0);
592 unit
->ByteOut(unit
->card
, 0x10c | 2 << 16, 0x4);
593 unit
->ByteOut(unit
->card
, 0x121 | 2 << 16, 0x61);
594 unit
->ByteOut(unit
->card
, 0x122 | 2 << 16, 0x68);
595 unit
->ByteOut(unit
->card
, 0x123 | 2 << 16, 0x6f);
596 unit
->ByteOut(unit
->card
, 0x124 | 2 << 16, 0x76);
597 unit
->ByteOut(unit
->card
, 0x125 | 2 << 16, 0x7d);
598 unit
->ByteOut(unit
->card
, 0x126 | 2 << 16, 0x84);
599 unit
->ByteOut(unit
->card
, 0x127 | 2 << 16, 0x8d);
600 unit
->ByteOut(unit
->card
, 0x14d | 2 << 16, 0x8);
601 unit
->ByteOut(unit
->card
, 0x150 | 2 << 16, 0x5);
602 unit
->ByteOut(unit
->card
, 0x151 | 2 << 16, 0xf5);
603 unit
->ByteOut(unit
->card
, 0x152 | 2 << 16, 0x4);
604 unit
->ByteOut(unit
->card
, 0x153 | 2 << 16, 0xa0);
605 unit
->ByteOut(unit
->card
, 0x154 | 2 << 16, 0x1f);
606 unit
->ByteOut(unit
->card
, 0x155 | 2 << 16, 0x23);
607 unit
->ByteOut(unit
->card
, 0x156 | 2 << 16, 0x45);
608 unit
->ByteOut(unit
->card
, 0x157 | 2 << 16, 0x67);
609 unit
->ByteOut(unit
->card
, 0x158 | 2 << 16, 0x8);
610 unit
->ByteOut(unit
->card
, 0x159 | 2 << 16, 0x8);
611 unit
->ByteOut(unit
->card
, 0x15a | 2 << 16, 0x8);
612 unit
->ByteOut(unit
->card
, 0x15b | 2 << 16, 0x8);
613 unit
->ByteOut(unit
->card
, 0x160 | 2 << 16, 0x8);
614 unit
->ByteOut(unit
->card
, 0x161 | 2 << 16, 0x8);
615 unit
->ByteOut(unit
->card
, 0x162 | 2 << 16, 0x8);
616 unit
->ByteOut(unit
->card
, 0x163 | 2 << 16, 0x8);
617 unit
->ByteOut(unit
->card
, 0x164 | 2 << 16, 0xcf);
618 unit
->ByteOut(unit
->card
, 0x172 | 2 << 16, 0x56);
619 unit
->ByteOut(unit
->card
, 0x173 | 2 << 16, 0x9a);
621 unit
->ByteOut(unit
->card
, 0x134, 0xf0);
622 unit
->ByteOut(unit
->card
, 0x135, 0xf);
623 unit
->ByteOut(unit
->card
, 0x15b, 0x40);
624 unit
->ByteOut(unit
->card
, 0x184, 0x88);
625 unit
->ByteOut(unit
->card
, 0x185, 0x24);
626 unit
->ByteOut(unit
->card
, 0x188, 0x54);
627 unit
->ByteOut(unit
->card
, 0x18b, 0xb8);
628 unit
->ByteOut(unit
->card
, 0x18c, 0x7);
629 unit
->ByteOut(unit
->card
, 0x18d, 0x0);
630 unit
->ByteOut(unit
->card
, 0x194, 0x1b);
631 unit
->ByteOut(unit
->card
, 0x195, 0x12);
632 unit
->ByteOut(unit
->card
, 0x196, 0x0);
633 unit
->ByteOut(unit
->card
, 0x197, 0x6);
634 unit
->ByteOut(unit
->card
, 0x19d, 0x1a);
635 unit
->ByteOut(unit
->card
, 0x19f, 0x10);
636 unit
->ByteOut(unit
->card
, 0x1b4, 0x22);
637 unit
->ByteOut(unit
->card
, 0x1be, 0x80);
638 unit
->ByteOut(unit
->card
, 0x1db, 0x0);
639 unit
->ByteOut(unit
->card
, 0x1ee, 0x0);
640 unit
->ByteOut(unit
->card
, 0x191, 0x3);
641 unit
->ByteOut(unit
->card
, 0x14c | 2 << 16, 0x0);
643 unit
->ByteOut(unit
->card
, 0x19f | 3 << 16, 0x0);
644 unit
->ByteOut(unit
->card
, 0x18c, 0x1);
645 unit
->ByteOut(unit
->card
, 0x18d, 0x10);
646 unit
->ByteOut(unit
->card
, 0x18e, 0x8);
647 unit
->ByteOut(unit
->card
, 0x18f, 0x0);
649 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_TIDACMAP
, 0xfa50);
650 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMIG
, 0);
652 unit
->LELongOut(unit
->card
, 0x1f0 | 1 << 16, 0);
653 unit
->LELongOut(unit
->card
, 0x1f4 | 1 << 16, 0);
654 unit
->ByteOut(unit
->card
, 0x1f8 | 1 << 16, 0);
656 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_RFTIMING
, 0x4001);
658 unit
->LEWordOut(unit
->card
, 0x172 | 2 << 16, 0x569a);
660 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
662 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
663 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
664 | R8180REG_CONFIG3F_ANAPARAMWRITE
);
665 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, 0);
669 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPIO0
, 1);
670 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPENABLE
, 0);
672 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, 0x480);
673 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
, 0x2488);
674 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
, 0x1fff);
675 BusyMilliDelay(100, base
);
677 /* Initialise radio */
679 success
= InitialiseRadio(unit
, base
);
681 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
682 R8180REG_COMMANDF_TXENABLE
| R8180REG_COMMANDF_RXENABLE
);
683 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMASK
, INT_MASK
);
685 unit
->ByteOut(unit
->card
, 0x41, 0xf4);
686 unit
->ByteOut(unit
->card
, 0x40, 0);
687 unit
->ByteOut(unit
->card
, 0x42, 0);
688 unit
->ByteOut(unit
->card
, 0x42, 1);
689 unit
->ByteOut(unit
->card
, 0x40, 0xf);
690 unit
->ByteOut(unit
->card
, 0x42, 0);
691 unit
->ByteOut(unit
->card
, 0x42, 1);
693 unit
->ByteOut(unit
->card
, 0x1db,
694 unit
->ByteIn(unit
->card
, 0x1db) | 1 << 2);
695 unit
->LEWordOut(unit
->card
, 0x172 | 3 << 16, 0x59fa);
696 unit
->LEWordOut(unit
->card
, 0x174 | 3 << 16, 0x59d2);
697 unit
->LEWordOut(unit
->card
, 0x176 | 3 << 16, 0x59d2);
698 unit
->LEWordOut(unit
->card
, 0x178 | 3 << 16, 0x19fa);
699 unit
->LEWordOut(unit
->card
, 0x17a | 3 << 16, 0x19fa);
700 unit
->LEWordOut(unit
->card
, 0x17c | 3 << 16, 0xd0);
701 unit
->ByteOut(unit
->card
, 0x161, 0);
702 unit
->ByteOut(unit
->card
, 0x180 | 1 << 16, 0xf);
703 unit
->ByteOut(unit
->card
, 0x183 | 1 << 16, 3);
704 unit
->ByteOut(unit
->card
, 0x1da, 0x10);
705 unit
->ByteOut(unit
->card
, 0x14d | 2 << 16, 8);
707 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_HSSIPARA
, 0x600321b);
709 /* Set maximum RX frame size */
711 unit
->LEWordOut(unit
->card
, 0x1ec | 1 << 16, 0x800);
713 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ACMCONTROL
, 0);
714 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
, R8180REG_MSRF_ENEDCA
);
719 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_RXCONF
,
720 R8180REG_RXCONFF_EARLYTHRESH
721 | R8180REG_RXCONFF_AUTORESETPHY
722 | R8180REG_RXCONFF_CHECKBSSID
723 | R8180REG_RXCONFF_MGMT
724 | R8180REG_RXCONFF_DATA
725 | 7 << R8180REG_RXCONFB_FIFOTHRESH
726 | 7 << R8180REG_RXCONFB_MAXDMA
727 | R8180REG_RXCONFF_BCAST
728 | R8180REG_RXCONFF_MCAST
729 | R8180REG_RXCONFF_UCAST
);
730 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXAGCCTL
,
731 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_TXAGCCTL
)
732 & ~(R8180REG_TXAGCCTLF_PPGAINSHIFT
733 | R8180REG_TXAGCCTLF_PPANTSELSHIFT
734 | R8180REG_TXAGCCTLF_FEEDBACKANT
));
735 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_TXCONF
,
736 R8180REG_TXCONFF_DISREQQSIZE
737 | 7 << R8180REG_TXCONFB_MAXDMA
738 | TX_TRIES
<< R8180REG_TXCONFB_SHORTTRIES
739 | TX_TRIES
<< R8180REG_TXCONFB_LONGTRIES
);
742 /* Determine features, and get offsets of certain fields within frame
745 unit
->retries_offset
= R8180FRM_RETRY
;
746 unit
->tx_desc_size
= 32;
747 unit
->rx_desc_size
= 20;
751 unit
->iv_sizes
[S2ENC_WEP
] = IV_SIZE
;
752 unit
->iv_sizes
[S2ENC_TKIP
] = EIV_SIZE
;
753 unit
->iv_sizes
[S2ENC_CCMP
] = EIV_SIZE
;
755 /* Set encryption functions */
757 unit
->fragment_encrypt_functions
[S2ENC_NONE
] = WriteClearFragment
;
759 if((unit
->flags
& UNITF_HARDWEP
) != 0)
760 unit
->fragment_encrypt_functions
[S2ENC_WEP
] = WriteWEPFragment
;
762 unit
->fragment_encrypt_functions
[S2ENC_WEP
] = EncryptWEPFragment
;
764 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
765 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = WriteTKIPFragment
;
767 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = EncryptTKIPFragment
;
769 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
770 unit
->fragment_encrypt_functions
[S2ENC_CCMP
] = WriteCCMPFragment
;
772 unit
->fragment_encrypt_functions
[S2ENC_CCMP
] = EncryptCCMPFragment
;
774 /* Set decryption functions */
776 unit
->fragment_decrypt_functions
[S2ENC_NONE
] = ReadClearFragment
;
778 if((unit
->flags
& UNITF_HARDWEP
) != 0)
779 unit
->fragment_decrypt_functions
[S2ENC_WEP
] = ReadWEPFragment
;
781 unit
->fragment_decrypt_functions
[S2ENC_WEP
] = DecryptWEPFragment
;
783 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
784 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = ReadTKIPFragment
;
786 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = DecryptTKIPFragment
;
788 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
789 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = ReadCCMPFragment
;
791 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = DecryptCCMPFragment
;
800 /****i* realtek8180.device/DeinitialiseAdapter *****************************
803 * DeinitialiseAdapter
806 * DeinitialiseAdapter(unit)
808 * VOID DeinitialiseAdapter(struct DevUnit *);
818 ****************************************************************************
822 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
826 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPIO0
, 1);
827 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPENABLE
, 1);
834 /****i* realtek8180.device/ConfigureAdapter ********************************
837 * ConfigureAdapter -- Set up card for transmission/reception.
840 * ConfigureAdapter(unit)
842 * VOID ConfigureAdapter(struct DevUnit *);
844 ****************************************************************************
848 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
855 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
856 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_BSSID
+ i
, unit
->bssid
[i
]);
858 /* Set channel and power */
860 SetPower(unit
, base
);
862 msr
= unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
)
863 & ~R8180REG_MSRF_LINK
;
864 if(unit
->assoc_id
!= 0)
866 msr
|= 2 << R8180REG_MSRB_LINK
;
867 if(unit
->generation
>= RTL8187B0_GEN
)
868 msr
|= R8180REG_MSRF_ENEDCA
;
870 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
, msr
);
874 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMWINDOW
, 2);
875 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMTRINTERVAL
, 100);
876 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL
, 100);
877 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL2
, 100);
879 if(unit
->generation
>= RTL8187B0_GEN
)
881 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SIFS
, 0x22);
882 if(unit
->band
== S2BAND_G
)
883 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SLOT
, 0x9);
885 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SLOT
, 0x14);
886 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EIFS
, 0x5b);
887 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SENSECOUNT
, 0x5b);
897 /****i* realtek8180.device/GoOnline ****************************************
900 * GoOnline -- Enable transmission/reception.
905 * VOID GoOnline(struct DevUnit *);
907 ****************************************************************************
911 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
913 /* Enable interrupts */
915 unit
->flags
|= UNITF_ONLINE
;
916 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMASK
, INT_MASK
);
918 /* Enable frame transmission and reception */
920 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
921 R8180REG_COMMANDF_TXENABLE
| R8180REG_COMMANDF_RXENABLE
);
923 /* Record start time and report Online event */
925 GetSysTime(&unit
->stats
.LastStart
);
926 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
933 /****i* realtek8180.device/GoOffline ***************************************
936 * GoOffline -- Disable transmission/reception.
941 * VOID GoOffline(struct DevUnit *);
951 ****************************************************************************
955 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
957 unit
->flags
&= ~UNITF_ONLINE
;
959 /* Flush pending read and write requests */
961 FlushUnit(unit
, MGMT_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
963 /* Report Offline event and return */
965 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
971 /****i* realtek8180.device/SetOptions **************************************
974 * SetOptions -- Set and use interface options.
977 * reconfigure = SetOptions(unit, tag_list)
979 * BOOL SetOptions(struct DevUnit *, struct TagItem *);
981 ****************************************************************************
985 BOOL
SetOptions(struct DevUnit
*unit
, const struct TagItem
*tag_list
,
986 struct DevBase
*base
)
988 struct TagItem
*tag_item
, *tlist
= (struct TagItem
*)tag_list
;
989 BOOL reconfigure
= TRUE
;
991 while((tag_item
= NextTagItem(&tlist
)) != NULL
)
993 switch(tag_item
->ti_Tag
)
996 ReportEvents(unit
, S2EVENT_CONNECT
, base
);
1000 CopyMem((APTR
)tag_item
->ti_Data
, unit
->bssid
, ETH_ADDRESSSIZE
);
1003 case S2INFO_AssocID
:
1004 unit
->assoc_id
= tag_item
->ti_Data
;
1007 case S2INFO_Capabilities
:
1008 unit
->capabilities
= tag_item
->ti_Data
;
1009 if((unit
->capabilities
& (1 << 5)) != 0)
1010 unit
->flags
|= UNITF_SHORTPREAMBLE
;
1012 unit
->flags
&= ~UNITF_SHORTPREAMBLE
;
1015 case S2INFO_DefaultKeyNo
:
1016 unit
->tx_key_no
= tag_item
->ti_Data
;
1019 case S2INFO_PortType
:
1020 unit
->mode
= tag_item
->ti_Data
;
1023 case S2INFO_Channel
:
1024 if(tag_item
->ti_Data
!= unit
->channel
)
1026 unit
->channel
= tag_item
->ti_Data
;
1032 unit
->band
= tag_item
->ti_Data
;
1033 if(unit
->band
== S2BAND_G
)
1036 unit
->tx_rate_code
= 11; /* 54 Mbps */
1037 unit
->mgmt_rate
= 2;
1038 unit
->mgmt_rate_code
= 1; /* 2 Mbps */
1040 else if(unit
->band
== S2BAND_B
)
1043 unit
->tx_rate_code
= 3; /* 11 Mbps */
1044 unit
->mgmt_rate
= 1;
1045 unit
->mgmt_rate_code
= 0; /* 1 Mbps */
1057 /****i* realtek8180.device/SetKey ******************************************
1060 * SetKey -- Set an encryption key.
1063 * SetKey(unit, index, type, key, key_length,
1066 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1069 ****************************************************************************
1073 VOID
SetKey(struct DevUnit
*unit
, ULONG index
, ULONG type
, const UBYTE
*key
,
1074 ULONG key_length
, const UBYTE
*rx_counter
, struct DevBase
*base
)
1076 struct KeyUnion
*slot
;
1077 struct EClockVal eclock
;
1081 slot
= &unit
->keys
[index
];
1085 CopyMem(key
, slot
->u
.wep
.key
, key_length
);
1086 slot
->u
.wep
.length
= key_length
;
1088 if((unit
->flags
& UNITF_HARDWEP
) == 0)
1090 /* Create a reasonably random IV */
1092 ReadEClock(&eclock
);
1093 slot
->u
.wep
.tx_iv
= FastRand(eclock
.ev_lo
^ eclock
.ev_hi
);
1099 CopyMem(key
, slot
->u
.tkip
.key
, 16);
1100 CopyMem(key
+ 16, slot
->u
.tkip
.tx_mic_key
, MIC_SIZE
);
1101 CopyMem(key
+ 24, slot
->u
.tkip
.rx_mic_key
, MIC_SIZE
);
1102 slot
->u
.tkip
.tx_iv_low
= 0;
1103 slot
->u
.tkip
.tx_iv_high
= 0;
1104 slot
->u
.tkip
.rx_iv_low
= LEWord(*(UWORD
*)rx_counter
);
1105 slot
->u
.tkip
.rx_iv_high
= LELong(*(ULONG
*)(rx_counter
+ 2));
1106 slot
->u
.tkip
.tx_ttak_set
= FALSE
;
1107 slot
->u
.tkip
.rx_ttak_set
= FALSE
;
1109 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
1114 /* Convert key to native endianness */
1116 for(i
= 0; i
< 8; i
++)
1117 slot
->u
.tkip
.key
[i
] = LEWord(slot
->u
.tkip
.key
[i
]);
1123 CopyMem(key
, slot
->u
.ccmp
.key
, 16);
1124 slot
->u
.ccmp
.tx_iv_low
= 0;
1125 slot
->u
.ccmp
.tx_iv_high
= 0;
1126 slot
->u
.ccmp
.rx_iv_low
= LEWord(*(UWORD
*)rx_counter
);
1127 slot
->u
.ccmp
.rx_iv_high
= LELong(*(ULONG
*)(rx_counter
+ 2));
1128 slot
->u
.ccmp
.stream_set
= FALSE
;
1131 /* Update type of key in selected slot */
1141 /****i* realtek8180.device/AddMulticastRange *******************************
1147 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1149 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1151 ****************************************************************************
1155 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1156 const UBYTE
*upper_bound
, struct DevBase
*base
)
1158 struct AddressRange
*range
;
1159 ULONG lower_bound_left
, upper_bound_left
;
1160 UWORD lower_bound_right
, upper_bound_right
;
1162 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1163 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1164 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1165 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1167 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1168 upper_bound_left
, upper_bound_right
, base
);
1174 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1177 range
->lower_bound_left
= lower_bound_left
;
1178 range
->lower_bound_right
= lower_bound_right
;
1179 range
->upper_bound_left
= upper_bound_left
;
1180 range
->upper_bound_right
= upper_bound_right
;
1181 range
->add_count
= 1;
1184 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1185 unit
->range_count
++;
1186 SetMulticast(unit
, base
);
1191 return range
!= NULL
;
1196 /****i* realtek8180.device/RemMulticastRange *******************************
1202 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1204 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1206 ****************************************************************************
1210 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1211 const UBYTE
*upper_bound
, struct DevBase
*base
)
1213 struct AddressRange
*range
;
1214 ULONG lower_bound_left
, upper_bound_left
;
1215 UWORD lower_bound_right
, upper_bound_right
;
1217 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1218 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1219 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1220 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1222 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1223 upper_bound_left
, upper_bound_right
, base
);
1227 if(--range
->add_count
== 0)
1230 Remove((APTR
)range
);
1231 unit
->range_count
--;
1232 SetMulticast(unit
, base
);
1234 FreeMem(range
, sizeof(struct AddressRange
));
1238 return range
!= NULL
;
1243 /****i* realtek8180.device/FindMulticastRange ******************************
1246 * FindMulticastRange
1249 * range = FindMulticastRange(unit, lower_bound_left,
1250 * lower_bound_right, upper_bound_left, upper_bound_right)
1252 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1253 * UWORD, ULONG, UWORD);
1255 ****************************************************************************
1259 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
1260 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
1261 UWORD upper_bound_right
, struct DevBase
*base
)
1263 struct AddressRange
*range
, *tail
;
1266 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1267 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1269 while(range
!= tail
&& !found
)
1271 if(lower_bound_left
== range
->lower_bound_left
&&
1272 lower_bound_right
== range
->lower_bound_right
&&
1273 upper_bound_left
== range
->upper_bound_left
&&
1274 upper_bound_right
== range
->upper_bound_right
)
1277 range
= (APTR
)range
->node
.mln_Succ
;
1288 /****i* realtek8180.device/SetMulticast ************************************
1294 * SetMulticast(unit)
1296 * VOID SetMulticast(struct DevUnit *);
1298 ****************************************************************************
1302 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
)
1309 /****i* realtek8180.device/FindTypeStats ***********************************
1315 * stats = FindTypeStats(unit, list,
1318 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1321 ****************************************************************************
1325 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1326 ULONG packet_type
, struct DevBase
*base
)
1328 struct TypeStats
*stats
, *tail
;
1331 stats
= (APTR
)list
->mlh_Head
;
1332 tail
= (APTR
)&list
->mlh_Tail
;
1334 while(stats
!= tail
&& !found
)
1336 if(stats
->packet_type
== packet_type
)
1339 stats
= (APTR
)stats
->node
.mln_Succ
;
1350 /****i* realtek8180.device/FlushUnit ***************************************
1356 * FlushUnit(unit, last_queue, error)
1358 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1360 ****************************************************************************
1364 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
1365 struct DevBase
*base
)
1367 struct IORequest
*request
;
1369 struct Opener
*opener
, *tail
;
1371 /* Abort queued requests */
1373 for(i
= 0; i
<= last_queue
; i
++)
1375 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
1377 request
->io_Error
= IOERR_ABORTED
;
1378 ReplyMsg((APTR
)request
);
1383 opener
= (APTR
)unit
->openers
.mlh_Head
;
1384 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1386 /* Flush every opener's read queues */
1388 while(opener
!= tail
)
1390 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1392 request
->io_Error
= error
;
1393 ReplyMsg((APTR
)request
);
1395 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
1397 request
->io_Error
= error
;
1398 ReplyMsg((APTR
)request
);
1400 opener
= (APTR
)opener
->node
.mln_Succ
;
1404 opener
= request
->ios2_BufferManagement
;
1405 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1407 request
->io_Error
= IOERR_ABORTED
;
1408 ReplyMsg((APTR
)request
);
1410 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
1412 request
->io_Error
= IOERR_ABORTED
;
1413 ReplyMsg((APTR
)request
);
1424 /****i* realtek8180.device/RXInt *******************************************
1427 * RXInt -- Soft interrupt for packet reception.
1432 * VOID RXInt(struct DevUnit *);
1437 * unit - A unit of this device.
1442 ****************************************************************************
1446 VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
1448 UWORD ieee_length
, frame_control
, frame_type
, slot
, next_slot
,
1449 frame_size
, frame_subtype
, encryption
, key_no
, buffer_no
, old_length
;
1450 struct DevBase
*base
;
1451 BOOL is_good
, proceed
= TRUE
;
1454 UBYTE
*rx_desc
, *buffer
, *p
, *frame
, *data
, *snap_frame
, *source
;
1456 base
= unit
->device
;
1457 slot
= unit
->rx_slot
;
1458 rx_desc
= unit
->rx_descs
[slot
];
1459 next_slot
= (slot
+ 1) % RX_SLOT_COUNT
;
1464 buffer
= unit
->rx_buffers
[slot
];
1466 status
= LELong(*(ULONG
*)(rx_desc
+ R8180FRM_RXSTATUS
));
1467 frame_size
= status
& R8180FRM_RXSTATUSF_LENGTH
;
1469 if((status
& (R8180FRM_RXSTATUSF_DMAERR
| R8180FRM_RXSTATUSF_OVERFLOW
1470 | R8180FRM_RXSTATUSF_RXERR
| R8180FRM_RXSTATUSF_BADCRC
)) == 0
1471 && frame_size
>= WIFI_FRM_DATA
+ 4)
1473 /* Get fragment info */
1476 ieee_length
= frame_size
- 4 - WIFI_FRM_DATA
;
1477 data
= frame
+ WIFI_FRM_DATA
;
1479 LEWord(*(UWORD
*)(frame
+ WIFI_FRM_CONTROL
));
1481 /* Get buffer to store fragment in */
1483 frag_no
= LEWord(*(UWORD
*)(frame
+ WIFI_FRM_SEQCONTROL
));
1484 if(unit
->mode
== S2PORT_ADHOC
)
1485 source
= frame
+ WIFI_FRM_ADDRESS2
;
1487 source
= frame
+ WIFI_FRM_ADDRESS3
;
1488 snap_frame
= GetRXBuffer(unit
, source
, frag_no
, &buffer_no
, base
);
1490 /* Get location to put new data */
1492 if(snap_frame
!= NULL
)
1494 if((frag_no
& 0xf ) > 0)
1496 BEWord(*(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
));
1499 /* Create new 802.3 header */
1501 CopyMem(frame
+ WIFI_FRM_ADDRESS1
, snap_frame
,
1503 CopyMem(source
, snap_frame
+ ETH_PACKET_SOURCE
,
1507 p
= snap_frame
+ ETH_HEADERSIZE
+ old_length
;
1509 /* Append fragment to frame, decrypting fragment if necessary */
1511 if((frame_control
& WIFI_FRM_CONTROLF_WEP
) != 0)
1513 key_no
= data
[3] >> 6 & 0x3;
1514 encryption
= unit
->keys
[key_no
].type
;
1517 encryption
= S2ENC_NONE
;
1519 /* Decrypt, check and/or copy fragment */
1521 is_good
= unit
->fragment_decrypt_functions
[encryption
](unit
,
1522 frame
, data
, &ieee_length
, p
, base
);
1524 /* Update length in frame being built with current fragment, or
1525 increment bad frame counter if fragment is bad */
1529 ieee_length
+= old_length
;
1530 *(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
) =
1531 MakeBEWord(ieee_length
);
1534 unit
->stats
.BadData
++;
1536 /* If all fragments have arrived, process the complete frame */
1538 if((frame_control
& WIFI_FRM_CONTROLF_MOREFRAGS
) == 0)
1542 /* Decrypt complete frame if necessary */
1544 data
= snap_frame
+ ETH_HEADERSIZE
;
1545 if(encryption
== S2ENC_TKIP
1546 && (unit
->flags
& UNITF_HARDTKIP
) == 0)
1548 is_good
= TKIPDecryptFrame(unit
, snap_frame
, data
,
1549 ieee_length
, data
, key_no
, base
);
1550 ieee_length
-= MIC_SIZE
;
1551 *(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
) =
1552 MakeBEWord(ieee_length
);
1554 unit
->stats
.BadData
++;
1560 /* Get frame's 802.11 type and subtype */
1562 frame_type
= (frame_control
& WIFI_FRM_CONTROLF_TYPE
)
1563 >> WIFI_FRM_CONTROLB_TYPE
;
1565 (frame_control
& WIFI_FRM_CONTROLF_SUBTYPE
)
1566 >> WIFI_FRM_CONTROLB_SUBTYPE
;
1568 /* If it's a management frame, process it separately;
1569 otherwise distribute it to clients after filtering */
1571 if(frame_type
== WIFI_FRMTYPE_MGMT
)
1573 if(frame_subtype
!= 8)
1574 DistributeMgmtFrame(unit
, frame
, frame_size
- 4,
1577 else if(AddressFilter(unit
, snap_frame
+ ETH_PACKET_DEST
,
1580 unit
->stats
.PacketsReceived
++;
1581 DistributeRXPacket(unit
, snap_frame
, base
);
1586 /* Mark fragment buffer as unused for next time */
1588 unit
->rx_fragment_nos
[buffer_no
] = -1;
1591 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_RX
, base
);
1600 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1604 /* Prepare descriptor for next time */
1606 unit
->ReceiveFrame(unit
->card
, buffer
,
1607 FRAME_BUFFER_SIZE
+ R8180_MAXDESCSIZE
);
1609 /* Get next descriptor */
1612 if(unit
->bus
== USB_BUS
)
1616 unit
->rx_slot
= slot
;
1623 /****i* realtek8180.device/GetRXBuffer *************************************
1626 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1629 * buffer = GetRXBuffer(unit, address, frag_no)
1631 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1633 ****************************************************************************
1637 static UBYTE
*GetRXBuffer(struct DevUnit
*unit
, const UBYTE
*address
,
1638 UWORD frag_no
, UWORD
*buffer_no
, struct DevBase
*base
)
1645 buffer
= unit
->rx_frames
;
1646 for(i
= 0, found
= FALSE
; i
< FRAME_BUFFER_COUNT
* 2 && !found
; i
++)
1648 /* Throw away old buffer contents if we didn't find a free slot the
1649 first time around */
1651 if(i
>= FRAME_BUFFER_COUNT
)
1652 unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
] = -1;
1654 /* For a frame's first fragment, find an empty slot; for subsequent
1655 fragments, find a slot with matching source address */
1657 n
= unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
];
1658 if(n
== -1 && (frag_no
& 0xf) == 0
1659 || *((ULONG
*)(buffer
+ ETH_PACKET_SOURCE
))
1660 == *((ULONG
*)(address
))
1661 && *((UWORD
*)(buffer
+ ETH_PACKET_SOURCE
+ 4))
1662 == *((UWORD
*)(address
+ 4)))
1666 unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
] = frag_no
;
1670 buffer
+= FRAME_BUFFER_SIZE
;
1681 /****i* realtek8180.device/DistributeRXPacket ******************************
1684 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1687 * DistributeRXPacket(unit, frame)
1689 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1691 ****************************************************************************
1695 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*frame
,
1696 struct DevBase
*base
)
1698 UWORD packet_size
, ieee_length
;
1699 BOOL is_orphan
= TRUE
, accepted
, is_snap
= FALSE
;
1702 const UBYTE
*template = snap_template
;
1703 struct IOSana2Req
*request
, *request_tail
;
1704 struct Opener
*opener
, *opener_tail
;
1705 struct TypeStats
*tracker
;
1707 buffer
= unit
->rx_buffer
;
1708 ieee_length
= BEWord(*(UWORD
*)(frame
+ ETH_PACKET_IEEELEN
));
1709 packet_size
= ETH_HEADERSIZE
+ ieee_length
;
1710 if(ieee_length
>= SNAP_HEADERSIZE
)
1711 is_snap
= *(const ULONG
*)(frame
+ ETH_PACKET_DATA
)
1712 == *(const ULONG
*)template;
1714 /* De-encapsulate SNAP packets and get packet type */
1718 packet_size
-= SNAP_HEADERSIZE
;
1719 CopyMem(frame
, buffer
, ETH_PACKET_TYPE
);
1720 CopyMem(frame
+ ETH_HEADERSIZE
+ SNAP_FRM_TYPE
,
1721 buffer
+ ETH_PACKET_TYPE
, packet_size
- ETH_PACKET_TYPE
);
1723 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1725 /* Offer packet to every opener */
1727 opener
= (APTR
)unit
->openers
.mlh_Head
;
1728 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1730 while(opener
!= opener_tail
)
1732 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1733 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1736 /* Offer packet to each request until it's accepted */
1738 while(request
!= request_tail
&& !accepted
)
1740 if(request
->ios2_PacketType
== packet_type
)
1742 CopyPacket(unit
, request
, packet_size
, packet_type
,
1747 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1752 opener
= (APTR
)opener
->node
.mln_Succ
;
1755 /* If packet was unwanted, give it to S2_READORPHAN request */
1759 unit
->stats
.UnknownTypesReceived
++;
1760 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1763 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1764 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1769 /* Update remaining statistics */
1771 if(packet_type
<= ETH_MTU
)
1772 packet_type
= ETH_MTU
;
1774 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1777 tracker
->stats
.PacketsReceived
++;
1778 tracker
->stats
.BytesReceived
+= packet_size
;
1786 /****i* realtek8180.device/CopyPacket **************************************
1789 * CopyPacket -- Copy packet to client's buffer.
1792 * CopyPacket(unit, request, packet_size, packet_type,
1795 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1798 ****************************************************************************
1802 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1803 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
,
1804 struct DevBase
*base
)
1806 struct Opener
*opener
;
1807 BOOL filtered
= FALSE
;
1809 /* Set multicast and broadcast flags */
1811 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1812 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1813 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1814 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1815 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1816 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1818 /* Set source and destination addresses and packet type */
1820 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1822 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1824 request
->ios2_PacketType
= packet_type
;
1826 /* Adjust for cooked packet request */
1828 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1830 packet_size
-= ETH_PACKET_DATA
;
1831 buffer
+= ETH_PACKET_DATA
;
1835 packet_size
+= 4; /* Needed for Shapeshifter & Fusion? */
1837 request
->ios2_DataLength
= packet_size
;
1841 opener
= request
->ios2_BufferManagement
;
1842 if(request
->ios2_Req
.io_Command
== CMD_READ
&&
1843 opener
->filter_hook
!= NULL
)
1844 if(!CallHookPkt(opener
->filter_hook
, request
, buffer
))
1849 /* Copy packet into opener's buffer and reply packet */
1851 if(!opener
->rx_function(request
->ios2_Data
, buffer
, packet_size
))
1853 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1854 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1856 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1859 Remove((APTR
)request
);
1860 ReplyMsg((APTR
)request
);
1868 /****i* realtek8180.device/AddressFilter ***********************************
1871 * AddressFilter -- Determine if an RX packet should be accepted.
1874 * accept = AddressFilter(unit, address)
1876 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1878 ****************************************************************************
1882 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1883 struct DevBase
*base
)
1885 struct AddressRange
*range
, *tail
;
1888 UWORD address_right
;
1890 /* Check whether address is unicast/broadcast or multicast */
1892 address_left
= BELong(*((ULONG
*)address
));
1893 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1895 if(((address_left
& 0x01000000) != 0) &&
1896 !((address_left
== 0xffffffff) && (address_right
== 0xffff)))
1898 /* Check if this multicast address is wanted */
1900 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1901 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1904 while((range
!= tail
) && !accept
)
1906 if((address_left
> range
->lower_bound_left
||
1907 address_left
== range
->lower_bound_left
&&
1908 address_right
>= range
->lower_bound_right
) &&
1909 (address_left
< range
->upper_bound_left
||
1910 address_left
== range
->upper_bound_left
&&
1911 address_right
<= range
->upper_bound_right
))
1913 range
= (APTR
)range
->node
.mln_Succ
;
1917 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1925 /****i* realtek8180.device/DistributeMgmtFrame *****************************
1928 * DistributeMgmtFrame -- Send a management frame to clients.
1931 * DistributeMgmtFrame(unit, frame, frame_size)
1933 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
1935 ****************************************************************************
1939 static VOID
DistributeMgmtFrame(struct DevUnit
*unit
, UBYTE
*frame
,
1940 UWORD frame_size
, struct DevBase
*base
)
1942 struct IOSana2Req
*request
;
1943 struct Opener
*opener
, *opener_tail
;
1945 /* Send packet to every opener */
1947 opener
= (APTR
)unit
->openers
.mlh_Head
;
1948 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1950 while(opener
!= opener_tail
)
1952 request
= (APTR
)RemHead(&opener
->mgmt_port
.mp_MsgList
);
1956 /* Copy packet into opener's buffer and reply packet */
1958 if(frame_size
<= request
->ios2_DataLength
)
1960 CopyMem(frame
, request
->ios2_Data
, frame_size
);
1961 request
->ios2_DataLength
= frame_size
;
1965 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1966 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1968 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1971 ReplyMsg((APTR
)request
);
1973 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1976 opener
= (APTR
)opener
->node
.mln_Succ
;
1984 /****i* realtek8180.device/TXInt *******************************************
1987 * TXInt -- Soft interrupt for packet transmission.
1992 * VOID TXInt(struct DevUnit *);
1997 * unit - A unit of this device.
2002 ****************************************************************************
2006 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
2008 struct DevBase
*base
;
2009 UWORD i
, frame_size
, data_size
, packet_type
, body_size
, slot
, new_slot
,
2010 encryption
, subtype
, duration
;
2011 UBYTE
*buffer
, *q
, *plaintext
, *ciphertext
, *frame
,
2012 mic_header
[ETH_ADDRESSSIZE
* 2];
2013 const UBYTE
*p
, *dest
, *source
;
2014 struct IOSana2Req
*request
;
2015 BOOL proceed
= TRUE
, is_ieee
, has_bssid
;
2016 struct Opener
*opener
;
2017 ULONG wire_error
, control_value
;
2019 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
2021 struct MsgPort
*port
;
2022 struct TypeStats
*tracker
;
2024 base
= unit
->device
;
2025 port
= unit
->request_ports
[WRITE_QUEUE
];
2027 while(proceed
&& (!IsMsgPortEmpty(port
)))
2029 slot
= unit
->tx_in_slot
;
2030 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2032 if(new_slot
!= unit
->tx_out_slot
)
2037 /* Get request and DMA frame descriptor */
2039 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2041 Remove((APTR
)request
);
2042 unit
->tx_requests
[slot
] = request
;
2043 tx_desc
= unit
->tx_descs
[slot
];
2044 frame
= unit
->tx_buffers
[slot
];
2046 /* Get packet data */
2048 opener
= request
->ios2_BufferManagement
;
2049 dma_tx_function
= opener
->dma_tx_function
;
2050 if(dma_tx_function
!= NULL
)
2051 buffer
= dma_tx_function(request
->ios2_Data
);
2057 buffer
= unit
->tx_buffer
;
2058 if(!opener
->tx_function(buffer
, request
->ios2_Data
,
2059 request
->ios2_DataLength
))
2061 error
= S2ERR_NO_RESOURCES
;
2062 wire_error
= S2WERR_BUFF_ERROR
;
2064 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2065 | S2EVENT_TX
, base
);
2071 /* Get packet type and/or length */
2073 data_size
= request
->ios2_DataLength
;
2074 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) != 0)
2076 data_size
-= ETH_PACKET_DATA
;
2077 packet_type
= BEWord(*(UWORD
*)(buffer
+ ETH_PACKET_TYPE
));
2080 packet_type
= request
->ios2_PacketType
;
2081 is_ieee
= packet_type
<= ETH_MTU
;
2083 /* Determine encryption type and frame subtype */
2087 encryption
= unit
->keys
[unit
->tx_key_no
].type
;
2092 encryption
= S2ENC_NONE
;
2096 /* Get source and destination addresses */
2098 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) != 0)
2101 source
= buffer
+ ETH_ADDRESSSIZE
;
2102 buffer
+= ETH_ADDRESSSIZE
* 2 + 2;
2106 dest
= request
->ios2_DstAddr
;
2107 source
= unit
->address
;
2110 /* Write 802.11 header */
2113 *(UWORD
*)q
= MakeLEWord(
2114 (encryption
== S2ENC_NONE
? 0 : WIFI_FRM_CONTROLF_WEP
)
2115 | (unit
->mode
== S2PORT_ADHOC
? 0 : WIFI_FRM_CONTROLF_TODS
)
2116 | subtype
<< WIFI_FRM_CONTROLB_SUBTYPE
2117 | WIFI_FRMTYPE_DATA
<< WIFI_FRM_CONTROLB_TYPE
);
2120 if(unit
->mode
== S2PORT_ADHOC
)
2124 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2127 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2130 if(unit
->mode
== S2PORT_ADHOC
)
2134 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2136 *(UWORD
*)q
= MakeLEWord(unit
->tx_sequence
);
2137 unit
->tx_sequence
+= 0x10;
2140 /* Leave room for encryption overhead */
2143 q
+= unit
->iv_sizes
[encryption
];
2146 /* Write SNAP header */
2150 for(i
= 0, p
= snap_template
;
2151 i
< SNAP_FRM_TYPE
; i
++)
2153 *(UWORD
*)q
= MakeBEWord(packet_type
);
2155 body_size
+= SNAP_HEADERSIZE
;
2158 /* Copy data into frame */
2160 CopyMem(buffer
, q
, data_size
);
2161 body_size
+= data_size
;
2163 /* Append MIC to frame for TKIP */
2165 if(encryption
== S2ENC_TKIP
)
2168 for(i
= 0, p
= dest
; i
< ETH_ADDRESSSIZE
; i
++)
2170 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2172 TKIPEncryptFrame(unit
, mic_header
, plaintext
, body_size
,
2174 body_size
+= MIC_SIZE
;
2177 /* Encrypt fragment if applicable */
2179 unit
->fragment_encrypt_functions
[encryption
](unit
, frame
,
2180 plaintext
, &body_size
, ciphertext
, base
);
2182 /* Clear frame descriptor as far as start of 802.11 header */
2185 for(i
= 0; i
< unit
->tx_desc_size
; i
++)
2188 /* Set TX control field */
2190 frame_size
= WIFI_FRM_DATA
+ body_size
;
2191 control_value
= R8180FRM_TXCONTROLF_NOENC
2192 | R8180FRM_TXCONTROLF_FIRSTFRAG
2193 | R8180FRM_TXCONTROLF_LASTFRAG
2194 | unit
->tx_rate_code
<< R8180FRM_TXCONTROLB_RATE
2196 *(ULONG
*)(tx_desc
+ R8180FRM_TXCONTROL
) =
2197 MakeLELong(control_value
);
2201 has_bssid
= ((frame
+ WIFI_FRM_ADDRESS1
)[0] & 0x1) == 0;
2203 duration
= SIFS_TIME
+ GetDuration(unit
, 14,
2204 AckRate(unit
, unit
->tx_rate
, base
), FALSE
, base
);
2207 *(UWORD
*)(frame
+ WIFI_FRM_DURATION
) = MakeLEWord(duration
);
2209 if(unit
->generation
>= RTL8187B0_GEN
)
2211 duration
+= GetDuration(unit
, frame_size
+ 4,
2213 (unit
->flags
& UNITF_SHORTPREAMBLE
) != 0 && has_bssid
,
2215 *(UWORD
*)(tx_desc
+ R8180FRM_TXDUR
) = MakeLEWord(duration
);
2218 /* Set max number of retries */
2220 *(ULONG
*)(tx_desc
+ unit
->retries_offset
) =
2221 MakeLELong((TX_TRIES
- 1) << 8);
2223 /* Pass packet to adapter */
2225 unit
->SendFrame(unit
->card
, tx_desc
,
2226 R8180_MAXDESCSIZE
+ frame_size
);
2227 unit
->tx_in_slot
= new_slot
;
2231 /* Reply failed request */
2233 request
->ios2_Req
.io_Error
= error
;
2234 request
->ios2_WireError
= wire_error
;
2235 ReplyMsg((APTR
)request
);
2238 /* Update statistics */
2242 unit
->stats
.PacketsSent
++;
2244 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2245 request
->ios2_PacketType
, base
);
2248 tracker
->stats
.PacketsSent
++;
2249 tracker
->stats
.BytesSent
+= ETH_HEADERSIZE
+ data_size
;
2257 /* Don't try to keep sending packets if there's no space left */
2261 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2262 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2266 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_IGNORE
;
2267 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2275 /****i* realtek8180.device/MgmtTXInt ***************************************
2278 * MgmtTXInt -- Soft interrupt for management frame transmission.
2283 * VOID MgmtTXInt(struct DevUnit *);
2288 * unit - A unit of this device.
2293 ****************************************************************************
2297 static VOID
MgmtTXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
2299 struct DevBase
*base
;
2300 UWORD frame_size
, slot
, new_slot
, i
, duration
;
2301 UBYTE
*desc
, *frame
, *q
;
2302 struct IOSana2Req
*request
;
2303 BOOL proceed
= TRUE
, has_bssid
;
2304 ULONG control_value
;
2305 struct MsgPort
*port
;
2307 base
= unit
->device
;
2308 port
= unit
->request_ports
[MGMT_QUEUE
];
2310 while(proceed
&& (!IsMsgPortEmpty(port
)))
2312 slot
= unit
->tx_in_slot
;
2313 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2315 if(new_slot
!= unit
->tx_out_slot
)
2317 /* Get request and frame descriptor */
2319 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2321 Remove((APTR
)request
);
2322 unit
->tx_requests
[slot
] = request
;
2323 desc
= unit
->tx_descs
[slot
];
2324 frame
= unit
->tx_buffers
[slot
];
2326 /* Get packet length */
2328 frame_size
= request
->ios2_DataLength
;
2330 /* Copy frame into transmit buffer */
2332 CopyMem(request
->ios2_Data
, frame
, frame_size
);
2334 /* Clear frame descriptor as far as start of 802.11 header */
2337 for(i
= 0; i
< unit
->tx_desc_size
; i
++)
2340 /* Set TX control field */
2342 control_value
= R8180FRM_TXCONTROLF_NOENC
2343 | R8180FRM_TXCONTROLF_FIRSTFRAG
2344 | R8180FRM_TXCONTROLF_LASTFRAG
2345 | unit
->mgmt_rate_code
<< R8180FRM_TXCONTROLB_RATE
2347 *(ULONG
*)(desc
+ R8180FRM_TXCONTROL
) = MakeLELong(control_value
);
2351 has_bssid
= ((frame
+ WIFI_FRM_ADDRESS1
)[0] & 0x1) == 0;
2353 duration
= SIFS_TIME
+ GetDuration(unit
, 14,
2354 AckRate(unit
, unit
->mgmt_rate
, base
), FALSE
, base
);
2357 *(UWORD
*)(frame
+ WIFI_FRM_DURATION
) = MakeLEWord(duration
);
2359 if(unit
->generation
>= RTL8187B0_GEN
)
2361 duration
+= GetDuration(unit
, frame_size
+ 4,
2362 unit
->mgmt_rate
, FALSE
, base
);
2363 *(UWORD
*)(desc
+ R8180FRM_TXDUR
) = MakeLEWord(duration
);
2366 /* Set max number of retries */
2368 *(ULONG
*)(desc
+ unit
->retries_offset
) =
2369 MakeLELong((TX_TRIES
- 1) << 8);
2371 /* Set sequence number */
2373 *(UWORD
*)(frame
+ WIFI_FRM_SEQCONTROL
) =
2374 MakeLEWord(unit
->tx_sequence
);
2375 unit
->tx_sequence
+= 0x10;
2377 /* Pass packet to adapter */
2379 unit
->SendFrame(unit
->card
, desc
, R8180_MAXDESCSIZE
+ frame_size
);
2380 unit
->tx_in_slot
= new_slot
;
2386 /* Don't try to keep sending packets if there's no space left */
2390 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2391 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2395 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2396 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_IGNORE
;
2404 /****i* realtek8180.device/RetireTXSlot ************************************
2407 * RetireTXSlot -- Clean up after a frame has been sent.
2410 * RetireTXSlot(unit)
2412 * VOID RetireTXSlot(struct DevUnit *);
2414 ****************************************************************************
2418 VOID
RetireTXSlot(struct DevUnit
*unit
, struct DevBase
*base
)
2420 UWORD frame_size
, slot
;
2421 struct IOSana2Req
*request
;
2422 struct TypeStats
*tracker
;
2424 /* Update statistics */
2426 slot
= unit
->tx_out_slot
;
2427 request
= unit
->tx_requests
[slot
];
2428 if(request
->ios2_Req
.io_Command
!= S2_WRITEMGMT
)
2430 frame_size
= request
->ios2_DataLength
;
2431 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2432 frame_size
+= ETH_HEADERSIZE
;
2434 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2435 request
->ios2_PacketType
, base
);
2438 tracker
->stats
.PacketsSent
++;
2439 tracker
->stats
.BytesSent
+= frame_size
;
2445 request
->ios2_Req
.io_Error
= 0;
2446 ReplyMsg((APTR
)request
);
2448 unit
->tx_out_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2450 /* Restart downloads if they had stopped */
2452 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
2453 Cause(&unit
->tx_int
);
2454 if(unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
== PA_IGNORE
)
2455 Cause(&unit
->mgmt_int
);
2462 /****i* realtek8180.device/ReportEvents ************************************
2468 * ReportEvents(unit, events)
2470 * VOID ReportEvents(struct DevUnit *, ULONG);
2475 * unit - A unit of this device.
2476 * events - A mask of events to report.
2481 ****************************************************************************
2485 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2486 struct DevBase
*base
)
2488 struct IOSana2Req
*request
, *tail
, *next_request
;
2491 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2492 next_request
= (APTR
)list
->lh_Head
;
2493 tail
= (APTR
)&list
->lh_Tail
;
2496 while(next_request
!= tail
)
2498 request
= next_request
;
2499 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2501 if((request
->ios2_WireError
& events
) != 0)
2503 request
->ios2_WireError
= events
;
2504 Remove((APTR
)request
);
2505 ReplyMsg((APTR
)request
);
2515 /****i* realtek8180.device/GetDuration *************************************
2518 * GetDuration -- Calculate a duration value.
2521 * GetDuration(unit, length, rate, is_mgmt)
2523 * VOID GetDuration(struct DevUnit *);
2526 * Calculates a duration for a frame of given length when transmitted
2527 * at a given rate. If this is a transmiss
2530 * unit - A unit of this device.
2531 * length - Length of frame whose duration is to be calculated.
2532 * rate - Rate frame will be transmitted at (in Mbps, rounded down).
2533 * is_short - Indicates if frame has a short preamble.
2538 ****************************************************************************
2542 static UWORD
GetDuration(struct DevUnit
*unit
, UWORD length
, UWORD rate
,
2543 BOOL short_preamble
, struct DevBase
*base
)
2545 UWORD duration
, cycles
;
2549 duration
= 97 + (length
* 8 - 1) / rate
;
2550 if (!short_preamble
|| rate
== 1)
2556 duration
= ((length
+ 29) / cycles
+ 1) * 4 + 26;
2564 /****i* realtek8180.device/AckRate *****************************************
2567 * AckRate -- Get the ACK rate corresponding to a data rate.
2570 * ack_rate = AckRate(unit, data_rate)
2572 * UWORD AckRate(struct DevUnit *, UWORD);
2575 * Calculates the rate at which the ACK frame for a data frame with the
2576 * given rate should be transmitted.
2579 * unit - A unit of this device.
2580 * rate - Rate data frame is transmitted at (in Mbps, rounded down).
2583 * ack_rate - The rate for the ACK frame (Mbps, rounded down).
2585 ****************************************************************************
2589 static UWORD
AckRate(struct DevUnit
*unit
, UWORD data_rate
,
2590 struct DevBase
*base
)
2625 /****i* realtek8180.device/UnitTask ****************************************
2633 * VOID UnitTask(struct DevUnit *);
2636 * Completes deferred requests, and handles card insertion and removal
2637 * in conjunction with the relevant interrupts.
2639 ****************************************************************************
2643 static VOID
UnitTask(struct DevUnit
*unit
)
2645 struct DevBase
*base
;
2646 struct IORequest
*request
;
2647 struct MsgPort
*general_port
;
2648 ULONG signals
= 0, wait_signals
, card_removed_signal
,
2649 card_inserted_signal
, general_port_signal
;
2651 base
= unit
->device
;
2653 /* Activate general request port */
2655 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
2656 general_port
->mp_SigTask
= unit
->task
;
2657 general_port
->mp_SigBit
= AllocSignal(-1);
2658 general_port_signal
= 1 << general_port
->mp_SigBit
;
2659 general_port
->mp_Flags
= PA_SIGNAL
;
2661 /* Allocate signals for notification of card removal and insertion */
2663 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
2664 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
2665 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
2666 | card_inserted_signal
| SIGBREAKF_CTRL_C
;
2668 /* Tell ourselves to check port for old messages */
2670 Signal(unit
->task
, general_port_signal
);
2672 /* Infinite loop to service requests and signals */
2676 signals
= Wait(wait_signals
);
2678 if((signals
& card_inserted_signal
) != 0)
2680 if(unit
->insertion_function(unit
->card
, base
))
2682 unit
->flags
|= UNITF_HAVEADAPTER
;
2683 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
2684 ConfigureAdapter(unit
, base
);
2685 if((unit
->flags
& UNITF_WASONLINE
) != 0)
2687 GoOnline(unit
, base
);
2688 unit
->flags
&= ~UNITF_WASONLINE
;
2693 if((signals
& card_removed_signal
) != 0)
2695 unit
->removal_function(unit
->card
, base
);
2696 if((unit
->flags
& UNITF_WASONLINE
) != 0)
2697 GoOffline(unit
, base
);
2700 if((signals
& general_port_signal
) != 0)
2702 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
2704 /* Service the request as soon as the unit is free */
2706 ObtainSemaphore(&unit
->access_lock
);
2707 ServiceRequest((APTR
)request
, base
);