Added two wireless drivers: atheros5000.device and realtek8180.device.
[AROS.git] / workbench / devs / networks / atheros5000 / unit.c
blob33b10ee60a24fe651bda70269fc4ab626bb7ad7a
1 /*
3 Copyright (C) 2001-2011 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 (*(struct ExecBase **)4)
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();
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
116 /****i* atheros5000.device/CreateUnit **************************************
118 * NAME
119 * CreateUnit -- Create a unit.
121 * SYNOPSIS
122 * unit = CreateUnit(index, io_base, id, card,
123 * io_tags, bus)
125 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
126 * struct TagItem *, UWORD);
128 * FUNCTION
129 * Creates a new unit.
131 ****************************************************************************
135 struct DevUnit *CreateUnit(ULONG index, APTR io_base, UWORD id, APTR card,
136 const struct TagItem *io_tags, UWORD bus, struct DevBase *base)
138 BOOL success = TRUE;
139 struct DevUnit *unit;
140 struct Task *task;
141 struct MsgPort *port;
142 UWORD i;
143 struct ath_desc *tx_desc, *rx_desc;
144 ULONG dma_size;
145 APTR stack;
146 HAL_STATUS hal_status;
148 unit = AllocMem(sizeof(struct DevUnit), MEMF_CLEAR | MEMF_PUBLIC);
149 if(unit == NULL)
150 success = FALSE;
152 if(success)
154 /* Initialise lists etc. */
156 NewList((APTR)&unit->openers);
157 NewList((APTR)&unit->type_trackers);
158 NewList((APTR)&unit->multicast_ranges);
160 unit->index = index;
161 unit->device = base;
162 unit->card = card;
163 unit->bus = bus;
165 /* Store DMA memory hooks */
167 unit->AllocDMAMem =
168 (APTR)GetTagData(IOTAG_AllocDMAMem, (UPINT)NULL, io_tags);
169 unit->FreeDMAMem =
170 (APTR)GetTagData(IOTAG_FreeDMAMem, (UPINT)NULL, io_tags);
171 if(unit->AllocDMAMem == NULL || unit->FreeDMAMem == NULL)
172 success = FALSE;
175 if(success)
177 /* Initialise HAL */
179 unit->hal = ath_hal_attach(id, unit, NULL, io_base, &hal_status);
181 if(unit->hal == NULL)
182 success = FALSE;
185 if(success)
187 InitSemaphore(&unit->access_lock);
189 /* Create the message ports for queuing requests */
191 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
193 unit->request_ports[i] = port = AllocMem(sizeof(struct MsgPort),
194 MEMF_PUBLIC | MEMF_CLEAR);
195 if(port == NULL)
196 success = FALSE;
198 if(success)
200 NewList(&port->mp_MsgList);
201 port->mp_Flags = PA_IGNORE;
205 if(success)
207 unit->request_ports[WRITE_QUEUE]->mp_SigTask = &unit->tx_int;
208 unit->request_ports[MGMT_QUEUE]->mp_SigTask = &unit->mgmt_int;
211 /* Allocate buffers and descriptors */
213 unit->tx_buffer = AllocVec(ETH_MAXPACKETSIZE, MEMF_PUBLIC);
214 for(i = 0; i < TX_SLOT_COUNT; i++)
216 unit->tx_buffers[i] =
217 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
218 if(unit->tx_buffers[i] == NULL)
219 success = FALSE;
221 for(i = 0; i < MGMT_SLOT_COUNT; i++)
223 unit->mgmt_buffers[i] =
224 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
225 if(unit->mgmt_buffers[i] == NULL)
226 success = FALSE;
228 unit->rx_buffer = AllocVec(FRAME_BUFFER_SIZE, MEMF_PUBLIC);
229 for(i = 0; i < RX_SLOT_COUNT; i++)
231 unit->rx_buffers[i] =
232 unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
233 if(unit->rx_buffers[i] == NULL)
234 success = FALSE;
236 unit->rx_frames =
237 AllocVec(FRAME_BUFFER_SIZE * FRAME_BUFFER_COUNT, MEMF_PUBLIC);
238 for(i = 0; i < FRAME_BUFFER_COUNT; i++)
239 unit->rx_fragment_nos[i] = -1;
240 unit->tx_descs = unit->AllocDMAMem(unit->card,
241 sizeof(struct ath_desc) * TX_SLOT_COUNT, 4);
242 unit->mgmt_descs = unit->AllocDMAMem(unit->card,
243 sizeof(struct ath_desc) * MGMT_SLOT_COUNT, 4);
244 unit->rx_descs = unit->AllocDMAMem(unit->card,
245 sizeof(struct ath_desc) * RX_SLOT_COUNT, 4);
246 unit->tx_requests = AllocVec(sizeof(APTR) * TX_SLOT_COUNT,
247 MEMF_PUBLIC);
248 unit->mgmt_requests = AllocVec(sizeof(APTR) * MGMT_SLOT_COUNT,
249 MEMF_PUBLIC);
250 unit->channels = AllocVec(sizeof(HAL_CHANNEL) * MAX_CHANNEL_COUNT,
251 MEMF_PUBLIC | MEMF_CLEAR);
252 if(unit->tx_buffer == NULL
253 || unit->rx_buffer == NULL
254 || unit->rx_frames == NULL
255 || unit->tx_descs == NULL
256 || unit->mgmt_descs == NULL
257 || unit->rx_descs == NULL
258 || unit->tx_requests == NULL
259 || unit->mgmt_requests == NULL
260 || unit->channels == NULL)
261 success = FALSE;
264 if(success)
266 /* Initialise network adapter hardware */
268 success = InitialiseAdapter(unit, FALSE, base);
269 unit->flags |= UNITF_HAVEADAPTER;
272 if(success)
274 /* Get physical addresses of DMA structures */
276 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
277 unit->tx_descs_p = (ULONG)CachePreDMA(unit->tx_descs, &dma_size, 0);
278 if(dma_size != sizeof(struct ath_desc) * TX_SLOT_COUNT)
279 success = FALSE;
280 CachePostDMA(unit->tx_descs, &dma_size, 0);
282 for(i = 0; i < TX_SLOT_COUNT; i++)
284 dma_size = FRAME_BUFFER_SIZE;
285 unit->tx_buffers_p[i] =
286 (ULONG)CachePreDMA(unit->tx_buffers[i], &dma_size, 0);
287 if(dma_size != FRAME_BUFFER_SIZE)
288 success = FALSE;
289 CachePostDMA(unit->tx_buffers[i], &dma_size, 0);
292 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
293 unit->mgmt_descs_p =
294 (ULONG)CachePreDMA(unit->mgmt_descs, &dma_size, 0);
295 if(dma_size != sizeof(struct ath_desc) * MGMT_SLOT_COUNT)
296 success = FALSE;
297 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
299 for(i = 0; i < MGMT_SLOT_COUNT; i++)
301 dma_size = FRAME_BUFFER_SIZE;
302 unit->mgmt_buffers_p[i] =
303 (ULONG)CachePreDMA(unit->mgmt_buffers[i], &dma_size, 0);
304 if(dma_size != FRAME_BUFFER_SIZE)
305 success = FALSE;
306 CachePostDMA(unit->mgmt_buffers[i], &dma_size, 0);
309 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
310 unit->rx_descs_p = (ULONG)CachePreDMA(unit->rx_descs, &dma_size, 0);
311 if(dma_size != sizeof(struct ath_desc) * RX_SLOT_COUNT)
312 success = FALSE;
313 CachePostDMA(unit->rx_descs, &dma_size, 0);
315 for(i = 0; i < RX_SLOT_COUNT; i++)
317 dma_size = FRAME_BUFFER_SIZE;
318 unit->rx_buffers_p[i] =
319 (ULONG)CachePreDMA(unit->rx_buffers[i], &dma_size, 0);
320 if(dma_size != FRAME_BUFFER_SIZE)
321 success = FALSE;
322 CachePostDMA(unit->rx_buffers[i], &dma_size, 0);
325 /* Construct TX ring */
327 for(tx_desc = unit->tx_descs, i = 0; i < TX_SLOT_COUNT; i++)
329 tx_desc->ds_data = unit->tx_buffers_p[i];
330 tx_desc++;
333 /* Construct management frame TX ring */
335 for(tx_desc = unit->mgmt_descs, i = 0; i < MGMT_SLOT_COUNT; i++)
337 tx_desc->ds_data = unit->mgmt_buffers_p[i];
338 tx_desc++;
341 /* Construct RX ring */
343 for(rx_desc = unit->rx_descs, i = 0; i < RX_SLOT_COUNT; i++)
345 rx_desc->ds_link = unit->rx_descs_p + ((i + 1) % RX_SLOT_COUNT)
346 * sizeof(struct ath_desc);
347 rx_desc->ds_data = unit->rx_buffers_p[i];
348 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
349 HAL_RXDESC_INTREQ);
350 rx_desc++;
353 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
354 CachePreDMA(unit->rx_descs, &dma_size, 0);
356 /* Record maximum speed in BPS */
358 unit->speed = 54000000;
360 /* Initialise status, transmit, receive and stats interrupts */
362 unit->status_int.is_Node.ln_Name =
363 base->device.dd_Library.lib_Node.ln_Name;
364 unit->status_int.is_Code = (APTR)StatusInt;
365 unit->status_int.is_Data = unit;
367 unit->rx_int.is_Node.ln_Name =
368 base->device.dd_Library.lib_Node.ln_Name;
369 unit->rx_int.is_Code = (APTR)RXInt;
370 unit->rx_int.is_Data = unit;
372 unit->tx_int.is_Node.ln_Name =
373 base->device.dd_Library.lib_Node.ln_Name;
374 unit->tx_int.is_Code = (APTR)TXInt;
375 unit->tx_int.is_Data = unit;
377 unit->tx_end_int.is_Node.ln_Name =
378 base->device.dd_Library.lib_Node.ln_Name;
379 unit->tx_end_int.is_Code = (APTR)TXEndInt;
380 unit->tx_end_int.is_Data = unit;
382 unit->mgmt_int.is_Node.ln_Name =
383 base->device.dd_Library.lib_Node.ln_Name;
384 unit->mgmt_int.is_Code = (APTR)MgmtTXInt;
385 unit->mgmt_int.is_Data = unit;
387 unit->mgmt_end_int.is_Node.ln_Name =
388 base->device.dd_Library.lib_Node.ln_Name;
389 unit->mgmt_end_int.is_Code = (APTR)MgmtTXEndInt;
390 unit->mgmt_end_int.is_Data = unit;
392 unit->reset_handler.is_Node.ln_Name =
393 base->device.dd_Library.lib_Node.ln_Name;
394 unit->reset_handler.is_Code = (APTR)ResetHandler;
395 unit->reset_handler.is_Data = unit;
397 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
398 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
400 /* Create a new task */
402 unit->task = task =
403 AllocMem(sizeof(struct Task), MEMF_PUBLIC | MEMF_CLEAR);
404 if(task == NULL)
405 success = FALSE;
408 if(success)
410 stack = AllocMem(STACK_SIZE, MEMF_PUBLIC);
411 if(stack == NULL)
412 success = FALSE;
415 if(success)
417 /* Initialise and start task */
419 task->tc_Node.ln_Type = NT_TASK;
420 task->tc_Node.ln_Pri = TASK_PRIORITY;
421 task->tc_Node.ln_Name = base->device.dd_Library.lib_Node.ln_Name;
422 task->tc_SPUpper = stack + STACK_SIZE;
423 task->tc_SPLower = stack;
424 task->tc_SPReg = stack + STACK_SIZE;
425 NewList(&task->tc_MemEntry);
427 if(AddTask(task, UnitTask, NULL) == NULL)
428 success = FALSE;
431 if(success)
433 /* Send the unit to the new task */
435 task->tc_UserData = unit;
437 /* Set default wireless options */
439 unit->mode = S2PORT_MANAGED;
442 if(!success)
444 DeleteUnit(unit, base);
445 unit = NULL;
448 return unit;
453 /****i* atheros5000.device/DeleteUnit **************************************
455 * NAME
456 * DeleteUnit -- Delete a unit.
458 * SYNOPSIS
459 * DeleteUnit(unit)
461 * VOID DeleteUnit(struct DevUnit *);
463 * FUNCTION
464 * Deletes a unit.
466 * INPUTS
467 * unit - Device unit (may be NULL).
469 * RESULT
470 * None.
472 ****************************************************************************
476 VOID DeleteUnit(struct DevUnit *unit, struct DevBase *base)
478 UBYTE i;
479 struct Task *task;
481 if(unit != NULL)
483 task = unit->task;
484 if(task != NULL)
486 if(task->tc_UserData != NULL)
488 RemTask(task);
489 FreeMem(task->tc_SPLower, STACK_SIZE);
490 Signal(unit->task, SIGBREAKF_CTRL_C);
492 FreeMem(task, sizeof(struct Task));
495 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
497 if(unit->request_ports[i] != NULL)
498 FreeMem(unit->request_ports[i], sizeof(struct MsgPort));
501 if((unit->flags & UNITF_ONLINE) != 0) /* Needed! */
502 GoOffline(unit, base);
504 for(i = 0; i < TX_SLOT_COUNT; i++)
505 unit->FreeDMAMem(unit->card, unit->tx_buffers[i]);
506 for(i = 0; i < MGMT_SLOT_COUNT; i++)
507 unit->FreeDMAMem(unit->card, unit->mgmt_buffers[i]);
508 for(i = 0; i < RX_SLOT_COUNT; i++)
509 unit->FreeDMAMem(unit->card, unit->rx_buffers[i]);
511 FreeVec(unit->tx_buffer);
512 FreeVec(unit->rx_frames);
513 FreeVec(unit->tx_requests);
514 FreeVec(unit->mgmt_requests);
515 FreeVec(unit->channels);
516 FreeVec(unit->rx_buffer);
518 if(unit->hal != NULL)
519 unit->hal->ah_detach(unit->hal);
521 FreeMem(unit, sizeof(struct DevUnit));
524 return;
529 /****i* atheros5000.device/InitialiseAdapter *******************************
531 * NAME
532 * InitialiseAdapter
534 * SYNOPSIS
535 * success = InitialiseAdapter(unit, reinsertion)
537 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
539 * FUNCTION
541 * INPUTS
542 * unit
543 * reinsertion
545 * RESULT
546 * success - Success indicator.
548 ****************************************************************************
552 BOOL InitialiseAdapter(struct DevUnit *unit, BOOL reinsertion,
553 struct DevBase *base)
555 UBYTE i, reg_class_id;
556 BOOL success = TRUE;
557 unsigned int channel_count, reg_class_count;
558 HAL_TXQ_INFO queue_info = {0};
560 /* Get default MAC address */
562 unit->hal->ah_getMacAddress(unit->hal, unit->default_address);
564 /* Get default antenna */
566 unit->antenna = unit->hal->ah_getDefAntenna(unit->hal);
568 /* Reset key cache */
570 for(i = 0; i < WIFI_KEYCOUNT; i++)
571 unit->hal->ah_resetKeyCacheEntry(unit->hal, i);
573 /* Initialise channels and rates */
575 ath_hal_init_channels(unit->hal, unit->channels,
576 MAX_CHANNEL_COUNT, &channel_count,
577 &reg_class_id, 1, &reg_class_count, CTRY_DEFAULT,
578 HAL_MODE_11B | HAL_MODE_PUREG, TRUE,
579 FALSE);
580 unit->channel_count = channel_count;
582 unit->channel = 1;
583 unit->band = S2BAND_B;
585 /* Check if multi-rate retries are supported */
587 if(unit->hal->ah_setupXTxDesc(unit->hal, NULL, 0, 0, 0, 0, 0, 0))
588 unit->flags |= UNITF_SLOWRETRIES;
590 /* Set up TX queue */
592 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
593 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
594 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
595 queue_info.tqi_qflags =
596 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
598 unit->tx_queue_no =
599 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
600 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
602 /* Set up management frame TX queue */
604 queue_info.tqi_aifs = HAL_TXQ_USEDEFAULT;
605 queue_info.tqi_cwmin = HAL_TXQ_USEDEFAULT;
606 queue_info.tqi_cwmax = HAL_TXQ_USEDEFAULT;
607 queue_info.tqi_qflags =
608 HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE;
610 unit->mgmt_queue_no =
611 unit->hal->ah_setupTxQueue(unit->hal, HAL_TX_QUEUE_DATA, &queue_info);
612 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
614 /* Find out hardware encryption capabilities */
616 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
617 HAL_CIPHER_WEP, NULL) == HAL_OK)
618 unit->flags |= UNITF_HARDWEP;
619 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
620 HAL_CIPHER_TKIP, NULL) == HAL_OK)
621 unit->flags |= UNITF_HARDTKIP;
622 #if 1
623 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
624 HAL_CIPHER_MIC, NULL) == HAL_OK)
626 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
627 // 0, TRUE, NULL))
628 0, 0, NULL))
629 unit->flags |= UNITF_HARDMIC;
631 #else
632 if(unit->hal->ah_setCapability(unit->hal, HAL_CAP_TKIP_MIC,
633 0, FALSE, NULL))
634 #endif
635 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_TKIP_SPLIT, 0,
636 NULL) == HAL_OK)
637 unit->flags |= UNITF_SPLITMIC;
638 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
639 HAL_CIPHER_AES_OCB, NULL) == HAL_OK)
640 unit->flags |= UNITF_HARDAESOCB;
641 if(unit->hal->ah_getCapability(unit->hal, HAL_CAP_CIPHER,
642 HAL_CIPHER_AES_CCM, NULL) == HAL_OK)
643 unit->flags |= UNITF_HARDCCMP;
645 /* Set IV sizes */
647 unit->iv_sizes[S2ENC_WEP] = IV_SIZE;
648 unit->iv_sizes[S2ENC_TKIP] = EIV_SIZE;
649 unit->iv_sizes[S2ENC_CCMP] = EIV_SIZE;
651 /* Set encryption functions */
653 unit->fragment_encrypt_functions[S2ENC_NONE] = WriteClearFragment;
655 if((unit->flags & UNITF_HARDWEP) != 0)
656 unit->fragment_encrypt_functions[S2ENC_WEP] = WriteWEPFragment;
657 else
658 unit->fragment_encrypt_functions[S2ENC_WEP] = EncryptWEPFragment;
660 if((unit->flags & UNITF_HARDTKIP) != 0)
661 unit->fragment_encrypt_functions[S2ENC_TKIP] = WriteTKIPFragment;
662 else
663 unit->fragment_encrypt_functions[S2ENC_TKIP] = EncryptTKIPFragment;
665 if((unit->flags & UNITF_HARDCCMP) != 0)
666 unit->fragment_encrypt_functions[S2ENC_CCMP] = WriteCCMPFragment;
667 else
668 unit->fragment_encrypt_functions[S2ENC_CCMP] = EncryptCCMPFragment;
670 /* Set decryption functions */
672 unit->fragment_decrypt_functions[S2ENC_NONE] = ReadClearFragment;
674 if((unit->flags & UNITF_HARDWEP) != 0)
675 unit->fragment_decrypt_functions[S2ENC_WEP] = ReadWEPFragment;
676 else
677 unit->fragment_decrypt_functions[S2ENC_WEP] = DecryptWEPFragment;
679 if((unit->flags & UNITF_HARDTKIP) != 0)
680 unit->fragment_decrypt_functions[S2ENC_TKIP] = ReadTKIPFragment;
681 else
682 unit->fragment_decrypt_functions[S2ENC_TKIP] = DecryptTKIPFragment;
684 if((unit->flags & UNITF_HARDCCMP) != 0)
685 unit->fragment_decrypt_functions[S2ENC_CCMP] = ReadCCMPFragment;
686 else
687 unit->fragment_decrypt_functions[S2ENC_CCMP] = DecryptCCMPFragment;
689 /* Return */
691 return success;
696 /****i* atheros5000.device/ConfigureAdapter ********************************
698 * NAME
699 * ConfigureAdapter -- Set up card for transmission/reception.
701 * SYNOPSIS
702 * ConfigureAdapter(unit)
704 * VOID ConfigureAdapter(struct DevUnit *);
706 ****************************************************************************
710 VOID ConfigureAdapter(struct DevUnit *unit, struct DevBase *base)
712 UWORD i, j, key_length, hal_band, key_type;
713 const struct KeyUnion *keys;
714 HAL_CHANNEL *channel = unit->channels, *ch;
715 ULONG freq = 2407 + unit->channel * 5;
716 HAL_STATUS status;
717 HAL_KEYVAL hal_key;
718 HAL_BOOL iq_done;
719 const HAL_RATE_TABLE *rate_table;
721 /* Get band-specific parameters */
723 if(unit->band == S2BAND_G)
725 hal_band = HAL_MODE_11G;
726 unit->band_mask = CHANNEL_G;
727 unit->tx_rates = g_retry_rates;
728 unit->mgmt_rate = G_MGMT_RATE;
730 else if(unit->band == S2BAND_B)
732 hal_band = HAL_MODE_11B;
733 unit->band_mask = CHANNEL_B;
734 unit->tx_rates = b_retry_rates;
735 unit->mgmt_rate = B_MGMT_RATE;
737 unit->rate_table = unit->hal->ah_getRateTable(unit->hal, hal_band);
739 /* Find rate codes to match our optimal and retry rates */
741 rate_table = unit->rate_table;
742 for(i = 0; i < rate_table->rateCount; i++)
744 for(j = 0; j < 4; j++)
746 if(rate_table->info[i].rateKbps == unit->tx_rates[j])
748 unit->tx_rate_codes[j] = rate_table->info[i].rateCode;
749 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
750 unit->tx_rate_codes[j] |= rate_table->info[i].shortPreamble;
753 if(rate_table->info[i].rateKbps == unit->mgmt_rate)
755 unit->mgmt_rate_code = rate_table->info[i].rateCode;
756 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
757 unit->mgmt_rate_code |= rate_table->info[i].shortPreamble;
761 /* Find a channel that matches requirements */
763 for(i = 0, ch = unit->channels; i < unit->channel_count; i++, ch++)
765 if(ch->channel == freq
766 && (ch->channelFlags & unit->band_mask) == unit->band_mask)
767 channel = ch;
770 /* Stop the transceiver if we're already online */
772 if((unit->flags & UNITF_ONLINE) != 0)
774 /* Disable frame transmission */
776 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
777 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
778 unit->hal->ah_setRxFilter(unit->hal, 0);
779 ath_hal_delay(3000);
781 /* Disable frame reception */
783 unit->hal->ah_stopPcuReceive(unit->hal);
784 unit->hal->ah_stopDmaReceive(unit->hal);
786 /* Disable interrupts */
788 unit->hal->ah_setInterrupts(unit->hal, 0);
791 /* Calculate RX filter mask */
793 unit->filter_mask = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_MCAST
794 | HAL_RX_FILTER_BCAST;
795 if((unit->flags & UNITF_PROM) != 0)
796 unit->filter_mask |= HAL_RX_FILTER_PROM;
797 if(unit->mode != S2PORT_MANAGED)
798 unit->filter_mask |= HAL_RX_FILTER_PROBEREQ;
800 /* Reset card */
802 unit->hal->ah_reset(unit->hal, HAL_M_STA, channel, FALSE, &status);
804 /* Set MAC address and miscellaneous wireless parameters */
806 unit->hal->ah_setMacAddress(unit->hal, unit->address);
807 unit->hal->ah_setPCUConfig(unit->hal);
808 SetMulticast(unit, base);
809 unit->hal->ah_setDefAntenna(unit->hal, unit->antenna);
810 unit->hal->ah_perCalibration(unit->hal, channel, &iq_done);
811 unit->hal->ah_setTxPowerLimit(unit->hal, TX_POWER);
813 /* Set association ID */
815 unit->hal->ah_writeAssocid(unit->hal, unit->bssid, unit->assoc_id);
817 /* Put on a reassuring light */
819 unit->hal->ah_setLedState(unit->hal, HAL_LED_RUN);
821 /* Set or clear default encryption keys where appropriate */
823 keys = unit->keys;
824 for(i = 0; i < WIFI_KEYCOUNT; i++)
826 key_type = unit->keys[i].type;
827 if(key_type <= S2ENC_WEP
828 || key_type == S2ENC_TKIP && (unit->flags & UNITF_HARDTKIP) == 0
829 || key_type == S2ENC_CCMP && (unit->flags & UNITF_HARDCCMP) == 0)
831 if(key_type == S2ENC_WEP && (unit->flags & UNITF_HARDWEP) != 0)
833 hal_key.kv_type = HAL_CIPHER_WEP;
834 key_length = keys[i].u.wep.length;
835 CopyMem(keys[i].u.wep.key, hal_key.kv_val, key_length);
837 else
839 hal_key.kv_type = HAL_CIPHER_CLR;
840 key_length = 0;
842 hal_key.kv_len = key_length;
843 unit->hal->ah_setKeyCacheEntry(unit->hal, i, &hal_key,
844 unit->bssid, FALSE);
848 /* Set pointer to RX ring */
850 unit->hal->ah_setRxDP(unit->hal,
851 unit->rx_descs_p + unit->rx_slot * sizeof(struct ath_desc));
853 /* Restart the transceiver if we're already online */
855 if((unit->flags & UNITF_ONLINE) != 0)
857 /* Enable interrupts */
859 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
861 /* Enable frame reception */
863 unit->hal->ah_enableReceive(unit->hal);
864 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
865 unit->hal->ah_startPcuReceive(unit->hal);
867 #if 0
868 /* Reset TX queues */
870 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
871 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
872 #endif
875 /* Return */
877 return;
882 /****i* atheros5000.device/GoOnline ****************************************
884 * NAME
885 * GoOnline -- Enable transmission/reception.
887 * SYNOPSIS
888 * GoOnline(unit)
890 * VOID GoOnline(struct DevUnit *);
892 ****************************************************************************
896 VOID GoOnline(struct DevUnit *unit, struct DevBase *base)
898 /* Enable interrupts */
900 unit->flags |= UNITF_ONLINE;
901 unit->hal->ah_setInterrupts(unit->hal, INT_MASK);
903 /* Enable frame reception */
905 unit->hal->ah_enableReceive(unit->hal);
906 unit->hal->ah_setRxFilter(unit->hal, unit->filter_mask);
907 unit->hal->ah_startPcuReceive(unit->hal);
909 #if 0
910 /* Reset TX queues */
912 unit->hal->ah_resetTxQueue(unit->hal, unit->tx_queue_no);
913 unit->hal->ah_resetTxQueue(unit->hal, unit->mgmt_queue_no);
914 #endif
916 /* Record start time and report Online event */
918 GetSysTime(&unit->stats.LastStart);
919 ReportEvents(unit, S2EVENT_ONLINE, base);
921 return;
926 /****i* atheros5000.device/GoOffline ***************************************
928 * NAME
929 * GoOffline -- Disable transmission/reception.
931 * SYNOPSIS
932 * GoOffline(unit)
934 * VOID GoOffline(struct DevUnit *);
936 * FUNCTION
938 * INPUTS
939 * unit
941 * RESULT
942 * None.
944 ****************************************************************************
948 VOID GoOffline(struct DevUnit *unit, struct DevBase *base)
950 unit->flags &= ~UNITF_ONLINE;
951 if((unit->flags & UNITF_HAVEADAPTER) != 0)
953 /* Disable frame transmission */
955 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
956 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
958 /* Disable frame reception */
960 unit->hal->ah_stopPcuReceive(unit->hal);
961 unit->hal->ah_stopDmaReceive(unit->hal);
962 unit->hal->ah_setRxFilter(unit->hal, 0);
963 ath_hal_delay(3000);
965 /* Stop interrupts */
967 unit->hal->ah_setInterrupts(unit->hal, 0);
969 /* Update statistics */
971 UpdateStats(unit, base);
974 /* Flush pending read and write requests */
976 FlushUnit(unit, MGMT_QUEUE, S2ERR_OUTOFSERVICE, base);
978 /* Report Offline event and return */
980 ReportEvents(unit, S2EVENT_OFFLINE, base);
981 return;
986 /****i* atheros5000.device/SetOptions **************************************
988 * NAME
989 * SetOptions -- Set and use interface options.
991 * SYNOPSIS
992 * reconfigure = SetOptions(unit, tag_list)
994 * BOOL SetOptions(struct DevUnit *, struct TagItem *);
996 ****************************************************************************
1000 BOOL SetOptions(struct DevUnit *unit, const struct TagItem *tag_list,
1001 struct DevBase *base)
1003 const struct TagItem *tag_item, *tlist = tag_list;
1004 BOOL reconfigure = TRUE;
1006 while((tag_item = NextTagItem(&tlist)) != NULL)
1008 switch(tag_item->ti_Tag)
1010 case S2INFO_BSSID:
1011 CopyMem((APTR)tag_item->ti_Data, unit->bssid, ETH_ADDRESSSIZE);
1012 break;
1014 case S2INFO_AssocID:
1015 unit->assoc_id = tag_item->ti_Data;
1016 break;
1018 case S2INFO_Capabilities:
1019 unit->capabilities = tag_item->ti_Data;
1020 if((unit->capabilities & (1 << 5)) != 0)
1021 unit->flags |= UNITF_SHORTPREAMBLE;
1022 else
1023 unit->flags &= ~UNITF_SHORTPREAMBLE;
1024 break;
1026 case S2INFO_DefaultKeyNo:
1027 unit->tx_key_no = tag_item->ti_Data;
1028 break;
1030 case S2INFO_PortType:
1031 unit->mode = tag_item->ti_Data;
1032 break;
1034 case S2INFO_Channel:
1035 if(tag_item->ti_Data != unit->channel)
1037 unit->channel = tag_item->ti_Data;
1038 reconfigure = TRUE;
1040 break;
1042 case S2INFO_Band:
1043 if(tag_item->ti_Data != unit->band)
1045 unit->band = tag_item->ti_Data;
1046 reconfigure = TRUE;
1048 break;
1052 return reconfigure;
1057 /****i* atheros5000.device/SetKey ******************************************
1059 * NAME
1060 * SetKey -- Set an encryption key.
1062 * SYNOPSIS
1063 * SetKey(unit, index, type, key, key_length,
1064 * rx_counter)
1066 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
1067 * UBYTE *);
1069 ****************************************************************************
1073 VOID SetKey(struct DevUnit *unit, ULONG index, ULONG type, const UBYTE *key,
1074 ULONG key_length, const UBYTE *rx_counter, struct DevBase *base)
1076 struct KeyUnion *slot;
1077 struct EClockVal eclock;
1078 HAL_KEYVAL hal_key;
1079 UWORD i;
1081 Disable();
1082 slot = &unit->keys[index];
1083 switch(type)
1085 case S2ENC_WEP:
1086 CopyMem(key, slot->u.wep.key, key_length);
1087 slot->u.wep.length = key_length;
1089 if((unit->flags & UNITF_HARDWEP) == 0)
1091 /* Create a reasonably random IV */
1093 ReadEClock(&eclock);
1094 slot->u.wep.tx_iv = FastRand(eclock.ev_lo ^ eclock.ev_hi);
1097 break;
1099 case S2ENC_TKIP:
1100 CopyMem(key, slot->u.tkip.key, 16);
1101 CopyMem(key + 16, slot->u.tkip.tx_mic_key, MIC_SIZE);
1102 CopyMem(key + 24, slot->u.tkip.rx_mic_key, MIC_SIZE);
1103 slot->u.tkip.tx_iv_low = 0;
1104 slot->u.tkip.tx_iv_high = 0;
1105 slot->u.tkip.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1106 slot->u.tkip.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1107 slot->u.tkip.tx_ttak_set = FALSE;
1108 slot->u.tkip.rx_ttak_set = FALSE;
1110 if((unit->flags & UNITF_HARDTKIP) != 0)
1112 // TO DO: Wait for TX queue to empty
1113 /* Load parameters for hardware encryption */
1115 hal_key.kv_type = HAL_CIPHER_TKIP;
1116 hal_key.kv_len = 16;
1117 CopyMem(slot->u.tkip.key, hal_key.kv_val, 16);
1119 CopyMem(slot->u.tkip.tx_mic_key, hal_key.kv_mic, MIC_SIZE);
1120 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1121 unit->bssid, FALSE);
1122 CopyMem(slot->u.tkip.rx_mic_key, hal_key.kv_mic, MIC_SIZE);
1123 unit->hal->ah_setKeyCacheEntry(unit->hal, index + 32, &hal_key,
1124 unit->bssid, FALSE);
1126 else
1128 /* Convert key to native endianness */
1130 for(i = 0; i < 8; i++)
1131 slot->u.tkip.key[i] = LEWord(slot->u.tkip.key[i]);
1134 break;
1136 case S2ENC_CCMP:
1137 CopyMem(key, slot->u.ccmp.key, 16);
1138 slot->u.ccmp.tx_iv_low = 0;
1139 slot->u.ccmp.tx_iv_high = 0;
1140 slot->u.ccmp.rx_iv_low = LEWord(*(UWORD *)rx_counter);
1141 slot->u.ccmp.rx_iv_high = LELong(*(ULONG *)(rx_counter + 2));
1142 slot->u.ccmp.stream_set = FALSE;
1144 if((unit->flags & UNITF_HARDCCMP) != 0)
1146 // TO DO: Wait for TX queue to empty
1147 /* Load parameters for hardware encryption */
1149 hal_key.kv_type = HAL_CIPHER_AES_CCM;
1150 hal_key.kv_len = 16;
1151 CopyMem(slot->u.ccmp.key, hal_key.kv_val, 16);
1152 unit->hal->ah_setKeyCacheEntry(unit->hal, index, &hal_key,
1153 unit->bssid, FALSE);
1157 /* Update type of key in selected slot */
1159 slot->type = type;
1160 Enable();
1162 return;
1167 /****i* atheros5000.device/AddMulticastRange *******************************
1169 * NAME
1170 * AddMulticastRange
1172 * SYNOPSIS
1173 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1175 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1177 ****************************************************************************
1181 BOOL AddMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1182 const UBYTE *upper_bound, struct DevBase *base)
1184 struct AddressRange *range;
1185 ULONG lower_bound_left, upper_bound_left;
1186 UWORD lower_bound_right, upper_bound_right;
1188 lower_bound_left = BELong(*((ULONG *)lower_bound));
1189 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1190 upper_bound_left = BELong(*((ULONG *)upper_bound));
1191 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1193 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1194 upper_bound_left, upper_bound_right, base);
1196 if(range != NULL)
1197 range->add_count++;
1198 else
1200 range = AllocMem(sizeof(struct AddressRange), MEMF_PUBLIC);
1201 if(range != NULL)
1203 range->lower_bound_left = lower_bound_left;
1204 range->lower_bound_right = lower_bound_right;
1205 range->upper_bound_left = upper_bound_left;
1206 range->upper_bound_right = upper_bound_right;
1207 range->add_count = 1;
1209 Disable();
1210 AddTail((APTR)&unit->multicast_ranges, (APTR)range);
1211 unit->range_count++;
1212 SetMulticast(unit, base);
1213 Enable();
1217 return range != NULL;
1222 /****i* atheros5000.device/RemMulticastRange *******************************
1224 * NAME
1225 * RemMulticastRange
1227 * SYNOPSIS
1228 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1230 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1232 ****************************************************************************
1236 BOOL RemMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
1237 const UBYTE *upper_bound, struct DevBase *base)
1239 struct AddressRange *range;
1240 ULONG lower_bound_left, upper_bound_left;
1241 UWORD lower_bound_right, upper_bound_right;
1243 lower_bound_left = BELong(*((ULONG *)lower_bound));
1244 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
1245 upper_bound_left = BELong(*((ULONG *)upper_bound));
1246 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
1248 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
1249 upper_bound_left, upper_bound_right, base);
1251 if(range != NULL)
1253 if(--range->add_count == 0)
1255 Disable();
1256 Remove((APTR)range);
1257 unit->range_count--;
1258 SetMulticast(unit, base);
1259 Enable();
1260 FreeMem(range, sizeof(struct AddressRange));
1264 return range != NULL;
1269 /****i* atheros5000.device/FindMulticastRange ******************************
1271 * NAME
1272 * FindMulticastRange
1274 * SYNOPSIS
1275 * range = FindMulticastRange(unit, lower_bound_left,
1276 * lower_bound_right, upper_bound_left, upper_bound_right)
1278 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1279 * UWORD, ULONG, UWORD);
1281 ****************************************************************************
1285 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
1286 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
1287 UWORD upper_bound_right, struct DevBase *base)
1289 struct AddressRange *range, *tail;
1290 BOOL found = FALSE;
1292 range = (APTR)unit->multicast_ranges.mlh_Head;
1293 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
1295 while(range != tail && !found)
1297 if(lower_bound_left == range->lower_bound_left &&
1298 lower_bound_right == range->lower_bound_right &&
1299 upper_bound_left == range->upper_bound_left &&
1300 upper_bound_right == range->upper_bound_right)
1301 found = TRUE;
1302 else
1303 range = (APTR)range->node.mln_Succ;
1306 if(!found)
1307 range = NULL;
1309 return range;
1314 /****i* atheros5000.device/SetMulticast ************************************
1316 * NAME
1317 * SetMulticast
1319 * SYNOPSIS
1320 * SetMulticast(unit)
1322 * VOID SetMulticast(struct DevUnit *);
1324 ****************************************************************************
1328 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base)
1330 unit->hal->ah_setMulticastFilter(unit->hal, 0xffffffff, 0xffffffff);
1332 return;
1337 /****i* atheros5000.device/FindTypeStats ***********************************
1339 * NAME
1340 * FindTypeStats
1342 * SYNOPSIS
1343 * stats = FindTypeStats(unit, list,
1344 * packet_type)
1346 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1347 * ULONG);
1349 ****************************************************************************
1353 struct TypeStats *FindTypeStats(struct DevUnit *unit, struct MinList *list,
1354 ULONG packet_type, struct DevBase *base)
1356 struct TypeStats *stats, *tail;
1357 BOOL found = FALSE;
1359 stats = (APTR)list->mlh_Head;
1360 tail = (APTR)&list->mlh_Tail;
1362 while(stats != tail && !found)
1364 if(stats->packet_type == packet_type)
1365 found = TRUE;
1366 else
1367 stats = (APTR)stats->node.mln_Succ;
1370 if(!found)
1371 stats = NULL;
1373 return stats;
1378 /****i* atheros5000.device/FlushUnit ***************************************
1380 * NAME
1381 * FlushUnit
1383 * SYNOPSIS
1384 * FlushUnit(unit, last_queue, error)
1386 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1388 ****************************************************************************
1392 VOID FlushUnit(struct DevUnit *unit, UBYTE last_queue, BYTE error,
1393 struct DevBase *base)
1395 struct IORequest *request;
1396 UBYTE i;
1397 struct Opener *opener, *tail;
1399 /* Abort queued requests */
1401 for(i = 0; i <= last_queue; i++)
1403 while((request = (APTR)GetMsg(unit->request_ports[i])) != NULL)
1405 request->io_Error = IOERR_ABORTED;
1406 ReplyMsg((APTR)request);
1410 #if 1
1411 opener = (APTR)unit->openers.mlh_Head;
1412 tail = (APTR)&unit->openers.mlh_Tail;
1414 /* Flush every opener's read queues */
1416 while(opener != tail)
1418 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1420 request->io_Error = error;
1421 ReplyMsg((APTR)request);
1423 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1425 request->io_Error = error;
1426 ReplyMsg((APTR)request);
1428 opener = (APTR)opener->node.mln_Succ;
1431 #else
1432 opener = request->ios2_BufferManagement;
1433 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
1435 request->io_Error = IOERR_ABORTED;
1436 ReplyMsg((APTR)request);
1438 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
1440 request->io_Error = IOERR_ABORTED;
1441 ReplyMsg((APTR)request);
1443 #endif
1445 /* Return */
1447 return;
1452 /****i* atheros5000.device/StatusInt ***************************************
1454 * NAME
1455 * StatusInt
1457 * SYNOPSIS
1458 * finished = StatusInt(unit)
1460 * BOOL StatusInt(struct DevUnit *);
1462 * FUNCTION
1464 * INPUTS
1465 * unit
1467 * RESULT
1468 * finished
1470 ****************************************************************************
1472 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1473 * Since we don't use this parameter, we can lie.
1477 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1479 struct DevBase *base;
1480 ULONG queue_mask;
1481 HAL_INT ints, int_mask;
1483 base = unit->device;
1484 int_mask = unit->hal->ah_getInterrupts(unit->hal);
1486 if(!unit->hal->ah_isInterruptPending(unit->hal)) return FALSE;
1488 /* Handle ints */
1490 if(unit->hal->ah_getPendingInterrupts(unit->hal, &ints))
1492 if((ints & HAL_INT_TX) != 0)
1494 int_mask &= ~(HAL_INT_TX | HAL_INT_TXDESC);
1495 queue_mask = 1 << unit->tx_queue_no | 1 << unit->mgmt_queue_no;
1496 unit->hal->ah_getTxIntrQueue(unit->hal, &queue_mask);
1497 if((queue_mask & 1 << unit->tx_queue_no) != 0)
1498 Cause(&unit->tx_end_int);
1499 if((queue_mask & 1 << unit->mgmt_queue_no) != 0)
1500 Cause(&unit->mgmt_end_int);
1502 if((ints & HAL_INT_RX) != 0)
1504 int_mask &= ~(HAL_INT_RX | HAL_INT_RXEOL);
1505 Cause(&unit->rx_int);
1509 #ifdef __MORPHOS__
1510 int_mask = INT_MASK;
1511 #endif
1512 // unit->hal->ah_setInterrupts(unit->hal, int_mask))
1514 return FALSE;
1519 /****i* atheros5000.device/RXInt *******************************************
1521 * NAME
1522 * RXInt -- Soft interrupt for packet reception.
1524 * SYNOPSIS
1525 * RXInt(unit)
1527 * VOID RXInt(struct DevUnit *);
1529 * FUNCTION
1531 * INPUTS
1532 * unit - A unit of this device.
1534 * RESULT
1535 * None.
1537 ****************************************************************************
1541 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
1543 UWORD ieee_length, frame_control, frame_type, slot, next_slot,
1544 frame_subtype, encryption, key_no, buffer_no, old_length;
1545 struct DevBase *base;
1546 BOOL is_good;
1547 LONG frag_no;
1548 struct ath_desc *rx_desc, *next_desc;
1549 ULONG dma_size, rx_desc_p;
1550 UBYTE *buffer, *p, *frame, *data, *snap_frame, *source;
1551 struct ath_rx_status status;
1553 base = unit->device;
1554 slot = unit->rx_slot;
1555 rx_desc = unit->rx_descs + slot;
1556 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1557 next_slot = (slot + 1) % RX_SLOT_COUNT;
1558 next_desc = unit->rx_descs + next_slot;
1560 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1561 CachePostDMA(unit->rx_descs, &dma_size, 0);
1563 while(unit->hal->ah_procRxDesc(unit->hal, rx_desc, rx_desc_p, next_desc,
1564 unit->hal->ah_getTsf64(unit->hal), &status) != HAL_EINPROGRESS)
1566 is_good = TRUE;
1567 buffer = unit->rx_buffers[slot];
1569 dma_size = FRAME_BUFFER_SIZE;
1570 CachePostDMA(buffer, &dma_size, 0);
1572 if(status.rs_status == 0
1573 && status.rs_datalen >= WIFI_FRM_DATA + FCS_SIZE)
1575 /* Get fragment info */
1577 frame = buffer;
1578 ieee_length = status.rs_datalen - FCS_SIZE - WIFI_FRM_DATA;
1579 data = frame + WIFI_FRM_DATA;
1580 frame_control =
1581 LEWord(*(UWORD *)(frame + WIFI_FRM_CONTROL));
1583 /* Get buffer to store fragment in */
1585 frag_no = LEWord(*(UWORD *)(frame + WIFI_FRM_SEQCONTROL));
1586 if(unit->mode == S2PORT_ADHOC)
1587 source = frame + WIFI_FRM_ADDRESS2;
1588 else
1589 source = frame + WIFI_FRM_ADDRESS3;
1590 snap_frame = GetRXBuffer(unit, source, frag_no, &buffer_no, base);
1592 /* Get location to put new data */
1594 if(snap_frame != NULL)
1596 if((frag_no & 0xf ) > 0)
1597 old_length =
1598 BEWord(*(UWORD *)(snap_frame + ETH_PACKET_IEEELEN));
1599 else
1601 /* Create new 802.3 header */
1603 CopyMem(frame + WIFI_FRM_ADDRESS1, snap_frame,
1604 ETH_ADDRESSSIZE);
1605 CopyMem(source, snap_frame + ETH_PACKET_SOURCE,
1606 ETH_ADDRESSSIZE);
1607 old_length = 0;
1609 p = snap_frame + ETH_HEADERSIZE + old_length;
1611 /* Get encryption type and key index */
1613 if((frame_control & WIFI_FRM_CONTROLF_WEP) != 0)
1615 key_no = data[3] >> 6 & 0x3;
1616 encryption = unit->keys[key_no].type;
1618 else
1619 encryption = S2ENC_NONE;
1621 /* Append fragment to frame, decrypting/checking fragment if
1622 necessary */
1624 is_good = unit->fragment_decrypt_functions[encryption](unit,
1625 frame, data, &ieee_length, p, base);
1627 /* Update length in frame being built with current fragment, or
1628 increment bad frame counter if fragment is bad */
1630 if(is_good)
1632 ieee_length += old_length;
1633 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1634 MakeBEWord(ieee_length);
1636 else
1637 unit->stats.BadData++;
1639 /* If all fragments have arrived, process the complete frame */
1641 if((frame_control & WIFI_FRM_CONTROLF_MOREFRAGS) == 0)
1643 if(is_good)
1645 /* Decrypt complete frame if necessary */
1647 data = snap_frame + ETH_HEADERSIZE;
1648 if(encryption == S2ENC_TKIP)
1649 // && (unit->flags & UNITF_HARDTKIP) == 0)
1650 // && (unit->flags & UNITF_HARDMIC) == 0)
1652 is_good = TKIPDecryptFrame(unit, snap_frame, data,
1653 ieee_length, data, key_no, base);
1654 ieee_length -= MIC_SIZE;
1655 *(UWORD *)(snap_frame + ETH_PACKET_IEEELEN) =
1656 MakeBEWord(ieee_length);
1657 if(!is_good)
1658 unit->stats.BadData++;
1662 if(is_good)
1664 /* Get frame's 802.11 type and subtype */
1666 frame_type = (frame_control & WIFI_FRM_CONTROLF_TYPE)
1667 >> WIFI_FRM_CONTROLB_TYPE;
1668 frame_subtype =
1669 (frame_control & WIFI_FRM_CONTROLF_SUBTYPE)
1670 >> WIFI_FRM_CONTROLB_SUBTYPE;
1672 /* If it's a management frame, process it separately;
1673 otherwise distribute it to clients after filtering */
1675 if(frame_type == WIFI_FRMTYPE_MGMT)
1677 DistributeMgmtFrame(unit, frame, status.rs_datalen - 4,
1678 base);
1680 else if(AddressFilter(unit, snap_frame + ETH_PACKET_DEST,
1681 base))
1683 unit->stats.PacketsReceived++;
1684 DistributeRXPacket(unit, snap_frame, base);
1689 /* Mark fragment buffer as unused for next time */
1691 unit->rx_fragment_nos[buffer_no] = -1;
1693 else
1694 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_RX, base);
1696 else
1698 is_good = FALSE;
1701 if(!is_good)
1703 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_HARDWARE | S2EVENT_RX,
1704 base);
1707 /* Prepare descriptor for next time */
1709 unit->hal->ah_setupRxDesc(unit->hal, rx_desc, FRAME_BUFFER_SIZE,
1710 HAL_RXDESC_INTREQ);
1712 dma_size = FRAME_BUFFER_SIZE;
1713 CachePreDMA(buffer, &dma_size, 0);
1715 /* Get next descriptor */
1717 slot = next_slot;
1718 rx_desc = next_desc;
1719 rx_desc_p = unit->rx_descs_p + slot * sizeof(struct ath_desc);
1720 next_slot = (slot + 1) % RX_SLOT_COUNT;
1721 next_desc = unit->rx_descs + next_slot;
1724 dma_size = sizeof(struct ath_desc) * RX_SLOT_COUNT;
1725 CachePreDMA(unit->rx_descs, &dma_size, 0);
1727 unit->rx_slot = slot;
1728 // TO DO: unstall reception?
1730 /* Re-enable RX interrupts */
1732 #if 0
1733 Disable();
1734 unit->hal->ah_setInterrupts(unit->hal,
1735 unit->hal->ah_getInterrupts(unit->hal) | HAL_INT_RX | HAL_INT_RXEOL);
1736 Enable();
1737 #endif
1739 return;
1744 /****i* atheros5000.device/GetRXBuffer *************************************
1746 * NAME
1747 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
1749 * SYNOPSIS
1750 * buffer = GetRXBuffer(unit, address, frag_no)
1752 * UBYTE *GetRXBuffer(struct DevUnit *, UBYTE *, UWORD);
1754 ****************************************************************************
1758 static UBYTE *GetRXBuffer(struct DevUnit *unit, const UBYTE *address,
1759 UWORD frag_no, UWORD *buffer_no, struct DevBase *base)
1761 UWORD i;
1762 UBYTE *buffer;
1763 LONG n;
1764 BOOL found;
1766 buffer = unit->rx_frames;
1767 for(i = 0, found = FALSE; i < FRAME_BUFFER_COUNT * 2 && !found; i++)
1769 /* Throw away old buffer contents if we didn't find a free slot the
1770 first time around */
1772 if(i >= FRAME_BUFFER_COUNT)
1773 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = -1;
1775 /* For a frame's first fragment, find an empty slot; for subsequent
1776 fragments, find a slot with matching source address */
1778 n = unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT];
1779 if(n == -1 && (frag_no & 0xf) == 0
1780 || *((ULONG *)(buffer + ETH_PACKET_SOURCE))
1781 == *((ULONG *)(address))
1782 && *((UWORD *)(buffer + ETH_PACKET_SOURCE + 4))
1783 == *((UWORD *)(address + 4)))
1785 found = TRUE;
1786 if(n == -1)
1787 unit->rx_fragment_nos[i % FRAME_BUFFER_COUNT] = frag_no;
1788 *buffer_no = i;
1790 else
1791 buffer += FRAME_BUFFER_SIZE;
1794 if(!found)
1795 buffer = NULL;
1797 return buffer;
1802 /****i* atheros5000.device/DistributeRXPacket ******************************
1804 * NAME
1805 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1807 * SYNOPSIS
1808 * DistributeRXPacket(unit, frame)
1810 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1812 ****************************************************************************
1816 static VOID DistributeRXPacket(struct DevUnit *unit, UBYTE *frame,
1817 struct DevBase *base)
1819 UWORD packet_size, ieee_length;
1820 BOOL is_orphan = TRUE, accepted, is_snap = FALSE;
1821 ULONG packet_type;
1822 UBYTE *buffer;
1823 const UBYTE *template = snap_template;
1824 struct IOSana2Req *request, *request_tail;
1825 struct Opener *opener, *opener_tail;
1826 struct TypeStats *tracker;
1828 ieee_length = BEWord(*(UWORD *)(frame + ETH_PACKET_IEEELEN));
1829 packet_size = ETH_HEADERSIZE + ieee_length;
1830 if(ieee_length >= SNAP_HEADERSIZE)
1831 is_snap = *(const ULONG *)(frame + ETH_PACKET_DATA)
1832 == *(const ULONG *)template;
1834 /* De-encapsulate SNAP packets and get packet type */
1836 if(is_snap)
1838 buffer = unit->rx_buffer;
1839 packet_size -= SNAP_HEADERSIZE;
1840 CopyMem(frame, buffer, ETH_PACKET_TYPE);
1841 CopyMem(frame + ETH_HEADERSIZE + SNAP_FRM_TYPE,
1842 buffer + ETH_PACKET_TYPE, packet_size - ETH_PACKET_TYPE);
1844 else
1845 buffer = frame;
1847 packet_type = BEWord(*((UWORD *)(buffer + ETH_PACKET_TYPE)));
1849 if(packet_size <= ETH_MAXPACKETSIZE)
1851 /* Offer packet to every opener */
1853 opener = (APTR)unit->openers.mlh_Head;
1854 opener_tail = (APTR)&unit->openers.mlh_Tail;
1856 while(opener != opener_tail)
1858 request = (APTR)opener->read_port.mp_MsgList.lh_Head;
1859 request_tail = (APTR)&opener->read_port.mp_MsgList.lh_Tail;
1860 accepted = FALSE;
1862 /* Offer packet to each request until it's accepted */
1864 while(request != request_tail && !accepted)
1866 if(request->ios2_PacketType == packet_type)
1868 CopyPacket(unit, request, packet_size, packet_type,
1869 buffer, base);
1870 accepted = TRUE;
1872 request =
1873 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1876 if(accepted)
1877 is_orphan = FALSE;
1878 opener = (APTR)opener->node.mln_Succ;
1881 /* If packet was unwanted, give it to S2_READORPHAN request */
1883 if(is_orphan)
1885 unit->stats.UnknownTypesReceived++;
1886 if(!IsMsgPortEmpty(unit->request_ports[ADOPT_QUEUE]))
1888 CopyPacket(unit,
1889 (APTR)unit->request_ports[ADOPT_QUEUE]->
1890 mp_MsgList.lh_Head, packet_size, packet_type, buffer,
1891 base);
1895 /* Update remaining statistics */
1897 if(packet_type <= ETH_MTU)
1898 packet_type = ETH_MTU;
1899 tracker =
1900 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
1901 if(tracker != NULL)
1903 tracker->stats.PacketsReceived++;
1904 tracker->stats.BytesReceived += packet_size;
1907 else
1908 unit->stats.BadData++;
1910 return;
1915 /****i* atheros5000.device/CopyPacket **************************************
1917 * NAME
1918 * CopyPacket -- Copy packet to client's buffer.
1920 * SYNOPSIS
1921 * CopyPacket(unit, request, packet_size, packet_type,
1922 * buffer)
1924 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1925 * UBYTE *);
1927 ****************************************************************************
1931 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
1932 UWORD packet_size, UWORD packet_type, UBYTE *buffer,
1933 struct DevBase *base)
1935 struct Opener *opener;
1936 BOOL filtered = FALSE;
1938 /* Set multicast and broadcast flags */
1940 request->ios2_Req.io_Flags &= ~(SANA2IOF_BCAST | SANA2IOF_MCAST);
1941 if((*((ULONG *)(buffer + ETH_PACKET_DEST)) == 0xffffffff) &&
1942 (*((UWORD *)(buffer + ETH_PACKET_DEST + 4)) == 0xffff))
1943 request->ios2_Req.io_Flags |= SANA2IOF_BCAST;
1944 else if((buffer[ETH_PACKET_DEST] & 0x1) != 0)
1945 request->ios2_Req.io_Flags |= SANA2IOF_MCAST;
1947 /* Set source and destination addresses and packet type */
1949 CopyMem(buffer + ETH_PACKET_SOURCE, request->ios2_SrcAddr,
1950 ETH_ADDRESSSIZE);
1951 CopyMem(buffer + ETH_PACKET_DEST, request->ios2_DstAddr,
1952 ETH_ADDRESSSIZE);
1953 request->ios2_PacketType = packet_type;
1955 /* Adjust for cooked packet request */
1957 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1959 packet_size -= ETH_PACKET_DATA;
1960 buffer += ETH_PACKET_DATA;
1962 #ifdef USE_HACKS
1963 else
1964 packet_size += 4; /* Needed for Shapeshifter & Fusion? */
1965 #endif
1966 request->ios2_DataLength = packet_size;
1968 /* Filter packet */
1970 opener = request->ios2_BufferManagement;
1971 if(request->ios2_Req.io_Command == CMD_READ &&
1972 opener->filter_hook != NULL)
1973 if(!CallHookPkt(opener->filter_hook, request, buffer))
1974 filtered = TRUE;
1976 if(!filtered)
1978 /* Copy packet into opener's buffer and reply packet */
1980 if(!opener->rx_function(request->ios2_Data, buffer, packet_size))
1982 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1983 request->ios2_WireError = S2WERR_BUFF_ERROR;
1984 ReportEvents(unit,
1985 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
1986 base);
1988 Remove((APTR)request);
1989 ReplyMsg((APTR)request);
1992 return;
1997 /****i* atheros5000.device/AddressFilter ***********************************
1999 * NAME
2000 * AddressFilter -- Determine if an RX packet should be accepted.
2002 * SYNOPSIS
2003 * accept = AddressFilter(unit, address)
2005 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
2007 ****************************************************************************
2011 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
2012 struct DevBase *base)
2014 struct AddressRange *range, *tail;
2015 BOOL accept = TRUE;
2016 ULONG address_left;
2017 UWORD address_right;
2019 /* Check whether address is unicast/broadcast or multicast */
2021 address_left = BELong(*((ULONG *)address));
2022 address_right = BEWord(*((UWORD *)(address + 4)));
2024 if(((address_left & 0x01000000) != 0) &&
2025 !((address_left == 0xffffffff) && (address_right == 0xffff)))
2027 /* Check if this multicast address is wanted */
2029 range = (APTR)unit->multicast_ranges.mlh_Head;
2030 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
2031 accept = FALSE;
2033 while((range != tail) && !accept)
2035 if((address_left > range->lower_bound_left ||
2036 address_left == range->lower_bound_left &&
2037 address_right >= range->lower_bound_right) &&
2038 (address_left < range->upper_bound_left ||
2039 address_left == range->upper_bound_left &&
2040 address_right <= range->upper_bound_right))
2041 accept = TRUE;
2042 range = (APTR)range->node.mln_Succ;
2045 if(!accept)
2046 unit->special_stats[S2SS_ETHERNET_BADMULTICAST & 0xffff]++;
2049 return accept;
2054 /****i* atheros5000.device/DistributeMgmtFrame *****************************
2056 * NAME
2057 * DistributeMgmtFrame -- Send a management frame to clients.
2059 * SYNOPSIS
2060 * DistributeMgmtFrame(unit, frame, frame_size)
2062 * VOID DistributeMgmtFrame(struct DevUnit *, UBYTE *, UWORD);
2064 ****************************************************************************
2068 static VOID DistributeMgmtFrame(struct DevUnit *unit, UBYTE *frame,
2069 UWORD frame_size, struct DevBase *base)
2071 struct IOSana2Req *request;
2072 struct Opener *opener, *opener_tail;
2074 /* Send packet to every opener */
2076 opener = (APTR)unit->openers.mlh_Head;
2077 opener_tail = (APTR)&unit->openers.mlh_Tail;
2079 while(opener != opener_tail)
2081 request = (APTR)RemHead(&opener->mgmt_port.mp_MsgList);
2083 if(request != NULL)
2085 /* Copy packet into opener's buffer and reply packet */
2087 if(frame_size <= request->ios2_DataLength)
2089 CopyMem(frame, request->ios2_Data, frame_size);
2090 request->ios2_DataLength = frame_size;
2092 else
2094 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
2095 request->ios2_WireError = S2WERR_BUFF_ERROR;
2096 ReportEvents(unit,
2097 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
2098 base);
2100 ReplyMsg((APTR)request);
2101 request =
2102 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2105 opener = (APTR)opener->node.mln_Succ;
2108 return;
2113 /****i* atheros5000.device/TXInt *******************************************
2115 * NAME
2116 * TXInt -- Soft interrupt for packet transmission.
2118 * SYNOPSIS
2119 * TXInt(unit)
2121 * VOID TXInt(struct DevUnit *);
2123 * FUNCTION
2125 * INPUTS
2126 * unit - A unit of this device.
2128 * RESULT
2129 * None.
2131 ****************************************************************************
2135 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2137 struct DevBase *base;
2138 UWORD i, frame_size, data_size, packet_type, body_size, slot, new_slot,
2139 last_slot, encryption, subtype, duration;
2140 UBYTE *buffer, *q, *plaintext, *ciphertext, *frame,
2141 mic_header[ETH_ADDRESSSIZE * 2];
2142 const UBYTE *p, *dest, *source;
2143 struct IOSana2Req *request;
2144 BOOL proceed = TRUE, is_ieee;
2145 struct Opener *opener;
2146 ULONG wire_error, dma_size;
2147 struct ath_desc *tx_desc, *last_desc;
2148 UBYTE *(*dma_tx_function)(REG(a0, APTR));
2149 BYTE error;
2150 struct MsgPort *port;
2151 struct TypeStats *tracker;
2152 const HAL_RATE_TABLE *rate_table;
2154 base = unit->device;
2155 port = unit->request_ports[WRITE_QUEUE];
2156 rate_table = unit->rate_table;
2158 while(proceed && (!IsMsgPortEmpty(port)))
2160 slot = unit->tx_in_slot;
2161 new_slot = (slot + 1) % TX_SLOT_COUNT;
2163 // if(new_slot != unit->tx_out_slot)
2164 if(slot == unit->tx_out_slot) // one packet at a time
2166 error = 0;
2167 body_size = 0;
2169 /* Get request and DMA frame descriptor */
2171 request = (APTR)port->mp_MsgList.lh_Head;
2173 Remove((APTR)request);
2174 unit->tx_requests[slot] = request;
2175 tx_desc = unit->tx_descs + slot;
2176 frame = unit->tx_buffers[slot];
2178 /* Get packet data */
2180 opener = request->ios2_BufferManagement;
2181 dma_tx_function = opener->dma_tx_function;
2182 if(dma_tx_function != NULL)
2183 buffer = dma_tx_function(request->ios2_Data);
2184 else
2185 buffer = NULL;
2187 if(buffer == NULL)
2189 buffer = unit->tx_buffer;
2190 if(!opener->tx_function(buffer, request->ios2_Data,
2191 request->ios2_DataLength))
2193 error = S2ERR_NO_RESOURCES;
2194 wire_error = S2WERR_BUFF_ERROR;
2195 ReportEvents(unit,
2196 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF
2197 | S2EVENT_TX, base);
2201 if(error == 0)
2203 /* Get packet type and/or length */
2205 data_size = request->ios2_DataLength;
2206 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2208 data_size -= ETH_PACKET_DATA;
2209 packet_type = BEWord(*(UWORD *)(buffer + ETH_PACKET_TYPE));
2211 else
2212 packet_type = request->ios2_PacketType;
2213 is_ieee = packet_type <= ETH_MTU;
2215 /* Determine encryption type and frame subtype */
2217 if(data_size > 0)
2219 encryption = unit->keys[unit->tx_key_no].type;
2220 subtype = 0;
2222 else
2224 encryption = S2ENC_NONE;
2225 subtype = 4;
2228 /* Get source and destination addresses */
2230 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) != 0)
2232 dest = buffer;
2233 source = buffer + ETH_ADDRESSSIZE;
2234 buffer += ETH_ADDRESSSIZE * 2 + 2;
2236 else
2238 dest = request->ios2_DstAddr;
2239 source = unit->address;
2242 /* Write 802.11 header */
2244 q = frame;
2245 *(UWORD *)q = MakeLEWord(
2246 (encryption == S2ENC_NONE ? 0 : WIFI_FRM_CONTROLF_WEP)
2247 | (unit->mode == S2PORT_ADHOC ? 0 : WIFI_FRM_CONTROLF_TODS)
2248 | subtype << WIFI_FRM_CONTROLB_SUBTYPE
2249 | WIFI_FRMTYPE_DATA << WIFI_FRM_CONTROLB_TYPE);
2250 q += 2;
2252 i = rate_table->rateCodeToIndex[unit->tx_rate_codes[0]];
2253 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2254 duration = rate_table->info[i].spAckDuration;
2255 else
2256 duration = rate_table->info[i].lpAckDuration;
2257 *(UWORD *)q = MakeLEWord(duration);
2258 q += 2;
2260 if(unit->mode == S2PORT_ADHOC)
2261 p = dest;
2262 else
2263 p = unit->bssid;
2264 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2265 *q++ = *p++;
2267 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2268 *q++ = *p++;
2270 if(unit->mode == S2PORT_ADHOC)
2271 p = unit->bssid;
2272 else
2273 p = dest;
2274 for(i = 0; i < ETH_ADDRESSSIZE; i++)
2275 *q++ = *p++;
2276 *(UWORD *)q = 0;
2277 q += 2;
2279 // TO DO: need to pad header to 4-byte boundary?
2281 /* Leave room for encryption overhead */
2283 ciphertext = q;
2284 q += unit->iv_sizes[encryption];
2285 plaintext = q;
2287 /* Write SNAP header */
2289 if(!is_ieee)
2291 for(i = 0, p = snap_template;
2292 i < SNAP_FRM_TYPE; i++)
2293 *q++ = *p++;
2294 *(UWORD *)q = MakeBEWord(packet_type);
2295 q += 2;
2296 body_size += SNAP_HEADERSIZE;
2299 /* Copy data into frame */
2301 CopyMem(buffer, q, data_size);
2302 body_size += data_size;
2304 /* Append MIC to frame for TKIP */
2306 if(encryption == S2ENC_TKIP)
2308 // if((unit->flags & UNITF_HARDMIC) == 0)
2310 q = mic_header;
2311 for(i = 0, p = dest; i < ETH_ADDRESSSIZE; i++)
2312 *q++ = *p++;
2313 for(i = 0, p = source; i < ETH_ADDRESSSIZE; i++)
2314 *q++ = *p++;
2315 TKIPEncryptFrame(unit, mic_header, plaintext, body_size,
2316 plaintext, base);
2318 body_size += MIC_SIZE;
2321 /* Encrypt fragment if applicable */
2323 unit->fragment_encrypt_functions[encryption](unit, frame,
2324 plaintext, &body_size, ciphertext, base);
2326 /* Fill in DMA descriptor for packet transmission */
2328 frame_size = WIFI_FRM_DATA + body_size;
2329 tx_desc->ds_link = (ULONG)NULL;
2330 unit->hal->ah_setupTxDesc(unit->hal, tx_desc, frame_size + 4, // + CRC?
2331 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2332 ((unit->flags & UNITF_SLOWRETRIES) != 0) ?
2333 unit->tx_rate_codes[0] : unit->tx_rate_codes[1],
2334 ((unit->flags & UNITF_SLOWRETRIES) != 0) ? 1 : TX_TRIES,
2335 HAL_TXKEYIX_INVALID,
2336 HAL_ANTENNA_MIN_MODE,
2337 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK,
2338 0, 0, 0, 0, 3);
2339 if((unit->flags & UNITF_SLOWRETRIES) != 0)
2340 unit->hal->ah_setupXTxDesc(unit->hal, tx_desc,
2341 unit->tx_rate_codes[1], 1,
2342 unit->tx_rate_codes[2], 1,
2343 unit->tx_rate_codes[3], TX_TRIES - 3);
2344 unit->hal->ah_fillTxDesc(unit->hal, tx_desc, frame_size, TRUE, TRUE,
2345 tx_desc);
2347 dma_size = frame_size;
2348 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2350 /* Pass packet to adapter */
2352 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2353 last_slot = (slot + TX_SLOT_COUNT - 1) % TX_SLOT_COUNT;
2354 if(unit->tx_out_slot != slot)
2355 //if(unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no) > 0)
2357 last_desc =
2358 unit->tx_descs + last_slot;
2359 last_desc->ds_link = unit->tx_descs_p + slot * sizeof(struct ath_desc);
2360 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2361 CachePreDMA(unit->tx_descs, &dma_size, 0);
2363 else
2365 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2366 CachePreDMA(unit->tx_descs, &dma_size, 0);
2367 unit->hal->ah_setTxDP(unit->hal, unit->tx_queue_no,
2368 unit->tx_descs_p + slot * sizeof(struct ath_desc));
2371 unit->hal->ah_startTxDma(unit->hal, unit->tx_queue_no);
2372 unit->tx_in_slot = new_slot;
2374 else
2376 /* Reply failed request */
2378 request->ios2_Req.io_Error = error;
2379 request->ios2_WireError = wire_error;
2380 ReplyMsg((APTR)request);
2383 /* Update statistics */
2385 if(error == 0)
2387 unit->stats.PacketsSent++;
2389 tracker = FindTypeStats(unit, &unit->type_trackers,
2390 request->ios2_PacketType, base);
2391 if(tracker != NULL)
2393 tracker->stats.PacketsSent++;
2394 tracker->stats.BytesSent += ETH_HEADERSIZE + data_size;
2398 else
2399 proceed = FALSE;
2402 /* Don't try to keep sending packets if there's no space left */
2404 if(proceed)
2405 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
2406 else
2407 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_IGNORE;
2409 return;
2414 /****i* atheros5000.device/TXEndInt ****************************************
2416 * NAME
2417 * TXEndInt -- Clean up after a data frame has been sent.
2419 * SYNOPSIS
2420 * TXEndInt(unit, int_code)
2422 * VOID TXEndInt(struct DevUnit *, APTR);
2424 * NOTES
2425 * I think it's safe to assume that there will always be at least one
2426 * completed packet whenever this interrupt is called.
2428 ****************************************************************************
2432 static VOID TXEndInt(REG(a1, struct DevUnit *unit),
2433 REG(a6, APTR int_code))
2435 UWORD frame_size, new_out_slot, i;
2436 UBYTE *frame;
2437 struct DevBase *base;
2438 struct IOSana2Req *request;
2439 ULONG dma_size;
2440 struct TypeStats *tracker;
2442 /* Find out which packets have completed */
2444 base = unit->device;
2445 new_out_slot = (unit->tx_in_slot + TX_SLOT_COUNT
2446 - unit->hal->ah_numTxPending(unit->hal, unit->tx_queue_no))
2447 % TX_SLOT_COUNT;
2449 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2450 CachePostDMA(unit->tx_descs, &dma_size, 0);
2452 /* Retire sent packets */
2454 for(i = unit->tx_out_slot; i != new_out_slot;
2455 i = (i + 1) % TX_SLOT_COUNT)
2457 frame = unit->tx_buffers[i];
2458 dma_size = FRAME_BUFFER_SIZE;
2459 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2461 /* Update statistics */
2463 request = unit->tx_requests[i];
2464 frame_size = request->ios2_DataLength;
2465 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
2466 frame_size += ETH_HEADERSIZE;
2468 tracker = FindTypeStats(unit, &unit->type_trackers,
2469 request->ios2_PacketType, base);
2470 if(tracker != NULL)
2472 tracker->stats.PacketsSent++;
2473 tracker->stats.BytesSent += frame_size;
2476 /* Reply request */
2478 request->ios2_Req.io_Error = 0;
2479 ReplyMsg((APTR)request);
2482 unit->tx_out_slot = i;
2484 dma_size = sizeof(struct ath_desc) * TX_SLOT_COUNT;
2485 CachePreDMA(unit->tx_descs, &dma_size, 0);
2487 /* Restart downloads if they had stopped */
2489 if(unit->request_ports[WRITE_QUEUE]->mp_Flags == PA_IGNORE)
2490 Cause(&unit->tx_int);
2492 return;
2497 /****i* atheros5000.device/MgmtTXInt ***************************************
2499 * NAME
2500 * MgmtTXInt -- Soft interrupt for management frame transmission.
2502 * SYNOPSIS
2503 * MgmtTXInt(unit)
2505 * VOID MgmtTXInt(struct DevUnit *);
2507 * FUNCTION
2509 * INPUTS
2510 * unit - A unit of this device.
2512 * RESULT
2513 * None.
2515 ****************************************************************************
2519 static VOID MgmtTXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code))
2521 struct DevBase *base;
2522 UWORD frame_size, slot, new_slot, last_slot, i, duration;
2523 UBYTE *frame;
2524 struct IOSana2Req *request;
2525 BOOL proceed = TRUE, has_bssid;
2526 ULONG dma_size;
2527 struct ath_desc *desc, *last_desc;
2528 struct MsgPort *port;
2529 const HAL_RATE_TABLE *rate_table;
2531 base = unit->device;
2532 port = unit->request_ports[MGMT_QUEUE];
2533 rate_table = unit->rate_table;
2535 while(proceed && (!IsMsgPortEmpty(port)))
2537 slot = unit->mgmt_in_slot;
2538 new_slot = (slot + 1) % MGMT_SLOT_COUNT;
2540 // if(new_slot != unit->mgmt_out_slot)
2541 if(slot == unit->mgmt_out_slot) // one packet at a time
2543 /* Get request and DMA frame descriptor */
2545 request = (APTR)port->mp_MsgList.lh_Head;
2547 Remove((APTR)request);
2548 unit->mgmt_requests[slot] = request;
2549 desc = unit->mgmt_descs + slot;
2550 frame = unit->mgmt_buffers[slot];
2552 /* Get packet length */
2554 frame_size = request->ios2_DataLength;
2556 /* Copy frame into DMA buffer */
2558 CopyMem(request->ios2_Data, frame, frame_size);
2560 /* Set duration */
2562 has_bssid = ((frame + WIFI_FRM_ADDRESS1)[0] & 0x1) == 0;
2563 i = rate_table->rateCodeToIndex[unit->mgmt_rate_code];
2564 if(has_bssid)
2566 if((unit->flags & UNITF_SHORTPREAMBLE) != 0)
2567 duration = rate_table->info[i].spAckDuration;
2568 else
2569 duration = rate_table->info[i].lpAckDuration;
2571 else
2572 duration = 0;
2573 *(UWORD *)(frame + WIFI_FRM_DURATION) = MakeLEWord(duration);
2575 /* Fill in DMA descriptor for packet transmission */
2577 desc->ds_link = (ULONG)NULL;
2578 unit->hal->ah_setupTxDesc(unit->hal, desc, frame_size + 4, // + CRC?
2579 WIFI_FRM_DATA, HAL_PKT_TYPE_NORMAL, TX_POWER,
2580 unit->mgmt_rate_code, TX_TRIES, HAL_TXKEYIX_INVALID,
2581 HAL_ANTENNA_MIN_MODE,
2582 HAL_TXDESC_INTREQ | HAL_TXDESC_CLRDMASK
2583 | (has_bssid ? 0 : HAL_TXDESC_NOACK),
2584 0, 0, 0, 0, 3);
2585 unit->hal->ah_fillTxDesc(unit->hal, desc, frame_size, TRUE, TRUE,
2586 desc);
2588 dma_size = frame_size;
2589 CachePreDMA(frame, &dma_size, DMA_ReadFromRAM);
2591 /* Pass packet to adapter */
2593 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2594 last_slot = (slot + MGMT_SLOT_COUNT - 1) % MGMT_SLOT_COUNT;
2595 if(unit->mgmt_out_slot != slot)
2596 //if(unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no) > 0)
2598 last_desc = unit->mgmt_descs + last_slot;
2599 last_desc->ds_link =
2600 unit->mgmt_descs_p + slot * sizeof(struct ath_desc);
2601 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2602 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2604 else
2606 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2607 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2608 unit->hal->ah_setTxDP(unit->hal, unit->mgmt_queue_no,
2609 unit->mgmt_descs_p + slot * sizeof(struct ath_desc));
2612 unit->hal->ah_startTxDma(unit->hal, unit->mgmt_queue_no);
2613 unit->mgmt_in_slot = new_slot;
2615 else
2616 proceed = FALSE;
2619 /* Don't try to keep sending packets if there's no space left */
2621 if(proceed)
2622 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_SOFTINT;
2623 else
2624 unit->request_ports[MGMT_QUEUE]->mp_Flags = PA_IGNORE;
2626 return;
2631 /****i* atheros5000.device/MgmtTXEndInt ************************************
2633 * NAME
2634 * MgmtTXEndInt -- Clean up after a management frame has been sent.
2636 * SYNOPSIS
2637 * MgmtTXEndInt(unit, int_code)
2639 * VOID MgmtTXEndInt(struct DevUnit *, APTR);
2641 * NOTES
2642 * I think it's safe to assume that there will always be at least one
2643 * completed packet whenever this interrupt is called.
2645 ****************************************************************************
2649 static VOID MgmtTXEndInt(REG(a1, struct DevUnit *unit),
2650 REG(a6, APTR int_code))
2652 UWORD new_out_slot, i;
2653 UBYTE *frame;
2654 struct DevBase *base;
2655 struct IOSana2Req *request;
2656 ULONG dma_size;
2658 /* Find out which packets have completed */
2660 base = unit->device;
2661 new_out_slot = (unit->mgmt_in_slot + MGMT_SLOT_COUNT
2662 - unit->hal->ah_numTxPending(unit->hal, unit->mgmt_queue_no))
2663 % MGMT_SLOT_COUNT;
2665 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2666 CachePostDMA(unit->mgmt_descs, &dma_size, 0);
2668 /* Retire sent frames */
2670 for(i = unit->mgmt_out_slot; i != new_out_slot;
2671 i = (i + 1) % MGMT_SLOT_COUNT)
2673 frame = unit->mgmt_buffers[i];
2674 dma_size = FRAME_BUFFER_SIZE;
2675 CachePostDMA(frame, &dma_size, DMA_ReadFromRAM);
2677 /* Reply request */
2679 request = unit->mgmt_requests[i];
2680 request->ios2_Req.io_Error = 0;
2681 ReplyMsg((APTR)request);
2684 unit->mgmt_out_slot = i;
2686 dma_size = sizeof(struct ath_desc) * MGMT_SLOT_COUNT;
2687 CachePreDMA(unit->mgmt_descs, &dma_size, 0);
2689 /* Restart downloads if they had stopped */
2691 if(unit->request_ports[MGMT_QUEUE]->mp_Flags == PA_IGNORE)
2692 Cause(&unit->mgmt_int);
2694 return;
2699 /****i* atheros5000.device/ResetHandler ************************************
2701 * NAME
2702 * ResetHandler -- Disable hardware before a reboot.
2704 * SYNOPSIS
2705 * ResetHandler(unit, int_code)
2707 * VOID ResetHandler(struct DevUnit *, APTR);
2709 ****************************************************************************
2713 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
2714 REG(a6, APTR int_code))
2716 struct DevBase *base;
2718 base = unit->device;
2720 if((unit->flags & UNITF_HAVEADAPTER) != 0)
2722 /* Disable frame transmission */
2724 unit->hal->ah_stopTxDma(unit->hal, unit->tx_queue_no);
2725 unit->hal->ah_stopTxDma(unit->hal, unit->mgmt_queue_no);
2727 /* Disable frame reception */
2729 unit->hal->ah_stopPcuReceive(unit->hal);
2730 unit->hal->ah_stopDmaReceive(unit->hal);
2732 /* Stop interrupts */
2734 unit->hal->ah_setInterrupts(unit->hal, 0);
2737 return;
2742 /****i* atheros5000.device/UpdateStats *************************************
2744 * NAME
2745 * UpdateStats
2747 * SYNOPSIS
2748 * UpdateStats(unit)
2750 * VOID UpdateStats(struct DevUnit *);
2752 * FUNCTION
2754 * INPUTS
2755 * unit - A unit of this device.
2757 * RESULT
2758 * None.
2760 ****************************************************************************
2764 VOID UpdateStats(struct DevUnit *unit, struct DevBase *base)
2766 /* Ask for and wait for stats */
2768 return;
2773 /****i* atheros5000.device/ReportEvents ************************************
2775 * NAME
2776 * ReportEvents
2778 * SYNOPSIS
2779 * ReportEvents(unit, events)
2781 * VOID ReportEvents(struct DevUnit *, ULONG);
2783 * FUNCTION
2785 * INPUTS
2786 * unit - A unit of this device.
2787 * events - A mask of events to report.
2789 * RESULT
2790 * None.
2792 ****************************************************************************
2796 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
2797 struct DevBase *base)
2799 struct IOSana2Req *request, *tail, *next_request;
2800 struct List *list;
2802 list = &unit->request_ports[EVENT_QUEUE]->mp_MsgList;
2803 next_request = (APTR)list->lh_Head;
2804 tail = (APTR)&list->lh_Tail;
2806 Disable();
2807 while(next_request != tail)
2809 request = next_request;
2810 next_request = (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
2812 if((request->ios2_WireError & events) != 0)
2814 request->ios2_WireError = events;
2815 Remove((APTR)request);
2816 ReplyMsg((APTR)request);
2819 Enable();
2821 return;
2826 /****i* atheros5000.device/GetRadioBands ***********************************
2828 * NAME
2829 * GetRadioBands -- Get information on current network.
2831 * SYNOPSIS
2832 * tag_list = GetRadioBands(unit, pool)
2834 * struct TagItem *GetRadioBands(struct DevUnit *, APTR);
2836 * FUNCTION
2838 * INPUTS
2839 * unit - A unit of this device.
2840 * pool - A memory pool.
2842 * RESULT
2843 * None.
2845 ****************************************************************************
2849 #if 0
2850 struct TagItem *GetRadioBands(struct DevUnit *unit, APTR pool,
2851 struct DevBase *base)
2853 BYTE error = 0;
2854 struct Sana2RadioBand *bands;
2855 UWORD i;
2857 bands = AllocPooled(pool, sizeof(struct Sana2RadioBand) * 3);
2858 if(bands == NULL)
2859 error = S2ERR_NO_RESOURCES;
2861 if(error == 0)
2863 for(i = 0; i < 1; i++)
2865 bands[i] = AllocPooled(pool, sizeof(UWORD) * unit->channel_counts[S2BAND_B]);
2869 // if(error != 0)
2870 // bands = NULL;
2872 return bands;
2874 #endif
2878 /****i* atheros5000.device/UnitTask ****************************************
2880 * NAME
2881 * UnitTask
2883 * SYNOPSIS
2884 * UnitTask()
2886 * VOID UnitTask();
2888 * FUNCTION
2889 * Completes deferred requests, and handles card insertion and removal
2890 * in conjunction with the relevant interrupts.
2892 ****************************************************************************
2896 #ifdef __MORPHOS__
2897 #undef UnitTask
2898 #endif
2900 static VOID UnitTask()
2902 struct Task *task;
2903 struct IORequest *request;
2904 struct DevUnit *unit;
2905 struct DevBase *base;
2906 struct MsgPort *general_port;
2907 ULONG signals = 0, wait_signals, card_removed_signal,
2908 card_inserted_signal, general_port_signal;
2910 /* Get parameters */
2912 task = AbsExecBase->ThisTask;
2913 unit = task->tc_UserData;
2914 base = unit->device;
2916 /* Activate general request port */
2918 general_port = unit->request_ports[GENERAL_QUEUE];
2919 general_port->mp_SigTask = task;
2920 general_port->mp_SigBit = AllocSignal(-1);
2921 general_port_signal = 1 << general_port->mp_SigBit;
2922 general_port->mp_Flags = PA_SIGNAL;
2924 /* Allocate signals for notification of card removal and insertion */
2926 card_removed_signal = unit->card_removed_signal = 1 << AllocSignal(-1);
2927 card_inserted_signal = unit->card_inserted_signal = 1 << AllocSignal(-1);
2928 wait_signals = (1 << general_port->mp_SigBit) | card_removed_signal
2929 | card_inserted_signal | SIGBREAKF_CTRL_C;
2931 /* Tell ourselves to check port for old messages */
2933 Signal(task, general_port_signal);
2935 /* Infinite loop to service requests and signals */
2937 while((signals & SIGBREAKF_CTRL_C) == 0)
2939 signals = Wait(wait_signals);
2941 if((signals & card_inserted_signal) != 0)
2943 if(unit->insertion_function(unit->card, base))
2945 unit->flags |= UNITF_HAVEADAPTER;
2946 if((unit->flags & UNITF_CONFIGURED) != 0)
2947 ConfigureAdapter(unit, base);
2948 if((unit->flags & UNITF_WASONLINE) != 0)
2950 GoOnline(unit, base);
2951 unit->flags &= ~UNITF_WASONLINE;
2956 if((signals & card_removed_signal) != 0)
2958 unit->removal_function(unit->card, base);
2959 if((unit->flags & UNITF_WASONLINE) != 0)
2960 GoOffline(unit, base);
2963 if((signals & general_port_signal) != 0)
2965 while((request = (APTR)GetMsg(general_port)) != NULL)
2967 /* Service the request as soon as the unit is free */
2969 ObtainSemaphore(&unit->access_lock);
2970 ServiceRequest((APTR)request, base);
2975 FreeMem(task->tc_SPLower, STACK_SIZE);