Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / atheros5000 / unit.c
blob7c591fbda674118f0a70b7651b67b4dd11eaf9d9
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 #if !defined(__AROS__)
95 static const UBYTE broadcast_address[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
96 #endif
97 static const ULONG g_retry_rates[] = {54000, 36000, 18000, 2000};
98 static const ULONG b_retry_rates[] = {11000, 5500, 2000, 1000};
101 #ifdef __amigaos4__
102 #undef AddTask
103 #define AddTask(task, initial_pc, final_pc) \
104 IExec->AddTask(task, initial_pc, final_pc, NULL)
105 #endif
106 #ifdef __MORPHOS__
107 static const struct EmulLibEntry mos_task_trap =
109 TRAP_LIB,
111 (APTR)UnitTask
113 #define UnitTask &mos_task_trap
114 #endif
115 #ifdef __AROS__
116 #undef AddTask
117 #define AddTask(task, initial_pc, final_pc) \
118 ({ \
119 struct TagItem _task_tags[] = \
120 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
121 NewAddTask(task, initial_pc, final_pc, _task_tags); \
123 #endif
127 /****i* atheros5000.device/CreateUnit **************************************
129 * NAME
130 * CreateUnit -- Create a unit.
132 * SYNOPSIS
133 * unit = CreateUnit(index, io_base, id, card,
134 * io_tags, bus)
136 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
137 * struct TagItem *, UWORD);
139 * FUNCTION
140 * Creates a new unit.
142 ****************************************************************************
146 struct DevUnit *CreateUnit(ULONG index, APTR io_base, UWORD id, APTR card,
147 struct TagItem *io_tags, UWORD bus, struct DevBase *base)
149 BOOL success = TRUE;
150 struct DevUnit *unit;
151 struct Task *task;
152 struct MsgPort *port;
153 UWORD i;
154 struct ath_desc *tx_desc, *rx_desc;
155 ULONG dma_size;
156 APTR stack;
157 HAL_STATUS hal_status;
159 unit = AllocMem(sizeof(struct DevUnit), MEMF_CLEAR | MEMF_PUBLIC);
160 if(unit == NULL)
161 success = FALSE;
163 if(success)
165 /* Initialise lists etc. */
167 NewList((APTR)&unit->openers);
168 NewList((APTR)&unit->type_trackers);
169 NewList((APTR)&unit->multicast_ranges);
171 unit->index = index;
172 unit->device = base;
173 unit->card = card;
174 unit->bus = bus;
176 /* Store DMA memory hooks */
178 unit->AllocDMAMem =
179 (APTR)GetTagData(IOTAG_AllocDMAMem, (UPINT)NULL, io_tags);
180 unit->FreeDMAMem =
181 (APTR)GetTagData(IOTAG_FreeDMAMem, (UPINT)NULL, io_tags);
182 if(unit->AllocDMAMem == NULL || unit->FreeDMAMem == NULL)
183 success = FALSE;
186 if(success)
188 /* Initialise HAL */
190 unit->hal = ath_hal_attach(id, unit, NULL, io_base, &hal_status);
192 if(unit->hal == NULL)
193 success = FALSE;
196 if(success)
198 InitSemaphore(&unit->access_lock);
200 /* Create the message ports for queuing requests */
202 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
204 unit->request_ports[i] = port = AllocMem(sizeof(struct MsgPort),
205 MEMF_PUBLIC | MEMF_CLEAR);
206 if(port == NULL)
207 success = FALSE;
209 if(success)
211 NewList(&port->mp_MsgList);
212 port->mp_Flags = PA_IGNORE;
216 if(success)
218 unit->request_ports[WRITE_QUEUE]->mp_SigTask = &unit->tx_int;
219 unit->request_ports[MGMT_QUEUE]->mp_SigTask = &unit->mgmt_int;
222 /* Allocate buffers and descriptors */
224 unit->tx_buffer = AllocVec(ETH_MAXPACKETSIZE, MEMF_PUBLIC);
225 for(i = 0; i < TX_SLOT_COUNT; i++)
227 unit->tx_buffers[i] =
228 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
229 if(unit->tx_buffers[i] == NULL)
230 success = FALSE;
232 for(i = 0; i < MGMT_SLOT_COUNT; i++)
234 unit->mgmt_buffers[i] =
235 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
236 if(unit->mgmt_buffers[i] == NULL)
237 success = FALSE;
239 unit->rx_buffer = AllocVec(FRAME_BUFFER_SIZE, MEMF_PUBLIC);
240 for(i = 0; i < RX_SLOT_COUNT; i++)
242 unit->rx_buffers[i] =
243 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
244 if(unit->rx_buffers[i] == NULL)
245 success = FALSE;
247 unit->rx_frames =
248 AllocVec(FRAME_BUFFER_SIZE * FRAME_BUFFER_COUNT, MEMF_PUBLIC);
249 for(i = 0; i < FRAME_BUFFER_COUNT; i++)
250 unit->rx_fragment_nos[i] = -1;
251 unit->tx_descs = unit->AllocDMAMem(unit->card,
252 sizeof(struct ath_desc) * TX_SLOT_COUNT, 4);
253 unit->mgmt_descs = unit->AllocDMAMem(unit->card,
254 sizeof(struct ath_desc) * MGMT_SLOT_COUNT, 4);
255 unit->rx_descs = unit->AllocDMAMem(unit->card,
256 sizeof(struct ath_desc) * RX_SLOT_COUNT, 4);
257 unit->tx_requests = AllocVec(sizeof(APTR) * TX_SLOT_COUNT,
258 MEMF_PUBLIC);
259 unit->mgmt_requests = AllocVec(sizeof(APTR) * MGMT_SLOT_COUNT,
260 MEMF_PUBLIC);
261 unit->channels = AllocVec(sizeof(HAL_CHANNEL) * MAX_CHANNEL_COUNT,
262 MEMF_PUBLIC | MEMF_CLEAR);
263 if(unit->tx_buffer == NULL
264 || unit->rx_buffer == NULL
265 || unit->rx_frames == NULL
266 || unit->tx_descs == NULL
267 || unit->mgmt_descs == NULL
268 || unit->rx_descs == NULL
269 || unit->tx_requests == NULL
270 || unit->mgmt_requests == NULL
271 || unit->channels == NULL)
272 success = FALSE;
275 if(success)
277 /* Initialise network adapter hardware */
279 success = InitialiseAdapter(unit, FALSE, base);
280 unit->flags |= UNITF_HAVEADAPTER;
283 if(success)
285 /* Get physical addresses of DMA structures */
287 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
288 unit->tx_descs_p =
289 (ULONG)(UPINT)CachePreDMA(unit->tx_descs, &dma_size, 0);
290 if(dma_size != sizeof(struct ath_desc) * TX_SLOT_COUNT)
291 success = FALSE;
292 CachePostDMA(unit->tx_descs, &dma_size, 0);
294 for(i = 0; i < TX_SLOT_COUNT; i++)
296 dma_size = FRAME_BUFFER_SIZE;
297 unit->tx_buffers_p[i] =
298 (ULONG)(UPINT)CachePreDMA(unit->tx_buffers[i], &dma_size, 0);
299 if(dma_size != FRAME_BUFFER_SIZE)
300 success = FALSE;
301 CachePostDMA(unit->tx_buffers[i], &dma_size, 0);
304 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
305 unit->mgmt_descs_p =
306 (ULONG)(UPINT)CachePreDMA(unit->mgmt_descs, &dma_size, 0);
307 if(dma_size != sizeof(struct ath_desc) * MGMT_SLOT_COUNT)
308 success = FALSE;
309 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
311 for(i = 0; i < MGMT_SLOT_COUNT; i++)
313 dma_size = FRAME_BUFFER_SIZE;
314 unit->mgmt_buffers_p[i] =
315 (ULONG)(UPINT)CachePreDMA(unit->mgmt_buffers[i], &dma_size, 0);
316 if(dma_size != FRAME_BUFFER_SIZE)
317 success = FALSE;
318 CachePostDMA(unit->mgmt_buffers[i], &dma_size, 0);
321 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
322 unit->rx_descs_p =
323 (ULONG)(UPINT)CachePreDMA(unit->rx_descs, &dma_size, 0);
324 if(dma_size != sizeof(struct ath_desc) * RX_SLOT_COUNT)
325 success = FALSE;
326 CachePostDMA(unit->rx_descs, &dma_size, 0);
328 for(i = 0; i < RX_SLOT_COUNT; i++)
330 dma_size = FRAME_BUFFER_SIZE;
331 unit->rx_buffers_p[i] =
332 (ULONG)(UPINT)CachePreDMA(unit->rx_buffers[i], &dma_size, 0);
333 if(dma_size != FRAME_BUFFER_SIZE)
334 success = FALSE;
335 CachePostDMA(unit->rx_buffers[i], &dma_size, 0);
338 /* Construct TX ring */
340 for(tx_desc = unit->tx_descs, i = 0; i < TX_SLOT_COUNT; i++)
342 tx_desc->ds_data = unit->tx_buffers_p[i];
343 tx_desc++;
346 /* Construct management frame TX ring */
348 for(tx_desc = unit->mgmt_descs, i = 0; i < MGMT_SLOT_COUNT; i++)
350 tx_desc->ds_data = unit->mgmt_buffers_p[i];
351 tx_desc++;
354 /* Construct RX ring */
356 for(rx_desc = unit->rx_descs, i = 0; i < RX_SLOT_COUNT; i++)
358 rx_desc->ds_link = unit->rx_descs_p + ((i + 1) % RX_SLOT_COUNT)
359 * sizeof(struct ath_desc);
360 rx_desc->ds_data = unit->rx_buffers_p[i];
361 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
362 HAL_RXDESC_INTREQ);
363 rx_desc++;
366 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
367 CachePreDMA(unit->rx_descs, &dma_size, 0);
369 /* Record maximum speed in BPS */
371 unit->speed = 54000000;
373 /* Initialise status, transmit, receive and stats interrupts */
375 unit->status_int.is_Node.ln_Name =
376 base->device.dd_Library.lib_Node.ln_Name;
377 unit->status_int.is_Code = (APTR)StatusInt;
378 unit->status_int.is_Data = unit;
380 unit->rx_int.is_Node.ln_Name =
381 base->device.dd_Library.lib_Node.ln_Name;
382 unit->rx_int.is_Code = (APTR)RXInt;
383 unit->rx_int.is_Data = unit;
385 unit->tx_int.is_Node.ln_Name =
386 base->device.dd_Library.lib_Node.ln_Name;
387 unit->tx_int.is_Code = (APTR)TXInt;
388 unit->tx_int.is_Data = unit;
390 unit->tx_end_int.is_Node.ln_Name =
391 base->device.dd_Library.lib_Node.ln_Name;
392 unit->tx_end_int.is_Code = (APTR)TXEndInt;
393 unit->tx_end_int.is_Data = unit;
395 unit->mgmt_int.is_Node.ln_Name =
396 base->device.dd_Library.lib_Node.ln_Name;
397 unit->mgmt_int.is_Code = (APTR)MgmtTXInt;
398 unit->mgmt_int.is_Data = unit;
400 unit->mgmt_end_int.is_Node.ln_Name =
401 base->device.dd_Library.lib_Node.ln_Name;
402 unit->mgmt_end_int.is_Code = (APTR)MgmtTXEndInt;
403 unit->mgmt_end_int.is_Data = unit;
405 unit->reset_handler.is_Node.ln_Name =
406 base->device.dd_Library.lib_Node.ln_Name;
407 unit->reset_handler.is_Code = (APTR)ResetHandler;
408 unit->reset_handler.is_Data = unit;
410 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
411 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
413 /* Create a new task */
415 unit->task = task =
416 AllocMem(sizeof(struct Task), MEMF_PUBLIC | MEMF_CLEAR);
417 if(task == NULL)
418 success = FALSE;
421 if(success)
423 stack = AllocMem(STACK_SIZE, MEMF_PUBLIC);
424 if(stack == NULL)
425 success = FALSE;
428 if(success)
430 /* Initialise and start task */
432 task->tc_Node.ln_Type = NT_TASK;
433 task->tc_Node.ln_Pri = TASK_PRIORITY;
434 task->tc_Node.ln_Name = base->device.dd_Library.lib_Node.ln_Name;
435 task->tc_SPUpper = stack + STACK_SIZE;
436 task->tc_SPLower = stack;
437 task->tc_SPReg = stack + STACK_SIZE;
438 NewList(&task->tc_MemEntry);
440 if(AddTask(task, UnitTask, NULL) == NULL)
441 success = FALSE;
444 if(success)
446 /* Send the unit to the new task */
448 task->tc_UserData = unit;
450 /* Set default wireless options */
452 unit->mode = S2PORT_MANAGED;
455 if(!success)
457 DeleteUnit(unit, base);
458 unit = NULL;
461 return unit;
466 /****i* atheros5000.device/DeleteUnit **************************************
468 * NAME
469 * DeleteUnit -- Delete a unit.
471 * SYNOPSIS
472 * DeleteUnit(unit)
474 * VOID DeleteUnit(struct DevUnit *);
476 * FUNCTION
477 * Deletes a unit.
479 * INPUTS
480 * unit - Device unit (may be NULL).
482 * RESULT
483 * None.
485 ****************************************************************************
489 VOID DeleteUnit(struct DevUnit *unit, struct DevBase *base)
491 UBYTE i;
492 struct Task *task;
494 if(unit != NULL)
496 task = unit->task;
497 if(task != NULL)
499 if(task->tc_UserData != NULL)
501 RemTask(task);
502 FreeMem(task->tc_SPLower, STACK_SIZE);
503 Signal(unit->task, SIGBREAKF_CTRL_C);
505 FreeMem(task, sizeof(struct Task));
508 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
510 if(unit->request_ports[i] != NULL)
511 FreeMem(unit->request_ports[i], sizeof(struct MsgPort));
514 if((unit->flags & UNITF_ONLINE) != 0) /* Needed! */
515 GoOffline(unit, base);
517 for(i = 0; i < TX_SLOT_COUNT; i++)
518 unit->FreeDMAMem(unit->card, unit->tx_buffers[i]);
519 for(i = 0; i < MGMT_SLOT_COUNT; i++)
520 unit->FreeDMAMem(unit->card, unit->mgmt_buffers[i]);
521 for(i = 0; i < RX_SLOT_COUNT; i++)
522 unit->FreeDMAMem(unit->card, unit->rx_buffers[i]);
524 FreeVec(unit->tx_buffer);
525 FreeVec(unit->rx_frames);
526 FreeVec(unit->tx_requests);
527 FreeVec(unit->mgmt_requests);
528 FreeVec(unit->channels);
529 FreeVec(unit->rx_buffer);
531 if(unit->hal != NULL)
532 unit->hal->ah_detach(unit->hal);
534 FreeMem(unit, sizeof(struct DevUnit));
537 return;
542 /****i* atheros5000.device/InitialiseAdapter *******************************
544 * NAME
545 * InitialiseAdapter
547 * SYNOPSIS
548 * success = InitialiseAdapter(unit, reinsertion)
550 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
552 * FUNCTION
554 * INPUTS
555 * unit
556 * reinsertion
558 * RESULT
559 * success - Success indicator.
561 ****************************************************************************
565 BOOL InitialiseAdapter(struct DevUnit *unit, BOOL reinsertion,
566 struct DevBase *base)
568 UBYTE i, reg_class_id;
569 BOOL success = TRUE;
570 unsigned int channel_count, reg_class_count;
571 HAL_TXQ_INFO queue_info = {0};
573 /* Get default MAC address */
575 unit->hal->ah_getMacAddress(unit->hal, unit->default_address);
577 /* Get default antenna */
579 unit->antenna = unit->hal->ah_getDefAntenna(unit->hal);
581 /* Reset key cache */
583 for(i = 0; i < WIFI_KEYCOUNT; i++)
584 unit->hal->ah_resetKeyCacheEntry(unit->hal, i);
586 /* Initialise channels and rates */
588 ath_hal_init_channels(unit->hal, unit->channels,
589 MAX_CHANNEL_COUNT, &channel_count,
590 &reg_class_id, 1, &reg_class_count, CTRY_DEFAULT,
591 HAL_MODE_11B | HAL_MODE_PUREG, TRUE,
592 FALSE);
593 unit->channel_count = channel_count;
595 unit->channel = 1;
596 unit->band = S2BAND_B;
598 /* Check if multi-rate retries are supported */
600 if(unit->hal->ah_setupXTxDesc(unit->hal, NULL, 0, 0, 0, 0, 0, 0))
601 unit->flags |= UNITF_SLOWRETRIES;
603 /* Set up TX queue */
605 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
606 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
607 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
608 queue_info.tqi_qflags =
609 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
611 unit->tx_queue_no =
612 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
613 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
615 /* Set up management frame TX queue */
617 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
618 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
619 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
620 queue_info.tqi_qflags =
621 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
623 unit->mgmt_queue_no =
624 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
625 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
627 /* Find out hardware encryption capabilities */
629 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
630 HAL_CIPHER_WEP, NULL) == HAL_OK)
631 unit->flags |= UNITF_HARDWEP;
632 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
633 HAL_CIPHER_TKIP, NULL) == HAL_OK)
634 unit->flags |= UNITF_HARDTKIP;
635 #if 1
636 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
637 HAL_CIPHER_MIC, NULL) == HAL_OK)
639 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
640 // 0, TRUE, NULL))
641 0, 0, NULL))
642 unit->flags |= UNITF_HARDMIC;
644 #else
645 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
646 0, FALSE, NULL))
647 #endif
648 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_TKIP_SPLIT, 0,
649 NULL) == HAL_OK)
650 unit->flags |= UNITF_SPLITMIC;
651 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
652 HAL_CIPHER_AES_OCB, NULL) == HAL_OK)
653 unit->flags |= UNITF_HARDAESOCB;
654 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
655 HAL_CIPHER_AES_CCM, NULL) == HAL_OK)
656 unit->flags |= UNITF_HARDCCMP;
658 /* Set IV sizes */
660 unit->iv_sizes[S2ENC_WEP] = IV_SIZE;
661 unit->iv_sizes[S2ENC_TKIP] = EIV_SIZE;
662 unit->iv_sizes[S2ENC_CCMP] = EIV_SIZE;
664 /* Set encryption functions */
666 unit->fragment_encrypt_functions[S2ENC_NONE] = WriteClearFragment;
668 if((unit->flags & UNITF_HARDWEP) != 0)
669 unit->fragment_encrypt_functions[S2ENC_WEP] = WriteWEPFragment;
670 else
671 unit->fragment_encrypt_functions[S2ENC_WEP] = EncryptWEPFragment;
673 if((unit->flags & UNITF_HARDTKIP) != 0)
674 unit->fragment_encrypt_functions[S2ENC_TKIP] = WriteTKIPFragment;
675 else
676 unit->fragment_encrypt_functions[S2ENC_TKIP] = EncryptTKIPFragment;
678 if((unit->flags & UNITF_HARDCCMP) != 0)
679 unit->fragment_encrypt_functions[S2ENC_CCMP] = WriteCCMPFragment;
680 else
681 unit->fragment_encrypt_functions[S2ENC_CCMP] = EncryptCCMPFragment;
683 /* Set decryption functions */
685 unit->fragment_decrypt_functions[S2ENC_NONE] = ReadClearFragment;
687 if((unit->flags & UNITF_HARDWEP) != 0)
688 unit->fragment_decrypt_functions[S2ENC_WEP] = ReadWEPFragment;
689 else
690 unit->fragment_decrypt_functions[S2ENC_WEP] = DecryptWEPFragment;
692 if((unit->flags & UNITF_HARDTKIP) != 0)
693 unit->fragment_decrypt_functions[S2ENC_TKIP] = ReadTKIPFragment;
694 else
695 unit->fragment_decrypt_functions[S2ENC_TKIP] = DecryptTKIPFragment;
697 if((unit->flags & UNITF_HARDCCMP) != 0)
698 unit->fragment_decrypt_functions[S2ENC_CCMP] = ReadCCMPFragment;
699 else
700 unit->fragment_decrypt_functions[S2ENC_CCMP] = DecryptCCMPFragment;
702 /* Return */
704 return success;
709 /****i* atheros5000.device/ConfigureAdapter ********************************
711 * NAME
712 * ConfigureAdapter -- Set up card for transmission/reception.
714 * SYNOPSIS
715 * ConfigureAdapter(unit)
717 * VOID ConfigureAdapter(struct DevUnit *);
719 ****************************************************************************
723 VOID ConfigureAdapter(struct DevUnit *unit, struct DevBase *base)
725 UWORD i, j, key_length, hal_band, key_type;
726 const struct KeyUnion *keys;
727 HAL_CHANNEL *channel = unit->channels, *ch;
728 ULONG freq = 2407 + unit->channel * 5;
729 HAL_STATUS status;
730 HAL_KEYVAL hal_key;
731 HAL_BOOL iq_done;
732 const HAL_RATE_TABLE *rate_table;
734 /* Get band-specific parameters */
736 if(unit->band == S2BAND_G)
738 hal_band = HAL_MODE_11G;
739 unit->band_mask = CHANNEL_G;
740 unit->tx_rates = g_retry_rates;
741 unit->mgmt_rate = G_MGMT_RATE;
743 else if(unit->band == S2BAND_B)
745 hal_band = HAL_MODE_11B;
746 unit->band_mask = CHANNEL_B;
747 unit->tx_rates = b_retry_rates;
748 unit->mgmt_rate = B_MGMT_RATE;
750 unit->rate_table = unit->hal->ah_getRateTable(unit->hal, hal_band);
752 /* Find rate codes to match our optimal and retry rates */
754 rate_table = unit->rate_table;
755 for(i = 0; i < rate_table->rateCount; i++)
757 for(j = 0; j < 4; j++)
759 if(rate_table->info[i].rateKbps == unit->tx_rates[j])
761 unit->tx_rate_codes[j] = rate_table->info[i].rateCode;
762 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
763 unit->tx_rate_codes[j] |= rate_table->info[i].shortPreamble;
766 if(rate_table->info[i].rateKbps == unit->mgmt_rate)
768 unit->mgmt_rate_code = rate_table->info[i].rateCode;
769 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
770 unit->mgmt_rate_code |= rate_table->info[i].shortPreamble;
774 /* Find a channel that matches requirements */
776 for(i = 0, ch = unit->channels; i < unit->channel_count; i++, ch++)
778 if(ch->channel == freq
779 && (ch->channelFlags & unit->band_mask) == unit->band_mask)
780 channel = ch;
783 /* Stop the transceiver if we're already online */
785 if((unit->flags & UNITF_ONLINE) != 0)
787 /* Disable frame transmission */
789 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
790 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
791 unit->hal->ah_setRxFilter(unit->hal, 0);
792 ath_hal_delay(3000);
794 /* Disable frame reception */
796 unit->hal->ah_stopPcuReceive(unit->hal);
797 unit->hal->ah_stopDmaReceive(unit->hal);
799 /* Disable interrupts */
801 unit->hal->ah_setInterrupts(unit->hal, 0);
804 /* Calculate RX filter mask */
806 unit->filter_mask = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_MCAST
807 | HAL_RX_FILTER_BCAST;
808 if((unit->flags & UNITF_PROM) != 0)
809 unit->filter_mask |= HAL_RX_FILTER_PROM;
810 if(unit->mode != S2PORT_MANAGED)
811 unit->filter_mask |= HAL_RX_FILTER_PROBEREQ;
813 /* Reset card */
815 unit->hal->ah_reset(unit->hal, HAL_M_STA, channel, FALSE, &status);
817 /* Set MAC address and miscellaneous wireless parameters */
819 unit->hal->ah_setMacAddress(unit->hal, unit->address);
820 unit->hal->ah_setPCUConfig(unit->hal);
821 SetMulticast(unit, base);
822 unit->hal->ah_setDefAntenna(unit->hal, unit->antenna);
823 unit->hal->ah_perCalibration(unit->hal, channel, &iq_done);
824 unit->hal->ah_setTxPowerLimit(unit->hal, TX_POWER);
826 /* Set association ID */
828 unit->hal->ah_writeAssocid(unit->hal, unit->bssid, unit->assoc_id);
830 /* Put on a reassuring light */
832 unit->hal->ah_setLedState(unit->hal, HAL_LED_RUN);
834 /* Set or clear default encryption keys where appropriate */
836 keys = unit->keys;
837 for(i = 0; i < WIFI_KEYCOUNT; i++)
839 key_type = unit->keys[i].type;
840 if(key_type <= S2ENC_WEP
841 || key_type == S2ENC_TKIP && (unit->flags & UNITF_HARDTKIP) == 0
842 || key_type == S2ENC_CCMP && (unit->flags & UNITF_HARDCCMP) == 0)
844 if(key_type == S2ENC_WEP && (unit->flags & UNITF_HARDWEP) != 0)
846 hal_key.kv_type = HAL_CIPHER_WEP;
847 key_length = keys[i].u.wep.length;
848 CopyMem(keys[i].u.wep.key, hal_key.kv_val, key_length);
850 else
852 hal_key.kv_type = HAL_CIPHER_CLR;
853 key_length = 0;
855 hal_key.kv_len = key_length;
856 unit->hal->ah_setKeyCacheEntry(unit->hal, i, &hal_key,
857 unit->bssid, FALSE);
861 /* Set pointer to RX ring */
863 unit->hal->ah_setRxDP(unit->hal,
864 unit->rx_descs_p + unit->rx_slot * sizeof(struct ath_desc));
866 /* Restart the transceiver if we're already online */
868 if((unit->flags & UNITF_ONLINE) != 0)
870 /* Enable interrupts */
872 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
874 /* Enable frame reception */
876 unit->hal->ah_enableReceive(unit->hal);
877 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
878 unit->hal->ah_startPcuReceive(unit->hal);
880 #if 0
881 /* Reset TX queues */
883 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
884 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
885 #endif
888 /* Return */
890 return;
895 /****i* atheros5000.device/GoOnline ****************************************
897 * NAME
898 * GoOnline -- Enable transmission/reception.
900 * SYNOPSIS
901 * GoOnline(unit)
903 * VOID GoOnline(struct DevUnit *);
905 ****************************************************************************
909 VOID GoOnline(struct DevUnit *unit, struct DevBase *base)
911 /* Enable interrupts */
913 unit->flags |= UNITF_ONLINE;
914 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
916 /* Enable frame reception */
918 unit->hal->ah_enableReceive(unit->hal);
919 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
920 unit->hal->ah_startPcuReceive(unit->hal);
922 #if 0
923 /* Reset TX queues */
925 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
926 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
927 #endif
929 /* Record start time and report Online event */
931 GetSysTime(&unit->stats.LastStart);
932 ReportEvents(unit, S2EVENT_ONLINE, base);
934 return;
939 /****i* atheros5000.device/GoOffline ***************************************
941 * NAME
942 * GoOffline -- Disable transmission/reception.
944 * SYNOPSIS
945 * GoOffline(unit)
947 * VOID GoOffline(struct DevUnit *);
949 * FUNCTION
951 * INPUTS
952 * unit
954 * RESULT
955 * None.
957 ****************************************************************************
961 VOID GoOffline(struct DevUnit *unit, struct DevBase *base)
963 unit->flags &= ~UNITF_ONLINE;
964 if((unit->flags & UNITF_HAVEADAPTER) != 0)
966 /* Disable frame transmission */
968 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
969 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
971 /* Disable frame reception */
973 unit->hal->ah_stopPcuReceive(unit->hal);
974 unit->hal->ah_stopDmaReceive(unit->hal);
975 unit->hal->ah_setRxFilter(unit->hal, 0);
976 ath_hal_delay(3000);
978 /* Stop interrupts */
980 unit->hal->ah_setInterrupts(unit->hal, 0);
982 /* Update statistics */
984 UpdateStats(unit, base);
987 /* Flush pending read and write requests */
989 FlushUnit(unit, MGMT_QUEUE, S2ERR_OUTOFSERVICE, base);
991 /* Report Offline event and return */
993 ReportEvents(unit, S2EVENT_OFFLINE, base);
994 return;
999 /****i* atheros5000.device/SetOptions **************************************
1001 * NAME
1002 * SetOptions -- Set and use interface options.
1004 * SYNOPSIS
1005 * reconfigure = SetOptions(unit, tag_list)
1007 * BOOL SetOptions(struct DevUnit *, struct TagItem *);
1009 ****************************************************************************
1013 BOOL SetOptions(struct DevUnit *unit, const struct TagItem *tag_list,
1014 struct DevBase *base)
1016 struct TagItem *tag_item, *tlist = (struct TagItem *)tag_list;
1017 BOOL reconfigure = TRUE;
1019 while((tag_item = NextTagItem(&tlist)) != NULL)
1021 switch(tag_item->ti_Tag)
1023 case S2INFO_SSID:
1024 ReportEvents(unit, S2EVENT_CONNECT, base);
1025 break;
1027 case S2INFO_BSSID:
1028 CopyMem((APTR)tag_item->ti_Data, unit->bssid, ETH_ADDRESSSIZE);
1029 break;
1031 case S2INFO_AssocID:
1032 unit->assoc_id = tag_item->ti_Data;
1033 break;
1035 case S2INFO_Capabilities:
1036 unit->capabilities = tag_item->ti_Data;
1037 if((unit->capabilities & (1 << 5)) != 0)
1038 unit->flags |= UNITF_SHORTPREAMBLE;
1039 else
1040 unit->flags &= ~UNITF_SHORTPREAMBLE;
1041 break;
1043 case S2INFO_DefaultKeyNo:
1044 unit->tx_key_no = tag_item->ti_Data;
1045 break;
1047 case S2INFO_PortType:
1048 unit->mode = tag_item->ti_Data;
1049 break;
1051 case S2INFO_Channel:
1052 if(tag_item->ti_Data != unit->channel)
1054 unit->channel = tag_item->ti_Data;
1055 reconfigure = TRUE;
1057 break;
1059 case S2INFO_Band:
1060 if(tag_item->ti_Data != unit->band)
1062 unit->band = tag_item->ti_Data;
1063 reconfigure = TRUE;
1065 break;
1069 return reconfigure;
1074 /****i* atheros5000.device/SetKey ******************************************
1076 * NAME
1077 * SetKey -- Set an encryption key.
1079 * SYNOPSIS
1080 * SetKey(unit, index, type, key, key_length,
1081 * rx_counter)
1083 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1084 * UBYTE *);
1086 ****************************************************************************
1090 VOID SetKey(struct DevUnit *unit, ULONG index, ULONG type, const UBYTE *key,
1091 ULONG key_length, const UBYTE *rx_counter, struct DevBase *base)
1093 struct KeyUnion *slot;
1094 struct EClockVal eclock;
1095 HAL_KEYVAL hal_key;
1096 UWORD i;
1098 Disable();
1099 slot = &unit->keys[index];
1100 switch(type)
1102 case S2ENC_WEP:
1103 CopyMem(key, slot->u.wep.key, key_length);
1104 slot->u.wep.length = key_length;
1106 if((unit->flags & UNITF_HARDWEP) == 0)
1108 /* Create a reasonably random IV */
1110 ReadEClock(&eclock);
1111 slot->u.wep.tx_iv = FastRand(eclock.ev_lo ^ eclock.ev_hi);
1114 break;
1116 case S2ENC_TKIP:
1117 CopyMem(key, slot->u.tkip.key, 16);
1118 CopyMem(key + 16, slot->u.tkip.tx_mic_key, MIC_SIZE);
1119 CopyMem(key + 24, slot->u.tkip.rx_mic_key, MIC_SIZE);
1120 slot->u.tkip.tx_iv_low = 0;
1121 slot->u.tkip.tx_iv_high = 0;
1122 slot->u.tkip.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1123 slot->u.tkip.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1124 slot->u.tkip.tx_ttak_set = FALSE;
1125 slot->u.tkip.rx_ttak_set = FALSE;
1127 if((unit->flags & UNITF_HARDTKIP) != 0)
1129 // TO DO: Wait for TX queue to empty
1130 /* Load parameters for hardware encryption */
1132 hal_key.kv_type = HAL_CIPHER_TKIP;
1133 hal_key.kv_len = 16;
1134 CopyMem(slot->u.tkip.key, hal_key.kv_val, 16);
1136 CopyMem(slot->u.tkip.tx_mic_key, hal_key.kv_mic, MIC_SIZE);
1137 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1138 unit->bssid, FALSE);
1139 CopyMem(slot->u.tkip.rx_mic_key, hal_key.kv_mic, MIC_SIZE);
1140 unit->hal->ah_setKeyCacheEntry(unit->hal, index + 32, &hal_key,
1141 unit->bssid, FALSE);
1143 else
1145 /* Convert key to native endianness */
1147 for(i = 0; i < 8; i++)
1148 slot->u.tkip.key[i] = LEWord(slot->u.tkip.key[i]);
1151 break;
1153 case S2ENC_CCMP:
1154 CopyMem(key, slot->u.ccmp.key, 16);
1155 slot->u.ccmp.tx_iv_low = 0;
1156 slot->u.ccmp.tx_iv_high = 0;
1157 slot->u.ccmp.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1158 slot->u.ccmp.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1159 slot->u.ccmp.stream_set = FALSE;
1161 if((unit->flags & UNITF_HARDCCMP) != 0)
1163 // TO DO: Wait for TX queue to empty
1164 /* Load parameters for hardware encryption */
1166 hal_key.kv_type = HAL_CIPHER_AES_CCM;
1167 hal_key.kv_len = 16;
1168 CopyMem(slot->u.ccmp.key, hal_key.kv_val, 16);
1169 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1170 unit->bssid, FALSE);
1174 /* Update type of key in selected slot */
1176 slot->type = type;
1177 Enable();
1179 return;
1184 /****i* atheros5000.device/AddMulticastRange *******************************
1186 * NAME
1187 * AddMulticastRange
1189 * SYNOPSIS
1190 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1192 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1194 ****************************************************************************
1198 BOOL AddMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1199 const UBYTE *upper_bound, struct DevBase *base)
1201 struct AddressRange *range;
1202 ULONG lower_bound_left, upper_bound_left;
1203 UWORD lower_bound_right, upper_bound_right;
1205 lower_bound_left = BELong(*((ULONG *)lower_bound));
1206 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1207 upper_bound_left = BELong(*((ULONG *)upper_bound));
1208 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1210 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1211 upper_bound_left, upper_bound_right, base);
1213 if(range != NULL)
1214 range->add_count++;
1215 else
1217 range = AllocMem(sizeof(struct AddressRange), MEMF_PUBLIC);
1218 if(range != NULL)
1220 range->lower_bound_left = lower_bound_left;
1221 range->lower_bound_right = lower_bound_right;
1222 range->upper_bound_left = upper_bound_left;
1223 range->upper_bound_right = upper_bound_right;
1224 range->add_count = 1;
1226 Disable();
1227 AddTail((APTR)&unit->multicast_ranges, (APTR)range);
1228 unit->range_count++;
1229 SetMulticast(unit, base);
1230 Enable();
1234 return range != NULL;
1239 /****i* atheros5000.device/RemMulticastRange *******************************
1241 * NAME
1242 * RemMulticastRange
1244 * SYNOPSIS
1245 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1247 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1249 ****************************************************************************
1253 BOOL RemMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1254 const UBYTE *upper_bound, struct DevBase *base)
1256 struct AddressRange *range;
1257 ULONG lower_bound_left, upper_bound_left;
1258 UWORD lower_bound_right, upper_bound_right;
1260 lower_bound_left = BELong(*((ULONG *)lower_bound));
1261 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1262 upper_bound_left = BELong(*((ULONG *)upper_bound));
1263 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1265 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1266 upper_bound_left, upper_bound_right, base);
1268 if(range != NULL)
1270 if(--range->add_count == 0)
1272 Disable();
1273 Remove((APTR)range);
1274 unit->range_count--;
1275 SetMulticast(unit, base);
1276 Enable();
1277 FreeMem(range, sizeof(struct AddressRange));
1281 return range != NULL;
1286 /****i* atheros5000.device/FindMulticastRange ******************************
1288 * NAME
1289 * FindMulticastRange
1291 * SYNOPSIS
1292 * range = FindMulticastRange(unit, lower_bound_left,
1293 * lower_bound_right, upper_bound_left, upper_bound_right)
1295 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1296 * UWORD, ULONG, UWORD);
1298 ****************************************************************************
1302 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
1303 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
1304 UWORD upper_bound_right, struct DevBase *base)
1306 struct AddressRange *range, *tail;
1307 BOOL found = FALSE;
1309 range = (APTR)unit->multicast_ranges.mlh_Head;
1310 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
1312 while(range != tail && !found)
1314 if(lower_bound_left == range->lower_bound_left &&
1315 lower_bound_right == range->lower_bound_right &&
1316 upper_bound_left == range->upper_bound_left &&
1317 upper_bound_right == range->upper_bound_right)
1318 found = TRUE;
1319 else
1320 range = (APTR)range->node.mln_Succ;
1323 if(!found)
1324 range = NULL;
1326 return range;
1331 /****i* atheros5000.device/SetMulticast ************************************
1333 * NAME
1334 * SetMulticast
1336 * SYNOPSIS
1337 * SetMulticast(unit)
1339 * VOID SetMulticast(struct DevUnit *);
1341 ****************************************************************************
1345 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base)
1347 unit->hal->ah_setMulticastFilter(unit->hal, 0xffffffff, 0xffffffff);
1349 return;
1354 /****i* atheros5000.device/FindTypeStats ***********************************
1356 * NAME
1357 * FindTypeStats
1359 * SYNOPSIS
1360 * stats = FindTypeStats(unit, list,
1361 * packet_type)
1363 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1364 * ULONG);
1366 ****************************************************************************
1370 struct TypeStats *FindTypeStats(struct DevUnit *unit, struct MinList *list,
1371 ULONG packet_type, struct DevBase *base)
1373 struct TypeStats *stats, *tail;
1374 BOOL found = FALSE;
1376 stats = (APTR)list->mlh_Head;
1377 tail = (APTR)&list->mlh_Tail;
1379 while(stats != tail && !found)
1381 if(stats->packet_type == packet_type)
1382 found = TRUE;
1383 else
1384 stats = (APTR)stats->node.mln_Succ;
1387 if(!found)
1388 stats = NULL;
1390 return stats;
1395 /****i* atheros5000.device/FlushUnit ***************************************
1397 * NAME
1398 * FlushUnit
1400 * SYNOPSIS
1401 * FlushUnit(unit, last_queue, error)
1403 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1405 ****************************************************************************
1409 VOID FlushUnit(struct DevUnit *unit, UBYTE last_queue, BYTE error,
1410 struct DevBase *base)
1412 struct IORequest *request;
1413 UBYTE i;
1414 struct Opener *opener, *tail;
1416 /* Abort queued requests */
1418 for(i = 0; i <= last_queue; i++)
1420 while((request = (APTR)GetMsg(unit->request_ports[i])) != NULL)
1422 request->io_Error = IOERR_ABORTED;
1423 ReplyMsg((APTR)request);
1427 #if 1
1428 opener = (APTR)unit->openers.mlh_Head;
1429 tail = (APTR)&unit->openers.mlh_Tail;
1431 /* Flush every opener's read queues */
1433 while(opener != tail)
1435 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1437 request->io_Error = error;
1438 ReplyMsg((APTR)request);
1440 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1442 request->io_Error = error;
1443 ReplyMsg((APTR)request);
1445 opener = (APTR)opener->node.mln_Succ;
1448 #else
1449 opener = request->ios2_BufferManagement;
1450 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1452 request->io_Error = IOERR_ABORTED;
1453 ReplyMsg((APTR)request);
1455 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1457 request->io_Error = IOERR_ABORTED;
1458 ReplyMsg((APTR)request);
1460 #endif
1462 /* Return */
1464 return;
1469 /****i* atheros5000.device/StatusInt ***************************************
1471 * NAME
1472 * StatusInt
1474 * SYNOPSIS
1475 * finished = StatusInt(unit)
1477 * BOOL StatusInt(struct DevUnit *);
1479 * FUNCTION
1481 * INPUTS
1482 * unit
1484 * RESULT
1485 * finished
1487 ****************************************************************************
1489 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1490 * Since we don't use this parameter, we can lie.
1494 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1496 struct DevBase *base;
1497 uint32_t queue_mask;
1498 HAL_INT ints, int_mask;
1500 base = unit->device;
1501 int_mask = unit->hal->ah_getInterrupts(unit->hal);
1503 if(!unit->hal->ah_isInterruptPending(unit->hal)) return FALSE;
1505 /* Handle ints */
1507 if(unit->hal->ah_getPendingInterrupts(unit->hal, &ints))
1509 if((ints & HAL_INT_TX) != 0)
1511 int_mask &= ~(HAL_INT_TX | HAL_INT_TXDESC);
1512 queue_mask = 1 << unit->tx_queue_no | 1 << unit->mgmt_queue_no;
1513 unit->hal->ah_getTxIntrQueue(unit->hal, &queue_mask);
1514 if((queue_mask & 1 << unit->tx_queue_no) != 0)
1515 Cause(&unit->tx_end_int);
1516 if((queue_mask & 1 << unit->mgmt_queue_no) != 0)
1517 Cause(&unit->mgmt_end_int);
1519 if((ints & HAL_INT_RX) != 0)
1521 int_mask &= ~(HAL_INT_RX | HAL_INT_RXEOL);
1522 Cause(&unit->rx_int);
1526 #ifdef __MORPHOS__
1527 int_mask = INT_MASK;
1528 #endif
1529 // unit->hal->ah_setInterrupts(unit->hal, int_mask))
1531 return FALSE;
1536 /****i* atheros5000.device/RXInt *******************************************
1538 * NAME
1539 * RXInt -- Soft interrupt for packet reception.
1541 * SYNOPSIS
1542 * RXInt(unit)
1544 * VOID RXInt(struct DevUnit *);
1546 * FUNCTION
1548 * INPUTS
1549 * unit - A unit of this device.
1551 * RESULT
1552 * None.
1554 ****************************************************************************
1558 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1560 UWORD ieee_length, frame_control, frame_type, slot, next_slot,
1561 encryption, key_no, buffer_no, old_length;
1562 struct DevBase *base;
1563 BOOL is_good;
1564 LONG frag_no;
1565 struct ath_desc *rx_desc, *next_desc;
1566 ULONG dma_size, rx_desc_p;
1567 UBYTE *buffer, *p, *frame, *data, *snap_frame, *source;
1568 struct ath_rx_status status;
1570 base = unit->device;
1571 slot = unit->rx_slot;
1572 rx_desc = unit->rx_descs + slot;
1573 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1574 next_slot = (slot + 1) % RX_SLOT_COUNT;
1575 next_desc = unit->rx_descs + next_slot;
1577 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1578 CachePostDMA(unit->rx_descs, &dma_size, 0);
1580 while(unit->hal->ah_procRxDesc(unit->hal, rx_desc, rx_desc_p, next_desc,
1581 unit->hal->ah_getTsf64(unit->hal), &status) != HAL_EINPROGRESS)
1583 is_good = TRUE;
1584 buffer = unit->rx_buffers[slot];
1586 dma_size = FRAME_BUFFER_SIZE;
1587 CachePostDMA(buffer, &dma_size, 0);
1589 if(status.rs_status == 0
1590 && status.rs_datalen >= WIFI_FRM_DATA + FCS_SIZE)
1592 /* Get fragment info */
1594 frame = buffer;
1595 ieee_length = status.rs_datalen - FCS_SIZE - WIFI_FRM_DATA;
1596 data = frame + WIFI_FRM_DATA;
1597 frame_control =
1598 LEWord(*(UWORD *)(frame + WIFI_FRM_CONTROL));
1600 /* Get buffer to store fragment in */
1602 frag_no = LEWord(*(UWORD *)(frame + WIFI_FRM_SEQCONTROL));
1603 if(unit->mode == S2PORT_ADHOC)
1604 source = frame + WIFI_FRM_ADDRESS2;
1605 else
1606 source = frame + WIFI_FRM_ADDRESS3;
1607 snap_frame = GetRXBuffer(unit, source, frag_no, &buffer_no, base);
1609 /* Get location to put new data */
1611 if(snap_frame != NULL)
1613 if((frag_no & 0xf ) > 0)
1614 old_length =
1615 BEWord(*(UWORD *)(snap_frame + ETH_PACKET_IEEELEN));
1616 else
1618 /* Create new 802.3 header */
1620 CopyMem(frame + WIFI_FRM_ADDRESS1, snap_frame,
1621 ETH_ADDRESSSIZE);
1622 CopyMem(source, snap_frame + ETH_PACKET_SOURCE,
1623 ETH_ADDRESSSIZE);
1624 old_length = 0;
1626 p = snap_frame + ETH_HEADERSIZE + old_length;
1628 /* Get encryption type and key index */
1630 if((frame_control & WIFI_FRM_CONTROLF_WEP) != 0)
1632 key_no = data[3] >> 6 & 0x3;
1633 encryption = unit->keys[key_no].type;
1635 else
1636 encryption = S2ENC_NONE;
1638 /* Append fragment to frame, decrypting/checking fragment if
1639 necessary */
1641 is_good = unit->fragment_decrypt_functions[encryption](unit,
1642 frame, data, &ieee_length, p, base);
1644 /* Update length in frame being built with current fragment, or
1645 increment bad frame counter if fragment is bad */
1647 if(is_good)
1649 ieee_length += old_length;
1650 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1651 MakeBEWord(ieee_length);
1653 else
1654 unit->stats.BadData++;
1656 /* If all fragments have arrived, process the complete frame */
1658 if((frame_control & WIFI_FRM_CONTROLF_MOREFRAGS) == 0)
1660 if(is_good)
1662 /* Decrypt complete frame if necessary */
1664 data = snap_frame + ETH_HEADERSIZE;
1665 if(encryption == S2ENC_TKIP)
1666 // && (unit->flags & UNITF_HARDTKIP) == 0)
1667 // && (unit->flags & UNITF_HARDMIC) == 0)
1669 is_good = TKIPDecryptFrame(unit, snap_frame, data,
1670 ieee_length, data, key_no, base);
1671 ieee_length -= MIC_SIZE;
1672 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1673 MakeBEWord(ieee_length);
1674 if(!is_good)
1675 unit->stats.BadData++;
1679 if(is_good)
1681 /* Get frame's 802.11 type and subtype */
1683 frame_type = (frame_control & WIFI_FRM_CONTROLF_TYPE)
1684 >> WIFI_FRM_CONTROLB_TYPE;
1686 /* If it's a management frame, process it separately;
1687 otherwise distribute it to clients after filtering */
1689 if(frame_type == WIFI_FRMTYPE_MGMT)
1691 DistributeMgmtFrame(unit, frame, status.rs_datalen - 4,
1692 base);
1694 else if(AddressFilter(unit, snap_frame + ETH_PACKET_DEST,
1695 base))
1697 unit->stats.PacketsReceived++;
1698 DistributeRXPacket(unit, snap_frame, base);
1703 /* Mark fragment buffer as unused for next time */
1705 unit->rx_fragment_nos[buffer_no] = -1;
1707 else
1708 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_RX, base);
1710 else
1712 is_good = FALSE;
1715 if(!is_good)
1717 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_HARDWARE | S2EVENT_RX,
1718 base);
1721 /* Prepare descriptor for next time */
1723 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
1724 HAL_RXDESC_INTREQ);
1726 dma_size = FRAME_BUFFER_SIZE;
1727 CachePreDMA(buffer, &dma_size, 0);
1729 /* Get next descriptor */
1731 slot = next_slot;
1732 rx_desc = next_desc;
1733 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1734 next_slot = (slot + 1) % RX_SLOT_COUNT;
1735 next_desc = unit->rx_descs + next_slot;
1738 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1739 CachePreDMA(unit->rx_descs, &dma_size, 0);
1741 unit->rx_slot = slot;
1742 // TO DO: unstall reception?
1744 /* Re-enable RX interrupts */
1746 #if 0
1747 Disable();
1748 unit->hal->ah_setInterrupts(unit->hal,
1749 unit->hal->ah_getInterrupts(unit->hal) | HAL_INT_RX | HAL_INT_RXEOL);
1750 Enable();
1751 #endif
1753 return;
1758 /****i* atheros5000.device/GetRXBuffer *************************************
1760 * NAME
1761 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1763 * SYNOPSIS
1764 * buffer = GetRXBuffer(unit, address, frag_no)
1766 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1768 ****************************************************************************
1772 static UBYTE *GetRXBuffer(struct DevUnit *unit, const UBYTE *address,
1773 UWORD frag_no, UWORD *buffer_no, struct DevBase *base)
1775 UWORD i;
1776 UBYTE *buffer;
1777 LONG n;
1778 BOOL found;
1780 buffer = unit->rx_frames;
1781 for(i = 0, found = FALSE; i < FRAME_BUFFER_COUNT * 2 && !found; i++)
1783 /* Throw away old buffer contents if we didn't find a free slot the
1784 first time around */
1786 if(i >= FRAME_BUFFER_COUNT)
1787 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = -1;
1789 /* For a frame's first fragment, find an empty slot; for subsequent
1790 fragments, find a slot with matching source address */
1792 n = unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT];
1793 if(n == -1 && (frag_no & 0xf) == 0
1794 || *((ULONG *)(buffer + ETH_PACKET_SOURCE))
1795 == *((ULONG *)(address))
1796 && *((UWORD *)(buffer + ETH_PACKET_SOURCE + 4))
1797 == *((UWORD *)(address + 4)))
1799 found = TRUE;
1800 if(n == -1)
1801 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = frag_no;
1802 *buffer_no = i;
1804 else
1805 buffer += FRAME_BUFFER_SIZE;
1808 if(!found)
1809 buffer = NULL;
1811 return buffer;
1816 /****i* atheros5000.device/DistributeRXPacket ******************************
1818 * NAME
1819 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1821 * SYNOPSIS
1822 * DistributeRXPacket(unit, frame)
1824 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1826 ****************************************************************************
1830 static VOID DistributeRXPacket(struct DevUnit *unit, UBYTE *frame,
1831 struct DevBase *base)
1833 UWORD packet_size, ieee_length;
1834 BOOL is_orphan = TRUE, accepted, is_snap = FALSE;
1835 ULONG packet_type;
1836 UBYTE *buffer;
1837 const UBYTE *template = snap_template;
1838 struct IOSana2Req *request, *request_tail;
1839 struct Opener *opener, *opener_tail;
1840 struct TypeStats *tracker;
1842 ieee_length = BEWord(*(UWORD *)(frame + ETH_PACKET_IEEELEN));
1843 packet_size = ETH_HEADERSIZE + ieee_length;
1844 if(ieee_length >= SNAP_HEADERSIZE)
1845 is_snap = *(const ULONG *)(frame + ETH_PACKET_DATA)
1846 == *(const ULONG *)template;
1848 /* De-encapsulate SNAP packets and get packet type */
1850 if(is_snap)
1852 buffer = unit->rx_buffer;
1853 packet_size -= SNAP_HEADERSIZE;
1854 CopyMem(frame, buffer, ETH_PACKET_TYPE);
1855 CopyMem(frame + ETH_HEADERSIZE + SNAP_FRM_TYPE,
1856 buffer + ETH_PACKET_TYPE, packet_size - ETH_PACKET_TYPE);
1858 else
1859 buffer = frame;
1861 packet_type = BEWord(*((UWORD *)(buffer + ETH_PACKET_TYPE)));
1863 if(packet_size <= ETH_MAXPACKETSIZE)
1865 /* Offer packet to every opener */
1867 opener = (APTR)unit->openers.mlh_Head;
1868 opener_tail = (APTR)&unit->openers.mlh_Tail;
1870 while(opener != opener_tail)
1872 request = (APTR)opener->read_port.mp_MsgList.lh_Head;
1873 request_tail = (APTR)&opener->read_port.mp_MsgList.lh_Tail;
1874 accepted = FALSE;
1876 /* Offer packet to each request until it's accepted */
1878 while(request != request_tail && !accepted)
1880 if(request->ios2_PacketType == packet_type)
1882 CopyPacket(unit, request, packet_size, packet_type,
1883 buffer, base);
1884 accepted = TRUE;
1886 request =
1887 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1890 if(accepted)
1891 is_orphan = FALSE;
1892 opener = (APTR)opener->node.mln_Succ;
1895 /* If packet was unwanted, give it to S2_READORPHAN request */
1897 if(is_orphan)
1899 unit->stats.UnknownTypesReceived++;
1900 if(!IsMsgPortEmpty(unit->request_ports[ADOPT_QUEUE]))
1902 CopyPacket(unit,
1903 (APTR)unit->request_ports[ADOPT_QUEUE]->
1904 mp_MsgList.lh_Head, packet_size, packet_type, buffer,
1905 base);
1909 /* Update remaining statistics */
1911 if(packet_type <= ETH_MTU)
1912 packet_type = ETH_MTU;
1913 tracker =
1914 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
1915 if(tracker != NULL)
1917 tracker->stats.PacketsReceived++;
1918 tracker->stats.BytesReceived += packet_size;
1921 else
1922 unit->stats.BadData++;
1924 return;
1929 /****i* atheros5000.device/CopyPacket **************************************
1931 * NAME
1932 * CopyPacket -- Copy packet to client's buffer.
1934 * SYNOPSIS
1935 * CopyPacket(unit, request, packet_size, packet_type,
1936 * buffer)
1938 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1939 * UBYTE *);
1941 ****************************************************************************
1945 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
1946 UWORD packet_size, UWORD packet_type, UBYTE *buffer,
1947 struct DevBase *base)
1949 struct Opener *opener;
1950 BOOL filtered = FALSE;
1952 /* Set multicast and broadcast flags */
1954 request->ios2_Req.io_Flags &= ~(SANA2IOF_BCAST | SANA2IOF_MCAST);
1955 if((*((ULONG *)(buffer + ETH_PACKET_DEST)) == 0xffffffff) &&
1956 (*((UWORD *)(buffer + ETH_PACKET_DEST + 4)) == 0xffff))
1957 request->ios2_Req.io_Flags |= SANA2IOF_BCAST;
1958 else if((buffer[ETH_PACKET_DEST] & 0x1) != 0)
1959 request->ios2_Req.io_Flags |= SANA2IOF_MCAST;
1961 /* Set source and destination addresses and packet type */
1963 CopyMem(buffer + ETH_PACKET_SOURCE, request->ios2_SrcAddr,
1964 ETH_ADDRESSSIZE);
1965 CopyMem(buffer + ETH_PACKET_DEST, request->ios2_DstAddr,
1966 ETH_ADDRESSSIZE);
1967 request->ios2_PacketType = packet_type;
1969 /* Adjust for cooked packet request */
1971 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1973 packet_size -= ETH_PACKET_DATA;
1974 buffer += ETH_PACKET_DATA;
1976 #ifdef USE_HACKS
1977 else
1978 packet_size += 4; /* Needed for Shapeshifter & Fusion? */
1979 #endif
1980 request->ios2_DataLength = packet_size;
1982 /* Filter packet */
1984 opener = request->ios2_BufferManagement;
1985 if(request->ios2_Req.io_Command == CMD_READ &&
1986 opener->filter_hook != NULL)
1987 if(!CallHookPkt(opener->filter_hook, request, buffer))
1988 filtered = TRUE;
1990 if(!filtered)
1992 /* Copy packet into opener's buffer and reply packet */
1994 if(!opener->rx_function(request->ios2_Data, buffer, packet_size))
1996 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1997 request->ios2_WireError = S2WERR_BUFF_ERROR;
1998 ReportEvents(unit,
1999 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
2000 base);
2002 Remove((APTR)request);
2003 ReplyMsg((APTR)request);
2006 return;
2011 /****i* atheros5000.device/AddressFilter ***********************************
2013 * NAME
2014 * AddressFilter -- Determine if an RX packet should be accepted.
2016 * SYNOPSIS
2017 * accept = AddressFilter(unit, address)
2019 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
2021 ****************************************************************************
2025 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
2026 struct DevBase *base)
2028 struct AddressRange *range, *tail;
2029 BOOL accept = TRUE;
2030 ULONG address_left;
2031 UWORD address_right;
2033 /* Check whether address is unicast/broadcast or multicast */
2035 address_left = BELong(*((ULONG *)address));
2036 address_right = BEWord(*((UWORD *)(address + 4)));
2038 if(((address_left & 0x01000000) != 0) &&
2039 !((address_left == 0xffffffff) && (address_right == 0xffff)))
2041 /* Check if this multicast address is wanted */
2043 range = (APTR)unit->multicast_ranges.mlh_Head;
2044 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
2045 accept = FALSE;
2047 while((range != tail) && !accept)
2049 if((address_left > range->lower_bound_left ||
2050 address_left == range->lower_bound_left &&
2051 address_right >= range->lower_bound_right) &&
2052 (address_left < range->upper_bound_left ||
2053 address_left == range->upper_bound_left &&
2054 address_right <= range->upper_bound_right))
2055 accept = TRUE;
2056 range = (APTR)range->node.mln_Succ;
2059 if(!accept)
2060 unit->special_stats[S2SS_ETHERNET_BADMULTICAST & 0xffff]++;
2063 return accept;
2068 /****i* atheros5000.device/DistributeMgmtFrame *****************************
2070 * NAME
2071 * DistributeMgmtFrame -- Send a management frame to clients.
2073 * SYNOPSIS
2074 * DistributeMgmtFrame(unit, frame, frame_size)
2076 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
2078 ****************************************************************************
2082 static VOID DistributeMgmtFrame(struct DevUnit *unit, UBYTE *frame,
2083 UWORD frame_size, struct DevBase *base)
2085 struct IOSana2Req *request;
2086 struct Opener *opener, *opener_tail;
2088 /* Send packet to every opener */
2090 opener = (APTR)unit->openers.mlh_Head;
2091 opener_tail = (APTR)&unit->openers.mlh_Tail;
2093 while(opener != opener_tail)
2095 request = (APTR)RemHead(&opener->mgmt_port.mp_MsgList);
2097 if(request != NULL)
2099 /* Copy packet into opener's buffer and reply packet */
2101 if(frame_size <= request->ios2_DataLength)
2103 CopyMem(frame, request->ios2_Data, frame_size);
2104 request->ios2_DataLength = frame_size;
2106 else
2108 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
2109 request->ios2_WireError = S2WERR_BUFF_ERROR;
2110 ReportEvents(unit,
2111 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
2112 base);
2114 ReplyMsg((APTR)request);
2115 request =
2116 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2119 opener = (APTR)opener->node.mln_Succ;
2122 return;
2127 /****i* atheros5000.device/TXInt *******************************************
2129 * NAME
2130 * TXInt -- Soft interrupt for packet transmission.
2132 * SYNOPSIS
2133 * TXInt(unit)
2135 * VOID TXInt(struct DevUnit *);
2137 * FUNCTION
2139 * INPUTS
2140 * unit - A unit of this device.
2142 * RESULT
2143 * None.
2145 ****************************************************************************
2149 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2151 struct DevBase *base;
2152 UWORD i, frame_size, data_size, packet_type, body_size, slot, new_slot,
2153 last_slot, encryption, subtype, duration;
2154 UBYTE *buffer, *q, *plaintext, *ciphertext, *frame,
2155 mic_header[ETH_ADDRESSSIZE * 2];
2156 const UBYTE *p, *dest, *source;
2157 struct IOSana2Req *request;
2158 BOOL proceed = TRUE, is_ieee;
2159 struct Opener *opener;
2160 ULONG wire_error, dma_size;
2161 struct ath_desc *tx_desc, *last_desc;
2162 UBYTE *(*dma_tx_function)(REG(a0, APTR));
2163 BYTE error;
2164 struct MsgPort *port;
2165 struct TypeStats *tracker;
2166 const HAL_RATE_TABLE *rate_table;
2168 base = unit->device;
2169 port = unit->request_ports[WRITE_QUEUE];
2170 rate_table = unit->rate_table;
2172 while(proceed && (!IsMsgPortEmpty(port)))
2174 slot = unit->tx_in_slot;
2175 new_slot = (slot + 1) % TX_SLOT_COUNT;
2177 // if(new_slot != unit->tx_out_slot)
2178 if(slot == unit->tx_out_slot) // one packet at a time
2180 error = 0;
2181 body_size = 0;
2183 /* Get request and DMA frame descriptor */
2185 request = (APTR)port->mp_MsgList.lh_Head;
2187 Remove((APTR)request);
2188 unit->tx_requests[slot] = request;
2189 tx_desc = unit->tx_descs + slot;
2190 frame = unit->tx_buffers[slot];
2192 /* Get packet data */
2194 opener = request->ios2_BufferManagement;
2195 dma_tx_function = opener->dma_tx_function;
2196 if(dma_tx_function != NULL)
2197 buffer = dma_tx_function(request->ios2_Data);
2198 else
2199 buffer = NULL;
2201 if(buffer == NULL)
2203 buffer = unit->tx_buffer;
2204 if(!opener->tx_function(buffer, request->ios2_Data,
2205 request->ios2_DataLength))
2207 error = S2ERR_NO_RESOURCES;
2208 wire_error = S2WERR_BUFF_ERROR;
2209 ReportEvents(unit,
2210 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF
2211 | S2EVENT_TX, base);
2215 if(error == 0)
2217 /* Get packet type and/or length */
2219 data_size = request->ios2_DataLength;
2220 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2222 data_size -= ETH_PACKET_DATA;
2223 packet_type = BEWord(*(UWORD *)(buffer + ETH_PACKET_TYPE));
2225 else
2226 packet_type = request->ios2_PacketType;
2227 is_ieee = packet_type <= ETH_MTU;
2229 /* Determine encryption type and frame subtype */
2231 if(data_size > 0)
2233 encryption = unit->keys[unit->tx_key_no].type;
2234 subtype = 0;
2236 else
2238 encryption = S2ENC_NONE;
2239 subtype = 4;
2242 /* Get source and destination addresses */
2244 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2246 dest = buffer;
2247 source = buffer + ETH_ADDRESSSIZE;
2248 buffer += ETH_ADDRESSSIZE * 2 + 2;
2250 else
2252 dest = request->ios2_DstAddr;
2253 source = unit->address;
2256 /* Write 802.11 header */
2258 q = frame;
2259 *(UWORD *)q = MakeLEWord(
2260 (encryption == S2ENC_NONE ? 0 : WIFI_FRM_CONTROLF_WEP)
2261 | (unit->mode == S2PORT_ADHOC ? 0 : WIFI_FRM_CONTROLF_TODS)
2262 | subtype << WIFI_FRM_CONTROLB_SUBTYPE
2263 | WIFI_FRMTYPE_DATA << WIFI_FRM_CONTROLB_TYPE);
2264 q += 2;
2266 i = rate_table->rateCodeToIndex[unit->tx_rate_codes[0]];
2267 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2268 duration = rate_table->info[i].spAckDuration;
2269 else
2270 duration = rate_table->info[i].lpAckDuration;
2271 *(UWORD *)q = MakeLEWord(duration);
2272 q += 2;
2274 if(unit->mode == S2PORT_ADHOC)
2275 p = dest;
2276 else
2277 p = unit->bssid;
2278 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2279 *q++ = *p++;
2281 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2282 *q++ = *p++;
2284 if(unit->mode == S2PORT_ADHOC)
2285 p = unit->bssid;
2286 else
2287 p = dest;
2288 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2289 *q++ = *p++;
2290 *(UWORD *)q = 0;
2291 q += 2;
2293 // TO DO: need to pad header to 4-byte boundary?
2295 /* Leave room for encryption overhead */
2297 ciphertext = q;
2298 q += unit->iv_sizes[encryption];
2299 plaintext = q;
2301 /* Write SNAP header */
2303 if(!is_ieee)
2305 for(i = 0, p = snap_template;
2306 i < SNAP_FRM_TYPE; i++)
2307 *q++ = *p++;
2308 *(UWORD *)q = MakeBEWord(packet_type);
2309 q += 2;
2310 body_size += SNAP_HEADERSIZE;
2313 /* Copy data into frame */
2315 CopyMem(buffer, q, data_size);
2316 body_size += data_size;
2318 /* Append MIC to frame for TKIP */
2320 if(encryption == S2ENC_TKIP)
2322 // if((unit->flags & UNITF_HARDMIC) == 0)
2324 q = mic_header;
2325 for(i = 0, p = dest; i < ETH_ADDRESSSIZE; i++)
2326 *q++ = *p++;
2327 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2328 *q++ = *p++;
2329 TKIPEncryptFrame(unit, mic_header, plaintext, body_size,
2330 plaintext, base);
2332 body_size += MIC_SIZE;
2335 /* Encrypt fragment if applicable */
2337 unit->fragment_encrypt_functions[encryption](unit, frame,
2338 plaintext, &body_size, ciphertext, base);
2340 /* Fill in DMA descriptor for packet transmission */
2342 frame_size = WIFI_FRM_DATA + body_size;
2343 tx_desc->ds_link = (ULONG)(UPINT)NULL;
2344 unit->hal->ah_setupTxDesc(unit->hal, tx_desc, frame_size + 4, // + CRC?
2345 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2346 ((unit->flags & UNITF_SLOWRETRIES) != 0) ?
2347 unit->tx_rate_codes[0] : unit->tx_rate_codes[1],
2348 ((unit->flags & UNITF_SLOWRETRIES) != 0) ? 1 : TX_TRIES,
2349 HAL_TXKEYIX_INVALID,
2350 HAL_ANTENNA_MIN_MODE,
2351 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK,
2352 0, 0, 0, 0, 3);
2353 if((unit->flags & UNITF_SLOWRETRIES) != 0)
2354 unit->hal->ah_setupXTxDesc(unit->hal, tx_desc,
2355 unit->tx_rate_codes[1], 1,
2356 unit->tx_rate_codes[2], 1,
2357 unit->tx_rate_codes[3], TX_TRIES - 3);
2358 unit->hal->ah_fillTxDesc(unit->hal, tx_desc, frame_size, TRUE, TRUE,
2359 tx_desc);
2361 dma_size = frame_size;
2362 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2364 /* Pass packet to adapter */
2366 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2367 last_slot = (slot + TX_SLOT_COUNT - 1) % TX_SLOT_COUNT;
2368 if(unit->tx_out_slot != slot)
2369 //if(unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no) > 0)
2371 last_desc =
2372 unit->tx_descs + last_slot;
2373 last_desc->ds_link = unit->tx_descs_p + slot * sizeof(struct ath_desc);
2374 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2375 CachePreDMA(unit->tx_descs, &dma_size, 0);
2377 else
2379 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2380 CachePreDMA(unit->tx_descs, &dma_size, 0);
2381 unit->hal->ah_setTxDP(unit->hal, unit->tx_queue_no,
2382 unit->tx_descs_p + slot * sizeof(struct ath_desc));
2385 unit->hal->ah_startTxDma(unit->hal, unit->tx_queue_no);
2386 unit->tx_in_slot = new_slot;
2388 else
2390 /* Reply failed request */
2392 request->ios2_Req.io_Error = error;
2393 request->ios2_WireError = wire_error;
2394 ReplyMsg((APTR)request);
2397 /* Update statistics */
2399 if(error == 0)
2401 unit->stats.PacketsSent++;
2403 tracker = FindTypeStats(unit, &unit->type_trackers,
2404 request->ios2_PacketType, base);
2405 if(tracker != NULL)
2407 tracker->stats.PacketsSent++;
2408 tracker->stats.BytesSent += ETH_HEADERSIZE + data_size;
2412 else
2413 proceed = FALSE;
2416 /* Don't try to keep sending packets if there's no space left */
2418 if(proceed)
2419 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
2420 else
2421 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_IGNORE;
2423 return;
2428 /****i* atheros5000.device/TXEndInt ****************************************
2430 * NAME
2431 * TXEndInt -- Clean up after a data frame has been sent.
2433 * SYNOPSIS
2434 * TXEndInt(unit, int_code)
2436 * VOID TXEndInt(struct DevUnit *, APTR);
2438 * NOTES
2439 * I think it's safe to assume that there will always be at least one
2440 * completed packet whenever this interrupt is called.
2442 ****************************************************************************
2446 static VOID TXEndInt(REG(a1, struct DevUnit *unit),
2447 REG(a6, APTR int_code))
2449 UWORD frame_size, new_out_slot, i;
2450 UBYTE *frame;
2451 struct DevBase *base;
2452 struct IOSana2Req *request;
2453 ULONG dma_size;
2454 struct TypeStats *tracker;
2456 /* Find out which packets have completed */
2458 base = unit->device;
2459 new_out_slot = (unit->tx_in_slot + TX_SLOT_COUNT
2460 - unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no))
2461 % TX_SLOT_COUNT;
2463 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2464 CachePostDMA(unit->tx_descs, &dma_size, 0);
2466 /* Retire sent packets */
2468 for(i = unit->tx_out_slot; i != new_out_slot;
2469 i = (i + 1) % TX_SLOT_COUNT)
2471 frame = unit->tx_buffers[i];
2472 dma_size = FRAME_BUFFER_SIZE;
2473 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2475 /* Update statistics */
2477 request = unit->tx_requests[i];
2478 frame_size = request->ios2_DataLength;
2479 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
2480 frame_size += ETH_HEADERSIZE;
2482 tracker = FindTypeStats(unit, &unit->type_trackers,
2483 request->ios2_PacketType, base);
2484 if(tracker != NULL)
2486 tracker->stats.PacketsSent++;
2487 tracker->stats.BytesSent += frame_size;
2490 /* Reply request */
2492 request->ios2_Req.io_Error = 0;
2493 ReplyMsg((APTR)request);
2496 unit->tx_out_slot = i;
2498 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2499 CachePreDMA(unit->tx_descs, &dma_size, 0);
2501 /* Restart downloads if they had stopped */
2503 if(unit->request_ports[WRITE_QUEUE]->mp_Flags == PA_IGNORE)
2504 Cause(&unit->tx_int);
2506 return;
2511 /****i* atheros5000.device/MgmtTXInt ***************************************
2513 * NAME
2514 * MgmtTXInt -- Soft interrupt for management frame transmission.
2516 * SYNOPSIS
2517 * MgmtTXInt(unit)
2519 * VOID MgmtTXInt(struct DevUnit *);
2521 * FUNCTION
2523 * INPUTS
2524 * unit - A unit of this device.
2526 * RESULT
2527 * None.
2529 ****************************************************************************
2533 static VOID MgmtTXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2535 struct DevBase *base;
2536 UWORD frame_size, slot, new_slot, last_slot, i, duration;
2537 UBYTE *frame;
2538 struct IOSana2Req *request;
2539 BOOL proceed = TRUE, has_bssid;
2540 ULONG dma_size;
2541 struct ath_desc *desc, *last_desc;
2542 struct MsgPort *port;
2543 const HAL_RATE_TABLE *rate_table;
2545 base = unit->device;
2546 port = unit->request_ports[MGMT_QUEUE];
2547 rate_table = unit->rate_table;
2549 while(proceed && (!IsMsgPortEmpty(port)))
2551 slot = unit->mgmt_in_slot;
2552 new_slot = (slot + 1) % MGMT_SLOT_COUNT;
2554 // if(new_slot != unit->mgmt_out_slot)
2555 if(slot == unit->mgmt_out_slot) // one packet at a time
2557 /* Get request and DMA frame descriptor */
2559 request = (APTR)port->mp_MsgList.lh_Head;
2561 Remove((APTR)request);
2562 unit->mgmt_requests[slot] = request;
2563 desc = unit->mgmt_descs + slot;
2564 frame = unit->mgmt_buffers[slot];
2566 /* Get packet length */
2568 frame_size = request->ios2_DataLength;
2570 /* Copy frame into DMA buffer */
2572 CopyMem(request->ios2_Data, frame, frame_size);
2574 /* Set duration */
2576 has_bssid = ((frame + WIFI_FRM_ADDRESS1)[0] & 0x1) == 0;
2577 i = rate_table->rateCodeToIndex[unit->mgmt_rate_code];
2578 if(has_bssid)
2580 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2581 duration = rate_table->info[i].spAckDuration;
2582 else
2583 duration = rate_table->info[i].lpAckDuration;
2585 else
2586 duration = 0;
2587 *(UWORD *)(frame + WIFI_FRM_DURATION) = MakeLEWord(duration);
2589 /* Fill in DMA descriptor for packet transmission */
2591 desc->ds_link = (ULONG)(UPINT)NULL;
2592 unit->hal->ah_setupTxDesc(unit->hal, desc, frame_size + 4, // + CRC?
2593 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2594 unit->mgmt_rate_code, TX_TRIES, HAL_TXKEYIX_INVALID,
2595 HAL_ANTENNA_MIN_MODE,
2596 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK
2597 | (has_bssid ? 0 : HAL_TXDESC_NOACK),
2598 0, 0, 0, 0, 3);
2599 unit->hal->ah_fillTxDesc(unit->hal, desc, frame_size, TRUE, TRUE,
2600 desc);
2602 dma_size = frame_size;
2603 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2605 /* Pass packet to adapter */
2607 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2608 last_slot = (slot + MGMT_SLOT_COUNT - 1) % MGMT_SLOT_COUNT;
2609 if(unit->mgmt_out_slot != slot)
2610 //if(unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no) > 0)
2612 last_desc = unit->mgmt_descs + last_slot;
2613 last_desc->ds_link =
2614 unit->mgmt_descs_p + slot * sizeof(struct ath_desc);
2615 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2616 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2618 else
2620 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2621 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2622 unit->hal->ah_setTxDP(unit->hal, unit->mgmt_queue_no,
2623 unit->mgmt_descs_p + slot * sizeof(struct ath_desc));
2626 unit->hal->ah_startTxDma(unit->hal, unit->mgmt_queue_no);
2627 unit->mgmt_in_slot = new_slot;
2629 else
2630 proceed = FALSE;
2633 /* Don't try to keep sending packets if there's no space left */
2635 if(proceed)
2636 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
2637 else
2638 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_IGNORE;
2640 return;
2645 /****i* atheros5000.device/MgmtTXEndInt ************************************
2647 * NAME
2648 * MgmtTXEndInt -- Clean up after a management frame has been sent.
2650 * SYNOPSIS
2651 * MgmtTXEndInt(unit, int_code)
2653 * VOID MgmtTXEndInt(struct DevUnit *, APTR);
2655 * NOTES
2656 * I think it's safe to assume that there will always be at least one
2657 * completed packet whenever this interrupt is called.
2659 ****************************************************************************
2663 static VOID MgmtTXEndInt(REG(a1, struct DevUnit *unit),
2664 REG(a6, APTR int_code))
2666 UWORD new_out_slot, i;
2667 UBYTE *frame;
2668 struct DevBase *base;
2669 struct IOSana2Req *request;
2670 ULONG dma_size;
2672 /* Find out which packets have completed */
2674 base = unit->device;
2675 new_out_slot = (unit->mgmt_in_slot + MGMT_SLOT_COUNT
2676 - unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no))
2677 % MGMT_SLOT_COUNT;
2679 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2680 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
2682 /* Retire sent frames */
2684 for(i = unit->mgmt_out_slot; i != new_out_slot;
2685 i = (i + 1) % MGMT_SLOT_COUNT)
2687 frame = unit->mgmt_buffers[i];
2688 dma_size = FRAME_BUFFER_SIZE;
2689 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2691 /* Reply request */
2693 request = unit->mgmt_requests[i];
2694 request->ios2_Req.io_Error = 0;
2695 ReplyMsg((APTR)request);
2698 unit->mgmt_out_slot = i;
2700 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2701 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2703 /* Restart downloads if they had stopped */
2705 if(unit->request_ports[MGMT_QUEUE]->mp_Flags == PA_IGNORE)
2706 Cause(&unit->mgmt_int);
2708 return;
2713 /****i* atheros5000.device/ResetHandler ************************************
2715 * NAME
2716 * ResetHandler -- Disable hardware before a reboot.
2718 * SYNOPSIS
2719 * ResetHandler(unit, int_code)
2721 * VOID ResetHandler(struct DevUnit *, APTR);
2723 ****************************************************************************
2727 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
2728 REG(a6, APTR int_code))
2730 if((unit->flags & UNITF_HAVEADAPTER) != 0)
2732 /* Disable frame transmission */
2734 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2735 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2737 /* Disable frame reception */
2739 unit->hal->ah_stopPcuReceive(unit->hal);
2740 unit->hal->ah_stopDmaReceive(unit->hal);
2742 /* Stop interrupts */
2744 unit->hal->ah_setInterrupts(unit->hal, 0);
2747 return;
2752 /****i* atheros5000.device/UpdateStats *************************************
2754 * NAME
2755 * UpdateStats
2757 * SYNOPSIS
2758 * UpdateStats(unit)
2760 * VOID UpdateStats(struct DevUnit *);
2762 * FUNCTION
2764 * INPUTS
2765 * unit - A unit of this device.
2767 * RESULT
2768 * None.
2770 ****************************************************************************
2774 VOID UpdateStats(struct DevUnit *unit, struct DevBase *base)
2776 /* Ask for and wait for stats */
2778 return;
2783 /****i* atheros5000.device/ReportEvents ************************************
2785 * NAME
2786 * ReportEvents
2788 * SYNOPSIS
2789 * ReportEvents(unit, events)
2791 * VOID ReportEvents(struct DevUnit *, ULONG);
2793 * FUNCTION
2795 * INPUTS
2796 * unit - A unit of this device.
2797 * events - A mask of events to report.
2799 * RESULT
2800 * None.
2802 ****************************************************************************
2806 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
2807 struct DevBase *base)
2809 struct IOSana2Req *request, *tail, *next_request;
2810 struct List *list;
2812 list = &unit->request_ports[EVENT_QUEUE]->mp_MsgList;
2813 next_request = (APTR)list->lh_Head;
2814 tail = (APTR)&list->lh_Tail;
2816 Disable();
2817 while(next_request != tail)
2819 request = next_request;
2820 next_request = (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2822 if((request->ios2_WireError & events) != 0)
2824 request->ios2_WireError = events;
2825 Remove((APTR)request);
2826 ReplyMsg((APTR)request);
2829 Enable();
2831 return;
2836 /****i* atheros5000.device/GetRadioBands ***********************************
2838 * NAME
2839 * GetRadioBands -- Get information on current network.
2841 * SYNOPSIS
2842 * tag_list = GetRadioBands(unit, pool)
2844 * struct TagItem *GetRadioBands(struct DevUnit *, APTR);
2846 * FUNCTION
2848 * INPUTS
2849 * unit - A unit of this device.
2850 * pool - A memory pool.
2852 * RESULT
2853 * None.
2855 ****************************************************************************
2859 #if 0
2860 struct TagItem *GetRadioBands(struct DevUnit *unit, APTR pool,
2861 struct DevBase *base)
2863 BYTE error = 0;
2864 struct Sana2RadioBand *bands;
2865 UWORD i;
2867 bands = AllocPooled(pool, sizeof(struct Sana2RadioBand) * 3);
2868 if(bands == NULL)
2869 error = S2ERR_NO_RESOURCES;
2871 if(error == 0)
2873 for(i = 0; i < 1; i++)
2875 bands[i] = AllocPooled(pool, sizeof(UWORD) * unit->channel_counts[S2BAND_B]);
2879 // if(error != 0)
2880 // bands = NULL;
2882 return bands;
2884 #endif
2888 /****i* atheros5000.device/UnitTask ****************************************
2890 * NAME
2891 * UnitTask
2893 * SYNOPSIS
2894 * UnitTask()
2896 * VOID UnitTask();
2898 * FUNCTION
2899 * Completes deferred requests, and handles card insertion and removal
2900 * in conjunction with the relevant interrupts.
2902 ****************************************************************************
2906 #ifdef __MORPHOS__
2907 #undef UnitTask
2908 #endif
2910 static VOID UnitTask(struct ExecBase *sys_base)
2912 struct Task *task;
2913 struct IORequest *request;
2914 struct DevUnit *unit;
2915 struct DevBase *base;
2916 struct MsgPort *general_port;
2917 ULONG signals = 0, wait_signals, card_removed_signal,
2918 card_inserted_signal, general_port_signal;
2920 /* Get parameters */
2922 task = AbsExecBase->ThisTask;
2923 unit = task->tc_UserData;
2924 base = unit->device;
2926 /* Activate general request port */
2928 general_port = unit->request_ports[GENERAL_QUEUE];
2929 general_port->mp_SigTask = task;
2930 general_port->mp_SigBit = AllocSignal(-1);
2931 general_port_signal = 1 << general_port->mp_SigBit;
2932 general_port->mp_Flags = PA_SIGNAL;
2934 /* Allocate signals for notification of card removal and insertion */
2936 card_removed_signal = unit->card_removed_signal = 1 << AllocSignal(-1);
2937 card_inserted_signal = unit->card_inserted_signal = 1 << AllocSignal(-1);
2938 wait_signals = (1 << general_port->mp_SigBit) | card_removed_signal
2939 | card_inserted_signal | SIGBREAKF_CTRL_C;
2941 /* Tell ourselves to check port for old messages */
2943 Signal(task, general_port_signal);
2945 /* Infinite loop to service requests and signals */
2947 while((signals & SIGBREAKF_CTRL_C) == 0)
2949 signals = Wait(wait_signals);
2951 if((signals & card_inserted_signal) != 0)
2953 if(unit->insertion_function(unit->card, base))
2955 unit->flags |= UNITF_HAVEADAPTER;
2956 if((unit->flags & UNITF_CONFIGURED) != 0)
2957 ConfigureAdapter(unit, base);
2958 if((unit->flags & UNITF_WASONLINE) != 0)
2960 GoOnline(unit, base);
2961 unit->flags &= ~UNITF_WASONLINE;
2966 if((signals & card_removed_signal) != 0)
2968 unit->removal_function(unit->card, base);
2969 if((unit->flags & UNITF_WASONLINE) != 0)
2970 GoOffline(unit, base);
2973 if((signals & general_port_signal) != 0)
2975 while((request = (APTR)GetMsg(general_port)) != NULL)
2977 /* Service the request as soon as the unit is free */
2979 ObtainSemaphore(&unit->access_lock);
2980 ServiceRequest((APTR)request, base);
2985 FreeMem(task->tc_SPLower, STACK_SIZE);