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/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
27 #include <proto/exec.h>
29 #include <proto/alib.h>
31 #include <clib/alib_protos.h>
33 #include <proto/utility.h>
34 #include <proto/timer.h>
38 #include "unit_protos.h"
39 #include "request_protos.h"
40 #include "radio_protos.h"
41 #include "eeprom_protos.h"
42 #include "encryption_protos.h"
43 #include "timer_protos.h"
44 #include "realtek8187.h"
47 #define TASK_PRIORITY 0
48 #define STACK_SIZE 4096
49 #define INT_MASK 0xffff
54 #define AbsExecBase sys_base
57 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
);
58 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
59 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
60 UWORD upper_bound_right
, struct DevBase
*base
);
61 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
);
62 static UBYTE
*GetRXBuffer(struct DevUnit
*unit
, const UBYTE
*address
,
63 UWORD frag_no
, UWORD
*buffer_no
, struct DevBase
*base
);
64 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*frame
,
65 struct DevBase
*base
);
66 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
67 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
,
68 struct DevBase
*base
);
69 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
70 struct DevBase
*base
);
71 static VOID
DistributeMgmtFrame(struct DevUnit
*unit
, UBYTE
*frame
,
72 UWORD frame_size
, struct DevBase
*base
);
73 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
74 static VOID
MgmtTXInt(REG(a1
, struct DevUnit
*unit
),
75 REG(a6
, APTR int_code
));
76 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
77 struct DevBase
*base
);
78 static UWORD
GetDuration(struct DevUnit
*unit
, UWORD length
, UWORD rate
,
79 BOOL short_preamble
, struct DevBase
*base
);
80 static UWORD
AckRate(struct DevUnit
*unit
, UWORD data_rate
,
81 struct DevBase
*base
);
82 static VOID
UnitTask(struct ExecBase
*sys_base
);
85 static const UBYTE snap_template
[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
86 #if !defined(__AROS__)
87 static const UBYTE broadcast_address
[] =
88 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
93 #define AddTask(task, initial_pc, final_pc) \
94 IExec->AddTask(task, initial_pc, final_pc, NULL)
97 static const struct EmulLibEntry mos_task_trap
=
103 #define UnitTask &mos_task_trap
107 #define AddTask(task, initial_pc, final_pc) \
109 struct TagItem _task_tags[] = \
110 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
111 NewAddTask(task, initial_pc, final_pc, _task_tags); \
117 /****i* realtek8180.device/CreateUnit **************************************
120 * CreateUnit -- Create a unit.
123 * unit = CreateUnit(index, io_base, id, card,
126 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
127 * struct TagItem *, UWORD);
130 * Creates a new unit.
132 ****************************************************************************
136 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
137 const struct TagItem
*_io_tags
, UWORD bus
, struct DevBase
*base
)
139 struct TagItem
*io_tags
= (struct TagItem
*)io_tags
;
141 struct DevUnit
*unit
;
143 struct MsgPort
*port
;
147 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
153 /* Initialise lists etc. */
155 NewList((APTR
)&unit
->openers
);
156 NewList((APTR
)&unit
->type_trackers
);
157 NewList((APTR
)&unit
->multicast_ranges
);
163 unit
->generation
= RTL8187B1_GEN
;
165 unit
->tx_rate_code
= 3; /* 11 Mbps */
167 unit
->mgmt_rate_code
= 0; /* 1 Mbps */
170 /* Store I/O hooks */
173 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
175 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
177 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
179 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
181 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
183 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
185 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
187 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
189 (APTR
)GetTagData(IOTAG_SendFrame
, (UPINT
)NULL
, io_tags
);
191 (APTR
)GetTagData(IOTAG_ReceiveFrame
, (UPINT
)NULL
, io_tags
);
192 if(unit
->ByteIn
== NULL
193 || unit
->ByteOut
== NULL
194 || unit
->LEWordIn
== NULL
195 || unit
->LELongIn
== NULL
196 || unit
->LEWordOut
== NULL
197 || unit
->LELongOut
== NULL
198 || unit
->AllocDMAMem
== NULL
199 || unit
->FreeDMAMem
== NULL
200 || unit
->SendFrame
== NULL
201 || unit
->ReceiveFrame
== NULL
)
207 InitSemaphore(&unit
->access_lock
);
209 /* Create the message ports for queuing requests */
211 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
213 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
214 MEMF_PUBLIC
| MEMF_CLEAR
);
220 NewList(&port
->mp_MsgList
);
221 port
->mp_Flags
= PA_IGNORE
;
227 unit
->request_ports
[WRITE_QUEUE
]->mp_SigTask
= &unit
->tx_int
;
228 unit
->request_ports
[MGMT_QUEUE
]->mp_SigTask
= &unit
->mgmt_int
;
231 /* Allocate buffers and descriptors */
233 unit
->tx_buffer
= AllocVec(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
);
234 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
236 unit
->tx_descs
[i
] = unit
->AllocDMAMem(unit
->card
,
237 R8180_MAXDESCSIZE
+ FRAME_BUFFER_SIZE
, 4);
238 if(unit
->tx_descs
[i
] != NULL
)
239 unit
->tx_buffers
[i
] = unit
->tx_descs
[i
] + R8180_MAXDESCSIZE
;
243 unit
->rx_buffer
= AllocVec(FRAME_BUFFER_SIZE
, MEMF_PUBLIC
);
244 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
246 if(unit
->bus
!= USB_BUS
)
248 unit
->rx_descs
[i
] = unit
->AllocDMAMem(unit
->card
,
249 R8180_MAXDESCSIZE
, 4);
250 if(unit
->rx_descs
[i
] == NULL
)
253 unit
->rx_buffers
[i
] = unit
->AllocDMAMem(unit
->card
,
254 FRAME_BUFFER_SIZE
+ R8180_MAXDESCSIZE
, 4);
255 if(unit
->rx_buffers
[i
] == NULL
)
259 AllocVec(FRAME_BUFFER_SIZE
* FRAME_BUFFER_COUNT
, MEMF_PUBLIC
);
260 for(i
= 0; i
< FRAME_BUFFER_COUNT
; i
++)
261 unit
->rx_fragment_nos
[i
] = -1;
262 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
264 if(unit
->tx_buffer
== NULL
265 || unit
->rx_buffer
== NULL
266 || unit
->rx_frames
== NULL
267 || unit
->tx_requests
== NULL
)
273 /* Initialise network adapter hardware */
275 success
= InitialiseAdapter(unit
, FALSE
, base
);
276 unit
->flags
|= UNITF_HAVEADAPTER
;
281 /* Record maximum speed in BPS */
283 unit
->speed
= 54000000;
285 /* Initialise interrupts */
287 unit
->rx_int
.is_Node
.ln_Name
=
288 base
->device
.dd_Library
.lib_Node
.ln_Name
;
289 unit
->rx_int
.is_Code
= (APTR
)RXInt
;
290 unit
->rx_int
.is_Data
= unit
;
292 unit
->tx_int
.is_Node
.ln_Name
=
293 base
->device
.dd_Library
.lib_Node
.ln_Name
;
294 unit
->tx_int
.is_Code
= (APTR
)TXInt
;
295 unit
->tx_int
.is_Data
= unit
;
297 unit
->mgmt_int
.is_Node
.ln_Name
=
298 base
->device
.dd_Library
.lib_Node
.ln_Name
;
299 unit
->mgmt_int
.is_Code
= (APTR
)MgmtTXInt
;
300 unit
->mgmt_int
.is_Data
= unit
;
302 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
303 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
305 /* Create a new task */
308 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
315 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
322 /* Initialise and start task */
324 task
->tc_Node
.ln_Type
= NT_TASK
;
325 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
326 task
->tc_Node
.ln_Name
= base
->device
.dd_Library
.lib_Node
.ln_Name
;
327 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
328 task
->tc_SPLower
= stack
;
329 task
->tc_SPReg
= stack
+ STACK_SIZE
;
330 NewList(&task
->tc_MemEntry
);
332 if(AddTask(task
, UnitTask
, NULL
) == NULL
)
338 /* Send the unit to the new task */
340 task
->tc_UserData
= unit
;
342 /* Set default wireless options */
344 unit
->mode
= S2PORT_MANAGED
;
349 DeleteUnit(unit
, base
);
358 /****i* realtek8180.device/DeleteUnit **************************************
361 * DeleteUnit -- Delete a unit.
366 * VOID DeleteUnit(struct DevUnit *);
372 * unit - Device unit (may be NULL).
377 ****************************************************************************
381 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
391 if(task
->tc_UserData
!= NULL
)
394 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
396 FreeMem(task
, sizeof(struct Task
));
399 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
401 if(unit
->request_ports
[i
] != NULL
)
402 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
405 if((unit
->flags
& UNITF_ONLINE
) != 0) /* Needed! */
406 GoOffline(unit
, base
);
408 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
409 DeinitialiseAdapter(unit
, base
);
411 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
412 unit
->FreeDMAMem(unit
->card
, unit
->tx_descs
[i
]);
413 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
415 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffers
[i
]);
416 if(unit
->bus
!= USB_BUS
)
417 unit
->FreeDMAMem(unit
->card
, unit
->rx_descs
[i
]);
420 FreeVec(unit
->tx_buffer
);
421 FreeVec(unit
->rx_frames
);
422 FreeVec(unit
->tx_requests
);
423 FreeVec(unit
->rx_buffer
);
425 FreeMem(unit
, sizeof(struct DevUnit
));
433 /****i* realtek8180.device/InitialiseAdapter *******************************
439 * success = InitialiseAdapter(unit, reinsertion)
441 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
450 * success - Success indicator.
452 ****************************************************************************
456 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
457 struct DevBase
*base
)
459 BOOL success
= FALSE
;
460 UBYTE reg_62
, revision
;
464 /* Initialise EEPROM */
466 rx_conf
= unit
->LELongIn(unit
->card
, 0x100 + R8180REG_RXCONF
);
467 unit
->eeprom_addr_size
= ((rx_conf
& (1 << 6)) != 0) ? 8 : 6;
469 BusyMicroDelay(10, base
);
470 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
472 /* Get default MAC address */
474 p
= (UWORD
*)unit
->default_address
;
475 for(i
= 0; i
< ETH_ADDRESSSIZE
/ sizeof(UWORD
); i
++)
476 *p
++ = LEWord(ReadEEPROM(unit
, R8180ROM_ADDRESS0
+ i
, base
));
478 /* Refine main chip revision */
480 if(unit
->generation
== RTL8187B1_GEN
)
482 revision
= unit
->ByteIn(unit
->card
, 0x100 + 0xe1);
483 if(revision
== 1 || revision
== 2)
484 unit
->generation
= RTL8187B2_GEN
;
488 if((unit
->LELongIn(unit
->card
, 0x100 + R8180REG_TXCONF
)
489 & R8180REG_TXCONFF_HWVER
) == 6 << R8180REG_TXCONFB_HWVER
)
490 unit
->generation
= RTL8187B0_GEN
;
493 /* Set up power tables */
495 GetPower(unit
, base
);
499 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
500 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
501 | R8180REG_CONFIG3F_ANAPARAMWRITE
| R8180REG_CONFIG3F_GNTSELECT
);
502 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ANAPARAM2
, 0x727f3f52);
503 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_ANAPARAM1
, 0x45090658);
504 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ANAPARAM3
, 0);
506 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
507 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
508 & ~R8180REG_CONFIG3F_ANAPARAMWRITE
);
510 /* Reset PLL sequence */
512 unit
->ByteOut(unit
->card
, 0x161, 0x10);
513 reg_62
= unit
->ByteIn(unit
->card
, 0x162);
514 unit
->ByteOut(unit
->card
, 0x162, reg_62
& ~(1 << 5));
515 unit
->ByteOut(unit
->card
, 0x162, reg_62
| (1 << 5));
517 /* Send reset command */
519 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
520 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_COMMAND
)
521 & 0x2 | R8180REG_COMMANDF_RESET
);
523 for(i
= 0; i
< 10 && !success
; i
++)
525 BusyMilliDelay(2, base
);
526 if((unit
->ByteIn(unit
->card
, 0x100 + R8180REG_COMMAND
)
527 & R8180REG_COMMANDF_RESET
) == 0)
531 if(success
&& unit
->generation
== RTL8187L_GEN
)
533 /* Reload registers from EEPROM */
535 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_LOAD
);
537 for(i
= 0, success
= FALSE
; i
< 10 && !success
; i
++)
539 BusyMilliDelay(4, base
);
540 if((unit
->ByteIn(unit
->card
, 0x100 + R8180REG_EEPROM
)
541 & R8180REG_EEPROMF_COMMAND
) == 0)
550 if(unit
->generation
== RTL8187L_GEN
)
551 unit
->LEWordOut(unit
->card
, 0x12d, 0xfff);
553 unit
->LEWordOut(unit
->card
, 0x134, 0xfff);
554 unit
->LEWordOut(unit
->card
, 0x12c, 0x1ff);
555 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CWCONF
,
556 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CWCONF
)
557 | R8180REG_CWCONFF_PPRETRYSHIFT
);
558 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXAGCCTL
,
559 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_TXAGCCTL
)
560 | R8180REG_TXAGCCTLF_PPGAINSHIFT
);
562 unit
->LEWordOut(unit
->card
, 0x1e0 | 1 << 16, 0xfff);
563 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_RATEFALLBACK
,
564 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_RATEFALLBACK
)
565 | R8180REG_RATEFALLBACKF_ENABLE
);
567 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
,
568 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
) & 0xf3);
569 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
,
570 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
)
571 | R8180REG_MSRF_ENEDCA
);
572 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ACMCONTROL
, 0);
574 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMWINDOW
, 2);
575 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL
, 100);
576 unit
->LEWordOut(unit
->card
, 0x1d4 | 1 << 16, 0xffff);
578 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
579 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG1
,
580 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG1
) & 0x3f | 0x80);
581 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, 0);
583 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_WPACONF
, 0);
585 unit
->ByteOut(unit
->card
, 0x1f0, 0x32);
586 unit
->ByteOut(unit
->card
, 0x1f1, 0x32);
587 unit
->ByteOut(unit
->card
, 0x1f2, 0x0);
588 unit
->ByteOut(unit
->card
, 0x1f3, 0x0);
589 unit
->ByteOut(unit
->card
, 0x1f4, 0x32);
590 unit
->ByteOut(unit
->card
, 0x1f5, 0x43);
591 unit
->ByteOut(unit
->card
, 0x1f6, 0x0);
592 unit
->ByteOut(unit
->card
, 0x1f7, 0x0);
593 unit
->ByteOut(unit
->card
, 0x1f8, 0x46);
594 unit
->ByteOut(unit
->card
, 0x1f9, 0xa4);
595 unit
->ByteOut(unit
->card
, 0x1fa, 0x0);
596 unit
->ByteOut(unit
->card
, 0x1fb, 0x0);
597 unit
->ByteOut(unit
->card
, 0x1fc, 0x96);
598 unit
->ByteOut(unit
->card
, 0x1fd, 0xa4);
599 unit
->ByteOut(unit
->card
, 0x1fe, 0x0);
600 unit
->ByteOut(unit
->card
, 0x1ff, 0x0);
602 unit
->ByteOut(unit
->card
, 0x158 | 1 << 16, 0x4b);
603 unit
->ByteOut(unit
->card
, 0x159 | 1 << 16, 0x0);
604 unit
->ByteOut(unit
->card
, 0x15a | 1 << 16, 0x4b);
605 unit
->ByteOut(unit
->card
, 0x15b | 1 << 16, 0x0);
606 unit
->ByteOut(unit
->card
, 0x160 | 1 << 16, 0x4b);
607 unit
->ByteOut(unit
->card
, 0x161 | 1 << 16, 0x9);
608 unit
->ByteOut(unit
->card
, 0x162 | 1 << 16, 0x4b);
609 unit
->ByteOut(unit
->card
, 0x163 | 1 << 16, 0x9);
610 unit
->ByteOut(unit
->card
, 0x1ce | 1 << 16, 0xf);
611 unit
->ByteOut(unit
->card
, 0x1cf | 1 << 16, 0x0);
612 unit
->ByteOut(unit
->card
, 0x1e0 | 1 << 16, 0xff);
613 unit
->ByteOut(unit
->card
, 0x1e1 | 1 << 16, 0xf);
614 unit
->ByteOut(unit
->card
, 0x1e2 | 1 << 16, 0x0);
615 unit
->ByteOut(unit
->card
, 0x1f0 | 1 << 16, 0x4e);
616 unit
->ByteOut(unit
->card
, 0x1f1 | 1 << 16, 0x1);
617 unit
->ByteOut(unit
->card
, 0x1f2 | 1 << 16, 0x2);
618 unit
->ByteOut(unit
->card
, 0x1f3 | 1 << 16, 0x3);
619 unit
->ByteOut(unit
->card
, 0x1f4 | 1 << 16, 0x4);
620 unit
->ByteOut(unit
->card
, 0x1f5 | 1 << 16, 0x5);
621 unit
->ByteOut(unit
->card
, 0x1f6 | 1 << 16, 0x6);
622 unit
->ByteOut(unit
->card
, 0x1f7 | 1 << 16, 0x7);
623 unit
->ByteOut(unit
->card
, 0x1f8 | 1 << 16, 0x8);
625 unit
->ByteOut(unit
->card
, 0x14e | 2 << 16, 0x0);
626 unit
->ByteOut(unit
->card
, 0x10c | 2 << 16, 0x4);
627 unit
->ByteOut(unit
->card
, 0x121 | 2 << 16, 0x61);
628 unit
->ByteOut(unit
->card
, 0x122 | 2 << 16, 0x68);
629 unit
->ByteOut(unit
->card
, 0x123 | 2 << 16, 0x6f);
630 unit
->ByteOut(unit
->card
, 0x124 | 2 << 16, 0x76);
631 unit
->ByteOut(unit
->card
, 0x125 | 2 << 16, 0x7d);
632 unit
->ByteOut(unit
->card
, 0x126 | 2 << 16, 0x84);
633 unit
->ByteOut(unit
->card
, 0x127 | 2 << 16, 0x8d);
634 unit
->ByteOut(unit
->card
, 0x14d | 2 << 16, 0x8);
635 unit
->ByteOut(unit
->card
, 0x150 | 2 << 16, 0x5);
636 unit
->ByteOut(unit
->card
, 0x151 | 2 << 16, 0xf5);
637 unit
->ByteOut(unit
->card
, 0x152 | 2 << 16, 0x4);
638 unit
->ByteOut(unit
->card
, 0x153 | 2 << 16, 0xa0);
639 unit
->ByteOut(unit
->card
, 0x154 | 2 << 16, 0x1f);
640 unit
->ByteOut(unit
->card
, 0x155 | 2 << 16, 0x23);
641 unit
->ByteOut(unit
->card
, 0x156 | 2 << 16, 0x45);
642 unit
->ByteOut(unit
->card
, 0x157 | 2 << 16, 0x67);
643 unit
->ByteOut(unit
->card
, 0x158 | 2 << 16, 0x8);
644 unit
->ByteOut(unit
->card
, 0x159 | 2 << 16, 0x8);
645 unit
->ByteOut(unit
->card
, 0x15a | 2 << 16, 0x8);
646 unit
->ByteOut(unit
->card
, 0x15b | 2 << 16, 0x8);
647 unit
->ByteOut(unit
->card
, 0x160 | 2 << 16, 0x8);
648 unit
->ByteOut(unit
->card
, 0x161 | 2 << 16, 0x8);
649 unit
->ByteOut(unit
->card
, 0x162 | 2 << 16, 0x8);
650 unit
->ByteOut(unit
->card
, 0x163 | 2 << 16, 0x8);
651 unit
->ByteOut(unit
->card
, 0x164 | 2 << 16, 0xcf);
652 unit
->ByteOut(unit
->card
, 0x172 | 2 << 16, 0x56);
653 unit
->ByteOut(unit
->card
, 0x173 | 2 << 16, 0x9a);
655 unit
->ByteOut(unit
->card
, 0x134, 0xf0);
656 unit
->ByteOut(unit
->card
, 0x135, 0xf);
657 unit
->ByteOut(unit
->card
, 0x15b, 0x40);
658 unit
->ByteOut(unit
->card
, 0x184, 0x88);
659 unit
->ByteOut(unit
->card
, 0x185, 0x24);
660 unit
->ByteOut(unit
->card
, 0x188, 0x54);
661 unit
->ByteOut(unit
->card
, 0x18b, 0xb8);
662 unit
->ByteOut(unit
->card
, 0x18c, 0x7);
663 unit
->ByteOut(unit
->card
, 0x18d, 0x0);
664 unit
->ByteOut(unit
->card
, 0x194, 0x1b);
665 unit
->ByteOut(unit
->card
, 0x195, 0x12);
666 unit
->ByteOut(unit
->card
, 0x196, 0x0);
667 unit
->ByteOut(unit
->card
, 0x197, 0x6);
668 unit
->ByteOut(unit
->card
, 0x19d, 0x1a);
669 unit
->ByteOut(unit
->card
, 0x19f, 0x10);
670 unit
->ByteOut(unit
->card
, 0x1b4, 0x22);
671 unit
->ByteOut(unit
->card
, 0x1be, 0x80);
672 unit
->ByteOut(unit
->card
, 0x1db, 0x0);
673 unit
->ByteOut(unit
->card
, 0x1ee, 0x0);
674 unit
->ByteOut(unit
->card
, 0x191, 0x3);
675 unit
->ByteOut(unit
->card
, 0x14c | 2 << 16, 0x0);
677 unit
->ByteOut(unit
->card
, 0x19f | 3 << 16, 0x0);
678 unit
->ByteOut(unit
->card
, 0x18c, 0x1);
679 unit
->ByteOut(unit
->card
, 0x18d, 0x10);
680 unit
->ByteOut(unit
->card
, 0x18e, 0x8);
681 unit
->ByteOut(unit
->card
, 0x18f, 0x0);
683 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_TIDACMAP
, 0xfa50);
684 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMIG
, 0);
686 unit
->LELongOut(unit
->card
, 0x1f0 | 1 << 16, 0);
687 unit
->LELongOut(unit
->card
, 0x1f4 | 1 << 16, 0);
688 unit
->ByteOut(unit
->card
, 0x1f8 | 1 << 16, 0);
690 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_RFTIMING
, 0x4001);
692 unit
->LEWordOut(unit
->card
, 0x172 | 2 << 16, 0x569a);
694 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, R8180ECMD_CONFIG
);
696 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_CONFIG3
,
697 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_CONFIG3
)
698 | R8180REG_CONFIG3F_ANAPARAMWRITE
);
699 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EEPROM
, 0);
703 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPIO0
, 1);
704 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPENABLE
, 0);
706 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSOUTPUT
, 0x480);
707 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSSELECT
, 0x2488);
708 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_RFPINSENABLE
, 0x1fff);
709 BusyMilliDelay(100, base
);
711 /* Initialise radio */
713 success
= InitialiseRadio(unit
, base
);
715 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
716 R8180REG_COMMANDF_TXENABLE
| R8180REG_COMMANDF_RXENABLE
);
717 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMASK
, INT_MASK
);
719 unit
->ByteOut(unit
->card
, 0x41, 0xf4);
720 unit
->ByteOut(unit
->card
, 0x40, 0);
721 unit
->ByteOut(unit
->card
, 0x42, 0);
722 unit
->ByteOut(unit
->card
, 0x42, 1);
723 unit
->ByteOut(unit
->card
, 0x40, 0xf);
724 unit
->ByteOut(unit
->card
, 0x42, 0);
725 unit
->ByteOut(unit
->card
, 0x42, 1);
727 unit
->ByteOut(unit
->card
, 0x1db,
728 unit
->ByteIn(unit
->card
, 0x1db) | 1 << 2);
729 unit
->LEWordOut(unit
->card
, 0x172 | 3 << 16, 0x59fa);
730 unit
->LEWordOut(unit
->card
, 0x174 | 3 << 16, 0x59d2);
731 unit
->LEWordOut(unit
->card
, 0x176 | 3 << 16, 0x59d2);
732 unit
->LEWordOut(unit
->card
, 0x178 | 3 << 16, 0x19fa);
733 unit
->LEWordOut(unit
->card
, 0x17a | 3 << 16, 0x19fa);
734 unit
->LEWordOut(unit
->card
, 0x17c | 3 << 16, 0xd0);
735 unit
->ByteOut(unit
->card
, 0x161, 0);
736 unit
->ByteOut(unit
->card
, 0x180 | 1 << 16, 0xf);
737 unit
->ByteOut(unit
->card
, 0x183 | 1 << 16, 3);
738 unit
->ByteOut(unit
->card
, 0x1da, 0x10);
739 unit
->ByteOut(unit
->card
, 0x14d | 2 << 16, 8);
741 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_HSSIPARA
, 0x600321b);
743 /* Set maximum RX frame size */
745 unit
->LEWordOut(unit
->card
, 0x1ec | 1 << 16, 0x800);
747 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_ACMCONTROL
, 0);
748 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
, R8180REG_MSRF_ENEDCA
);
753 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_RXCONF
,
754 R8180REG_RXCONFF_EARLYTHRESH
755 | R8180REG_RXCONFF_AUTORESETPHY
756 | R8180REG_RXCONFF_CHECKBSSID
757 | R8180REG_RXCONFF_MGMT
758 | R8180REG_RXCONFF_DATA
759 | 7 << R8180REG_RXCONFB_FIFOTHRESH
760 | 7 << R8180REG_RXCONFB_MAXDMA
761 | R8180REG_RXCONFF_BCAST
762 | R8180REG_RXCONFF_MCAST
763 | R8180REG_RXCONFF_UCAST
);
764 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_TXAGCCTL
,
765 unit
->ByteIn(unit
->card
, 0x100 + R8180REG_TXAGCCTL
)
766 & ~(R8180REG_TXAGCCTLF_PPGAINSHIFT
767 | R8180REG_TXAGCCTLF_PPANTSELSHIFT
768 | R8180REG_TXAGCCTLF_FEEDBACKANT
));
769 unit
->LELongOut(unit
->card
, 0x100 + R8180REG_TXCONF
,
770 R8180REG_TXCONFF_DISREQQSIZE
771 | 7 << R8180REG_TXCONFB_MAXDMA
772 | TX_TRIES
<< R8180REG_TXCONFB_SHORTTRIES
773 | TX_TRIES
<< R8180REG_TXCONFB_LONGTRIES
);
776 /* Determine features, and get offsets of certain fields within frame
779 unit
->retries_offset
= R8180FRM_RETRY
;
780 unit
->tx_desc_size
= 32;
781 unit
->rx_desc_size
= 20;
785 unit
->iv_sizes
[S2ENC_WEP
] = IV_SIZE
;
786 unit
->iv_sizes
[S2ENC_TKIP
] = EIV_SIZE
;
787 unit
->iv_sizes
[S2ENC_CCMP
] = EIV_SIZE
;
789 /* Set encryption functions */
791 unit
->fragment_encrypt_functions
[S2ENC_NONE
] = WriteClearFragment
;
793 if((unit
->flags
& UNITF_HARDWEP
) != 0)
794 unit
->fragment_encrypt_functions
[S2ENC_WEP
] = WriteWEPFragment
;
796 unit
->fragment_encrypt_functions
[S2ENC_WEP
] = EncryptWEPFragment
;
798 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
799 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = WriteTKIPFragment
;
801 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = EncryptTKIPFragment
;
803 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
804 unit
->fragment_encrypt_functions
[S2ENC_CCMP
] = WriteCCMPFragment
;
806 unit
->fragment_encrypt_functions
[S2ENC_CCMP
] = EncryptCCMPFragment
;
808 /* Set decryption functions */
810 unit
->fragment_decrypt_functions
[S2ENC_NONE
] = ReadClearFragment
;
812 if((unit
->flags
& UNITF_HARDWEP
) != 0)
813 unit
->fragment_decrypt_functions
[S2ENC_WEP
] = ReadWEPFragment
;
815 unit
->fragment_decrypt_functions
[S2ENC_WEP
] = DecryptWEPFragment
;
817 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
818 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = ReadTKIPFragment
;
820 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = DecryptTKIPFragment
;
822 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
823 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = ReadCCMPFragment
;
825 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = DecryptCCMPFragment
;
834 /****i* realtek8180.device/DeinitialiseAdapter *****************************
837 * DeinitialiseAdapter
840 * DeinitialiseAdapter(unit)
842 * VOID DeinitialiseAdapter(struct DevUnit *);
852 ****************************************************************************
856 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
860 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPIO0
, 1);
861 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_GPENABLE
, 1);
868 /****i* realtek8180.device/ConfigureAdapter ********************************
871 * ConfigureAdapter -- Set up card for transmission/reception.
874 * ConfigureAdapter(unit)
876 * VOID ConfigureAdapter(struct DevUnit *);
878 ****************************************************************************
882 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
889 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
890 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_BSSID
+ i
, unit
->bssid
[i
]);
892 /* Set channel and power */
894 SetPower(unit
, base
);
896 msr
= unit
->ByteIn(unit
->card
, 0x100 + R8180REG_MSR
)
897 & ~R8180REG_MSRF_LINK
;
898 if(unit
->assoc_id
!= 0)
900 msr
|= 2 << R8180REG_MSRB_LINK
;
901 if(unit
->generation
>= RTL8187B0_GEN
)
902 msr
|= R8180REG_MSRF_ENEDCA
;
904 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_MSR
, msr
);
908 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMWINDOW
, 2);
909 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_ATIMTRINTERVAL
, 100);
910 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL
, 100);
911 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_BEACONINTERVAL2
, 100);
913 if(unit
->generation
>= RTL8187B0_GEN
)
915 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SIFS
, 0x22);
916 if(unit
->band
== S2BAND_G
)
917 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SLOT
, 0x9);
919 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SLOT
, 0x14);
920 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_EIFS
, 0x5b);
921 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_SENSECOUNT
, 0x5b);
931 /****i* realtek8180.device/GoOnline ****************************************
934 * GoOnline -- Enable transmission/reception.
939 * VOID GoOnline(struct DevUnit *);
941 ****************************************************************************
945 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
947 /* Enable interrupts */
949 unit
->flags
|= UNITF_ONLINE
;
950 unit
->LEWordOut(unit
->card
, 0x100 + R8180REG_INTMASK
, INT_MASK
);
952 /* Enable frame transmission and reception */
954 unit
->ByteOut(unit
->card
, 0x100 + R8180REG_COMMAND
,
955 R8180REG_COMMANDF_TXENABLE
| R8180REG_COMMANDF_RXENABLE
);
957 /* Record start time and report Online event */
959 GetSysTime(&unit
->stats
.LastStart
);
960 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
967 /****i* realtek8180.device/GoOffline ***************************************
970 * GoOffline -- Disable transmission/reception.
975 * VOID GoOffline(struct DevUnit *);
985 ****************************************************************************
989 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
991 unit
->flags
&= ~UNITF_ONLINE
;
993 /* Flush pending read and write requests */
995 FlushUnit(unit
, MGMT_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
997 /* Report Offline event and return */
999 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
1005 /****i* realtek8180.device/SetOptions **************************************
1008 * SetOptions -- Set and use interface options.
1011 * reconfigure = SetOptions(unit, tag_list)
1013 * BOOL SetOptions(struct DevUnit *, struct TagItem *);
1015 ****************************************************************************
1019 BOOL
SetOptions(struct DevUnit
*unit
, const struct TagItem
*tag_list
,
1020 struct DevBase
*base
)
1022 struct TagItem
*tag_item
, *tlist
= (struct TagItem
*)tag_list
;
1023 BOOL reconfigure
= TRUE
;
1025 while((tag_item
= NextTagItem(&tlist
)) != NULL
)
1027 switch(tag_item
->ti_Tag
)
1030 ReportEvents(unit
, S2EVENT_CONNECT
, base
);
1034 CopyMem((APTR
)tag_item
->ti_Data
, unit
->bssid
, ETH_ADDRESSSIZE
);
1037 case S2INFO_AssocID
:
1038 unit
->assoc_id
= tag_item
->ti_Data
;
1041 case S2INFO_Capabilities
:
1042 unit
->capabilities
= tag_item
->ti_Data
;
1043 if((unit
->capabilities
& (1 << 5)) != 0)
1044 unit
->flags
|= UNITF_SHORTPREAMBLE
;
1046 unit
->flags
&= ~UNITF_SHORTPREAMBLE
;
1049 case S2INFO_DefaultKeyNo
:
1050 unit
->tx_key_no
= tag_item
->ti_Data
;
1053 case S2INFO_PortType
:
1054 unit
->mode
= tag_item
->ti_Data
;
1057 case S2INFO_Channel
:
1058 if(tag_item
->ti_Data
!= unit
->channel
)
1060 unit
->channel
= tag_item
->ti_Data
;
1066 unit
->band
= tag_item
->ti_Data
;
1067 if(unit
->band
== S2BAND_G
)
1070 unit
->tx_rate_code
= 11; /* 54 Mbps */
1071 unit
->mgmt_rate
= 2;
1072 unit
->mgmt_rate_code
= 1; /* 2 Mbps */
1074 else if(unit
->band
== S2BAND_B
)
1077 unit
->tx_rate_code
= 3; /* 11 Mbps */
1078 unit
->mgmt_rate
= 1;
1079 unit
->mgmt_rate_code
= 0; /* 1 Mbps */
1091 /****i* realtek8180.device/SetKey ******************************************
1094 * SetKey -- Set an encryption key.
1097 * SetKey(unit, index, type, key, key_length,
1100 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1103 ****************************************************************************
1107 VOID
SetKey(struct DevUnit
*unit
, ULONG index
, ULONG type
, const UBYTE
*key
,
1108 ULONG key_length
, const UBYTE
*rx_counter
, struct DevBase
*base
)
1110 struct KeyUnion
*slot
;
1111 struct EClockVal eclock
;
1115 slot
= &unit
->keys
[index
];
1119 CopyMem(key
, slot
->u
.wep
.key
, key_length
);
1120 slot
->u
.wep
.length
= key_length
;
1122 if((unit
->flags
& UNITF_HARDWEP
) == 0)
1124 /* Create a reasonably random IV */
1126 ReadEClock(&eclock
);
1127 slot
->u
.wep
.tx_iv
= FastRand(eclock
.ev_lo
^ eclock
.ev_hi
);
1133 CopyMem(key
, slot
->u
.tkip
.key
, 16);
1134 CopyMem(key
+ 16, slot
->u
.tkip
.tx_mic_key
, MIC_SIZE
);
1135 CopyMem(key
+ 24, slot
->u
.tkip
.rx_mic_key
, MIC_SIZE
);
1136 slot
->u
.tkip
.tx_iv_low
= 0;
1137 slot
->u
.tkip
.tx_iv_high
= 0;
1138 slot
->u
.tkip
.rx_iv_low
= LEWord(*(UWORD
*)rx_counter
);
1139 slot
->u
.tkip
.rx_iv_high
= LELong(*(ULONG
*)(rx_counter
+ 2));
1140 slot
->u
.tkip
.tx_ttak_set
= FALSE
;
1141 slot
->u
.tkip
.rx_ttak_set
= FALSE
;
1143 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
1148 /* Convert key to native endianness */
1150 for(i
= 0; i
< 8; i
++)
1151 slot
->u
.tkip
.key
[i
] = LEWord(slot
->u
.tkip
.key
[i
]);
1157 CopyMem(key
, slot
->u
.ccmp
.key
, 16);
1158 slot
->u
.ccmp
.tx_iv_low
= 0;
1159 slot
->u
.ccmp
.tx_iv_high
= 0;
1160 slot
->u
.ccmp
.rx_iv_low
= LEWord(*(UWORD
*)rx_counter
);
1161 slot
->u
.ccmp
.rx_iv_high
= LELong(*(ULONG
*)(rx_counter
+ 2));
1162 slot
->u
.ccmp
.stream_set
= FALSE
;
1165 /* Update type of key in selected slot */
1175 /****i* realtek8180.device/AddMulticastRange *******************************
1181 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1183 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1185 ****************************************************************************
1189 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1190 const UBYTE
*upper_bound
, struct DevBase
*base
)
1192 struct AddressRange
*range
;
1193 ULONG lower_bound_left
, upper_bound_left
;
1194 UWORD lower_bound_right
, upper_bound_right
;
1196 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1197 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1198 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1199 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1201 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1202 upper_bound_left
, upper_bound_right
, base
);
1208 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1211 range
->lower_bound_left
= lower_bound_left
;
1212 range
->lower_bound_right
= lower_bound_right
;
1213 range
->upper_bound_left
= upper_bound_left
;
1214 range
->upper_bound_right
= upper_bound_right
;
1215 range
->add_count
= 1;
1218 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1219 unit
->range_count
++;
1220 SetMulticast(unit
, base
);
1225 return range
!= NULL
;
1230 /****i* realtek8180.device/RemMulticastRange *******************************
1236 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1238 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1240 ****************************************************************************
1244 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1245 const UBYTE
*upper_bound
, struct DevBase
*base
)
1247 struct AddressRange
*range
;
1248 ULONG lower_bound_left
, upper_bound_left
;
1249 UWORD lower_bound_right
, upper_bound_right
;
1251 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1252 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1253 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1254 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1256 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1257 upper_bound_left
, upper_bound_right
, base
);
1261 if(--range
->add_count
== 0)
1264 Remove((APTR
)range
);
1265 unit
->range_count
--;
1266 SetMulticast(unit
, base
);
1268 FreeMem(range
, sizeof(struct AddressRange
));
1272 return range
!= NULL
;
1277 /****i* realtek8180.device/FindMulticastRange ******************************
1280 * FindMulticastRange
1283 * range = FindMulticastRange(unit, lower_bound_left,
1284 * lower_bound_right, upper_bound_left, upper_bound_right)
1286 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1287 * UWORD, ULONG, UWORD);
1289 ****************************************************************************
1293 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
1294 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
1295 UWORD upper_bound_right
, struct DevBase
*base
)
1297 struct AddressRange
*range
, *tail
;
1300 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1301 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1303 while(range
!= tail
&& !found
)
1305 if(lower_bound_left
== range
->lower_bound_left
&&
1306 lower_bound_right
== range
->lower_bound_right
&&
1307 upper_bound_left
== range
->upper_bound_left
&&
1308 upper_bound_right
== range
->upper_bound_right
)
1311 range
= (APTR
)range
->node
.mln_Succ
;
1322 /****i* realtek8180.device/SetMulticast ************************************
1328 * SetMulticast(unit)
1330 * VOID SetMulticast(struct DevUnit *);
1332 ****************************************************************************
1336 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
)
1343 /****i* realtek8180.device/FindTypeStats ***********************************
1349 * stats = FindTypeStats(unit, list,
1352 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1355 ****************************************************************************
1359 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1360 ULONG packet_type
, struct DevBase
*base
)
1362 struct TypeStats
*stats
, *tail
;
1365 stats
= (APTR
)list
->mlh_Head
;
1366 tail
= (APTR
)&list
->mlh_Tail
;
1368 while(stats
!= tail
&& !found
)
1370 if(stats
->packet_type
== packet_type
)
1373 stats
= (APTR
)stats
->node
.mln_Succ
;
1384 /****i* realtek8180.device/FlushUnit ***************************************
1390 * FlushUnit(unit, last_queue, error)
1392 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1394 ****************************************************************************
1398 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
1399 struct DevBase
*base
)
1401 struct IORequest
*request
;
1403 struct Opener
*opener
, *tail
;
1405 /* Abort queued requests */
1407 for(i
= 0; i
<= last_queue
; i
++)
1409 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
1411 request
->io_Error
= IOERR_ABORTED
;
1412 ReplyMsg((APTR
)request
);
1417 opener
= (APTR
)unit
->openers
.mlh_Head
;
1418 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1420 /* Flush every opener's read queues */
1422 while(opener
!= tail
)
1424 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1426 request
->io_Error
= error
;
1427 ReplyMsg((APTR
)request
);
1429 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
1431 request
->io_Error
= error
;
1432 ReplyMsg((APTR
)request
);
1434 opener
= (APTR
)opener
->node
.mln_Succ
;
1438 opener
= request
->ios2_BufferManagement
;
1439 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1441 request
->io_Error
= IOERR_ABORTED
;
1442 ReplyMsg((APTR
)request
);
1444 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
1446 request
->io_Error
= IOERR_ABORTED
;
1447 ReplyMsg((APTR
)request
);
1458 /****i* realtek8180.device/RXInt *******************************************
1461 * RXInt -- Soft interrupt for packet reception.
1466 * VOID RXInt(struct DevUnit *);
1471 * unit - A unit of this device.
1476 ****************************************************************************
1480 VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
1482 UWORD ieee_length
, frame_control
, frame_type
, slot
, next_slot
,
1483 frame_size
, frame_subtype
, encryption
, key_no
, buffer_no
, old_length
;
1484 struct DevBase
*base
;
1485 BOOL is_good
, proceed
= TRUE
;
1488 UBYTE
*rx_desc
, *buffer
, *p
, *frame
, *data
, *snap_frame
, *source
;
1490 base
= unit
->device
;
1491 slot
= unit
->rx_slot
;
1492 rx_desc
= unit
->rx_descs
[slot
];
1493 next_slot
= (slot
+ 1) % RX_SLOT_COUNT
;
1498 buffer
= unit
->rx_buffers
[slot
];
1500 status
= LELong(*(ULONG
*)(rx_desc
+ R8180FRM_RXSTATUS
));
1501 frame_size
= status
& R8180FRM_RXSTATUSF_LENGTH
;
1503 if((status
& (R8180FRM_RXSTATUSF_DMAERR
| R8180FRM_RXSTATUSF_OVERFLOW
1504 | R8180FRM_RXSTATUSF_RXERR
| R8180FRM_RXSTATUSF_BADCRC
)) == 0
1505 && frame_size
>= WIFI_FRM_DATA
+ 4)
1507 /* Get fragment info */
1510 ieee_length
= frame_size
- 4 - WIFI_FRM_DATA
;
1511 data
= frame
+ WIFI_FRM_DATA
;
1513 LEWord(*(UWORD
*)(frame
+ WIFI_FRM_CONTROL
));
1515 /* Get buffer to store fragment in */
1517 frag_no
= LEWord(*(UWORD
*)(frame
+ WIFI_FRM_SEQCONTROL
));
1518 if(unit
->mode
== S2PORT_ADHOC
)
1519 source
= frame
+ WIFI_FRM_ADDRESS2
;
1521 source
= frame
+ WIFI_FRM_ADDRESS3
;
1522 snap_frame
= GetRXBuffer(unit
, source
, frag_no
, &buffer_no
, base
);
1524 /* Get location to put new data */
1526 if(snap_frame
!= NULL
)
1528 if((frag_no
& 0xf ) > 0)
1530 BEWord(*(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
));
1533 /* Create new 802.3 header */
1535 CopyMem(frame
+ WIFI_FRM_ADDRESS1
, snap_frame
,
1537 CopyMem(source
, snap_frame
+ ETH_PACKET_SOURCE
,
1541 p
= snap_frame
+ ETH_HEADERSIZE
+ old_length
;
1543 /* Append fragment to frame, decrypting fragment if necessary */
1545 if((frame_control
& WIFI_FRM_CONTROLF_WEP
) != 0)
1547 key_no
= data
[3] >> 6 & 0x3;
1548 encryption
= unit
->keys
[key_no
].type
;
1551 encryption
= S2ENC_NONE
;
1553 /* Decrypt, check and/or copy fragment */
1555 is_good
= unit
->fragment_decrypt_functions
[encryption
](unit
,
1556 frame
, data
, &ieee_length
, p
, base
);
1558 /* Update length in frame being built with current fragment, or
1559 increment bad frame counter if fragment is bad */
1563 ieee_length
+= old_length
;
1564 *(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
) =
1565 MakeBEWord(ieee_length
);
1568 unit
->stats
.BadData
++;
1570 /* If all fragments have arrived, process the complete frame */
1572 if((frame_control
& WIFI_FRM_CONTROLF_MOREFRAGS
) == 0)
1576 /* Decrypt complete frame if necessary */
1578 data
= snap_frame
+ ETH_HEADERSIZE
;
1579 if(encryption
== S2ENC_TKIP
1580 && (unit
->flags
& UNITF_HARDTKIP
) == 0)
1582 is_good
= TKIPDecryptFrame(unit
, snap_frame
, data
,
1583 ieee_length
, data
, key_no
, base
);
1584 ieee_length
-= MIC_SIZE
;
1585 *(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
) =
1586 MakeBEWord(ieee_length
);
1588 unit
->stats
.BadData
++;
1594 /* Get frame's 802.11 type and subtype */
1596 frame_type
= (frame_control
& WIFI_FRM_CONTROLF_TYPE
)
1597 >> WIFI_FRM_CONTROLB_TYPE
;
1599 (frame_control
& WIFI_FRM_CONTROLF_SUBTYPE
)
1600 >> WIFI_FRM_CONTROLB_SUBTYPE
;
1602 /* If it's a management frame, process it separately;
1603 otherwise distribute it to clients after filtering */
1605 if(frame_type
== WIFI_FRMTYPE_MGMT
)
1607 if(frame_subtype
!= 8)
1608 DistributeMgmtFrame(unit
, frame
, frame_size
- 4,
1611 else if(AddressFilter(unit
, snap_frame
+ ETH_PACKET_DEST
,
1614 unit
->stats
.PacketsReceived
++;
1615 DistributeRXPacket(unit
, snap_frame
, base
);
1620 /* Mark fragment buffer as unused for next time */
1622 unit
->rx_fragment_nos
[buffer_no
] = -1;
1625 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_RX
, base
);
1634 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1638 /* Prepare descriptor for next time */
1640 unit
->ReceiveFrame(unit
->card
, buffer
,
1641 FRAME_BUFFER_SIZE
+ R8180_MAXDESCSIZE
);
1643 /* Get next descriptor */
1646 if(unit
->bus
== USB_BUS
)
1650 unit
->rx_slot
= slot
;
1657 /****i* realtek8180.device/GetRXBuffer *************************************
1660 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1663 * buffer = GetRXBuffer(unit, address, frag_no)
1665 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1667 ****************************************************************************
1671 static UBYTE
*GetRXBuffer(struct DevUnit
*unit
, const UBYTE
*address
,
1672 UWORD frag_no
, UWORD
*buffer_no
, struct DevBase
*base
)
1679 buffer
= unit
->rx_frames
;
1680 for(i
= 0, found
= FALSE
; i
< FRAME_BUFFER_COUNT
* 2 && !found
; i
++)
1682 /* Throw away old buffer contents if we didn't find a free slot the
1683 first time around */
1685 if(i
>= FRAME_BUFFER_COUNT
)
1686 unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
] = -1;
1688 /* For a frame's first fragment, find an empty slot; for subsequent
1689 fragments, find a slot with matching source address */
1691 n
= unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
];
1692 if(n
== -1 && (frag_no
& 0xf) == 0
1693 || *((ULONG
*)(buffer
+ ETH_PACKET_SOURCE
))
1694 == *((ULONG
*)(address
))
1695 && *((UWORD
*)(buffer
+ ETH_PACKET_SOURCE
+ 4))
1696 == *((UWORD
*)(address
+ 4)))
1700 unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
] = frag_no
;
1704 buffer
+= FRAME_BUFFER_SIZE
;
1715 /****i* realtek8180.device/DistributeRXPacket ******************************
1718 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1721 * DistributeRXPacket(unit, frame)
1723 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1725 ****************************************************************************
1729 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*frame
,
1730 struct DevBase
*base
)
1732 UWORD packet_size
, ieee_length
;
1733 BOOL is_orphan
= TRUE
, accepted
, is_snap
= FALSE
;
1736 const UBYTE
*template = snap_template
;
1737 struct IOSana2Req
*request
, *request_tail
;
1738 struct Opener
*opener
, *opener_tail
;
1739 struct TypeStats
*tracker
;
1741 buffer
= unit
->rx_buffer
;
1742 ieee_length
= BEWord(*(UWORD
*)(frame
+ ETH_PACKET_IEEELEN
));
1743 packet_size
= ETH_HEADERSIZE
+ ieee_length
;
1744 if(ieee_length
>= SNAP_HEADERSIZE
)
1745 is_snap
= *(const ULONG
*)(frame
+ ETH_PACKET_DATA
)
1746 == *(const ULONG
*)template;
1748 /* De-encapsulate SNAP packets and get packet type */
1752 packet_size
-= SNAP_HEADERSIZE
;
1753 CopyMem(frame
, buffer
, ETH_PACKET_TYPE
);
1754 CopyMem(frame
+ ETH_HEADERSIZE
+ SNAP_FRM_TYPE
,
1755 buffer
+ ETH_PACKET_TYPE
, packet_size
- ETH_PACKET_TYPE
);
1757 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1759 /* Offer packet to every opener */
1761 opener
= (APTR
)unit
->openers
.mlh_Head
;
1762 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1764 while(opener
!= opener_tail
)
1766 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1767 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1770 /* Offer packet to each request until it's accepted */
1772 while(request
!= request_tail
&& !accepted
)
1774 if(request
->ios2_PacketType
== packet_type
)
1776 CopyPacket(unit
, request
, packet_size
, packet_type
,
1781 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1786 opener
= (APTR
)opener
->node
.mln_Succ
;
1789 /* If packet was unwanted, give it to S2_READORPHAN request */
1793 unit
->stats
.UnknownTypesReceived
++;
1794 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1797 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1798 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1803 /* Update remaining statistics */
1805 if(packet_type
<= ETH_MTU
)
1806 packet_type
= ETH_MTU
;
1808 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1811 tracker
->stats
.PacketsReceived
++;
1812 tracker
->stats
.BytesReceived
+= packet_size
;
1820 /****i* realtek8180.device/CopyPacket **************************************
1823 * CopyPacket -- Copy packet to client's buffer.
1826 * CopyPacket(unit, request, packet_size, packet_type,
1829 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1832 ****************************************************************************
1836 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1837 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
,
1838 struct DevBase
*base
)
1840 struct Opener
*opener
;
1841 BOOL filtered
= FALSE
;
1843 /* Set multicast and broadcast flags */
1845 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1846 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1847 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1848 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1849 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1850 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1852 /* Set source and destination addresses and packet type */
1854 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1856 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1858 request
->ios2_PacketType
= packet_type
;
1860 /* Adjust for cooked packet request */
1862 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1864 packet_size
-= ETH_PACKET_DATA
;
1865 buffer
+= ETH_PACKET_DATA
;
1869 packet_size
+= 4; /* Needed for Shapeshifter & Fusion? */
1871 request
->ios2_DataLength
= packet_size
;
1875 opener
= request
->ios2_BufferManagement
;
1876 if(request
->ios2_Req
.io_Command
== CMD_READ
&&
1877 opener
->filter_hook
!= NULL
)
1878 if(!CallHookPkt(opener
->filter_hook
, request
, buffer
))
1883 /* Copy packet into opener's buffer and reply packet */
1885 if(!opener
->rx_function(request
->ios2_Data
, buffer
, packet_size
))
1887 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1888 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1890 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1893 Remove((APTR
)request
);
1894 ReplyMsg((APTR
)request
);
1902 /****i* realtek8180.device/AddressFilter ***********************************
1905 * AddressFilter -- Determine if an RX packet should be accepted.
1908 * accept = AddressFilter(unit, address)
1910 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1912 ****************************************************************************
1916 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1917 struct DevBase
*base
)
1919 struct AddressRange
*range
, *tail
;
1922 UWORD address_right
;
1924 /* Check whether address is unicast/broadcast or multicast */
1926 address_left
= BELong(*((ULONG
*)address
));
1927 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1929 if(((address_left
& 0x01000000) != 0) &&
1930 !((address_left
== 0xffffffff) && (address_right
== 0xffff)))
1932 /* Check if this multicast address is wanted */
1934 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1935 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1938 while((range
!= tail
) && !accept
)
1940 if((address_left
> range
->lower_bound_left
||
1941 address_left
== range
->lower_bound_left
&&
1942 address_right
>= range
->lower_bound_right
) &&
1943 (address_left
< range
->upper_bound_left
||
1944 address_left
== range
->upper_bound_left
&&
1945 address_right
<= range
->upper_bound_right
))
1947 range
= (APTR
)range
->node
.mln_Succ
;
1951 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1959 /****i* realtek8180.device/DistributeMgmtFrame *****************************
1962 * DistributeMgmtFrame -- Send a management frame to clients.
1965 * DistributeMgmtFrame(unit, frame, frame_size)
1967 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
1969 ****************************************************************************
1973 static VOID
DistributeMgmtFrame(struct DevUnit
*unit
, UBYTE
*frame
,
1974 UWORD frame_size
, struct DevBase
*base
)
1976 struct IOSana2Req
*request
;
1977 struct Opener
*opener
, *opener_tail
;
1979 /* Send packet to every opener */
1981 opener
= (APTR
)unit
->openers
.mlh_Head
;
1982 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1984 while(opener
!= opener_tail
)
1986 request
= (APTR
)RemHead(&opener
->mgmt_port
.mp_MsgList
);
1990 /* Copy packet into opener's buffer and reply packet */
1992 if(frame_size
<= request
->ios2_DataLength
)
1994 CopyMem(frame
, request
->ios2_Data
, frame_size
);
1995 request
->ios2_DataLength
= frame_size
;
1999 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
2000 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
2002 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
2005 ReplyMsg((APTR
)request
);
2007 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2010 opener
= (APTR
)opener
->node
.mln_Succ
;
2018 /****i* realtek8180.device/TXInt *******************************************
2021 * TXInt -- Soft interrupt for packet transmission.
2026 * VOID TXInt(struct DevUnit *);
2031 * unit - A unit of this device.
2036 ****************************************************************************
2040 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
2042 struct DevBase
*base
;
2043 UWORD i
, frame_size
, data_size
, packet_type
, body_size
, slot
, new_slot
,
2044 encryption
, subtype
, duration
;
2045 UBYTE
*buffer
, *q
, *plaintext
, *ciphertext
, *frame
,
2046 mic_header
[ETH_ADDRESSSIZE
* 2];
2047 const UBYTE
*p
, *dest
, *source
;
2048 struct IOSana2Req
*request
;
2049 BOOL proceed
= TRUE
, is_ieee
, has_bssid
;
2050 struct Opener
*opener
;
2051 ULONG wire_error
, control_value
;
2053 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
2055 struct MsgPort
*port
;
2056 struct TypeStats
*tracker
;
2058 base
= unit
->device
;
2059 port
= unit
->request_ports
[WRITE_QUEUE
];
2061 while(proceed
&& (!IsMsgPortEmpty(port
)))
2063 slot
= unit
->tx_in_slot
;
2064 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2066 if(new_slot
!= unit
->tx_out_slot
)
2071 /* Get request and DMA frame descriptor */
2073 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2075 Remove((APTR
)request
);
2076 unit
->tx_requests
[slot
] = request
;
2077 tx_desc
= unit
->tx_descs
[slot
];
2078 frame
= unit
->tx_buffers
[slot
];
2080 /* Get packet data */
2082 opener
= request
->ios2_BufferManagement
;
2083 dma_tx_function
= opener
->dma_tx_function
;
2084 if(dma_tx_function
!= NULL
)
2085 buffer
= dma_tx_function(request
->ios2_Data
);
2091 buffer
= unit
->tx_buffer
;
2092 if(!opener
->tx_function(buffer
, request
->ios2_Data
,
2093 request
->ios2_DataLength
))
2095 error
= S2ERR_NO_RESOURCES
;
2096 wire_error
= S2WERR_BUFF_ERROR
;
2098 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2099 | S2EVENT_TX
, base
);
2105 /* Get packet type and/or length */
2107 data_size
= request
->ios2_DataLength
;
2108 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) != 0)
2110 data_size
-= ETH_PACKET_DATA
;
2111 packet_type
= BEWord(*(UWORD
*)(buffer
+ ETH_PACKET_TYPE
));
2114 packet_type
= request
->ios2_PacketType
;
2115 is_ieee
= packet_type
<= ETH_MTU
;
2117 /* Determine encryption type and frame subtype */
2121 encryption
= unit
->keys
[unit
->tx_key_no
].type
;
2126 encryption
= S2ENC_NONE
;
2130 /* Get source and destination addresses */
2132 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) != 0)
2135 source
= buffer
+ ETH_ADDRESSSIZE
;
2136 buffer
+= ETH_ADDRESSSIZE
* 2 + 2;
2140 dest
= request
->ios2_DstAddr
;
2141 source
= unit
->address
;
2144 /* Write 802.11 header */
2147 *(UWORD
*)q
= MakeLEWord(
2148 (encryption
== S2ENC_NONE
? 0 : WIFI_FRM_CONTROLF_WEP
)
2149 | (unit
->mode
== S2PORT_ADHOC
? 0 : WIFI_FRM_CONTROLF_TODS
)
2150 | subtype
<< WIFI_FRM_CONTROLB_SUBTYPE
2151 | WIFI_FRMTYPE_DATA
<< WIFI_FRM_CONTROLB_TYPE
);
2154 if(unit
->mode
== S2PORT_ADHOC
)
2158 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2161 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2164 if(unit
->mode
== S2PORT_ADHOC
)
2168 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2170 *(UWORD
*)q
= MakeLEWord(unit
->tx_sequence
);
2171 unit
->tx_sequence
+= 0x10;
2174 /* Leave room for encryption overhead */
2177 q
+= unit
->iv_sizes
[encryption
];
2180 /* Write SNAP header */
2184 for(i
= 0, p
= snap_template
;
2185 i
< SNAP_FRM_TYPE
; i
++)
2187 *(UWORD
*)q
= MakeBEWord(packet_type
);
2189 body_size
+= SNAP_HEADERSIZE
;
2192 /* Copy data into frame */
2194 CopyMem(buffer
, q
, data_size
);
2195 body_size
+= data_size
;
2197 /* Append MIC to frame for TKIP */
2199 if(encryption
== S2ENC_TKIP
)
2202 for(i
= 0, p
= dest
; i
< ETH_ADDRESSSIZE
; i
++)
2204 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2206 TKIPEncryptFrame(unit
, mic_header
, plaintext
, body_size
,
2208 body_size
+= MIC_SIZE
;
2211 /* Encrypt fragment if applicable */
2213 unit
->fragment_encrypt_functions
[encryption
](unit
, frame
,
2214 plaintext
, &body_size
, ciphertext
, base
);
2216 /* Clear frame descriptor as far as start of 802.11 header */
2219 for(i
= 0; i
< unit
->tx_desc_size
; i
++)
2222 /* Set TX control field */
2224 frame_size
= WIFI_FRM_DATA
+ body_size
;
2225 control_value
= R8180FRM_TXCONTROLF_NOENC
2226 | R8180FRM_TXCONTROLF_FIRSTFRAG
2227 | R8180FRM_TXCONTROLF_LASTFRAG
2228 | unit
->tx_rate_code
<< R8180FRM_TXCONTROLB_RATE
2230 *(ULONG
*)(tx_desc
+ R8180FRM_TXCONTROL
) =
2231 MakeLELong(control_value
);
2235 has_bssid
= ((frame
+ WIFI_FRM_ADDRESS1
)[0] & 0x1) == 0;
2237 duration
= SIFS_TIME
+ GetDuration(unit
, 14,
2238 AckRate(unit
, unit
->tx_rate
, base
), FALSE
, base
);
2241 *(UWORD
*)(frame
+ WIFI_FRM_DURATION
) = MakeLEWord(duration
);
2243 if(unit
->generation
>= RTL8187B0_GEN
)
2245 duration
+= GetDuration(unit
, frame_size
+ 4,
2247 (unit
->flags
& UNITF_SHORTPREAMBLE
) != 0 && has_bssid
,
2249 *(UWORD
*)(tx_desc
+ R8180FRM_TXDUR
) = MakeLEWord(duration
);
2252 /* Set max number of retries */
2254 *(ULONG
*)(tx_desc
+ unit
->retries_offset
) =
2255 MakeLELong((TX_TRIES
- 1) << 8);
2257 /* Pass packet to adapter */
2259 unit
->SendFrame(unit
->card
, tx_desc
,
2260 R8180_MAXDESCSIZE
+ frame_size
);
2261 unit
->tx_in_slot
= new_slot
;
2265 /* Reply failed request */
2267 request
->ios2_Req
.io_Error
= error
;
2268 request
->ios2_WireError
= wire_error
;
2269 ReplyMsg((APTR
)request
);
2272 /* Update statistics */
2276 unit
->stats
.PacketsSent
++;
2278 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2279 request
->ios2_PacketType
, base
);
2282 tracker
->stats
.PacketsSent
++;
2283 tracker
->stats
.BytesSent
+= ETH_HEADERSIZE
+ data_size
;
2291 /* Don't try to keep sending packets if there's no space left */
2295 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2296 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2300 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_IGNORE
;
2301 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2309 /****i* realtek8180.device/MgmtTXInt ***************************************
2312 * MgmtTXInt -- Soft interrupt for management frame transmission.
2317 * VOID MgmtTXInt(struct DevUnit *);
2322 * unit - A unit of this device.
2327 ****************************************************************************
2331 static VOID
MgmtTXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
2333 struct DevBase
*base
;
2334 UWORD frame_size
, slot
, new_slot
, i
, duration
;
2335 UBYTE
*desc
, *frame
, *q
;
2336 struct IOSana2Req
*request
;
2337 BOOL proceed
= TRUE
, has_bssid
;
2338 ULONG control_value
;
2339 struct MsgPort
*port
;
2341 base
= unit
->device
;
2342 port
= unit
->request_ports
[MGMT_QUEUE
];
2344 while(proceed
&& (!IsMsgPortEmpty(port
)))
2346 slot
= unit
->tx_in_slot
;
2347 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2349 if(new_slot
!= unit
->tx_out_slot
)
2351 /* Get request and frame descriptor */
2353 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2355 Remove((APTR
)request
);
2356 unit
->tx_requests
[slot
] = request
;
2357 desc
= unit
->tx_descs
[slot
];
2358 frame
= unit
->tx_buffers
[slot
];
2360 /* Get packet length */
2362 frame_size
= request
->ios2_DataLength
;
2364 /* Copy frame into transmit buffer */
2366 CopyMem(request
->ios2_Data
, frame
, frame_size
);
2368 /* Clear frame descriptor as far as start of 802.11 header */
2371 for(i
= 0; i
< unit
->tx_desc_size
; i
++)
2374 /* Set TX control field */
2376 control_value
= R8180FRM_TXCONTROLF_NOENC
2377 | R8180FRM_TXCONTROLF_FIRSTFRAG
2378 | R8180FRM_TXCONTROLF_LASTFRAG
2379 | unit
->mgmt_rate_code
<< R8180FRM_TXCONTROLB_RATE
2381 *(ULONG
*)(desc
+ R8180FRM_TXCONTROL
) = MakeLELong(control_value
);
2385 has_bssid
= ((frame
+ WIFI_FRM_ADDRESS1
)[0] & 0x1) == 0;
2387 duration
= SIFS_TIME
+ GetDuration(unit
, 14,
2388 AckRate(unit
, unit
->mgmt_rate
, base
), FALSE
, base
);
2391 *(UWORD
*)(frame
+ WIFI_FRM_DURATION
) = MakeLEWord(duration
);
2393 if(unit
->generation
>= RTL8187B0_GEN
)
2395 duration
+= GetDuration(unit
, frame_size
+ 4,
2396 unit
->mgmt_rate
, FALSE
, base
);
2397 *(UWORD
*)(desc
+ R8180FRM_TXDUR
) = MakeLEWord(duration
);
2400 /* Set max number of retries */
2402 *(ULONG
*)(desc
+ unit
->retries_offset
) =
2403 MakeLELong((TX_TRIES
- 1) << 8);
2405 /* Set sequence number */
2407 *(UWORD
*)(frame
+ WIFI_FRM_SEQCONTROL
) =
2408 MakeLEWord(unit
->tx_sequence
);
2409 unit
->tx_sequence
+= 0x10;
2411 /* Pass packet to adapter */
2413 unit
->SendFrame(unit
->card
, desc
, R8180_MAXDESCSIZE
+ frame_size
);
2414 unit
->tx_in_slot
= new_slot
;
2420 /* Don't try to keep sending packets if there's no space left */
2424 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2425 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2429 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2430 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_IGNORE
;
2438 /****i* realtek8180.device/RetireTXSlot ************************************
2441 * RetireTXSlot -- Clean up after a frame has been sent.
2444 * RetireTXSlot(unit)
2446 * VOID RetireTXSlot(struct DevUnit *);
2448 ****************************************************************************
2452 VOID
RetireTXSlot(struct DevUnit
*unit
, struct DevBase
*base
)
2454 UWORD frame_size
, slot
;
2455 struct IOSana2Req
*request
;
2456 struct TypeStats
*tracker
;
2458 /* Update statistics */
2460 slot
= unit
->tx_out_slot
;
2461 request
= unit
->tx_requests
[slot
];
2462 if(request
->ios2_Req
.io_Command
!= S2_WRITEMGMT
)
2464 frame_size
= request
->ios2_DataLength
;
2465 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2466 frame_size
+= ETH_HEADERSIZE
;
2468 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2469 request
->ios2_PacketType
, base
);
2472 tracker
->stats
.PacketsSent
++;
2473 tracker
->stats
.BytesSent
+= frame_size
;
2479 request
->ios2_Req
.io_Error
= 0;
2480 ReplyMsg((APTR
)request
);
2482 unit
->tx_out_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2484 /* Restart downloads if they had stopped */
2486 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
2487 Cause(&unit
->tx_int
);
2488 if(unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
== PA_IGNORE
)
2489 Cause(&unit
->mgmt_int
);
2496 /****i* realtek8180.device/ReportEvents ************************************
2502 * ReportEvents(unit, events)
2504 * VOID ReportEvents(struct DevUnit *, ULONG);
2509 * unit - A unit of this device.
2510 * events - A mask of events to report.
2515 ****************************************************************************
2519 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2520 struct DevBase
*base
)
2522 struct IOSana2Req
*request
, *tail
, *next_request
;
2525 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2526 next_request
= (APTR
)list
->lh_Head
;
2527 tail
= (APTR
)&list
->lh_Tail
;
2530 while(next_request
!= tail
)
2532 request
= next_request
;
2533 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2535 if((request
->ios2_WireError
& events
) != 0)
2537 request
->ios2_WireError
= events
;
2538 Remove((APTR
)request
);
2539 ReplyMsg((APTR
)request
);
2549 /****i* realtek8180.device/GetDuration *************************************
2552 * GetDuration -- Calculate a duration value.
2555 * GetDuration(unit, length, rate, is_mgmt)
2557 * VOID GetDuration(struct DevUnit *);
2560 * Calculates a duration for a frame of given length when transmitted
2561 * at a given rate. If this is a transmiss
2564 * unit - A unit of this device.
2565 * length - Length of frame whose duration is to be calculated.
2566 * rate - Rate frame will be transmitted at (in Mbps, rounded down).
2567 * is_short - Indicates if frame has a short preamble.
2572 ****************************************************************************
2576 static UWORD
GetDuration(struct DevUnit
*unit
, UWORD length
, UWORD rate
,
2577 BOOL short_preamble
, struct DevBase
*base
)
2579 UWORD duration
, cycles
;
2583 duration
= 97 + (length
* 8 - 1) / rate
;
2584 if (!short_preamble
|| rate
== 1)
2590 duration
= ((length
+ 29) / cycles
+ 1) * 4 + 26;
2598 /****i* realtek8180.device/AckRate *****************************************
2601 * AckRate -- Get the ACK rate corresponding to a data rate.
2604 * ack_rate = AckRate(unit, data_rate)
2606 * UWORD AckRate(struct DevUnit *, UWORD);
2609 * Calculates the rate at which the ACK frame for a data frame with the
2610 * given rate should be transmitted.
2613 * unit - A unit of this device.
2614 * rate - Rate data frame is transmitted at (in Mbps, rounded down).
2617 * ack_rate - The rate for the ACK frame (Mbps, rounded down).
2619 ****************************************************************************
2623 static UWORD
AckRate(struct DevUnit
*unit
, UWORD data_rate
,
2624 struct DevBase
*base
)
2659 /****i* realtek8180.device/UnitTask ****************************************
2670 * Completes deferred requests, and handles card insertion and removal
2671 * in conjunction with the relevant interrupts.
2673 ****************************************************************************
2681 static VOID
UnitTask(struct ExecBase
*sys_base
)
2684 struct IORequest
*request
;
2685 struct DevUnit
*unit
;
2686 struct DevBase
*base
;
2687 struct MsgPort
*general_port
;
2688 ULONG signals
= 0, wait_signals
, card_removed_signal
,
2689 card_inserted_signal
, general_port_signal
;
2691 /* Get parameters */
2693 task
= AbsExecBase
->ThisTask
;
2694 unit
= task
->tc_UserData
;
2695 base
= unit
->device
;
2697 /* Activate general request port */
2699 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
2700 general_port
->mp_SigTask
= task
;
2701 general_port
->mp_SigBit
= AllocSignal(-1);
2702 general_port_signal
= 1 << general_port
->mp_SigBit
;
2703 general_port
->mp_Flags
= PA_SIGNAL
;
2705 /* Allocate signals for notification of card removal and insertion */
2707 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
2708 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
2709 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
2710 | card_inserted_signal
| SIGBREAKF_CTRL_C
;
2712 /* Tell ourselves to check port for old messages */
2714 Signal(task
, general_port_signal
);
2716 /* Infinite loop to service requests and signals */
2720 signals
= Wait(wait_signals
);
2722 if((signals
& card_inserted_signal
) != 0)
2724 if(unit
->insertion_function(unit
->card
, base
))
2726 unit
->flags
|= UNITF_HAVEADAPTER
;
2727 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
2728 ConfigureAdapter(unit
, base
);
2729 if((unit
->flags
& UNITF_WASONLINE
) != 0)
2731 GoOnline(unit
, base
);
2732 unit
->flags
&= ~UNITF_WASONLINE
;
2737 if((signals
& card_removed_signal
) != 0)
2739 unit
->removal_function(unit
->card
, base
);
2740 if((unit
->flags
& UNITF_WASONLINE
) != 0)
2741 GoOffline(unit
, base
);
2744 if((signals
& general_port_signal
) != 0)
2746 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
2748 /* Service the request as soon as the unit is free */
2750 ObtainSemaphore(&unit
->access_lock
);
2751 ServiceRequest((APTR
)request
, base
);