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,
23 #include <exec/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
27 #include <proto/exec.h>
29 #include <proto/alib.h>
31 #include <clib/alib_protos.h>
33 #include <proto/utility.h>
34 #include <proto/dos.h>
35 #include <proto/timer.h>
39 #include "unit_protos.h"
40 #include "request_protos.h"
41 #include "encryption_protos.h"
43 #include "hal/ah_desc.h"
46 #define TASK_PRIORITY 0
47 #define STACK_SIZE 4096
49 (HAL_INT_GLOBAL | HAL_INT_TX | HAL_INT_TXDESC | HAL_INT_RX \
51 #define TX_POWER (20 << 1)
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
60 #define AbsExecBase (*(struct ExecBase **)4)
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};
101 #define AddTask(task, initial_pc, final_pc) \
102 IExec->AddTask(task, initial_pc, final_pc, NULL)
105 static const struct EmulLibEntry mos_task_trap
=
111 #define UnitTask &mos_task_trap
116 /****i* atheros5000.device/CreateUnit **************************************
119 * CreateUnit -- Create a unit.
122 * unit = CreateUnit(index, io_base, id, card,
125 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
126 * struct TagItem *, UWORD);
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
)
139 struct DevUnit
*unit
;
141 struct MsgPort
*port
;
143 struct ath_desc
*tx_desc
, *rx_desc
;
146 HAL_STATUS hal_status
;
148 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
154 /* Initialise lists etc. */
156 NewList((APTR
)&unit
->openers
);
157 NewList((APTR
)&unit
->type_trackers
);
158 NewList((APTR
)&unit
->multicast_ranges
);
165 /* Store DMA memory hooks */
168 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
170 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
171 if(unit
->AllocDMAMem
== NULL
|| unit
->FreeDMAMem
== NULL
)
179 unit
->hal
= ath_hal_attach(id
, unit
, NULL
, io_base
, &hal_status
);
181 if(unit
->hal
== NULL
)
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
);
200 NewList(&port
->mp_MsgList
);
201 port
->mp_Flags
= PA_IGNORE
;
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
)
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
)
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
)
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
,
248 unit
->mgmt_requests
= AllocVec(sizeof(APTR
) * MGMT_SLOT_COUNT
,
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
)
266 /* Initialise network adapter hardware */
268 success
= InitialiseAdapter(unit
, FALSE
, base
);
269 unit
->flags
|= UNITF_HAVEADAPTER
;
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
)
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
)
289 CachePostDMA(unit
->tx_buffers
[i
], &dma_size
, 0);
292 dma_size
= sizeof(struct ath_desc
) * MGMT_SLOT_COUNT
;
294 (ULONG
)CachePreDMA(unit
->mgmt_descs
, &dma_size
, 0);
295 if(dma_size
!= sizeof(struct ath_desc
) * MGMT_SLOT_COUNT
)
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
)
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
)
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
)
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
];
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
];
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
,
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 */
403 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
410 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
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
)
433 /* Send the unit to the new task */
435 task
->tc_UserData
= unit
;
437 /* Set default wireless options */
439 unit
->mode
= S2PORT_MANAGED
;
444 DeleteUnit(unit
, base
);
453 /****i* atheros5000.device/DeleteUnit **************************************
456 * DeleteUnit -- Delete a unit.
461 * VOID DeleteUnit(struct DevUnit *);
467 * unit - Device unit (may be NULL).
472 ****************************************************************************
476 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
486 if(task
->tc_UserData
!= NULL
)
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
));
529 /****i* atheros5000.device/InitialiseAdapter *******************************
535 * success = InitialiseAdapter(unit, reinsertion)
537 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
546 * success - Success indicator.
548 ****************************************************************************
552 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
553 struct DevBase
*base
)
555 UBYTE i
, reg_class_id
;
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 ®_class_id
, 1, ®_class_count
, CTRY_DEFAULT
,
578 HAL_MODE_11B
| HAL_MODE_PUREG
, TRUE
,
580 unit
->channel_count
= channel_count
;
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
;
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
;
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
,
629 unit
->flags
|= UNITF_HARDMIC
;
632 if(unit
->hal
->ah_setCapability(unit
->hal
, HAL_CAP_TKIP_MIC
,
635 if(unit
->hal
->ah_getCapability(unit
->hal
, HAL_CAP_TKIP_SPLIT
, 0,
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
;
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
;
658 unit
->fragment_encrypt_functions
[S2ENC_WEP
] = EncryptWEPFragment
;
660 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
661 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = WriteTKIPFragment
;
663 unit
->fragment_encrypt_functions
[S2ENC_TKIP
] = EncryptTKIPFragment
;
665 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
666 unit
->fragment_encrypt_functions
[S2ENC_CCMP
] = WriteCCMPFragment
;
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
;
677 unit
->fragment_decrypt_functions
[S2ENC_WEP
] = DecryptWEPFragment
;
679 if((unit
->flags
& UNITF_HARDTKIP
) != 0)
680 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = ReadTKIPFragment
;
682 unit
->fragment_decrypt_functions
[S2ENC_TKIP
] = DecryptTKIPFragment
;
684 if((unit
->flags
& UNITF_HARDCCMP
) != 0)
685 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = ReadCCMPFragment
;
687 unit
->fragment_decrypt_functions
[S2ENC_CCMP
] = DecryptCCMPFragment
;
696 /****i* atheros5000.device/ConfigureAdapter ********************************
699 * ConfigureAdapter -- Set up card for transmission/reception.
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;
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
)
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);
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
;
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 */
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
);
839 hal_key
.kv_type
= HAL_CIPHER_CLR
;
842 hal_key
.kv_len
= key_length
;
843 unit
->hal
->ah_setKeyCacheEntry(unit
->hal
, i
, &hal_key
,
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
);
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
);
882 /****i* atheros5000.device/GoOnline ****************************************
885 * GoOnline -- Enable transmission/reception.
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
);
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
);
916 /* Record start time and report Online event */
918 GetSysTime(&unit
->stats
.LastStart
);
919 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
926 /****i* atheros5000.device/GoOffline ***************************************
929 * GoOffline -- Disable transmission/reception.
934 * VOID GoOffline(struct DevUnit *);
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);
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
);
986 /****i* atheros5000.device/SetOptions **************************************
989 * SetOptions -- Set and use interface options.
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
)
1011 CopyMem((APTR
)tag_item
->ti_Data
, unit
->bssid
, ETH_ADDRESSSIZE
);
1014 case S2INFO_AssocID
:
1015 unit
->assoc_id
= tag_item
->ti_Data
;
1018 case S2INFO_Capabilities
:
1019 unit
->capabilities
= tag_item
->ti_Data
;
1020 if((unit
->capabilities
& (1 << 5)) != 0)
1021 unit
->flags
|= UNITF_SHORTPREAMBLE
;
1023 unit
->flags
&= ~UNITF_SHORTPREAMBLE
;
1026 case S2INFO_DefaultKeyNo
:
1027 unit
->tx_key_no
= tag_item
->ti_Data
;
1030 case S2INFO_PortType
:
1031 unit
->mode
= tag_item
->ti_Data
;
1034 case S2INFO_Channel
:
1035 if(tag_item
->ti_Data
!= unit
->channel
)
1037 unit
->channel
= tag_item
->ti_Data
;
1043 if(tag_item
->ti_Data
!= unit
->band
)
1045 unit
->band
= tag_item
->ti_Data
;
1057 /****i* atheros5000.device/SetKey ******************************************
1060 * SetKey -- Set an encryption key.
1063 * SetKey(unit, index, type, key, key_length,
1066 * VOID SetKey(struct DevUnit *, ULONG, ULONG, UBYTE *, ULONG,
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
;
1082 slot
= &unit
->keys
[index
];
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
);
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
);
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
]);
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 */
1167 /****i* atheros5000.device/AddMulticastRange *******************************
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
);
1200 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
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;
1210 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1211 unit
->range_count
++;
1212 SetMulticast(unit
, base
);
1217 return range
!= NULL
;
1222 /****i* atheros5000.device/RemMulticastRange *******************************
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
);
1253 if(--range
->add_count
== 0)
1256 Remove((APTR
)range
);
1257 unit
->range_count
--;
1258 SetMulticast(unit
, base
);
1260 FreeMem(range
, sizeof(struct AddressRange
));
1264 return range
!= NULL
;
1269 /****i* atheros5000.device/FindMulticastRange ******************************
1272 * FindMulticastRange
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
;
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
)
1303 range
= (APTR
)range
->node
.mln_Succ
;
1314 /****i* atheros5000.device/SetMulticast ************************************
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);
1337 /****i* atheros5000.device/FindTypeStats ***********************************
1343 * stats = FindTypeStats(unit, list,
1346 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1349 ****************************************************************************
1353 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1354 ULONG packet_type
, struct DevBase
*base
)
1356 struct TypeStats
*stats
, *tail
;
1359 stats
= (APTR
)list
->mlh_Head
;
1360 tail
= (APTR
)&list
->mlh_Tail
;
1362 while(stats
!= tail
&& !found
)
1364 if(stats
->packet_type
== packet_type
)
1367 stats
= (APTR
)stats
->node
.mln_Succ
;
1378 /****i* atheros5000.device/FlushUnit ***************************************
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
;
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
);
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
;
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
);
1452 /****i* atheros5000.device/StatusInt ***************************************
1458 * finished = StatusInt(unit)
1460 * BOOL StatusInt(struct DevUnit *);
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
;
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
;
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
);
1510 int_mask
= INT_MASK
;
1512 // unit->hal->ah_setInterrupts(unit->hal, int_mask))
1519 /****i* atheros5000.device/RXInt *******************************************
1522 * RXInt -- Soft interrupt for packet reception.
1527 * VOID RXInt(struct DevUnit *);
1532 * unit - A unit of this device.
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
;
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
)
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 */
1578 ieee_length
= status
.rs_datalen
- FCS_SIZE
- WIFI_FRM_DATA
;
1579 data
= frame
+ WIFI_FRM_DATA
;
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
;
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)
1598 BEWord(*(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
));
1601 /* Create new 802.3 header */
1603 CopyMem(frame
+ WIFI_FRM_ADDRESS1
, snap_frame
,
1605 CopyMem(source
, snap_frame
+ ETH_PACKET_SOURCE
,
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
;
1619 encryption
= S2ENC_NONE
;
1621 /* Append fragment to frame, decrypting/checking fragment if
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 */
1632 ieee_length
+= old_length
;
1633 *(UWORD
*)(snap_frame
+ ETH_PACKET_IEEELEN
) =
1634 MakeBEWord(ieee_length
);
1637 unit
->stats
.BadData
++;
1639 /* If all fragments have arrived, process the complete frame */
1641 if((frame_control
& WIFI_FRM_CONTROLF_MOREFRAGS
) == 0)
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
);
1658 unit
->stats
.BadData
++;
1664 /* Get frame's 802.11 type and subtype */
1666 frame_type
= (frame_control
& WIFI_FRM_CONTROLF_TYPE
)
1667 >> WIFI_FRM_CONTROLB_TYPE
;
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,
1680 else if(AddressFilter(unit
, snap_frame
+ ETH_PACKET_DEST
,
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;
1694 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_RX
, base
);
1703 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1707 /* Prepare descriptor for next time */
1709 unit
->hal
->ah_setupRxDesc(unit
->hal
, rx_desc
, FRAME_BUFFER_SIZE
,
1712 dma_size
= FRAME_BUFFER_SIZE
;
1713 CachePreDMA(buffer
, &dma_size
, 0);
1715 /* Get next descriptor */
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 */
1734 unit
->hal
->ah_setInterrupts(unit
->hal
,
1735 unit
->hal
->ah_getInterrupts(unit
->hal
) | HAL_INT_RX
| HAL_INT_RXEOL
);
1744 /****i* atheros5000.device/GetRXBuffer *************************************
1747 * GetRXBuffer -- Find an appropriate RX frame buffer to use.
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
)
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)))
1787 unit
->rx_fragment_nos
[i
% FRAME_BUFFER_COUNT
] = frag_no
;
1791 buffer
+= FRAME_BUFFER_SIZE
;
1802 /****i* atheros5000.device/DistributeRXPacket ******************************
1805 * DistributeRXPacket -- Send a packet to all appropriate destinations.
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
;
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 */
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
);
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
;
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
,
1873 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1878 opener
= (APTR
)opener
->node
.mln_Succ
;
1881 /* If packet was unwanted, give it to S2_READORPHAN request */
1885 unit
->stats
.UnknownTypesReceived
++;
1886 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1889 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1890 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1895 /* Update remaining statistics */
1897 if(packet_type
<= ETH_MTU
)
1898 packet_type
= ETH_MTU
;
1900 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1903 tracker
->stats
.PacketsReceived
++;
1904 tracker
->stats
.BytesReceived
+= packet_size
;
1908 unit
->stats
.BadData
++;
1915 /****i* atheros5000.device/CopyPacket **************************************
1918 * CopyPacket -- Copy packet to client's buffer.
1921 * CopyPacket(unit, request, packet_size, packet_type,
1924 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
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
,
1951 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
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
;
1964 packet_size
+= 4; /* Needed for Shapeshifter & Fusion? */
1966 request
->ios2_DataLength
= packet_size
;
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
))
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
;
1985 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1988 Remove((APTR
)request
);
1989 ReplyMsg((APTR
)request
);
1997 /****i* atheros5000.device/AddressFilter ***********************************
2000 * AddressFilter -- Determine if an RX packet should be accepted.
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
;
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
;
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
))
2042 range
= (APTR
)range
->node
.mln_Succ
;
2046 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
2054 /****i* atheros5000.device/DistributeMgmtFrame *****************************
2057 * DistributeMgmtFrame -- Send a management frame to clients.
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
);
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
;
2094 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
2095 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
2097 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
2100 ReplyMsg((APTR
)request
);
2102 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2105 opener
= (APTR
)opener
->node
.mln_Succ
;
2113 /****i* atheros5000.device/TXInt *******************************************
2116 * TXInt -- Soft interrupt for packet transmission.
2121 * VOID TXInt(struct DevUnit *);
2126 * unit - A unit of this device.
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
));
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
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
);
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
;
2196 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2197 | S2EVENT_TX
, base
);
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
));
2212 packet_type
= request
->ios2_PacketType
;
2213 is_ieee
= packet_type
<= ETH_MTU
;
2215 /* Determine encryption type and frame subtype */
2219 encryption
= unit
->keys
[unit
->tx_key_no
].type
;
2224 encryption
= S2ENC_NONE
;
2228 /* Get source and destination addresses */
2230 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) != 0)
2233 source
= buffer
+ ETH_ADDRESSSIZE
;
2234 buffer
+= ETH_ADDRESSSIZE
* 2 + 2;
2238 dest
= request
->ios2_DstAddr
;
2239 source
= unit
->address
;
2242 /* Write 802.11 header */
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
);
2252 i
= rate_table
->rateCodeToIndex
[unit
->tx_rate_codes
[0]];
2253 if((unit
->flags
& UNITF_SHORTPREAMBLE
) != 0)
2254 duration
= rate_table
->info
[i
].spAckDuration
;
2256 duration
= rate_table
->info
[i
].lpAckDuration
;
2257 *(UWORD
*)q
= MakeLEWord(duration
);
2260 if(unit
->mode
== S2PORT_ADHOC
)
2264 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2267 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2270 if(unit
->mode
== S2PORT_ADHOC
)
2274 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
2279 // TO DO: need to pad header to 4-byte boundary?
2281 /* Leave room for encryption overhead */
2284 q
+= unit
->iv_sizes
[encryption
];
2287 /* Write SNAP header */
2291 for(i
= 0, p
= snap_template
;
2292 i
< SNAP_FRM_TYPE
; i
++)
2294 *(UWORD
*)q
= MakeBEWord(packet_type
);
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)
2311 for(i
= 0, p
= dest
; i
< ETH_ADDRESSSIZE
; i
++)
2313 for(i
= 0, p
= source
; i
< ETH_ADDRESSSIZE
; i
++)
2315 TKIPEncryptFrame(unit
, mic_header
, plaintext
, body_size
,
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
,
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
,
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)
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);
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
;
2376 /* Reply failed request */
2378 request
->ios2_Req
.io_Error
= error
;
2379 request
->ios2_WireError
= wire_error
;
2380 ReplyMsg((APTR
)request
);
2383 /* Update statistics */
2387 unit
->stats
.PacketsSent
++;
2389 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2390 request
->ios2_PacketType
, base
);
2393 tracker
->stats
.PacketsSent
++;
2394 tracker
->stats
.BytesSent
+= ETH_HEADERSIZE
+ data_size
;
2402 /* Don't try to keep sending packets if there's no space left */
2405 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2407 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2414 /****i* atheros5000.device/TXEndInt ****************************************
2417 * TXEndInt -- Clean up after a data frame has been sent.
2420 * TXEndInt(unit, int_code)
2422 * VOID TXEndInt(struct DevUnit *, APTR);
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
;
2437 struct DevBase
*base
;
2438 struct IOSana2Req
*request
;
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
))
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
);
2472 tracker
->stats
.PacketsSent
++;
2473 tracker
->stats
.BytesSent
+= frame_size
;
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
);
2497 /****i* atheros5000.device/MgmtTXInt ***************************************
2500 * MgmtTXInt -- Soft interrupt for management frame transmission.
2505 * VOID MgmtTXInt(struct DevUnit *);
2510 * unit - A unit of this device.
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
;
2524 struct IOSana2Req
*request
;
2525 BOOL proceed
= TRUE
, has_bssid
;
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
);
2562 has_bssid
= ((frame
+ WIFI_FRM_ADDRESS1
)[0] & 0x1) == 0;
2563 i
= rate_table
->rateCodeToIndex
[unit
->mgmt_rate_code
];
2566 if((unit
->flags
& UNITF_SHORTPREAMBLE
) != 0)
2567 duration
= rate_table
->info
[i
].spAckDuration
;
2569 duration
= rate_table
->info
[i
].lpAckDuration
;
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
),
2585 unit
->hal
->ah_fillTxDesc(unit
->hal
, desc
, frame_size
, TRUE
, TRUE
,
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);
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
;
2619 /* Don't try to keep sending packets if there's no space left */
2622 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2624 unit
->request_ports
[MGMT_QUEUE
]->mp_Flags
= PA_IGNORE
;
2631 /****i* atheros5000.device/MgmtTXEndInt ************************************
2634 * MgmtTXEndInt -- Clean up after a management frame has been sent.
2637 * MgmtTXEndInt(unit, int_code)
2639 * VOID MgmtTXEndInt(struct DevUnit *, APTR);
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
;
2654 struct DevBase
*base
;
2655 struct IOSana2Req
*request
;
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
))
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
);
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
);
2699 /****i* atheros5000.device/ResetHandler ************************************
2702 * ResetHandler -- Disable hardware before a reboot.
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);
2742 /****i* atheros5000.device/UpdateStats *************************************
2750 * VOID UpdateStats(struct DevUnit *);
2755 * unit - A unit of this device.
2760 ****************************************************************************
2764 VOID
UpdateStats(struct DevUnit
*unit
, struct DevBase
*base
)
2766 /* Ask for and wait for stats */
2773 /****i* atheros5000.device/ReportEvents ************************************
2779 * ReportEvents(unit, events)
2781 * VOID ReportEvents(struct DevUnit *, ULONG);
2786 * unit - A unit of this device.
2787 * events - A mask of events to report.
2792 ****************************************************************************
2796 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2797 struct DevBase
*base
)
2799 struct IOSana2Req
*request
, *tail
, *next_request
;
2802 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2803 next_request
= (APTR
)list
->lh_Head
;
2804 tail
= (APTR
)&list
->lh_Tail
;
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
);
2826 /****i* atheros5000.device/GetRadioBands ***********************************
2829 * GetRadioBands -- Get information on current network.
2832 * tag_list = GetRadioBands(unit, pool)
2834 * struct TagItem *GetRadioBands(struct DevUnit *, APTR);
2839 * unit - A unit of this device.
2840 * pool - A memory pool.
2845 ****************************************************************************
2850 struct TagItem
*GetRadioBands(struct DevUnit
*unit
, APTR pool
,
2851 struct DevBase
*base
)
2854 struct Sana2RadioBand
*bands
;
2857 bands
= AllocPooled(pool
, sizeof(struct Sana2RadioBand
) * 3);
2859 error
= S2ERR_NO_RESOURCES
;
2863 for(i
= 0; i
< 1; i
++)
2865 bands
[i
] = AllocPooled(pool
, sizeof(UWORD
) * unit
->channel_counts
[S2BAND_B
]);
2878 /****i* atheros5000.device/UnitTask ****************************************
2889 * Completes deferred requests, and handles card insertion and removal
2890 * in conjunction with the relevant interrupts.
2892 ****************************************************************************
2900 static VOID
UnitTask()
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
);