Report S2EVENT_CONNECT when a new SSID is selected.
[AROS.git] / workbench / devs / networks / atheros5000 / unit.c
blobac7c00a6216096f0daf60f1d6ad6ee86abfbca29
1 /*
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,
18 MA 02111-1307, USA.
23 #include <exec/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
27 #include <proto/exec.h>
28 #ifndef __amigaos4__
29 #include <proto/alib.h>
30 #else
31 #include <clib/alib_protos.h>
32 #endif
33 #include <proto/utility.h>
34 #include <proto/dos.h>
35 #include <proto/timer.h>
37 #include "device.h"
39 #include "unit_protos.h"
40 #include "request_protos.h"
41 #include "encryption_protos.h"
42 #include "hal/ah.h"
43 #include "hal/ah_desc.h"
46 #define TASK_PRIORITY 0
47 #define STACK_SIZE 4096
48 #define INT_MASK \
49 (HAL_INT_GLOBAL | HAL_INT_TX | HAL_INT_TXDESC | HAL_INT_RX \
50 | HAL_INT_RXEOL)
51 #define TX_POWER (20 << 1)
52 #define TX_TRIES 11
53 #define G_MGMT_RATE 2000
54 #define B_MGMT_RATE 1000
55 #define FRAME_BUFFER_SIZE (WIFI_FRM_DATA + SNAP_HEADERSIZE \
56 + 2 * ETH_MTU + EIV_SIZE + ICV_SIZE + MIC_SIZE + FCS_SIZE + 4)
57 #define MAX_CHANNEL_COUNT 100
59 #ifndef AbsExecBase
60 #define AbsExecBase sys_base
61 #endif
63 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
64 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
65 UWORD upper_bound_right, struct DevBase *base);
66 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base);
67 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
68 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
69 static UBYTE *GetRXBuffer(struct DevUnit *unit, const UBYTE *address,
70 UWORD frag_no, UWORD *buffer_no, struct DevBase *base);
71 static VOID DistributeRXPacket(struct DevUnit *unit, UBYTE *frame,
72 struct DevBase *base);
73 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
74 UWORD packet_size, UWORD packet_type, UBYTE *buffer,
75 struct DevBase *base);
76 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
77 struct DevBase *base);
78 static VOID DistributeMgmtFrame(struct DevUnit *unit, UBYTE *frame,
79 UWORD frame_size, struct DevBase *base);
80 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
81 static VOID TXEndInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
82 static VOID MgmtTXInt(REG(a1, struct DevUnit *unit),
83 REG(a6, APTR int_code));
84 static VOID MgmtTXEndInt(REG(a1, struct DevUnit *unit),
85 REG(a6, APTR int_code));
86 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
87 REG(a6, APTR int_code));
88 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
89 struct DevBase *base);
90 static VOID UnitTask(struct ExecBase *sys_base);
93 static const UBYTE snap_template[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
94 static const UBYTE broadcast_address[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
95 static const ULONG g_retry_rates[] = {54000, 36000, 18000, 2000};
96 static const ULONG b_retry_rates[] = {11000, 5500, 2000, 1000};
99 #ifdef __amigaos4__
100 #undef AddTask
101 #define AddTask(task, initial_pc, final_pc) \
102 IExec->AddTask(task, initial_pc, final_pc, NULL)
103 #endif
104 #ifdef __MORPHOS__
105 static const struct EmulLibEntry mos_task_trap =
107 TRAP_LIB,
109 (APTR)UnitTask
111 #define UnitTask &mos_task_trap
112 #endif
113 #ifdef __AROS__
114 #undef AddTask
115 #define AddTask(task, initial_pc, final_pc) \
116 ({ \
117 struct TagItem _task_tags[] = \
118 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
119 NewAddTask(task, initial_pc, final_pc, _task_tags); \
121 #endif
125 /****i* atheros5000.device/CreateUnit **************************************
127 * NAME
128 * CreateUnit -- Create a unit.
130 * SYNOPSIS
131 * unit = CreateUnit(index, io_base, id, card,
132 * io_tags, bus)
134 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
135 * struct TagItem *, UWORD);
137 * FUNCTION
138 * Creates a new unit.
140 ****************************************************************************
144 struct DevUnit *CreateUnit(ULONG index, APTR io_base, UWORD id, APTR card,
145 const struct TagItem *io_tags, UWORD bus, struct DevBase *base)
147 BOOL success = TRUE;
148 struct DevUnit *unit;
149 struct Task *task;
150 struct MsgPort *port;
151 UWORD i;
152 struct ath_desc *tx_desc, *rx_desc;
153 ULONG dma_size;
154 APTR stack;
155 HAL_STATUS hal_status;
157 unit = AllocMem(sizeof(struct DevUnit), MEMF_CLEAR | MEMF_PUBLIC);
158 if(unit == NULL)
159 success = FALSE;
161 if(success)
163 /* Initialise lists etc. */
165 NewList((APTR)&unit->openers);
166 NewList((APTR)&unit->type_trackers);
167 NewList((APTR)&unit->multicast_ranges);
169 unit->index = index;
170 unit->device = base;
171 unit->card = card;
172 unit->bus = bus;
174 /* Store DMA memory hooks */
176 unit->AllocDMAMem =
177 (APTR)GetTagData(IOTAG_AllocDMAMem, (UPINT)NULL, io_tags);
178 unit->FreeDMAMem =
179 (APTR)GetTagData(IOTAG_FreeDMAMem, (UPINT)NULL, io_tags);
180 if(unit->AllocDMAMem == NULL || unit->FreeDMAMem == NULL)
181 success = FALSE;
184 if(success)
186 /* Initialise HAL */
188 unit->hal = ath_hal_attach(id, unit, NULL, io_base, &hal_status);
190 if(unit->hal == NULL)
191 success = FALSE;
194 if(success)
196 InitSemaphore(&unit->access_lock);
198 /* Create the message ports for queuing requests */
200 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
202 unit->request_ports[i] = port = AllocMem(sizeof(struct MsgPort),
203 MEMF_PUBLIC | MEMF_CLEAR);
204 if(port == NULL)
205 success = FALSE;
207 if(success)
209 NewList(&port->mp_MsgList);
210 port->mp_Flags = PA_IGNORE;
214 if(success)
216 unit->request_ports[WRITE_QUEUE]->mp_SigTask = &unit->tx_int;
217 unit->request_ports[MGMT_QUEUE]->mp_SigTask = &unit->mgmt_int;
220 /* Allocate buffers and descriptors */
222 unit->tx_buffer = AllocVec(ETH_MAXPACKETSIZE, MEMF_PUBLIC);
223 for(i = 0; i < TX_SLOT_COUNT; i++)
225 unit->tx_buffers[i] =
226 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
227 if(unit->tx_buffers[i] == NULL)
228 success = FALSE;
230 for(i = 0; i < MGMT_SLOT_COUNT; i++)
232 unit->mgmt_buffers[i] =
233 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
234 if(unit->mgmt_buffers[i] == NULL)
235 success = FALSE;
237 unit->rx_buffer = AllocVec(FRAME_BUFFER_SIZE, MEMF_PUBLIC);
238 for(i = 0; i < RX_SLOT_COUNT; i++)
240 unit->rx_buffers[i] =
241 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
242 if(unit->rx_buffers[i] == NULL)
243 success = FALSE;
245 unit->rx_frames =
246 AllocVec(FRAME_BUFFER_SIZE * FRAME_BUFFER_COUNT, MEMF_PUBLIC);
247 for(i = 0; i < FRAME_BUFFER_COUNT; i++)
248 unit->rx_fragment_nos[i] = -1;
249 unit->tx_descs = unit->AllocDMAMem(unit->card,
250 sizeof(struct ath_desc) * TX_SLOT_COUNT, 4);
251 unit->mgmt_descs = unit->AllocDMAMem(unit->card,
252 sizeof(struct ath_desc) * MGMT_SLOT_COUNT, 4);
253 unit->rx_descs = unit->AllocDMAMem(unit->card,
254 sizeof(struct ath_desc) * RX_SLOT_COUNT, 4);
255 unit->tx_requests = AllocVec(sizeof(APTR) * TX_SLOT_COUNT,
256 MEMF_PUBLIC);
257 unit->mgmt_requests = AllocVec(sizeof(APTR) * MGMT_SLOT_COUNT,
258 MEMF_PUBLIC);
259 unit->channels = AllocVec(sizeof(HAL_CHANNEL) * MAX_CHANNEL_COUNT,
260 MEMF_PUBLIC | MEMF_CLEAR);
261 if(unit->tx_buffer == NULL
262 || unit->rx_buffer == NULL
263 || unit->rx_frames == NULL
264 || unit->tx_descs == NULL
265 || unit->mgmt_descs == NULL
266 || unit->rx_descs == NULL
267 || unit->tx_requests == NULL
268 || unit->mgmt_requests == NULL
269 || unit->channels == NULL)
270 success = FALSE;
273 if(success)
275 /* Initialise network adapter hardware */
277 success = InitialiseAdapter(unit, FALSE, base);
278 unit->flags |= UNITF_HAVEADAPTER;
281 if(success)
283 /* Get physical addresses of DMA structures */
285 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
286 unit->tx_descs_p =
287 (ULONG)(UPINT)CachePreDMA(unit->tx_descs, &dma_size, 0);
288 if(dma_size != sizeof(struct ath_desc) * TX_SLOT_COUNT)
289 success = FALSE;
290 CachePostDMA(unit->tx_descs, &dma_size, 0);
292 for(i = 0; i < TX_SLOT_COUNT; i++)
294 dma_size = FRAME_BUFFER_SIZE;
295 unit->tx_buffers_p[i] =
296 (ULONG)(UPINT)CachePreDMA(unit->tx_buffers[i], &dma_size, 0);
297 if(dma_size != FRAME_BUFFER_SIZE)
298 success = FALSE;
299 CachePostDMA(unit->tx_buffers[i], &dma_size, 0);
302 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
303 unit->mgmt_descs_p =
304 (ULONG)(UPINT)CachePreDMA(unit->mgmt_descs, &dma_size, 0);
305 if(dma_size != sizeof(struct ath_desc) * MGMT_SLOT_COUNT)
306 success = FALSE;
307 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
309 for(i = 0; i < MGMT_SLOT_COUNT; i++)
311 dma_size = FRAME_BUFFER_SIZE;
312 unit->mgmt_buffers_p[i] =
313 (ULONG)(UPINT)CachePreDMA(unit->mgmt_buffers[i], &dma_size, 0);
314 if(dma_size != FRAME_BUFFER_SIZE)
315 success = FALSE;
316 CachePostDMA(unit->mgmt_buffers[i], &dma_size, 0);
319 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
320 unit->rx_descs_p =
321 (ULONG)(UPINT)CachePreDMA(unit->rx_descs, &dma_size, 0);
322 if(dma_size != sizeof(struct ath_desc) * RX_SLOT_COUNT)
323 success = FALSE;
324 CachePostDMA(unit->rx_descs, &dma_size, 0);
326 for(i = 0; i < RX_SLOT_COUNT; i++)
328 dma_size = FRAME_BUFFER_SIZE;
329 unit->rx_buffers_p[i] =
330 (ULONG)(UPINT)CachePreDMA(unit->rx_buffers[i], &dma_size, 0);
331 if(dma_size != FRAME_BUFFER_SIZE)
332 success = FALSE;
333 CachePostDMA(unit->rx_buffers[i], &dma_size, 0);
336 /* Construct TX ring */
338 for(tx_desc = unit->tx_descs, i = 0; i < TX_SLOT_COUNT; i++)
340 tx_desc->ds_data = unit->tx_buffers_p[i];
341 tx_desc++;
344 /* Construct management frame TX ring */
346 for(tx_desc = unit->mgmt_descs, i = 0; i < MGMT_SLOT_COUNT; i++)
348 tx_desc->ds_data = unit->mgmt_buffers_p[i];
349 tx_desc++;
352 /* Construct RX ring */
354 for(rx_desc = unit->rx_descs, i = 0; i < RX_SLOT_COUNT; i++)
356 rx_desc->ds_link = unit->rx_descs_p + ((i + 1) % RX_SLOT_COUNT)
357 * sizeof(struct ath_desc);
358 rx_desc->ds_data = unit->rx_buffers_p[i];
359 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
360 HAL_RXDESC_INTREQ);
361 rx_desc++;
364 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
365 CachePreDMA(unit->rx_descs, &dma_size, 0);
367 /* Record maximum speed in BPS */
369 unit->speed = 54000000;
371 /* Initialise status, transmit, receive and stats interrupts */
373 unit->status_int.is_Node.ln_Name =
374 base->device.dd_Library.lib_Node.ln_Name;
375 unit->status_int.is_Code = (APTR)StatusInt;
376 unit->status_int.is_Data = unit;
378 unit->rx_int.is_Node.ln_Name =
379 base->device.dd_Library.lib_Node.ln_Name;
380 unit->rx_int.is_Code = (APTR)RXInt;
381 unit->rx_int.is_Data = unit;
383 unit->tx_int.is_Node.ln_Name =
384 base->device.dd_Library.lib_Node.ln_Name;
385 unit->tx_int.is_Code = (APTR)TXInt;
386 unit->tx_int.is_Data = unit;
388 unit->tx_end_int.is_Node.ln_Name =
389 base->device.dd_Library.lib_Node.ln_Name;
390 unit->tx_end_int.is_Code = (APTR)TXEndInt;
391 unit->tx_end_int.is_Data = unit;
393 unit->mgmt_int.is_Node.ln_Name =
394 base->device.dd_Library.lib_Node.ln_Name;
395 unit->mgmt_int.is_Code = (APTR)MgmtTXInt;
396 unit->mgmt_int.is_Data = unit;
398 unit->mgmt_end_int.is_Node.ln_Name =
399 base->device.dd_Library.lib_Node.ln_Name;
400 unit->mgmt_end_int.is_Code = (APTR)MgmtTXEndInt;
401 unit->mgmt_end_int.is_Data = unit;
403 unit->reset_handler.is_Node.ln_Name =
404 base->device.dd_Library.lib_Node.ln_Name;
405 unit->reset_handler.is_Code = (APTR)ResetHandler;
406 unit->reset_handler.is_Data = unit;
408 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
409 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
411 /* Create a new task */
413 unit->task = task =
414 AllocMem(sizeof(struct Task), MEMF_PUBLIC | MEMF_CLEAR);
415 if(task == NULL)
416 success = FALSE;
419 if(success)
421 stack = AllocMem(STACK_SIZE, MEMF_PUBLIC);
422 if(stack == NULL)
423 success = FALSE;
426 if(success)
428 /* Initialise and start task */
430 task->tc_Node.ln_Type = NT_TASK;
431 task->tc_Node.ln_Pri = TASK_PRIORITY;
432 task->tc_Node.ln_Name = base->device.dd_Library.lib_Node.ln_Name;
433 task->tc_SPUpper = stack + STACK_SIZE;
434 task->tc_SPLower = stack;
435 task->tc_SPReg = stack + STACK_SIZE;
436 NewList(&task->tc_MemEntry);
438 if(AddTask(task, UnitTask, NULL) == NULL)
439 success = FALSE;
442 if(success)
444 /* Send the unit to the new task */
446 task->tc_UserData = unit;
448 /* Set default wireless options */
450 unit->mode = S2PORT_MANAGED;
453 if(!success)
455 DeleteUnit(unit, base);
456 unit = NULL;
459 return unit;
464 /****i* atheros5000.device/DeleteUnit **************************************
466 * NAME
467 * DeleteUnit -- Delete a unit.
469 * SYNOPSIS
470 * DeleteUnit(unit)
472 * VOID DeleteUnit(struct DevUnit *);
474 * FUNCTION
475 * Deletes a unit.
477 * INPUTS
478 * unit - Device unit (may be NULL).
480 * RESULT
481 * None.
483 ****************************************************************************
487 VOID DeleteUnit(struct DevUnit *unit, struct DevBase *base)
489 UBYTE i;
490 struct Task *task;
492 if(unit != NULL)
494 task = unit->task;
495 if(task != NULL)
497 if(task->tc_UserData != NULL)
499 RemTask(task);
500 FreeMem(task->tc_SPLower, STACK_SIZE);
501 Signal(unit->task, SIGBREAKF_CTRL_C);
503 FreeMem(task, sizeof(struct Task));
506 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
508 if(unit->request_ports[i] != NULL)
509 FreeMem(unit->request_ports[i], sizeof(struct MsgPort));
512 if((unit->flags & UNITF_ONLINE) != 0) /* Needed! */
513 GoOffline(unit, base);
515 for(i = 0; i < TX_SLOT_COUNT; i++)
516 unit->FreeDMAMem(unit->card, unit->tx_buffers[i]);
517 for(i = 0; i < MGMT_SLOT_COUNT; i++)
518 unit->FreeDMAMem(unit->card, unit->mgmt_buffers[i]);
519 for(i = 0; i < RX_SLOT_COUNT; i++)
520 unit->FreeDMAMem(unit->card, unit->rx_buffers[i]);
522 FreeVec(unit->tx_buffer);
523 FreeVec(unit->rx_frames);
524 FreeVec(unit->tx_requests);
525 FreeVec(unit->mgmt_requests);
526 FreeVec(unit->channels);
527 FreeVec(unit->rx_buffer);
529 if(unit->hal != NULL)
530 unit->hal->ah_detach(unit->hal);
532 FreeMem(unit, sizeof(struct DevUnit));
535 return;
540 /****i* atheros5000.device/InitialiseAdapter *******************************
542 * NAME
543 * InitialiseAdapter
545 * SYNOPSIS
546 * success = InitialiseAdapter(unit, reinsertion)
548 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
550 * FUNCTION
552 * INPUTS
553 * unit
554 * reinsertion
556 * RESULT
557 * success - Success indicator.
559 ****************************************************************************
563 BOOL InitialiseAdapter(struct DevUnit *unit, BOOL reinsertion,
564 struct DevBase *base)
566 UBYTE i, reg_class_id;
567 BOOL success = TRUE;
568 unsigned int channel_count, reg_class_count;
569 HAL_TXQ_INFO queue_info = {0};
571 /* Get default MAC address */
573 unit->hal->ah_getMacAddress(unit->hal, unit->default_address);
575 /* Get default antenna */
577 unit->antenna = unit->hal->ah_getDefAntenna(unit->hal);
579 /* Reset key cache */
581 for(i = 0; i < WIFI_KEYCOUNT; i++)
582 unit->hal->ah_resetKeyCacheEntry(unit->hal, i);
584 /* Initialise channels and rates */
586 ath_hal_init_channels(unit->hal, unit->channels,
587 MAX_CHANNEL_COUNT, &channel_count,
588 &reg_class_id, 1, &reg_class_count, CTRY_DEFAULT,
589 HAL_MODE_11B | HAL_MODE_PUREG, TRUE,
590 FALSE);
591 unit->channel_count = channel_count;
593 unit->channel = 1;
594 unit->band = S2BAND_B;
596 /* Check if multi-rate retries are supported */
598 if(unit->hal->ah_setupXTxDesc(unit->hal, NULL, 0, 0, 0, 0, 0, 0))
599 unit->flags |= UNITF_SLOWRETRIES;
601 /* Set up TX queue */
603 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
604 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
605 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
606 queue_info.tqi_qflags =
607 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
609 unit->tx_queue_no =
610 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
611 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
613 /* Set up management frame TX queue */
615 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
616 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
617 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
618 queue_info.tqi_qflags =
619 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
621 unit->mgmt_queue_no =
622 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
623 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
625 /* Find out hardware encryption capabilities */
627 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
628 HAL_CIPHER_WEP, NULL) == HAL_OK)
629 unit->flags |= UNITF_HARDWEP;
630 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
631 HAL_CIPHER_TKIP, NULL) == HAL_OK)
632 unit->flags |= UNITF_HARDTKIP;
633 #if 1
634 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
635 HAL_CIPHER_MIC, NULL) == HAL_OK)
637 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
638 // 0, TRUE, NULL))
639 0, 0, NULL))
640 unit->flags |= UNITF_HARDMIC;
642 #else
643 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
644 0, FALSE, NULL))
645 #endif
646 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_TKIP_SPLIT, 0,
647 NULL) == HAL_OK)
648 unit->flags |= UNITF_SPLITMIC;
649 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
650 HAL_CIPHER_AES_OCB, NULL) == HAL_OK)
651 unit->flags |= UNITF_HARDAESOCB;
652 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
653 HAL_CIPHER_AES_CCM, NULL) == HAL_OK)
654 unit->flags |= UNITF_HARDCCMP;
656 /* Set IV sizes */
658 unit->iv_sizes[S2ENC_WEP] = IV_SIZE;
659 unit->iv_sizes[S2ENC_TKIP] = EIV_SIZE;
660 unit->iv_sizes[S2ENC_CCMP] = EIV_SIZE;
662 /* Set encryption functions */
664 unit->fragment_encrypt_functions[S2ENC_NONE] = WriteClearFragment;
666 if((unit->flags & UNITF_HARDWEP) != 0)
667 unit->fragment_encrypt_functions[S2ENC_WEP] = WriteWEPFragment;
668 else
669 unit->fragment_encrypt_functions[S2ENC_WEP] = EncryptWEPFragment;
671 if((unit->flags & UNITF_HARDTKIP) != 0)
672 unit->fragment_encrypt_functions[S2ENC_TKIP] = WriteTKIPFragment;
673 else
674 unit->fragment_encrypt_functions[S2ENC_TKIP] = EncryptTKIPFragment;
676 if((unit->flags & UNITF_HARDCCMP) != 0)
677 unit->fragment_encrypt_functions[S2ENC_CCMP] = WriteCCMPFragment;
678 else
679 unit->fragment_encrypt_functions[S2ENC_CCMP] = EncryptCCMPFragment;
681 /* Set decryption functions */
683 unit->fragment_decrypt_functions[S2ENC_NONE] = ReadClearFragment;
685 if((unit->flags & UNITF_HARDWEP) != 0)
686 unit->fragment_decrypt_functions[S2ENC_WEP] = ReadWEPFragment;
687 else
688 unit->fragment_decrypt_functions[S2ENC_WEP] = DecryptWEPFragment;
690 if((unit->flags & UNITF_HARDTKIP) != 0)
691 unit->fragment_decrypt_functions[S2ENC_TKIP] = ReadTKIPFragment;
692 else
693 unit->fragment_decrypt_functions[S2ENC_TKIP] = DecryptTKIPFragment;
695 if((unit->flags & UNITF_HARDCCMP) != 0)
696 unit->fragment_decrypt_functions[S2ENC_CCMP] = ReadCCMPFragment;
697 else
698 unit->fragment_decrypt_functions[S2ENC_CCMP] = DecryptCCMPFragment;
700 /* Return */
702 return success;
707 /****i* atheros5000.device/ConfigureAdapter ********************************
709 * NAME
710 * ConfigureAdapter -- Set up card for transmission/reception.
712 * SYNOPSIS
713 * ConfigureAdapter(unit)
715 * VOID ConfigureAdapter(struct DevUnit *);
717 ****************************************************************************
721 VOID ConfigureAdapter(struct DevUnit *unit, struct DevBase *base)
723 UWORD i, j, key_length, hal_band, key_type;
724 const struct KeyUnion *keys;
725 HAL_CHANNEL *channel = unit->channels, *ch;
726 ULONG freq = 2407 + unit->channel * 5;
727 HAL_STATUS status;
728 HAL_KEYVAL hal_key;
729 HAL_BOOL iq_done;
730 const HAL_RATE_TABLE *rate_table;
732 /* Get band-specific parameters */
734 if(unit->band == S2BAND_G)
736 hal_band = HAL_MODE_11G;
737 unit->band_mask = CHANNEL_G;
738 unit->tx_rates = g_retry_rates;
739 unit->mgmt_rate = G_MGMT_RATE;
741 else if(unit->band == S2BAND_B)
743 hal_band = HAL_MODE_11B;
744 unit->band_mask = CHANNEL_B;
745 unit->tx_rates = b_retry_rates;
746 unit->mgmt_rate = B_MGMT_RATE;
748 unit->rate_table = unit->hal->ah_getRateTable(unit->hal, hal_band);
750 /* Find rate codes to match our optimal and retry rates */
752 rate_table = unit->rate_table;
753 for(i = 0; i < rate_table->rateCount; i++)
755 for(j = 0; j < 4; j++)
757 if(rate_table->info[i].rateKbps == unit->tx_rates[j])
759 unit->tx_rate_codes[j] = rate_table->info[i].rateCode;
760 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
761 unit->tx_rate_codes[j] |= rate_table->info[i].shortPreamble;
764 if(rate_table->info[i].rateKbps == unit->mgmt_rate)
766 unit->mgmt_rate_code = rate_table->info[i].rateCode;
767 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
768 unit->mgmt_rate_code |= rate_table->info[i].shortPreamble;
772 /* Find a channel that matches requirements */
774 for(i = 0, ch = unit->channels; i < unit->channel_count; i++, ch++)
776 if(ch->channel == freq
777 && (ch->channelFlags & unit->band_mask) == unit->band_mask)
778 channel = ch;
781 /* Stop the transceiver if we're already online */
783 if((unit->flags & UNITF_ONLINE) != 0)
785 /* Disable frame transmission */
787 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
788 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
789 unit->hal->ah_setRxFilter(unit->hal, 0);
790 ath_hal_delay(3000);
792 /* Disable frame reception */
794 unit->hal->ah_stopPcuReceive(unit->hal);
795 unit->hal->ah_stopDmaReceive(unit->hal);
797 /* Disable interrupts */
799 unit->hal->ah_setInterrupts(unit->hal, 0);
802 /* Calculate RX filter mask */
804 unit->filter_mask = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_MCAST
805 | HAL_RX_FILTER_BCAST;
806 if((unit->flags & UNITF_PROM) != 0)
807 unit->filter_mask |= HAL_RX_FILTER_PROM;
808 if(unit->mode != S2PORT_MANAGED)
809 unit->filter_mask |= HAL_RX_FILTER_PROBEREQ;
811 /* Reset card */
813 unit->hal->ah_reset(unit->hal, HAL_M_STA, channel, FALSE, &status);
815 /* Set MAC address and miscellaneous wireless parameters */
817 unit->hal->ah_setMacAddress(unit->hal, unit->address);
818 unit->hal->ah_setPCUConfig(unit->hal);
819 SetMulticast(unit, base);
820 unit->hal->ah_setDefAntenna(unit->hal, unit->antenna);
821 unit->hal->ah_perCalibration(unit->hal, channel, &iq_done);
822 unit->hal->ah_setTxPowerLimit(unit->hal, TX_POWER);
824 /* Set association ID */
826 unit->hal->ah_writeAssocid(unit->hal, unit->bssid, unit->assoc_id);
828 /* Put on a reassuring light */
830 unit->hal->ah_setLedState(unit->hal, HAL_LED_RUN);
832 /* Set or clear default encryption keys where appropriate */
834 keys = unit->keys;
835 for(i = 0; i < WIFI_KEYCOUNT; i++)
837 key_type = unit->keys[i].type;
838 if(key_type <= S2ENC_WEP
839 || key_type == S2ENC_TKIP && (unit->flags & UNITF_HARDTKIP) == 0
840 || key_type == S2ENC_CCMP && (unit->flags & UNITF_HARDCCMP) == 0)
842 if(key_type == S2ENC_WEP && (unit->flags & UNITF_HARDWEP) != 0)
844 hal_key.kv_type = HAL_CIPHER_WEP;
845 key_length = keys[i].u.wep.length;
846 CopyMem(keys[i].u.wep.key, hal_key.kv_val, key_length);
848 else
850 hal_key.kv_type = HAL_CIPHER_CLR;
851 key_length = 0;
853 hal_key.kv_len = key_length;
854 unit->hal->ah_setKeyCacheEntry(unit->hal, i, &hal_key,
855 unit->bssid, FALSE);
859 /* Set pointer to RX ring */
861 unit->hal->ah_setRxDP(unit->hal,
862 unit->rx_descs_p + unit->rx_slot * sizeof(struct ath_desc));
864 /* Restart the transceiver if we're already online */
866 if((unit->flags & UNITF_ONLINE) != 0)
868 /* Enable interrupts */
870 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
872 /* Enable frame reception */
874 unit->hal->ah_enableReceive(unit->hal);
875 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
876 unit->hal->ah_startPcuReceive(unit->hal);
878 #if 0
879 /* Reset TX queues */
881 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
882 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
883 #endif
886 /* Return */
888 return;
893 /****i* atheros5000.device/GoOnline ****************************************
895 * NAME
896 * GoOnline -- Enable transmission/reception.
898 * SYNOPSIS
899 * GoOnline(unit)
901 * VOID GoOnline(struct DevUnit *);
903 ****************************************************************************
907 VOID GoOnline(struct DevUnit *unit, struct DevBase *base)
909 /* Enable interrupts */
911 unit->flags |= UNITF_ONLINE;
912 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
914 /* Enable frame reception */
916 unit->hal->ah_enableReceive(unit->hal);
917 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
918 unit->hal->ah_startPcuReceive(unit->hal);
920 #if 0
921 /* Reset TX queues */
923 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
924 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
925 #endif
927 /* Record start time and report Online event */
929 GetSysTime(&unit->stats.LastStart);
930 ReportEvents(unit, S2EVENT_ONLINE, base);
932 return;
937 /****i* atheros5000.device/GoOffline ***************************************
939 * NAME
940 * GoOffline -- Disable transmission/reception.
942 * SYNOPSIS
943 * GoOffline(unit)
945 * VOID GoOffline(struct DevUnit *);
947 * FUNCTION
949 * INPUTS
950 * unit
952 * RESULT
953 * None.
955 ****************************************************************************
959 VOID GoOffline(struct DevUnit *unit, struct DevBase *base)
961 unit->flags &= ~UNITF_ONLINE;
962 if((unit->flags & UNITF_HAVEADAPTER) != 0)
964 /* Disable frame transmission */
966 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
967 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
969 /* Disable frame reception */
971 unit->hal->ah_stopPcuReceive(unit->hal);
972 unit->hal->ah_stopDmaReceive(unit->hal);
973 unit->hal->ah_setRxFilter(unit->hal, 0);
974 ath_hal_delay(3000);
976 /* Stop interrupts */
978 unit->hal->ah_setInterrupts(unit->hal, 0);
980 /* Update statistics */
982 UpdateStats(unit, base);
985 /* Flush pending read and write requests */
987 FlushUnit(unit, MGMT_QUEUE, S2ERR_OUTOFSERVICE, base);
989 /* Report Offline event and return */
991 ReportEvents(unit, S2EVENT_OFFLINE, base);
992 return;
997 /****i* atheros5000.device/SetOptions **************************************
999 * NAME
1000 * SetOptions -- Set and use interface options.
1002 * SYNOPSIS
1003 * reconfigure = SetOptions(unit, tag_list)
1005 * BOOL SetOptions(struct DevUnit *, struct TagItem *);
1007 ****************************************************************************
1011 BOOL SetOptions(struct DevUnit *unit, const struct TagItem *tag_list,
1012 struct DevBase *base)
1014 struct TagItem *tag_item, *tlist = (struct TagItem *)tag_list;
1015 BOOL reconfigure = TRUE;
1017 while((tag_item = NextTagItem(&tlist)) != NULL)
1019 switch(tag_item->ti_Tag)
1021 case S2INFO_SSID:
1022 ReportEvents(unit, S2EVENT_CONNECT, base);
1023 break;
1025 case S2INFO_BSSID:
1026 CopyMem((APTR)tag_item->ti_Data, unit->bssid, ETH_ADDRESSSIZE);
1027 break;
1029 case S2INFO_AssocID:
1030 unit->assoc_id = tag_item->ti_Data;
1031 break;
1033 case S2INFO_Capabilities:
1034 unit->capabilities = tag_item->ti_Data;
1035 if((unit->capabilities & (1 << 5)) != 0)
1036 unit->flags |= UNITF_SHORTPREAMBLE;
1037 else
1038 unit->flags &= ~UNITF_SHORTPREAMBLE;
1039 break;
1041 case S2INFO_DefaultKeyNo:
1042 unit->tx_key_no = tag_item->ti_Data;
1043 break;
1045 case S2INFO_PortType:
1046 unit->mode = tag_item->ti_Data;
1047 break;
1049 case S2INFO_Channel:
1050 if(tag_item->ti_Data != unit->channel)
1052 unit->channel = tag_item->ti_Data;
1053 reconfigure = TRUE;
1055 break;
1057 case S2INFO_Band:
1058 if(tag_item->ti_Data != unit->band)
1060 unit->band = tag_item->ti_Data;
1061 reconfigure = TRUE;
1063 break;
1067 return reconfigure;
1072 /****i* atheros5000.device/SetKey ******************************************
1074 * NAME
1075 * SetKey -- Set an encryption key.
1077 * SYNOPSIS
1078 * SetKey(unit, index, type, key, key_length,
1079 * rx_counter)
1081 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1082 * UBYTE *);
1084 ****************************************************************************
1088 VOID SetKey(struct DevUnit *unit, ULONG index, ULONG type, const UBYTE *key,
1089 ULONG key_length, const UBYTE *rx_counter, struct DevBase *base)
1091 struct KeyUnion *slot;
1092 struct EClockVal eclock;
1093 HAL_KEYVAL hal_key;
1094 UWORD i;
1096 Disable();
1097 slot = &unit->keys[index];
1098 switch(type)
1100 case S2ENC_WEP:
1101 CopyMem(key, slot->u.wep.key, key_length);
1102 slot->u.wep.length = key_length;
1104 if((unit->flags & UNITF_HARDWEP) == 0)
1106 /* Create a reasonably random IV */
1108 ReadEClock(&eclock);
1109 slot->u.wep.tx_iv = FastRand(eclock.ev_lo ^ eclock.ev_hi);
1112 break;
1114 case S2ENC_TKIP:
1115 CopyMem(key, slot->u.tkip.key, 16);
1116 CopyMem(key + 16, slot->u.tkip.tx_mic_key, MIC_SIZE);
1117 CopyMem(key + 24, slot->u.tkip.rx_mic_key, MIC_SIZE);
1118 slot->u.tkip.tx_iv_low = 0;
1119 slot->u.tkip.tx_iv_high = 0;
1120 slot->u.tkip.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1121 slot->u.tkip.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1122 slot->u.tkip.tx_ttak_set = FALSE;
1123 slot->u.tkip.rx_ttak_set = FALSE;
1125 if((unit->flags & UNITF_HARDTKIP) != 0)
1127 // TO DO: Wait for TX queue to empty
1128 /* Load parameters for hardware encryption */
1130 hal_key.kv_type = HAL_CIPHER_TKIP;
1131 hal_key.kv_len = 16;
1132 CopyMem(slot->u.tkip.key, hal_key.kv_val, 16);
1134 CopyMem(slot->u.tkip.tx_mic_key, hal_key.kv_mic, MIC_SIZE);
1135 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1136 unit->bssid, FALSE);
1137 CopyMem(slot->u.tkip.rx_mic_key, hal_key.kv_mic, MIC_SIZE);
1138 unit->hal->ah_setKeyCacheEntry(unit->hal, index + 32, &hal_key,
1139 unit->bssid, FALSE);
1141 else
1143 /* Convert key to native endianness */
1145 for(i = 0; i < 8; i++)
1146 slot->u.tkip.key[i] = LEWord(slot->u.tkip.key[i]);
1149 break;
1151 case S2ENC_CCMP:
1152 CopyMem(key, slot->u.ccmp.key, 16);
1153 slot->u.ccmp.tx_iv_low = 0;
1154 slot->u.ccmp.tx_iv_high = 0;
1155 slot->u.ccmp.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1156 slot->u.ccmp.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1157 slot->u.ccmp.stream_set = FALSE;
1159 if((unit->flags & UNITF_HARDCCMP) != 0)
1161 // TO DO: Wait for TX queue to empty
1162 /* Load parameters for hardware encryption */
1164 hal_key.kv_type = HAL_CIPHER_AES_CCM;
1165 hal_key.kv_len = 16;
1166 CopyMem(slot->u.ccmp.key, hal_key.kv_val, 16);
1167 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1168 unit->bssid, FALSE);
1172 /* Update type of key in selected slot */
1174 slot->type = type;
1175 Enable();
1177 return;
1182 /****i* atheros5000.device/AddMulticastRange *******************************
1184 * NAME
1185 * AddMulticastRange
1187 * SYNOPSIS
1188 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1190 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1192 ****************************************************************************
1196 BOOL AddMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1197 const UBYTE *upper_bound, struct DevBase *base)
1199 struct AddressRange *range;
1200 ULONG lower_bound_left, upper_bound_left;
1201 UWORD lower_bound_right, upper_bound_right;
1203 lower_bound_left = BELong(*((ULONG *)lower_bound));
1204 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1205 upper_bound_left = BELong(*((ULONG *)upper_bound));
1206 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1208 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1209 upper_bound_left, upper_bound_right, base);
1211 if(range != NULL)
1212 range->add_count++;
1213 else
1215 range = AllocMem(sizeof(struct AddressRange), MEMF_PUBLIC);
1216 if(range != NULL)
1218 range->lower_bound_left = lower_bound_left;
1219 range->lower_bound_right = lower_bound_right;
1220 range->upper_bound_left = upper_bound_left;
1221 range->upper_bound_right = upper_bound_right;
1222 range->add_count = 1;
1224 Disable();
1225 AddTail((APTR)&unit->multicast_ranges, (APTR)range);
1226 unit->range_count++;
1227 SetMulticast(unit, base);
1228 Enable();
1232 return range != NULL;
1237 /****i* atheros5000.device/RemMulticastRange *******************************
1239 * NAME
1240 * RemMulticastRange
1242 * SYNOPSIS
1243 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1245 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1247 ****************************************************************************
1251 BOOL RemMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1252 const UBYTE *upper_bound, struct DevBase *base)
1254 struct AddressRange *range;
1255 ULONG lower_bound_left, upper_bound_left;
1256 UWORD lower_bound_right, upper_bound_right;
1258 lower_bound_left = BELong(*((ULONG *)lower_bound));
1259 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1260 upper_bound_left = BELong(*((ULONG *)upper_bound));
1261 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1263 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1264 upper_bound_left, upper_bound_right, base);
1266 if(range != NULL)
1268 if(--range->add_count == 0)
1270 Disable();
1271 Remove((APTR)range);
1272 unit->range_count--;
1273 SetMulticast(unit, base);
1274 Enable();
1275 FreeMem(range, sizeof(struct AddressRange));
1279 return range != NULL;
1284 /****i* atheros5000.device/FindMulticastRange ******************************
1286 * NAME
1287 * FindMulticastRange
1289 * SYNOPSIS
1290 * range = FindMulticastRange(unit, lower_bound_left,
1291 * lower_bound_right, upper_bound_left, upper_bound_right)
1293 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1294 * UWORD, ULONG, UWORD);
1296 ****************************************************************************
1300 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
1301 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
1302 UWORD upper_bound_right, struct DevBase *base)
1304 struct AddressRange *range, *tail;
1305 BOOL found = FALSE;
1307 range = (APTR)unit->multicast_ranges.mlh_Head;
1308 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
1310 while(range != tail && !found)
1312 if(lower_bound_left == range->lower_bound_left &&
1313 lower_bound_right == range->lower_bound_right &&
1314 upper_bound_left == range->upper_bound_left &&
1315 upper_bound_right == range->upper_bound_right)
1316 found = TRUE;
1317 else
1318 range = (APTR)range->node.mln_Succ;
1321 if(!found)
1322 range = NULL;
1324 return range;
1329 /****i* atheros5000.device/SetMulticast ************************************
1331 * NAME
1332 * SetMulticast
1334 * SYNOPSIS
1335 * SetMulticast(unit)
1337 * VOID SetMulticast(struct DevUnit *);
1339 ****************************************************************************
1343 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base)
1345 unit->hal->ah_setMulticastFilter(unit->hal, 0xffffffff, 0xffffffff);
1347 return;
1352 /****i* atheros5000.device/FindTypeStats ***********************************
1354 * NAME
1355 * FindTypeStats
1357 * SYNOPSIS
1358 * stats = FindTypeStats(unit, list,
1359 * packet_type)
1361 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1362 * ULONG);
1364 ****************************************************************************
1368 struct TypeStats *FindTypeStats(struct DevUnit *unit, struct MinList *list,
1369 ULONG packet_type, struct DevBase *base)
1371 struct TypeStats *stats, *tail;
1372 BOOL found = FALSE;
1374 stats = (APTR)list->mlh_Head;
1375 tail = (APTR)&list->mlh_Tail;
1377 while(stats != tail && !found)
1379 if(stats->packet_type == packet_type)
1380 found = TRUE;
1381 else
1382 stats = (APTR)stats->node.mln_Succ;
1385 if(!found)
1386 stats = NULL;
1388 return stats;
1393 /****i* atheros5000.device/FlushUnit ***************************************
1395 * NAME
1396 * FlushUnit
1398 * SYNOPSIS
1399 * FlushUnit(unit, last_queue, error)
1401 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1403 ****************************************************************************
1407 VOID FlushUnit(struct DevUnit *unit, UBYTE last_queue, BYTE error,
1408 struct DevBase *base)
1410 struct IORequest *request;
1411 UBYTE i;
1412 struct Opener *opener, *tail;
1414 /* Abort queued requests */
1416 for(i = 0; i <= last_queue; i++)
1418 while((request = (APTR)GetMsg(unit->request_ports[i])) != NULL)
1420 request->io_Error = IOERR_ABORTED;
1421 ReplyMsg((APTR)request);
1425 #if 1
1426 opener = (APTR)unit->openers.mlh_Head;
1427 tail = (APTR)&unit->openers.mlh_Tail;
1429 /* Flush every opener's read queues */
1431 while(opener != tail)
1433 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1435 request->io_Error = error;
1436 ReplyMsg((APTR)request);
1438 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1440 request->io_Error = error;
1441 ReplyMsg((APTR)request);
1443 opener = (APTR)opener->node.mln_Succ;
1446 #else
1447 opener = request->ios2_BufferManagement;
1448 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1450 request->io_Error = IOERR_ABORTED;
1451 ReplyMsg((APTR)request);
1453 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1455 request->io_Error = IOERR_ABORTED;
1456 ReplyMsg((APTR)request);
1458 #endif
1460 /* Return */
1462 return;
1467 /****i* atheros5000.device/StatusInt ***************************************
1469 * NAME
1470 * StatusInt
1472 * SYNOPSIS
1473 * finished = StatusInt(unit)
1475 * BOOL StatusInt(struct DevUnit *);
1477 * FUNCTION
1479 * INPUTS
1480 * unit
1482 * RESULT
1483 * finished
1485 ****************************************************************************
1487 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1488 * Since we don't use this parameter, we can lie.
1492 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1494 struct DevBase *base;
1495 uint32_t queue_mask;
1496 HAL_INT ints, int_mask;
1498 base = unit->device;
1499 int_mask = unit->hal->ah_getInterrupts(unit->hal);
1501 if(!unit->hal->ah_isInterruptPending(unit->hal)) return FALSE;
1503 /* Handle ints */
1505 if(unit->hal->ah_getPendingInterrupts(unit->hal, &ints))
1507 if((ints & HAL_INT_TX) != 0)
1509 int_mask &= ~(HAL_INT_TX | HAL_INT_TXDESC);
1510 queue_mask = 1 << unit->tx_queue_no | 1 << unit->mgmt_queue_no;
1511 unit->hal->ah_getTxIntrQueue(unit->hal, &queue_mask);
1512 if((queue_mask & 1 << unit->tx_queue_no) != 0)
1513 Cause(&unit->tx_end_int);
1514 if((queue_mask & 1 << unit->mgmt_queue_no) != 0)
1515 Cause(&unit->mgmt_end_int);
1517 if((ints & HAL_INT_RX) != 0)
1519 int_mask &= ~(HAL_INT_RX | HAL_INT_RXEOL);
1520 Cause(&unit->rx_int);
1524 #ifdef __MORPHOS__
1525 int_mask = INT_MASK;
1526 #endif
1527 // unit->hal->ah_setInterrupts(unit->hal, int_mask))
1529 return FALSE;
1534 /****i* atheros5000.device/RXInt *******************************************
1536 * NAME
1537 * RXInt -- Soft interrupt for packet reception.
1539 * SYNOPSIS
1540 * RXInt(unit)
1542 * VOID RXInt(struct DevUnit *);
1544 * FUNCTION
1546 * INPUTS
1547 * unit - A unit of this device.
1549 * RESULT
1550 * None.
1552 ****************************************************************************
1556 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1558 UWORD ieee_length, frame_control, frame_type, slot, next_slot,
1559 encryption, key_no, buffer_no, old_length;
1560 struct DevBase *base;
1561 BOOL is_good;
1562 LONG frag_no;
1563 struct ath_desc *rx_desc, *next_desc;
1564 ULONG dma_size, rx_desc_p;
1565 UBYTE *buffer, *p, *frame, *data, *snap_frame, *source;
1566 struct ath_rx_status status;
1568 base = unit->device;
1569 slot = unit->rx_slot;
1570 rx_desc = unit->rx_descs + slot;
1571 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1572 next_slot = (slot + 1) % RX_SLOT_COUNT;
1573 next_desc = unit->rx_descs + next_slot;
1575 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1576 CachePostDMA(unit->rx_descs, &dma_size, 0);
1578 while(unit->hal->ah_procRxDesc(unit->hal, rx_desc, rx_desc_p, next_desc,
1579 unit->hal->ah_getTsf64(unit->hal), &status) != HAL_EINPROGRESS)
1581 is_good = TRUE;
1582 buffer = unit->rx_buffers[slot];
1584 dma_size = FRAME_BUFFER_SIZE;
1585 CachePostDMA(buffer, &dma_size, 0);
1587 if(status.rs_status == 0
1588 && status.rs_datalen >= WIFI_FRM_DATA + FCS_SIZE)
1590 /* Get fragment info */
1592 frame = buffer;
1593 ieee_length = status.rs_datalen - FCS_SIZE - WIFI_FRM_DATA;
1594 data = frame + WIFI_FRM_DATA;
1595 frame_control =
1596 LEWord(*(UWORD *)(frame + WIFI_FRM_CONTROL));
1598 /* Get buffer to store fragment in */
1600 frag_no = LEWord(*(UWORD *)(frame + WIFI_FRM_SEQCONTROL));
1601 if(unit->mode == S2PORT_ADHOC)
1602 source = frame + WIFI_FRM_ADDRESS2;
1603 else
1604 source = frame + WIFI_FRM_ADDRESS3;
1605 snap_frame = GetRXBuffer(unit, source, frag_no, &buffer_no, base);
1607 /* Get location to put new data */
1609 if(snap_frame != NULL)
1611 if((frag_no & 0xf ) > 0)
1612 old_length =
1613 BEWord(*(UWORD *)(snap_frame + ETH_PACKET_IEEELEN));
1614 else
1616 /* Create new 802.3 header */
1618 CopyMem(frame + WIFI_FRM_ADDRESS1, snap_frame,
1619 ETH_ADDRESSSIZE);
1620 CopyMem(source, snap_frame + ETH_PACKET_SOURCE,
1621 ETH_ADDRESSSIZE);
1622 old_length = 0;
1624 p = snap_frame + ETH_HEADERSIZE + old_length;
1626 /* Get encryption type and key index */
1628 if((frame_control & WIFI_FRM_CONTROLF_WEP) != 0)
1630 key_no = data[3] >> 6 & 0x3;
1631 encryption = unit->keys[key_no].type;
1633 else
1634 encryption = S2ENC_NONE;
1636 /* Append fragment to frame, decrypting/checking fragment if
1637 necessary */
1639 is_good = unit->fragment_decrypt_functions[encryption](unit,
1640 frame, data, &ieee_length, p, base);
1642 /* Update length in frame being built with current fragment, or
1643 increment bad frame counter if fragment is bad */
1645 if(is_good)
1647 ieee_length += old_length;
1648 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1649 MakeBEWord(ieee_length);
1651 else
1652 unit->stats.BadData++;
1654 /* If all fragments have arrived, process the complete frame */
1656 if((frame_control & WIFI_FRM_CONTROLF_MOREFRAGS) == 0)
1658 if(is_good)
1660 /* Decrypt complete frame if necessary */
1662 data = snap_frame + ETH_HEADERSIZE;
1663 if(encryption == S2ENC_TKIP)
1664 // && (unit->flags & UNITF_HARDTKIP) == 0)
1665 // && (unit->flags & UNITF_HARDMIC) == 0)
1667 is_good = TKIPDecryptFrame(unit, snap_frame, data,
1668 ieee_length, data, key_no, base);
1669 ieee_length -= MIC_SIZE;
1670 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1671 MakeBEWord(ieee_length);
1672 if(!is_good)
1673 unit->stats.BadData++;
1677 if(is_good)
1679 /* Get frame's 802.11 type and subtype */
1681 frame_type = (frame_control & WIFI_FRM_CONTROLF_TYPE)
1682 >> WIFI_FRM_CONTROLB_TYPE;
1684 /* If it's a management frame, process it separately;
1685 otherwise distribute it to clients after filtering */
1687 if(frame_type == WIFI_FRMTYPE_MGMT)
1689 DistributeMgmtFrame(unit, frame, status.rs_datalen - 4,
1690 base);
1692 else if(AddressFilter(unit, snap_frame + ETH_PACKET_DEST,
1693 base))
1695 unit->stats.PacketsReceived++;
1696 DistributeRXPacket(unit, snap_frame, base);
1701 /* Mark fragment buffer as unused for next time */
1703 unit->rx_fragment_nos[buffer_no] = -1;
1705 else
1706 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_RX, base);
1708 else
1710 is_good = FALSE;
1713 if(!is_good)
1715 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_HARDWARE | S2EVENT_RX,
1716 base);
1719 /* Prepare descriptor for next time */
1721 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
1722 HAL_RXDESC_INTREQ);
1724 dma_size = FRAME_BUFFER_SIZE;
1725 CachePreDMA(buffer, &dma_size, 0);
1727 /* Get next descriptor */
1729 slot = next_slot;
1730 rx_desc = next_desc;
1731 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1732 next_slot = (slot + 1) % RX_SLOT_COUNT;
1733 next_desc = unit->rx_descs + next_slot;
1736 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1737 CachePreDMA(unit->rx_descs, &dma_size, 0);
1739 unit->rx_slot = slot;
1740 // TO DO: unstall reception?
1742 /* Re-enable RX interrupts */
1744 #if 0
1745 Disable();
1746 unit->hal->ah_setInterrupts(unit->hal,
1747 unit->hal->ah_getInterrupts(unit->hal) | HAL_INT_RX | HAL_INT_RXEOL);
1748 Enable();
1749 #endif
1751 return;
1756 /****i* atheros5000.device/GetRXBuffer *************************************
1758 * NAME
1759 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1761 * SYNOPSIS
1762 * buffer = GetRXBuffer(unit, address, frag_no)
1764 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1766 ****************************************************************************
1770 static UBYTE *GetRXBuffer(struct DevUnit *unit, const UBYTE *address,
1771 UWORD frag_no, UWORD *buffer_no, struct DevBase *base)
1773 UWORD i;
1774 UBYTE *buffer;
1775 LONG n;
1776 BOOL found;
1778 buffer = unit->rx_frames;
1779 for(i = 0, found = FALSE; i < FRAME_BUFFER_COUNT * 2 && !found; i++)
1781 /* Throw away old buffer contents if we didn't find a free slot the
1782 first time around */
1784 if(i >= FRAME_BUFFER_COUNT)
1785 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = -1;
1787 /* For a frame's first fragment, find an empty slot; for subsequent
1788 fragments, find a slot with matching source address */
1790 n = unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT];
1791 if(n == -1 && (frag_no & 0xf) == 0
1792 || *((ULONG *)(buffer + ETH_PACKET_SOURCE))
1793 == *((ULONG *)(address))
1794 && *((UWORD *)(buffer + ETH_PACKET_SOURCE + 4))
1795 == *((UWORD *)(address + 4)))
1797 found = TRUE;
1798 if(n == -1)
1799 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = frag_no;
1800 *buffer_no = i;
1802 else
1803 buffer += FRAME_BUFFER_SIZE;
1806 if(!found)
1807 buffer = NULL;
1809 return buffer;
1814 /****i* atheros5000.device/DistributeRXPacket ******************************
1816 * NAME
1817 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1819 * SYNOPSIS
1820 * DistributeRXPacket(unit, frame)
1822 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1824 ****************************************************************************
1828 static VOID DistributeRXPacket(struct DevUnit *unit, UBYTE *frame,
1829 struct DevBase *base)
1831 UWORD packet_size, ieee_length;
1832 BOOL is_orphan = TRUE, accepted, is_snap = FALSE;
1833 ULONG packet_type;
1834 UBYTE *buffer;
1835 const UBYTE *template = snap_template;
1836 struct IOSana2Req *request, *request_tail;
1837 struct Opener *opener, *opener_tail;
1838 struct TypeStats *tracker;
1840 ieee_length = BEWord(*(UWORD *)(frame + ETH_PACKET_IEEELEN));
1841 packet_size = ETH_HEADERSIZE + ieee_length;
1842 if(ieee_length >= SNAP_HEADERSIZE)
1843 is_snap = *(const ULONG *)(frame + ETH_PACKET_DATA)
1844 == *(const ULONG *)template;
1846 /* De-encapsulate SNAP packets and get packet type */
1848 if(is_snap)
1850 buffer = unit->rx_buffer;
1851 packet_size -= SNAP_HEADERSIZE;
1852 CopyMem(frame, buffer, ETH_PACKET_TYPE);
1853 CopyMem(frame + ETH_HEADERSIZE + SNAP_FRM_TYPE,
1854 buffer + ETH_PACKET_TYPE, packet_size - ETH_PACKET_TYPE);
1856 else
1857 buffer = frame;
1859 packet_type = BEWord(*((UWORD *)(buffer + ETH_PACKET_TYPE)));
1861 if(packet_size <= ETH_MAXPACKETSIZE)
1863 /* Offer packet to every opener */
1865 opener = (APTR)unit->openers.mlh_Head;
1866 opener_tail = (APTR)&unit->openers.mlh_Tail;
1868 while(opener != opener_tail)
1870 request = (APTR)opener->read_port.mp_MsgList.lh_Head;
1871 request_tail = (APTR)&opener->read_port.mp_MsgList.lh_Tail;
1872 accepted = FALSE;
1874 /* Offer packet to each request until it's accepted */
1876 while(request != request_tail && !accepted)
1878 if(request->ios2_PacketType == packet_type)
1880 CopyPacket(unit, request, packet_size, packet_type,
1881 buffer, base);
1882 accepted = TRUE;
1884 request =
1885 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1888 if(accepted)
1889 is_orphan = FALSE;
1890 opener = (APTR)opener->node.mln_Succ;
1893 /* If packet was unwanted, give it to S2_READORPHAN request */
1895 if(is_orphan)
1897 unit->stats.UnknownTypesReceived++;
1898 if(!IsMsgPortEmpty(unit->request_ports[ADOPT_QUEUE]))
1900 CopyPacket(unit,
1901 (APTR)unit->request_ports[ADOPT_QUEUE]->
1902 mp_MsgList.lh_Head, packet_size, packet_type, buffer,
1903 base);
1907 /* Update remaining statistics */
1909 if(packet_type <= ETH_MTU)
1910 packet_type = ETH_MTU;
1911 tracker =
1912 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
1913 if(tracker != NULL)
1915 tracker->stats.PacketsReceived++;
1916 tracker->stats.BytesReceived += packet_size;
1919 else
1920 unit->stats.BadData++;
1922 return;
1927 /****i* atheros5000.device/CopyPacket **************************************
1929 * NAME
1930 * CopyPacket -- Copy packet to client's buffer.
1932 * SYNOPSIS
1933 * CopyPacket(unit, request, packet_size, packet_type,
1934 * buffer)
1936 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1937 * UBYTE *);
1939 ****************************************************************************
1943 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
1944 UWORD packet_size, UWORD packet_type, UBYTE *buffer,
1945 struct DevBase *base)
1947 struct Opener *opener;
1948 BOOL filtered = FALSE;
1950 /* Set multicast and broadcast flags */
1952 request->ios2_Req.io_Flags &= ~(SANA2IOF_BCAST | SANA2IOF_MCAST);
1953 if((*((ULONG *)(buffer + ETH_PACKET_DEST)) == 0xffffffff) &&
1954 (*((UWORD *)(buffer + ETH_PACKET_DEST + 4)) == 0xffff))
1955 request->ios2_Req.io_Flags |= SANA2IOF_BCAST;
1956 else if((buffer[ETH_PACKET_DEST] & 0x1) != 0)
1957 request->ios2_Req.io_Flags |= SANA2IOF_MCAST;
1959 /* Set source and destination addresses and packet type */
1961 CopyMem(buffer + ETH_PACKET_SOURCE, request->ios2_SrcAddr,
1962 ETH_ADDRESSSIZE);
1963 CopyMem(buffer + ETH_PACKET_DEST, request->ios2_DstAddr,
1964 ETH_ADDRESSSIZE);
1965 request->ios2_PacketType = packet_type;
1967 /* Adjust for cooked packet request */
1969 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1971 packet_size -= ETH_PACKET_DATA;
1972 buffer += ETH_PACKET_DATA;
1974 #ifdef USE_HACKS
1975 else
1976 packet_size += 4; /* Needed for Shapeshifter & Fusion? */
1977 #endif
1978 request->ios2_DataLength = packet_size;
1980 /* Filter packet */
1982 opener = request->ios2_BufferManagement;
1983 if(request->ios2_Req.io_Command == CMD_READ &&
1984 opener->filter_hook != NULL)
1985 if(!CallHookPkt(opener->filter_hook, request, buffer))
1986 filtered = TRUE;
1988 if(!filtered)
1990 /* Copy packet into opener's buffer and reply packet */
1992 if(!opener->rx_function(request->ios2_Data, buffer, packet_size))
1994 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1995 request->ios2_WireError = S2WERR_BUFF_ERROR;
1996 ReportEvents(unit,
1997 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
1998 base);
2000 Remove((APTR)request);
2001 ReplyMsg((APTR)request);
2004 return;
2009 /****i* atheros5000.device/AddressFilter ***********************************
2011 * NAME
2012 * AddressFilter -- Determine if an RX packet should be accepted.
2014 * SYNOPSIS
2015 * accept = AddressFilter(unit, address)
2017 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
2019 ****************************************************************************
2023 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
2024 struct DevBase *base)
2026 struct AddressRange *range, *tail;
2027 BOOL accept = TRUE;
2028 ULONG address_left;
2029 UWORD address_right;
2031 /* Check whether address is unicast/broadcast or multicast */
2033 address_left = BELong(*((ULONG *)address));
2034 address_right = BEWord(*((UWORD *)(address + 4)));
2036 if(((address_left & 0x01000000) != 0) &&
2037 !((address_left == 0xffffffff) && (address_right == 0xffff)))
2039 /* Check if this multicast address is wanted */
2041 range = (APTR)unit->multicast_ranges.mlh_Head;
2042 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
2043 accept = FALSE;
2045 while((range != tail) && !accept)
2047 if((address_left > range->lower_bound_left ||
2048 address_left == range->lower_bound_left &&
2049 address_right >= range->lower_bound_right) &&
2050 (address_left < range->upper_bound_left ||
2051 address_left == range->upper_bound_left &&
2052 address_right <= range->upper_bound_right))
2053 accept = TRUE;
2054 range = (APTR)range->node.mln_Succ;
2057 if(!accept)
2058 unit->special_stats[S2SS_ETHERNET_BADMULTICAST & 0xffff]++;
2061 return accept;
2066 /****i* atheros5000.device/DistributeMgmtFrame *****************************
2068 * NAME
2069 * DistributeMgmtFrame -- Send a management frame to clients.
2071 * SYNOPSIS
2072 * DistributeMgmtFrame(unit, frame, frame_size)
2074 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
2076 ****************************************************************************
2080 static VOID DistributeMgmtFrame(struct DevUnit *unit, UBYTE *frame,
2081 UWORD frame_size, struct DevBase *base)
2083 struct IOSana2Req *request;
2084 struct Opener *opener, *opener_tail;
2086 /* Send packet to every opener */
2088 opener = (APTR)unit->openers.mlh_Head;
2089 opener_tail = (APTR)&unit->openers.mlh_Tail;
2091 while(opener != opener_tail)
2093 request = (APTR)RemHead(&opener->mgmt_port.mp_MsgList);
2095 if(request != NULL)
2097 /* Copy packet into opener's buffer and reply packet */
2099 if(frame_size <= request->ios2_DataLength)
2101 CopyMem(frame, request->ios2_Data, frame_size);
2102 request->ios2_DataLength = frame_size;
2104 else
2106 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
2107 request->ios2_WireError = S2WERR_BUFF_ERROR;
2108 ReportEvents(unit,
2109 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
2110 base);
2112 ReplyMsg((APTR)request);
2113 request =
2114 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2117 opener = (APTR)opener->node.mln_Succ;
2120 return;
2125 /****i* atheros5000.device/TXInt *******************************************
2127 * NAME
2128 * TXInt -- Soft interrupt for packet transmission.
2130 * SYNOPSIS
2131 * TXInt(unit)
2133 * VOID TXInt(struct DevUnit *);
2135 * FUNCTION
2137 * INPUTS
2138 * unit - A unit of this device.
2140 * RESULT
2141 * None.
2143 ****************************************************************************
2147 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2149 struct DevBase *base;
2150 UWORD i, frame_size, data_size, packet_type, body_size, slot, new_slot,
2151 last_slot, encryption, subtype, duration;
2152 UBYTE *buffer, *q, *plaintext, *ciphertext, *frame,
2153 mic_header[ETH_ADDRESSSIZE * 2];
2154 const UBYTE *p, *dest, *source;
2155 struct IOSana2Req *request;
2156 BOOL proceed = TRUE, is_ieee;
2157 struct Opener *opener;
2158 ULONG wire_error, dma_size;
2159 struct ath_desc *tx_desc, *last_desc;
2160 UBYTE *(*dma_tx_function)(REG(a0, APTR));
2161 BYTE error;
2162 struct MsgPort *port;
2163 struct TypeStats *tracker;
2164 const HAL_RATE_TABLE *rate_table;
2166 base = unit->device;
2167 port = unit->request_ports[WRITE_QUEUE];
2168 rate_table = unit->rate_table;
2170 while(proceed && (!IsMsgPortEmpty(port)))
2172 slot = unit->tx_in_slot;
2173 new_slot = (slot + 1) % TX_SLOT_COUNT;
2175 // if(new_slot != unit->tx_out_slot)
2176 if(slot == unit->tx_out_slot) // one packet at a time
2178 error = 0;
2179 body_size = 0;
2181 /* Get request and DMA frame descriptor */
2183 request = (APTR)port->mp_MsgList.lh_Head;
2185 Remove((APTR)request);
2186 unit->tx_requests[slot] = request;
2187 tx_desc = unit->tx_descs + slot;
2188 frame = unit->tx_buffers[slot];
2190 /* Get packet data */
2192 opener = request->ios2_BufferManagement;
2193 dma_tx_function = opener->dma_tx_function;
2194 if(dma_tx_function != NULL)
2195 buffer = dma_tx_function(request->ios2_Data);
2196 else
2197 buffer = NULL;
2199 if(buffer == NULL)
2201 buffer = unit->tx_buffer;
2202 if(!opener->tx_function(buffer, request->ios2_Data,
2203 request->ios2_DataLength))
2205 error = S2ERR_NO_RESOURCES;
2206 wire_error = S2WERR_BUFF_ERROR;
2207 ReportEvents(unit,
2208 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF
2209 | S2EVENT_TX, base);
2213 if(error == 0)
2215 /* Get packet type and/or length */
2217 data_size = request->ios2_DataLength;
2218 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2220 data_size -= ETH_PACKET_DATA;
2221 packet_type = BEWord(*(UWORD *)(buffer + ETH_PACKET_TYPE));
2223 else
2224 packet_type = request->ios2_PacketType;
2225 is_ieee = packet_type <= ETH_MTU;
2227 /* Determine encryption type and frame subtype */
2229 if(data_size > 0)
2231 encryption = unit->keys[unit->tx_key_no].type;
2232 subtype = 0;
2234 else
2236 encryption = S2ENC_NONE;
2237 subtype = 4;
2240 /* Get source and destination addresses */
2242 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2244 dest = buffer;
2245 source = buffer + ETH_ADDRESSSIZE;
2246 buffer += ETH_ADDRESSSIZE * 2 + 2;
2248 else
2250 dest = request->ios2_DstAddr;
2251 source = unit->address;
2254 /* Write 802.11 header */
2256 q = frame;
2257 *(UWORD *)q = MakeLEWord(
2258 (encryption == S2ENC_NONE ? 0 : WIFI_FRM_CONTROLF_WEP)
2259 | (unit->mode == S2PORT_ADHOC ? 0 : WIFI_FRM_CONTROLF_TODS)
2260 | subtype << WIFI_FRM_CONTROLB_SUBTYPE
2261 | WIFI_FRMTYPE_DATA << WIFI_FRM_CONTROLB_TYPE);
2262 q += 2;
2264 i = rate_table->rateCodeToIndex[unit->tx_rate_codes[0]];
2265 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2266 duration = rate_table->info[i].spAckDuration;
2267 else
2268 duration = rate_table->info[i].lpAckDuration;
2269 *(UWORD *)q = MakeLEWord(duration);
2270 q += 2;
2272 if(unit->mode == S2PORT_ADHOC)
2273 p = dest;
2274 else
2275 p = unit->bssid;
2276 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2277 *q++ = *p++;
2279 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2280 *q++ = *p++;
2282 if(unit->mode == S2PORT_ADHOC)
2283 p = unit->bssid;
2284 else
2285 p = dest;
2286 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2287 *q++ = *p++;
2288 *(UWORD *)q = 0;
2289 q += 2;
2291 // TO DO: need to pad header to 4-byte boundary?
2293 /* Leave room for encryption overhead */
2295 ciphertext = q;
2296 q += unit->iv_sizes[encryption];
2297 plaintext = q;
2299 /* Write SNAP header */
2301 if(!is_ieee)
2303 for(i = 0, p = snap_template;
2304 i < SNAP_FRM_TYPE; i++)
2305 *q++ = *p++;
2306 *(UWORD *)q = MakeBEWord(packet_type);
2307 q += 2;
2308 body_size += SNAP_HEADERSIZE;
2311 /* Copy data into frame */
2313 CopyMem(buffer, q, data_size);
2314 body_size += data_size;
2316 /* Append MIC to frame for TKIP */
2318 if(encryption == S2ENC_TKIP)
2320 // if((unit->flags & UNITF_HARDMIC) == 0)
2322 q = mic_header;
2323 for(i = 0, p = dest; i < ETH_ADDRESSSIZE; i++)
2324 *q++ = *p++;
2325 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2326 *q++ = *p++;
2327 TKIPEncryptFrame(unit, mic_header, plaintext, body_size,
2328 plaintext, base);
2330 body_size += MIC_SIZE;
2333 /* Encrypt fragment if applicable */
2335 unit->fragment_encrypt_functions[encryption](unit, frame,
2336 plaintext, &body_size, ciphertext, base);
2338 /* Fill in DMA descriptor for packet transmission */
2340 frame_size = WIFI_FRM_DATA + body_size;
2341 tx_desc->ds_link = (ULONG)(UPINT)NULL;
2342 unit->hal->ah_setupTxDesc(unit->hal, tx_desc, frame_size + 4, // + CRC?
2343 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2344 ((unit->flags & UNITF_SLOWRETRIES) != 0) ?
2345 unit->tx_rate_codes[0] : unit->tx_rate_codes[1],
2346 ((unit->flags & UNITF_SLOWRETRIES) != 0) ? 1 : TX_TRIES,
2347 HAL_TXKEYIX_INVALID,
2348 HAL_ANTENNA_MIN_MODE,
2349 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK,
2350 0, 0, 0, 0, 3);
2351 if((unit->flags & UNITF_SLOWRETRIES) != 0)
2352 unit->hal->ah_setupXTxDesc(unit->hal, tx_desc,
2353 unit->tx_rate_codes[1], 1,
2354 unit->tx_rate_codes[2], 1,
2355 unit->tx_rate_codes[3], TX_TRIES - 3);
2356 unit->hal->ah_fillTxDesc(unit->hal, tx_desc, frame_size, TRUE, TRUE,
2357 tx_desc);
2359 dma_size = frame_size;
2360 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2362 /* Pass packet to adapter */
2364 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2365 last_slot = (slot + TX_SLOT_COUNT - 1) % TX_SLOT_COUNT;
2366 if(unit->tx_out_slot != slot)
2367 //if(unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no) > 0)
2369 last_desc =
2370 unit->tx_descs + last_slot;
2371 last_desc->ds_link = unit->tx_descs_p + slot * sizeof(struct ath_desc);
2372 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2373 CachePreDMA(unit->tx_descs, &dma_size, 0);
2375 else
2377 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2378 CachePreDMA(unit->tx_descs, &dma_size, 0);
2379 unit->hal->ah_setTxDP(unit->hal, unit->tx_queue_no,
2380 unit->tx_descs_p + slot * sizeof(struct ath_desc));
2383 unit->hal->ah_startTxDma(unit->hal, unit->tx_queue_no);
2384 unit->tx_in_slot = new_slot;
2386 else
2388 /* Reply failed request */
2390 request->ios2_Req.io_Error = error;
2391 request->ios2_WireError = wire_error;
2392 ReplyMsg((APTR)request);
2395 /* Update statistics */
2397 if(error == 0)
2399 unit->stats.PacketsSent++;
2401 tracker = FindTypeStats(unit, &unit->type_trackers,
2402 request->ios2_PacketType, base);
2403 if(tracker != NULL)
2405 tracker->stats.PacketsSent++;
2406 tracker->stats.BytesSent += ETH_HEADERSIZE + data_size;
2410 else
2411 proceed = FALSE;
2414 /* Don't try to keep sending packets if there's no space left */
2416 if(proceed)
2417 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
2418 else
2419 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_IGNORE;
2421 return;
2426 /****i* atheros5000.device/TXEndInt ****************************************
2428 * NAME
2429 * TXEndInt -- Clean up after a data frame has been sent.
2431 * SYNOPSIS
2432 * TXEndInt(unit, int_code)
2434 * VOID TXEndInt(struct DevUnit *, APTR);
2436 * NOTES
2437 * I think it's safe to assume that there will always be at least one
2438 * completed packet whenever this interrupt is called.
2440 ****************************************************************************
2444 static VOID TXEndInt(REG(a1, struct DevUnit *unit),
2445 REG(a6, APTR int_code))
2447 UWORD frame_size, new_out_slot, i;
2448 UBYTE *frame;
2449 struct DevBase *base;
2450 struct IOSana2Req *request;
2451 ULONG dma_size;
2452 struct TypeStats *tracker;
2454 /* Find out which packets have completed */
2456 base = unit->device;
2457 new_out_slot = (unit->tx_in_slot + TX_SLOT_COUNT
2458 - unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no))
2459 % TX_SLOT_COUNT;
2461 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2462 CachePostDMA(unit->tx_descs, &dma_size, 0);
2464 /* Retire sent packets */
2466 for(i = unit->tx_out_slot; i != new_out_slot;
2467 i = (i + 1) % TX_SLOT_COUNT)
2469 frame = unit->tx_buffers[i];
2470 dma_size = FRAME_BUFFER_SIZE;
2471 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2473 /* Update statistics */
2475 request = unit->tx_requests[i];
2476 frame_size = request->ios2_DataLength;
2477 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
2478 frame_size += ETH_HEADERSIZE;
2480 tracker = FindTypeStats(unit, &unit->type_trackers,
2481 request->ios2_PacketType, base);
2482 if(tracker != NULL)
2484 tracker->stats.PacketsSent++;
2485 tracker->stats.BytesSent += frame_size;
2488 /* Reply request */
2490 request->ios2_Req.io_Error = 0;
2491 ReplyMsg((APTR)request);
2494 unit->tx_out_slot = i;
2496 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2497 CachePreDMA(unit->tx_descs, &dma_size, 0);
2499 /* Restart downloads if they had stopped */
2501 if(unit->request_ports[WRITE_QUEUE]->mp_Flags == PA_IGNORE)
2502 Cause(&unit->tx_int);
2504 return;
2509 /****i* atheros5000.device/MgmtTXInt ***************************************
2511 * NAME
2512 * MgmtTXInt -- Soft interrupt for management frame transmission.
2514 * SYNOPSIS
2515 * MgmtTXInt(unit)
2517 * VOID MgmtTXInt(struct DevUnit *);
2519 * FUNCTION
2521 * INPUTS
2522 * unit - A unit of this device.
2524 * RESULT
2525 * None.
2527 ****************************************************************************
2531 static VOID MgmtTXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2533 struct DevBase *base;
2534 UWORD frame_size, slot, new_slot, last_slot, i, duration;
2535 UBYTE *frame;
2536 struct IOSana2Req *request;
2537 BOOL proceed = TRUE, has_bssid;
2538 ULONG dma_size;
2539 struct ath_desc *desc, *last_desc;
2540 struct MsgPort *port;
2541 const HAL_RATE_TABLE *rate_table;
2543 base = unit->device;
2544 port = unit->request_ports[MGMT_QUEUE];
2545 rate_table = unit->rate_table;
2547 while(proceed && (!IsMsgPortEmpty(port)))
2549 slot = unit->mgmt_in_slot;
2550 new_slot = (slot + 1) % MGMT_SLOT_COUNT;
2552 // if(new_slot != unit->mgmt_out_slot)
2553 if(slot == unit->mgmt_out_slot) // one packet at a time
2555 /* Get request and DMA frame descriptor */
2557 request = (APTR)port->mp_MsgList.lh_Head;
2559 Remove((APTR)request);
2560 unit->mgmt_requests[slot] = request;
2561 desc = unit->mgmt_descs + slot;
2562 frame = unit->mgmt_buffers[slot];
2564 /* Get packet length */
2566 frame_size = request->ios2_DataLength;
2568 /* Copy frame into DMA buffer */
2570 CopyMem(request->ios2_Data, frame, frame_size);
2572 /* Set duration */
2574 has_bssid = ((frame + WIFI_FRM_ADDRESS1)[0] & 0x1) == 0;
2575 i = rate_table->rateCodeToIndex[unit->mgmt_rate_code];
2576 if(has_bssid)
2578 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2579 duration = rate_table->info[i].spAckDuration;
2580 else
2581 duration = rate_table->info[i].lpAckDuration;
2583 else
2584 duration = 0;
2585 *(UWORD *)(frame + WIFI_FRM_DURATION) = MakeLEWord(duration);
2587 /* Fill in DMA descriptor for packet transmission */
2589 desc->ds_link = (ULONG)(UPINT)NULL;
2590 unit->hal->ah_setupTxDesc(unit->hal, desc, frame_size + 4, // + CRC?
2591 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2592 unit->mgmt_rate_code, TX_TRIES, HAL_TXKEYIX_INVALID,
2593 HAL_ANTENNA_MIN_MODE,
2594 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK
2595 | (has_bssid ? 0 : HAL_TXDESC_NOACK),
2596 0, 0, 0, 0, 3);
2597 unit->hal->ah_fillTxDesc(unit->hal, desc, frame_size, TRUE, TRUE,
2598 desc);
2600 dma_size = frame_size;
2601 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2603 /* Pass packet to adapter */
2605 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2606 last_slot = (slot + MGMT_SLOT_COUNT - 1) % MGMT_SLOT_COUNT;
2607 if(unit->mgmt_out_slot != slot)
2608 //if(unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no) > 0)
2610 last_desc = unit->mgmt_descs + last_slot;
2611 last_desc->ds_link =
2612 unit->mgmt_descs_p + slot * sizeof(struct ath_desc);
2613 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2614 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2616 else
2618 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2619 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2620 unit->hal->ah_setTxDP(unit->hal, unit->mgmt_queue_no,
2621 unit->mgmt_descs_p + slot * sizeof(struct ath_desc));
2624 unit->hal->ah_startTxDma(unit->hal, unit->mgmt_queue_no);
2625 unit->mgmt_in_slot = new_slot;
2627 else
2628 proceed = FALSE;
2631 /* Don't try to keep sending packets if there's no space left */
2633 if(proceed)
2634 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
2635 else
2636 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_IGNORE;
2638 return;
2643 /****i* atheros5000.device/MgmtTXEndInt ************************************
2645 * NAME
2646 * MgmtTXEndInt -- Clean up after a management frame has been sent.
2648 * SYNOPSIS
2649 * MgmtTXEndInt(unit, int_code)
2651 * VOID MgmtTXEndInt(struct DevUnit *, APTR);
2653 * NOTES
2654 * I think it's safe to assume that there will always be at least one
2655 * completed packet whenever this interrupt is called.
2657 ****************************************************************************
2661 static VOID MgmtTXEndInt(REG(a1, struct DevUnit *unit),
2662 REG(a6, APTR int_code))
2664 UWORD new_out_slot, i;
2665 UBYTE *frame;
2666 struct DevBase *base;
2667 struct IOSana2Req *request;
2668 ULONG dma_size;
2670 /* Find out which packets have completed */
2672 base = unit->device;
2673 new_out_slot = (unit->mgmt_in_slot + MGMT_SLOT_COUNT
2674 - unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no))
2675 % MGMT_SLOT_COUNT;
2677 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2678 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
2680 /* Retire sent frames */
2682 for(i = unit->mgmt_out_slot; i != new_out_slot;
2683 i = (i + 1) % MGMT_SLOT_COUNT)
2685 frame = unit->mgmt_buffers[i];
2686 dma_size = FRAME_BUFFER_SIZE;
2687 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2689 /* Reply request */
2691 request = unit->mgmt_requests[i];
2692 request->ios2_Req.io_Error = 0;
2693 ReplyMsg((APTR)request);
2696 unit->mgmt_out_slot = i;
2698 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2699 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2701 /* Restart downloads if they had stopped */
2703 if(unit->request_ports[MGMT_QUEUE]->mp_Flags == PA_IGNORE)
2704 Cause(&unit->mgmt_int);
2706 return;
2711 /****i* atheros5000.device/ResetHandler ************************************
2713 * NAME
2714 * ResetHandler -- Disable hardware before a reboot.
2716 * SYNOPSIS
2717 * ResetHandler(unit, int_code)
2719 * VOID ResetHandler(struct DevUnit *, APTR);
2721 ****************************************************************************
2725 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
2726 REG(a6, APTR int_code))
2728 if((unit->flags & UNITF_HAVEADAPTER) != 0)
2730 /* Disable frame transmission */
2732 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2733 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2735 /* Disable frame reception */
2737 unit->hal->ah_stopPcuReceive(unit->hal);
2738 unit->hal->ah_stopDmaReceive(unit->hal);
2740 /* Stop interrupts */
2742 unit->hal->ah_setInterrupts(unit->hal, 0);
2745 return;
2750 /****i* atheros5000.device/UpdateStats *************************************
2752 * NAME
2753 * UpdateStats
2755 * SYNOPSIS
2756 * UpdateStats(unit)
2758 * VOID UpdateStats(struct DevUnit *);
2760 * FUNCTION
2762 * INPUTS
2763 * unit - A unit of this device.
2765 * RESULT
2766 * None.
2768 ****************************************************************************
2772 VOID UpdateStats(struct DevUnit *unit, struct DevBase *base)
2774 /* Ask for and wait for stats */
2776 return;
2781 /****i* atheros5000.device/ReportEvents ************************************
2783 * NAME
2784 * ReportEvents
2786 * SYNOPSIS
2787 * ReportEvents(unit, events)
2789 * VOID ReportEvents(struct DevUnit *, ULONG);
2791 * FUNCTION
2793 * INPUTS
2794 * unit - A unit of this device.
2795 * events - A mask of events to report.
2797 * RESULT
2798 * None.
2800 ****************************************************************************
2804 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
2805 struct DevBase *base)
2807 struct IOSana2Req *request, *tail, *next_request;
2808 struct List *list;
2810 list = &unit->request_ports[EVENT_QUEUE]->mp_MsgList;
2811 next_request = (APTR)list->lh_Head;
2812 tail = (APTR)&list->lh_Tail;
2814 Disable();
2815 while(next_request != tail)
2817 request = next_request;
2818 next_request = (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2820 if((request->ios2_WireError & events) != 0)
2822 request->ios2_WireError = events;
2823 Remove((APTR)request);
2824 ReplyMsg((APTR)request);
2827 Enable();
2829 return;
2834 /****i* atheros5000.device/GetRadioBands ***********************************
2836 * NAME
2837 * GetRadioBands -- Get information on current network.
2839 * SYNOPSIS
2840 * tag_list = GetRadioBands(unit, pool)
2842 * struct TagItem *GetRadioBands(struct DevUnit *, APTR);
2844 * FUNCTION
2846 * INPUTS
2847 * unit - A unit of this device.
2848 * pool - A memory pool.
2850 * RESULT
2851 * None.
2853 ****************************************************************************
2857 #if 0
2858 struct TagItem *GetRadioBands(struct DevUnit *unit, APTR pool,
2859 struct DevBase *base)
2861 BYTE error = 0;
2862 struct Sana2RadioBand *bands;
2863 UWORD i;
2865 bands = AllocPooled(pool, sizeof(struct Sana2RadioBand) * 3);
2866 if(bands == NULL)
2867 error = S2ERR_NO_RESOURCES;
2869 if(error == 0)
2871 for(i = 0; i < 1; i++)
2873 bands[i] = AllocPooled(pool, sizeof(UWORD) * unit->channel_counts[S2BAND_B]);
2877 // if(error != 0)
2878 // bands = NULL;
2880 return bands;
2882 #endif
2886 /****i* atheros5000.device/UnitTask ****************************************
2888 * NAME
2889 * UnitTask
2891 * SYNOPSIS
2892 * UnitTask()
2894 * VOID UnitTask();
2896 * FUNCTION
2897 * Completes deferred requests, and handles card insertion and removal
2898 * in conjunction with the relevant interrupts.
2900 ****************************************************************************
2904 #ifdef __MORPHOS__
2905 #undef UnitTask
2906 #endif
2908 static VOID UnitTask(struct ExecBase *sys_base)
2910 struct Task *task;
2911 struct IORequest *request;
2912 struct DevUnit *unit;
2913 struct DevBase *base;
2914 struct MsgPort *general_port;
2915 ULONG signals = 0, wait_signals, card_removed_signal,
2916 card_inserted_signal, general_port_signal;
2918 /* Get parameters */
2920 task = AbsExecBase->ThisTask;
2921 unit = task->tc_UserData;
2922 base = unit->device;
2924 /* Activate general request port */
2926 general_port = unit->request_ports[GENERAL_QUEUE];
2927 general_port->mp_SigTask = task;
2928 general_port->mp_SigBit = AllocSignal(-1);
2929 general_port_signal = 1 << general_port->mp_SigBit;
2930 general_port->mp_Flags = PA_SIGNAL;
2932 /* Allocate signals for notification of card removal and insertion */
2934 card_removed_signal = unit->card_removed_signal = 1 << AllocSignal(-1);
2935 card_inserted_signal = unit->card_inserted_signal = 1 << AllocSignal(-1);
2936 wait_signals = (1 << general_port->mp_SigBit) | card_removed_signal
2937 | card_inserted_signal | SIGBREAKF_CTRL_C;
2939 /* Tell ourselves to check port for old messages */
2941 Signal(task, general_port_signal);
2943 /* Infinite loop to service requests and signals */
2945 while((signals & SIGBREAKF_CTRL_C) == 0)
2947 signals = Wait(wait_signals);
2949 if((signals & card_inserted_signal) != 0)
2951 if(unit->insertion_function(unit->card, base))
2953 unit->flags |= UNITF_HAVEADAPTER;
2954 if((unit->flags & UNITF_CONFIGURED) != 0)
2955 ConfigureAdapter(unit, base);
2956 if((unit->flags & UNITF_WASONLINE) != 0)
2958 GoOnline(unit, base);
2959 unit->flags &= ~UNITF_WASONLINE;
2964 if((signals & card_removed_signal) != 0)
2966 unit->removal_function(unit->card, base);
2967 if((unit->flags & UNITF_WASONLINE) != 0)
2968 GoOffline(unit, base);
2971 if((signals & general_port_signal) != 0)
2973 while((request = (APTR)GetMsg(general_port)) != NULL)
2975 /* Service the request as soon as the unit is free */
2977 ObtainSemaphore(&unit->access_lock);
2978 ServiceRequest((APTR)request, base);
2983 FreeMem(task->tc_SPLower, STACK_SIZE);