#include "ath5k.h"#include "reg.h"#include "base.h"Go to the source code of this file.
Functions | |
| FILE_LICENCE (MIT) | |
| int | ath5k_hw_set_opmode (struct ath5k_hw *ah) |
| ath5k_hw_set_opmode - Set PCU operating mode | |
| void | ath5k_hw_set_ack_bitrate_high (struct ath5k_hw *ah, int high) |
| ath5k_hw_set_ack_bitrate - set bitrate for ACKs | |
| unsigned int | ath5k_hw_get_ack_timeout (struct ath5k_hw *ah) |
| ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec | |
| int | ath5k_hw_set_ack_timeout (struct ath5k_hw *ah, unsigned int timeout) |
| ath5k_hw_set_ack_timeout - Set ACK timeout on PCU | |
| unsigned int | ath5k_hw_get_cts_timeout (struct ath5k_hw *ah) |
| ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec | |
| int | ath5k_hw_set_cts_timeout (struct ath5k_hw *ah, unsigned int timeout) |
| ath5k_hw_set_cts_timeout - Set CTS timeout on PCU | |
| void | ath5k_hw_get_lladdr (struct ath5k_hw *ah, u8 *mac) |
| ath5k_hw_get_lladdr - Get station id | |
| int | ath5k_hw_set_lladdr (struct ath5k_hw *ah, const u8 *mac) |
| ath5k_hw_set_lladdr - Set station id | |
| void | ath5k_hw_set_associd (struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) |
| ath5k_hw_set_associd - Set BSSID for association | |
| int | ath5k_hw_set_bssid_mask (struct ath5k_hw *ah, const u8 *mask) |
| ath5k_hw_set_bssid_mask - filter out bssids we listen | |
| void | ath5k_hw_start_rx_pcu (struct ath5k_hw *ah) |
| ath5k_hw_start_rx_pcu - Start RX engine | |
| void | ath5k_hw_stop_rx_pcu (struct ath5k_hw *ah) |
| at5k_hw_stop_rx_pcu - Stop RX engine | |
| void | ath5k_hw_set_mcast_filter (struct ath5k_hw *ah, u32 filter0, u32 filter1) |
| u32 | ath5k_hw_get_rx_filter (struct ath5k_hw *ah) |
| ath5k_hw_get_rx_filter - Get current rx filter | |
| void | ath5k_hw_set_rx_filter (struct ath5k_hw *ah, u32 filter) |
| ath5k_hw_set_rx_filter - Set rx filter | |
| int | ath5k_hw_reset_key (struct ath5k_hw *ah, u16 entry) |
| FILE_LICENCE | ( | MIT | ) |
| int ath5k_hw_set_opmode | ( | struct ath5k_hw * | ah | ) |
ath5k_hw_set_opmode - Set PCU operating mode
: The &struct ath5k_hw
Initialize PCU for the various operating modes (AP/STA etc)
For gPXE we always assume STA mode.
Definition at line 48 of file ath5k_pcu.c.
References ath5k_hw::ah_sta_id, ath5k_hw::ah_version, AR5K_AR5210, AR5K_BCR, AR5K_HIGH_ID, AR5K_LOW_ID, AR5K_STA_ID0, AR5K_STA_ID1, AR5K_STA_ID1_ADHOC, AR5K_STA_ID1_AP, AR5K_STA_ID1_KEYSRCH_MODE, AR5K_STA_ID1_NO_PSPOLL, AR5K_STA_ID1_PWR_SV, ath5k_hw_reg_read(), ath5k_hw_reg_write(), and u32.
Referenced by ath5k_hw_attach(), ath5k_hw_reset(), and ath5k_mode_setup().
00049 { 00050 u32 pcu_reg, beacon_reg, low_id, high_id; 00051 00052 00053 /* Preserve rest settings */ 00054 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 00055 pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP 00056 | AR5K_STA_ID1_KEYSRCH_MODE 00057 | (ah->ah_version == AR5K_AR5210 ? 00058 (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); 00059 00060 beacon_reg = 0; 00061 00062 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE 00063 | (ah->ah_version == AR5K_AR5210 ? 00064 AR5K_STA_ID1_PWR_SV : 0); 00065 00066 /* 00067 * Set PCU registers 00068 */ 00069 low_id = AR5K_LOW_ID(ah->ah_sta_id); 00070 high_id = AR5K_HIGH_ID(ah->ah_sta_id); 00071 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); 00072 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); 00073 00074 /* 00075 * Set Beacon Control Register on 5210 00076 */ 00077 if (ah->ah_version == AR5K_AR5210) 00078 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); 00079 00080 return 0; 00081 }
| void ath5k_hw_set_ack_bitrate_high | ( | struct ath5k_hw * | ah, | |
| int | high | |||
| ) |
ath5k_hw_set_ack_bitrate - set bitrate for ACKs
: The &struct ath5k_hw : Flag to determine if we want to use high transmition rate for ACKs or not
If high flag is set, we tell hw to use a set of control rates based on the current transmition rate (check out control_rates array inside reset.c). If not hw just uses the lowest rate available for the current modulation scheme being used (1Mbit for CCK and 6Mbits for OFDM).
Definition at line 95 of file ath5k_pcu.c.
References ath5k_hw::ah_version, AR5K_AR5212, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_STA_ID1, AR5K_STA_ID1_ACKCTS_6MB, AR5K_STA_ID1_BASE_RATE_11B, and u32.
Referenced by ath5k_init().
00096 { 00097 if (ah->ah_version != AR5K_AR5212) 00098 return; 00099 else { 00100 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; 00101 if (high) 00102 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); 00103 else 00104 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); 00105 } 00106 }
| unsigned int ath5k_hw_get_ack_timeout | ( | struct ath5k_hw * | ah | ) |
ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
: The &struct ath5k_hw
Definition at line 118 of file ath5k_pcu.c.
References ath5k_hw::ah_turbo, AR5K_REG_MS, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, ath5k_hw_clocktoh(), and ath5k_hw_reg_read().
00119 { 00120 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 00121 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); 00122 }
| int ath5k_hw_set_ack_timeout | ( | struct ath5k_hw * | ah, | |
| unsigned int | timeout | |||
| ) |
ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
: The &struct ath5k_hw : Timeout in usec
Definition at line 130 of file ath5k_pcu.c.
References ath5k_hw::ah_turbo, AR5K_REG_MS, AR5K_REG_WRITE_BITS, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, ath5k_hw_clocktoh(), ath5k_hw_htoclock(), and EINVAL.
00131 { 00132 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), 00133 ah->ah_turbo) <= timeout) 00134 return -EINVAL; 00135 00136 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, 00137 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 00138 00139 return 0; 00140 }
| unsigned int ath5k_hw_get_cts_timeout | ( | struct ath5k_hw * | ah | ) |
ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
: The &struct ath5k_hw
Definition at line 147 of file ath5k_pcu.c.
References ath5k_hw::ah_turbo, AR5K_REG_MS, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, ath5k_hw_clocktoh(), and ath5k_hw_reg_read().
00148 { 00149 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 00150 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); 00151 }
| int ath5k_hw_set_cts_timeout | ( | struct ath5k_hw * | ah, | |
| unsigned int | timeout | |||
| ) |
ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
: The &struct ath5k_hw : Timeout in usec
Definition at line 159 of file ath5k_pcu.c.
References ath5k_hw::ah_turbo, AR5K_REG_MS, AR5K_REG_WRITE_BITS, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, ath5k_hw_clocktoh(), ath5k_hw_htoclock(), and EINVAL.
00160 { 00161 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), 00162 ah->ah_turbo) <= timeout) 00163 return -EINVAL; 00164 00165 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, 00166 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 00167 00168 return 0; 00169 }
ath5k_hw_get_lladdr - Get station id
: The &struct ath5k_hw : The card's mac address
Initialize ah->ah_sta_id using the mac address provided (just a memcpy).
TODO: Remove it once we merge ath5k_softc and ath5k_hw
Definition at line 187 of file ath5k_pcu.c.
References ath5k_hw::ah_sta_id, ETH_ALEN, and memcpy.
ath5k_hw_set_lladdr - Set station id
: The &struct ath5k_hw : The card's mac address
Set station id on hw using the provided mac address
Definition at line 200 of file ath5k_pcu.c.
References ath5k_hw::ah_sta_id, AR5K_HIGH_ID, AR5K_LOW_ID, AR5K_STA_ID0, AR5K_STA_ID1, ath5k_hw_reg_read(), ath5k_hw_reg_write(), ETH_ALEN, memcpy, and u32.
Referenced by ath5k_start(), and ath5k_stop().
00201 { 00202 u32 low_id, high_id; 00203 u32 pcu_reg; 00204 00205 /* Set new station ID */ 00206 memcpy(ah->ah_sta_id, mac, ETH_ALEN); 00207 00208 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 00209 00210 low_id = AR5K_LOW_ID(mac); 00211 high_id = AR5K_HIGH_ID(mac); 00212 00213 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); 00214 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); 00215 00216 return 0; 00217 }
ath5k_hw_set_associd - Set BSSID for association
: The &struct ath5k_hw : BSSID : Assoc id
Sets the BSSID which trigers the "SME Join" operation
Definition at line 228 of file ath5k_pcu.c.
References ath5k_hw::ah_bssid_mask, ath5k_hw::ah_version, AR5K_AR5212, AR5K_BSS_ID0, AR5K_BSS_ID1, AR5K_BSS_ID1_AID_S, AR5K_BSS_IDM0, AR5K_BSS_IDM1, AR5K_HIGH_ID, AR5K_LOW_ID, ath5k_hw_reg_write(), and u32.
Referenced by ath5k_config(), ath5k_hw_attach(), and ath5k_hw_reset().
00229 { 00230 u32 low_id, high_id; 00231 00232 /* 00233 * Set simple BSSID mask on 5212 00234 */ 00235 if (ah->ah_version == AR5K_AR5212) { 00236 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask), 00237 AR5K_BSS_IDM0); 00238 ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask), 00239 AR5K_BSS_IDM1); 00240 } 00241 00242 /* 00243 * Set BSSID which triggers the "SME Join" operation 00244 */ 00245 low_id = AR5K_LOW_ID(bssid); 00246 high_id = AR5K_HIGH_ID(bssid); 00247 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); 00248 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << 00249 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); 00250 }
ath5k_hw_set_bssid_mask - filter out bssids we listen
: the &struct ath5k_hw : the bssid_mask, a u8 array of size ETH_ALEN
BSSID masking is a method used by AR5212 and newer hardware to inform PCU which bits of the interface's MAC address should be looked at when trying to decide which packets to ACK. In station mode and AP mode with a single BSS every bit matters since we lock to only one BSS. In AP mode with multiple BSSes (virtual interfaces) not every bit matters because hw must accept frames for all BSSes and so we tweak some bits of our mac address in order to have multiple BSSes.
NOTE: This is a simple filter and does *not* filter out all relevant frames. Some frames that are not for us might get ACKed from us by PCU because they just match the mask.
When handling multiple BSSes you can get the BSSID mask by computing the set of ~ ( MAC XOR BSSID ) for all bssids we handle.
When you do this you are essentially computing the common bits of all your BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with the MAC address to obtain the relevant bits and compare the result with (frame's BSSID & mask) to see if they match.
Definition at line 348 of file ath5k_pcu.c.
References ath5k_hw::ah_bssid_mask, ath5k_hw::ah_version, AR5K_AR5212, AR5K_BSS_IDM0, AR5K_BSS_IDM1, AR5K_HIGH_ID, AR5K_LOW_ID, ath5k_hw_reg_write(), EIO, ETH_ALEN, memcpy, and u32.
Referenced by ath5k_attach(), and ath5k_mode_setup().
00349 { 00350 u32 low_id, high_id; 00351 00352 /* Cache bssid mask so that we can restore it 00353 * on reset */ 00354 memcpy(ah->ah_bssid_mask, mask, ETH_ALEN); 00355 if (ah->ah_version == AR5K_AR5212) { 00356 low_id = AR5K_LOW_ID(mask); 00357 high_id = AR5K_HIGH_ID(mask); 00358 00359 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0); 00360 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1); 00361 00362 return 0; 00363 } 00364 00365 return -EIO; 00366 }
| void ath5k_hw_start_rx_pcu | ( | struct ath5k_hw * | ah | ) |
ath5k_hw_start_rx_pcu - Start RX engine
: The &struct ath5k_hw
Starts RX engine on PCU so that hw can process RXed frames (ACK etc).
NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma TODO: Init ANI here
Definition at line 384 of file ath5k_pcu.c.
References AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX, and AR5K_REG_DISABLE_BITS.
Referenced by ath5k_rx_start().
00385 { 00386 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 00387 }
| void ath5k_hw_stop_rx_pcu | ( | struct ath5k_hw * | ah | ) |
at5k_hw_stop_rx_pcu - Stop RX engine
: The &struct ath5k_hw
Stops RX engine on PCU
TODO: Detach ANI here
Definition at line 398 of file ath5k_pcu.c.
References AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX, and AR5K_REG_ENABLE_BITS.
Referenced by ath5k_rx_stop().
00399 { 00400 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 00401 }
Definition at line 406 of file ath5k_pcu.c.
References AR5K_MCAST_FILTER0, AR5K_MCAST_FILTER1, and ath5k_hw_reg_write().
Referenced by ath5k_configure_filter(), and ath5k_mode_setup().
00407 { 00408 /* Set the multicat filter */ 00409 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); 00410 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); 00411 }
ath5k_hw_get_rx_filter - Get current rx filter
: The &struct ath5k_hw
Returns the RX filter by reading rx filter and phy error filter registers. RX filter is used to set the allowed frame types that PCU will accept and pass to the driver. For a list of frame types check out reg.h.
Definition at line 424 of file ath5k_pcu.c.
References ath5k_hw::ah_version, AR5K_AR5212, AR5K_PHY_ERR_FIL, AR5K_PHY_ERR_FIL_CCK, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHY_ERR_FIL_RADAR, AR5K_RX_FILTER, AR5K_RX_FILTER_PHYERR, AR5K_RX_FILTER_RADARERR, ath5k_hw_reg_read(), filter(), and u32.
00425 { 00426 u32 data, filter = 0; 00427 00428 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); 00429 00430 /*Radar detection for 5212*/ 00431 if (ah->ah_version == AR5K_AR5212) { 00432 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL); 00433 00434 if (data & AR5K_PHY_ERR_FIL_RADAR) 00435 filter |= AR5K_RX_FILTER_RADARERR; 00436 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK)) 00437 filter |= AR5K_RX_FILTER_PHYERR; 00438 } 00439 00440 return filter; 00441 }
ath5k_hw_set_rx_filter - Set rx filter
: The &struct ath5k_hw : RX filter mask (see reg.h)
Sets RX filter register and also handles PHY error filter register on 5212 and newer chips so that we have proper PHY error reporting.
Definition at line 453 of file ath5k_pcu.c.
References ath5k_hw::ah_version, AR5K_AR5210, AR5K_AR5212, AR5K_PHY_ERR_FIL, AR5K_PHY_ERR_FIL_CCK, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHY_ERR_FIL_RADAR, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_RX_FILTER, AR5K_RX_FILTER_PHYERR, AR5K_RX_FILTER_PROM, AR5K_RX_FILTER_RADARERR, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA, ath5k_hw_reg_write(), and u32.
Referenced by ath5k_configure_filter(), ath5k_mode_setup(), and ath5k_rx_stop().
00454 { 00455 u32 data = 0; 00456 00457 /* Set PHY error filter register on 5212*/ 00458 if (ah->ah_version == AR5K_AR5212) { 00459 if (filter & AR5K_RX_FILTER_RADARERR) 00460 data |= AR5K_PHY_ERR_FIL_RADAR; 00461 if (filter & AR5K_RX_FILTER_PHYERR) 00462 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK; 00463 } 00464 00465 /* 00466 * The AR5210 uses promiscous mode to detect radar activity 00467 */ 00468 if (ah->ah_version == AR5K_AR5210 && 00469 (filter & AR5K_RX_FILTER_RADARERR)) { 00470 filter &= ~AR5K_RX_FILTER_RADARERR; 00471 filter |= AR5K_RX_FILTER_PROM; 00472 } 00473 00474 /*Zero length DMA (phy error reporting) */ 00475 if (data) 00476 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); 00477 else 00478 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); 00479 00480 /*Write RX Filter register*/ 00481 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER); 00482 00483 /*Write PHY error filter register on 5212*/ 00484 if (ah->ah_version == AR5K_AR5212) 00485 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL); 00486 00487 }
Definition at line 496 of file ath5k_pcu.c.
References ath5k_hw::ah_version, AR5K_AR5211, AR5K_KEYCACHE_SIZE, AR5K_KEYTABLE_MIC_OFFSET, AR5K_KEYTABLE_OFF, AR5K_KEYTABLE_TYPE, AR5K_KEYTABLE_TYPE_NULL, AR5K_KEYTABLE_TYPE_TKIP, ath5k_hw_reg_read(), ath5k_hw_reg_write(), and u16.
Referenced by ath5k_init().
00497 { 00498 unsigned int i, type; 00499 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; 00500 00501 type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); 00502 00503 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) 00504 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); 00505 00506 /* Reset associated MIC entry if TKIP 00507 * is enabled located at offset (entry + 64) */ 00508 if (type == AR5K_KEYTABLE_TYPE_TKIP) { 00509 for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) 00510 ath5k_hw_reg_write(ah, 0, 00511 AR5K_KEYTABLE_OFF(micentry, i)); 00512 } 00513 00514 /* 00515 * Set NULL encryption on AR5212+ 00516 * 00517 * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) 00518 * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 00519 * 00520 * Note2: Windows driver (ndiswrapper) sets this to 00521 * 0x00000714 instead of 0x00000007 00522 */ 00523 if (ah->ah_version >= AR5K_AR5211) { 00524 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, 00525 AR5K_KEYTABLE_TYPE(entry)); 00526 00527 if (type == AR5K_KEYTABLE_TYPE_TKIP) { 00528 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, 00529 AR5K_KEYTABLE_TYPE(micentry)); 00530 } 00531 } 00532 00533 return 0; 00534 }
1.5.7.1