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.h53
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c33
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c140
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h14
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c193
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c187
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h19
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c33
11 files changed, 314 insertions, 366 deletions
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 06d006675d7..eb83b7b4d0e 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 6cd5efcec41..6a2a9676111 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
@@ -1012,6 +1007,14 @@ struct ath5k_capabilities {
1012 } cap_queues; 1007 } cap_queues;
1013}; 1008};
1014 1009
1010/* size of noise floor history (keep it a power of two) */
1011#define ATH5K_NF_CAL_HIST_MAX 8
1012struct ath5k_nfcal_hist
1013{
1014 s16 index; /* current index into nfval */
1015 s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
1016};
1017
1015 1018
1016/***************************************\ 1019/***************************************\
1017 HARDWARE ABSTRACTION LAYER STRUCTURE 1020 HARDWARE ABSTRACTION LAYER STRUCTURE
@@ -1027,6 +1030,7 @@ struct ath5k_capabilities {
1027/* TODO: Clean up and merge with ath5k_softc */ 1030/* TODO: Clean up and merge with ath5k_softc */
1028struct ath5k_hw { 1031struct ath5k_hw {
1029 u32 ah_magic; 1032 u32 ah_magic;
1033 struct ath_common common;
1030 1034
1031 struct ath5k_softc *ah_sc; 1035 struct ath5k_softc *ah_sc;
1032 void __iomem *ah_iobase; 1036 void __iomem *ah_iobase;
@@ -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 */
@@ -1203,10 +1201,9 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
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);
1205/* BSSID Functions */ 1203/* 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); 1204extern 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); 1205extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
1209extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); 1206extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1210/* Receive start/stop functions */ 1207/* Receive start/stop functions */
1211extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); 1208extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1212extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); 1209extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
@@ -1288,8 +1285,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); 1285extern 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); 1286extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1290/* PHY calibration */ 1287/* PHY calibration */
1288void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1291extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); 1289extern 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); 1290extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1291extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah);
1293extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah); 1292extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
1294/* Spur mitigation */ 1293/* Spur mitigation */
1295bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1294bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
@@ -1329,17 +1328,21 @@ static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1329 return turbo ? (clock / 80) : (clock / 40); 1328 return turbo ? (clock / 80) : (clock / 40);
1330} 1329}
1331 1330
1332/* 1331static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
1333 * Read from a register 1332{
1334 */ 1333 return &ah->common;
1334}
1335
1336static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
1337{
1338 return &(ath5k_hw_common(ah)->regulatory);
1339}
1340
1335static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) 1341static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1336{ 1342{
1337 return ioread32(ah->ah_iobase + reg); 1343 return ioread32(ah->ah_iobase + reg);
1338} 1344}
1339 1345
1340/*
1341 * Write to a register
1342 */
1343static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) 1346static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1344{ 1347{
1345 iowrite32(val, ah->ah_iobase + reg); 1348 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 71a1bd25451..42284445b75 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -101,25 +101,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 101 * -ENODEV if the device is not supported or prints an error msg if something
102 * else went wrong. 102 * else went wrong.
103 */ 103 */
104struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc) 104int ath5k_hw_attach(struct ath5k_softc *sc)
105{ 105{
106 struct ath5k_hw *ah; 106 struct ath5k_hw *ah = sc->ah;
107 struct ath_common *common = ath5k_hw_common(ah);
107 struct pci_dev *pdev = sc->pdev; 108 struct pci_dev *pdev = sc->pdev;
108 struct ath5k_eeprom_info *ee; 109 struct ath5k_eeprom_info *ee;
109 int ret; 110 int ret;
110 u32 srev; 111 u32 srev;
111 112
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 /* 113 /*
124 * HW information 114 * HW information
125 */ 115 */
@@ -278,12 +268,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
278 goto err_free; 268 goto err_free;
279 } 269 }
280 270
271 ee = &ah->ah_capabilities.cap_eeprom;
272
281 /* 273 /*
282 * Write PCI-E power save settings 274 * Write PCI-E power save settings
283 */ 275 */
284 if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { 276 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); 277 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
288 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); 278 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
289 279
@@ -321,7 +311,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
321 } 311 }
322 312
323 /* Crypto settings */ 313 /* Crypto settings */
324 ee = &ah->ah_capabilities.cap_eeprom;
325 ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && 314 ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
326 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && 315 (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
327 !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); 316 !AR5K_EEPROM_AES_DIS(ee->ee_misc5));
@@ -336,20 +325,21 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
336 ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){}); 325 ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
337 326
338 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ 327 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
339 memset(ah->ah_bssid, 0xff, ETH_ALEN); 328 memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
340 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 329 ath5k_hw_set_associd(ah);
341 ath5k_hw_set_opmode(ah); 330 ath5k_hw_set_opmode(ah);
342 331
343 ath5k_hw_rfgain_opt_init(ah); 332 ath5k_hw_rfgain_opt_init(ah);
344 333
334 ath5k_hw_init_nfcal_hist(ah);
335
345 /* turn on HW LEDs */ 336 /* turn on HW LEDs */
346 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); 337 ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
347 338
348 return ah; 339 return 0;
349err_free: 340err_free:
350 kfree(ah); 341 kfree(ah);
351err: 342 return ret;
352 return ERR_PTR(ret);
353} 343}
354 344
355/** 345/**
@@ -369,5 +359,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
369 ath5k_eeprom_detach(ah); 359 ath5k_eeprom_detach(ah);
370 360
371 /* assume interrupts are down */ 361 /* assume interrupts are down */
372 kfree(ah);
373} 362}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 95a8e232b58..a4c086f069b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -195,12 +195,13 @@ static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
195 const struct pci_device_id *id); 195 const struct pci_device_id *id);
196static void __devexit ath5k_pci_remove(struct pci_dev *pdev); 196static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
197#ifdef CONFIG_PM 197#ifdef CONFIG_PM
198static int ath5k_pci_suspend(struct pci_dev *pdev, 198static int ath5k_pci_suspend(struct device *dev);
199 pm_message_t state); 199static int ath5k_pci_resume(struct device *dev);
200static int ath5k_pci_resume(struct pci_dev *pdev); 200
201SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
202#define ATH5K_PM_OPS (&ath5k_pm_ops)
201#else 203#else
202#define ath5k_pci_suspend NULL 204#define ATH5K_PM_OPS NULL
203#define ath5k_pci_resume NULL
204#endif /* CONFIG_PM */ 205#endif /* CONFIG_PM */
205 206
206static struct pci_driver ath5k_pci_driver = { 207static struct pci_driver ath5k_pci_driver = {
@@ -208,8 +209,7 @@ static struct pci_driver ath5k_pci_driver = {
208 .id_table = ath5k_pci_id_table, 209 .id_table = ath5k_pci_id_table,
209 .probe = ath5k_pci_probe, 210 .probe = ath5k_pci_probe,
210 .remove = __devexit_p(ath5k_pci_remove), 211 .remove = __devexit_p(ath5k_pci_remove),
211 .suspend = ath5k_pci_suspend, 212 .driver.pm = ATH5K_PM_OPS,
212 .resume = ath5k_pci_resume,
213}; 213};
214 214
215 215
@@ -323,10 +323,13 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
323static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, 323static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
324 struct ath5k_buf *bf) 324 struct ath5k_buf *bf)
325{ 325{
326 struct ath5k_hw *ah = sc->ah;
327 struct ath_common *common = ath5k_hw_common(ah);
328
326 BUG_ON(!bf); 329 BUG_ON(!bf);
327 if (!bf->skb) 330 if (!bf->skb)
328 return; 331 return;
329 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 332 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
330 PCI_DMA_FROMDEVICE); 333 PCI_DMA_FROMDEVICE);
331 dev_kfree_skb_any(bf->skb); 334 dev_kfree_skb_any(bf->skb);
332 bf->skb = NULL; 335 bf->skb = NULL;
@@ -437,6 +440,22 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
437 440
438 return name; 441 return name;
439} 442}
443static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
444{
445 struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
446 return ath5k_hw_reg_read(ah, reg_offset);
447}
448
449static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
450{
451 struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
452 ath5k_hw_reg_write(ah, val, reg_offset);
453}
454
455static const struct ath_ops ath5k_common_ops = {
456 .read = ath5k_ioread32,
457 .write = ath5k_iowrite32,
458};
440 459
441static int __devinit 460static int __devinit
442ath5k_pci_probe(struct pci_dev *pdev, 461ath5k_pci_probe(struct pci_dev *pdev,
@@ -444,6 +463,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
444{ 463{
445 void __iomem *mem; 464 void __iomem *mem;
446 struct ath5k_softc *sc; 465 struct ath5k_softc *sc;
466 struct ath_common *common;
447 struct ieee80211_hw *hw; 467 struct ieee80211_hw *hw;
448 int ret; 468 int ret;
449 u8 csz; 469 u8 csz;
@@ -547,7 +567,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
547 __set_bit(ATH_STAT_INVALID, sc->status); 567 __set_bit(ATH_STAT_INVALID, sc->status);
548 568
549 sc->iobase = mem; /* So we can unmap it on detach */ 569 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; 570 sc->opmode = NL80211_IFTYPE_STATION;
552 sc->bintval = 1000; 571 sc->bintval = 1000;
553 mutex_init(&sc->lock); 572 mutex_init(&sc->lock);
@@ -565,13 +584,28 @@ ath5k_pci_probe(struct pci_dev *pdev,
565 goto err_free; 584 goto err_free;
566 } 585 }
567 586
568 /* Initialize device */ 587 /*If we passed the test malloc a ath5k_hw struct*/
569 sc->ah = ath5k_hw_attach(sc); 588 sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
570 if (IS_ERR(sc->ah)) { 589 if (!sc->ah) {
571 ret = PTR_ERR(sc->ah); 590 ret = -ENOMEM;
591 ATH5K_ERR(sc, "out of memory\n");
572 goto err_irq; 592 goto err_irq;
573 } 593 }
574 594
595 sc->ah->ah_sc = sc;
596 sc->ah->ah_iobase = sc->iobase;
597 common = ath5k_hw_common(sc->ah);
598 common->ops = &ath5k_common_ops;
599 common->ah = sc->ah;
600 common->hw = hw;
601 common->cachelsz = csz << 2; /* convert to bytes */
602
603 /* Initialize device */
604 ret = ath5k_hw_attach(sc);
605 if (ret) {
606 goto err_free_ah;
607 }
608
575 /* set up multi-rate retry capabilities */ 609 /* set up multi-rate retry capabilities */
576 if (sc->ah->ah_version == AR5K_AR5212) { 610 if (sc->ah->ah_version == AR5K_AR5212) {
577 hw->max_rates = 4; 611 hw->max_rates = 4;
@@ -640,6 +674,8 @@ err_ah:
640 ath5k_hw_detach(sc->ah); 674 ath5k_hw_detach(sc->ah);
641err_irq: 675err_irq:
642 free_irq(pdev->irq, sc); 676 free_irq(pdev->irq, sc);
677err_free_ah:
678 kfree(sc->ah);
643err_free: 679err_free:
644 ieee80211_free_hw(hw); 680 ieee80211_free_hw(hw);
645err_map: 681err_map:
@@ -661,6 +697,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
661 ath5k_debug_finish_device(sc); 697 ath5k_debug_finish_device(sc);
662 ath5k_detach(pdev, hw); 698 ath5k_detach(pdev, hw);
663 ath5k_hw_detach(sc->ah); 699 ath5k_hw_detach(sc->ah);
700 kfree(sc->ah);
664 free_irq(pdev->irq, sc); 701 free_irq(pdev->irq, sc);
665 pci_iounmap(pdev, sc->iobase); 702 pci_iounmap(pdev, sc->iobase);
666 pci_release_region(pdev, 0); 703 pci_release_region(pdev, 0);
@@ -669,33 +706,20 @@ ath5k_pci_remove(struct pci_dev *pdev)
669} 706}
670 707
671#ifdef CONFIG_PM 708#ifdef CONFIG_PM
672static int 709static int ath5k_pci_suspend(struct device *dev)
673ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
674{ 710{
675 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 711 struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev));
676 struct ath5k_softc *sc = hw->priv; 712 struct ath5k_softc *sc = hw->priv;
677 713
678 ath5k_led_off(sc); 714 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; 715 return 0;
685} 716}
686 717
687static int 718static int ath5k_pci_resume(struct device *dev)
688ath5k_pci_resume(struct pci_dev *pdev)
689{ 719{
720 struct pci_dev *pdev = to_pci_dev(dev);
690 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 721 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
691 struct ath5k_softc *sc = hw->priv; 722 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 723
700 /* 724 /*
701 * Suspend/Resume resets the PCI configuration space, so we have to 725 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -718,7 +742,7 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
718{ 742{
719 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 743 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
720 struct ath5k_softc *sc = hw->priv; 744 struct ath5k_softc *sc = hw->priv;
721 struct ath_regulatory *regulatory = &sc->common.regulatory; 745 struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
722 746
723 return ath_reg_notifier_apply(wiphy, request, regulatory); 747 return ath_reg_notifier_apply(wiphy, request, regulatory);
724} 748}
@@ -728,7 +752,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
728{ 752{
729 struct ath5k_softc *sc = hw->priv; 753 struct ath5k_softc *sc = hw->priv;
730 struct ath5k_hw *ah = sc->ah; 754 struct ath5k_hw *ah = sc->ah;
731 struct ath_regulatory *regulatory = &sc->common.regulatory; 755 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
732 u8 mac[ETH_ALEN] = {}; 756 u8 mac[ETH_ALEN] = {};
733 int ret; 757 int ret;
734 758
@@ -815,7 +839,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
815 839
816 SET_IEEE80211_PERM_ADDR(hw, mac); 840 SET_IEEE80211_PERM_ADDR(hw, mac);
817 /* All MAC address bits matter for ACKs */ 841 /* All MAC address bits matter for ACKs */
818 memset(sc->bssidmask, 0xff, ETH_ALEN); 842 memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
819 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); 843 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
820 844
821 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; 845 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
@@ -1152,24 +1176,26 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
1152static 1176static
1153struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) 1177struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
1154{ 1178{
1179 struct ath_common *common = ath5k_hw_common(sc->ah);
1155 struct sk_buff *skb; 1180 struct sk_buff *skb;
1156 1181
1157 /* 1182 /*
1158 * Allocate buffer with headroom_needed space for the 1183 * Allocate buffer with headroom_needed space for the
1159 * fake physical layer header at the start. 1184 * fake physical layer header at the start.
1160 */ 1185 */
1161 skb = ath_rxbuf_alloc(&sc->common, 1186 skb = ath_rxbuf_alloc(common,
1162 sc->rxbufsize + sc->common.cachelsz - 1, 1187 common->rx_bufsize,
1163 GFP_ATOMIC); 1188 GFP_ATOMIC);
1164 1189
1165 if (!skb) { 1190 if (!skb) {
1166 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", 1191 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1167 sc->rxbufsize + sc->common.cachelsz - 1); 1192 common->rx_bufsize);
1168 return NULL; 1193 return NULL;
1169 } 1194 }
1170 1195
1171 *skb_addr = pci_map_single(sc->pdev, 1196 *skb_addr = pci_map_single(sc->pdev,
1172 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); 1197 skb->data, common->rx_bufsize,
1198 PCI_DMA_FROMDEVICE);
1173 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { 1199 if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
1174 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); 1200 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1175 dev_kfree_skb(skb); 1201 dev_kfree_skb(skb);
@@ -1605,13 +1631,14 @@ static int
1605ath5k_rx_start(struct ath5k_softc *sc) 1631ath5k_rx_start(struct ath5k_softc *sc)
1606{ 1632{
1607 struct ath5k_hw *ah = sc->ah; 1633 struct ath5k_hw *ah = sc->ah;
1634 struct ath_common *common = ath5k_hw_common(ah);
1608 struct ath5k_buf *bf; 1635 struct ath5k_buf *bf;
1609 int ret; 1636 int ret;
1610 1637
1611 sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz); 1638 common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
1612 1639
1613 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", 1640 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
1614 sc->common.cachelsz, sc->rxbufsize); 1641 common->cachelsz, common->rx_bufsize);
1615 1642
1616 spin_lock_bh(&sc->rxbuflock); 1643 spin_lock_bh(&sc->rxbuflock);
1617 sc->rxlink = NULL; 1644 sc->rxlink = NULL;
@@ -1656,6 +1683,8 @@ static unsigned int
1656ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, 1683ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1657 struct sk_buff *skb, struct ath5k_rx_status *rs) 1684 struct sk_buff *skb, struct ath5k_rx_status *rs)
1658{ 1685{
1686 struct ath5k_hw *ah = sc->ah;
1687 struct ath_common *common = ath5k_hw_common(ah);
1659 struct ieee80211_hdr *hdr = (void *)skb->data; 1688 struct ieee80211_hdr *hdr = (void *)skb->data;
1660 unsigned int keyix, hlen; 1689 unsigned int keyix, hlen;
1661 1690
@@ -1672,7 +1701,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1672 skb->len >= hlen + 4) { 1701 skb->len >= hlen + 4) {
1673 keyix = skb->data[hlen + 3] >> 6; 1702 keyix = skb->data[hlen + 3] >> 6;
1674 1703
1675 if (test_bit(keyix, sc->keymap)) 1704 if (test_bit(keyix, common->keymap))
1676 return RX_FLAG_DECRYPTED; 1705 return RX_FLAG_DECRYPTED;
1677 } 1706 }
1678 1707
@@ -1684,13 +1713,14 @@ static void
1684ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, 1713ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1685 struct ieee80211_rx_status *rxs) 1714 struct ieee80211_rx_status *rxs)
1686{ 1715{
1716 struct ath_common *common = ath5k_hw_common(sc->ah);
1687 u64 tsf, bc_tstamp; 1717 u64 tsf, bc_tstamp;
1688 u32 hw_tu; 1718 u32 hw_tu;
1689 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1719 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1690 1720
1691 if (ieee80211_is_beacon(mgmt->frame_control) && 1721 if (ieee80211_is_beacon(mgmt->frame_control) &&
1692 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && 1722 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
1693 memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { 1723 memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
1694 /* 1724 /*
1695 * Received an IBSS beacon with the same BSSID. Hardware *must* 1725 * Received an IBSS beacon with the same BSSID. Hardware *must*
1696 * have updated the local TSF. We have to work around various 1726 * have updated the local TSF. We have to work around various
@@ -1745,6 +1775,8 @@ ath5k_tasklet_rx(unsigned long data)
1745 struct sk_buff *skb, *next_skb; 1775 struct sk_buff *skb, *next_skb;
1746 dma_addr_t next_skb_addr; 1776 dma_addr_t next_skb_addr;
1747 struct ath5k_softc *sc = (void *)data; 1777 struct ath5k_softc *sc = (void *)data;
1778 struct ath5k_hw *ah = sc->ah;
1779 struct ath_common *common = ath5k_hw_common(ah);
1748 struct ath5k_buf *bf; 1780 struct ath5k_buf *bf;
1749 struct ath5k_desc *ds; 1781 struct ath5k_desc *ds;
1750 int ret; 1782 int ret;
@@ -1822,7 +1854,7 @@ accept:
1822 if (!next_skb) 1854 if (!next_skb)
1823 goto next; 1855 goto next;
1824 1856
1825 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 1857 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
1826 PCI_DMA_FROMDEVICE); 1858 PCI_DMA_FROMDEVICE);
1827 skb_put(skb, rs.rs_datalen); 1859 skb_put(skb, rs.rs_datalen);
1828 1860
@@ -3008,6 +3040,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3008 struct ieee80211_key_conf *key) 3040 struct ieee80211_key_conf *key)
3009{ 3041{
3010 struct ath5k_softc *sc = hw->priv; 3042 struct ath5k_softc *sc = hw->priv;
3043 struct ath5k_hw *ah = sc->ah;
3044 struct ath_common *common = ath5k_hw_common(ah);
3011 int ret = 0; 3045 int ret = 0;
3012 3046
3013 if (modparam_nohwcrypt) 3047 if (modparam_nohwcrypt)
@@ -3040,14 +3074,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3040 ATH5K_ERR(sc, "can't set the key\n"); 3074 ATH5K_ERR(sc, "can't set the key\n");
3041 goto unlock; 3075 goto unlock;
3042 } 3076 }
3043 __set_bit(key->keyidx, sc->keymap); 3077 __set_bit(key->keyidx, common->keymap);
3044 key->hw_key_idx = key->keyidx; 3078 key->hw_key_idx = key->keyidx;
3045 key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | 3079 key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
3046 IEEE80211_KEY_FLAG_GENERATE_MMIC); 3080 IEEE80211_KEY_FLAG_GENERATE_MMIC);
3047 break; 3081 break;
3048 case DISABLE_KEY: 3082 case DISABLE_KEY:
3049 ath5k_hw_reset_key(sc->ah, key->keyidx); 3083 ath5k_hw_reset_key(sc->ah, key->keyidx);
3050 __clear_bit(key->keyidx, sc->keymap); 3084 __clear_bit(key->keyidx, common->keymap);
3051 break; 3085 break;
3052 default: 3086 default:
3053 ret = -EINVAL; 3087 ret = -EINVAL;
@@ -3176,6 +3210,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3176{ 3210{
3177 struct ath5k_softc *sc = hw->priv; 3211 struct ath5k_softc *sc = hw->priv;
3178 struct ath5k_hw *ah = sc->ah; 3212 struct ath5k_hw *ah = sc->ah;
3213 struct ath_common *common = ath5k_hw_common(ah);
3179 unsigned long flags; 3214 unsigned long flags;
3180 3215
3181 mutex_lock(&sc->lock); 3216 mutex_lock(&sc->lock);
@@ -3184,10 +3219,9 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3184 3219
3185 if (changes & BSS_CHANGED_BSSID) { 3220 if (changes & BSS_CHANGED_BSSID) {
3186 /* Cache for later use during resets */ 3221 /* Cache for later use during resets */
3187 memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN); 3222 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
3188 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have 3223 common->curaid = 0;
3189 * a clean way of letting us retrieve this yet. */ 3224 ath5k_hw_set_associd(ah);
3190 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
3191 mmiowb(); 3225 mmiowb();
3192 } 3226 }
3193 3227
@@ -3200,6 +3234,14 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
3200 set_beacon_filter(hw, sc->assoc); 3234 set_beacon_filter(hw, sc->assoc);
3201 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3235 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3202 AR5K_LED_ASSOC : AR5K_LED_INIT); 3236 AR5K_LED_ASSOC : AR5K_LED_INIT);
3237 if (bss_conf->assoc) {
3238 ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
3239 "Bss Info ASSOC %d, bssid: %pM\n",
3240 bss_conf->aid, common->curbssid);
3241 common->curaid = bss_conf->aid;
3242 ath5k_hw_set_associd(ah);
3243 /* Once ANI is available you would start it here */
3244 }
3203 } 3245 }
3204 3246
3205 if (changes & BSS_CHANGED_BEACON) { 3247 if (changes & BSS_CHANGED_BEACON) {
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index a28c42f32c9..b72338c9bde 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -115,7 +115,6 @@ 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]; 120 struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
@@ -154,8 +153,6 @@ struct ath5k_softc {
154 153
155 enum ath5k_int imask; /* interrupt mask copy */ 154 enum ath5k_int imask; /* interrupt mask copy */
156 155
157 DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
158
159 u8 bssidmask[ETH_ALEN]; 156 u8 bssidmask[ETH_ALEN];
160 157
161 unsigned int led_pin, /* GPIO pin for driving LED */ 158 unsigned int led_pin, /* GPIO pin for driving LED */
@@ -202,15 +199,4 @@ struct ath5k_softc {
202#define ath5k_hw_hasveol(_ah) \ 199#define ath5k_hw_hasveol(_ah) \
203 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0) 200 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
204 201
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 202#endif
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 18eb5190ce4..8fa43930882 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 b548c8eaaae..d495890355d 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) */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 2942f13c9c4..64fc1eb9b6d 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
@@ -238,28 +241,6 @@ int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
238 return 0; 241 return 0;
239} 242}
240 243
241
242/****************\
243* BSSID handling *
244\****************/
245
246/**
247 * ath5k_hw_get_lladdr - Get station id
248 *
249 * @ah: The &struct ath5k_hw
250 * @mac: The card's mac address
251 *
252 * Initialize ah->ah_sta_id using the mac address provided
253 * (just a memcpy).
254 *
255 * TODO: Remove it once we merge ath5k_softc and ath5k_hw
256 */
257void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
258{
259 ATH5K_TRACE(ah->ah_sc);
260 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
261}
262
263/** 244/**
264 * ath5k_hw_set_lladdr - Set station id 245 * ath5k_hw_set_lladdr - Set station id
265 * 246 *
@@ -270,17 +251,18 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
270 */ 251 */
271int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) 252int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
272{ 253{
254 struct ath_common *common = ath5k_hw_common(ah);
273 u32 low_id, high_id; 255 u32 low_id, high_id;
274 u32 pcu_reg; 256 u32 pcu_reg;
275 257
276 ATH5K_TRACE(ah->ah_sc); 258 ATH5K_TRACE(ah->ah_sc);
277 /* Set new station ID */ 259 /* Set new station ID */
278 memcpy(ah->ah_sta_id, mac, ETH_ALEN); 260 memcpy(common->macaddr, mac, ETH_ALEN);
279 261
280 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; 262 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
281 263
282 low_id = AR5K_LOW_ID(mac); 264 low_id = get_unaligned_le32(mac);
283 high_id = AR5K_HIGH_ID(mac); 265 high_id = get_unaligned_le16(mac + 4);
284 266
285 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); 267 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
286 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); 268 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
@@ -297,159 +279,51 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
297 * 279 *
298 * Sets the BSSID which trigers the "SME Join" operation 280 * Sets the BSSID which trigers the "SME Join" operation
299 */ 281 */
300void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) 282void ath5k_hw_set_associd(struct ath5k_hw *ah)
301{ 283{
302 u32 low_id, high_id; 284 struct ath_common *common = ath5k_hw_common(ah);
303 u16 tim_offset = 0; 285 u16 tim_offset = 0;
304 286
305 /* 287 /*
306 * Set simple BSSID mask on 5212 288 * Set simple BSSID mask on 5212
307 */ 289 */
308 if (ah->ah_version == AR5K_AR5212) { 290 if (ah->ah_version == AR5K_AR5212)
309 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask), 291 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 292
315 /* 293 /*
316 * Set BSSID which triggers the "SME Join" operation 294 * Set BSSID which triggers the "SME Join" operation
317 */ 295 */
318 low_id = AR5K_LOW_ID(bssid); 296 ath5k_hw_reg_write(ah,
319 high_id = AR5K_HIGH_ID(bssid); 297 get_unaligned_le32(common->curbssid),
320 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); 298 AR5K_BSS_ID0);
321 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << 299 ath5k_hw_reg_write(ah,
322 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); 300 get_unaligned_le16(common->curbssid + 4) |
323 301 ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
324 if (assoc_id == 0) { 302 AR5K_BSS_ID1);
303
304 if (common->curaid == 0) {
325 ath5k_hw_disable_pspoll(ah); 305 ath5k_hw_disable_pspoll(ah);
326 return; 306 return;
327 } 307 }
328 308
329 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM, 309 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
330 tim_offset ? tim_offset + 4 : 0); 310 tim_offset ? tim_offset + 4 : 0);
331 311
332 ath5k_hw_enable_pspoll(ah, NULL, 0); 312 ath5k_hw_enable_pspoll(ah, NULL, 0);
333} 313}
334 314
335/** 315void 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{ 316{
433 u32 low_id, high_id; 317 struct ath_common *common = ath5k_hw_common(ah);
434 ATH5K_TRACE(ah->ah_sc); 318 ATH5K_TRACE(ah->ah_sc);
435 319
436 /* Cache bssid mask so that we can restore it 320 /* Cache bssid mask so that we can restore it
437 * on reset */ 321 * on reset */
438 memcpy(ah->ah_bssid_mask, mask, ETH_ALEN); 322 memcpy(common->bssidmask, mask, ETH_ALEN);
439 if (ah->ah_version == AR5K_AR5212) { 323 if (ah->ah_version == AR5K_AR5212)
440 low_id = AR5K_LOW_ID(mask); 324 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} 325}
451 326
452
453/************\ 327/************\
454* RX Control * 328* RX Control *
455\************/ 329\************/
@@ -1157,14 +1031,17 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
1157 /* Invalid entry (key table overflow) */ 1031 /* Invalid entry (key table overflow) */
1158 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); 1032 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
1159 1033
1160 /* MAC may be NULL if it's a broadcast key. In this case no need to 1034 /*
1161 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ 1035 * MAC may be NULL if it's a broadcast key. In this case no need to
1036 * to compute get_unaligned_le32 and get_unaligned_le16 as we
1037 * already know it.
1038 */
1162 if (!mac) { 1039 if (!mac) {
1163 low_id = 0xffffffff; 1040 low_id = 0xffffffff;
1164 high_id = 0xffff | AR5K_KEYTABLE_VALID; 1041 high_id = 0xffff | AR5K_KEYTABLE_VALID;
1165 } else { 1042 } else {
1166 low_id = AR5K_LOW_ID(mac); 1043 low_id = get_unaligned_le32(mac);
1167 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID; 1044 high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
1168 } 1045 }
1169 1046
1170 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); 1047 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 1a039f2bd73..721ec5ee381 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1124,77 +1124,148 @@ ath5k_hw_calibration_poll(struct ath5k_hw *ah)
1124 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION; 1124 ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
1125 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); 1125 AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
1126 } 1126 }
1127}
1127 1128
1129static int sign_extend(int val, const int nbits)
1130{
1131 int order = BIT(nbits-1);
1132 return (val ^ order) - order;
1128} 1133}
1129 1134
1130/** 1135static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1131 * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration 1136{
1132 * 1137 s32 val;
1133 * @ah: struct ath5k_hw pointer we are operating on 1138
1134 * @freq: the channel frequency, just used for error logging 1139 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1135 * 1140 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 1141}
1137 * it to complete. Then the noise floor value is compared to some maximum 1142
1138 * noise floor we consider valid. 1143void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1139 * 1144{
1140 * Note that this is different from what the madwifi HAL does: it reads the 1145 int i;
1141 * noise floor and afterwards initiates the calibration. Since the noise floor 1146
1142 * calibration can take some time to finish, depending on the current channel 1147 ah->ah_nfcal_hist.index = 0;
1143 * use, that avoids the occasional timeout warnings we are seeing now. 1148 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1144 * 1149 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: 1150}
1146 * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \ 1151
1147 * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7 1152static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1153{
1154 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1155 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX-1);
1156 hist->nfval[hist->index] = noise_floor;
1157}
1158
1159static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1160{
1161 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1162 s16 tmp;
1163 int i, j;
1164
1165 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1166 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1167 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {
1168 if (sort[j] > sort[j-1]) {
1169 tmp = sort[j];
1170 sort[j] = sort[j-1];
1171 sort[j-1] = tmp;
1172 }
1173 }
1174 }
1175 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1176 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1177 "cal %d:%d\n", i, sort[i]);
1178 }
1179 return sort[(ATH5K_NF_CAL_HIST_MAX-1) / 2];
1180}
1181
1182/*
1183 * When we tell the hardware to perform a noise floor calibration
1184 * by setting the AR5K_PHY_AGCCTL_NF bit, it will periodically
1185 * sample-and-hold the minimum noise level seen at the antennas.
1186 * This value is then stored in a ring buffer of recently measured
1187 * noise floor values so we have a moving window of the last few
1188 * samples.
1148 * 1189 *
1149 * XXX: Since during noise floor calibration antennas are detached according to 1190 * The median of the values in the history is then loaded into the
1150 * the patent, we should stop tx queues here. 1191 * hardware for its own use for RSSI and CCA measurements.
1151 */ 1192 */
1152int 1193void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1153ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
1154{ 1194{
1155 int ret; 1195 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1156 unsigned int i; 1196 u32 val;
1157 s32 noise_floor; 1197 s16 nf, threshold;
1198 u8 ee_mode;
1158 1199
1159 /* 1200 /* keep last value if calibration hasn't completed */
1160 * Enable noise floor calibration 1201 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
1161 */ 1202 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1162 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1203 "NF did not complete in calibration window\n");
1163 AR5K_PHY_AGCCTL_NF);
1164 1204
1165 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, 1205 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 } 1206 }
1172 1207
1173 /* Wait until the noise floor is calibrated and read the value */ 1208 switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
1174 for (i = 20; i > 0; i--) { 1209 case CHANNEL_A:
1175 mdelay(1); 1210 case CHANNEL_T:
1176 noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF); 1211 case CHANNEL_XR:
1177 noise_floor = AR5K_PHY_NF_RVAL(noise_floor); 1212 ee_mode = AR5K_EEPROM_MODE_11A;
1178 if (noise_floor & AR5K_PHY_NF_ACTIVE) { 1213 break;
1179 noise_floor = AR5K_PHY_NF_AVAL(noise_floor); 1214 case CHANNEL_G:
1180 1215 case CHANNEL_TG:
1181 if (noise_floor <= AR5K_TUNE_NOISE_FLOOR) 1216 ee_mode = AR5K_EEPROM_MODE_11G;
1182 break; 1217 break;
1183 } 1218 default:
1219 case CHANNEL_B:
1220 ee_mode = AR5K_EEPROM_MODE_11B;
1221 break;
1184 } 1222 }
1185 1223
1186 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1187 "noise floor %d\n", noise_floor);
1188 1224
1189 if (noise_floor > AR5K_TUNE_NOISE_FLOOR) { 1225 /* completed NF calibration, test threshold */
1190 ATH5K_ERR(ah->ah_sc, 1226 nf = ath5k_hw_read_measured_noise_floor(ah);
1191 "noise floor calibration failed (%uMHz)\n", freq); 1227 threshold = ee->ee_noise_floor_thr[ee_mode];
1192 return -EAGAIN; 1228
1229 if (nf > threshold) {
1230 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1231 "noise floor failure detected; "
1232 "read %d, threshold %d\n",
1233 nf, threshold);
1234
1235 nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1193 } 1236 }
1194 1237
1195 ah->ah_noise_floor = noise_floor; 1238 ath5k_hw_update_nfcal_hist(ah, nf);
1239 nf = ath5k_hw_get_median_noise_floor(ah);
1196 1240
1197 return 0; 1241 /* load noise floor (in .5 dBm) so the hardware will use it */
1242 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M;
1243 val |= (nf * 2) & AR5K_PHY_NF_M;
1244 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1245
1246 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1247 ~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE));
1248
1249 ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF,
1250 0, false);
1251
1252 /*
1253 * Load a high max CCA Power value (-50 dBm in .5 dBm units)
1254 * so that we're not capped by the median we just loaded.
1255 * This will be used as the initial value for the next noise
1256 * floor calibration.
1257 */
1258 val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M);
1259 ath5k_hw_reg_write(ah, val, AR5K_PHY_NF);
1260 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1261 AR5K_PHY_AGCCTL_NF_EN |
1262 AR5K_PHY_AGCCTL_NF_NOUPDATE |
1263 AR5K_PHY_AGCCTL_NF);
1264
1265 ah->ah_noise_floor = nf;
1266
1267 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1268 "noise floor calibrated: %d\n", nf);
1198} 1269}
1199 1270
1200/* 1271/*
@@ -1287,7 +1358,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1287 return ret; 1358 return ret;
1288 } 1359 }
1289 1360
1290 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1361 ath5k_hw_update_noise_floor(ah);
1291 1362
1292 /* 1363 /*
1293 * Re-enable RX/TX and beacons 1364 * Re-enable RX/TX and beacons
@@ -1360,7 +1431,7 @@ done:
1360 * since noise floor calibration interrupts rx path while I/Q 1431 * since noise floor calibration interrupts rx path while I/Q
1361 * calibration doesn't. We don't need to run noise floor calibration 1432 * calibration doesn't. We don't need to run noise floor calibration
1362 * as often as I/Q calibration.*/ 1433 * as often as I/Q calibration.*/
1363 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1434 ath5k_hw_update_noise_floor(ah);
1364 1435
1365 /* Initiate a gain_F calibration */ 1436 /* Initiate a gain_F calibration */
1366 ath5k_hw_request_rfgain_probe(ah); 1437 ath5k_hw_request_rfgain_probe(ah);
@@ -2954,8 +3025,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2954 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); 3025 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
2955 return -EINVAL; 3026 return -EINVAL;
2956 } 3027 }
2957 if (txpower == 0)
2958 txpower = AR5K_TUNE_DEFAULT_TXPOWER;
2959 3028
2960 /* Reset TX power values */ 3029 /* Reset TX power values */
2961 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 3030 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index c63ea6afd96..4cb9c5df9f4 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/*
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 34e13c70084..62954fc7786 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"
@@ -870,6 +872,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, 872int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
871 struct ieee80211_channel *channel, bool change_channel) 873 struct ieee80211_channel *channel, bool change_channel)
872{ 874{
875 struct ath_common *common = ath5k_hw_common(ah);
873 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; 876 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
874 u32 phy_tst1; 877 u32 phy_tst1;
875 u8 mode, freq, ee_mode, ant[2]; 878 u8 mode, freq, ee_mode, ant[2];
@@ -1171,10 +1174,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); 1174 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1172 1175
1173 /* Restore sta_id flags and preserve our mac address*/ 1176 /* Restore sta_id flags and preserve our mac address*/
1174 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), 1177 ath5k_hw_reg_write(ah,
1175 AR5K_STA_ID0); 1178 get_unaligned_le32(common->macaddr),
1176 ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), 1179 AR5K_STA_ID0);
1177 AR5K_STA_ID1); 1180 ath5k_hw_reg_write(ah,
1181 staid1_flags | get_unaligned_le16(common->macaddr + 4),
1182 AR5K_STA_ID1);
1178 1183
1179 1184
1180 /* 1185 /*
@@ -1182,8 +1187,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1182 */ 1187 */
1183 1188
1184 /* Restore bssid and bssid mask */ 1189 /* Restore bssid and bssid mask */
1185 /* XXX: add ah->aid once mac80211 gives this to us */ 1190 ath5k_hw_set_associd(ah);
1186 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
1187 1191
1188 /* Set PCU config */ 1192 /* Set PCU config */
1189 ath5k_hw_set_opmode(ah); 1193 ath5k_hw_set_opmode(ah);
@@ -1289,7 +1293,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1289 * out and/or noise floor calibration might timeout. 1293 * out and/or noise floor calibration might timeout.
1290 */ 1294 */
1291 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1295 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1292 AR5K_PHY_AGCCTL_CAL); 1296 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
1293 1297
1294 /* At the same time start I/Q calibration for QAM constellation 1298 /* At the same time start I/Q calibration for QAM constellation
1295 * -no need for CCK- */ 1299 * -no need for CCK- */
@@ -1310,21 +1314,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1310 channel->center_freq); 1314 channel->center_freq);
1311 } 1315 }
1312 1316
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 */ 1317 /* Restore antenna mode */
1329 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 1318 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1330 1319