Fixed my network drivers to work with ABIv1 (apart from prism2.device, which
[AROS.git] / workbench / devs / networks / atheros5000 / unit.c
blob796bd7121196b9bf93066b628080ebba09074d17
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_BSSID:
1022 CopyMem((APTR)tag_item->ti_Data, unit->bssid, ETH_ADDRESSSIZE);
1023 break;
1025 case S2INFO_AssocID:
1026 unit->assoc_id = tag_item->ti_Data;
1027 break;
1029 case S2INFO_Capabilities:
1030 unit->capabilities = tag_item->ti_Data;
1031 if((unit->capabilities & (1 << 5)) != 0)
1032 unit->flags |= UNITF_SHORTPREAMBLE;
1033 else
1034 unit->flags &= ~UNITF_SHORTPREAMBLE;
1035 break;
1037 case S2INFO_DefaultKeyNo:
1038 unit->tx_key_no = tag_item->ti_Data;
1039 break;
1041 case S2INFO_PortType:
1042 unit->mode = tag_item->ti_Data;
1043 break;
1045 case S2INFO_Channel:
1046 if(tag_item->ti_Data != unit->channel)
1048 unit->channel = tag_item->ti_Data;
1049 reconfigure = TRUE;
1051 break;
1053 case S2INFO_Band:
1054 if(tag_item->ti_Data != unit->band)
1056 unit->band = tag_item->ti_Data;
1057 reconfigure = TRUE;
1059 break;
1063 return reconfigure;
1068 /****i* atheros5000.device/SetKey ******************************************
1070 * NAME
1071 * SetKey -- Set an encryption key.
1073 * SYNOPSIS
1074 * SetKey(unit, index, type, key, key_length,
1075 * rx_counter)
1077 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1078 * UBYTE *);
1080 ****************************************************************************
1084 VOID SetKey(struct DevUnit *unit, ULONG index, ULONG type, const UBYTE *key,
1085 ULONG key_length, const UBYTE *rx_counter, struct DevBase *base)
1087 struct KeyUnion *slot;
1088 struct EClockVal eclock;
1089 HAL_KEYVAL hal_key;
1090 UWORD i;
1092 Disable();
1093 slot = &unit->keys[index];
1094 switch(type)
1096 case S2ENC_WEP:
1097 CopyMem(key, slot->u.wep.key, key_length);
1098 slot->u.wep.length = key_length;
1100 if((unit->flags & UNITF_HARDWEP) == 0)
1102 /* Create a reasonably random IV */
1104 ReadEClock(&eclock);
1105 slot->u.wep.tx_iv = FastRand(eclock.ev_lo ^ eclock.ev_hi);
1108 break;
1110 case S2ENC_TKIP:
1111 CopyMem(key, slot->u.tkip.key, 16);
1112 CopyMem(key + 16, slot->u.tkip.tx_mic_key, MIC_SIZE);
1113 CopyMem(key + 24, slot->u.tkip.rx_mic_key, MIC_SIZE);
1114 slot->u.tkip.tx_iv_low = 0;
1115 slot->u.tkip.tx_iv_high = 0;
1116 slot->u.tkip.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1117 slot->u.tkip.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1118 slot->u.tkip.tx_ttak_set = FALSE;
1119 slot->u.tkip.rx_ttak_set = FALSE;
1121 if((unit->flags & UNITF_HARDTKIP) != 0)
1123 // TO DO: Wait for TX queue to empty
1124 /* Load parameters for hardware encryption */
1126 hal_key.kv_type = HAL_CIPHER_TKIP;
1127 hal_key.kv_len = 16;
1128 CopyMem(slot->u.tkip.key, hal_key.kv_val, 16);
1130 CopyMem(slot->u.tkip.tx_mic_key, hal_key.kv_mic, MIC_SIZE);
1131 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1132 unit->bssid, FALSE);
1133 CopyMem(slot->u.tkip.rx_mic_key, hal_key.kv_mic, MIC_SIZE);
1134 unit->hal->ah_setKeyCacheEntry(unit->hal, index + 32, &hal_key,
1135 unit->bssid, FALSE);
1137 else
1139 /* Convert key to native endianness */
1141 for(i = 0; i < 8; i++)
1142 slot->u.tkip.key[i] = LEWord(slot->u.tkip.key[i]);
1145 break;
1147 case S2ENC_CCMP:
1148 CopyMem(key, slot->u.ccmp.key, 16);
1149 slot->u.ccmp.tx_iv_low = 0;
1150 slot->u.ccmp.tx_iv_high = 0;
1151 slot->u.ccmp.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1152 slot->u.ccmp.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1153 slot->u.ccmp.stream_set = FALSE;
1155 if((unit->flags & UNITF_HARDCCMP) != 0)
1157 // TO DO: Wait for TX queue to empty
1158 /* Load parameters for hardware encryption */
1160 hal_key.kv_type = HAL_CIPHER_AES_CCM;
1161 hal_key.kv_len = 16;
1162 CopyMem(slot->u.ccmp.key, hal_key.kv_val, 16);
1163 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1164 unit->bssid, FALSE);
1168 /* Update type of key in selected slot */
1170 slot->type = type;
1171 Enable();
1173 return;
1178 /****i* atheros5000.device/AddMulticastRange *******************************
1180 * NAME
1181 * AddMulticastRange
1183 * SYNOPSIS
1184 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1186 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1188 ****************************************************************************
1192 BOOL AddMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1193 const UBYTE *upper_bound, struct DevBase *base)
1195 struct AddressRange *range;
1196 ULONG lower_bound_left, upper_bound_left;
1197 UWORD lower_bound_right, upper_bound_right;
1199 lower_bound_left = BELong(*((ULONG *)lower_bound));
1200 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1201 upper_bound_left = BELong(*((ULONG *)upper_bound));
1202 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1204 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1205 upper_bound_left, upper_bound_right, base);
1207 if(range != NULL)
1208 range->add_count++;
1209 else
1211 range = AllocMem(sizeof(struct AddressRange), MEMF_PUBLIC);
1212 if(range != NULL)
1214 range->lower_bound_left = lower_bound_left;
1215 range->lower_bound_right = lower_bound_right;
1216 range->upper_bound_left = upper_bound_left;
1217 range->upper_bound_right = upper_bound_right;
1218 range->add_count = 1;
1220 Disable();
1221 AddTail((APTR)&unit->multicast_ranges, (APTR)range);
1222 unit->range_count++;
1223 SetMulticast(unit, base);
1224 Enable();
1228 return range != NULL;
1233 /****i* atheros5000.device/RemMulticastRange *******************************
1235 * NAME
1236 * RemMulticastRange
1238 * SYNOPSIS
1239 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1241 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1243 ****************************************************************************
1247 BOOL RemMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1248 const UBYTE *upper_bound, struct DevBase *base)
1250 struct AddressRange *range;
1251 ULONG lower_bound_left, upper_bound_left;
1252 UWORD lower_bound_right, upper_bound_right;
1254 lower_bound_left = BELong(*((ULONG *)lower_bound));
1255 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1256 upper_bound_left = BELong(*((ULONG *)upper_bound));
1257 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1259 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1260 upper_bound_left, upper_bound_right, base);
1262 if(range != NULL)
1264 if(--range->add_count == 0)
1266 Disable();
1267 Remove((APTR)range);
1268 unit->range_count--;
1269 SetMulticast(unit, base);
1270 Enable();
1271 FreeMem(range, sizeof(struct AddressRange));
1275 return range != NULL;
1280 /****i* atheros5000.device/FindMulticastRange ******************************
1282 * NAME
1283 * FindMulticastRange
1285 * SYNOPSIS
1286 * range = FindMulticastRange(unit, lower_bound_left,
1287 * lower_bound_right, upper_bound_left, upper_bound_right)
1289 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1290 * UWORD, ULONG, UWORD);
1292 ****************************************************************************
1296 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
1297 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
1298 UWORD upper_bound_right, struct DevBase *base)
1300 struct AddressRange *range, *tail;
1301 BOOL found = FALSE;
1303 range = (APTR)unit->multicast_ranges.mlh_Head;
1304 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
1306 while(range != tail && !found)
1308 if(lower_bound_left == range->lower_bound_left &&
1309 lower_bound_right == range->lower_bound_right &&
1310 upper_bound_left == range->upper_bound_left &&
1311 upper_bound_right == range->upper_bound_right)
1312 found = TRUE;
1313 else
1314 range = (APTR)range->node.mln_Succ;
1317 if(!found)
1318 range = NULL;
1320 return range;
1325 /****i* atheros5000.device/SetMulticast ************************************
1327 * NAME
1328 * SetMulticast
1330 * SYNOPSIS
1331 * SetMulticast(unit)
1333 * VOID SetMulticast(struct DevUnit *);
1335 ****************************************************************************
1339 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base)
1341 unit->hal->ah_setMulticastFilter(unit->hal, 0xffffffff, 0xffffffff);
1343 return;
1348 /****i* atheros5000.device/FindTypeStats ***********************************
1350 * NAME
1351 * FindTypeStats
1353 * SYNOPSIS
1354 * stats = FindTypeStats(unit, list,
1355 * packet_type)
1357 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1358 * ULONG);
1360 ****************************************************************************
1364 struct TypeStats *FindTypeStats(struct DevUnit *unit, struct MinList *list,
1365 ULONG packet_type, struct DevBase *base)
1367 struct TypeStats *stats, *tail;
1368 BOOL found = FALSE;
1370 stats = (APTR)list->mlh_Head;
1371 tail = (APTR)&list->mlh_Tail;
1373 while(stats != tail && !found)
1375 if(stats->packet_type == packet_type)
1376 found = TRUE;
1377 else
1378 stats = (APTR)stats->node.mln_Succ;
1381 if(!found)
1382 stats = NULL;
1384 return stats;
1389 /****i* atheros5000.device/FlushUnit ***************************************
1391 * NAME
1392 * FlushUnit
1394 * SYNOPSIS
1395 * FlushUnit(unit, last_queue, error)
1397 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1399 ****************************************************************************
1403 VOID FlushUnit(struct DevUnit *unit, UBYTE last_queue, BYTE error,
1404 struct DevBase *base)
1406 struct IORequest *request;
1407 UBYTE i;
1408 struct Opener *opener, *tail;
1410 /* Abort queued requests */
1412 for(i = 0; i <= last_queue; i++)
1414 while((request = (APTR)GetMsg(unit->request_ports[i])) != NULL)
1416 request->io_Error = IOERR_ABORTED;
1417 ReplyMsg((APTR)request);
1421 #if 1
1422 opener = (APTR)unit->openers.mlh_Head;
1423 tail = (APTR)&unit->openers.mlh_Tail;
1425 /* Flush every opener's read queues */
1427 while(opener != tail)
1429 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1431 request->io_Error = error;
1432 ReplyMsg((APTR)request);
1434 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1436 request->io_Error = error;
1437 ReplyMsg((APTR)request);
1439 opener = (APTR)opener->node.mln_Succ;
1442 #else
1443 opener = request->ios2_BufferManagement;
1444 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1446 request->io_Error = IOERR_ABORTED;
1447 ReplyMsg((APTR)request);
1449 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1451 request->io_Error = IOERR_ABORTED;
1452 ReplyMsg((APTR)request);
1454 #endif
1456 /* Return */
1458 return;
1463 /****i* atheros5000.device/StatusInt ***************************************
1465 * NAME
1466 * StatusInt
1468 * SYNOPSIS
1469 * finished = StatusInt(unit)
1471 * BOOL StatusInt(struct DevUnit *);
1473 * FUNCTION
1475 * INPUTS
1476 * unit
1478 * RESULT
1479 * finished
1481 ****************************************************************************
1483 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1484 * Since we don't use this parameter, we can lie.
1488 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1490 struct DevBase *base;
1491 uint32_t queue_mask;
1492 HAL_INT ints, int_mask;
1494 base = unit->device;
1495 int_mask = unit->hal->ah_getInterrupts(unit->hal);
1497 if(!unit->hal->ah_isInterruptPending(unit->hal)) return FALSE;
1499 /* Handle ints */
1501 if(unit->hal->ah_getPendingInterrupts(unit->hal, &ints))
1503 if((ints & HAL_INT_TX) != 0)
1505 int_mask &= ~(HAL_INT_TX | HAL_INT_TXDESC);
1506 queue_mask = 1 << unit->tx_queue_no | 1 << unit->mgmt_queue_no;
1507 unit->hal->ah_getTxIntrQueue(unit->hal, &queue_mask);
1508 if((queue_mask & 1 << unit->tx_queue_no) != 0)
1509 Cause(&unit->tx_end_int);
1510 if((queue_mask & 1 << unit->mgmt_queue_no) != 0)
1511 Cause(&unit->mgmt_end_int);
1513 if((ints & HAL_INT_RX) != 0)
1515 int_mask &= ~(HAL_INT_RX | HAL_INT_RXEOL);
1516 Cause(&unit->rx_int);
1520 #ifdef __MORPHOS__
1521 int_mask = INT_MASK;
1522 #endif
1523 // unit->hal->ah_setInterrupts(unit->hal, int_mask))
1525 return FALSE;
1530 /****i* atheros5000.device/RXInt *******************************************
1532 * NAME
1533 * RXInt -- Soft interrupt for packet reception.
1535 * SYNOPSIS
1536 * RXInt(unit)
1538 * VOID RXInt(struct DevUnit *);
1540 * FUNCTION
1542 * INPUTS
1543 * unit - A unit of this device.
1545 * RESULT
1546 * None.
1548 ****************************************************************************
1552 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1554 UWORD ieee_length, frame_control, frame_type, slot, next_slot,
1555 encryption, key_no, buffer_no, old_length;
1556 struct DevBase *base;
1557 BOOL is_good;
1558 LONG frag_no;
1559 struct ath_desc *rx_desc, *next_desc;
1560 ULONG dma_size, rx_desc_p;
1561 UBYTE *buffer, *p, *frame, *data, *snap_frame, *source;
1562 struct ath_rx_status status;
1564 base = unit->device;
1565 slot = unit->rx_slot;
1566 rx_desc = unit->rx_descs + slot;
1567 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1568 next_slot = (slot + 1) % RX_SLOT_COUNT;
1569 next_desc = unit->rx_descs + next_slot;
1571 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1572 CachePostDMA(unit->rx_descs, &dma_size, 0);
1574 while(unit->hal->ah_procRxDesc(unit->hal, rx_desc, rx_desc_p, next_desc,
1575 unit->hal->ah_getTsf64(unit->hal), &status) != HAL_EINPROGRESS)
1577 is_good = TRUE;
1578 buffer = unit->rx_buffers[slot];
1580 dma_size = FRAME_BUFFER_SIZE;
1581 CachePostDMA(buffer, &dma_size, 0);
1583 if(status.rs_status == 0
1584 && status.rs_datalen >= WIFI_FRM_DATA + FCS_SIZE)
1586 /* Get fragment info */
1588 frame = buffer;
1589 ieee_length = status.rs_datalen - FCS_SIZE - WIFI_FRM_DATA;
1590 data = frame + WIFI_FRM_DATA;
1591 frame_control =
1592 LEWord(*(UWORD *)(frame + WIFI_FRM_CONTROL));
1594 /* Get buffer to store fragment in */
1596 frag_no = LEWord(*(UWORD *)(frame + WIFI_FRM_SEQCONTROL));
1597 if(unit->mode == S2PORT_ADHOC)
1598 source = frame + WIFI_FRM_ADDRESS2;
1599 else
1600 source = frame + WIFI_FRM_ADDRESS3;
1601 snap_frame = GetRXBuffer(unit, source, frag_no, &buffer_no, base);
1603 /* Get location to put new data */
1605 if(snap_frame != NULL)
1607 if((frag_no & 0xf ) > 0)
1608 old_length =
1609 BEWord(*(UWORD *)(snap_frame + ETH_PACKET_IEEELEN));
1610 else
1612 /* Create new 802.3 header */
1614 CopyMem(frame + WIFI_FRM_ADDRESS1, snap_frame,
1615 ETH_ADDRESSSIZE);
1616 CopyMem(source, snap_frame + ETH_PACKET_SOURCE,
1617 ETH_ADDRESSSIZE);
1618 old_length = 0;
1620 p = snap_frame + ETH_HEADERSIZE + old_length;
1622 /* Get encryption type and key index */
1624 if((frame_control & WIFI_FRM_CONTROLF_WEP) != 0)
1626 key_no = data[3] >> 6 & 0x3;
1627 encryption = unit->keys[key_no].type;
1629 else
1630 encryption = S2ENC_NONE;
1632 /* Append fragment to frame, decrypting/checking fragment if
1633 necessary */
1635 is_good = unit->fragment_decrypt_functions[encryption](unit,
1636 frame, data, &ieee_length, p, base);
1638 /* Update length in frame being built with current fragment, or
1639 increment bad frame counter if fragment is bad */
1641 if(is_good)
1643 ieee_length += old_length;
1644 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1645 MakeBEWord(ieee_length);
1647 else
1648 unit->stats.BadData++;
1650 /* If all fragments have arrived, process the complete frame */
1652 if((frame_control & WIFI_FRM_CONTROLF_MOREFRAGS) == 0)
1654 if(is_good)
1656 /* Decrypt complete frame if necessary */
1658 data = snap_frame + ETH_HEADERSIZE;
1659 if(encryption == S2ENC_TKIP)
1660 // && (unit->flags & UNITF_HARDTKIP) == 0)
1661 // && (unit->flags & UNITF_HARDMIC) == 0)
1663 is_good = TKIPDecryptFrame(unit, snap_frame, data,
1664 ieee_length, data, key_no, base);
1665 ieee_length -= MIC_SIZE;
1666 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1667 MakeBEWord(ieee_length);
1668 if(!is_good)
1669 unit->stats.BadData++;
1673 if(is_good)
1675 /* Get frame's 802.11 type and subtype */
1677 frame_type = (frame_control & WIFI_FRM_CONTROLF_TYPE)
1678 >> WIFI_FRM_CONTROLB_TYPE;
1680 /* If it's a management frame, process it separately;
1681 otherwise distribute it to clients after filtering */
1683 if(frame_type == WIFI_FRMTYPE_MGMT)
1685 DistributeMgmtFrame(unit, frame, status.rs_datalen - 4,
1686 base);
1688 else if(AddressFilter(unit, snap_frame + ETH_PACKET_DEST,
1689 base))
1691 unit->stats.PacketsReceived++;
1692 DistributeRXPacket(unit, snap_frame, base);
1697 /* Mark fragment buffer as unused for next time */
1699 unit->rx_fragment_nos[buffer_no] = -1;
1701 else
1702 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_RX, base);
1704 else
1706 is_good = FALSE;
1709 if(!is_good)
1711 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_HARDWARE | S2EVENT_RX,
1712 base);
1715 /* Prepare descriptor for next time */
1717 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
1718 HAL_RXDESC_INTREQ);
1720 dma_size = FRAME_BUFFER_SIZE;
1721 CachePreDMA(buffer, &dma_size, 0);
1723 /* Get next descriptor */
1725 slot = next_slot;
1726 rx_desc = next_desc;
1727 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1728 next_slot = (slot + 1) % RX_SLOT_COUNT;
1729 next_desc = unit->rx_descs + next_slot;
1732 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1733 CachePreDMA(unit->rx_descs, &dma_size, 0);
1735 unit->rx_slot = slot;
1736 // TO DO: unstall reception?
1738 /* Re-enable RX interrupts */
1740 #if 0
1741 Disable();
1742 unit->hal->ah_setInterrupts(unit->hal,
1743 unit->hal->ah_getInterrupts(unit->hal) | HAL_INT_RX | HAL_INT_RXEOL);
1744 Enable();
1745 #endif
1747 return;
1752 /****i* atheros5000.device/GetRXBuffer *************************************
1754 * NAME
1755 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1757 * SYNOPSIS
1758 * buffer = GetRXBuffer(unit, address, frag_no)
1760 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1762 ****************************************************************************
1766 static UBYTE *GetRXBuffer(struct DevUnit *unit, const UBYTE *address,
1767 UWORD frag_no, UWORD *buffer_no, struct DevBase *base)
1769 UWORD i;
1770 UBYTE *buffer;
1771 LONG n;
1772 BOOL found;
1774 buffer = unit->rx_frames;
1775 for(i = 0, found = FALSE; i < FRAME_BUFFER_COUNT * 2 && !found; i++)
1777 /* Throw away old buffer contents if we didn't find a free slot the
1778 first time around */
1780 if(i >= FRAME_BUFFER_COUNT)
1781 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = -1;
1783 /* For a frame's first fragment, find an empty slot; for subsequent
1784 fragments, find a slot with matching source address */
1786 n = unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT];
1787 if(n == -1 && (frag_no & 0xf) == 0
1788 || *((ULONG *)(buffer + ETH_PACKET_SOURCE))
1789 == *((ULONG *)(address))
1790 && *((UWORD *)(buffer + ETH_PACKET_SOURCE + 4))
1791 == *((UWORD *)(address + 4)))
1793 found = TRUE;
1794 if(n == -1)
1795 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = frag_no;
1796 *buffer_no = i;
1798 else
1799 buffer += FRAME_BUFFER_SIZE;
1802 if(!found)
1803 buffer = NULL;
1805 return buffer;
1810 /****i* atheros5000.device/DistributeRXPacket ******************************
1812 * NAME
1813 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1815 * SYNOPSIS
1816 * DistributeRXPacket(unit, frame)
1818 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1820 ****************************************************************************
1824 static VOID DistributeRXPacket(struct DevUnit *unit, UBYTE *frame,
1825 struct DevBase *base)
1827 UWORD packet_size, ieee_length;
1828 BOOL is_orphan = TRUE, accepted, is_snap = FALSE;
1829 ULONG packet_type;
1830 UBYTE *buffer;
1831 const UBYTE *template = snap_template;
1832 struct IOSana2Req *request, *request_tail;
1833 struct Opener *opener, *opener_tail;
1834 struct TypeStats *tracker;
1836 ieee_length = BEWord(*(UWORD *)(frame + ETH_PACKET_IEEELEN));
1837 packet_size = ETH_HEADERSIZE + ieee_length;
1838 if(ieee_length >= SNAP_HEADERSIZE)
1839 is_snap = *(const ULONG *)(frame + ETH_PACKET_DATA)
1840 == *(const ULONG *)template;
1842 /* De-encapsulate SNAP packets and get packet type */
1844 if(is_snap)
1846 buffer = unit->rx_buffer;
1847 packet_size -= SNAP_HEADERSIZE;
1848 CopyMem(frame, buffer, ETH_PACKET_TYPE);
1849 CopyMem(frame + ETH_HEADERSIZE + SNAP_FRM_TYPE,
1850 buffer + ETH_PACKET_TYPE, packet_size - ETH_PACKET_TYPE);
1852 else
1853 buffer = frame;
1855 packet_type = BEWord(*((UWORD *)(buffer + ETH_PACKET_TYPE)));
1857 if(packet_size <= ETH_MAXPACKETSIZE)
1859 /* Offer packet to every opener */
1861 opener = (APTR)unit->openers.mlh_Head;
1862 opener_tail = (APTR)&unit->openers.mlh_Tail;
1864 while(opener != opener_tail)
1866 request = (APTR)opener->read_port.mp_MsgList.lh_Head;
1867 request_tail = (APTR)&opener->read_port.mp_MsgList.lh_Tail;
1868 accepted = FALSE;
1870 /* Offer packet to each request until it's accepted */
1872 while(request != request_tail && !accepted)
1874 if(request->ios2_PacketType == packet_type)
1876 CopyPacket(unit, request, packet_size, packet_type,
1877 buffer, base);
1878 accepted = TRUE;
1880 request =
1881 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1884 if(accepted)
1885 is_orphan = FALSE;
1886 opener = (APTR)opener->node.mln_Succ;
1889 /* If packet was unwanted, give it to S2_READORPHAN request */
1891 if(is_orphan)
1893 unit->stats.UnknownTypesReceived++;
1894 if(!IsMsgPortEmpty(unit->request_ports[ADOPT_QUEUE]))
1896 CopyPacket(unit,
1897 (APTR)unit->request_ports[ADOPT_QUEUE]->
1898 mp_MsgList.lh_Head, packet_size, packet_type, buffer,
1899 base);
1903 /* Update remaining statistics */
1905 if(packet_type <= ETH_MTU)
1906 packet_type = ETH_MTU;
1907 tracker =
1908 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
1909 if(tracker != NULL)
1911 tracker->stats.PacketsReceived++;
1912 tracker->stats.BytesReceived += packet_size;
1915 else
1916 unit->stats.BadData++;
1918 return;
1923 /****i* atheros5000.device/CopyPacket **************************************
1925 * NAME
1926 * CopyPacket -- Copy packet to client's buffer.
1928 * SYNOPSIS
1929 * CopyPacket(unit, request, packet_size, packet_type,
1930 * buffer)
1932 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1933 * UBYTE *);
1935 ****************************************************************************
1939 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
1940 UWORD packet_size, UWORD packet_type, UBYTE *buffer,
1941 struct DevBase *base)
1943 struct Opener *opener;
1944 BOOL filtered = FALSE;
1946 /* Set multicast and broadcast flags */
1948 request->ios2_Req.io_Flags &= ~(SANA2IOF_BCAST | SANA2IOF_MCAST);
1949 if((*((ULONG *)(buffer + ETH_PACKET_DEST)) == 0xffffffff) &&
1950 (*((UWORD *)(buffer + ETH_PACKET_DEST + 4)) == 0xffff))
1951 request->ios2_Req.io_Flags |= SANA2IOF_BCAST;
1952 else if((buffer[ETH_PACKET_DEST] & 0x1) != 0)
1953 request->ios2_Req.io_Flags |= SANA2IOF_MCAST;
1955 /* Set source and destination addresses and packet type */
1957 CopyMem(buffer + ETH_PACKET_SOURCE, request->ios2_SrcAddr,
1958 ETH_ADDRESSSIZE);
1959 CopyMem(buffer + ETH_PACKET_DEST, request->ios2_DstAddr,
1960 ETH_ADDRESSSIZE);
1961 request->ios2_PacketType = packet_type;
1963 /* Adjust for cooked packet request */
1965 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1967 packet_size -= ETH_PACKET_DATA;
1968 buffer += ETH_PACKET_DATA;
1970 #ifdef USE_HACKS
1971 else
1972 packet_size += 4; /* Needed for Shapeshifter & Fusion? */
1973 #endif
1974 request->ios2_DataLength = packet_size;
1976 /* Filter packet */
1978 opener = request->ios2_BufferManagement;
1979 if(request->ios2_Req.io_Command == CMD_READ &&
1980 opener->filter_hook != NULL)
1981 if(!CallHookPkt(opener->filter_hook, request, buffer))
1982 filtered = TRUE;
1984 if(!filtered)
1986 /* Copy packet into opener's buffer and reply packet */
1988 if(!opener->rx_function(request->ios2_Data, buffer, packet_size))
1990 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1991 request->ios2_WireError = S2WERR_BUFF_ERROR;
1992 ReportEvents(unit,
1993 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
1994 base);
1996 Remove((APTR)request);
1997 ReplyMsg((APTR)request);
2000 return;
2005 /****i* atheros5000.device/AddressFilter ***********************************
2007 * NAME
2008 * AddressFilter -- Determine if an RX packet should be accepted.
2010 * SYNOPSIS
2011 * accept = AddressFilter(unit, address)
2013 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
2015 ****************************************************************************
2019 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
2020 struct DevBase *base)
2022 struct AddressRange *range, *tail;
2023 BOOL accept = TRUE;
2024 ULONG address_left;
2025 UWORD address_right;
2027 /* Check whether address is unicast/broadcast or multicast */
2029 address_left = BELong(*((ULONG *)address));
2030 address_right = BEWord(*((UWORD *)(address + 4)));
2032 if(((address_left & 0x01000000) != 0) &&
2033 !((address_left == 0xffffffff) && (address_right == 0xffff)))
2035 /* Check if this multicast address is wanted */
2037 range = (APTR)unit->multicast_ranges.mlh_Head;
2038 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
2039 accept = FALSE;
2041 while((range != tail) && !accept)
2043 if((address_left > range->lower_bound_left ||
2044 address_left == range->lower_bound_left &&
2045 address_right >= range->lower_bound_right) &&
2046 (address_left < range->upper_bound_left ||
2047 address_left == range->upper_bound_left &&
2048 address_right <= range->upper_bound_right))
2049 accept = TRUE;
2050 range = (APTR)range->node.mln_Succ;
2053 if(!accept)
2054 unit->special_stats[S2SS_ETHERNET_BADMULTICAST & 0xffff]++;
2057 return accept;
2062 /****i* atheros5000.device/DistributeMgmtFrame *****************************
2064 * NAME
2065 * DistributeMgmtFrame -- Send a management frame to clients.
2067 * SYNOPSIS
2068 * DistributeMgmtFrame(unit, frame, frame_size)
2070 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
2072 ****************************************************************************
2076 static VOID DistributeMgmtFrame(struct DevUnit *unit, UBYTE *frame,
2077 UWORD frame_size, struct DevBase *base)
2079 struct IOSana2Req *request;
2080 struct Opener *opener, *opener_tail;
2082 /* Send packet to every opener */
2084 opener = (APTR)unit->openers.mlh_Head;
2085 opener_tail = (APTR)&unit->openers.mlh_Tail;
2087 while(opener != opener_tail)
2089 request = (APTR)RemHead(&opener->mgmt_port.mp_MsgList);
2091 if(request != NULL)
2093 /* Copy packet into opener's buffer and reply packet */
2095 if(frame_size <= request->ios2_DataLength)
2097 CopyMem(frame, request->ios2_Data, frame_size);
2098 request->ios2_DataLength = frame_size;
2100 else
2102 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
2103 request->ios2_WireError = S2WERR_BUFF_ERROR;
2104 ReportEvents(unit,
2105 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
2106 base);
2108 ReplyMsg((APTR)request);
2109 request =
2110 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2113 opener = (APTR)opener->node.mln_Succ;
2116 return;
2121 /****i* atheros5000.device/TXInt *******************************************
2123 * NAME
2124 * TXInt -- Soft interrupt for packet transmission.
2126 * SYNOPSIS
2127 * TXInt(unit)
2129 * VOID TXInt(struct DevUnit *);
2131 * FUNCTION
2133 * INPUTS
2134 * unit - A unit of this device.
2136 * RESULT
2137 * None.
2139 ****************************************************************************
2143 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2145 struct DevBase *base;
2146 UWORD i, frame_size, data_size, packet_type, body_size, slot, new_slot,
2147 last_slot, encryption, subtype, duration;
2148 UBYTE *buffer, *q, *plaintext, *ciphertext, *frame,
2149 mic_header[ETH_ADDRESSSIZE * 2];
2150 const UBYTE *p, *dest, *source;
2151 struct IOSana2Req *request;
2152 BOOL proceed = TRUE, is_ieee;
2153 struct Opener *opener;
2154 ULONG wire_error, dma_size;
2155 struct ath_desc *tx_desc, *last_desc;
2156 UBYTE *(*dma_tx_function)(REG(a0, APTR));
2157 BYTE error;
2158 struct MsgPort *port;
2159 struct TypeStats *tracker;
2160 const HAL_RATE_TABLE *rate_table;
2162 base = unit->device;
2163 port = unit->request_ports[WRITE_QUEUE];
2164 rate_table = unit->rate_table;
2166 while(proceed && (!IsMsgPortEmpty(port)))
2168 slot = unit->tx_in_slot;
2169 new_slot = (slot + 1) % TX_SLOT_COUNT;
2171 // if(new_slot != unit->tx_out_slot)
2172 if(slot == unit->tx_out_slot) // one packet at a time
2174 error = 0;
2175 body_size = 0;
2177 /* Get request and DMA frame descriptor */
2179 request = (APTR)port->mp_MsgList.lh_Head;
2181 Remove((APTR)request);
2182 unit->tx_requests[slot] = request;
2183 tx_desc = unit->tx_descs + slot;
2184 frame = unit->tx_buffers[slot];
2186 /* Get packet data */
2188 opener = request->ios2_BufferManagement;
2189 dma_tx_function = opener->dma_tx_function;
2190 if(dma_tx_function != NULL)
2191 buffer = dma_tx_function(request->ios2_Data);
2192 else
2193 buffer = NULL;
2195 if(buffer == NULL)
2197 buffer = unit->tx_buffer;
2198 if(!opener->tx_function(buffer, request->ios2_Data,
2199 request->ios2_DataLength))
2201 error = S2ERR_NO_RESOURCES;
2202 wire_error = S2WERR_BUFF_ERROR;
2203 ReportEvents(unit,
2204 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF
2205 | S2EVENT_TX, base);
2209 if(error == 0)
2211 /* Get packet type and/or length */
2213 data_size = request->ios2_DataLength;
2214 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2216 data_size -= ETH_PACKET_DATA;
2217 packet_type = BEWord(*(UWORD *)(buffer + ETH_PACKET_TYPE));
2219 else
2220 packet_type = request->ios2_PacketType;
2221 is_ieee = packet_type <= ETH_MTU;
2223 /* Determine encryption type and frame subtype */
2225 if(data_size > 0)
2227 encryption = unit->keys[unit->tx_key_no].type;
2228 subtype = 0;
2230 else
2232 encryption = S2ENC_NONE;
2233 subtype = 4;
2236 /* Get source and destination addresses */
2238 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2240 dest = buffer;
2241 source = buffer + ETH_ADDRESSSIZE;
2242 buffer += ETH_ADDRESSSIZE * 2 + 2;
2244 else
2246 dest = request->ios2_DstAddr;
2247 source = unit->address;
2250 /* Write 802.11 header */
2252 q = frame;
2253 *(UWORD *)q = MakeLEWord(
2254 (encryption == S2ENC_NONE ? 0 : WIFI_FRM_CONTROLF_WEP)
2255 | (unit->mode == S2PORT_ADHOC ? 0 : WIFI_FRM_CONTROLF_TODS)
2256 | subtype << WIFI_FRM_CONTROLB_SUBTYPE
2257 | WIFI_FRMTYPE_DATA << WIFI_FRM_CONTROLB_TYPE);
2258 q += 2;
2260 i = rate_table->rateCodeToIndex[unit->tx_rate_codes[0]];
2261 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2262 duration = rate_table->info[i].spAckDuration;
2263 else
2264 duration = rate_table->info[i].lpAckDuration;
2265 *(UWORD *)q = MakeLEWord(duration);
2266 q += 2;
2268 if(unit->mode == S2PORT_ADHOC)
2269 p = dest;
2270 else
2271 p = unit->bssid;
2272 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2273 *q++ = *p++;
2275 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2276 *q++ = *p++;
2278 if(unit->mode == S2PORT_ADHOC)
2279 p = unit->bssid;
2280 else
2281 p = dest;
2282 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2283 *q++ = *p++;
2284 *(UWORD *)q = 0;
2285 q += 2;
2287 // TO DO: need to pad header to 4-byte boundary?
2289 /* Leave room for encryption overhead */
2291 ciphertext = q;
2292 q += unit->iv_sizes[encryption];
2293 plaintext = q;
2295 /* Write SNAP header */
2297 if(!is_ieee)
2299 for(i = 0, p = snap_template;
2300 i < SNAP_FRM_TYPE; i++)
2301 *q++ = *p++;
2302 *(UWORD *)q = MakeBEWord(packet_type);
2303 q += 2;
2304 body_size += SNAP_HEADERSIZE;
2307 /* Copy data into frame */
2309 CopyMem(buffer, q, data_size);
2310 body_size += data_size;
2312 /* Append MIC to frame for TKIP */
2314 if(encryption == S2ENC_TKIP)
2316 // if((unit->flags & UNITF_HARDMIC) == 0)
2318 q = mic_header;
2319 for(i = 0, p = dest; i < ETH_ADDRESSSIZE; i++)
2320 *q++ = *p++;
2321 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2322 *q++ = *p++;
2323 TKIPEncryptFrame(unit, mic_header, plaintext, body_size,
2324 plaintext, base);
2326 body_size += MIC_SIZE;
2329 /* Encrypt fragment if applicable */
2331 unit->fragment_encrypt_functions[encryption](unit, frame,
2332 plaintext, &body_size, ciphertext, base);
2334 /* Fill in DMA descriptor for packet transmission */
2336 frame_size = WIFI_FRM_DATA + body_size;
2337 tx_desc->ds_link = (ULONG)(UPINT)NULL;
2338 unit->hal->ah_setupTxDesc(unit->hal, tx_desc, frame_size + 4, // + CRC?
2339 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2340 ((unit->flags & UNITF_SLOWRETRIES) != 0) ?
2341 unit->tx_rate_codes[0] : unit->tx_rate_codes[1],
2342 ((unit->flags & UNITF_SLOWRETRIES) != 0) ? 1 : TX_TRIES,
2343 HAL_TXKEYIX_INVALID,
2344 HAL_ANTENNA_MIN_MODE,
2345 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK,
2346 0, 0, 0, 0, 3);
2347 if((unit->flags & UNITF_SLOWRETRIES) != 0)
2348 unit->hal->ah_setupXTxDesc(unit->hal, tx_desc,
2349 unit->tx_rate_codes[1], 1,
2350 unit->tx_rate_codes[2], 1,
2351 unit->tx_rate_codes[3], TX_TRIES - 3);
2352 unit->hal->ah_fillTxDesc(unit->hal, tx_desc, frame_size, TRUE, TRUE,
2353 tx_desc);
2355 dma_size = frame_size;
2356 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2358 /* Pass packet to adapter */
2360 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2361 last_slot = (slot + TX_SLOT_COUNT - 1) % TX_SLOT_COUNT;
2362 if(unit->tx_out_slot != slot)
2363 //if(unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no) > 0)
2365 last_desc =
2366 unit->tx_descs + last_slot;
2367 last_desc->ds_link = unit->tx_descs_p + slot * sizeof(struct ath_desc);
2368 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2369 CachePreDMA(unit->tx_descs, &dma_size, 0);
2371 else
2373 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2374 CachePreDMA(unit->tx_descs, &dma_size, 0);
2375 unit->hal->ah_setTxDP(unit->hal, unit->tx_queue_no,
2376 unit->tx_descs_p + slot * sizeof(struct ath_desc));
2379 unit->hal->ah_startTxDma(unit->hal, unit->tx_queue_no);
2380 unit->tx_in_slot = new_slot;
2382 else
2384 /* Reply failed request */
2386 request->ios2_Req.io_Error = error;
2387 request->ios2_WireError = wire_error;
2388 ReplyMsg((APTR)request);
2391 /* Update statistics */
2393 if(error == 0)
2395 unit->stats.PacketsSent++;
2397 tracker = FindTypeStats(unit, &unit->type_trackers,
2398 request->ios2_PacketType, base);
2399 if(tracker != NULL)
2401 tracker->stats.PacketsSent++;
2402 tracker->stats.BytesSent += ETH_HEADERSIZE + data_size;
2406 else
2407 proceed = FALSE;
2410 /* Don't try to keep sending packets if there's no space left */
2412 if(proceed)
2413 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
2414 else
2415 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_IGNORE;
2417 return;
2422 /****i* atheros5000.device/TXEndInt ****************************************
2424 * NAME
2425 * TXEndInt -- Clean up after a data frame has been sent.
2427 * SYNOPSIS
2428 * TXEndInt(unit, int_code)
2430 * VOID TXEndInt(struct DevUnit *, APTR);
2432 * NOTES
2433 * I think it's safe to assume that there will always be at least one
2434 * completed packet whenever this interrupt is called.
2436 ****************************************************************************
2440 static VOID TXEndInt(REG(a1, struct DevUnit *unit),
2441 REG(a6, APTR int_code))
2443 UWORD frame_size, new_out_slot, i;
2444 UBYTE *frame;
2445 struct DevBase *base;
2446 struct IOSana2Req *request;
2447 ULONG dma_size;
2448 struct TypeStats *tracker;
2450 /* Find out which packets have completed */
2452 base = unit->device;
2453 new_out_slot = (unit->tx_in_slot + TX_SLOT_COUNT
2454 - unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no))
2455 % TX_SLOT_COUNT;
2457 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2458 CachePostDMA(unit->tx_descs, &dma_size, 0);
2460 /* Retire sent packets */
2462 for(i = unit->tx_out_slot; i != new_out_slot;
2463 i = (i + 1) % TX_SLOT_COUNT)
2465 frame = unit->tx_buffers[i];
2466 dma_size = FRAME_BUFFER_SIZE;
2467 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2469 /* Update statistics */
2471 request = unit->tx_requests[i];
2472 frame_size = request->ios2_DataLength;
2473 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
2474 frame_size += ETH_HEADERSIZE;
2476 tracker = FindTypeStats(unit, &unit->type_trackers,
2477 request->ios2_PacketType, base);
2478 if(tracker != NULL)
2480 tracker->stats.PacketsSent++;
2481 tracker->stats.BytesSent += frame_size;
2484 /* Reply request */
2486 request->ios2_Req.io_Error = 0;
2487 ReplyMsg((APTR)request);
2490 unit->tx_out_slot = i;
2492 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2493 CachePreDMA(unit->tx_descs, &dma_size, 0);
2495 /* Restart downloads if they had stopped */
2497 if(unit->request_ports[WRITE_QUEUE]->mp_Flags == PA_IGNORE)
2498 Cause(&unit->tx_int);
2500 return;
2505 /****i* atheros5000.device/MgmtTXInt ***************************************
2507 * NAME
2508 * MgmtTXInt -- Soft interrupt for management frame transmission.
2510 * SYNOPSIS
2511 * MgmtTXInt(unit)
2513 * VOID MgmtTXInt(struct DevUnit *);
2515 * FUNCTION
2517 * INPUTS
2518 * unit - A unit of this device.
2520 * RESULT
2521 * None.
2523 ****************************************************************************
2527 static VOID MgmtTXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2529 struct DevBase *base;
2530 UWORD frame_size, slot, new_slot, last_slot, i, duration;
2531 UBYTE *frame;
2532 struct IOSana2Req *request;
2533 BOOL proceed = TRUE, has_bssid;
2534 ULONG dma_size;
2535 struct ath_desc *desc, *last_desc;
2536 struct MsgPort *port;
2537 const HAL_RATE_TABLE *rate_table;
2539 base = unit->device;
2540 port = unit->request_ports[MGMT_QUEUE];
2541 rate_table = unit->rate_table;
2543 while(proceed && (!IsMsgPortEmpty(port)))
2545 slot = unit->mgmt_in_slot;
2546 new_slot = (slot + 1) % MGMT_SLOT_COUNT;
2548 // if(new_slot != unit->mgmt_out_slot)
2549 if(slot == unit->mgmt_out_slot) // one packet at a time
2551 /* Get request and DMA frame descriptor */
2553 request = (APTR)port->mp_MsgList.lh_Head;
2555 Remove((APTR)request);
2556 unit->mgmt_requests[slot] = request;
2557 desc = unit->mgmt_descs + slot;
2558 frame = unit->mgmt_buffers[slot];
2560 /* Get packet length */
2562 frame_size = request->ios2_DataLength;
2564 /* Copy frame into DMA buffer */
2566 CopyMem(request->ios2_Data, frame, frame_size);
2568 /* Set duration */
2570 has_bssid = ((frame + WIFI_FRM_ADDRESS1)[0] & 0x1) == 0;
2571 i = rate_table->rateCodeToIndex[unit->mgmt_rate_code];
2572 if(has_bssid)
2574 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2575 duration = rate_table->info[i].spAckDuration;
2576 else
2577 duration = rate_table->info[i].lpAckDuration;
2579 else
2580 duration = 0;
2581 *(UWORD *)(frame + WIFI_FRM_DURATION) = MakeLEWord(duration);
2583 /* Fill in DMA descriptor for packet transmission */
2585 desc->ds_link = (ULONG)(UPINT)NULL;
2586 unit->hal->ah_setupTxDesc(unit->hal, desc, frame_size + 4, // + CRC?
2587 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2588 unit->mgmt_rate_code, TX_TRIES, HAL_TXKEYIX_INVALID,
2589 HAL_ANTENNA_MIN_MODE,
2590 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK
2591 | (has_bssid ? 0 : HAL_TXDESC_NOACK),
2592 0, 0, 0, 0, 3);
2593 unit->hal->ah_fillTxDesc(unit->hal, desc, frame_size, TRUE, TRUE,
2594 desc);
2596 dma_size = frame_size;
2597 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2599 /* Pass packet to adapter */
2601 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2602 last_slot = (slot + MGMT_SLOT_COUNT - 1) % MGMT_SLOT_COUNT;
2603 if(unit->mgmt_out_slot != slot)
2604 //if(unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no) > 0)
2606 last_desc = unit->mgmt_descs + last_slot;
2607 last_desc->ds_link =
2608 unit->mgmt_descs_p + slot * sizeof(struct ath_desc);
2609 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2610 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2612 else
2614 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2615 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2616 unit->hal->ah_setTxDP(unit->hal, unit->mgmt_queue_no,
2617 unit->mgmt_descs_p + slot * sizeof(struct ath_desc));
2620 unit->hal->ah_startTxDma(unit->hal, unit->mgmt_queue_no);
2621 unit->mgmt_in_slot = new_slot;
2623 else
2624 proceed = FALSE;
2627 /* Don't try to keep sending packets if there's no space left */
2629 if(proceed)
2630 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
2631 else
2632 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_IGNORE;
2634 return;
2639 /****i* atheros5000.device/MgmtTXEndInt ************************************
2641 * NAME
2642 * MgmtTXEndInt -- Clean up after a management frame has been sent.
2644 * SYNOPSIS
2645 * MgmtTXEndInt(unit, int_code)
2647 * VOID MgmtTXEndInt(struct DevUnit *, APTR);
2649 * NOTES
2650 * I think it's safe to assume that there will always be at least one
2651 * completed packet whenever this interrupt is called.
2653 ****************************************************************************
2657 static VOID MgmtTXEndInt(REG(a1, struct DevUnit *unit),
2658 REG(a6, APTR int_code))
2660 UWORD new_out_slot, i;
2661 UBYTE *frame;
2662 struct DevBase *base;
2663 struct IOSana2Req *request;
2664 ULONG dma_size;
2666 /* Find out which packets have completed */
2668 base = unit->device;
2669 new_out_slot = (unit->mgmt_in_slot + MGMT_SLOT_COUNT
2670 - unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no))
2671 % MGMT_SLOT_COUNT;
2673 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2674 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
2676 /* Retire sent frames */
2678 for(i = unit->mgmt_out_slot; i != new_out_slot;
2679 i = (i + 1) % MGMT_SLOT_COUNT)
2681 frame = unit->mgmt_buffers[i];
2682 dma_size = FRAME_BUFFER_SIZE;
2683 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2685 /* Reply request */
2687 request = unit->mgmt_requests[i];
2688 request->ios2_Req.io_Error = 0;
2689 ReplyMsg((APTR)request);
2692 unit->mgmt_out_slot = i;
2694 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2695 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2697 /* Restart downloads if they had stopped */
2699 if(unit->request_ports[MGMT_QUEUE]->mp_Flags == PA_IGNORE)
2700 Cause(&unit->mgmt_int);
2702 return;
2707 /****i* atheros5000.device/ResetHandler ************************************
2709 * NAME
2710 * ResetHandler -- Disable hardware before a reboot.
2712 * SYNOPSIS
2713 * ResetHandler(unit, int_code)
2715 * VOID ResetHandler(struct DevUnit *, APTR);
2717 ****************************************************************************
2721 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
2722 REG(a6, APTR int_code))
2724 if((unit->flags & UNITF_HAVEADAPTER) != 0)
2726 /* Disable frame transmission */
2728 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2729 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2731 /* Disable frame reception */
2733 unit->hal->ah_stopPcuReceive(unit->hal);
2734 unit->hal->ah_stopDmaReceive(unit->hal);
2736 /* Stop interrupts */
2738 unit->hal->ah_setInterrupts(unit->hal, 0);
2741 return;
2746 /****i* atheros5000.device/UpdateStats *************************************
2748 * NAME
2749 * UpdateStats
2751 * SYNOPSIS
2752 * UpdateStats(unit)
2754 * VOID UpdateStats(struct DevUnit *);
2756 * FUNCTION
2758 * INPUTS
2759 * unit - A unit of this device.
2761 * RESULT
2762 * None.
2764 ****************************************************************************
2768 VOID UpdateStats(struct DevUnit *unit, struct DevBase *base)
2770 /* Ask for and wait for stats */
2772 return;
2777 /****i* atheros5000.device/ReportEvents ************************************
2779 * NAME
2780 * ReportEvents
2782 * SYNOPSIS
2783 * ReportEvents(unit, events)
2785 * VOID ReportEvents(struct DevUnit *, ULONG);
2787 * FUNCTION
2789 * INPUTS
2790 * unit - A unit of this device.
2791 * events - A mask of events to report.
2793 * RESULT
2794 * None.
2796 ****************************************************************************
2800 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
2801 struct DevBase *base)
2803 struct IOSana2Req *request, *tail, *next_request;
2804 struct List *list;
2806 list = &unit->request_ports[EVENT_QUEUE]->mp_MsgList;
2807 next_request = (APTR)list->lh_Head;
2808 tail = (APTR)&list->lh_Tail;
2810 Disable();
2811 while(next_request != tail)
2813 request = next_request;
2814 next_request = (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2816 if((request->ios2_WireError & events) != 0)
2818 request->ios2_WireError = events;
2819 Remove((APTR)request);
2820 ReplyMsg((APTR)request);
2823 Enable();
2825 return;
2830 /****i* atheros5000.device/GetRadioBands ***********************************
2832 * NAME
2833 * GetRadioBands -- Get information on current network.
2835 * SYNOPSIS
2836 * tag_list = GetRadioBands(unit, pool)
2838 * struct TagItem *GetRadioBands(struct DevUnit *, APTR);
2840 * FUNCTION
2842 * INPUTS
2843 * unit - A unit of this device.
2844 * pool - A memory pool.
2846 * RESULT
2847 * None.
2849 ****************************************************************************
2853 #if 0
2854 struct TagItem *GetRadioBands(struct DevUnit *unit, APTR pool,
2855 struct DevBase *base)
2857 BYTE error = 0;
2858 struct Sana2RadioBand *bands;
2859 UWORD i;
2861 bands = AllocPooled(pool, sizeof(struct Sana2RadioBand) * 3);
2862 if(bands == NULL)
2863 error = S2ERR_NO_RESOURCES;
2865 if(error == 0)
2867 for(i = 0; i < 1; i++)
2869 bands[i] = AllocPooled(pool, sizeof(UWORD) * unit->channel_counts[S2BAND_B]);
2873 // if(error != 0)
2874 // bands = NULL;
2876 return bands;
2878 #endif
2882 /****i* atheros5000.device/UnitTask ****************************************
2884 * NAME
2885 * UnitTask
2887 * SYNOPSIS
2888 * UnitTask()
2890 * VOID UnitTask();
2892 * FUNCTION
2893 * Completes deferred requests, and handles card insertion and removal
2894 * in conjunction with the relevant interrupts.
2896 ****************************************************************************
2900 #ifdef __MORPHOS__
2901 #undef UnitTask
2902 #endif
2904 static VOID UnitTask(struct ExecBase *sys_base)
2906 struct Task *task;
2907 struct IORequest *request;
2908 struct DevUnit *unit;
2909 struct DevBase *base;
2910 struct MsgPort *general_port;
2911 ULONG signals = 0, wait_signals, card_removed_signal,
2912 card_inserted_signal, general_port_signal;
2914 /* Get parameters */
2916 task = AbsExecBase->ThisTask;
2917 unit = task->tc_UserData;
2918 base = unit->device;
2920 /* Activate general request port */
2922 general_port = unit->request_ports[GENERAL_QUEUE];
2923 general_port->mp_SigTask = task;
2924 general_port->mp_SigBit = AllocSignal(-1);
2925 general_port_signal = 1 << general_port->mp_SigBit;
2926 general_port->mp_Flags = PA_SIGNAL;
2928 /* Allocate signals for notification of card removal and insertion */
2930 card_removed_signal = unit->card_removed_signal = 1 << AllocSignal(-1);
2931 card_inserted_signal = unit->card_inserted_signal = 1 << AllocSignal(-1);
2932 wait_signals = (1 << general_port->mp_SigBit) | card_removed_signal
2933 | card_inserted_signal | SIGBREAKF_CTRL_C;
2935 /* Tell ourselves to check port for old messages */
2937 Signal(task, general_port_signal);
2939 /* Infinite loop to service requests and signals */
2941 while((signals & SIGBREAKF_CTRL_C) == 0)
2943 signals = Wait(wait_signals);
2945 if((signals & card_inserted_signal) != 0)
2947 if(unit->insertion_function(unit->card, base))
2949 unit->flags |= UNITF_HAVEADAPTER;
2950 if((unit->flags & UNITF_CONFIGURED) != 0)
2951 ConfigureAdapter(unit, base);
2952 if((unit->flags & UNITF_WASONLINE) != 0)
2954 GoOnline(unit, base);
2955 unit->flags &= ~UNITF_WASONLINE;
2960 if((signals & card_removed_signal) != 0)
2962 unit->removal_function(unit->card, base);
2963 if((unit->flags & UNITF_WASONLINE) != 0)
2964 GoOffline(unit, base);
2967 if((signals & general_port_signal) != 0)
2969 while((request = (APTR)GetMsg(general_port)) != NULL)
2971 /* Service the request as soon as the unit is free */
2973 ObtainSemaphore(&unit->access_lock);
2974 ServiceRequest((APTR)request, base);
2979 FreeMem(task->tc_SPLower, STACK_SIZE);