aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h68
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c34
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c267
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h19
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c41
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h8
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c6
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c292
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c235
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c25
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h20
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c69
14 files changed, 607 insertions, 483 deletions
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 06d006675d7d..eb83b7b4d0e3 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,6 +1,6 @@
1config ATH5K 1config ATH5K
2 tristate "Atheros 5xxx wireless cards support" 2 tristate "Atheros 5xxx wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211 3 depends on PCI && MAC80211
4 select MAC80211_LEDS 4 select MAC80211_LEDS
5 select LEDS_CLASS 5 select LEDS_CLASS
6 select NEW_LEDS 6 select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6cd5efcec417..ac67f02e26d8 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -35,6 +35,7 @@
35 * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities) 35 * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
36 * and clean up common bits, then introduce set/get functions in eeprom.c */ 36 * and clean up common bits, then introduce set/get functions in eeprom.c */
37#include "eeprom.h" 37#include "eeprom.h"
38#include "../ath.h"
38 39
39/* PCI IDs */ 40/* PCI IDs */
40#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ 41#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */
@@ -165,13 +166,6 @@
165#define AR5K_INI_VAL_XR 0 166#define AR5K_INI_VAL_XR 0
166#define AR5K_INI_VAL_MAX 5 167#define AR5K_INI_VAL_MAX 5
167 168
168/* Used for BSSID etc manipulation */
169#define AR5K_LOW_ID(_a)( \
170(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
171)
172
173#define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8)
174
175/* 169/*
176 * Some tuneable values (these should be changeable by the user) 170 * Some tuneable values (these should be changeable by the user)
177 * TODO: Make use of them and add more options OR use debug/configfs 171 * TODO: Make use of them and add more options OR use debug/configfs
@@ -204,6 +198,7 @@
204#define AR5K_TUNE_CWMAX_11B 1023 198#define AR5K_TUNE_CWMAX_11B 1023
205#define AR5K_TUNE_CWMAX_XR 7 199#define AR5K_TUNE_CWMAX_XR 7
206#define AR5K_TUNE_NOISE_FLOOR -72 200#define AR5K_TUNE_NOISE_FLOOR -72
201#define AR5K_TUNE_CCA_MAX_GOOD_VALUE -95
207#define AR5K_TUNE_MAX_TXPOWER 63 202#define AR5K_TUNE_MAX_TXPOWER 63
208#define AR5K_TUNE_DEFAULT_TXPOWER 25 203#define AR5K_TUNE_DEFAULT_TXPOWER 25
209#define AR5K_TUNE_TPC_TXPOWER false 204#define AR5K_TUNE_TPC_TXPOWER false
@@ -540,13 +535,12 @@ struct ath5k_txq_info {
540 u32 tqi_cbr_period; /* Constant bit rate period */ 535 u32 tqi_cbr_period; /* Constant bit rate period */
541 u32 tqi_cbr_overflow_limit; 536 u32 tqi_cbr_overflow_limit;
542 u32 tqi_burst_time; 537 u32 tqi_burst_time;
543 u32 tqi_ready_time; /* Not used */ 538 u32 tqi_ready_time; /* Time queue waits after an event */
544}; 539};
545 540
546/* 541/*
547 * Transmit packet types. 542 * Transmit packet types.
548 * used on tx control descriptor 543 * used on tx control descriptor
549 * TODO: Use them inside base.c corectly
550 */ 544 */
551enum ath5k_pkt_type { 545enum ath5k_pkt_type {
552 AR5K_PKT_TYPE_NORMAL = 0, 546 AR5K_PKT_TYPE_NORMAL = 0,
@@ -1012,6 +1006,14 @@ struct ath5k_capabilities {
1012 } cap_queues; 1006 } cap_queues;
1013}; 1007};
1014 1008
1009/* size of noise floor history (keep it a power of two) */
1010#define ATH5K_NF_CAL_HIST_MAX 8
1011struct ath5k_nfcal_hist
1012{
1013 s16 index; /* current index into nfval */
1014 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1015};
1016
1015 1017
1016/***************************************\ 1018/***************************************\
1017 HARDWARE ABSTRACTION LAYER STRUCTURE 1019 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1027,6 +1029,7 @@ struct ath5k_capabilities {
1027/* TODO: Clean up and merge with ath5k_softc */ 1029/* TODO: Clean up and merge with ath5k_softc */
1028struct ath5k_hw { 1030struct ath5k_hw {
1029 u32 ah_magic; 1031 u32 ah_magic;
1032 struct ath_common common;
1030 1033
1031 struct ath5k_softc *ah_sc; 1034 struct ath5k_softc *ah_sc;
1032 void __iomem *ah_iobase; 1035 void __iomem *ah_iobase;
@@ -1059,6 +1062,7 @@ struct ath5k_hw {
1059 u32 ah_cw_min; 1062 u32 ah_cw_min;
1060 u32 ah_cw_max; 1063 u32 ah_cw_max;
1061 u32 ah_limit_tx_retries; 1064 u32 ah_limit_tx_retries;
1065 u8 ah_coverage_class;
1062 1066
1063 /* Antenna Control */ 1067 /* Antenna Control */
1064 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1068 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1067,14 +1071,6 @@ struct ath5k_hw {
1067 u8 ah_def_ant; 1071 u8 ah_def_ant;
1068 bool ah_software_retry; 1072 bool ah_software_retry;
1069 1073
1070 u8 ah_sta_id[ETH_ALEN];
1071
1072 /* Current BSSID we are trying to assoc to / create.
1073 * This is passed by mac80211 on config_interface() and cached here for
1074 * use in resets */
1075 u8 ah_bssid[ETH_ALEN];
1076 u8 ah_bssid_mask[ETH_ALEN];
1077
1078 int ah_gpio_npins; 1074 int ah_gpio_npins;
1079 1075
1080 struct ath5k_capabilities ah_capabilities; 1076 struct ath5k_capabilities ah_capabilities;
@@ -1125,6 +1121,8 @@ struct ath5k_hw {
1125 struct ieee80211_channel r_last_channel; 1121 struct ieee80211_channel r_last_channel;
1126 } ah_radar; 1122 } ah_radar;
1127 1123
1124 struct ath5k_nfcal_hist ah_nfcal_hist;
1125
1128 /* noise floor from last periodic calibration */ 1126 /* noise floor from last periodic calibration */
1129 s32 ah_noise_floor; 1127 s32 ah_noise_floor;
1130 1128
@@ -1160,7 +1158,7 @@ struct ath5k_hw {
1160 */ 1158 */
1161 1159
1162/* Attach/Detach Functions */ 1160/* Attach/Detach Functions */
1163extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc); 1161extern int ath5k_hw_attach(struct ath5k_softc *sc);
1164extern void ath5k_hw_detach(struct ath5k_hw *ah); 1162extern void ath5k_hw_detach(struct ath5k_hw *ah);
1165 1163
1166/* LED functions */ 1164/* LED functions */
@@ -1202,11 +1200,11 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1202 1200
1203/* Protocol Control Unit Functions */ 1201/* Protocol Control Unit Functions */
1204extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
1203extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1205/* BSSID Functions */ 1204/* BSSID Functions */
1206extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
1207extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1205extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1208extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id); 1206extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
1209extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1207extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1210/* Receive start/stop functions */ 1208/* Receive start/stop functions */
1211extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1209extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1212extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1210extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
@@ -1234,6 +1232,10 @@ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1234extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); 1232extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1235extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); 1233extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1236extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); 1234extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1235/* Clock rate related functions */
1236unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1237unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1238unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1237/* Key table (WEP) functions */ 1239/* Key table (WEP) functions */
1238extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1240extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1239extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1241extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
@@ -1288,8 +1290,10 @@ extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
1288extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); 1290extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1289extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1291extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1290/* PHY calibration */ 1292/* PHY calibration */
1293void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1291extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1294extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1292extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); 1295extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1296extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
1293extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah); 1297extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1294/* Spur mitigation */ 1298/* Spur mitigation */
1295bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1299bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
@@ -1311,35 +1315,21 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1311 * Functions used internaly 1315 * Functions used internaly
1312 */ 1316 */
1313 1317
1314/* 1318static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
1315 * Translate usec to hw clock units
1316 * TODO: Half/quarter rate
1317 */
1318static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1319{ 1319{
1320 return turbo ? (usec * 80) : (usec * 40); 1320 return &ah->common;
1321} 1321}
1322 1322
1323/* 1323static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
1324 * Translate hw clock units to usec
1325 * TODO: Half/quarter rate
1326 */
1327static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1328{ 1324{
1329 return turbo ? (clock / 80) : (clock / 40); 1325 return &(ath5k_hw_common(ah)->regulatory);
1330} 1326}
1331 1327
1332/*
1333 * Read from a register
1334 */
1335static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) 1328static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1336{ 1329{
1337 return ioread32(ah->ah_iobase + reg); 1330 return ioread32(ah->ah_iobase + reg);
1338} 1331}
1339 1332
1340/*
1341 * Write to a register
1342 */
1343static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) 1333static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1344{ 1334{
1345 iowrite32(val, ah->ah_iobase + reg); 1335 iowrite32(val, ah->ah_iobase + reg);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 71a1bd254517..dc0786cc2639 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -21,6 +21,7 @@
21\*************************************/ 21\*************************************/
22 22
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/slab.h>
24#include "ath5k.h" 25#include "ath5k.h"
25#include "reg.h" 26#include "reg.h"
26#include "debug.h" 27#include "debug.h"
@@ -101,25 +102,15 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
101 * -ENODEV if the device is not supported or prints an error msg if something 102 * -ENODEV if the device is not supported or prints an error msg if something
102 * else went wrong. 103 * else went wrong.
103 */ 104 */
104struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc) 105int ath5k_hw_attach(struct ath5k_softc *sc)
105{ 106{
106 struct ath5k_hw *ah; 107 struct ath5k_hw *ah = sc->ah;
108 struct ath_common *common = ath5k_hw_common(ah);
107 struct pci_dev *pdev = sc->pdev; 109 struct pci_dev *pdev = sc->pdev;
108 struct ath5k_eeprom_info *ee; 110 struct ath5k_eeprom_info *ee;
109 int ret; 111 int ret;
110 u32 srev; 112 u32 srev;
111 113
112 /*If we passed the test malloc a ath5k_hw struct*/
113 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
114 if (ah == NULL) {
115 ret = -ENOMEM;
116 ATH5K_ERR(sc, "out of memory\n");
117 goto err;
118 }
119
120 ah->ah_sc = sc;
121 ah->ah_iobase = sc->iobase;
122
123 /* 114 /*
124 * HW information 115 * HW information
125 */ 116 */
@@ -278,12 +269,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
278 goto err_free; 269 goto err_free;
279 } 270 }
280 271
272 ee = &ah->ah_capabilities.cap_eeprom;
273
281 /* 274 /*
282 * Write PCI-E power save settings 275 * Write PCI-E power save settings
283 */ 276 */
284 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { 277 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
285 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
286
287 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); 278 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
288 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); 279 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
289 280
@@ -321,7 +312,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
321 } 312 }
322 313
323 /* Crypto settings */ 314 /* Crypto settings */
324 ee = &ah->ah_capabilities.cap_eeprom;
325 ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && 315 ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
326 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && 316 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
327 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); 317 !AR5K_EEPROM_AES_DIS(ee->ee_misc5));
@@ -336,20 +326,21 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
336 ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){}); 326 ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
337 327
338 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 328 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
339 memset(ah->ah_bssid, 0xff, ETH_ALEN); 329 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
340 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 330 ath5k_hw_set_associd(ah);
341 ath5k_hw_set_opmode(ah); 331 ath5k_hw_set_opmode(ah);
342 332
343 ath5k_hw_rfgain_opt_init(ah); 333 ath5k_hw_rfgain_opt_init(ah);
344 334
335 ath5k_hw_init_nfcal_hist(ah);
336
345 /* turn on HW LEDs */ 337 /* turn on HW LEDs */
346 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); 338 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
347 339
348 return ah; 340 return 0;
349err_free: 341err_free:
350 kfree(ah); 342 kfree(ah);
351err: 343 return ret;
352 return ERR_PTR(ret);
353} 344}
354 345
355/** 346/**
@@ -369,5 +360,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
369 ath5k_eeprom_detach(ah); 360 ath5k_eeprom_detach(ah);
370 361
371 /* assume interrupts are down */ 362 /* assume interrupts are down */
372 kfree(ah);
373} 363}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 95a8e232b58f..3abbe7513ab5 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -50,6 +50,7 @@
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/ethtool.h> 51#include <linux/ethtool.h>
52#include <linux/uaccess.h> 52#include <linux/uaccess.h>
53#include <linux/slab.h>
53 54
54#include <net/ieee80211_radiotap.h> 55#include <net/ieee80211_radiotap.h>
55 56
@@ -83,7 +84,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
83 84
84 85
85/* Known PCI ids */ 86/* Known PCI ids */
86static const struct pci_device_id ath5k_pci_id_table[] = { 87static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {
87 { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ 88 { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
88 { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ 89 { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
89 { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ 90 { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
@@ -195,12 +196,13 @@ static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
195 const struct pci_device_id *id); 196 const struct pci_device_id *id);
196static void __devexit ath5k_pci_remove(struct pci_dev *pdev); 197static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
197#ifdef CONFIG_PM 198#ifdef CONFIG_PM
198static int ath5k_pci_suspend(struct pci_dev *pdev, 199static int ath5k_pci_suspend(struct device *dev);
199 pm_message_t state); 200static int ath5k_pci_resume(struct device *dev);
200static int ath5k_pci_resume(struct pci_dev *pdev); 201
202SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
203#define ATH5K_PM_OPS (&ath5k_pm_ops)
201#else 204#else
202#define ath5k_pci_suspend NULL 205#define ATH5K_PM_OPS NULL
203#define ath5k_pci_resume NULL
204#endif /* CONFIG_PM */ 206#endif /* CONFIG_PM */
205 207
206static struct pci_driver ath5k_pci_driver = { 208static struct pci_driver ath5k_pci_driver = {
@@ -208,8 +210,7 @@ static struct pci_driver ath5k_pci_driver = {
208 .id_table = ath5k_pci_id_table, 210 .id_table = ath5k_pci_id_table,
209 .probe = ath5k_pci_probe, 211 .probe = ath5k_pci_probe,
210 .remove = __devexit_p(ath5k_pci_remove), 212 .remove = __devexit_p(ath5k_pci_remove),
211 .suspend = ath5k_pci_suspend, 213 .driver.pm = ATH5K_PM_OPS,
212 .resume = ath5k_pci_resume,
213}; 214};
214 215
215 216
@@ -225,9 +226,9 @@ static int ath5k_reset_wake(struct ath5k_softc *sc);
225static int ath5k_start(struct ieee80211_hw *hw); 226static int ath5k_start(struct ieee80211_hw *hw);
226static void ath5k_stop(struct ieee80211_hw *hw); 227static void ath5k_stop(struct ieee80211_hw *hw);
227static int ath5k_add_interface(struct ieee80211_hw *hw, 228static int ath5k_add_interface(struct ieee80211_hw *hw,
228 struct ieee80211_if_init_conf *conf); 229 struct ieee80211_vif *vif);
229static void ath5k_remove_interface(struct ieee80211_hw *hw, 230static void ath5k_remove_interface(struct ieee80211_hw *hw,
230 struct ieee80211_if_init_conf *conf); 231 struct ieee80211_vif *vif);
231static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 232static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, 233static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
233 int mc_count, struct dev_addr_list *mc_list); 234 int mc_count, struct dev_addr_list *mc_list);
@@ -241,8 +242,6 @@ static int ath5k_set_key(struct ieee80211_hw *hw,
241 struct ieee80211_key_conf *key); 242 struct ieee80211_key_conf *key);
242static int ath5k_get_stats(struct ieee80211_hw *hw, 243static int ath5k_get_stats(struct ieee80211_hw *hw,
243 struct ieee80211_low_level_stats *stats); 244 struct ieee80211_low_level_stats *stats);
244static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
245 struct ieee80211_tx_queue_stats *stats);
246static u64 ath5k_get_tsf(struct ieee80211_hw *hw); 245static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
247static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); 246static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
248static void ath5k_reset_tsf(struct ieee80211_hw *hw); 247static void ath5k_reset_tsf(struct ieee80211_hw *hw);
@@ -254,6 +253,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
254 u32 changes); 253 u32 changes);
255static void ath5k_sw_scan_start(struct ieee80211_hw *hw); 254static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
256static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); 255static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
256static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
257 u8 coverage_class);
257 258
258static const struct ieee80211_ops ath5k_hw_ops = { 259static const struct ieee80211_ops ath5k_hw_ops = {
259 .tx = ath5k_tx, 260 .tx = ath5k_tx,
@@ -267,13 +268,13 @@ static const struct ieee80211_ops ath5k_hw_ops = {
267 .set_key = ath5k_set_key, 268 .set_key = ath5k_set_key,
268 .get_stats = ath5k_get_stats, 269 .get_stats = ath5k_get_stats,
269 .conf_tx = NULL, 270 .conf_tx = NULL,
270 .get_tx_stats = ath5k_get_tx_stats,
271 .get_tsf = ath5k_get_tsf, 271 .get_tsf = ath5k_get_tsf,
272 .set_tsf = ath5k_set_tsf, 272 .set_tsf = ath5k_set_tsf,
273 .reset_tsf = ath5k_reset_tsf, 273 .reset_tsf = ath5k_reset_tsf,
274 .bss_info_changed = ath5k_bss_info_changed, 274 .bss_info_changed = ath5k_bss_info_changed,
275 .sw_scan_start = ath5k_sw_scan_start, 275 .sw_scan_start = ath5k_sw_scan_start,
276 .sw_scan_complete = ath5k_sw_scan_complete, 276 .sw_scan_complete = ath5k_sw_scan_complete,
277 .set_coverage_class = ath5k_set_coverage_class,
277}; 278};
278 279
279/* 280/*
@@ -323,10 +324,13 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
323static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, 324static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
324 struct ath5k_buf *bf) 325 struct ath5k_buf *bf)
325{ 326{
327 struct ath5k_hw *ah = sc->ah;
328 struct ath_common *common = ath5k_hw_common(ah);
329
326 BUG_ON(!bf); 330 BUG_ON(!bf);
327 if (!bf->skb) 331 if (!bf->skb)
328 return; 332 return;
329 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 333 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
330 PCI_DMA_FROMDEVICE); 334 PCI_DMA_FROMDEVICE);
331 dev_kfree_skb_any(bf->skb); 335 dev_kfree_skb_any(bf->skb);
332 bf->skb = NULL; 336 bf->skb = NULL;
@@ -437,6 +441,22 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
437 441
438 return name; 442 return name;
439} 443}
444static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
445{
446 struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
447 return ath5k_hw_reg_read(ah, reg_offset);
448}
449
450static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
451{
452 struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
453 ath5k_hw_reg_write(ah, val, reg_offset);
454}
455
456static const struct ath_ops ath5k_common_ops = {
457 .read = ath5k_ioread32,
458 .write = ath5k_iowrite32,
459};
440 460
441static int __devinit 461static int __devinit
442ath5k_pci_probe(struct pci_dev *pdev, 462ath5k_pci_probe(struct pci_dev *pdev,
@@ -444,6 +464,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
444{ 464{
445 void __iomem *mem; 465 void __iomem *mem;
446 struct ath5k_softc *sc; 466 struct ath5k_softc *sc;
467 struct ath_common *common;
447 struct ieee80211_hw *hw; 468 struct ieee80211_hw *hw;
448 int ret; 469 int ret;
449 u8 csz; 470 u8 csz;
@@ -547,7 +568,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
547 __set_bit(ATH_STAT_INVALID, sc->status); 568 __set_bit(ATH_STAT_INVALID, sc->status);
548 569
549 sc->iobase = mem; /* So we can unmap it on detach */ 570 sc->iobase = mem; /* So we can unmap it on detach */
550 sc->common.cachelsz = csz << 2; /* convert to bytes */
551 sc->opmode = NL80211_IFTYPE_STATION; 571 sc->opmode = NL80211_IFTYPE_STATION;
552 sc->bintval = 1000; 572 sc->bintval = 1000;
553 mutex_init(&sc->lock); 573 mutex_init(&sc->lock);
@@ -565,13 +585,28 @@ ath5k_pci_probe(struct pci_dev *pdev,
565 goto err_free; 585 goto err_free;
566 } 586 }
567 587
568 /* Initialize device */ 588 /*If we passed the test malloc a ath5k_hw struct*/
569 sc->ah = ath5k_hw_attach(sc); 589 sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
570 if (IS_ERR(sc->ah)) { 590 if (!sc->ah) {
571 ret = PTR_ERR(sc->ah); 591 ret = -ENOMEM;
592 ATH5K_ERR(sc, "out of memory\n");
572 goto err_irq; 593 goto err_irq;
573 } 594 }
574 595
596 sc->ah->ah_sc = sc;
597 sc->ah->ah_iobase = sc->iobase;
598 common = ath5k_hw_common(sc->ah);
599 common->ops = &ath5k_common_ops;
600 common->ah = sc->ah;
601 common->hw = hw;
602 common->cachelsz = csz << 2; /* convert to bytes */
603
604 /* Initialize device */
605 ret = ath5k_hw_attach(sc);
606 if (ret) {
607 goto err_free_ah;
608 }
609
575 /* set up multi-rate retry capabilities */ 610 /* set up multi-rate retry capabilities */
576 if (sc->ah->ah_version == AR5K_AR5212) { 611 if (sc->ah->ah_version == AR5K_AR5212) {
577 hw->max_rates = 4; 612 hw->max_rates = 4;
@@ -640,6 +675,8 @@ err_ah:
640 ath5k_hw_detach(sc->ah); 675 ath5k_hw_detach(sc->ah);
641err_irq: 676err_irq:
642 free_irq(pdev->irq, sc); 677 free_irq(pdev->irq, sc);
678err_free_ah:
679 kfree(sc->ah);
643err_free: 680err_free:
644 ieee80211_free_hw(hw); 681 ieee80211_free_hw(hw);
645err_map: 682err_map:
@@ -661,6 +698,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
661 ath5k_debug_finish_device(sc); 698 ath5k_debug_finish_device(sc);
662 ath5k_detach(pdev, hw); 699 ath5k_detach(pdev, hw);
663 ath5k_hw_detach(sc->ah); 700 ath5k_hw_detach(sc->ah);
701 kfree(sc->ah);
664 free_irq(pdev->irq, sc); 702 free_irq(pdev->irq, sc);
665 pci_iounmap(pdev, sc->iobase); 703 pci_iounmap(pdev, sc->iobase);
666 pci_release_region(pdev, 0); 704 pci_release_region(pdev, 0);
@@ -669,33 +707,20 @@ ath5k_pci_remove(struct pci_dev *pdev)
669} 707}
670 708
671#ifdef CONFIG_PM 709#ifdef CONFIG_PM
672static int 710static int ath5k_pci_suspend(struct device *dev)
673ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
674{ 711{
675 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 712 struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
676 struct ath5k_softc *sc = hw->priv; 713 struct ath5k_softc *sc = hw->priv;
677 714
678 ath5k_led_off(sc); 715 ath5k_led_off(sc);
679
680 pci_save_state(pdev);
681 pci_disable_device(pdev);
682 pci_set_power_state(pdev, PCI_D3hot);
683
684 return 0; 716 return 0;
685} 717}
686 718
687static int 719static int ath5k_pci_resume(struct device *dev)
688ath5k_pci_resume(struct pci_dev *pdev)
689{ 720{
721 struct pci_dev *pdev = to_pci_dev(dev);
690 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 722 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
691 struct ath5k_softc *sc = hw->priv; 723 struct ath5k_softc *sc = hw->priv;
692 int err;
693
694 pci_restore_state(pdev);
695
696 err = pci_enable_device(pdev);
697 if (err)
698 return err;
699 724
700 /* 725 /*
701 * Suspend/Resume resets the PCI configuration space, so we have to 726 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -718,7 +743,7 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
718{ 743{
719 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 744 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
720 struct ath5k_softc *sc = hw->priv; 745 struct ath5k_softc *sc = hw->priv;
721 struct ath_regulatory *regulatory = &sc->common.regulatory; 746 struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
722 747
723 return ath_reg_notifier_apply(wiphy, request, regulatory); 748 return ath_reg_notifier_apply(wiphy, request, regulatory);
724} 749}
@@ -728,7 +753,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
728{ 753{
729 struct ath5k_softc *sc = hw->priv; 754 struct ath5k_softc *sc = hw->priv;
730 struct ath5k_hw *ah = sc->ah; 755 struct ath5k_hw *ah = sc->ah;
731 struct ath_regulatory *regulatory = &sc->common.regulatory; 756 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
732 u8 mac[ETH_ALEN] = {}; 757 u8 mac[ETH_ALEN] = {};
733 int ret; 758 int ret;
734 759
@@ -815,7 +840,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
815 840
816 SET_IEEE80211_PERM_ADDR(hw, mac); 841 SET_IEEE80211_PERM_ADDR(hw, mac);
817 /* All MAC address bits matter for ACKs */ 842 /* All MAC address bits matter for ACKs */
818 memset(sc->bssidmask, 0xff, ETH_ALEN); 843 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
819 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); 844 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
820 845
821 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; 846 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
@@ -1152,24 +1177,26 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
1152static 1177static
1153struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) 1178struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
1154{ 1179{
1180 struct ath_common *common = ath5k_hw_common(sc->ah);
1155 struct sk_buff *skb; 1181 struct sk_buff *skb;
1156 1182
1157 /* 1183 /*
1158 * Allocate buffer with headroom_needed space for the 1184 * Allocate buffer with headroom_needed space for the
1159 * fake physical layer header at the start. 1185 * fake physical layer header at the start.
1160 */ 1186 */
1161 skb = ath_rxbuf_alloc(&sc->common, 1187 skb = ath_rxbuf_alloc(common,
1162 sc->rxbufsize + sc->common.cachelsz - 1, 1188 common->rx_bufsize,
1163 GFP_ATOMIC); 1189 GFP_ATOMIC);
1164 1190
1165 if (!skb) { 1191 if (!skb) {
1166 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", 1192 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1167 sc->rxbufsize + sc->common.cachelsz - 1); 1193 common->rx_bufsize);
1168 return NULL; 1194 return NULL;
1169 } 1195 }
1170 1196
1171 *skb_addr = pci_map_single(sc->pdev, 1197 *skb_addr = pci_map_single(sc->pdev,
1172 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); 1198 skb->data, common->rx_bufsize,
1199 PCI_DMA_FROMDEVICE);
1173 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { 1200 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
1174 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); 1201 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1175 dev_kfree_skb(skb); 1202 dev_kfree_skb(skb);
@@ -1220,6 +1247,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1220 return 0; 1247 return 0;
1221} 1248}
1222 1249
1250static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
1251{
1252 struct ieee80211_hdr *hdr;
1253 enum ath5k_pkt_type htype;
1254 __le16 fc;
1255
1256 hdr = (struct ieee80211_hdr *)skb->data;
1257 fc = hdr->frame_control;
1258
1259 if (ieee80211_is_beacon(fc))
1260 htype = AR5K_PKT_TYPE_BEACON;
1261 else if (ieee80211_is_probe_resp(fc))
1262 htype = AR5K_PKT_TYPE_PROBE_RESP;
1263 else if (ieee80211_is_atim(fc))
1264 htype = AR5K_PKT_TYPE_ATIM;
1265 else if (ieee80211_is_pspoll(fc))
1266 htype = AR5K_PKT_TYPE_PSPOLL;
1267 else
1268 htype = AR5K_PKT_TYPE_NORMAL;
1269
1270 return htype;
1271}
1272
1223static int 1273static int
1224ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, 1274ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1225 struct ath5k_txq *txq) 1275 struct ath5k_txq *txq)
@@ -1274,7 +1324,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1274 sc->vif, pktlen, info)); 1324 sc->vif, pktlen, info));
1275 } 1325 }
1276 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1326 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1277 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1327 ieee80211_get_hdrlen_from_skb(skb),
1328 get_hw_packet_type(skb),
1278 (sc->power_level * 2), 1329 (sc->power_level * 2),
1279 hw_rate, 1330 hw_rate,
1280 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, 1331 info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
@@ -1303,7 +1354,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1303 1354
1304 spin_lock_bh(&txq->lock); 1355 spin_lock_bh(&txq->lock);
1305 list_add_tail(&bf->list, &txq->q); 1356 list_add_tail(&bf->list, &txq->q);
1306 sc->tx_stats[txq->qnum].len++;
1307 if (txq->link == NULL) /* is this first packet? */ 1357 if (txq->link == NULL) /* is this first packet? */
1308 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); 1358 ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
1309 else /* no, so only link it */ 1359 else /* no, so only link it */
@@ -1487,7 +1537,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1487 1537
1488 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); 1538 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
1489 if (ret) 1539 if (ret)
1490 return ret; 1540 goto err;
1541
1491 if (sc->opmode == NL80211_IFTYPE_AP || 1542 if (sc->opmode == NL80211_IFTYPE_AP ||
1492 sc->opmode == NL80211_IFTYPE_MESH_POINT) { 1543 sc->opmode == NL80211_IFTYPE_MESH_POINT) {
1493 /* 1544 /*
@@ -1514,10 +1565,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1514 if (ret) { 1565 if (ret) {
1515 ATH5K_ERR(sc, "%s: unable to update parameters for beacon " 1566 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1516 "hardware queue!\n", __func__); 1567 "hardware queue!\n", __func__);
1517 return ret; 1568 goto err;
1518 } 1569 }
1570 ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
1571 if (ret)
1572 goto err;
1573
1574 /* reconfigure cabq with ready time to 80% of beacon_interval */
1575 ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1576 if (ret)
1577 goto err;
1578
1579 qi.tqi_ready_time = (sc->bintval * 80) / 100;
1580 ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1581 if (ret)
1582 goto err;
1519 1583
1520 return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; 1584 ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
1585err:
1586 return ret;
1521} 1587}
1522 1588
1523static void 1589static void
@@ -1536,7 +1602,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1536 ath5k_txbuf_free(sc, bf); 1602 ath5k_txbuf_free(sc, bf);
1537 1603
1538 spin_lock_bh(&sc->txbuflock); 1604 spin_lock_bh(&sc->txbuflock);
1539 sc->tx_stats[txq->qnum].len--;
1540 list_move_tail(&bf->list, &sc->txbuf); 1605 list_move_tail(&bf->list, &sc->txbuf);
1541 sc->txbuf_len++; 1606 sc->txbuf_len++;
1542 spin_unlock_bh(&sc->txbuflock); 1607 spin_unlock_bh(&sc->txbuflock);
@@ -1605,13 +1670,14 @@ static int
1605ath5k_rx_start(struct ath5k_softc *sc) 1670ath5k_rx_start(struct ath5k_softc *sc)
1606{ 1671{
1607 struct ath5k_hw *ah = sc->ah; 1672 struct ath5k_hw *ah = sc->ah;
1673 struct ath_common *common = ath5k_hw_common(ah);
1608 struct ath5k_buf *bf; 1674 struct ath5k_buf *bf;
1609 int ret; 1675 int ret;
1610 1676
1611 sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz); 1677 common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
1612 1678
1613 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", 1679 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
1614 sc->common.cachelsz, sc->rxbufsize); 1680 common->cachelsz, common->rx_bufsize);
1615 1681
1616 spin_lock_bh(&sc->rxbuflock); 1682 spin_lock_bh(&sc->rxbuflock);
1617 sc->rxlink = NULL; 1683 sc->rxlink = NULL;
@@ -1656,6 +1722,8 @@ static unsigned int
1656ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, 1722ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1657 struct sk_buff *skb, struct ath5k_rx_status *rs) 1723 struct sk_buff *skb, struct ath5k_rx_status *rs)
1658{ 1724{
1725 struct ath5k_hw *ah = sc->ah;
1726 struct ath_common *common = ath5k_hw_common(ah);
1659 struct ieee80211_hdr *hdr = (void *)skb->data; 1727 struct ieee80211_hdr *hdr = (void *)skb->data;
1660 unsigned int keyix, hlen; 1728 unsigned int keyix, hlen;
1661 1729
@@ -1672,7 +1740,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1672 skb->len >= hlen + 4) { 1740 skb->len >= hlen + 4) {
1673 keyix = skb->data[hlen + 3] >> 6; 1741 keyix = skb->data[hlen + 3] >> 6;
1674 1742
1675 if (test_bit(keyix, sc->keymap)) 1743 if (test_bit(keyix, common->keymap))
1676 return RX_FLAG_DECRYPTED; 1744 return RX_FLAG_DECRYPTED;
1677 } 1745 }
1678 1746
@@ -1684,13 +1752,14 @@ static void
1684ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, 1752ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1685 struct ieee80211_rx_status *rxs) 1753 struct ieee80211_rx_status *rxs)
1686{ 1754{
1755 struct ath_common *common = ath5k_hw_common(sc->ah);
1687 u64 tsf, bc_tstamp; 1756 u64 tsf, bc_tstamp;
1688 u32 hw_tu; 1757 u32 hw_tu;
1689 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1758 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1690 1759
1691 if (ieee80211_is_beacon(mgmt->frame_control) && 1760 if (ieee80211_is_beacon(mgmt->frame_control) &&
1692 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && 1761 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
1693 memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { 1762 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
1694 /* 1763 /*
1695 * Received an IBSS beacon with the same BSSID. Hardware *must* 1764 * Received an IBSS beacon with the same BSSID. Hardware *must*
1696 * have updated the local TSF. We have to work around various 1765 * have updated the local TSF. We have to work around various
@@ -1745,6 +1814,8 @@ ath5k_tasklet_rx(unsigned long data)
1745 struct sk_buff *skb, *next_skb; 1814 struct sk_buff *skb, *next_skb;
1746 dma_addr_t next_skb_addr; 1815 dma_addr_t next_skb_addr;
1747 struct ath5k_softc *sc = (void *)data; 1816 struct ath5k_softc *sc = (void *)data;
1817 struct ath5k_hw *ah = sc->ah;
1818 struct ath_common *common = ath5k_hw_common(ah);
1748 struct ath5k_buf *bf; 1819 struct ath5k_buf *bf;
1749 struct ath5k_desc *ds; 1820 struct ath5k_desc *ds;
1750 int ret; 1821 int ret;
@@ -1822,7 +1893,7 @@ accept:
1822 if (!next_skb) 1893 if (!next_skb)
1823 goto next; 1894 goto next;
1824 1895
1825 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 1896 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
1826 PCI_DMA_FROMDEVICE); 1897 PCI_DMA_FROMDEVICE);
1827 skb_put(skb, rs.rs_datalen); 1898 skb_put(skb, rs.rs_datalen);
1828 1899
@@ -1871,17 +1942,6 @@ accept:
1871 rxs->noise = sc->ah->ah_noise_floor; 1942 rxs->noise = sc->ah->ah_noise_floor;
1872 rxs->signal = rxs->noise + rs.rs_rssi; 1943 rxs->signal = rxs->noise + rs.rs_rssi;
1873 1944
1874 /* An rssi of 35 indicates you should be able use
1875 * 54 Mbps reliably. A more elaborate scheme can be used
1876 * here but it requires a map of SNR/throughput for each
1877 * possible mode used */
1878 rxs->qual = rs.rs_rssi * 100 / 35;
1879
1880 /* rssi can be more than 35 though, anything above that
1881 * should be considered at 100% */
1882 if (rxs->qual > 100)
1883 rxs->qual = 100;
1884
1885 rxs->antenna = rs.rs_antenna; 1945 rxs->antenna = rs.rs_antenna;
1886 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); 1946 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1887 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); 1947 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
@@ -1971,10 +2031,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1971 } 2031 }
1972 2032
1973 ieee80211_tx_status(sc->hw, skb); 2033 ieee80211_tx_status(sc->hw, skb);
1974 sc->tx_stats[txq->qnum].count++;
1975 2034
1976 spin_lock(&sc->txbuflock); 2035 spin_lock(&sc->txbuflock);
1977 sc->tx_stats[txq->qnum].len--;
1978 list_move_tail(&bf->list, &sc->txbuf); 2036 list_move_tail(&bf->list, &sc->txbuf);
1979 sc->txbuf_len++; 2037 sc->txbuf_len++;
1980 spin_unlock(&sc->txbuflock); 2038 spin_unlock(&sc->txbuflock);
@@ -2349,6 +2407,9 @@ ath5k_init(struct ath5k_softc *sc)
2349 */ 2407 */
2350 ath5k_stop_locked(sc); 2408 ath5k_stop_locked(sc);
2351 2409
2410 /* Set PHY calibration interval */
2411 ah->ah_cal_intval = ath5k_calinterval;
2412
2352 /* 2413 /*
2353 * The basic interface to setting the hardware in a good 2414 * The basic interface to setting the hardware in a good
2354 * state is ``reset''. On return the hardware is known to 2415 * state is ``reset''. On return the hardware is known to
@@ -2376,10 +2437,6 @@ ath5k_init(struct ath5k_softc *sc)
2376 2437
2377 /* Set ack to be sent at low bit-rates */ 2438 /* Set ack to be sent at low bit-rates */
2378 ath5k_hw_set_ack_bitrate_high(ah, false); 2439 ath5k_hw_set_ack_bitrate_high(ah, false);
2379
2380 /* Set PHY calibration inteval */
2381 ah->ah_cal_intval = ath5k_calinterval;
2382
2383 ret = 0; 2440 ret = 0;
2384done: 2441done:
2385 mmiowb(); 2442 mmiowb();
@@ -2753,7 +2810,7 @@ static void ath5k_stop(struct ieee80211_hw *hw)
2753} 2810}
2754 2811
2755static int ath5k_add_interface(struct ieee80211_hw *hw, 2812static int ath5k_add_interface(struct ieee80211_hw *hw,
2756 struct ieee80211_if_init_conf *conf) 2813 struct ieee80211_vif *vif)
2757{ 2814{
2758 struct ath5k_softc *sc = hw->priv; 2815 struct ath5k_softc *sc = hw->priv;
2759 int ret; 2816 int ret;
@@ -2764,22 +2821,22 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2764 goto end; 2821 goto end;
2765 } 2822 }
2766 2823
2767 sc->vif = conf->vif; 2824 sc->vif = vif;
2768 2825
2769 switch (conf->type) { 2826 switch (vif->type) {
2770 case NL80211_IFTYPE_AP: 2827 case NL80211_IFTYPE_AP:
2771 case NL80211_IFTYPE_STATION: 2828 case NL80211_IFTYPE_STATION:
2772 case NL80211_IFTYPE_ADHOC: 2829 case NL80211_IFTYPE_ADHOC:
2773 case NL80211_IFTYPE_MESH_POINT: 2830 case NL80211_IFTYPE_MESH_POINT:
2774 case NL80211_IFTYPE_MONITOR: 2831 case NL80211_IFTYPE_MONITOR:
2775 sc->opmode = conf->type; 2832 sc->opmode = vif->type;
2776 break; 2833 break;
2777 default: 2834 default:
2778 ret = -EOPNOTSUPP; 2835 ret = -EOPNOTSUPP;
2779 goto end; 2836 goto end;
2780 } 2837 }
2781 2838
2782 ath5k_hw_set_lladdr(sc->ah, conf->mac_addr); 2839 ath5k_hw_set_lladdr(sc->ah, vif->addr);
2783 ath5k_mode_setup(sc); 2840 ath5k_mode_setup(sc);
2784 2841
2785 ret = 0; 2842 ret = 0;
@@ -2790,13 +2847,13 @@ end:
2790 2847
2791static void 2848static void
2792ath5k_remove_interface(struct ieee80211_hw *hw, 2849ath5k_remove_interface(struct ieee80211_hw *hw,
2793 struct ieee80211_if_init_conf *conf) 2850 struct ieee80211_vif *vif)
2794{ 2851{
2795 struct ath5k_softc *sc = hw->priv; 2852 struct ath5k_softc *sc = hw->priv;
2796 u8 mac[ETH_ALEN] = {}; 2853 u8 mac[ETH_ALEN] = {};
2797 2854
2798 mutex_lock(&sc->lock); 2855 mutex_lock(&sc->lock);
2799 if (sc->vif != conf->vif) 2856 if (sc->vif != vif)
2800 goto end; 2857 goto end;
2801 2858
2802 ath5k_hw_set_lladdr(sc->ah, mac); 2859 ath5k_hw_set_lladdr(sc->ah, mac);
@@ -3008,6 +3065,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3008 struct ieee80211_key_conf *key) 3065 struct ieee80211_key_conf *key)
3009{ 3066{
3010 struct ath5k_softc *sc = hw->priv; 3067 struct ath5k_softc *sc = hw->priv;
3068 struct ath5k_hw *ah = sc->ah;
3069 struct ath_common *common = ath5k_hw_common(ah);
3011 int ret = 0; 3070 int ret = 0;
3012 3071
3013 if (modparam_nohwcrypt) 3072 if (modparam_nohwcrypt)
@@ -3040,14 +3099,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3040 ATH5K_ERR(sc, "can't set the key\n"); 3099 ATH5K_ERR(sc, "can't set the key\n");
3041 goto unlock; 3100 goto unlock;
3042 } 3101 }
3043 __set_bit(key->keyidx, sc->keymap); 3102 __set_bit(key->keyidx, common->keymap);
3044 key->hw_key_idx = key->keyidx; 3103 key->hw_key_idx = key->keyidx;
3045 key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | 3104 key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
3046 IEEE80211_KEY_FLAG_GENERATE_MMIC); 3105 IEEE80211_KEY_FLAG_GENERATE_MMIC);
3047 break; 3106 break;
3048 case DISABLE_KEY: 3107 case DISABLE_KEY:
3049 ath5k_hw_reset_key(sc->ah, key->keyidx); 3108 ath5k_hw_reset_key(sc->ah, key->keyidx);
3050 __clear_bit(key->keyidx, sc->keymap); 3109 __clear_bit(key->keyidx, common->keymap);
3051 break; 3110 break;
3052 default: 3111 default:
3053 ret = -EINVAL; 3112 ret = -EINVAL;
@@ -3075,17 +3134,6 @@ ath5k_get_stats(struct ieee80211_hw *hw,
3075 return 0; 3134 return 0;
3076} 3135}
3077 3136
3078static int
3079ath5k_get_tx_stats(struct ieee80211_hw *hw,
3080 struct ieee80211_tx_queue_stats *stats)
3081{
3082 struct ath5k_softc *sc = hw->priv;
3083
3084 memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
3085
3086 return 0;
3087}
3088
3089static u64 3137static u64
3090ath5k_get_tsf(struct ieee80211_hw *hw) 3138ath5k_get_tsf(struct ieee80211_hw *hw)
3091{ 3139{
@@ -3176,6 +3224,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3176{ 3224{
3177 struct ath5k_softc *sc = hw->priv; 3225 struct ath5k_softc *sc = hw->priv;
3178 struct ath5k_hw *ah = sc->ah; 3226 struct ath5k_hw *ah = sc->ah;
3227 struct ath_common *common = ath5k_hw_common(ah);
3179 unsigned long flags; 3228 unsigned long flags;
3180 3229
3181 mutex_lock(&sc->lock); 3230 mutex_lock(&sc->lock);
@@ -3184,10 +3233,9 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3184 3233
3185 if (changes & BSS_CHANGED_BSSID) { 3234 if (changes & BSS_CHANGED_BSSID) {
3186 /* Cache for later use during resets */ 3235 /* Cache for later use during resets */
3187 memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN); 3236 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
3188 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have 3237 common->curaid = 0;
3189 * a clean way of letting us retrieve this yet. */ 3238 ath5k_hw_set_associd(ah);
3190 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
3191 mmiowb(); 3239 mmiowb();
3192 } 3240 }
3193 3241
@@ -3200,6 +3248,14 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3200 set_beacon_filter(hw, sc->assoc); 3248 set_beacon_filter(hw, sc->assoc);
3201 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3249 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3202 AR5K_LED_ASSOC : AR5K_LED_INIT); 3250 AR5K_LED_ASSOC : AR5K_LED_INIT);
3251 if (bss_conf->assoc) {
3252 ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
3253 "Bss Info ASSOC %d, bssid: %pM\n",
3254 bss_conf->aid, common->curbssid);
3255 common->curaid = bss_conf->aid;
3256 ath5k_hw_set_associd(ah);
3257 /* Once ANI is available you would start it here */
3258 }
3203 } 3259 }
3204 3260
3205 if (changes & BSS_CHANGED_BEACON) { 3261 if (changes & BSS_CHANGED_BEACON) {
@@ -3232,3 +3288,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
3232 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3288 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3233 AR5K_LED_ASSOC : AR5K_LED_INIT); 3289 AR5K_LED_ASSOC : AR5K_LED_INIT);
3234} 3290}
3291
3292/**
3293 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
3294 *
3295 * @hw: struct ieee80211_hw pointer
3296 * @coverage_class: IEEE 802.11 coverage class number
3297 *
3298 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
3299 * coverage class. The values are persistent, they are restored after device
3300 * reset.
3301 */
3302static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
3303{
3304 struct ath5k_softc *sc = hw->priv;
3305
3306 mutex_lock(&sc->lock);
3307 ath5k_hw_set_coverage_class(sc->ah, coverage_class);
3308 mutex_unlock(&sc->lock);
3309}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index a28c42f32c9d..7e1a88a5abdb 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38/* 38/*
39 * Defintions for the Atheros Wireless LAN controller driver. 39 * Definitions for the Atheros Wireless LAN controller driver.
40 */ 40 */
41#ifndef _DEV_ATH_ATHVAR_H 41#ifndef _DEV_ATH_ATHVAR_H
42#define _DEV_ATH_ATHVAR_H 42#define _DEV_ATH_ATHVAR_H
@@ -115,10 +115,8 @@ struct ath5k_rfkill {
115 * associated with an instance of a device */ 115 * associated with an instance of a device */
116struct ath5k_softc { 116struct ath5k_softc {
117 struct pci_dev *pdev; /* for dma mapping */ 117 struct pci_dev *pdev; /* for dma mapping */
118 struct ath_common common;
119 void __iomem *iobase; /* address of the device */ 118 void __iomem *iobase; /* address of the device */
120 struct mutex lock; /* dev-level lock */ 119 struct mutex lock; /* dev-level lock */
121 struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
122 struct ieee80211_low_level_stats ll_stats; 120 struct ieee80211_low_level_stats ll_stats;
123 struct ieee80211_hw *hw; /* IEEE 802.11 common */ 121 struct ieee80211_hw *hw; /* IEEE 802.11 common */
124 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 122 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
@@ -154,8 +152,6 @@ struct ath5k_softc {
154 152
155 enum ath5k_int imask; /* interrupt mask copy */ 153 enum ath5k_int imask; /* interrupt mask copy */
156 154
157 DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
158
159 u8 bssidmask[ETH_ALEN]; 155 u8 bssidmask[ETH_ALEN];
160 156
161 unsigned int led_pin, /* GPIO pin for driving LED */ 157 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -193,7 +189,7 @@ struct ath5k_softc {
193 struct ath5k_txq *cabq; /* content after beacon */ 189 struct ath5k_txq *cabq; /* content after beacon */
194 190
195 int power_level; /* Requested tx power in dbm */ 191 int power_level; /* Requested tx power in dbm */
196 bool assoc; /* assocate state */ 192 bool assoc; /* associate state */
197 bool enable_beacon; /* true if beacons are on */ 193 bool enable_beacon; /* true if beacons are on */
198}; 194};
199 195
@@ -202,15 +198,4 @@ struct ath5k_softc {
202#define ath5k_hw_hasveol(_ah) \ 198#define ath5k_hw_hasveol(_ah) \
203 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0) 199 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
204 200
205static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
206{
207 return &ah->ah_sc->common;
208}
209
210static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
211{
212 return &(ath5k_hw_common(ah)->regulatory);
213
214}
215
216#endif 201#endif
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 644962adda97..67665cdc7afe 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -21,6 +21,8 @@
21* EEPROM access functions and helpers * 21* EEPROM access functions and helpers *
22\*************************************/ 22\*************************************/
23 23
24#include <linux/slab.h>
25
24#include "ath5k.h" 26#include "ath5k.h"
25#include "reg.h" 27#include "reg.h"
26#include "debug.h" 28#include "debug.h"
@@ -97,6 +99,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
97 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 99 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
98 int ret; 100 int ret;
99 u16 val; 101 u16 val;
102 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
100 103
101 /* 104 /*
102 * Read values from EEPROM and store them in the capability structure 105 * Read values from EEPROM and store them in the capability structure
@@ -111,20 +114,44 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
111 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) 114 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
112 return 0; 115 return 0;
113 116
114#ifdef notyet
115 /* 117 /*
116 * Validate the checksum of the EEPROM date. There are some 118 * Validate the checksum of the EEPROM date. There are some
117 * devices with invalid EEPROMs. 119 * devices with invalid EEPROMs.
118 */ 120 */
119 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { 121 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
122 if (val) {
123 eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
124 AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
125 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
126 eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
127
128 /*
129 * Fail safe check to prevent stupid loops due
130 * to busted EEPROMs. XXX: This value is likely too
131 * big still, waiting on a better value.
132 */
133 if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
134 ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
135 "%d (0x%04x) max expected: %d (0x%04x)\n",
136 eep_max, eep_max,
137 3 * AR5K_EEPROM_INFO_MAX,
138 3 * AR5K_EEPROM_INFO_MAX);
139 return -EIO;
140 }
141 }
142
143 for (cksum = 0, offset = 0; offset < eep_max; offset++) {
120 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); 144 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
121 cksum ^= val; 145 cksum ^= val;
122 } 146 }
123 if (cksum != AR5K_EEPROM_INFO_CKSUM) { 147 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
124 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); 148 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
149 "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
150 cksum, eep_max,
151 eep_max == AR5K_EEPROM_INFO_MAX ?
152 "default size" : "custom size");
125 return -EIO; 153 return -EIO;
126 } 154 }
127#endif
128 155
129 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), 156 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
130 ee_ant_gain); 157 ee_ant_gain);
@@ -404,8 +431,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
404 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; 431 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
405 432
406 AR5K_EEPROM_READ(o++, val); 433 AR5K_EEPROM_READ(o++, val);
407 ee->ee_i_cal[mode] = (val >> 8) & 0x3f; 434 ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
408 ee->ee_q_cal[mode] = (val >> 3) & 0x1f; 435 ee->ee_q_cal[mode] = val & 0x1f;
409 436
410 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { 437 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
411 AR5K_EEPROM_READ(o++, val); 438 AR5K_EEPROM_READ(o++, val);
@@ -1492,7 +1519,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
1492 * This info is used to calibrate the baseband power table. Imagine 1519 * This info is used to calibrate the baseband power table. Imagine
1493 * that for each channel there is a power curve that's hw specific 1520 * that for each channel there is a power curve that's hw specific
1494 * (depends on amplifier etc) and we try to "correct" this curve using 1521 * (depends on amplifier etc) and we try to "correct" this curve using
1495 * offests we pass on to phy chip (baseband -> before amplifier) so that 1522 * offsets we pass on to phy chip (baseband -> before amplifier) so that
1496 * it can use accurate power values when setting tx power (takes amplifier's 1523 * it can use accurate power values when setting tx power (takes amplifier's
1497 * performance on each channel into account). 1524 * performance on each channel into account).
1498 * 1525 *
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 0123f3521a0b..473a483bb9c3 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -37,6 +37,14 @@
37#define AR5K_EEPROM_RFKILL_POLARITY_S 1 37#define AR5K_EEPROM_RFKILL_POLARITY_S 1
38 38
39#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ 39#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
40
41/* FLASH(EEPROM) Defines for AR531X chips */
42#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */
43#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */
44#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0
45#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4
46#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12
47
40#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ 48#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
41#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ 49#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
42#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) 50#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 18eb5190ce4b..8fa439308828 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -560,8 +560,8 @@ static const struct ath5k_ini ar5212_ini_common_start[] = {
560 { AR5K_SLEEP0, 0x0002aaaa }, 560 { AR5K_SLEEP0, 0x0002aaaa },
561 { AR5K_SLEEP1, 0x02005555 }, 561 { AR5K_SLEEP1, 0x02005555 },
562 { AR5K_SLEEP2, 0x00000000 }, 562 { AR5K_SLEEP2, 0x00000000 },
563 { AR5K_BSS_IDM0, 0xffffffff }, 563 { AR_BSSMSKL, 0xffffffff },
564 { AR5K_BSS_IDM1, 0x0000ffff }, 564 { AR_BSSMSKU, 0x0000ffff },
565 { AR5K_TXPC, 0x00000000 }, 565 { AR5K_TXPC, 0x00000000 },
566 { AR5K_PROFCNT_TX, 0x00000000 }, 566 { AR5K_PROFCNT_TX, 0x00000000 },
567 { AR5K_PROFCNT_RX, 0x00000000 }, 567 { AR5K_PROFCNT_RX, 0x00000000 },
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index b548c8eaaae1..67aa52e9bf94 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -59,6 +59,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
59 { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) }, 59 { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
60 /* Acer Aspire One A150 (maximlevitsky@gmail.com) */ 60 /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
61 { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) }, 61 { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
62 /* Acer Aspire One AO531h AO751h (keng-yu.lin@canonical.com) */
63 { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe00d), ATH_LED(3, 0) },
62 /* Acer Ferrari 5000 (russ.dill@gmail.com) */ 64 /* Acer Ferrari 5000 (russ.dill@gmail.com) */
63 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, 65 { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
64 /* E-machines E510 (tuliom@gmail.com) */ 66 /* E-machines E510 (tuliom@gmail.com) */
@@ -75,8 +77,12 @@ static const struct pci_device_id ath5k_led_devices[] = {
75 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, 77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
76 /* HP Compaq C700 (nitrousnrg@gmail.com) */ 78 /* HP Compaq C700 (nitrousnrg@gmail.com) */
77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, 79 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
80 /* LiteOn AR5BXB63 (magooz@salug.it) */
81 { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
78 /* IBM-specific AR5212 (all others) */ 82 /* IBM-specific AR5212 (all others) */
79 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, 83 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
84 /* Dell Vostro A860 (shahar@shahar-or.co.il) */
85 { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0112), ATH_LED(3, 0) },
80 { } 86 { }
81}; 87};
82 88
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 2942f13c9c4a..aefe84f9c04b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -24,6 +24,8 @@
24* Protocol Control Unit Functions * 24* Protocol Control Unit Functions *
25\*********************************/ 25\*********************************/
26 26
27#include <asm/unaligned.h>
28
27#include "ath5k.h" 29#include "ath5k.h"
28#include "reg.h" 30#include "reg.h"
29#include "debug.h" 31#include "debug.h"
@@ -44,6 +46,7 @@
44 */ 46 */
45int ath5k_hw_set_opmode(struct ath5k_hw *ah) 47int ath5k_hw_set_opmode(struct ath5k_hw *ah)
46{ 48{
49 struct ath_common *common = ath5k_hw_common(ah);
47 u32 pcu_reg, beacon_reg, low_id, high_id; 50 u32 pcu_reg, beacon_reg, low_id, high_id;
48 51
49 52
@@ -95,8 +98,8 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
95 /* 98 /*
96 * Set PCU registers 99 * Set PCU registers
97 */ 100 */
98 low_id = AR5K_LOW_ID(ah->ah_sta_id); 101 low_id = get_unaligned_le32(common->macaddr);
99 high_id = AR5K_HIGH_ID(ah->ah_sta_id); 102 high_id = get_unaligned_le16(common->macaddr + 4);
100 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); 103 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
101 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); 104 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
102 105
@@ -184,8 +187,8 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
184{ 187{
185 ATH5K_TRACE(ah->ah_sc); 188 ATH5K_TRACE(ah->ah_sc);
186 189
187 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
188 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); 191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
189} 192}
190 193
191/** 194/**
@@ -197,12 +200,12 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
197int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
198{ 201{
199 ATH5K_TRACE(ah->ah_sc); 202 ATH5K_TRACE(ah->ah_sc);
200 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), 203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
201 ah->ah_turbo) <= timeout) 204 <= timeout)
202 return -EINVAL; 205 return -EINVAL;
203 206
204 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, 207 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
205 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 208 ath5k_hw_htoclock(ah, timeout));
206 209
207 return 0; 210 return 0;
208} 211}
@@ -215,8 +218,8 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
215unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) 218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
216{ 219{
217 ATH5K_TRACE(ah->ah_sc); 220 ATH5K_TRACE(ah->ah_sc);
218 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
219 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); 222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
220} 223}
221 224
222/** 225/**
@@ -228,36 +231,94 @@ unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
228int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
229{ 232{
230 ATH5K_TRACE(ah->ah_sc); 233 ATH5K_TRACE(ah->ah_sc);
231 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), 234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
232 ah->ah_turbo) <= timeout) 235 <= timeout)
233 return -EINVAL; 236 return -EINVAL;
234 237
235 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, 238 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
236 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 239 ath5k_hw_htoclock(ah, timeout));
237 240
238 return 0; 241 return 0;
239} 242}
240 243
244/**
245 * ath5k_hw_htoclock - Translate usec to hw clock units
246 *
247 * @ah: The &struct ath5k_hw
248 * @usec: value in microseconds
249 */
250unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
251{
252 return usec * ath5k_hw_get_clockrate(ah);
253}
241 254
242/****************\ 255/**
243* BSSID handling * 256 * ath5k_hw_clocktoh - Translate hw clock units to usec
244\****************/ 257 * @clock: value in hw clock units
258 */
259unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
260{
261 return clock / ath5k_hw_get_clockrate(ah);
262}
245 263
246/** 264/**
247 * ath5k_hw_get_lladdr - Get station id 265 * ath5k_hw_get_clockrate - Get the clock rate for current mode
248 * 266 *
249 * @ah: The &struct ath5k_hw 267 * @ah: The &struct ath5k_hw
250 * @mac: The card's mac address 268 */
269unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
270{
271 struct ieee80211_channel *channel = ah->ah_current_channel;
272 int clock;
273
274 if (channel->hw_value & CHANNEL_5GHZ)
275 clock = 40; /* 802.11a */
276 else if (channel->hw_value & CHANNEL_CCK)
277 clock = 22; /* 802.11b */
278 else
279 clock = 44; /* 802.11g */
280
281 /* Clock rate in turbo modes is twice the normal rate */
282 if (channel->hw_value & CHANNEL_TURBO)
283 clock *= 2;
284
285 return clock;
286}
287
288/**
289 * ath5k_hw_get_default_slottime - Get the default slot time for current mode
251 * 290 *
252 * Initialize ah->ah_sta_id using the mac address provided 291 * @ah: The &struct ath5k_hw
253 * (just a memcpy). 292 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{
295 struct ieee80211_channel *channel = ah->ah_current_channel;
296
297 if (channel->hw_value & CHANNEL_TURBO)
298 return 6; /* both turbo modes */
299
300 if (channel->hw_value & CHANNEL_CCK)
301 return 20; /* 802.11b */
302
303 return 9; /* 802.11 a/g */
304}
305
306/**
307 * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
254 * 308 *
255 * TODO: Remove it once we merge ath5k_softc and ath5k_hw 309 * @ah: The &struct ath5k_hw
256 */ 310 */
257void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) 311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
258{ 312{
259 ATH5K_TRACE(ah->ah_sc); 313 struct ieee80211_channel *channel = ah->ah_current_channel;
260 memcpy(mac, ah->ah_sta_id, ETH_ALEN); 314
315 if (channel->hw_value & CHANNEL_TURBO)
316 return 8; /* both turbo modes */
317
318 if (channel->hw_value & CHANNEL_5GHZ)
319 return 16; /* 802.11a */
320
321 return 10; /* 802.11 b/g */
261} 322}
262 323
263/** 324/**
@@ -270,17 +331,18 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
270 */ 331 */
271int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) 332int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
272{ 333{
334 struct ath_common *common = ath5k_hw_common(ah);
273 u32 low_id, high_id; 335 u32 low_id, high_id;
274 u32 pcu_reg; 336 u32 pcu_reg;
275 337
276 ATH5K_TRACE(ah->ah_sc); 338 ATH5K_TRACE(ah->ah_sc);
277 /* Set new station ID */ 339 /* Set new station ID */
278 memcpy(ah->ah_sta_id, mac, ETH_ALEN); 340 memcpy(common->macaddr, mac, ETH_ALEN);
279 341
280 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 342 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
281 343
282 low_id = AR5K_LOW_ID(mac); 344 low_id = get_unaligned_le32(mac);
283 high_id = AR5K_HIGH_ID(mac); 345 high_id = get_unaligned_le16(mac + 4);
284 346
285 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); 347 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
286 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); 348 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
@@ -297,159 +359,51 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
297 * 359 *
298 * Sets the BSSID which trigers the "SME Join" operation 360 * Sets the BSSID which trigers the "SME Join" operation
299 */ 361 */
300void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) 362void ath5k_hw_set_associd(struct ath5k_hw *ah)
301{ 363{
302 u32 low_id, high_id; 364 struct ath_common *common = ath5k_hw_common(ah);
303 u16 tim_offset = 0; 365 u16 tim_offset = 0;
304 366
305 /* 367 /*
306 * Set simple BSSID mask on 5212 368 * Set simple BSSID mask on 5212
307 */ 369 */
308 if (ah->ah_version == AR5K_AR5212) { 370 if (ah->ah_version == AR5K_AR5212)
309 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask), 371 ath_hw_setbssidmask(common);
310 AR5K_BSS_IDM0);
311 ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
312 AR5K_BSS_IDM1);
313 }
314 372
315 /* 373 /*
316 * Set BSSID which triggers the "SME Join" operation 374 * Set BSSID which triggers the "SME Join" operation
317 */ 375 */
318 low_id = AR5K_LOW_ID(bssid); 376 ath5k_hw_reg_write(ah,
319 high_id = AR5K_HIGH_ID(bssid); 377 get_unaligned_le32(common->curbssid),
320 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); 378 AR5K_BSS_ID0);
321 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << 379 ath5k_hw_reg_write(ah,
322 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); 380 get_unaligned_le16(common->curbssid + 4) |
323 381 ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
324 if (assoc_id == 0) { 382 AR5K_BSS_ID1);
383
384 if (common->curaid == 0) {
325 ath5k_hw_disable_pspoll(ah); 385 ath5k_hw_disable_pspoll(ah);
326 return; 386 return;
327 } 387 }
328 388
329 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM, 389 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
330 tim_offset ? tim_offset + 4 : 0); 390 tim_offset ? tim_offset + 4 : 0);
331 391
332 ath5k_hw_enable_pspoll(ah, NULL, 0); 392 ath5k_hw_enable_pspoll(ah, NULL, 0);
333} 393}
334 394
335/** 395void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
336 * ath5k_hw_set_bssid_mask - filter out bssids we listen
337 *
338 * @ah: the &struct ath5k_hw
339 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
340 *
341 * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
342 * which bits of the interface's MAC address should be looked at when trying
343 * to decide which packets to ACK. In station mode and AP mode with a single
344 * BSS every bit matters since we lock to only one BSS. In AP mode with
345 * multiple BSSes (virtual interfaces) not every bit matters because hw must
346 * accept frames for all BSSes and so we tweak some bits of our mac address
347 * in order to have multiple BSSes.
348 *
349 * NOTE: This is a simple filter and does *not* filter out all
350 * relevant frames. Some frames that are not for us might get ACKed from us
351 * by PCU because they just match the mask.
352 *
353 * When handling multiple BSSes you can get the BSSID mask by computing the
354 * set of ~ ( MAC XOR BSSID ) for all bssids we handle.
355 *
356 * When you do this you are essentially computing the common bits of all your
357 * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
358 * the MAC address to obtain the relevant bits and compare the result with
359 * (frame's BSSID & mask) to see if they match.
360 */
361/*
362 * Simple example: on your card you have have two BSSes you have created with
363 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
364 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
365 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
366 *
367 * \
368 * MAC: 0001 |
369 * BSSID-01: 0100 | --> Belongs to us
370 * BSSID-02: 1001 |
371 * /
372 * -------------------
373 * BSSID-03: 0110 | --> External
374 * -------------------
375 *
376 * Our bssid_mask would then be:
377 *
378 * On loop iteration for BSSID-01:
379 * ~(0001 ^ 0100) -> ~(0101)
380 * -> 1010
381 * bssid_mask = 1010
382 *
383 * On loop iteration for BSSID-02:
384 * bssid_mask &= ~(0001 ^ 1001)
385 * bssid_mask = (1010) & ~(0001 ^ 1001)
386 * bssid_mask = (1010) & ~(1001)
387 * bssid_mask = (1010) & (0110)
388 * bssid_mask = 0010
389 *
390 * A bssid_mask of 0010 means "only pay attention to the second least
391 * significant bit". This is because its the only bit common
392 * amongst the MAC and all BSSIDs we support. To findout what the real
393 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
394 * or our MAC address (we assume the hardware uses the MAC address).
395 *
396 * Now, suppose there's an incoming frame for BSSID-03:
397 *
398 * IFRAME-01: 0110
399 *
400 * An easy eye-inspeciton of this already should tell you that this frame
401 * will not pass our check. This is beacuse the bssid_mask tells the
402 * hardware to only look at the second least significant bit and the
403 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
404 * as 1, which does not match 0.
405 *
406 * So with IFRAME-01 we *assume* the hardware will do:
407 *
408 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
409 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
410 * --> allow = (0010) == 0000 ? 1 : 0;
411 * --> allow = 0
412 *
413 * Lets now test a frame that should work:
414 *
415 * IFRAME-02: 0001 (we should allow)
416 *
417 * allow = (0001 & 1010) == 1010
418 *
419 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
420 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
421 * --> allow = (0010) == (0010)
422 * --> allow = 1
423 *
424 * Other examples:
425 *
426 * IFRAME-03: 0100 --> allowed
427 * IFRAME-04: 1001 --> allowed
428 * IFRAME-05: 1101 --> allowed but its not for us!!!
429 *
430 */
431int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
432{ 396{
433 u32 low_id, high_id; 397 struct ath_common *common = ath5k_hw_common(ah);
434 ATH5K_TRACE(ah->ah_sc); 398 ATH5K_TRACE(ah->ah_sc);
435 399
436 /* Cache bssid mask so that we can restore it 400 /* Cache bssid mask so that we can restore it
437 * on reset */ 401 * on reset */
438 memcpy(ah->ah_bssid_mask, mask, ETH_ALEN); 402 memcpy(common->bssidmask, mask, ETH_ALEN);
439 if (ah->ah_version == AR5K_AR5212) { 403 if (ah->ah_version == AR5K_AR5212)
440 low_id = AR5K_LOW_ID(mask); 404 ath_hw_setbssidmask(common);
441 high_id = AR5K_HIGH_ID(mask);
442
443 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
444 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
445
446 return 0;
447 }
448
449 return -EIO;
450} 405}
451 406
452
453/************\ 407/************\
454* RX Control * 408* RX Control *
455\************/ 409\************/
@@ -1157,14 +1111,17 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
1157 /* Invalid entry (key table overflow) */ 1111 /* Invalid entry (key table overflow) */
1158 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); 1112 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
1159 1113
1160 /* MAC may be NULL if it's a broadcast key. In this case no need to 1114 /*
1161 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ 1115 * MAC may be NULL if it's a broadcast key. In this case no need to
1116 * to compute get_unaligned_le32 and get_unaligned_le16 as we
1117 * already know it.
1118 */
1162 if (!mac) { 1119 if (!mac) {
1163 low_id = 0xffffffff; 1120 low_id = 0xffffffff;
1164 high_id = 0xffff | AR5K_KEYTABLE_VALID; 1121 high_id = 0xffff | AR5K_KEYTABLE_VALID;
1165 } else { 1122 } else {
1166 low_id = AR5K_LOW_ID(mac); 1123 low_id = get_unaligned_le32(mac);
1167 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID; 1124 high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
1168 } 1125 }
1169 1126
1170 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); 1127 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
@@ -1173,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
1173 return 0; 1130 return 0;
1174} 1131}
1175 1132
1133/**
1134 * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
1135 *
1136 * @ah: The &struct ath5k_hw
1137 * @coverage_class: IEEE 802.11 coverage class number
1138 *
1139 * Sets slot time, ACK timeout and CTS timeout for given coverage class.
1140 */
1141void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
1142{
1143 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1144 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
1145 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
1146 int cts_timeout = ack_timeout;
1147
1148 ath5k_hw_set_slot_time(ah, slot_time);
1149 ath5k_hw_set_ack_timeout(ah, ack_timeout);
1150 ath5k_hw_set_cts_timeout(ah, cts_timeout);
1151
1152 ah->ah_coverage_class = coverage_class;
1153}
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 1a039f2bd732..68e2bccd90d3 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -23,6 +23,7 @@
23#define _ATH5K_PHY 23#define _ATH5K_PHY
24 24
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/slab.h>
26 27
27#include "ath5k.h" 28#include "ath5k.h"
28#include "reg.h" 29#include "reg.h"
@@ -117,7 +118,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
117 118
118/* 119/*
119 * This code is used to optimize rf gain on different environments 120 * This code is used to optimize rf gain on different environments
120 * (temprature mostly) based on feedback from a power detector. 121 * (temperature mostly) based on feedback from a power detector.
121 * 122 *
122 * It's only used on RF5111 and RF5112, later RF chips seem to have 123 * It's only used on RF5111 and RF5112, later RF chips seem to have
123 * auto adjustment on hw -notice they have a much smaller BANK 7 and 124 * auto adjustment on hw -notice they have a much smaller BANK 7 and
@@ -1124,77 +1125,148 @@ ath5k_hw_calibration_poll(struct ath5k_hw *ah)
1124 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION; 1125 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
1125 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); 1126 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
1126 } 1127 }
1128}
1127 1129
1130static int sign_extend(int val, const int nbits)
1131{
1132 int order = BIT(nbits-1);
1133 return (val ^ order) - order;
1128} 1134}
1129 1135
1130/** 1136static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1131 * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration 1137{
1132 * 1138 s32 val;
1133 * @ah: struct ath5k_hw pointer we are operating on 1139
1134 * @freq: the channel frequency, just used for error logging 1140 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1135 * 1141 return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9);
1136 * This function performs a noise floor calibration of the PHY and waits for 1142}
1137 * it to complete. Then the noise floor value is compared to some maximum 1143
1138 * noise floor we consider valid. 1144void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1139 * 1145{
1140 * Note that this is different from what the madwifi HAL does: it reads the 1146 int i;
1141 * noise floor and afterwards initiates the calibration. Since the noise floor 1147
1142 * calibration can take some time to finish, depending on the current channel 1148 ah->ah_nfcal_hist.index = 0;
1143 * use, that avoids the occasional timeout warnings we are seeing now. 1149 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1144 * 1150 ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1145 * See the following link for an Atheros patent on noise floor calibration: 1151}
1146 * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \ 1152
1147 * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7 1153static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1154{
1155 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1156 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX-1);
1157 hist->nfval[hist->index] = noise_floor;
1158}
1159
1160static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1161{
1162 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1163 s16 tmp;
1164 int i, j;
1165
1166 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1167 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1168 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
1169 if (sort[j] > sort[j-1]) {
1170 tmp = sort[j];
1171 sort[j] = sort[j-1];
1172 sort[j-1] = tmp;
1173 }
1174 }
1175 }
1176 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1177 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1178 "cal %d:%d\n", i, sort[i]);
1179 }
1180 return sort[(ATH5K_NF_CAL_HIST_MAX-1) / 2];
1181}
1182
1183/*
1184 * When we tell the hardware to perform a noise floor calibration
1185 * by setting the AR5K_PHY_AGCCTL_NF bit, it will periodically
1186 * sample-and-hold the minimum noise level seen at the antennas.
1187 * This value is then stored in a ring buffer of recently measured
1188 * noise floor values so we have a moving window of the last few
1189 * samples.
1148 * 1190 *
1149 * XXX: Since during noise floor calibration antennas are detached according to 1191 * The median of the values in the history is then loaded into the
1150 * the patent, we should stop tx queues here. 1192 * hardware for its own use for RSSI and CCA measurements.
1151 */ 1193 */
1152int 1194void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1153ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
1154{ 1195{
1155 int ret; 1196 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1156 unsigned int i; 1197 u32 val;
1157 s32 noise_floor; 1198 s16 nf, threshold;
1199 u8 ee_mode;
1158 1200
1159 /* 1201 /* keep last value if calibration hasn't completed */
1160 * Enable noise floor calibration 1202 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
1161 */ 1203 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1162 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1204 "NF did not complete in calibration window\n");
1163 AR5K_PHY_AGCCTL_NF);
1164 1205
1165 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, 1206 return;
1166 AR5K_PHY_AGCCTL_NF, 0, false);
1167 if (ret) {
1168 ATH5K_ERR(ah->ah_sc,
1169 "noise floor calibration timeout (%uMHz)\n", freq);
1170 return -EAGAIN;
1171 } 1207 }
1172 1208
1173 /* Wait until the noise floor is calibrated and read the value */ 1209 switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
1174 for (i = 20; i > 0; i--) { 1210 case CHANNEL_A:
1175 mdelay(1); 1211 case CHANNEL_T:
1176 noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF); 1212 case CHANNEL_XR:
1177 noise_floor = AR5K_PHY_NF_RVAL(noise_floor); 1213 ee_mode = AR5K_EEPROM_MODE_11A;
1178 if (noise_floor & AR5K_PHY_NF_ACTIVE) { 1214 break;
1179 noise_floor = AR5K_PHY_NF_AVAL(noise_floor); 1215 case CHANNEL_G:
1180 1216 case CHANNEL_TG:
1181 if (noise_floor <= AR5K_TUNE_NOISE_FLOOR) 1217 ee_mode = AR5K_EEPROM_MODE_11G;
1182 break; 1218 break;
1183 } 1219 default:
1220 case CHANNEL_B:
1221 ee_mode = AR5K_EEPROM_MODE_11B;
1222 break;
1184 } 1223 }
1185 1224
1186 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1187 "noise floor %d\n", noise_floor);
1188 1225
1189 if (noise_floor > AR5K_TUNE_NOISE_FLOOR) { 1226 /* completed NF calibration, test threshold */
1190 ATH5K_ERR(ah->ah_sc, 1227 nf = ath5k_hw_read_measured_noise_floor(ah);
1191 "noise floor calibration failed (%uMHz)\n", freq); 1228 threshold = ee->ee_noise_floor_thr[ee_mode];
1192 return -EAGAIN; 1229
1230 if (nf > threshold) {
1231 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1232 "noise floor failure detected; "
1233 "read %d, threshold %d\n",
1234 nf, threshold);
1235
1236 nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1193 } 1237 }
1194 1238
1195 ah->ah_noise_floor = noise_floor; 1239 ath5k_hw_update_nfcal_hist(ah, nf);
1240 nf = ath5k_hw_get_median_noise_floor(ah);
1196 1241
1197 return 0; 1242 /* load noise floor (in .5 dBm) so the hardware will use it */
1243 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M;
1244 val |= (nf * 2) & AR5K_PHY_NF_M;
1245 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1246
1247 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1248 ~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE));
1249
1250 ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1251 0, false);
1252
1253 /*
1254 * Load a high max CCA Power value (-50 dBm in .5 dBm units)
1255 * so that we're not capped by the median we just loaded.
1256 * This will be used as the initial value for the next noise
1257 * floor calibration.
1258 */
1259 val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M);
1260 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1261 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1262 AR5K_PHY_AGCCTL_NF_EN |
1263 AR5K_PHY_AGCCTL_NF_NOUPDATE |
1264 AR5K_PHY_AGCCTL_NF);
1265
1266 ah->ah_noise_floor = nf;
1267
1268 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1269 "noise floor calibrated: %d\n", nf);
1198} 1270}
1199 1271
1200/* 1272/*
@@ -1287,7 +1359,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1287 return ret; 1359 return ret;
1288 } 1360 }
1289 1361
1290 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1362 ath5k_hw_update_noise_floor(ah);
1291 1363
1292 /* 1364 /*
1293 * Re-enable RX/TX and beacons 1365 * Re-enable RX/TX and beacons
@@ -1315,38 +1387,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1315 goto done; 1387 goto done;
1316 1388
1317 /* Calibration has finished, get the results and re-run */ 1389 /* Calibration has finished, get the results and re-run */
1390
1391 /* work around empty results which can apparently happen on 5212 */
1318 for (i = 0; i <= 10; i++) { 1392 for (i = 0; i <= 10; i++) {
1319 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); 1393 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1320 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); 1394 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
1321 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); 1395 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
1396 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1397 "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
1398 if (i_pwr && q_pwr)
1399 break;
1322 } 1400 }
1323 1401
1324 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1402 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1325 q_coffd = q_pwr >> 7; 1403 q_coffd = q_pwr >> 7;
1326 1404
1327 /* No correction */ 1405 /* protect against divide by 0 and loss of sign bits */
1328 if (i_coffd == 0 || q_coffd == 0) 1406 if (i_coffd == 0 || q_coffd < 2)
1329 goto done; 1407 goto done;
1330 1408
1331 i_coff = ((-iq_corr) / i_coffd) & 0x3f; 1409 i_coff = (-iq_corr) / i_coffd;
1410 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
1332 1411
1333 /* Boundary check */ 1412 q_coff = (i_pwr / q_coffd) - 128;
1334 if (i_coff > 31) 1413 q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
1335 i_coff = 31;
1336 if (i_coff < -32)
1337 i_coff = -32;
1338 1414
1339 q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f; 1415 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1340 1416 "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
1341 /* Boundary check */ 1417 i_coff, q_coff, i_coffd, q_coffd);
1342 if (q_coff > 15)
1343 q_coff = 15;
1344 if (q_coff < -16)
1345 q_coff = -16;
1346 1418
1347 /* Commit new I/Q value */ 1419 /* Commit new I/Q values (set enable bit last to match HAL sources) */
1348 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | 1420 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
1349 ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); 1421 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
1422 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
1350 1423
1351 /* Re-enable calibration -if we don't we'll commit 1424 /* Re-enable calibration -if we don't we'll commit
1352 * the same values again and again */ 1425 * the same values again and again */
@@ -1360,7 +1433,7 @@ done:
1360 * since noise floor calibration interrupts rx path while I/Q 1433 * since noise floor calibration interrupts rx path while I/Q
1361 * calibration doesn't. We don't need to run noise floor calibration 1434 * calibration doesn't. We don't need to run noise floor calibration
1362 * as often as I/Q calibration.*/ 1435 * as often as I/Q calibration.*/
1363 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1436 ath5k_hw_update_noise_floor(ah);
1364 1437
1365 /* Initiate a gain_F calibration */ 1438 /* Initiate a gain_F calibration */
1366 ath5k_hw_request_rfgain_probe(ah); 1439 ath5k_hw_request_rfgain_probe(ah);
@@ -1802,7 +1875,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1802 break; 1875 break;
1803 case AR5K_ANTMODE_FIXED_A: 1876 case AR5K_ANTMODE_FIXED_A:
1804 def_ant = 1; 1877 def_ant = 1;
1805 tx_ant = 0; 1878 tx_ant = 1;
1806 use_def_for_tx = true; 1879 use_def_for_tx = true;
1807 update_def_on_tx = false; 1880 update_def_on_tx = false;
1808 use_def_for_rts = true; 1881 use_def_for_rts = true;
@@ -1811,7 +1884,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1811 break; 1884 break;
1812 case AR5K_ANTMODE_FIXED_B: 1885 case AR5K_ANTMODE_FIXED_B:
1813 def_ant = 2; 1886 def_ant = 2;
1814 tx_ant = 0; 1887 tx_ant = 2;
1815 use_def_for_tx = true; 1888 use_def_for_tx = true;
1816 update_def_on_tx = false; 1889 update_def_on_tx = false;
1817 use_def_for_rts = true; 1890 use_def_for_rts = true;
@@ -2675,7 +2748,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2675 /* Fill curves in reverse order 2748 /* Fill curves in reverse order
2676 * from lower power (max gain) 2749 * from lower power (max gain)
2677 * to higher power. Use curve -> idx 2750 * to higher power. Use curve -> idx
2678 * backmaping we did on eeprom init */ 2751 * backmapping we did on eeprom init */
2679 u8 idx = pdg_curve_to_idx[pdg]; 2752 u8 idx = pdg_curve_to_idx[pdg];
2680 2753
2681 /* Grab the needed curves by index */ 2754 /* Grab the needed curves by index */
@@ -2777,7 +2850,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
2777 /* Now we have a set of curves for this 2850 /* Now we have a set of curves for this
2778 * channel on tmpL (x range is table_max - table_min 2851 * channel on tmpL (x range is table_max - table_min
2779 * and y values are tmpL[pdg][]) sorted in the same 2852 * and y values are tmpL[pdg][]) sorted in the same
2780 * order as EEPROM (because we've used the backmaping). 2853 * order as EEPROM (because we've used the backmapping).
2781 * So for RF5112 it's from higher power to lower power 2854 * So for RF5112 it's from higher power to lower power
2782 * and for RF2413 it's from lower power to higher power. 2855 * and for RF2413 it's from lower power to higher power.
2783 * For RF5111 we only have one curve. */ 2856 * For RF5111 we only have one curve. */
@@ -2954,8 +3027,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2954 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); 3027 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
2955 return -EINVAL; 3028 return -EINVAL;
2956 } 3029 }
2957 if (txpower == 0)
2958 txpower = AR5K_TUNE_DEFAULT_TXPOWER;
2959 3030
2960 /* Reset TX power values */ 3031 /* Reset TX power values */
2961 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 3032 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index eeebb9aef206..9122a8556f45 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
408 break; 408 break;
409 409
410 case AR5K_TX_QUEUE_CAB: 410 case AR5K_TX_QUEUE_CAB:
411 /* XXX: use BCN_SENT_GT, if we can figure out how */
411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 412 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | 413 AR5K_QCU_MISC_FRSHED_DBA_GT |
413 AR5K_QCU_MISC_CBREXP_DIS | 414 AR5K_QCU_MISC_CBREXP_DIS |
414 AR5K_QCU_MISC_CBREXP_BCN_DIS); 415 AR5K_QCU_MISC_CBREXP_BCN_DIS);
415 416
416 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - 417 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
417 (AR5K_TUNE_SW_BEACON_RESP - 418 (AR5K_TUNE_SW_BEACON_RESP -
418 AR5K_TUNE_DMA_BEACON_RESP) - 419 AR5K_TUNE_DMA_BEACON_RESP) -
419 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 420 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
@@ -520,12 +521,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
520 */ 521 */
521unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) 522unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
522{ 523{
524 unsigned int slot_time_clock;
525
523 ATH5K_TRACE(ah->ah_sc); 526 ATH5K_TRACE(ah->ah_sc);
527
524 if (ah->ah_version == AR5K_AR5210) 528 if (ah->ah_version == AR5K_AR5210)
525 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, 529 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
526 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
527 else 530 else
528 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; 531 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
532
533 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
529} 534}
530 535
531/* 536/*
@@ -533,15 +538,17 @@ unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
533 */ 538 */
534int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 539int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
535{ 540{
541 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
542
536 ATH5K_TRACE(ah->ah_sc); 543 ATH5K_TRACE(ah->ah_sc);
537 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) 544
545 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
538 return -EINVAL; 546 return -EINVAL;
539 547
540 if (ah->ah_version == AR5K_AR5210) 548 if (ah->ah_version == AR5K_AR5210)
541 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, 549 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
542 ah->ah_turbo), AR5K_SLOT_TIME);
543 else 550 else
544 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); 551 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
545 552
546 return 0; 553 return 0;
547} 554}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index c63ea6afd96f..1464f89b249c 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -35,7 +35,7 @@
35 * released by Atheros and on various debug messages found on the net. 35 * released by Atheros and on various debug messages found on the net.
36 */ 36 */
37 37
38 38#include "../reg.h"
39 39
40/*====MAC DMA REGISTERS====*/ 40/*====MAC DMA REGISTERS====*/
41 41
@@ -1650,12 +1650,6 @@
1650#define AR5K_SLEEP2_DTIM_PER_S 16 1650#define AR5K_SLEEP2_DTIM_PER_S 16
1651 1651
1652/* 1652/*
1653 * BSSID mask registers
1654 */
1655#define AR5K_BSS_IDM0 0x80e0 /* Upper bits */
1656#define AR5K_BSS_IDM1 0x80e4 /* Lower bits */
1657
1658/*
1659 * TX power control (TPC) register 1653 * TX power control (TPC) register
1660 * 1654 *
1661 * XXX: PCDAC steps (0.5dbm) or DBM ? 1655 * XXX: PCDAC steps (0.5dbm) or DBM ?
@@ -2039,17 +2033,14 @@
2039#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ 2033#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
2040 2034
2041/* 2035/*
2042 * PHY noise floor status register 2036 * PHY noise floor status register (CCA = Clear Channel Assessment)
2043 */ 2037 */
2044#define AR5K_PHY_NF 0x9864 /* Register address */ 2038#define AR5K_PHY_NF 0x9864 /* Register address */
2045#define AR5K_PHY_NF_M 0x000001ff /* Noise floor mask */ 2039#define AR5K_PHY_NF_M 0x000001ff /* Noise floor, written to hardware in 1/2 dBm units */
2046#define AR5K_PHY_NF_ACTIVE 0x00000100 /* Noise floor calibration still active */ 2040#define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9))
2047#define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M)
2048#define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1)
2049#define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9))
2050#define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ 2041#define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */
2051#define AR5K_PHY_NF_THRESH62_S 12 2042#define AR5K_PHY_NF_THRESH62_S 12
2052#define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */ 2043#define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* Minimum measured noise level, read from hardware in 1 dBm units */
2053#define AR5K_PHY_NF_MINCCA_PWR_S 19 2044#define AR5K_PHY_NF_MINCCA_PWR_S 19
2054 2045
2055/* 2046/*
@@ -2196,6 +2187,7 @@
2196 */ 2187 */
2197#define AR5K_PHY_IQ 0x9920 /* Register Address */ 2188#define AR5K_PHY_IQ 0x9920 /* Register Address */
2198#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ 2189#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
2190#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0
2199#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ 2191#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
2200#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 2192#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
2201#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ 2193#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 34e13c700849..cbf28e379843 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -25,6 +25,8 @@
25 Reset functions and helpers 25 Reset functions and helpers
26\*****************************/ 26\*****************************/
27 27
28#include <asm/unaligned.h>
29
28#include <linux/pci.h> /* To determine if a card is pci-e */ 30#include <linux/pci.h> /* To determine if a card is pci-e */
29#include <linux/log2.h> 31#include <linux/log2.h>
30#include "ath5k.h" 32#include "ath5k.h"
@@ -58,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
58 !(channel->hw_value & CHANNEL_OFDM)); 60 !(channel->hw_value & CHANNEL_OFDM));
59 61
60 /* Get coefficient 62 /* Get coefficient
61 * ALGO: coef = (5 * clock * carrier_freq) / 2) 63 * ALGO: coef = (5 * clock / carrier_freq) / 2
62 * we scale coef by shifting clock value by 24 for 64 * we scale coef by shifting clock value by 24 for
63 * better precision since we use integers */ 65 * better precision since we use integers */
64 /* TODO: Half/quarter rate */ 66 /* TODO: Half/quarter rate */
65 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); 67 clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
66
67 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; 68 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
68 69
69 /* Get exponent 70 /* Get exponent
@@ -850,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
850 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, 851 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
851 AR5K_INIT_CYCRSSI_THR1); 852 AR5K_INIT_CYCRSSI_THR1);
852 853
853 /* I/Q correction 854 /* I/Q correction (set enable bit last to match HAL sources) */
854 * TODO: Per channel i/q infos ? */ 855 /* TODO: Per channel i/q infos ? */
855 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, 856 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
856 AR5K_PHY_IQ_CORR_ENABLE | 857 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
857 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | 858 ee->ee_i_cal[ee_mode]);
858 ee->ee_q_cal[ee_mode]); 859 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
860 ee->ee_q_cal[ee_mode]);
861 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
862 }
859 863
860 /* Heavy clipping -disable for now */ 864 /* Heavy clipping -disable for now */
861 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) 865 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@@ -870,6 +874,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
870int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 874int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
871 struct ieee80211_channel *channel, bool change_channel) 875 struct ieee80211_channel *channel, bool change_channel)
872{ 876{
877 struct ath_common *common = ath5k_hw_common(ah);
873 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; 878 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
874 u32 phy_tst1; 879 u32 phy_tst1;
875 u8 mode, freq, ee_mode, ant[2]; 880 u8 mode, freq, ee_mode, ant[2];
@@ -1171,10 +1176,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1171 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); 1176 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1172 1177
1173 /* Restore sta_id flags and preserve our mac address*/ 1178 /* Restore sta_id flags and preserve our mac address*/
1174 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), 1179 ath5k_hw_reg_write(ah,
1175 AR5K_STA_ID0); 1180 get_unaligned_le32(common->macaddr),
1176 ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), 1181 AR5K_STA_ID0);
1177 AR5K_STA_ID1); 1182 ath5k_hw_reg_write(ah,
1183 staid1_flags | get_unaligned_le16(common->macaddr + 4),
1184 AR5K_STA_ID1);
1178 1185
1179 1186
1180 /* 1187 /*
@@ -1182,8 +1189,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1182 */ 1189 */
1183 1190
1184 /* Restore bssid and bssid mask */ 1191 /* Restore bssid and bssid mask */
1185 /* XXX: add ah->aid once mac80211 gives this to us */ 1192 ath5k_hw_set_associd(ah);
1186 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
1187 1193
1188 /* Set PCU config */ 1194 /* Set PCU config */
1189 ath5k_hw_set_opmode(ah); 1195 ath5k_hw_set_opmode(ah);
@@ -1289,7 +1295,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1289 * out and/or noise floor calibration might timeout. 1295 * out and/or noise floor calibration might timeout.
1290 */ 1296 */
1291 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1297 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1292 AR5K_PHY_AGCCTL_CAL); 1298 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
1293 1299
1294 /* At the same time start I/Q calibration for QAM constellation 1300 /* At the same time start I/Q calibration for QAM constellation
1295 * -no need for CCK- */ 1301 * -no need for CCK- */
@@ -1310,24 +1316,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1310 channel->center_freq); 1316 channel->center_freq);
1311 } 1317 }
1312 1318
1313 /*
1314 * If we run NF calibration before AGC, it always times out.
1315 * Binary HAL starts NF and AGC calibration at the same time
1316 * and only waits for AGC to finish. Also if AGC or NF cal.
1317 * times out, reset doesn't fail on binary HAL. I believe
1318 * that's wrong because since rx path is routed to a detector,
1319 * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
1320 * enables noise floor calibration after offset calibration and if noise
1321 * floor calibration fails, reset fails. I believe that's
1322 * a better approach, we just need to find a polling interval
1323 * that suits best, even if reset continues we need to make
1324 * sure that rx path is ready.
1325 */
1326 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1327
1328 /* Restore antenna mode */ 1319 /* Restore antenna mode */
1329 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 1320 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1330 1321
1322 /* Restore slot time and ACK timeouts */
1323 if (ah->ah_coverage_class > 0)
1324 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1325
1331 /* 1326 /*
1332 * Configure QCUs/DCUs 1327 * Configure QCUs/DCUs
1333 */ 1328 */
@@ -1382,15 +1377,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1382 * Set clocks to 32KHz operation and use an 1377 * Set clocks to 32KHz operation and use an
1383 * external 32KHz crystal when sleeping if one 1378 * external 32KHz crystal when sleeping if one
1384 * exists */ 1379 * exists */
1385 if (ah->ah_version == AR5K_AR5212) 1380 if (ah->ah_version == AR5K_AR5212 &&
1386 ath5k_hw_set_sleep_clock(ah, true); 1381 ah->ah_op_mode != NL80211_IFTYPE_AP)
1382 ath5k_hw_set_sleep_clock(ah, true);
1387 1383
1388 /* 1384 /*
1389 * Disable beacons and reset the register 1385 * Disable beacons and reset the TSF
1390 */ 1386 */
1391 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | 1387 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
1392 AR5K_BEACON_RESET_TSF); 1388 ath5k_hw_reset_tsf(ah);
1393
1394 return 0; 1389 return 0;
1395} 1390}
1396 1391