diff options
author | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
commit | 4ba3eb034fb6fd1990ccc5a6d71d5abcda37b905 (patch) | |
tree | 0789ba36d96dba330416a1e6a9a68e891a78802a /drivers/net/wireless | |
parent | 35700212b45ea9f98fa682cfc1bc1a67c9ccc34b (diff) | |
parent | 18b6c9a2213d3b6e0212e8b225abf95f7564206a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless')
72 files changed, 1949 insertions, 1049 deletions
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 7e59b82e64d3..f9d6db8d013e 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -850,6 +850,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
850 | } | 850 | } |
851 | break; | 851 | break; |
852 | 852 | ||
853 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | ||
853 | case AR9170_RX_STATUS_MODULATION_OFDM: | 854 | case AR9170_RX_STATUS_MODULATION_OFDM: |
854 | switch (head->plcp[0] & 0xf) { | 855 | switch (head->plcp[0] & 0xf) { |
855 | case 0xb: | 856 | case 0xb: |
@@ -897,8 +898,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, | |||
897 | status->flag |= RX_FLAG_HT; | 898 | status->flag |= RX_FLAG_HT; |
898 | break; | 899 | break; |
899 | 900 | ||
900 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | 901 | default: |
901 | /* XXX */ | ||
902 | if (ar9170_nag_limiter(ar)) | 902 | if (ar9170_nag_limiter(ar)) |
903 | printk(KERN_ERR "%s: invalid modulation\n", | 903 | printk(KERN_ERR "%s: invalid modulation\n", |
904 | wiphy_name(ar->hw->wiphy)); | 904 | wiphy_name(ar->hw->wiphy)); |
@@ -2441,6 +2441,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2441 | } | 2441 | } |
2442 | 2442 | ||
2443 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, | 2443 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, |
2444 | struct ieee80211_vif *vif, | ||
2444 | enum ieee80211_ampdu_mlme_action action, | 2445 | enum ieee80211_ampdu_mlme_action action, |
2445 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2446 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2446 | { | 2447 | { |
@@ -2470,7 +2471,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2470 | tid_info->state = AR9170_TID_STATE_PROGRESS; | 2471 | tid_info->state = AR9170_TID_STATE_PROGRESS; |
2471 | tid_info->active = false; | 2472 | tid_info->active = false; |
2472 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2473 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2473 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2474 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2474 | break; | 2475 | break; |
2475 | 2476 | ||
2476 | case IEEE80211_AMPDU_TX_STOP: | 2477 | case IEEE80211_AMPDU_TX_STOP: |
@@ -2480,7 +2481,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2480 | tid_info->active = false; | 2481 | tid_info->active = false; |
2481 | skb_queue_purge(&tid_info->queue); | 2482 | skb_queue_purge(&tid_info->queue); |
2482 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2483 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2483 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2484 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2484 | break; | 2485 | break; |
2485 | 2486 | ||
2486 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 2487 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 6bdcdf6d1cc0..e0799d924057 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -68,8 +68,10 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
68 | { USB_DEVICE(0x0cf3, 0x1002) }, | 68 | { USB_DEVICE(0x0cf3, 0x1002) }, |
69 | /* Cace Airpcap NX */ | 69 | /* Cace Airpcap NX */ |
70 | { USB_DEVICE(0xcace, 0x0300) }, | 70 | { USB_DEVICE(0xcace, 0x0300) }, |
71 | /* D-Link DWA 160A */ | 71 | /* D-Link DWA 160 A1 */ |
72 | { USB_DEVICE(0x07d1, 0x3c10) }, | 72 | { USB_DEVICE(0x07d1, 0x3c10) }, |
73 | /* D-Link DWA 160 A2 */ | ||
74 | { USB_DEVICE(0x07d1, 0x3a09) }, | ||
73 | /* Netgear WNDA3100 */ | 75 | /* Netgear WNDA3100 */ |
74 | { USB_DEVICE(0x0846, 0x9010) }, | 76 | { USB_DEVICE(0x0846, 0x9010) }, |
75 | /* Netgear WN111 v2 */ | 77 | /* Netgear WN111 v2 */ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 721ec5ee381d..bbfdcd5e7cb1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -1399,7 +1399,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1399 | if (i_coffd == 0 || q_coffd == 0) | 1399 | if (i_coffd == 0 || q_coffd == 0) |
1400 | goto done; | 1400 | goto done; |
1401 | 1401 | ||
1402 | i_coff = ((-iq_corr) / i_coffd) & 0x3f; | 1402 | i_coff = ((-iq_corr) / i_coffd); |
1403 | 1403 | ||
1404 | /* Boundary check */ | 1404 | /* Boundary check */ |
1405 | if (i_coff > 31) | 1405 | if (i_coff > 31) |
@@ -1407,7 +1407,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1407 | if (i_coff < -32) | 1407 | if (i_coff < -32) |
1408 | i_coff = -32; | 1408 | i_coff = -32; |
1409 | 1409 | ||
1410 | q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f; | 1410 | q_coff = (((s32)i_pwr / q_coffd) - 128); |
1411 | 1411 | ||
1412 | /* Boundary check */ | 1412 | /* Boundary check */ |
1413 | if (q_coff > 15) | 1413 | if (q_coff > 15) |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d9bcc3abb425..2a40fa2cd914 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -198,18 +198,8 @@ struct ath_txq { | |||
198 | struct list_head axq_q; | 198 | struct list_head axq_q; |
199 | spinlock_t axq_lock; | 199 | spinlock_t axq_lock; |
200 | u32 axq_depth; | 200 | u32 axq_depth; |
201 | u8 axq_aggr_depth; | ||
202 | bool stopped; | 201 | bool stopped; |
203 | bool axq_tx_inprogress; | 202 | bool axq_tx_inprogress; |
204 | struct ath_buf *axq_linkbuf; | ||
205 | |||
206 | /* first desc of the last descriptor that contains CTS */ | ||
207 | struct ath_desc *axq_lastdsWithCTS; | ||
208 | |||
209 | /* final desc of the gating desc that determines whether | ||
210 | lastdsWithCTS has been DMA'ed or not */ | ||
211 | struct ath_desc *axq_gatingds; | ||
212 | |||
213 | struct list_head axq_acq; | 203 | struct list_head axq_acq; |
214 | }; | 204 | }; |
215 | 205 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 2f1e1612e2ad..4a13632e3e4d 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | |||
231 | { | 231 | { |
232 | struct ath_hw *ah = common->ah; | 232 | struct ath_hw *ah = common->ah; |
233 | struct ieee80211_hdr *hdr; | 233 | struct ieee80211_hdr *hdr; |
234 | int hdrlen, padsize; | 234 | int hdrlen, padpos, padsize; |
235 | u8 keyix; | 235 | u8 keyix; |
236 | __le16 fc; | 236 | __le16 fc; |
237 | 237 | ||
238 | /* see if any padding is done by the hw and remove it */ | 238 | /* see if any padding is done by the hw and remove it */ |
239 | hdr = (struct ieee80211_hdr *) skb->data; | 239 | hdr = (struct ieee80211_hdr *) skb->data; |
240 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 240 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
241 | padpos = 24; | ||
241 | fc = hdr->frame_control; | 242 | fc = hdr->frame_control; |
243 | if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) == | ||
244 | cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) { | ||
245 | padpos += 6; /* ETH_ALEN */ | ||
246 | } | ||
247 | if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) == | ||
248 | cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) { | ||
249 | padpos += 2; | ||
250 | } | ||
242 | 251 | ||
243 | /* The MAC header is padded to have 32-bit boundary if the | 252 | /* The MAC header is padded to have 32-bit boundary if the |
244 | * packet payload is non-zero. The general calculation for | 253 | * packet payload is non-zero. The general calculation for |
245 | * padsize would take into account odd header lengths: | 254 | * padsize would take into account odd header lengths: |
246 | * padsize = (4 - hdrlen % 4) % 4; However, since only | 255 | * padsize = (4 - padpos % 4) % 4; However, since only |
247 | * even-length headers are used, padding can only be 0 or 2 | 256 | * even-length headers are used, padding can only be 0 or 2 |
248 | * bytes and we can optimize this a bit. In addition, we must | 257 | * bytes and we can optimize this a bit. In addition, we must |
249 | * not try to remove padding from short control frames that do | 258 | * not try to remove padding from short control frames that do |
250 | * not have payload. */ | 259 | * not have payload. */ |
251 | padsize = hdrlen & 3; | 260 | padsize = padpos & 3; |
252 | if (padsize && hdrlen >= 24) { | 261 | if (padsize && skb->len>=padpos+padsize+FCS_LEN) { |
253 | memmove(skb->data + padsize, skb->data, hdrlen); | 262 | memmove(skb->data + padsize, skb->data, padpos); |
254 | skb_pull(skb, padsize); | 263 | skb_pull(skb, padsize); |
255 | } | 264 | } |
256 | 265 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 292e3d860c0e..4e1176029356 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -81,6 +81,7 @@ struct ath_buf { | |||
81 | u16 bf_flags; | 81 | u16 bf_flags; |
82 | struct ath_buf_state bf_state; | 82 | struct ath_buf_state bf_state; |
83 | dma_addr_t bf_dmacontext; | 83 | dma_addr_t bf_dmacontext; |
84 | struct ath_wiphy *aphy; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct ath_atx_tid { | 87 | struct ath_atx_tid { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 84f44269de47..06f1fcfb03e9 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -257,14 +257,17 @@ static const struct file_operations fops_interrupt = { | |||
257 | 257 | ||
258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) | 258 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) |
259 | { | 259 | { |
260 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
261 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 260 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
262 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 261 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
263 | int final_ts_idx, idx; | 262 | int final_ts_idx = 0, idx, i; |
264 | struct ath_rc_stats *stats; | 263 | struct ath_rc_stats *stats; |
265 | 264 | ||
266 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 265 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
267 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 266 | if (!rates[i].count) |
267 | break; | ||
268 | |||
269 | final_ts_idx = i; | ||
270 | } | ||
268 | idx = rates[final_ts_idx].idx; | 271 | idx = rates[final_ts_idx].idx; |
269 | stats = &sc->debug.stats.rcstats[idx]; | 272 | stats = &sc->debug.stats.rcstats[idx]; |
270 | stats->success++; | 273 | stats->success++; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b25eedf67e0b..53a7b980d8f6 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -390,8 +390,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
390 | ah->config.cck_trig_high = 200; | 390 | ah->config.cck_trig_high = 200; |
391 | ah->config.cck_trig_low = 100; | 391 | ah->config.cck_trig_low = 100; |
392 | ah->config.enable_ani = 1; | 392 | ah->config.enable_ani = 1; |
393 | ah->config.diversity_control = ATH9K_ANT_VARIABLE; | ||
394 | ah->config.antenna_switch_swap = 0; | ||
395 | 393 | ||
396 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 394 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
397 | ah->config.spurchans[i][0] = AR_NO_SPUR; | 395 | ah->config.spurchans[i][0] = AR_NO_SPUR; |
@@ -446,9 +444,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
446 | ah->acktimeout = (u32) -1; | 444 | ah->acktimeout = (u32) -1; |
447 | ah->ctstimeout = (u32) -1; | 445 | ah->ctstimeout = (u32) -1; |
448 | ah->globaltxtimeout = (u32) -1; | 446 | ah->globaltxtimeout = (u32) -1; |
449 | |||
450 | ah->gbeacon_rate = 0; | ||
451 | |||
452 | ah->power_mode = ATH9K_PM_UNDEFINED; | 447 | ah->power_mode = ATH9K_PM_UNDEFINED; |
453 | } | 448 | } |
454 | 449 | ||
@@ -1151,7 +1146,7 @@ static void ath9k_hw_init_chain_masks(struct ath_hw *ah) | |||
1151 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 1146 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
1152 | AR_PHY_SWAP_ALT_CHAIN); | 1147 | AR_PHY_SWAP_ALT_CHAIN); |
1153 | case 0x3: | 1148 | case 0x3: |
1154 | if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) { | 1149 | if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { |
1155 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | 1150 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); |
1156 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | 1151 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); |
1157 | break; | 1152 | break; |
@@ -2056,9 +2051,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2056 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); | 2051 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); |
2057 | ah->eep_ops->set_board_values(ah, chan); | 2052 | ah->eep_ops->set_board_values(ah, chan); |
2058 | 2053 | ||
2059 | if (AR_SREV_5416(ah)) | ||
2060 | ath9k_hw_decrease_chain_power(ah, chan); | ||
2061 | |||
2062 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 2054 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
2063 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) | 2055 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) |
2064 | | macStaId1 | 2056 | | macStaId1 |
@@ -3518,51 +3510,6 @@ void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | |||
3518 | } | 3510 | } |
3519 | EXPORT_SYMBOL(ath9k_hw_setantenna); | 3511 | EXPORT_SYMBOL(ath9k_hw_setantenna); |
3520 | 3512 | ||
3521 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
3522 | enum ath9k_ant_setting settings, | ||
3523 | struct ath9k_channel *chan, | ||
3524 | u8 *tx_chainmask, | ||
3525 | u8 *rx_chainmask, | ||
3526 | u8 *antenna_cfgd) | ||
3527 | { | ||
3528 | static u8 tx_chainmask_cfg, rx_chainmask_cfg; | ||
3529 | |||
3530 | if (AR_SREV_9280(ah)) { | ||
3531 | if (!tx_chainmask_cfg) { | ||
3532 | |||
3533 | tx_chainmask_cfg = *tx_chainmask; | ||
3534 | rx_chainmask_cfg = *rx_chainmask; | ||
3535 | } | ||
3536 | |||
3537 | switch (settings) { | ||
3538 | case ATH9K_ANT_FIXED_A: | ||
3539 | *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3540 | *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK; | ||
3541 | *antenna_cfgd = true; | ||
3542 | break; | ||
3543 | case ATH9K_ANT_FIXED_B: | ||
3544 | if (ah->caps.tx_chainmask > | ||
3545 | ATH9K_ANTENNA1_CHAINMASK) { | ||
3546 | *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3547 | } | ||
3548 | *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK; | ||
3549 | *antenna_cfgd = true; | ||
3550 | break; | ||
3551 | case ATH9K_ANT_VARIABLE: | ||
3552 | *tx_chainmask = tx_chainmask_cfg; | ||
3553 | *rx_chainmask = rx_chainmask_cfg; | ||
3554 | *antenna_cfgd = true; | ||
3555 | break; | ||
3556 | default: | ||
3557 | break; | ||
3558 | } | ||
3559 | } else { | ||
3560 | ah->config.diversity_control = settings; | ||
3561 | } | ||
3562 | |||
3563 | return true; | ||
3564 | } | ||
3565 | |||
3566 | /*********************/ | 3513 | /*********************/ |
3567 | /* General Operation */ | 3514 | /* General Operation */ |
3568 | /*********************/ | 3515 | /*********************/ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index abaa2f09a3bc..f8f5e997162c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -148,21 +148,6 @@ enum wireless_mode { | |||
148 | ATH9K_MODE_MAX, | 148 | ATH9K_MODE_MAX, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | /** | ||
152 | * ath9k_ant_setting - transmit antenna settings | ||
153 | * | ||
154 | * Configures the antenna setting to use for transmit. | ||
155 | * | ||
156 | * @ATH9K_ANT_VARIABLE: this means transmit on all active antennas | ||
157 | * @ATH9K_ANT_FIXED_A: this means transmit on the first antenna only | ||
158 | * @ATH9K_ANT_FIXED_B: this means transmit on the second antenna only | ||
159 | */ | ||
160 | enum ath9k_ant_setting { | ||
161 | ATH9K_ANT_VARIABLE = 0, | ||
162 | ATH9K_ANT_FIXED_A, | ||
163 | ATH9K_ANT_FIXED_B | ||
164 | }; | ||
165 | |||
166 | enum ath9k_hw_caps { | 151 | enum ath9k_hw_caps { |
167 | ATH9K_HW_CAP_MIC_AESCCM = BIT(0), | 152 | ATH9K_HW_CAP_MIC_AESCCM = BIT(0), |
168 | ATH9K_HW_CAP_MIC_CKIP = BIT(1), | 153 | ATH9K_HW_CAP_MIC_CKIP = BIT(1), |
@@ -226,8 +211,6 @@ struct ath9k_ops_config { | |||
226 | u32 cck_trig_high; | 211 | u32 cck_trig_high; |
227 | u32 cck_trig_low; | 212 | u32 cck_trig_low; |
228 | u32 enable_ani; | 213 | u32 enable_ani; |
229 | enum ath9k_ant_setting diversity_control; | ||
230 | u16 antenna_switch_swap; | ||
231 | int serialize_regmode; | 214 | int serialize_regmode; |
232 | bool intr_mitigation; | 215 | bool intr_mitigation; |
233 | #define SPUR_DISABLE 0 | 216 | #define SPUR_DISABLE 0 |
@@ -572,7 +555,6 @@ struct ath_hw { | |||
572 | u32 acktimeout; | 555 | u32 acktimeout; |
573 | u32 ctstimeout; | 556 | u32 ctstimeout; |
574 | u32 globaltxtimeout; | 557 | u32 globaltxtimeout; |
575 | u8 gbeacon_rate; | ||
576 | 558 | ||
577 | /* ANI */ | 559 | /* ANI */ |
578 | u32 proc_phyerr; | 560 | u32 proc_phyerr; |
@@ -659,11 +641,6 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | |||
659 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 641 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
660 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | 642 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); |
661 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 643 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
662 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | ||
663 | enum ath9k_ant_setting settings, | ||
664 | struct ath9k_channel *chan, | ||
665 | u8 *tx_chainmask, u8 *rx_chainmask, | ||
666 | u8 *antenna_cfgd); | ||
667 | 644 | ||
668 | /* General Operation */ | 645 | /* General Operation */ |
669 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 646 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3c02b977a613..cbf5d2a1bb26 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1893,6 +1893,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1893 | BIT(NL80211_IFTYPE_ADHOC) | | 1893 | BIT(NL80211_IFTYPE_ADHOC) | |
1894 | BIT(NL80211_IFTYPE_MESH_POINT); | 1894 | BIT(NL80211_IFTYPE_MESH_POINT); |
1895 | 1895 | ||
1896 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1897 | |||
1896 | hw->queues = 4; | 1898 | hw->queues = 4; |
1897 | hw->max_rates = 4; | 1899 | hw->max_rates = 4; |
1898 | hw->channel_change_time = 5000; | 1900 | hw->channel_change_time = 5000; |
@@ -2956,90 +2958,62 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2956 | struct ath_hw *ah = sc->sc_ah; | 2958 | struct ath_hw *ah = sc->sc_ah; |
2957 | struct ath_common *common = ath9k_hw_common(ah); | 2959 | struct ath_common *common = ath9k_hw_common(ah); |
2958 | struct ath_vif *avp = (void *)vif->drv_priv; | 2960 | struct ath_vif *avp = (void *)vif->drv_priv; |
2959 | u32 rfilt = 0; | 2961 | int error; |
2960 | int error, i; | ||
2961 | 2962 | ||
2962 | mutex_lock(&sc->mutex); | 2963 | mutex_lock(&sc->mutex); |
2963 | 2964 | ||
2964 | /* | 2965 | if (changed & BSS_CHANGED_BSSID) { |
2965 | * TODO: Need to decide which hw opmode to use for | 2966 | /* Set BSSID */ |
2966 | * multi-interface cases | 2967 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
2967 | * XXX: This belongs into add_interface! | 2968 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); |
2968 | */ | ||
2969 | if (vif->type == NL80211_IFTYPE_AP && | ||
2970 | ah->opmode != NL80211_IFTYPE_AP) { | ||
2971 | ah->opmode = NL80211_IFTYPE_STATION; | ||
2972 | ath9k_hw_setopmode(ah); | ||
2973 | memcpy(common->curbssid, common->macaddr, ETH_ALEN); | ||
2974 | common->curaid = 0; | 2969 | common->curaid = 0; |
2975 | ath9k_hw_write_associd(ah); | 2970 | ath9k_hw_write_associd(ah); |
2976 | /* Request full reset to get hw opmode changed properly */ | ||
2977 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
2978 | } | ||
2979 | 2971 | ||
2980 | if ((changed & BSS_CHANGED_BSSID) && | 2972 | /* Set aggregation protection mode parameters */ |
2981 | !is_zero_ether_addr(bss_conf->bssid)) { | 2973 | sc->config.ath_aggr_prot = 0; |
2982 | switch (vif->type) { | ||
2983 | case NL80211_IFTYPE_STATION: | ||
2984 | case NL80211_IFTYPE_ADHOC: | ||
2985 | case NL80211_IFTYPE_MESH_POINT: | ||
2986 | /* Set BSSID */ | ||
2987 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
2988 | memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); | ||
2989 | common->curaid = 0; | ||
2990 | ath9k_hw_write_associd(ah); | ||
2991 | 2974 | ||
2992 | /* Set aggregation protection mode parameters */ | 2975 | /* Only legacy IBSS for now */ |
2993 | sc->config.ath_aggr_prot = 0; | 2976 | if (vif->type == NL80211_IFTYPE_ADHOC) |
2977 | ath_update_chainmask(sc, 0); | ||
2994 | 2978 | ||
2995 | ath_print(common, ATH_DBG_CONFIG, | 2979 | ath_print(common, ATH_DBG_CONFIG, |
2996 | "RX filter 0x%x bssid %pM aid 0x%x\n", | 2980 | "BSSID: %pM aid: 0x%x\n", |
2997 | rfilt, common->curbssid, common->curaid); | 2981 | common->curbssid, common->curaid); |
2998 | 2982 | ||
2999 | /* need to reconfigure the beacon */ | 2983 | /* need to reconfigure the beacon */ |
3000 | sc->sc_flags &= ~SC_OP_BEACONS ; | 2984 | sc->sc_flags &= ~SC_OP_BEACONS ; |
2985 | } | ||
3001 | 2986 | ||
3002 | break; | 2987 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
3003 | default: | 2988 | if ((changed & BSS_CHANGED_BEACON) || |
3004 | break; | 2989 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
3005 | } | 2990 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2991 | error = ath_beacon_alloc(aphy, vif); | ||
2992 | if (!error) | ||
2993 | ath_beacon_config(sc, vif); | ||
3006 | } | 2994 | } |
3007 | 2995 | ||
3008 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 2996 | /* Disable transmission of beacons */ |
3009 | (vif->type == NL80211_IFTYPE_AP) || | 2997 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) |
3010 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 2998 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
3011 | if ((changed & BSS_CHANGED_BEACON) || | ||
3012 | (changed & BSS_CHANGED_BEACON_ENABLED && | ||
3013 | bss_conf->enable_beacon)) { | ||
3014 | /* | ||
3015 | * Allocate and setup the beacon frame. | ||
3016 | * | ||
3017 | * Stop any previous beacon DMA. This may be | ||
3018 | * necessary, for example, when an ibss merge | ||
3019 | * causes reconfiguration; we may be called | ||
3020 | * with beacon transmission active. | ||
3021 | */ | ||
3022 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3023 | 2999 | ||
3000 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3001 | sc->beacon_interval = bss_conf->beacon_int; | ||
3002 | /* | ||
3003 | * In case of AP mode, the HW TSF has to be reset | ||
3004 | * when the beacon interval changes. | ||
3005 | */ | ||
3006 | if (vif->type == NL80211_IFTYPE_AP) { | ||
3007 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3008 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
3024 | error = ath_beacon_alloc(aphy, vif); | 3009 | error = ath_beacon_alloc(aphy, vif); |
3025 | if (!error) | 3010 | if (!error) |
3026 | ath_beacon_config(sc, vif); | 3011 | ath_beacon_config(sc, vif); |
3012 | } else { | ||
3013 | ath_beacon_config(sc, vif); | ||
3027 | } | 3014 | } |
3028 | } | 3015 | } |
3029 | 3016 | ||
3030 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | ||
3031 | if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { | ||
3032 | for (i = 0; i < IEEE80211_WEP_NKID; i++) | ||
3033 | if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) | ||
3034 | ath9k_hw_keysetmac(sc->sc_ah, | ||
3035 | (u16)i, | ||
3036 | common->curbssid); | ||
3037 | } | ||
3038 | |||
3039 | /* Only legacy IBSS for now */ | ||
3040 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
3041 | ath_update_chainmask(sc, 0); | ||
3042 | |||
3043 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 3017 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
3044 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 3018 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", |
3045 | bss_conf->use_short_preamble); | 3019 | bss_conf->use_short_preamble); |
@@ -3065,18 +3039,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
3065 | ath9k_bss_assoc_info(sc, vif, bss_conf); | 3039 | ath9k_bss_assoc_info(sc, vif, bss_conf); |
3066 | } | 3040 | } |
3067 | 3041 | ||
3068 | /* | ||
3069 | * The HW TSF has to be reset when the beacon interval changes. | ||
3070 | * We set the flag here, and ath_beacon_config_ap() would take this | ||
3071 | * into account when it gets called through the subsequent | ||
3072 | * config_interface() call - with IFCC_BEACON in the changed field. | ||
3073 | */ | ||
3074 | |||
3075 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
3076 | sc->sc_flags |= SC_OP_TSF_RESET; | ||
3077 | sc->beacon_interval = bss_conf->beacon_int; | ||
3078 | } | ||
3079 | |||
3080 | mutex_unlock(&sc->mutex); | 3042 | mutex_unlock(&sc->mutex); |
3081 | } | 3043 | } |
3082 | 3044 | ||
@@ -3118,6 +3080,7 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) | |||
3118 | } | 3080 | } |
3119 | 3081 | ||
3120 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 3082 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
3083 | struct ieee80211_vif *vif, | ||
3121 | enum ieee80211_ampdu_mlme_action action, | 3084 | enum ieee80211_ampdu_mlme_action action, |
3122 | struct ieee80211_sta *sta, | 3085 | struct ieee80211_sta *sta, |
3123 | u16 tid, u16 *ssn) | 3086 | u16 tid, u16 *ssn) |
@@ -3135,11 +3098,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
3135 | break; | 3098 | break; |
3136 | case IEEE80211_AMPDU_TX_START: | 3099 | case IEEE80211_AMPDU_TX_START: |
3137 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3100 | ath_tx_aggr_start(sc, sta, tid, ssn); |
3138 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3101 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3139 | break; | 3102 | break; |
3140 | case IEEE80211_AMPDU_TX_STOP: | 3103 | case IEEE80211_AMPDU_TX_STOP: |
3141 | ath_tx_aggr_stop(sc, sta, tid); | 3104 | ath_tx_aggr_stop(sc, sta, tid); |
3142 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3105 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3143 | break; | 3106 | break; |
3144 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3107 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3145 | ath_tx_aggr_resume(sc, sta, tid); | 3108 | ath_tx_aggr_resume(sc, sta, tid); |
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c index 13ab4d7eb7aa..c3b59390fe38 100644 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ b/drivers/net/wireless/ath/ath9k/phy.c | |||
@@ -528,95 +528,6 @@ static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | |||
528 | } | 528 | } |
529 | 529 | ||
530 | /** | 530 | /** |
531 | * ath9k_hw_decrease_chain_power() | ||
532 | * | ||
533 | * @ah: atheros hardware structure | ||
534 | * @chan: | ||
535 | * | ||
536 | * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios. | ||
537 | * | ||
538 | * Sets a chain internal RF path to the lowest output power. Any | ||
539 | * further writes to bank6 after this setting will override these | ||
540 | * changes. Thus this function must be the last function in the | ||
541 | * sequence to modify bank 6. | ||
542 | * | ||
543 | * This function must be called after ar5416SetRfRegs() which is | ||
544 | * called from ath9k_hw_process_ini() due to swizzling of bank 6. | ||
545 | * Depends on ah->analogBank6Data being initialized by | ||
546 | * ath9k_hw_set_rf_regs() | ||
547 | * | ||
548 | * Additional additive reduction in power - | ||
549 | * change chain's switch table so chain's tx state is actually the rx | ||
550 | * state value. May produce different results in 2GHz/5GHz as well as | ||
551 | * board to board but in general should be a reduction. | ||
552 | * | ||
553 | * Activated by #ifdef ALTER_SWITCH. Not tried yet. If so, must be | ||
554 | * called after ah->eep_ops->set_board_values() due to RMW of | ||
555 | * PHY_SWITCH_CHAIN_0. | ||
556 | */ | ||
557 | void ath9k_hw_decrease_chain_power(struct ath_hw *ah, | ||
558 | struct ath9k_channel *chan) | ||
559 | { | ||
560 | int i, regWrites = 0; | ||
561 | u32 bank6SelMask; | ||
562 | u32 *bank6Temp = ah->bank6Temp; | ||
563 | |||
564 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
565 | |||
566 | switch (ah->config.diversity_control) { | ||
567 | case ATH9K_ANT_FIXED_A: | ||
568 | bank6SelMask = | ||
569 | (ah->config.antenna_switch_swap & ANTSWAP_AB) ? | ||
570 | REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */ | ||
571 | REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */ | ||
572 | break; | ||
573 | case ATH9K_ANT_FIXED_B: | ||
574 | bank6SelMask = | ||
575 | (ah->config.antenna_switch_swap & ANTSWAP_AB) ? | ||
576 | REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */ | ||
577 | REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */ | ||
578 | break; | ||
579 | case ATH9K_ANT_VARIABLE: | ||
580 | return; /* do not change anything */ | ||
581 | break; | ||
582 | default: | ||
583 | return; /* do not change anything */ | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | for (i = 0; i < ah->iniBank6.ia_rows; i++) | ||
588 | bank6Temp[i] = ah->analogBank6Data[i]; | ||
589 | |||
590 | /* Write Bank 5 to switch Bank 6 write to selected chain only */ | ||
591 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask); | ||
592 | |||
593 | /* | ||
594 | * Modify Bank6 selected chain to use lowest amplification. | ||
595 | * Modifies the parameters to a value of 1. | ||
596 | * Depends on existing bank 6 values to be cached in | ||
597 | * ah->analogBank6Data | ||
598 | */ | ||
599 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0); | ||
600 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0); | ||
601 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0); | ||
602 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0); | ||
603 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0); | ||
604 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0); | ||
605 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0); | ||
606 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0); | ||
607 | ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0); | ||
608 | |||
609 | REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites); | ||
610 | |||
611 | REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053); | ||
612 | #ifdef ALTER_SWITCH | ||
613 | REG_WRITE(ah, PHY_SWITCH_CHAIN_0, | ||
614 | (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38) | ||
615 | | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38)); | ||
616 | #endif | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios | 531 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios |
621 | * @ah: atheros hardware stucture | 532 | * @ah: atheros hardware stucture |
622 | * @chan: | 533 | * @chan: |
@@ -687,7 +598,6 @@ int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
687 | } | 598 | } |
688 | 599 | ||
689 | ath9k_hw_force_bias(ah, freq); | 600 | ath9k_hw_force_bias(ah, freq); |
690 | ath9k_hw_decrease_chain_power(ah, chan); | ||
691 | 601 | ||
692 | reg32 = | 602 | reg32 = |
693 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | 603 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index dc145a135dc7..31de27dc0c4a 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -35,9 +35,6 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | |||
35 | struct ath9k_channel *chan, | 35 | struct ath9k_channel *chan, |
36 | u16 modesIndex); | 36 | u16 modesIndex); |
37 | 37 | ||
38 | void ath9k_hw_decrease_chain_power(struct ath_hw *ah, | ||
39 | struct ath9k_channel *chan); | ||
40 | |||
41 | #define AR_PHY_BASE 0x9800 | 38 | #define AR_PHY_BASE 0x9800 |
42 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) | 39 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) |
43 | 40 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index bb72b46567f9..1d96777b4cd2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -859,12 +859,12 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
859 | static bool ath_rc_update_per(struct ath_softc *sc, | 859 | static bool ath_rc_update_per(struct ath_softc *sc, |
860 | const struct ath_rate_table *rate_table, | 860 | const struct ath_rate_table *rate_table, |
861 | struct ath_rate_priv *ath_rc_priv, | 861 | struct ath_rate_priv *ath_rc_priv, |
862 | struct ath_tx_info_priv *tx_info_priv, | 862 | struct ieee80211_tx_info *tx_info, |
863 | int tx_rate, int xretries, int retries, | 863 | int tx_rate, int xretries, int retries, |
864 | u32 now_msec) | 864 | u32 now_msec) |
865 | { | 865 | { |
866 | bool state_change = false; | 866 | bool state_change = false; |
867 | int count; | 867 | int count, n_bad_frames; |
868 | u8 last_per; | 868 | u8 last_per; |
869 | static u32 nretry_to_per_lookup[10] = { | 869 | static u32 nretry_to_per_lookup[10] = { |
870 | 100 * 0 / 1, | 870 | 100 * 0 / 1, |
@@ -880,6 +880,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
880 | }; | 880 | }; |
881 | 881 | ||
882 | last_per = ath_rc_priv->per[tx_rate]; | 882 | last_per = ath_rc_priv->per[tx_rate]; |
883 | n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len; | ||
883 | 884 | ||
884 | if (xretries) { | 885 | if (xretries) { |
885 | if (xretries == 1) { | 886 | if (xretries == 1) { |
@@ -907,7 +908,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
907 | if (retries >= count) | 908 | if (retries >= count) |
908 | retries = count - 1; | 909 | retries = count - 1; |
909 | 910 | ||
910 | if (tx_info_priv->n_bad_frames) { | 911 | if (n_bad_frames) { |
911 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) | 912 | /* new_PER = 7/8*old_PER + 1/8*(currentPER) |
912 | * Assuming that n_frames is not 0. The current PER | 913 | * Assuming that n_frames is not 0. The current PER |
913 | * from the retries is 100 * retries / (retries+1), | 914 | * from the retries is 100 * retries / (retries+1), |
@@ -920,14 +921,14 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
920 | * the above PER. The expression below is a | 921 | * the above PER. The expression below is a |
921 | * simplified version of the sum of these two terms. | 922 | * simplified version of the sum of these two terms. |
922 | */ | 923 | */ |
923 | if (tx_info_priv->n_frames > 0) { | 924 | if (tx_info->status.ampdu_len > 0) { |
924 | int n_frames, n_bad_frames; | 925 | int n_frames, n_bad_tries; |
925 | u8 cur_per, new_per; | 926 | u8 cur_per, new_per; |
926 | 927 | ||
927 | n_bad_frames = retries * tx_info_priv->n_frames + | 928 | n_bad_tries = retries * tx_info->status.ampdu_len + |
928 | tx_info_priv->n_bad_frames; | 929 | n_bad_frames; |
929 | n_frames = tx_info_priv->n_frames * (retries + 1); | 930 | n_frames = tx_info->status.ampdu_len * (retries + 1); |
930 | cur_per = (100 * n_bad_frames / n_frames) >> 3; | 931 | cur_per = (100 * n_bad_tries / n_frames) >> 3; |
931 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); | 932 | new_per = (u8)(last_per - (last_per >> 3) + cur_per); |
932 | ath_rc_priv->per[tx_rate] = new_per; | 933 | ath_rc_priv->per[tx_rate] = new_per; |
933 | } | 934 | } |
@@ -943,8 +944,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
943 | * this was a probe. Otherwise, ignore the probe. | 944 | * this was a probe. Otherwise, ignore the probe. |
944 | */ | 945 | */ |
945 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { | 946 | if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { |
946 | if (retries > 0 || 2 * tx_info_priv->n_bad_frames > | 947 | if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) { |
947 | tx_info_priv->n_frames) { | ||
948 | /* | 948 | /* |
949 | * Since we probed with just a single attempt, | 949 | * Since we probed with just a single attempt, |
950 | * any retries means the probe failed. Also, | 950 | * any retries means the probe failed. Also, |
@@ -1003,7 +1003,7 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
1003 | 1003 | ||
1004 | static void ath_rc_update_ht(struct ath_softc *sc, | 1004 | static void ath_rc_update_ht(struct ath_softc *sc, |
1005 | struct ath_rate_priv *ath_rc_priv, | 1005 | struct ath_rate_priv *ath_rc_priv, |
1006 | struct ath_tx_info_priv *tx_info_priv, | 1006 | struct ieee80211_tx_info *tx_info, |
1007 | int tx_rate, int xretries, int retries) | 1007 | int tx_rate, int xretries, int retries) |
1008 | { | 1008 | { |
1009 | u32 now_msec = jiffies_to_msecs(jiffies); | 1009 | u32 now_msec = jiffies_to_msecs(jiffies); |
@@ -1020,7 +1020,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1020 | 1020 | ||
1021 | /* Update PER first */ | 1021 | /* Update PER first */ |
1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | 1022 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, |
1023 | tx_info_priv, tx_rate, xretries, | 1023 | tx_info, tx_rate, xretries, |
1024 | retries, now_msec); | 1024 | retries, now_msec); |
1025 | 1025 | ||
1026 | /* | 1026 | /* |
@@ -1098,7 +1098,6 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1098 | struct ieee80211_tx_info *tx_info, | 1098 | struct ieee80211_tx_info *tx_info, |
1099 | int final_ts_idx, int xretries, int long_retry) | 1099 | int final_ts_idx, int xretries, int long_retry) |
1100 | { | 1100 | { |
1101 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1102 | const struct ath_rate_table *rate_table; | 1101 | const struct ath_rate_table *rate_table; |
1103 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | 1102 | struct ieee80211_tx_rate *rates = tx_info->status.rates; |
1104 | u8 flags; | 1103 | u8 flags; |
@@ -1124,9 +1123,8 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1124 | return; | 1123 | return; |
1125 | 1124 | ||
1126 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1125 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1127 | ath_rc_update_ht(sc, ath_rc_priv, | 1126 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, |
1128 | tx_info_priv, rix, | 1127 | rix, xretries ? 1 : 2, |
1129 | xretries ? 1 : 2, | ||
1130 | rates[i].count); | 1128 | rates[i].count); |
1131 | } | 1129 | } |
1132 | } | 1130 | } |
@@ -1149,8 +1147,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, | |||
1149 | return; | 1147 | return; |
1150 | 1148 | ||
1151 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); | 1149 | rix = ath_rc_get_rateindex(rate_table, &rates[i]); |
1152 | ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, | 1150 | ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry); |
1153 | xretries, long_retry); | ||
1154 | } | 1151 | } |
1155 | 1152 | ||
1156 | static const | 1153 | static const |
@@ -1301,23 +1298,30 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1301 | { | 1298 | { |
1302 | struct ath_softc *sc = priv; | 1299 | struct ath_softc *sc = priv; |
1303 | struct ath_rate_priv *ath_rc_priv = priv_sta; | 1300 | struct ath_rate_priv *ath_rc_priv = priv_sta; |
1304 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
1305 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1301 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1306 | struct ieee80211_hdr *hdr; | 1302 | struct ieee80211_hdr *hdr; |
1307 | int final_ts_idx, tx_status = 0, is_underrun = 0; | 1303 | int final_ts_idx = 0, tx_status = 0, is_underrun = 0; |
1304 | int long_retry = 0; | ||
1308 | __le16 fc; | 1305 | __le16 fc; |
1306 | int i; | ||
1309 | 1307 | ||
1310 | hdr = (struct ieee80211_hdr *)skb->data; | 1308 | hdr = (struct ieee80211_hdr *)skb->data; |
1311 | fc = hdr->frame_control; | 1309 | fc = hdr->frame_control; |
1312 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1310 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
1313 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | 1311 | struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; |
1312 | if (!rate->count) | ||
1313 | break; | ||
1314 | |||
1315 | final_ts_idx = i; | ||
1316 | long_retry = rate->count - 1; | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if (!priv_sta || !ieee80211_is_data(fc) || | 1319 | if (!priv_sta || !ieee80211_is_data(fc) || |
1316 | !tx_info_priv->update_rc) | 1320 | !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) |
1317 | goto exit; | 1321 | return; |
1318 | 1322 | ||
1319 | if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) | 1323 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) |
1320 | goto exit; | 1324 | return; |
1321 | 1325 | ||
1322 | /* | 1326 | /* |
1323 | * If underrun error is seen assume it as an excessive retry only | 1327 | * If underrun error is seen assume it as an excessive retry only |
@@ -1325,20 +1329,17 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1325 | * Adjust the long retry as if the frame was tried hw->max_rate_tries | 1329 | * Adjust the long retry as if the frame was tried hw->max_rate_tries |
1326 | * times. This affects how ratectrl updates PER for the failed rate. | 1330 | * times. This affects how ratectrl updates PER for the failed rate. |
1327 | */ | 1331 | */ |
1328 | if (tx_info_priv->tx.ts_flags & | 1332 | if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) && |
1329 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && | 1333 | (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) { |
1330 | ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) { | ||
1331 | tx_status = 1; | 1334 | tx_status = 1; |
1332 | is_underrun = 1; | 1335 | is_underrun = 1; |
1333 | } | 1336 | } |
1334 | 1337 | ||
1335 | if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || | 1338 | if (tx_info->pad[0] & ATH_TX_INFO_XRETRY) |
1336 | (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) | ||
1337 | tx_status = 1; | 1339 | tx_status = 1; |
1338 | 1340 | ||
1339 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, | 1341 | ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, |
1340 | (is_underrun) ? sc->hw->max_rate_tries : | 1342 | (is_underrun) ? sc->hw->max_rate_tries : long_retry); |
1341 | tx_info_priv->tx.ts_longretry); | ||
1342 | 1343 | ||
1343 | /* Check if aggregation has to be enabled for this tid */ | 1344 | /* Check if aggregation has to be enabled for this tid */ |
1344 | if (conf_is_ht(&sc->hw->conf) && | 1345 | if (conf_is_ht(&sc->hw->conf) && |
@@ -1352,13 +1353,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1352 | an = (struct ath_node *)sta->drv_priv; | 1353 | an = (struct ath_node *)sta->drv_priv; |
1353 | 1354 | ||
1354 | if(ath_tx_aggr_check(sc, an, tid)) | 1355 | if(ath_tx_aggr_check(sc, an, tid)) |
1355 | ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid); | 1356 | ieee80211_start_tx_ba_session(sta, tid); |
1356 | } | 1357 | } |
1357 | } | 1358 | } |
1358 | 1359 | ||
1359 | ath_debug_stat_rc(sc, skb); | 1360 | ath_debug_stat_rc(sc, skb); |
1360 | exit: | ||
1361 | kfree(tx_info_priv); | ||
1362 | } | 1361 | } |
1363 | 1362 | ||
1364 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | 1363 | static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 94cb9f8d2446..51f85ecbe88d 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -167,24 +167,18 @@ struct ath_rate_priv { | |||
167 | struct ath_rate_softc *asc; | 167 | struct ath_rate_softc *asc; |
168 | }; | 168 | }; |
169 | 169 | ||
170 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) | ||
171 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) | ||
172 | #define ATH_TX_INFO_UPDATE_RC (1 << 2) | ||
173 | #define ATH_TX_INFO_XRETRY (1 << 3) | ||
174 | #define ATH_TX_INFO_UNDERRUN (1 << 4) | ||
175 | |||
170 | enum ath9k_internal_frame_type { | 176 | enum ath9k_internal_frame_type { |
171 | ATH9K_NOT_INTERNAL, | 177 | ATH9K_NOT_INTERNAL, |
172 | ATH9K_INT_PAUSE, | 178 | ATH9K_INT_PAUSE, |
173 | ATH9K_INT_UNPAUSE | 179 | ATH9K_INT_UNPAUSE |
174 | }; | 180 | }; |
175 | 181 | ||
176 | struct ath_tx_info_priv { | ||
177 | struct ath_wiphy *aphy; | ||
178 | struct ath_tx_status tx; | ||
179 | int n_frames; | ||
180 | int n_bad_frames; | ||
181 | bool update_rc; | ||
182 | enum ath9k_internal_frame_type frame_type; | ||
183 | }; | ||
184 | |||
185 | #define ATH_TX_INFO_PRIV(tx_info) \ | ||
186 | ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0])) | ||
187 | |||
188 | void ath_rate_attach(struct ath_softc *sc); | 182 | void ath_rate_attach(struct ath_softc *sc); |
189 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); | 183 | u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate); |
190 | int ath_rate_control_register(void); | 184 | int ath_rate_control_register(void); |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 0a36b572294c..cd26caaf44e7 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -338,13 +338,11 @@ void ath9k_wiphy_chan_work(struct work_struct *work) | |||
338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | 338 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
339 | { | 339 | { |
340 | struct ath_wiphy *aphy = hw->priv; | 340 | struct ath_wiphy *aphy = hw->priv; |
341 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
342 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 341 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
343 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
344 | 342 | ||
345 | if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE && | 343 | if ((tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_PAUSE) && |
346 | aphy->state == ATH_WIPHY_PAUSING) { | 344 | aphy->state == ATH_WIPHY_PAUSING) { |
347 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { | 345 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { |
348 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " | 346 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " |
349 | "frame\n", wiphy_name(hw->wiphy)); | 347 | "frame\n", wiphy_name(hw->wiphy)); |
350 | /* | 348 | /* |
@@ -363,9 +361,6 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
363 | } | 361 | } |
364 | } | 362 | } |
365 | 363 | ||
366 | kfree(tx_info_priv); | ||
367 | tx_info->rate_driver_data[0] = NULL; | ||
368 | |||
369 | dev_kfree_skb(skb); | 364 | dev_kfree_skb(skb); |
370 | } | 365 | } |
371 | 366 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 86b54ddd01cb..745d91995d78 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -251,6 +251,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
251 | 251 | ||
252 | ATH_TXBUF_RESET(tbf); | 252 | ATH_TXBUF_RESET(tbf); |
253 | 253 | ||
254 | tbf->aphy = bf->aphy; | ||
254 | tbf->bf_mpdu = bf->bf_mpdu; | 255 | tbf->bf_mpdu = bf->bf_mpdu; |
255 | tbf->bf_buf_addr = bf->bf_buf_addr; | 256 | tbf->bf_buf_addr = bf->bf_buf_addr; |
256 | *(tbf->bf_desc) = *(bf->bf_desc); | 257 | *(tbf->bf_desc) = *(bf->bf_desc); |
@@ -270,7 +271,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
270 | struct ieee80211_hw *hw; | 271 | struct ieee80211_hw *hw; |
271 | struct ieee80211_hdr *hdr; | 272 | struct ieee80211_hdr *hdr; |
272 | struct ieee80211_tx_info *tx_info; | 273 | struct ieee80211_tx_info *tx_info; |
273 | struct ath_tx_info_priv *tx_info_priv; | ||
274 | struct ath_atx_tid *tid = NULL; | 274 | struct ath_atx_tid *tid = NULL; |
275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
276 | struct ath_desc *ds = bf_last->bf_desc; | 276 | struct ath_desc *ds = bf_last->bf_desc; |
@@ -284,8 +284,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
284 | hdr = (struct ieee80211_hdr *)skb->data; | 284 | hdr = (struct ieee80211_hdr *)skb->data; |
285 | 285 | ||
286 | tx_info = IEEE80211_SKB_CB(skb); | 286 | tx_info = IEEE80211_SKB_CB(skb); |
287 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0]; | 287 | hw = bf->aphy->hw; |
288 | hw = tx_info_priv->aphy->hw; | ||
289 | 288 | ||
290 | rcu_read_lock(); | 289 | rcu_read_lock(); |
291 | 290 | ||
@@ -464,7 +463,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
464 | struct sk_buff *skb; | 463 | struct sk_buff *skb; |
465 | struct ieee80211_tx_info *tx_info; | 464 | struct ieee80211_tx_info *tx_info; |
466 | struct ieee80211_tx_rate *rates; | 465 | struct ieee80211_tx_rate *rates; |
467 | struct ath_tx_info_priv *tx_info_priv; | ||
468 | u32 max_4ms_framelen, frmlen; | 466 | u32 max_4ms_framelen, frmlen; |
469 | u16 aggr_limit, legacy = 0; | 467 | u16 aggr_limit, legacy = 0; |
470 | int i; | 468 | int i; |
@@ -472,7 +470,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
472 | skb = bf->bf_mpdu; | 470 | skb = bf->bf_mpdu; |
473 | tx_info = IEEE80211_SKB_CB(skb); | 471 | tx_info = IEEE80211_SKB_CB(skb); |
474 | rates = tx_info->control.rates; | 472 | rates = tx_info->control.rates; |
475 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
476 | 473 | ||
477 | /* | 474 | /* |
478 | * Find the lowest frame length among the rate series that will have a | 475 | * Find the lowest frame length among the rate series that will have a |
@@ -702,7 +699,6 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
702 | /* anchor last desc of aggregate */ | 699 | /* anchor last desc of aggregate */ |
703 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | 700 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
704 | 701 | ||
705 | txq->axq_aggr_depth++; | ||
706 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 702 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
707 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 703 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
708 | 704 | ||
@@ -878,8 +874,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
878 | INIT_LIST_HEAD(&txq->axq_acq); | 874 | INIT_LIST_HEAD(&txq->axq_acq); |
879 | spin_lock_init(&txq->axq_lock); | 875 | spin_lock_init(&txq->axq_lock); |
880 | txq->axq_depth = 0; | 876 | txq->axq_depth = 0; |
881 | txq->axq_aggr_depth = 0; | ||
882 | txq->axq_linkbuf = NULL; | ||
883 | txq->axq_tx_inprogress = false; | 877 | txq->axq_tx_inprogress = false; |
884 | sc->tx.txqsetup |= 1<<qnum; | 878 | sc->tx.txqsetup |= 1<<qnum; |
885 | } | 879 | } |
@@ -1014,7 +1008,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1014 | 1008 | ||
1015 | if (list_empty(&txq->axq_q)) { | 1009 | if (list_empty(&txq->axq_q)) { |
1016 | txq->axq_link = NULL; | 1010 | txq->axq_link = NULL; |
1017 | txq->axq_linkbuf = NULL; | ||
1018 | spin_unlock_bh(&txq->axq_lock); | 1011 | spin_unlock_bh(&txq->axq_lock); |
1019 | break; | 1012 | break; |
1020 | } | 1013 | } |
@@ -1199,7 +1192,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1199 | 1192 | ||
1200 | list_splice_tail_init(head, &txq->axq_q); | 1193 | list_splice_tail_init(head, &txq->axq_q); |
1201 | txq->axq_depth++; | 1194 | txq->axq_depth++; |
1202 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
1203 | 1195 | ||
1204 | ath_print(common, ATH_DBG_QUEUE, | 1196 | ath_print(common, ATH_DBG_QUEUE, |
1205 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1197 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
@@ -1560,21 +1552,26 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1560 | struct ath_softc *sc = aphy->sc; | 1552 | struct ath_softc *sc = aphy->sc; |
1561 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1553 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1562 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1554 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1563 | struct ath_tx_info_priv *tx_info_priv; | ||
1564 | int hdrlen; | 1555 | int hdrlen; |
1565 | __le16 fc; | 1556 | __le16 fc; |
1566 | 1557 | ||
1567 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | 1558 | tx_info->pad[0] = 0; |
1568 | if (unlikely(!tx_info_priv)) | 1559 | switch (txctl->frame_type) { |
1569 | return -ENOMEM; | 1560 | case ATH9K_NOT_INTERNAL: |
1570 | tx_info->rate_driver_data[0] = tx_info_priv; | 1561 | break; |
1571 | tx_info_priv->aphy = aphy; | 1562 | case ATH9K_INT_PAUSE: |
1572 | tx_info_priv->frame_type = txctl->frame_type; | 1563 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; |
1564 | /* fall through */ | ||
1565 | case ATH9K_INT_UNPAUSE: | ||
1566 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | ||
1567 | break; | ||
1568 | } | ||
1573 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1569 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1574 | fc = hdr->frame_control; | 1570 | fc = hdr->frame_control; |
1575 | 1571 | ||
1576 | ATH_TXBUF_RESET(bf); | 1572 | ATH_TXBUF_RESET(bf); |
1577 | 1573 | ||
1574 | bf->aphy = aphy; | ||
1578 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | 1575 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); |
1579 | 1576 | ||
1580 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) | 1577 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) |
@@ -1599,8 +1596,6 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1599 | skb->len, DMA_TO_DEVICE); | 1596 | skb->len, DMA_TO_DEVICE); |
1600 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | 1597 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { |
1601 | bf->bf_mpdu = NULL; | 1598 | bf->bf_mpdu = NULL; |
1602 | kfree(tx_info_priv); | ||
1603 | tx_info->rate_driver_data[0] = NULL; | ||
1604 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 1599 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
1605 | "dma_mapping_error() on TX\n"); | 1600 | "dma_mapping_error() on TX\n"); |
1606 | return -ENOMEM; | 1601 | return -ENOMEM; |
@@ -1781,27 +1776,17 @@ exit: | |||
1781 | /*****************/ | 1776 | /*****************/ |
1782 | 1777 | ||
1783 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1778 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1784 | int tx_flags) | 1779 | struct ath_wiphy *aphy, int tx_flags) |
1785 | { | 1780 | { |
1786 | struct ieee80211_hw *hw = sc->hw; | 1781 | struct ieee80211_hw *hw = sc->hw; |
1787 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1782 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1788 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1789 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1783 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1790 | int hdrlen, padsize; | 1784 | int hdrlen, padsize; |
1791 | int frame_type = ATH9K_NOT_INTERNAL; | ||
1792 | 1785 | ||
1793 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1786 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1794 | 1787 | ||
1795 | if (tx_info_priv) { | 1788 | if (aphy) |
1796 | hw = tx_info_priv->aphy->hw; | 1789 | hw = aphy->hw; |
1797 | frame_type = tx_info_priv->frame_type; | ||
1798 | } | ||
1799 | |||
1800 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1801 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1802 | kfree(tx_info_priv); | ||
1803 | tx_info->rate_driver_data[0] = NULL; | ||
1804 | } | ||
1805 | 1790 | ||
1806 | if (tx_flags & ATH_TX_BAR) | 1791 | if (tx_flags & ATH_TX_BAR) |
1807 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1792 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
@@ -1833,10 +1818,10 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1833 | SC_OP_WAIT_FOR_TX_ACK)); | 1818 | SC_OP_WAIT_FOR_TX_ACK)); |
1834 | } | 1819 | } |
1835 | 1820 | ||
1836 | if (frame_type == ATH9K_NOT_INTERNAL) | 1821 | if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
1837 | ieee80211_tx_status(hw, skb); | ||
1838 | else | ||
1839 | ath9k_tx_status(hw, skb); | 1822 | ath9k_tx_status(hw, skb); |
1823 | else | ||
1824 | ieee80211_tx_status(hw, skb); | ||
1840 | } | 1825 | } |
1841 | 1826 | ||
1842 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1827 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1859,7 +1844,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1859 | } | 1844 | } |
1860 | 1845 | ||
1861 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1846 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1862 | ath_tx_complete(sc, skb, tx_flags); | 1847 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1863 | ath_debug_stat_tx(sc, txq, bf); | 1848 | ath_debug_stat_tx(sc, txq, bf); |
1864 | 1849 | ||
1865 | /* | 1850 | /* |
@@ -1907,8 +1892,7 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1907 | struct sk_buff *skb = bf->bf_mpdu; | 1892 | struct sk_buff *skb = bf->bf_mpdu; |
1908 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1893 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1909 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1894 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1910 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | 1895 | struct ieee80211_hw *hw = bf->aphy->hw; |
1911 | struct ieee80211_hw *hw = tx_info_priv->aphy->hw; | ||
1912 | u8 i, tx_rateindex; | 1896 | u8 i, tx_rateindex; |
1913 | 1897 | ||
1914 | if (txok) | 1898 | if (txok) |
@@ -1917,17 +1901,22 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1917 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 1901 | tx_rateindex = ds->ds_txstat.ts_rateindex; |
1918 | WARN_ON(tx_rateindex >= hw->max_rates); | 1902 | WARN_ON(tx_rateindex >= hw->max_rates); |
1919 | 1903 | ||
1920 | tx_info_priv->update_rc = update_rc; | 1904 | if (update_rc) |
1905 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1921 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1906 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1922 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1907 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1923 | 1908 | ||
1924 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1909 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
1925 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1910 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1926 | if (ieee80211_is_data(hdr->frame_control)) { | 1911 | if (ieee80211_is_data(hdr->frame_control)) { |
1927 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | 1912 | if (ds->ds_txstat.ts_flags & |
1928 | sizeof(tx_info_priv->tx)); | 1913 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
1929 | tx_info_priv->n_frames = bf->bf_nframes; | 1914 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
1930 | tx_info_priv->n_bad_frames = nbad; | 1915 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || |
1916 | (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) | ||
1917 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | ||
1918 | tx_info->status.ampdu_len = bf->bf_nframes; | ||
1919 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | ||
1931 | } | 1920 | } |
1932 | } | 1921 | } |
1933 | 1922 | ||
@@ -1971,7 +1960,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1971 | spin_lock_bh(&txq->axq_lock); | 1960 | spin_lock_bh(&txq->axq_lock); |
1972 | if (list_empty(&txq->axq_q)) { | 1961 | if (list_empty(&txq->axq_q)) { |
1973 | txq->axq_link = NULL; | 1962 | txq->axq_link = NULL; |
1974 | txq->axq_linkbuf = NULL; | ||
1975 | spin_unlock_bh(&txq->axq_lock); | 1963 | spin_unlock_bh(&txq->axq_lock); |
1976 | break; | 1964 | break; |
1977 | } | 1965 | } |
@@ -2005,10 +1993,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2005 | spin_unlock_bh(&txq->axq_lock); | 1993 | spin_unlock_bh(&txq->axq_lock); |
2006 | break; | 1994 | break; |
2007 | } | 1995 | } |
2008 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
2009 | txq->axq_lastdsWithCTS = NULL; | ||
2010 | if (ds == txq->axq_gatingds) | ||
2011 | txq->axq_gatingds = NULL; | ||
2012 | 1996 | ||
2013 | /* | 1997 | /* |
2014 | * Remove ath_buf's of the same transmit unit from txq, | 1998 | * Remove ath_buf's of the same transmit unit from txq, |
@@ -2022,9 +2006,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2022 | &txq->axq_q, lastbf->list.prev); | 2006 | &txq->axq_q, lastbf->list.prev); |
2023 | 2007 | ||
2024 | txq->axq_depth--; | 2008 | txq->axq_depth--; |
2025 | if (bf_isaggr(bf)) | ||
2026 | txq->axq_aggr_depth--; | ||
2027 | |||
2028 | txok = (ds->ds_txstat.ts_status == 0); | 2009 | txok = (ds->ds_txstat.ts_status == 0); |
2029 | txq->axq_tx_inprogress = false; | 2010 | txq->axq_tx_inprogress = false; |
2030 | spin_unlock_bh(&txq->axq_lock); | 2011 | spin_unlock_bh(&txq->axq_lock); |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 077bcc142cde..039ac490465c 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -450,7 +450,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
450 | const struct ieee80211_regdomain *regd; | 450 | const struct ieee80211_regdomain *regd; |
451 | 451 | ||
452 | wiphy->reg_notifier = reg_notifier; | 452 | wiphy->reg_notifier = reg_notifier; |
453 | wiphy->strict_regulatory = true; | 453 | wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; |
454 | 454 | ||
455 | if (ath_is_world_regd(reg)) { | 455 | if (ath_is_world_regd(reg)) { |
456 | /* | 456 | /* |
@@ -458,8 +458,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg, | |||
458 | * saved on the wiphy orig_* parameters | 458 | * saved on the wiphy orig_* parameters |
459 | */ | 459 | */ |
460 | regd = ath_world_regdomain(reg); | 460 | regd = ath_world_regdomain(reg); |
461 | wiphy->custom_regulatory = true; | 461 | wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
462 | wiphy->strict_regulatory = false; | ||
463 | } else { | 462 | } else { |
464 | /* | 463 | /* |
465 | * This gets applied in the case of the absense of CRDA, | 464 | * This gets applied in the case of the absense of CRDA, |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index b5cd7f57055b..027be275e035 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -383,44 +383,160 @@ static inline | |||
383 | } | 383 | } |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Check if a DMA region fits the device constraints. | ||
387 | * Returns true, if the region is OK for usage with this device. */ | ||
388 | static inline bool b43_dma_address_ok(struct b43_dmaring *ring, | ||
389 | dma_addr_t addr, size_t size) | ||
390 | { | ||
391 | switch (ring->type) { | ||
392 | case B43_DMA_30BIT: | ||
393 | if ((u64)addr + size > (1ULL << 30)) | ||
394 | return 0; | ||
395 | break; | ||
396 | case B43_DMA_32BIT: | ||
397 | if ((u64)addr + size > (1ULL << 32)) | ||
398 | return 0; | ||
399 | break; | ||
400 | case B43_DMA_64BIT: | ||
401 | /* Currently we can't have addresses beyond | ||
402 | * 64bit in the kernel. */ | ||
403 | break; | ||
404 | } | ||
405 | return 1; | ||
406 | } | ||
407 | |||
408 | #define is_4k_aligned(addr) (((u64)(addr) & 0x0FFFull) == 0) | ||
409 | #define is_8k_aligned(addr) (((u64)(addr) & 0x1FFFull) == 0) | ||
410 | |||
411 | static void b43_unmap_and_free_ringmem(struct b43_dmaring *ring, void *base, | ||
412 | dma_addr_t dmaaddr, size_t size) | ||
413 | { | ||
414 | ssb_dma_unmap_single(ring->dev->dev, dmaaddr, size, DMA_TO_DEVICE); | ||
415 | free_pages((unsigned long)base, get_order(size)); | ||
416 | } | ||
417 | |||
418 | static void * __b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
419 | dma_addr_t *dmaaddr, size_t size, | ||
420 | gfp_t gfp_flags) | ||
421 | { | ||
422 | void *base; | ||
423 | |||
424 | base = (void *)__get_free_pages(gfp_flags, get_order(size)); | ||
425 | if (!base) | ||
426 | return NULL; | ||
427 | memset(base, 0, size); | ||
428 | *dmaaddr = ssb_dma_map_single(ring->dev->dev, base, size, | ||
429 | DMA_TO_DEVICE); | ||
430 | if (ssb_dma_mapping_error(ring->dev->dev, *dmaaddr)) { | ||
431 | free_pages((unsigned long)base, get_order(size)); | ||
432 | return NULL; | ||
433 | } | ||
434 | |||
435 | return base; | ||
436 | } | ||
437 | |||
438 | static void * b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
439 | dma_addr_t *dmaaddr, size_t size) | ||
440 | { | ||
441 | void *base; | ||
442 | |||
443 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
444 | GFP_KERNEL); | ||
445 | if (!base) { | ||
446 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
447 | "for DMA ringmemory\n"); | ||
448 | return NULL; | ||
449 | } | ||
450 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
451 | /* The memory does not fit our device constraints. | ||
452 | * Retry with GFP_DMA set to get lower memory. */ | ||
453 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
454 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
455 | GFP_KERNEL | GFP_DMA); | ||
456 | if (!base) { | ||
457 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
458 | "in the GFP_DMA region for DMA ringmemory\n"); | ||
459 | return NULL; | ||
460 | } | ||
461 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
462 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
463 | b43err(ring->dev->wl, "Failed to allocate DMA " | ||
464 | "ringmemory that fits device constraints\n"); | ||
465 | return NULL; | ||
466 | } | ||
467 | } | ||
468 | /* We expect the memory to be 4k aligned, at least. */ | ||
469 | if (B43_WARN_ON(!is_4k_aligned(*dmaaddr))) { | ||
470 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
471 | return NULL; | ||
472 | } | ||
473 | |||
474 | return base; | ||
475 | } | ||
476 | |||
386 | static int alloc_ringmemory(struct b43_dmaring *ring) | 477 | static int alloc_ringmemory(struct b43_dmaring *ring) |
387 | { | 478 | { |
388 | gfp_t flags = GFP_KERNEL; | 479 | unsigned int required; |
389 | 480 | void *base; | |
390 | /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K | 481 | dma_addr_t dmaaddr; |
391 | * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing | 482 | |
392 | * has shown that 4K is sufficient for the latter as long as the buffer | 483 | /* There are several requirements to the descriptor ring memory: |
393 | * does not cross an 8K boundary. | 484 | * - The memory region needs to fit the address constraints for the |
394 | * | 485 | * device (same as for frame buffers). |
395 | * For unknown reasons - possibly a hardware error - the BCM4311 rev | 486 | * - For 30/32bit DMA devices, the descriptor ring must be 4k aligned. |
396 | * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, | 487 | * - For 64bit DMA devices, the descriptor ring must be 8k aligned. |
397 | * which accounts for the GFP_DMA flag below. | ||
398 | * | ||
399 | * The flags here must match the flags in free_ringmemory below! | ||
400 | */ | 488 | */ |
489 | |||
401 | if (ring->type == B43_DMA_64BIT) | 490 | if (ring->type == B43_DMA_64BIT) |
402 | flags |= GFP_DMA; | 491 | required = ring->nr_slots * sizeof(struct b43_dmadesc64); |
403 | ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, | 492 | else |
404 | B43_DMA_RINGMEMSIZE, | 493 | required = ring->nr_slots * sizeof(struct b43_dmadesc32); |
405 | &(ring->dmabase), flags); | 494 | if (B43_WARN_ON(required > 0x1000)) |
406 | if (!ring->descbase) { | 495 | return -ENOMEM; |
407 | b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); | 496 | |
497 | ring->alloc_descsize = 0x1000; | ||
498 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
499 | if (!base) | ||
500 | return -ENOMEM; | ||
501 | ring->alloc_descbase = base; | ||
502 | ring->alloc_dmabase = dmaaddr; | ||
503 | |||
504 | if ((ring->type != B43_DMA_64BIT) || is_8k_aligned(dmaaddr)) { | ||
505 | /* We're on <=32bit DMA, or we already got 8k aligned memory. | ||
506 | * That's all we need, so we're fine. */ | ||
507 | ring->descbase = base; | ||
508 | ring->dmabase = dmaaddr; | ||
509 | return 0; | ||
510 | } | ||
511 | b43_unmap_and_free_ringmem(ring, base, dmaaddr, ring->alloc_descsize); | ||
512 | |||
513 | /* Ok, we failed at the 8k alignment requirement. | ||
514 | * Try to force-align the memory region now. */ | ||
515 | ring->alloc_descsize = 0x2000; | ||
516 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
517 | if (!base) | ||
408 | return -ENOMEM; | 518 | return -ENOMEM; |
519 | ring->alloc_descbase = base; | ||
520 | ring->alloc_dmabase = dmaaddr; | ||
521 | |||
522 | if (is_8k_aligned(dmaaddr)) { | ||
523 | /* We're already 8k aligned. That Ok, too. */ | ||
524 | ring->descbase = base; | ||
525 | ring->dmabase = dmaaddr; | ||
526 | return 0; | ||
409 | } | 527 | } |
410 | memset(ring->descbase, 0, B43_DMA_RINGMEMSIZE); | 528 | /* Force-align it to 8k */ |
529 | ring->descbase = (void *)((u8 *)base + 0x1000); | ||
530 | ring->dmabase = dmaaddr + 0x1000; | ||
531 | B43_WARN_ON(!is_8k_aligned(ring->dmabase)); | ||
411 | 532 | ||
412 | return 0; | 533 | return 0; |
413 | } | 534 | } |
414 | 535 | ||
415 | static void free_ringmemory(struct b43_dmaring *ring) | 536 | static void free_ringmemory(struct b43_dmaring *ring) |
416 | { | 537 | { |
417 | gfp_t flags = GFP_KERNEL; | 538 | b43_unmap_and_free_ringmem(ring, ring->alloc_descbase, |
418 | 539 | ring->alloc_dmabase, ring->alloc_descsize); | |
419 | if (ring->type == B43_DMA_64BIT) | ||
420 | flags |= GFP_DMA; | ||
421 | |||
422 | ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, | ||
423 | ring->descbase, ring->dmabase, flags); | ||
424 | } | 540 | } |
425 | 541 | ||
426 | /* Reset the RX DMA channel */ | 542 | /* Reset the RX DMA channel */ |
@@ -530,29 +646,14 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
530 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) | 646 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) |
531 | return 1; | 647 | return 1; |
532 | 648 | ||
533 | switch (ring->type) { | 649 | if (!b43_dma_address_ok(ring, addr, buffersize)) { |
534 | case B43_DMA_30BIT: | 650 | /* We can't support this address. Unmap it again. */ |
535 | if ((u64)addr + buffersize > (1ULL << 30)) | 651 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); |
536 | goto address_error; | 652 | return 1; |
537 | break; | ||
538 | case B43_DMA_32BIT: | ||
539 | if ((u64)addr + buffersize > (1ULL << 32)) | ||
540 | goto address_error; | ||
541 | break; | ||
542 | case B43_DMA_64BIT: | ||
543 | /* Currently we can't have addresses beyond | ||
544 | * 64bit in the kernel. */ | ||
545 | break; | ||
546 | } | 653 | } |
547 | 654 | ||
548 | /* The address is OK. */ | 655 | /* The address is OK. */ |
549 | return 0; | 656 | return 0; |
550 | |||
551 | address_error: | ||
552 | /* We can't support this address. Unmap it again. */ | ||
553 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
554 | |||
555 | return 1; | ||
556 | } | 657 | } |
557 | 658 | ||
558 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | 659 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) |
@@ -614,6 +715,9 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
614 | meta->dmaaddr = dmaaddr; | 715 | meta->dmaaddr = dmaaddr; |
615 | ring->ops->fill_descriptor(ring, desc, dmaaddr, | 716 | ring->ops->fill_descriptor(ring, desc, dmaaddr, |
616 | ring->rx_buffersize, 0, 0, 0); | 717 | ring->rx_buffersize, 0, 0, 0); |
718 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
719 | ring->alloc_dmabase, | ||
720 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
617 | 721 | ||
618 | return 0; | 722 | return 0; |
619 | } | 723 | } |
@@ -770,7 +874,7 @@ static void free_all_descbuffers(struct b43_dmaring *ring) | |||
770 | for (i = 0; i < ring->nr_slots; i++) { | 874 | for (i = 0; i < ring->nr_slots; i++) { |
771 | desc = ring->ops->idx2desc(ring, i, &meta); | 875 | desc = ring->ops->idx2desc(ring, i, &meta); |
772 | 876 | ||
773 | if (!meta->skb) { | 877 | if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { |
774 | B43_WARN_ON(!ring->tx); | 878 | B43_WARN_ON(!ring->tx); |
775 | continue; | 879 | continue; |
776 | } | 880 | } |
@@ -822,7 +926,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
822 | enum b43_dmatype type) | 926 | enum b43_dmatype type) |
823 | { | 927 | { |
824 | struct b43_dmaring *ring; | 928 | struct b43_dmaring *ring; |
825 | int err; | 929 | int i, err; |
826 | dma_addr_t dma_test; | 930 | dma_addr_t dma_test; |
827 | 931 | ||
828 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 932 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
@@ -837,6 +941,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
837 | GFP_KERNEL); | 941 | GFP_KERNEL); |
838 | if (!ring->meta) | 942 | if (!ring->meta) |
839 | goto err_kfree_ring; | 943 | goto err_kfree_ring; |
944 | for (i = 0; i < ring->nr_slots; i++) | ||
945 | ring->meta->skb = B43_DMA_PTR_POISON; | ||
840 | 946 | ||
841 | ring->type = type; | 947 | ring->type = type; |
842 | ring->dev = dev; | 948 | ring->dev = dev; |
@@ -1147,11 +1253,13 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) | |||
1147 | case 0x5000: | 1253 | case 0x5000: |
1148 | ring = dma->tx_ring_mcast; | 1254 | ring = dma->tx_ring_mcast; |
1149 | break; | 1255 | break; |
1150 | default: | ||
1151 | B43_WARN_ON(1); | ||
1152 | } | 1256 | } |
1153 | *slot = (cookie & 0x0FFF); | 1257 | *slot = (cookie & 0x0FFF); |
1154 | B43_WARN_ON(!(ring && *slot >= 0 && *slot < ring->nr_slots)); | 1258 | if (unlikely(!ring || *slot < 0 || *slot >= ring->nr_slots)) { |
1259 | b43dbg(dev->wl, "TX-status contains " | ||
1260 | "invalid cookie: 0x%04X\n", cookie); | ||
1261 | return NULL; | ||
1262 | } | ||
1155 | 1263 | ||
1156 | return ring; | 1264 | return ring; |
1157 | } | 1265 | } |
@@ -1246,6 +1354,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1246 | } | 1354 | } |
1247 | /* Now transfer the whole frame. */ | 1355 | /* Now transfer the whole frame. */ |
1248 | wmb(); | 1356 | wmb(); |
1357 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
1358 | ring->alloc_dmabase, | ||
1359 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
1249 | ops->poke_tx(ring, next_slot(ring, slot)); | 1360 | ops->poke_tx(ring, next_slot(ring, slot)); |
1250 | return 0; | 1361 | return 0; |
1251 | 1362 | ||
@@ -1387,19 +1498,40 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1387 | struct b43_dmaring *ring; | 1498 | struct b43_dmaring *ring; |
1388 | struct b43_dmadesc_generic *desc; | 1499 | struct b43_dmadesc_generic *desc; |
1389 | struct b43_dmadesc_meta *meta; | 1500 | struct b43_dmadesc_meta *meta; |
1390 | int slot; | 1501 | int slot, firstused; |
1391 | bool frame_succeed; | 1502 | bool frame_succeed; |
1392 | 1503 | ||
1393 | ring = parse_cookie(dev, status->cookie, &slot); | 1504 | ring = parse_cookie(dev, status->cookie, &slot); |
1394 | if (unlikely(!ring)) | 1505 | if (unlikely(!ring)) |
1395 | return; | 1506 | return; |
1396 | |||
1397 | B43_WARN_ON(!ring->tx); | 1507 | B43_WARN_ON(!ring->tx); |
1508 | |||
1509 | /* Sanity check: TX packets are processed in-order on one ring. | ||
1510 | * Check if the slot deduced from the cookie really is the first | ||
1511 | * used slot. */ | ||
1512 | firstused = ring->current_slot - ring->used_slots + 1; | ||
1513 | if (firstused < 0) | ||
1514 | firstused = ring->nr_slots + firstused; | ||
1515 | if (unlikely(slot != firstused)) { | ||
1516 | /* This possibly is a firmware bug and will result in | ||
1517 | * malfunction, memory leaks and/or stall of DMA functionality. */ | ||
1518 | b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " | ||
1519 | "Expected %d, but got %d\n", | ||
1520 | ring->index, firstused, slot); | ||
1521 | return; | ||
1522 | } | ||
1523 | |||
1398 | ops = ring->ops; | 1524 | ops = ring->ops; |
1399 | while (1) { | 1525 | while (1) { |
1400 | B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); | 1526 | B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); |
1401 | desc = ops->idx2desc(ring, slot, &meta); | 1527 | desc = ops->idx2desc(ring, slot, &meta); |
1402 | 1528 | ||
1529 | if (b43_dma_ptr_is_poisoned(meta->skb)) { | ||
1530 | b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " | ||
1531 | "on ring %d\n", | ||
1532 | slot, firstused, ring->index); | ||
1533 | break; | ||
1534 | } | ||
1403 | if (meta->skb) { | 1535 | if (meta->skb) { |
1404 | struct b43_private_tx_info *priv_info = | 1536 | struct b43_private_tx_info *priv_info = |
1405 | b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); | 1537 | b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); |
@@ -1415,7 +1547,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1415 | if (meta->is_last_fragment) { | 1547 | if (meta->is_last_fragment) { |
1416 | struct ieee80211_tx_info *info; | 1548 | struct ieee80211_tx_info *info; |
1417 | 1549 | ||
1418 | BUG_ON(!meta->skb); | 1550 | if (unlikely(!meta->skb)) { |
1551 | /* This is a scatter-gather fragment of a frame, so | ||
1552 | * the skb pointer must not be NULL. */ | ||
1553 | b43dbg(dev->wl, "TX status unexpected NULL skb " | ||
1554 | "at slot %d (first=%d) on ring %d\n", | ||
1555 | slot, firstused, ring->index); | ||
1556 | break; | ||
1557 | } | ||
1419 | 1558 | ||
1420 | info = IEEE80211_SKB_CB(meta->skb); | 1559 | info = IEEE80211_SKB_CB(meta->skb); |
1421 | 1560 | ||
@@ -1433,20 +1572,29 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1433 | #endif /* DEBUG */ | 1572 | #endif /* DEBUG */ |
1434 | ieee80211_tx_status(dev->wl->hw, meta->skb); | 1573 | ieee80211_tx_status(dev->wl->hw, meta->skb); |
1435 | 1574 | ||
1436 | /* skb is freed by ieee80211_tx_status() */ | 1575 | /* skb will be freed by ieee80211_tx_status(). |
1437 | meta->skb = NULL; | 1576 | * Poison our pointer. */ |
1577 | meta->skb = B43_DMA_PTR_POISON; | ||
1438 | } else { | 1578 | } else { |
1439 | /* No need to call free_descriptor_buffer here, as | 1579 | /* No need to call free_descriptor_buffer here, as |
1440 | * this is only the txhdr, which is not allocated. | 1580 | * this is only the txhdr, which is not allocated. |
1441 | */ | 1581 | */ |
1442 | B43_WARN_ON(meta->skb); | 1582 | if (unlikely(meta->skb)) { |
1583 | b43dbg(dev->wl, "TX status unexpected non-NULL skb " | ||
1584 | "at slot %d (first=%d) on ring %d\n", | ||
1585 | slot, firstused, ring->index); | ||
1586 | break; | ||
1587 | } | ||
1443 | } | 1588 | } |
1444 | 1589 | ||
1445 | /* Everything unmapped and free'd. So it's not used anymore. */ | 1590 | /* Everything unmapped and free'd. So it's not used anymore. */ |
1446 | ring->used_slots--; | 1591 | ring->used_slots--; |
1447 | 1592 | ||
1448 | if (meta->is_last_fragment) | 1593 | if (meta->is_last_fragment) { |
1594 | /* This is the last scatter-gather | ||
1595 | * fragment of the frame. We are done. */ | ||
1449 | break; | 1596 | break; |
1597 | } | ||
1450 | slot = next_slot(ring, slot); | 1598 | slot = next_slot(ring, slot); |
1451 | } | 1599 | } |
1452 | if (ring->stopped) { | 1600 | if (ring->stopped) { |
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index f0b0838fb5ba..e607b392314c 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef B43_DMA_H_ | 1 | #ifndef B43_DMA_H_ |
2 | #define B43_DMA_H_ | 2 | #define B43_DMA_H_ |
3 | 3 | ||
4 | #include <linux/ieee80211.h> | 4 | #include <linux/err.h> |
5 | 5 | ||
6 | #include "b43.h" | 6 | #include "b43.h" |
7 | 7 | ||
@@ -157,7 +157,6 @@ struct b43_dmadesc_generic { | |||
157 | } __attribute__ ((__packed__)); | 157 | } __attribute__ ((__packed__)); |
158 | 158 | ||
159 | /* Misc DMA constants */ | 159 | /* Misc DMA constants */ |
160 | #define B43_DMA_RINGMEMSIZE PAGE_SIZE | ||
161 | #define B43_DMA0_RX_FRAMEOFFSET 30 | 160 | #define B43_DMA0_RX_FRAMEOFFSET 30 |
162 | 161 | ||
163 | /* DMA engine tuning knobs */ | 162 | /* DMA engine tuning knobs */ |
@@ -165,6 +164,10 @@ struct b43_dmadesc_generic { | |||
165 | #define B43_RXRING_SLOTS 64 | 164 | #define B43_RXRING_SLOTS 64 |
166 | #define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN | 165 | #define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN |
167 | 166 | ||
167 | /* Pointer poison */ | ||
168 | #define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM)) | ||
169 | #define b43_dma_ptr_is_poisoned(ptr) (unlikely((ptr) == B43_DMA_PTR_POISON)) | ||
170 | |||
168 | 171 | ||
169 | struct sk_buff; | 172 | struct sk_buff; |
170 | struct b43_private; | 173 | struct b43_private; |
@@ -243,6 +246,12 @@ struct b43_dmaring { | |||
243 | /* The QOS priority assigned to this ring. Only used for TX rings. | 246 | /* The QOS priority assigned to this ring. Only used for TX rings. |
244 | * This is the mac80211 "queue" value. */ | 247 | * This is the mac80211 "queue" value. */ |
245 | u8 queue_prio; | 248 | u8 queue_prio; |
249 | /* Pointers and size of the originally allocated and mapped memory | ||
250 | * region for the descriptor ring. */ | ||
251 | void *alloc_descbase; | ||
252 | dma_addr_t alloc_dmabase; | ||
253 | unsigned int alloc_descsize; | ||
254 | /* Pointer to our wireless device. */ | ||
246 | struct b43_wldev *dev; | 255 | struct b43_wldev *dev; |
247 | #ifdef CONFIG_B43_DEBUG | 256 | #ifdef CONFIG_B43_DEBUG |
248 | /* Maximum number of used slots. */ | 257 | /* Maximum number of used slots. */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index b7408370cf82..6c836c892e43 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -296,6 +296,33 @@ static const char *command_types[] = { | |||
296 | }; | 296 | }; |
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | #define WEXT_USECHANNELS 1 | ||
300 | |||
301 | static const long ipw2100_frequencies[] = { | ||
302 | 2412, 2417, 2422, 2427, | ||
303 | 2432, 2437, 2442, 2447, | ||
304 | 2452, 2457, 2462, 2467, | ||
305 | 2472, 2484 | ||
306 | }; | ||
307 | |||
308 | #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) | ||
309 | |||
310 | static const long ipw2100_rates_11b[] = { | ||
311 | 1000000, | ||
312 | 2000000, | ||
313 | 5500000, | ||
314 | 11000000 | ||
315 | }; | ||
316 | |||
317 | static struct ieee80211_rate ipw2100_bg_rates[] = { | ||
318 | { .bitrate = 10 }, | ||
319 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
320 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
321 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
322 | }; | ||
323 | |||
324 | #define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) | ||
325 | |||
299 | /* Pre-decl until we get the code solid and then we can clean it up */ | 326 | /* Pre-decl until we get the code solid and then we can clean it up */ |
300 | static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); | 327 | static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); |
301 | static void ipw2100_tx_send_data(struct ipw2100_priv *priv); | 328 | static void ipw2100_tx_send_data(struct ipw2100_priv *priv); |
@@ -1141,6 +1168,7 @@ static int rf_kill_active(struct ipw2100_priv *priv) | |||
1141 | int i; | 1168 | int i; |
1142 | 1169 | ||
1143 | if (!(priv->hw_features & HW_FEATURE_RFKILL)) { | 1170 | if (!(priv->hw_features & HW_FEATURE_RFKILL)) { |
1171 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1144 | priv->status &= ~STATUS_RF_KILL_HW; | 1172 | priv->status &= ~STATUS_RF_KILL_HW; |
1145 | return 0; | 1173 | return 0; |
1146 | } | 1174 | } |
@@ -1151,10 +1179,13 @@ static int rf_kill_active(struct ipw2100_priv *priv) | |||
1151 | value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1); | 1179 | value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1); |
1152 | } | 1180 | } |
1153 | 1181 | ||
1154 | if (value == 0) | 1182 | if (value == 0) { |
1183 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
1155 | priv->status |= STATUS_RF_KILL_HW; | 1184 | priv->status |= STATUS_RF_KILL_HW; |
1156 | else | 1185 | } else { |
1186 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1157 | priv->status &= ~STATUS_RF_KILL_HW; | 1187 | priv->status &= ~STATUS_RF_KILL_HW; |
1188 | } | ||
1158 | 1189 | ||
1159 | return (value == 0); | 1190 | return (value == 0); |
1160 | } | 1191 | } |
@@ -1814,13 +1845,6 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) | |||
1814 | return rc; | 1845 | return rc; |
1815 | } | 1846 | } |
1816 | 1847 | ||
1817 | /* Called by register_netdev() */ | ||
1818 | static int ipw2100_net_init(struct net_device *dev) | ||
1819 | { | ||
1820 | struct ipw2100_priv *priv = libipw_priv(dev); | ||
1821 | return ipw2100_up(priv, 1); | ||
1822 | } | ||
1823 | |||
1824 | static void ipw2100_down(struct ipw2100_priv *priv) | 1848 | static void ipw2100_down(struct ipw2100_priv *priv) |
1825 | { | 1849 | { |
1826 | unsigned long flags; | 1850 | unsigned long flags; |
@@ -1875,6 +1899,64 @@ static void ipw2100_down(struct ipw2100_priv *priv) | |||
1875 | netif_stop_queue(priv->net_dev); | 1899 | netif_stop_queue(priv->net_dev); |
1876 | } | 1900 | } |
1877 | 1901 | ||
1902 | /* Called by register_netdev() */ | ||
1903 | static int ipw2100_net_init(struct net_device *dev) | ||
1904 | { | ||
1905 | struct ipw2100_priv *priv = libipw_priv(dev); | ||
1906 | const struct libipw_geo *geo = libipw_get_geo(priv->ieee); | ||
1907 | struct wireless_dev *wdev = &priv->ieee->wdev; | ||
1908 | int ret; | ||
1909 | int i; | ||
1910 | |||
1911 | ret = ipw2100_up(priv, 1); | ||
1912 | if (ret) | ||
1913 | return ret; | ||
1914 | |||
1915 | memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); | ||
1916 | |||
1917 | /* fill-out priv->ieee->bg_band */ | ||
1918 | if (geo->bg_channels) { | ||
1919 | struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; | ||
1920 | |||
1921 | bg_band->band = IEEE80211_BAND_2GHZ; | ||
1922 | bg_band->n_channels = geo->bg_channels; | ||
1923 | bg_band->channels = | ||
1924 | kzalloc(geo->bg_channels * | ||
1925 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
1926 | /* translate geo->bg to bg_band.channels */ | ||
1927 | for (i = 0; i < geo->bg_channels; i++) { | ||
1928 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
1929 | bg_band->channels[i].center_freq = geo->bg[i].freq; | ||
1930 | bg_band->channels[i].hw_value = geo->bg[i].channel; | ||
1931 | bg_band->channels[i].max_power = geo->bg[i].max_power; | ||
1932 | if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
1933 | bg_band->channels[i].flags |= | ||
1934 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
1935 | if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) | ||
1936 | bg_band->channels[i].flags |= | ||
1937 | IEEE80211_CHAN_NO_IBSS; | ||
1938 | if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
1939 | bg_band->channels[i].flags |= | ||
1940 | IEEE80211_CHAN_RADAR; | ||
1941 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
1942 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
1943 | LIBIPW_CH_B_ONLY... */ | ||
1944 | } | ||
1945 | /* point at bitrate info */ | ||
1946 | bg_band->bitrates = ipw2100_bg_rates; | ||
1947 | bg_band->n_bitrates = RATE_COUNT; | ||
1948 | |||
1949 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; | ||
1950 | } | ||
1951 | |||
1952 | set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); | ||
1953 | if (wiphy_register(wdev->wiphy)) { | ||
1954 | ipw2100_down(priv); | ||
1955 | return -EIO; | ||
1956 | } | ||
1957 | return 0; | ||
1958 | } | ||
1959 | |||
1878 | static void ipw2100_reset_adapter(struct work_struct *work) | 1960 | static void ipw2100_reset_adapter(struct work_struct *work) |
1879 | { | 1961 | { |
1880 | struct ipw2100_priv *priv = | 1962 | struct ipw2100_priv *priv = |
@@ -2090,6 +2172,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) | |||
2090 | priv->net_dev->name); | 2172 | priv->net_dev->name); |
2091 | 2173 | ||
2092 | /* RF_KILL is now enabled (else we wouldn't be here) */ | 2174 | /* RF_KILL is now enabled (else we wouldn't be here) */ |
2175 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
2093 | priv->status |= STATUS_RF_KILL_HW; | 2176 | priv->status |= STATUS_RF_KILL_HW; |
2094 | 2177 | ||
2095 | /* Make sure the RF Kill check timer is running */ | 2178 | /* Make sure the RF Kill check timer is running */ |
@@ -6029,7 +6112,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6029 | struct ipw2100_priv *priv; | 6112 | struct ipw2100_priv *priv; |
6030 | struct net_device *dev; | 6113 | struct net_device *dev; |
6031 | 6114 | ||
6032 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv)); | 6115 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); |
6033 | if (!dev) | 6116 | if (!dev) |
6034 | return NULL; | 6117 | return NULL; |
6035 | priv = libipw_priv(dev); | 6118 | priv = libipw_priv(dev); |
@@ -6342,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, | |||
6342 | sysfs_remove_group(&pci_dev->dev.kobj, | 6425 | sysfs_remove_group(&pci_dev->dev.kobj, |
6343 | &ipw2100_attribute_group); | 6426 | &ipw2100_attribute_group); |
6344 | 6427 | ||
6345 | free_ieee80211(dev); | 6428 | free_ieee80211(dev, 0); |
6346 | pci_set_drvdata(pci_dev, NULL); | 6429 | pci_set_drvdata(pci_dev, NULL); |
6347 | } | 6430 | } |
6348 | 6431 | ||
@@ -6400,7 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) | |||
6400 | if (dev->base_addr) | 6483 | if (dev->base_addr) |
6401 | iounmap((void __iomem *)dev->base_addr); | 6484 | iounmap((void __iomem *)dev->base_addr); |
6402 | 6485 | ||
6403 | free_ieee80211(dev); | 6486 | /* wiphy_unregister needs to be here, before free_ieee80211 */ |
6487 | wiphy_unregister(priv->ieee->wdev.wiphy); | ||
6488 | kfree(priv->ieee->bg_band.channels); | ||
6489 | free_ieee80211(dev, 0); | ||
6404 | } | 6490 | } |
6405 | 6491 | ||
6406 | pci_release_regions(pci_dev); | 6492 | pci_release_regions(pci_dev); |
@@ -6601,26 +6687,6 @@ static void __exit ipw2100_exit(void) | |||
6601 | module_init(ipw2100_init); | 6687 | module_init(ipw2100_init); |
6602 | module_exit(ipw2100_exit); | 6688 | module_exit(ipw2100_exit); |
6603 | 6689 | ||
6604 | #define WEXT_USECHANNELS 1 | ||
6605 | |||
6606 | static const long ipw2100_frequencies[] = { | ||
6607 | 2412, 2417, 2422, 2427, | ||
6608 | 2432, 2437, 2442, 2447, | ||
6609 | 2452, 2457, 2462, 2467, | ||
6610 | 2472, 2484 | ||
6611 | }; | ||
6612 | |||
6613 | #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) | ||
6614 | |||
6615 | static const long ipw2100_rates_11b[] = { | ||
6616 | 1000000, | ||
6617 | 2000000, | ||
6618 | 5500000, | ||
6619 | 11000000 | ||
6620 | }; | ||
6621 | |||
6622 | #define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) | ||
6623 | |||
6624 | static int ipw2100_wx_get_name(struct net_device *dev, | 6690 | static int ipw2100_wx_get_name(struct net_device *dev, |
6625 | struct iw_request_info *info, | 6691 | struct iw_request_info *info, |
6626 | union iwreq_data *wrqu, char *extra) | 6692 | union iwreq_data *wrqu, char *extra) |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 9fe0e8078a88..c28984ae46ff 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -109,6 +109,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH; | |||
109 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ | 109 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ |
110 | #endif | 110 | #endif |
111 | 111 | ||
112 | static struct ieee80211_rate ipw2200_rates[] = { | ||
113 | { .bitrate = 10 }, | ||
114 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
115 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
116 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
117 | { .bitrate = 60 }, | ||
118 | { .bitrate = 90 }, | ||
119 | { .bitrate = 120 }, | ||
120 | { .bitrate = 180 }, | ||
121 | { .bitrate = 240 }, | ||
122 | { .bitrate = 360 }, | ||
123 | { .bitrate = 480 }, | ||
124 | { .bitrate = 540 } | ||
125 | }; | ||
126 | |||
127 | #define ipw2200_a_rates (ipw2200_rates + 4) | ||
128 | #define ipw2200_num_a_rates 8 | ||
129 | #define ipw2200_bg_rates (ipw2200_rates + 0) | ||
130 | #define ipw2200_num_bg_rates 12 | ||
112 | 131 | ||
113 | #ifdef CONFIG_IPW2200_QOS | 132 | #ifdef CONFIG_IPW2200_QOS |
114 | static int qos_enable = 0; | 133 | static int qos_enable = 0; |
@@ -1739,10 +1758,13 @@ static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO, | |||
1739 | 1758 | ||
1740 | static int rf_kill_active(struct ipw_priv *priv) | 1759 | static int rf_kill_active(struct ipw_priv *priv) |
1741 | { | 1760 | { |
1742 | if (0 == (ipw_read32(priv, 0x30) & 0x10000)) | 1761 | if (0 == (ipw_read32(priv, 0x30) & 0x10000)) { |
1743 | priv->status |= STATUS_RF_KILL_HW; | 1762 | priv->status |= STATUS_RF_KILL_HW; |
1744 | else | 1763 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); |
1764 | } else { | ||
1745 | priv->status &= ~STATUS_RF_KILL_HW; | 1765 | priv->status &= ~STATUS_RF_KILL_HW; |
1766 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1767 | } | ||
1746 | 1768 | ||
1747 | return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; | 1769 | return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; |
1748 | } | 1770 | } |
@@ -2025,6 +2047,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
2025 | if (inta & IPW_INTA_BIT_RF_KILL_DONE) { | 2047 | if (inta & IPW_INTA_BIT_RF_KILL_DONE) { |
2026 | IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); | 2048 | IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); |
2027 | priv->status |= STATUS_RF_KILL_HW; | 2049 | priv->status |= STATUS_RF_KILL_HW; |
2050 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
2028 | wake_up_interruptible(&priv->wait_command_queue); | 2051 | wake_up_interruptible(&priv->wait_command_queue); |
2029 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2052 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
2030 | cancel_delayed_work(&priv->request_scan); | 2053 | cancel_delayed_work(&priv->request_scan); |
@@ -8660,24 +8683,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) | |||
8660 | * | 8683 | * |
8661 | */ | 8684 | */ |
8662 | 8685 | ||
8663 | static int ipw_wx_get_name(struct net_device *dev, | ||
8664 | struct iw_request_info *info, | ||
8665 | union iwreq_data *wrqu, char *extra) | ||
8666 | { | ||
8667 | struct ipw_priv *priv = libipw_priv(dev); | ||
8668 | mutex_lock(&priv->mutex); | ||
8669 | if (priv->status & STATUS_RF_KILL_MASK) | ||
8670 | strcpy(wrqu->name, "radio off"); | ||
8671 | else if (!(priv->status & STATUS_ASSOCIATED)) | ||
8672 | strcpy(wrqu->name, "unassociated"); | ||
8673 | else | ||
8674 | snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", | ||
8675 | ipw_modes[priv->assoc_request.ieee_mode]); | ||
8676 | IPW_DEBUG_WX("Name: %s\n", wrqu->name); | ||
8677 | mutex_unlock(&priv->mutex); | ||
8678 | return 0; | ||
8679 | } | ||
8680 | |||
8681 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) | 8686 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) |
8682 | { | 8687 | { |
8683 | if (channel == 0) { | 8688 | if (channel == 0) { |
@@ -9977,7 +9982,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, | |||
9977 | /* Rebase the WE IOCTLs to zero for the handler array */ | 9982 | /* Rebase the WE IOCTLs to zero for the handler array */ |
9978 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] | 9983 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] |
9979 | static iw_handler ipw_wx_handlers[] = { | 9984 | static iw_handler ipw_wx_handlers[] = { |
9980 | IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, | 9985 | IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, |
9981 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, | 9986 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, |
9982 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, | 9987 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, |
9983 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, | 9988 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, |
@@ -11422,16 +11427,100 @@ static void ipw_bg_down(struct work_struct *work) | |||
11422 | /* Called by register_netdev() */ | 11427 | /* Called by register_netdev() */ |
11423 | static int ipw_net_init(struct net_device *dev) | 11428 | static int ipw_net_init(struct net_device *dev) |
11424 | { | 11429 | { |
11430 | int i, rc = 0; | ||
11425 | struct ipw_priv *priv = libipw_priv(dev); | 11431 | struct ipw_priv *priv = libipw_priv(dev); |
11432 | const struct libipw_geo *geo = libipw_get_geo(priv->ieee); | ||
11433 | struct wireless_dev *wdev = &priv->ieee->wdev; | ||
11426 | mutex_lock(&priv->mutex); | 11434 | mutex_lock(&priv->mutex); |
11427 | 11435 | ||
11428 | if (ipw_up(priv)) { | 11436 | if (ipw_up(priv)) { |
11429 | mutex_unlock(&priv->mutex); | 11437 | rc = -EIO; |
11430 | return -EIO; | 11438 | goto out; |
11439 | } | ||
11440 | |||
11441 | memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); | ||
11442 | |||
11443 | /* fill-out priv->ieee->bg_band */ | ||
11444 | if (geo->bg_channels) { | ||
11445 | struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; | ||
11446 | |||
11447 | bg_band->band = IEEE80211_BAND_2GHZ; | ||
11448 | bg_band->n_channels = geo->bg_channels; | ||
11449 | bg_band->channels = | ||
11450 | kzalloc(geo->bg_channels * | ||
11451 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11452 | /* translate geo->bg to bg_band.channels */ | ||
11453 | for (i = 0; i < geo->bg_channels; i++) { | ||
11454 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11455 | bg_band->channels[i].center_freq = geo->bg[i].freq; | ||
11456 | bg_band->channels[i].hw_value = geo->bg[i].channel; | ||
11457 | bg_band->channels[i].max_power = geo->bg[i].max_power; | ||
11458 | if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11459 | bg_band->channels[i].flags |= | ||
11460 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11461 | if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) | ||
11462 | bg_band->channels[i].flags |= | ||
11463 | IEEE80211_CHAN_NO_IBSS; | ||
11464 | if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11465 | bg_band->channels[i].flags |= | ||
11466 | IEEE80211_CHAN_RADAR; | ||
11467 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11468 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11469 | LIBIPW_CH_B_ONLY... */ | ||
11470 | } | ||
11471 | /* point at bitrate info */ | ||
11472 | bg_band->bitrates = ipw2200_bg_rates; | ||
11473 | bg_band->n_bitrates = ipw2200_num_bg_rates; | ||
11474 | |||
11475 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; | ||
11431 | } | 11476 | } |
11432 | 11477 | ||
11478 | /* fill-out priv->ieee->a_band */ | ||
11479 | if (geo->a_channels) { | ||
11480 | struct ieee80211_supported_band *a_band = &priv->ieee->a_band; | ||
11481 | |||
11482 | a_band->band = IEEE80211_BAND_5GHZ; | ||
11483 | a_band->n_channels = geo->a_channels; | ||
11484 | a_band->channels = | ||
11485 | kzalloc(geo->a_channels * | ||
11486 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11487 | /* translate geo->bg to a_band.channels */ | ||
11488 | for (i = 0; i < geo->a_channels; i++) { | ||
11489 | a_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11490 | a_band->channels[i].center_freq = geo->a[i].freq; | ||
11491 | a_band->channels[i].hw_value = geo->a[i].channel; | ||
11492 | a_band->channels[i].max_power = geo->a[i].max_power; | ||
11493 | if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11494 | a_band->channels[i].flags |= | ||
11495 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11496 | if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) | ||
11497 | a_band->channels[i].flags |= | ||
11498 | IEEE80211_CHAN_NO_IBSS; | ||
11499 | if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11500 | a_band->channels[i].flags |= | ||
11501 | IEEE80211_CHAN_RADAR; | ||
11502 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11503 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11504 | LIBIPW_CH_B_ONLY... */ | ||
11505 | } | ||
11506 | /* point at bitrate info */ | ||
11507 | a_band->bitrates = ipw2200_a_rates; | ||
11508 | a_band->n_bitrates = ipw2200_num_a_rates; | ||
11509 | |||
11510 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; | ||
11511 | } | ||
11512 | |||
11513 | set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); | ||
11514 | |||
11515 | /* With that information in place, we can now register the wiphy... */ | ||
11516 | if (wiphy_register(wdev->wiphy)) { | ||
11517 | rc = -EIO; | ||
11518 | goto out; | ||
11519 | } | ||
11520 | |||
11521 | out: | ||
11433 | mutex_unlock(&priv->mutex); | 11522 | mutex_unlock(&priv->mutex); |
11434 | return 0; | 11523 | return rc; |
11435 | } | 11524 | } |
11436 | 11525 | ||
11437 | /* PCI driver stuff */ | 11526 | /* PCI driver stuff */ |
@@ -11562,7 +11651,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11562 | if (priv->prom_net_dev) | 11651 | if (priv->prom_net_dev) |
11563 | return -EPERM; | 11652 | return -EPERM; |
11564 | 11653 | ||
11565 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); | 11654 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); |
11566 | if (priv->prom_net_dev == NULL) | 11655 | if (priv->prom_net_dev == NULL) |
11567 | return -ENOMEM; | 11656 | return -ENOMEM; |
11568 | 11657 | ||
@@ -11581,7 +11670,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11581 | 11670 | ||
11582 | rc = register_netdev(priv->prom_net_dev); | 11671 | rc = register_netdev(priv->prom_net_dev); |
11583 | if (rc) { | 11672 | if (rc) { |
11584 | free_ieee80211(priv->prom_net_dev); | 11673 | free_ieee80211(priv->prom_net_dev, 1); |
11585 | priv->prom_net_dev = NULL; | 11674 | priv->prom_net_dev = NULL; |
11586 | return rc; | 11675 | return rc; |
11587 | } | 11676 | } |
@@ -11595,7 +11684,7 @@ static void ipw_prom_free(struct ipw_priv *priv) | |||
11595 | return; | 11684 | return; |
11596 | 11685 | ||
11597 | unregister_netdev(priv->prom_net_dev); | 11686 | unregister_netdev(priv->prom_net_dev); |
11598 | free_ieee80211(priv->prom_net_dev); | 11687 | free_ieee80211(priv->prom_net_dev, 1); |
11599 | 11688 | ||
11600 | priv->prom_net_dev = NULL; | 11689 | priv->prom_net_dev = NULL; |
11601 | } | 11690 | } |
@@ -11623,7 +11712,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11623 | struct ipw_priv *priv; | 11712 | struct ipw_priv *priv; |
11624 | int i; | 11713 | int i; |
11625 | 11714 | ||
11626 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); | 11715 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); |
11627 | if (net_dev == NULL) { | 11716 | if (net_dev == NULL) { |
11628 | err = -ENOMEM; | 11717 | err = -ENOMEM; |
11629 | goto out; | 11718 | goto out; |
@@ -11771,7 +11860,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11771 | pci_disable_device(pdev); | 11860 | pci_disable_device(pdev); |
11772 | pci_set_drvdata(pdev, NULL); | 11861 | pci_set_drvdata(pdev, NULL); |
11773 | out_free_ieee80211: | 11862 | out_free_ieee80211: |
11774 | free_ieee80211(priv->net_dev); | 11863 | free_ieee80211(priv->net_dev, 0); |
11775 | out: | 11864 | out: |
11776 | return err; | 11865 | return err; |
11777 | } | 11866 | } |
@@ -11838,7 +11927,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11838 | pci_release_regions(pdev); | 11927 | pci_release_regions(pdev); |
11839 | pci_disable_device(pdev); | 11928 | pci_disable_device(pdev); |
11840 | pci_set_drvdata(pdev, NULL); | 11929 | pci_set_drvdata(pdev, NULL); |
11841 | free_ieee80211(priv->net_dev); | 11930 | /* wiphy_unregister needs to be here, before free_ieee80211 */ |
11931 | wiphy_unregister(priv->ieee->wdev.wiphy); | ||
11932 | kfree(priv->ieee->a_band.channels); | ||
11933 | kfree(priv->ieee->bg_band.channels); | ||
11934 | free_ieee80211(priv->net_dev, 0); | ||
11842 | free_firmware(); | 11935 | free_firmware(); |
11843 | } | 11936 | } |
11844 | 11937 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 1e334ff6bd52..bf45391172f3 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/ieee80211.h> | 31 | #include <linux/ieee80211.h> |
32 | 32 | ||
33 | #include <net/lib80211.h> | 33 | #include <net/lib80211.h> |
34 | #include <net/cfg80211.h> | ||
34 | 35 | ||
35 | #define LIBIPW_VERSION "git-1.1.13" | 36 | #define LIBIPW_VERSION "git-1.1.13" |
36 | 37 | ||
@@ -783,12 +784,15 @@ struct libipw_geo { | |||
783 | 784 | ||
784 | struct libipw_device { | 785 | struct libipw_device { |
785 | struct net_device *dev; | 786 | struct net_device *dev; |
787 | struct wireless_dev wdev; | ||
786 | struct libipw_security sec; | 788 | struct libipw_security sec; |
787 | 789 | ||
788 | /* Bookkeeping structures */ | 790 | /* Bookkeeping structures */ |
789 | struct libipw_stats ieee_stats; | 791 | struct libipw_stats ieee_stats; |
790 | 792 | ||
791 | struct libipw_geo geo; | 793 | struct libipw_geo geo; |
794 | struct ieee80211_supported_band bg_band; | ||
795 | struct ieee80211_supported_band a_band; | ||
792 | 796 | ||
793 | /* Probe / Beacon management */ | 797 | /* Probe / Beacon management */ |
794 | struct list_head network_free_list; | 798 | struct list_head network_free_list; |
@@ -1014,8 +1018,8 @@ static inline int libipw_is_cck_rate(u8 rate) | |||
1014 | } | 1018 | } |
1015 | 1019 | ||
1016 | /* ieee80211.c */ | 1020 | /* ieee80211.c */ |
1017 | extern void free_ieee80211(struct net_device *dev); | 1021 | extern void free_ieee80211(struct net_device *dev, int monitor); |
1018 | extern struct net_device *alloc_ieee80211(int sizeof_priv); | 1022 | extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); |
1019 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); | 1023 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); |
1020 | 1024 | ||
1021 | extern void libipw_networks_age(struct libipw_device *ieee, | 1025 | extern void libipw_networks_age(struct libipw_device *ieee, |
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index eb2b60834c17..e8a1ac5f8e11 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -62,6 +62,9 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
62 | MODULE_AUTHOR(DRV_COPYRIGHT); | 62 | MODULE_AUTHOR(DRV_COPYRIGHT); |
63 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
64 | 64 | ||
65 | struct cfg80211_ops libipw_config_ops = { }; | ||
66 | void *libipw_wiphy_privid = &libipw_wiphy_privid; | ||
67 | |||
65 | static int libipw_networks_allocate(struct libipw_device *ieee) | 68 | static int libipw_networks_allocate(struct libipw_device *ieee) |
66 | { | 69 | { |
67 | if (ieee->networks) | 70 | if (ieee->networks) |
@@ -140,7 +143,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu) | |||
140 | } | 143 | } |
141 | EXPORT_SYMBOL(libipw_change_mtu); | 144 | EXPORT_SYMBOL(libipw_change_mtu); |
142 | 145 | ||
143 | struct net_device *alloc_ieee80211(int sizeof_priv) | 146 | struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) |
144 | { | 147 | { |
145 | struct libipw_device *ieee; | 148 | struct libipw_device *ieee; |
146 | struct net_device *dev; | 149 | struct net_device *dev; |
@@ -157,10 +160,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
157 | 160 | ||
158 | ieee->dev = dev; | 161 | ieee->dev = dev; |
159 | 162 | ||
163 | if (!monitor) { | ||
164 | ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0); | ||
165 | if (!ieee->wdev.wiphy) { | ||
166 | LIBIPW_ERROR("Unable to allocate wiphy.\n"); | ||
167 | goto failed_free_netdev; | ||
168 | } | ||
169 | |||
170 | ieee->dev->ieee80211_ptr = &ieee->wdev; | ||
171 | ieee->wdev.iftype = NL80211_IFTYPE_STATION; | ||
172 | |||
173 | /* Fill-out wiphy structure bits we know... Not enough info | ||
174 | here to call set_wiphy_dev or set MAC address or channel info | ||
175 | -- have to do that in ->ndo_init... */ | ||
176 | ieee->wdev.wiphy->privid = libipw_wiphy_privid; | ||
177 | |||
178 | ieee->wdev.wiphy->max_scan_ssids = 1; | ||
179 | ieee->wdev.wiphy->max_scan_ie_len = 0; | ||
180 | ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ||
181 | | BIT(NL80211_IFTYPE_ADHOC); | ||
182 | } | ||
183 | |||
160 | err = libipw_networks_allocate(ieee); | 184 | err = libipw_networks_allocate(ieee); |
161 | if (err) { | 185 | if (err) { |
162 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); | 186 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); |
163 | goto failed_free_netdev; | 187 | goto failed_free_wiphy; |
164 | } | 188 | } |
165 | libipw_networks_initialize(ieee); | 189 | libipw_networks_initialize(ieee); |
166 | 190 | ||
@@ -193,19 +217,27 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
193 | 217 | ||
194 | return dev; | 218 | return dev; |
195 | 219 | ||
220 | failed_free_wiphy: | ||
221 | if (!monitor) | ||
222 | wiphy_free(ieee->wdev.wiphy); | ||
196 | failed_free_netdev: | 223 | failed_free_netdev: |
197 | free_netdev(dev); | 224 | free_netdev(dev); |
198 | failed: | 225 | failed: |
199 | return NULL; | 226 | return NULL; |
200 | } | 227 | } |
201 | 228 | ||
202 | void free_ieee80211(struct net_device *dev) | 229 | void free_ieee80211(struct net_device *dev, int monitor) |
203 | { | 230 | { |
204 | struct libipw_device *ieee = netdev_priv(dev); | 231 | struct libipw_device *ieee = netdev_priv(dev); |
205 | 232 | ||
206 | lib80211_crypt_info_free(&ieee->crypt_info); | 233 | lib80211_crypt_info_free(&ieee->crypt_info); |
207 | 234 | ||
208 | libipw_networks_free(ieee); | 235 | libipw_networks_free(ieee); |
236 | |||
237 | /* free cfg80211 resources */ | ||
238 | if (!monitor) | ||
239 | wiphy_free(ieee->wdev.wiphy); | ||
240 | |||
209 | free_netdev(dev); | 241 | free_netdev(dev); |
210 | } | 242 | } |
211 | 243 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8f82537045bf..8414178bcff4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -173,6 +173,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
173 | .use_rts_for_ht = true, /* use rts/cts protection */ | 173 | .use_rts_for_ht = true, /* use rts/cts protection */ |
174 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 174 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
175 | .support_ct_kill_exit = true, | 175 | .support_ct_kill_exit = true, |
176 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
176 | }; | 177 | }; |
177 | 178 | ||
178 | struct iwl_cfg iwl1000_bg_cfg = { | 179 | struct iwl_cfg iwl1000_bg_cfg = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 2b0d65c5780a..ecc23ec1f6a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -221,22 +221,13 @@ struct iwl3945_ibss_seq { | |||
221 | * for use by iwl-*.c | 221 | * for use by iwl-*.c |
222 | * | 222 | * |
223 | *****************************************************************************/ | 223 | *****************************************************************************/ |
224 | extern int iwl3945_power_init_handle(struct iwl_priv *priv); | ||
225 | extern int iwl3945_eeprom_init(struct iwl_priv *priv); | ||
226 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 224 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); |
227 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | 225 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); |
228 | extern int iwl3945_tx_queue_init(struct iwl_priv *priv, | ||
229 | struct iwl_tx_queue *txq, int count, u32 id); | ||
230 | extern void iwl3945_rx_replenish(void *data); | 226 | extern void iwl3945_rx_replenish(void *data); |
231 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 227 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
232 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); | ||
233 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, | ||
234 | const void *data); | ||
235 | extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv, | ||
236 | struct iwl_host_cmd *cmd); | ||
237 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, | 228 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
238 | struct ieee80211_hdr *hdr,int left); | 229 | struct ieee80211_hdr *hdr,int left); |
239 | extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv); | 230 | extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); |
240 | extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); | 231 | extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); |
241 | 232 | ||
242 | /* | 233 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index cc3942448703..386513b601f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1818,8 +1818,9 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | |||
1818 | addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; | 1818 | addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; |
1819 | addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; | 1819 | addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; |
1820 | addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; | 1820 | addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; |
1821 | addsta->sleep_tx_count = cmd->sleep_tx_count; | ||
1821 | addsta->reserved1 = cpu_to_le16(0); | 1822 | addsta->reserved1 = cpu_to_le16(0); |
1822 | addsta->reserved2 = cpu_to_le32(0); | 1823 | addsta->reserved2 = cpu_to_le16(0); |
1823 | 1824 | ||
1824 | return (u16)sizeof(struct iwl4965_addsta_cmd); | 1825 | return (u16)sizeof(struct iwl4965_addsta_cmd); |
1825 | } | 1826 | } |
@@ -1865,8 +1866,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
1865 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); | 1866 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); |
1866 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1867 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1867 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 1868 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
1868 | info->flags |= iwl_is_tx_success(status) ? | 1869 | info->flags |= iwl_tx_status_to_mac80211(status); |
1869 | IEEE80211_TX_STAT_ACK : 0; | ||
1870 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); | 1870 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); |
1871 | /* FIXME: code repetition end */ | 1871 | /* FIXME: code repetition end */ |
1872 | 1872 | ||
@@ -2021,8 +2021,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2021 | } | 2021 | } |
2022 | } else { | 2022 | } else { |
2023 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 2023 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
2024 | info->flags |= iwl_is_tx_success(status) ? | 2024 | info->flags |= iwl_tx_status_to_mac80211(status); |
2025 | IEEE80211_TX_STAT_ACK : 0; | ||
2026 | iwl_hwrate_to_tx_control(priv, | 2025 | iwl_hwrate_to_tx_control(priv, |
2027 | le32_to_cpu(tx_resp->rate_n_flags), | 2026 | le32_to_cpu(tx_resp->rate_n_flags), |
2028 | info); | 2027 | info); |
@@ -2240,6 +2239,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2240 | .broken_powersave = true, | 2239 | .broken_powersave = true, |
2241 | .led_compensation = 61, | 2240 | .led_compensation = 61, |
2242 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, | 2241 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, |
2242 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
2243 | }; | 2243 | }; |
2244 | 2244 | ||
2245 | /* Module firmware */ | 2245 | /* Module firmware */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e23d301e816f..e2f8615c8c9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -994,8 +994,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
994 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); | 994 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); |
995 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 995 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
996 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 996 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
997 | info->flags |= iwl_is_tx_success(status) ? | 997 | info->flags |= iwl_tx_status_to_mac80211(status); |
998 | IEEE80211_TX_STAT_ACK : 0; | ||
999 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); | 998 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); |
1000 | 999 | ||
1001 | /* FIXME: code repetition end */ | 1000 | /* FIXME: code repetition end */ |
@@ -1140,8 +1139,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1140 | BUG_ON(txq_id != txq->swq_id); | 1139 | BUG_ON(txq_id != txq->swq_id); |
1141 | 1140 | ||
1142 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1141 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1143 | info->flags |= iwl_is_tx_success(status) ? | 1142 | info->flags |= iwl_tx_status_to_mac80211(status); |
1144 | IEEE80211_TX_STAT_ACK : 0; | ||
1145 | iwl_hwrate_to_tx_control(priv, | 1143 | iwl_hwrate_to_tx_control(priv, |
1146 | le32_to_cpu(tx_resp->rate_n_flags), | 1144 | le32_to_cpu(tx_resp->rate_n_flags), |
1147 | info); | 1145 | info); |
@@ -1251,6 +1249,22 @@ int iwl5000_send_tx_power(struct iwl_priv *priv) | |||
1251 | 1249 | ||
1252 | /* half dBm need to multiply */ | 1250 | /* half dBm need to multiply */ |
1253 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); | 1251 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); |
1252 | |||
1253 | if (priv->tx_power_lmt_in_half_dbm && | ||
1254 | priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) { | ||
1255 | /* | ||
1256 | * For the newer devices which using enhanced/extend tx power | ||
1257 | * table in EEPROM, the format is in half dBm. driver need to | ||
1258 | * convert to dBm format before report to mac80211. | ||
1259 | * By doing so, there is a possibility of 1/2 dBm resolution | ||
1260 | * lost. driver will perform "round-up" operation before | ||
1261 | * reporting, but it will cause 1/2 dBm tx power over the | ||
1262 | * regulatory limit. Perform the checking here, if the | ||
1263 | * "tx_power_user_lmt" is higher than EEPROM value (in | ||
1264 | * half-dBm format), lower the tx power based on EEPROM | ||
1265 | */ | ||
1266 | tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; | ||
1267 | } | ||
1254 | tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; | 1268 | tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; |
1255 | tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; | 1269 | tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; |
1256 | 1270 | ||
@@ -1584,14 +1598,15 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
1584 | .ht_greenfield_support = true, | 1598 | .ht_greenfield_support = true, |
1585 | .led_compensation = 51, | 1599 | .led_compensation = 51, |
1586 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1600 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
1601 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
1587 | }; | 1602 | }; |
1588 | 1603 | ||
1589 | struct iwl_cfg iwl5100_bg_cfg = { | 1604 | struct iwl_cfg iwl5100_bgn_cfg = { |
1590 | .name = "5100BG", | 1605 | .name = "5100BGN", |
1591 | .fw_name_pre = IWL5000_FW_PRE, | 1606 | .fw_name_pre = IWL5000_FW_PRE, |
1592 | .ucode_api_max = IWL5000_UCODE_API_MAX, | 1607 | .ucode_api_max = IWL5000_UCODE_API_MAX, |
1593 | .ucode_api_min = IWL5000_UCODE_API_MIN, | 1608 | .ucode_api_min = IWL5000_UCODE_API_MIN, |
1594 | .sku = IWL_SKU_G, | 1609 | .sku = IWL_SKU_G|IWL_SKU_N, |
1595 | .ops = &iwl5000_ops, | 1610 | .ops = &iwl5000_ops, |
1596 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | 1611 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, |
1597 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | 1612 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, |
@@ -1627,7 +1642,6 @@ struct iwl_cfg iwl5100_abg_cfg = { | |||
1627 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, | 1642 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, |
1628 | .set_l0s = true, | 1643 | .set_l0s = true, |
1629 | .use_bsm = false, | 1644 | .use_bsm = false, |
1630 | .ht_greenfield_support = true, | ||
1631 | .led_compensation = 51, | 1645 | .led_compensation = 51, |
1632 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1646 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
1633 | }; | 1647 | }; |
@@ -1653,6 +1667,7 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
1653 | .ht_greenfield_support = true, | 1667 | .ht_greenfield_support = true, |
1654 | .led_compensation = 51, | 1668 | .led_compensation = 51, |
1655 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1669 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
1670 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
1656 | }; | 1671 | }; |
1657 | 1672 | ||
1658 | struct iwl_cfg iwl5350_agn_cfg = { | 1673 | struct iwl_cfg iwl5350_agn_cfg = { |
@@ -1676,6 +1691,7 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
1676 | .ht_greenfield_support = true, | 1691 | .ht_greenfield_support = true, |
1677 | .led_compensation = 51, | 1692 | .led_compensation = 51, |
1678 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1693 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
1694 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
1679 | }; | 1695 | }; |
1680 | 1696 | ||
1681 | struct iwl_cfg iwl5150_agn_cfg = { | 1697 | struct iwl_cfg iwl5150_agn_cfg = { |
@@ -1699,6 +1715,29 @@ struct iwl_cfg iwl5150_agn_cfg = { | |||
1699 | .ht_greenfield_support = true, | 1715 | .ht_greenfield_support = true, |
1700 | .led_compensation = 51, | 1716 | .led_compensation = 51, |
1701 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 1717 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
1718 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
1719 | }; | ||
1720 | |||
1721 | struct iwl_cfg iwl5150_abg_cfg = { | ||
1722 | .name = "5150ABG", | ||
1723 | .fw_name_pre = IWL5150_FW_PRE, | ||
1724 | .ucode_api_max = IWL5150_UCODE_API_MAX, | ||
1725 | .ucode_api_min = IWL5150_UCODE_API_MIN, | ||
1726 | .sku = IWL_SKU_A|IWL_SKU_G, | ||
1727 | .ops = &iwl5150_ops, | ||
1728 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
1729 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | ||
1730 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | ||
1731 | .num_of_queues = IWL50_NUM_QUEUES, | ||
1732 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1733 | .mod_params = &iwl50_mod_params, | ||
1734 | .valid_tx_ant = ANT_A, | ||
1735 | .valid_rx_ant = ANT_AB, | ||
1736 | .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, | ||
1737 | .set_l0s = true, | ||
1738 | .use_bsm = false, | ||
1739 | .led_compensation = 51, | ||
1740 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
1702 | }; | 1741 | }; |
1703 | 1742 | ||
1704 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); | 1743 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f732f6d194a0..74e571049273 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -306,6 +306,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
306 | .supports_idle = true, | 306 | .supports_idle = true, |
307 | .adv_thermal_throttle = true, | 307 | .adv_thermal_throttle = true, |
308 | .support_ct_kill_exit = true, | 308 | .support_ct_kill_exit = true, |
309 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, | ||
309 | }; | 310 | }; |
310 | 311 | ||
311 | struct iwl_cfg iwl6000i_2abg_cfg = { | 312 | struct iwl_cfg iwl6000i_2abg_cfg = { |
@@ -394,8 +395,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
394 | .supports_idle = true, | 395 | .supports_idle = true, |
395 | .adv_thermal_throttle = true, | 396 | .adv_thermal_throttle = true, |
396 | .support_ct_kill_exit = true, | 397 | .support_ct_kill_exit = true, |
397 | .support_sm_ps = true, | 398 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC, |
398 | .support_wimax_coexist = true, | ||
399 | }; | 399 | }; |
400 | 400 | ||
401 | struct iwl_cfg iwl6050_2abg_cfg = { | 401 | struct iwl_cfg iwl6050_2abg_cfg = { |
@@ -425,7 +425,6 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
425 | .supports_idle = true, | 425 | .supports_idle = true, |
426 | .adv_thermal_throttle = true, | 426 | .adv_thermal_throttle = true, |
427 | .support_ct_kill_exit = true, | 427 | .support_ct_kill_exit = true, |
428 | .support_wimax_coexist = true, | ||
429 | }; | 428 | }; |
430 | 429 | ||
431 | struct iwl_cfg iwl6000_3agn_cfg = { | 430 | struct iwl_cfg iwl6000_3agn_cfg = { |
@@ -456,38 +455,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
456 | .supports_idle = true, | 455 | .supports_idle = true, |
457 | .adv_thermal_throttle = true, | 456 | .adv_thermal_throttle = true, |
458 | .support_ct_kill_exit = true, | 457 | .support_ct_kill_exit = true, |
459 | }; | 458 | .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED, |
460 | |||
461 | struct iwl_cfg iwl6050_3agn_cfg = { | ||
462 | .name = "6050 Series 3x3 AGN", | ||
463 | .fw_name_pre = IWL6050_FW_PRE, | ||
464 | .ucode_api_max = IWL6050_UCODE_API_MAX, | ||
465 | .ucode_api_min = IWL6050_UCODE_API_MIN, | ||
466 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
467 | .ops = &iwl6050_ops, | ||
468 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
469 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, | ||
470 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
471 | .num_of_queues = IWL50_NUM_QUEUES, | ||
472 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
473 | .mod_params = &iwl50_mod_params, | ||
474 | .valid_tx_ant = ANT_ABC, | ||
475 | .valid_rx_ant = ANT_ABC, | ||
476 | .pll_cfg_val = 0, | ||
477 | .set_l0s = true, | ||
478 | .use_bsm = false, | ||
479 | .pa_type = IWL_PA_SYSTEM, | ||
480 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, | ||
481 | .shadow_ram_support = true, | ||
482 | .ht_greenfield_support = true, | ||
483 | .led_compensation = 51, | ||
484 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
485 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
486 | .supports_idle = true, | ||
487 | .adv_thermal_throttle = true, | ||
488 | .support_ct_kill_exit = true, | ||
489 | .support_sm_ps = true, | ||
490 | .support_wimax_coexist = true, | ||
491 | }; | 459 | }; |
492 | 460 | ||
493 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 461 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 43edd8fd4405..fe511cbf012e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -301,7 +301,7 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
303 | sta->addr, tid); | 303 | sta->addr, tid); |
304 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | 304 | ieee80211_start_tx_ba_session(sta, tid); |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
@@ -2964,16 +2964,16 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2964 | { | 2964 | { |
2965 | struct iwl_lq_sta *lq_sta = priv_sta; | 2965 | struct iwl_lq_sta *lq_sta = priv_sta; |
2966 | lq_sta->rs_sta_dbgfs_scale_table_file = | 2966 | lq_sta->rs_sta_dbgfs_scale_table_file = |
2967 | debugfs_create_file("rate_scale_table", 0600, dir, | 2967 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, |
2968 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 2968 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
2969 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2969 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2970 | debugfs_create_file("rate_stats_table", 0600, dir, | 2970 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, |
2971 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2971 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2972 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = | 2972 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = |
2973 | debugfs_create_file("rate_scale_data", 0600, dir, | 2973 | debugfs_create_file("rate_scale_data", S_IRUSR, dir, |
2974 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); | 2974 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); |
2975 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 2975 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
2976 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | 2976 | debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, |
2977 | &lq_sta->tx_agg_tid_en); | 2977 | &lq_sta->tx_agg_tid_en); |
2978 | 2978 | ||
2979 | } | 2979 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 29f7510ecdd7..c96513bddb10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -311,7 +311,7 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) | |||
311 | list_add(&frame->list, &priv->free_frames); | 311 | list_add(&frame->list, &priv->free_frames); |
312 | } | 312 | } |
313 | 313 | ||
314 | static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, | 314 | static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, |
315 | struct ieee80211_hdr *hdr, | 315 | struct ieee80211_hdr *hdr, |
316 | int left) | 316 | int left) |
317 | { | 317 | { |
@@ -328,34 +328,74 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, | |||
328 | return priv->ibss_beacon->len; | 328 | return priv->ibss_beacon->len; |
329 | } | 329 | } |
330 | 330 | ||
331 | /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ | ||
332 | static void iwl_set_beacon_tim(struct iwl_priv *priv, | ||
333 | struct iwl_tx_beacon_cmd *tx_beacon_cmd, | ||
334 | u8 *beacon, u32 frame_size) | ||
335 | { | ||
336 | u16 tim_idx; | ||
337 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; | ||
338 | |||
339 | /* | ||
340 | * The index is relative to frame start but we start looking at the | ||
341 | * variable-length part of the beacon. | ||
342 | */ | ||
343 | tim_idx = mgmt->u.beacon.variable - beacon; | ||
344 | |||
345 | /* Parse variable-length elements of beacon to find WLAN_EID_TIM */ | ||
346 | while ((tim_idx < (frame_size - 2)) && | ||
347 | (beacon[tim_idx] != WLAN_EID_TIM)) | ||
348 | tim_idx += beacon[tim_idx+1] + 2; | ||
349 | |||
350 | /* If TIM field was found, set variables */ | ||
351 | if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) { | ||
352 | tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx); | ||
353 | tx_beacon_cmd->tim_size = beacon[tim_idx+1]; | ||
354 | } else | ||
355 | IWL_WARN(priv, "Unable to find TIM Element in beacon\n"); | ||
356 | } | ||
357 | |||
331 | static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, | 358 | static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, |
332 | struct iwl_frame *frame, u8 rate) | 359 | struct iwl_frame *frame) |
333 | { | 360 | { |
334 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; | 361 | struct iwl_tx_beacon_cmd *tx_beacon_cmd; |
335 | unsigned int frame_size; | 362 | u32 frame_size; |
363 | u32 rate_flags; | ||
364 | u32 rate; | ||
365 | /* | ||
366 | * We have to set up the TX command, the TX Beacon command, and the | ||
367 | * beacon contents. | ||
368 | */ | ||
336 | 369 | ||
370 | /* Initialize memory */ | ||
337 | tx_beacon_cmd = &frame->u.beacon; | 371 | tx_beacon_cmd = &frame->u.beacon; |
338 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); | 372 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); |
339 | 373 | ||
340 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; | 374 | /* Set up TX beacon contents */ |
341 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
342 | |||
343 | frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame, | 375 | frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame, |
344 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); | 376 | sizeof(frame->u) - sizeof(*tx_beacon_cmd)); |
377 | if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) | ||
378 | return 0; | ||
345 | 379 | ||
346 | BUG_ON(frame_size > MAX_MPDU_SIZE); | 380 | /* Set up TX command fields */ |
347 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); | 381 | tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); |
382 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; | ||
383 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
384 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | | ||
385 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; | ||
348 | 386 | ||
349 | if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) | 387 | /* Set up TX beacon command fields */ |
350 | tx_beacon_cmd->tx.rate_n_flags = | 388 | iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, |
351 | iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); | 389 | frame_size); |
352 | else | ||
353 | tx_beacon_cmd->tx.rate_n_flags = | ||
354 | iwl_hw_set_rate_n_flags(rate, 0); | ||
355 | 390 | ||
356 | tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | | 391 | /* Set up packet rate and flags */ |
357 | TX_CMD_FLG_TSF_MSK | | 392 | rate = iwl_rate_get_lowest_plcp(priv); |
358 | TX_CMD_FLG_STA_RATE_MSK; | 393 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); |
394 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | ||
395 | if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) | ||
396 | rate_flags |= RATE_MCS_CCK_MSK; | ||
397 | tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, | ||
398 | rate_flags); | ||
359 | 399 | ||
360 | return sizeof(*tx_beacon_cmd) + frame_size; | 400 | return sizeof(*tx_beacon_cmd) + frame_size; |
361 | } | 401 | } |
@@ -364,19 +404,20 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) | |||
364 | struct iwl_frame *frame; | 404 | struct iwl_frame *frame; |
365 | unsigned int frame_size; | 405 | unsigned int frame_size; |
366 | int rc; | 406 | int rc; |
367 | u8 rate; | ||
368 | 407 | ||
369 | frame = iwl_get_free_frame(priv); | 408 | frame = iwl_get_free_frame(priv); |
370 | |||
371 | if (!frame) { | 409 | if (!frame) { |
372 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " | 410 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " |
373 | "command.\n"); | 411 | "command.\n"); |
374 | return -ENOMEM; | 412 | return -ENOMEM; |
375 | } | 413 | } |
376 | 414 | ||
377 | rate = iwl_rate_get_lowest_plcp(priv); | 415 | frame_size = iwl_hw_get_beacon_cmd(priv, frame); |
378 | 416 | if (!frame_size) { | |
379 | frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate); | 417 | IWL_ERR(priv, "Error configuring the beacon command\n"); |
418 | iwl_free_frame(priv, frame); | ||
419 | return -EINVAL; | ||
420 | } | ||
380 | 421 | ||
381 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, | 422 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, |
382 | &frame->u.cmd[0]); | 423 | &frame->u.cmd[0]); |
@@ -613,7 +654,7 @@ static void iwl_bg_statistics_periodic(unsigned long data) | |||
613 | if (!iwl_is_ready_rf(priv)) | 654 | if (!iwl_is_ready_rf(priv)) |
614 | return; | 655 | return; |
615 | 656 | ||
616 | iwl_send_statistics_request(priv, CMD_ASYNC); | 657 | iwl_send_statistics_request(priv, CMD_ASYNC, false); |
617 | } | 658 | } |
618 | 659 | ||
619 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, | 660 | static void iwl_rx_beacon_notif(struct iwl_priv *priv, |
@@ -730,7 +771,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
730 | * statistics request from the host as well as for the periodic | 771 | * statistics request from the host as well as for the periodic |
731 | * statistics notifications (after received beacons) from the uCode. | 772 | * statistics notifications (after received beacons) from the uCode. |
732 | */ | 773 | */ |
733 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; | 774 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; |
734 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; | 775 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; |
735 | 776 | ||
736 | iwl_setup_spectrum_handlers(priv); | 777 | iwl_setup_spectrum_handlers(priv); |
@@ -1038,7 +1079,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1038 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1079 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
1039 | iwl_rx_handle(priv); | 1080 | iwl_rx_handle(priv); |
1040 | priv->isr_stats.rx++; | 1081 | priv->isr_stats.rx++; |
1041 | iwl_leds_background(priv); | ||
1042 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1082 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
1043 | } | 1083 | } |
1044 | 1084 | ||
@@ -1226,19 +1266,27 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1226 | * 3- update RX shared data to indicate last write index. | 1266 | * 3- update RX shared data to indicate last write index. |
1227 | * 4- send interrupt. | 1267 | * 4- send interrupt. |
1228 | * This could lead to RX race, driver could receive RX interrupt | 1268 | * This could lead to RX race, driver could receive RX interrupt |
1229 | * but the shared data changes does not reflect this. | 1269 | * but the shared data changes does not reflect this; |
1230 | * this could lead to RX race, RX periodic will solve this race | 1270 | * periodic interrupt will detect any dangling Rx activity. |
1231 | */ | 1271 | */ |
1232 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | 1272 | |
1273 | /* Disable periodic interrupt; we use it as just a one-shot. */ | ||
1274 | iwl_write8(priv, CSR_INT_PERIODIC_REG, | ||
1233 | CSR_INT_PERIODIC_DIS); | 1275 | CSR_INT_PERIODIC_DIS); |
1234 | iwl_rx_handle(priv); | 1276 | iwl_rx_handle(priv); |
1235 | /* Only set RX periodic if real RX is received. */ | 1277 | |
1278 | /* | ||
1279 | * Enable periodic interrupt in 8 msec only if we received | ||
1280 | * real RX interrupt (instead of just periodic int), to catch | ||
1281 | * any dangling Rx interrupt. If it was just the periodic | ||
1282 | * interrupt, there was no dangling Rx activity, and no need | ||
1283 | * to extend the periodic interrupt; one-shot is enough. | ||
1284 | */ | ||
1236 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | 1285 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) |
1237 | iwl_write32(priv, CSR_INT_PERIODIC_REG, | 1286 | iwl_write8(priv, CSR_INT_PERIODIC_REG, |
1238 | CSR_INT_PERIODIC_ENA); | 1287 | CSR_INT_PERIODIC_ENA); |
1239 | 1288 | ||
1240 | priv->isr_stats.rx++; | 1289 | priv->isr_stats.rx++; |
1241 | iwl_leds_background(priv); | ||
1242 | } | 1290 | } |
1243 | 1291 | ||
1244 | /* This "Tx" DMA channel is used only for loading uCode */ | 1292 | /* This "Tx" DMA channel is used only for loading uCode */ |
@@ -1557,7 +1605,6 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1557 | return ret; | 1605 | return ret; |
1558 | } | 1606 | } |
1559 | 1607 | ||
1560 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1561 | static const char *desc_lookup_text[] = { | 1608 | static const char *desc_lookup_text[] = { |
1562 | "OK", | 1609 | "OK", |
1563 | "FAIL", | 1610 | "FAIL", |
@@ -1710,10 +1757,42 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1710 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | 1757 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); |
1711 | } | 1758 | } |
1712 | 1759 | ||
1760 | /** | ||
1761 | * iwl_print_last_event_logs - Dump the newest # of event log to syslog | ||
1762 | */ | ||
1763 | static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | ||
1764 | u32 num_wraps, u32 next_entry, | ||
1765 | u32 size, u32 mode) | ||
1766 | { | ||
1767 | /* | ||
1768 | * display the newest DEFAULT_LOG_ENTRIES entries | ||
1769 | * i.e the entries just before the next ont that uCode would fill. | ||
1770 | */ | ||
1771 | if (num_wraps) { | ||
1772 | if (next_entry < size) { | ||
1773 | iwl_print_event_log(priv, | ||
1774 | capacity - (size - next_entry), | ||
1775 | size - next_entry, mode); | ||
1776 | iwl_print_event_log(priv, 0, | ||
1777 | next_entry, mode); | ||
1778 | } else | ||
1779 | iwl_print_event_log(priv, next_entry - size, | ||
1780 | size, mode); | ||
1781 | } else { | ||
1782 | if (next_entry < size) | ||
1783 | iwl_print_event_log(priv, 0, next_entry, mode); | ||
1784 | else | ||
1785 | iwl_print_event_log(priv, next_entry - size, | ||
1786 | size, mode); | ||
1787 | } | ||
1788 | } | ||
1789 | |||
1713 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | 1790 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
1714 | #define MAX_EVENT_LOG_SIZE (512) | 1791 | #define MAX_EVENT_LOG_SIZE (512) |
1715 | 1792 | ||
1716 | void iwl_dump_nic_event_log(struct iwl_priv *priv) | 1793 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) |
1794 | |||
1795 | void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | ||
1717 | { | 1796 | { |
1718 | u32 base; /* SRAM byte address of event log header */ | 1797 | u32 base; /* SRAM byte address of event log header */ |
1719 | u32 capacity; /* event log capacity in # entries */ | 1798 | u32 capacity; /* event log capacity in # entries */ |
@@ -1758,19 +1837,37 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1758 | return; | 1837 | return; |
1759 | } | 1838 | } |
1760 | 1839 | ||
1761 | IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", | 1840 | #ifdef CONFIG_IWLWIFI_DEBUG |
1762 | size, num_wraps); | 1841 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) |
1763 | 1842 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | |
1764 | /* if uCode has wrapped back to top of log, start at the oldest entry, | 1843 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
1765 | * i.e the next one that uCode would fill. */ | 1844 | #else |
1766 | if (num_wraps) | 1845 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
1767 | iwl_print_event_log(priv, next_entry, | 1846 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
1768 | capacity - next_entry, mode); | 1847 | #endif |
1769 | /* (then/else) start at top of log */ | 1848 | IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", |
1770 | iwl_print_event_log(priv, 0, next_entry, mode); | 1849 | size); |
1771 | 1850 | ||
1772 | } | 1851 | #ifdef CONFIG_IWLWIFI_DEBUG |
1852 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | ||
1853 | /* | ||
1854 | * if uCode has wrapped back to top of log, | ||
1855 | * start at the oldest entry, | ||
1856 | * i.e the next one that uCode would fill. | ||
1857 | */ | ||
1858 | if (num_wraps) | ||
1859 | iwl_print_event_log(priv, next_entry, | ||
1860 | capacity - next_entry, mode); | ||
1861 | /* (then/else) start at top of log */ | ||
1862 | iwl_print_event_log(priv, 0, next_entry, mode); | ||
1863 | } else | ||
1864 | iwl_print_last_event_logs(priv, capacity, num_wraps, | ||
1865 | next_entry, size, mode); | ||
1866 | #else | ||
1867 | iwl_print_last_event_logs(priv, capacity, num_wraps, | ||
1868 | next_entry, size, mode); | ||
1773 | #endif | 1869 | #endif |
1870 | } | ||
1774 | 1871 | ||
1775 | /** | 1872 | /** |
1776 | * iwl_alive_start - called after REPLY_ALIVE notification received | 1873 | * iwl_alive_start - called after REPLY_ALIVE notification received |
@@ -2360,16 +2457,14 @@ static int iwl_setup_mac(struct iwl_priv *priv) | |||
2360 | BIT(NL80211_IFTYPE_STATION) | | 2457 | BIT(NL80211_IFTYPE_STATION) | |
2361 | BIT(NL80211_IFTYPE_ADHOC); | 2458 | BIT(NL80211_IFTYPE_ADHOC); |
2362 | 2459 | ||
2363 | hw->wiphy->custom_regulatory = true; | 2460 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | |
2364 | 2461 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | |
2365 | /* Firmware does not support this */ | ||
2366 | hw->wiphy->disable_beacon_hints = true; | ||
2367 | 2462 | ||
2368 | /* | 2463 | /* |
2369 | * For now, disable PS by default because it affects | 2464 | * For now, disable PS by default because it affects |
2370 | * RX performance significantly. | 2465 | * RX performance significantly. |
2371 | */ | 2466 | */ |
2372 | hw->wiphy->ps_default = false; | 2467 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
2373 | 2468 | ||
2374 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | 2469 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; |
2375 | /* we create the 802.11 header and a zero-length SSID element */ | 2470 | /* we create the 802.11 header and a zero-length SSID element */ |
@@ -2523,6 +2618,10 @@ void iwl_config_ap(struct iwl_priv *priv) | |||
2523 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " | 2618 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2524 | "Attempting to continue.\n"); | 2619 | "Attempting to continue.\n"); |
2525 | 2620 | ||
2621 | /* AP has all antennas */ | ||
2622 | priv->chain_noise_data.active_chains = | ||
2623 | priv->hw_params.valid_rx_ant; | ||
2624 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | ||
2526 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2625 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2527 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2626 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
2528 | 2627 | ||
@@ -2551,6 +2650,7 @@ void iwl_config_ap(struct iwl_priv *priv) | |||
2551 | /* restore RXON assoc */ | 2650 | /* restore RXON assoc */ |
2552 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2651 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2553 | iwlcore_commit_rxon(priv); | 2652 | iwlcore_commit_rxon(priv); |
2653 | iwl_reset_qos(priv); | ||
2554 | spin_lock_irqsave(&priv->lock, flags); | 2654 | spin_lock_irqsave(&priv->lock, flags); |
2555 | iwl_activate_qos(priv, 1); | 2655 | iwl_activate_qos(priv, 1); |
2556 | spin_unlock_irqrestore(&priv->lock, flags); | 2656 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2646,6 +2746,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2646 | } | 2746 | } |
2647 | 2747 | ||
2648 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | 2748 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, |
2749 | struct ieee80211_vif *vif, | ||
2649 | enum ieee80211_ampdu_mlme_action action, | 2750 | enum ieee80211_ampdu_mlme_action action, |
2650 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2751 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2651 | { | 2752 | { |
@@ -2699,6 +2800,45 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, | |||
2699 | return 0; | 2800 | return 0; |
2700 | } | 2801 | } |
2701 | 2802 | ||
2803 | static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | ||
2804 | struct ieee80211_vif *vif, | ||
2805 | enum sta_notify_cmd cmd, | ||
2806 | struct ieee80211_sta *sta) | ||
2807 | { | ||
2808 | struct iwl_priv *priv = hw->priv; | ||
2809 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
2810 | int sta_id; | ||
2811 | |||
2812 | /* | ||
2813 | * TODO: We really should use this callback to | ||
2814 | * actually maintain the station table in | ||
2815 | * the device. | ||
2816 | */ | ||
2817 | |||
2818 | switch (cmd) { | ||
2819 | case STA_NOTIFY_ADD: | ||
2820 | atomic_set(&sta_priv->pending_frames, 0); | ||
2821 | if (vif->type == NL80211_IFTYPE_AP) | ||
2822 | sta_priv->client = true; | ||
2823 | break; | ||
2824 | case STA_NOTIFY_SLEEP: | ||
2825 | WARN_ON(!sta_priv->client); | ||
2826 | sta_priv->asleep = true; | ||
2827 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
2828 | ieee80211_sta_block_awake(hw, sta, true); | ||
2829 | break; | ||
2830 | case STA_NOTIFY_AWAKE: | ||
2831 | WARN_ON(!sta_priv->client); | ||
2832 | sta_priv->asleep = false; | ||
2833 | sta_id = iwl_find_station(priv, sta->addr); | ||
2834 | if (sta_id != IWL_INVALID_STATION) | ||
2835 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
2836 | break; | ||
2837 | default: | ||
2838 | break; | ||
2839 | } | ||
2840 | } | ||
2841 | |||
2702 | /***************************************************************************** | 2842 | /***************************************************************************** |
2703 | * | 2843 | * |
2704 | * sysfs attributes | 2844 | * sysfs attributes |
@@ -2893,7 +3033,7 @@ static ssize_t show_statistics(struct device *d, | |||
2893 | return -EAGAIN; | 3033 | return -EAGAIN; |
2894 | 3034 | ||
2895 | mutex_lock(&priv->mutex); | 3035 | mutex_lock(&priv->mutex); |
2896 | rc = iwl_send_statistics_request(priv, 0); | 3036 | rc = iwl_send_statistics_request(priv, CMD_SYNC, false); |
2897 | mutex_unlock(&priv->mutex); | 3037 | mutex_unlock(&priv->mutex); |
2898 | 3038 | ||
2899 | if (rc) { | 3039 | if (rc) { |
@@ -3045,10 +3185,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3045 | priv->band = IEEE80211_BAND_2GHZ; | 3185 | priv->band = IEEE80211_BAND_2GHZ; |
3046 | 3186 | ||
3047 | priv->iw_mode = NL80211_IFTYPE_STATION; | 3187 | priv->iw_mode = NL80211_IFTYPE_STATION; |
3048 | if (priv->cfg->support_sm_ps) | ||
3049 | priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC; | ||
3050 | else | ||
3051 | priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED; | ||
3052 | 3188 | ||
3053 | /* Choose which receivers/antennas to use */ | 3189 | /* Choose which receivers/antennas to use */ |
3054 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 3190 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
@@ -3130,7 +3266,8 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3130 | .reset_tsf = iwl_mac_reset_tsf, | 3266 | .reset_tsf = iwl_mac_reset_tsf, |
3131 | .bss_info_changed = iwl_bss_info_changed, | 3267 | .bss_info_changed = iwl_bss_info_changed, |
3132 | .ampdu_action = iwl_mac_ampdu_action, | 3268 | .ampdu_action = iwl_mac_ampdu_action, |
3133 | .hw_scan = iwl_mac_hw_scan | 3269 | .hw_scan = iwl_mac_hw_scan, |
3270 | .sta_notify = iwl_mac_sta_notify, | ||
3134 | }; | 3271 | }; |
3135 | 3272 | ||
3136 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3273 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
@@ -3454,23 +3591,63 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
3454 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | 3591 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, |
3455 | #endif /* CONFIG_IWL4965 */ | 3592 | #endif /* CONFIG_IWL4965 */ |
3456 | #ifdef CONFIG_IWL5000 | 3593 | #ifdef CONFIG_IWL5000 |
3457 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, | 3594 | /* 5100 Series WiFi */ |
3458 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, | 3595 | {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ |
3459 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, | 3596 | {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3460 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, | 3597 | {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ |
3461 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, | 3598 | {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3462 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, | 3599 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */ |
3463 | {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, | 3600 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */ |
3464 | {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, | 3601 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */ |
3465 | {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)}, | 3602 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */ |
3466 | {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)}, | 3603 | {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */ |
3467 | /* 5350 WiFi/WiMax */ | 3604 | {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3468 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, | 3605 | {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */ |
3469 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, | 3606 | {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */ |
3470 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, | 3607 | {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */ |
3471 | /* 5150 Wifi/WiMax */ | 3608 | {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */ |
3472 | {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, | 3609 | {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */ |
3473 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, | 3610 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */ |
3611 | {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3612 | {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3613 | {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */ | ||
3614 | {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */ | ||
3615 | {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */ | ||
3616 | {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */ | ||
3617 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */ | ||
3618 | {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */ | ||
3619 | |||
3620 | /* 5300 Series WiFi */ | ||
3621 | {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3622 | {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3623 | {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3624 | {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3625 | {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3626 | {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3627 | {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3628 | {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3629 | {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3630 | {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3631 | {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */ | ||
3632 | {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */ | ||
3633 | |||
3634 | /* 5350 Series WiFi/WiMax */ | ||
3635 | {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3636 | {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3637 | {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */ | ||
3638 | |||
3639 | /* 5150 Series Wifi/WiMax */ | ||
3640 | {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3641 | {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3642 | {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3643 | {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3644 | {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3645 | {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3646 | |||
3647 | {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ | ||
3648 | {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ | ||
3649 | {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */ | ||
3650 | {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */ | ||
3474 | 3651 | ||
3475 | /* 6x00 Series */ | 3652 | /* 6x00 Series */ |
3476 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | 3653 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, |
@@ -3485,13 +3662,10 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
3485 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, | 3662 | {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, |
3486 | 3663 | ||
3487 | /* 6x50 WiFi/WiMax Series */ | 3664 | /* 6x50 WiFi/WiMax Series */ |
3488 | {IWL_PCI_DEVICE(0x0086, 0x1101, iwl6050_3agn_cfg)}, | ||
3489 | {IWL_PCI_DEVICE(0x0086, 0x1121, iwl6050_3agn_cfg)}, | ||
3490 | {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, | 3665 | {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, |
3491 | {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, | 3666 | {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)}, |
3492 | {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, | 3667 | {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)}, |
3493 | {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, | 3668 | {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)}, |
3494 | {IWL_PCI_DEVICE(0x0088, 0x1111, iwl6050_3agn_cfg)}, | ||
3495 | {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, | 3669 | {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, |
3496 | {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, | 3670 | {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, |
3497 | 3671 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index d994de7438d8..95a57b36a7ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -900,7 +900,7 @@ void iwl_reset_run_time_calib(struct iwl_priv *priv) | |||
900 | 900 | ||
901 | /* Ask for statistics now, the uCode will send notification | 901 | /* Ask for statistics now, the uCode will send notification |
902 | * periodically after association */ | 902 | * periodically after association */ |
903 | iwl_send_statistics_request(priv, CMD_ASYNC); | 903 | iwl_send_statistics_request(priv, CMD_ASYNC, true); |
904 | } | 904 | } |
905 | EXPORT_SYMBOL(iwl_reset_run_time_calib); | 905 | EXPORT_SYMBOL(iwl_reset_run_time_calib); |
906 | 906 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 2857287be4fd..e91507531923 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -977,6 +977,7 @@ struct iwl_qosparam_cmd { | |||
977 | #define STA_MODIFY_TX_RATE_MSK 0x04 | 977 | #define STA_MODIFY_TX_RATE_MSK 0x04 |
978 | #define STA_MODIFY_ADDBA_TID_MSK 0x08 | 978 | #define STA_MODIFY_ADDBA_TID_MSK 0x08 |
979 | #define STA_MODIFY_DELBA_TID_MSK 0x10 | 979 | #define STA_MODIFY_DELBA_TID_MSK 0x10 |
980 | #define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 | ||
980 | 981 | ||
981 | /* Receiver address (actually, Rx station's index into station table), | 982 | /* Receiver address (actually, Rx station's index into station table), |
982 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ | 983 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ |
@@ -1107,7 +1108,14 @@ struct iwl4965_addsta_cmd { | |||
1107 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | 1108 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ |
1108 | __le16 add_immediate_ba_ssn; | 1109 | __le16 add_immediate_ba_ssn; |
1109 | 1110 | ||
1110 | __le32 reserved2; | 1111 | /* |
1112 | * Number of packets OK to transmit to station even though | ||
1113 | * it is asleep -- used to synchronise PS-poll and u-APSD | ||
1114 | * responses while ucode keeps track of STA sleep state. | ||
1115 | */ | ||
1116 | __le16 sleep_tx_count; | ||
1117 | |||
1118 | __le16 reserved2; | ||
1111 | } __attribute__ ((packed)); | 1119 | } __attribute__ ((packed)); |
1112 | 1120 | ||
1113 | /* 5000 */ | 1121 | /* 5000 */ |
@@ -1138,7 +1146,14 @@ struct iwl_addsta_cmd { | |||
1138 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | 1146 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ |
1139 | __le16 add_immediate_ba_ssn; | 1147 | __le16 add_immediate_ba_ssn; |
1140 | 1148 | ||
1141 | __le32 reserved2; | 1149 | /* |
1150 | * Number of packets OK to transmit to station even though | ||
1151 | * it is asleep -- used to synchronise PS-poll and u-APSD | ||
1152 | * responses while ucode keeps track of STA sleep state. | ||
1153 | */ | ||
1154 | __le16 sleep_tx_count; | ||
1155 | |||
1156 | __le16 reserved2; | ||
1142 | } __attribute__ ((packed)); | 1157 | } __attribute__ ((packed)); |
1143 | 1158 | ||
1144 | 1159 | ||
@@ -1690,6 +1705,21 @@ enum { | |||
1690 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ | 1705 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ |
1691 | }; | 1706 | }; |
1692 | 1707 | ||
1708 | static inline u32 iwl_tx_status_to_mac80211(u32 status) | ||
1709 | { | ||
1710 | status &= TX_STATUS_MSK; | ||
1711 | |||
1712 | switch (status) { | ||
1713 | case TX_STATUS_SUCCESS: | ||
1714 | case TX_STATUS_DIRECT_DONE: | ||
1715 | return IEEE80211_TX_STAT_ACK; | ||
1716 | case TX_STATUS_FAIL_DEST_PS: | ||
1717 | return IEEE80211_TX_STAT_TX_FILTERED; | ||
1718 | default: | ||
1719 | return 0; | ||
1720 | } | ||
1721 | } | ||
1722 | |||
1693 | static inline bool iwl_is_tx_success(u32 status) | 1723 | static inline bool iwl_is_tx_success(u32 status) |
1694 | { | 1724 | { |
1695 | status &= TX_STATUS_MSK; | 1725 | status &= TX_STATUS_MSK; |
@@ -3071,6 +3101,10 @@ struct statistics_general { | |||
3071 | __le32 reserved3; | 3101 | __le32 reserved3; |
3072 | } __attribute__ ((packed)); | 3102 | } __attribute__ ((packed)); |
3073 | 3103 | ||
3104 | #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) | ||
3105 | #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) | ||
3106 | #define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2) | ||
3107 | |||
3074 | /* | 3108 | /* |
3075 | * REPLY_STATISTICS_CMD = 0x9c, | 3109 | * REPLY_STATISTICS_CMD = 0x9c, |
3076 | * 3945 and 4965 identical. | 3110 | * 3945 and 4965 identical. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6b18aab8fa9b..574d36658702 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -209,6 +209,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) | |||
209 | } | 209 | } |
210 | return ant; | 210 | return ant; |
211 | } | 211 | } |
212 | EXPORT_SYMBOL(iwl_toggle_tx_ant); | ||
212 | 213 | ||
213 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 214 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
214 | EXPORT_SYMBOL(iwl_bcast_addr); | 215 | EXPORT_SYMBOL(iwl_bcast_addr); |
@@ -255,7 +256,10 @@ int iwl_hw_nic_init(struct iwl_priv *priv) | |||
255 | /* nic_init */ | 256 | /* nic_init */ |
256 | spin_lock_irqsave(&priv->lock, flags); | 257 | spin_lock_irqsave(&priv->lock, flags); |
257 | priv->cfg->ops->lib->apm_ops.init(priv); | 258 | priv->cfg->ops->lib->apm_ops.init(priv); |
258 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | 259 | |
260 | /* Set interrupt coalescing timer to 512 usecs */ | ||
261 | iwl_write8(priv, CSR_INT_COALESCING, 512 / 32); | ||
262 | |||
259 | spin_unlock_irqrestore(&priv->lock, flags); | 263 | spin_unlock_irqrestore(&priv->lock, flags); |
260 | 264 | ||
261 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | 265 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); |
@@ -446,13 +450,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
446 | if (priv->cfg->ht_greenfield_support) | 450 | if (priv->cfg->ht_greenfield_support) |
447 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | 451 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; |
448 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | 452 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; |
449 | if (priv->cfg->support_sm_ps) | 453 | ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & |
450 | ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & | 454 | (priv->cfg->sm_ps_mode << 2)); |
451 | (WLAN_HT_CAP_SM_PS_DYNAMIC << 2)); | ||
452 | else | ||
453 | ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & | ||
454 | (WLAN_HT_CAP_SM_PS_DISABLED << 2)); | ||
455 | |||
456 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | 455 | max_bit_rate = MAX_BIT_RATE_20_MHZ; |
457 | if (priv->hw_params.ht40_channel & BIT(band)) { | 456 | if (priv->hw_params.ht40_channel & BIT(band)) { |
458 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 457 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
@@ -1007,25 +1006,23 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) | |||
1007 | int idle_cnt = active_cnt; | 1006 | int idle_cnt = active_cnt; |
1008 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); | 1007 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); |
1009 | 1008 | ||
1010 | if (priv->cfg->support_sm_ps) { | 1009 | /* # Rx chains when idling and maybe trying to save power */ |
1011 | /* # Rx chains when idling and maybe trying to save power */ | 1010 | switch (priv->cfg->sm_ps_mode) { |
1012 | switch (priv->current_ht_config.sm_ps) { | 1011 | case WLAN_HT_CAP_SM_PS_STATIC: |
1013 | case WLAN_HT_CAP_SM_PS_STATIC: | 1012 | idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; |
1014 | case WLAN_HT_CAP_SM_PS_DYNAMIC: | 1013 | break; |
1015 | idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL : | 1014 | case WLAN_HT_CAP_SM_PS_DYNAMIC: |
1016 | IWL_NUM_IDLE_CHAINS_SINGLE; | 1015 | idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL : |
1017 | break; | 1016 | IWL_NUM_IDLE_CHAINS_SINGLE; |
1018 | case WLAN_HT_CAP_SM_PS_DISABLED: | 1017 | break; |
1019 | idle_cnt = (is_cam) ? active_cnt : | 1018 | case WLAN_HT_CAP_SM_PS_DISABLED: |
1020 | IWL_NUM_IDLE_CHAINS_SINGLE; | 1019 | break; |
1021 | break; | 1020 | case WLAN_HT_CAP_SM_PS_INVALID: |
1022 | case WLAN_HT_CAP_SM_PS_INVALID: | 1021 | default: |
1023 | default: | 1022 | IWL_ERR(priv, "invalid sm_ps mode %u\n", |
1024 | IWL_ERR(priv, "invalid sm_ps mode %d\n", | 1023 | priv->cfg->sm_ps_mode); |
1025 | priv->current_ht_config.sm_ps); | 1024 | WARN_ON(1); |
1026 | WARN_ON(1); | 1025 | break; |
1027 | break; | ||
1028 | } | ||
1029 | } | 1026 | } |
1030 | return idle_cnt; | 1027 | return idle_cnt; |
1031 | } | 1028 | } |
@@ -1365,12 +1362,11 @@ void iwl_irq_handle_error(struct iwl_priv *priv) | |||
1365 | /* Cancel currently queued command. */ | 1362 | /* Cancel currently queued command. */ |
1366 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 1363 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
1367 | 1364 | ||
1365 | priv->cfg->ops->lib->dump_nic_error_log(priv); | ||
1366 | priv->cfg->ops->lib->dump_nic_event_log(priv, false); | ||
1368 | #ifdef CONFIG_IWLWIFI_DEBUG | 1367 | #ifdef CONFIG_IWLWIFI_DEBUG |
1369 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) { | 1368 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) |
1370 | priv->cfg->ops->lib->dump_nic_error_log(priv); | ||
1371 | priv->cfg->ops->lib->dump_nic_event_log(priv); | ||
1372 | iwl_print_rx_config_cmd(priv); | 1369 | iwl_print_rx_config_cmd(priv); |
1373 | } | ||
1374 | #endif | 1370 | #endif |
1375 | 1371 | ||
1376 | wake_up_interruptible(&priv->wait_command_queue); | 1372 | wake_up_interruptible(&priv->wait_command_queue); |
@@ -1991,16 +1987,21 @@ int iwl_send_bt_config(struct iwl_priv *priv) | |||
1991 | } | 1987 | } |
1992 | EXPORT_SYMBOL(iwl_send_bt_config); | 1988 | EXPORT_SYMBOL(iwl_send_bt_config); |
1993 | 1989 | ||
1994 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | 1990 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) |
1995 | { | 1991 | { |
1996 | u32 stat_flags = 0; | 1992 | struct iwl_statistics_cmd statistics_cmd = { |
1997 | struct iwl_host_cmd cmd = { | 1993 | .configuration_flags = |
1998 | .id = REPLY_STATISTICS_CMD, | 1994 | clear ? IWL_STATS_CONF_CLEAR_STATS : 0, |
1999 | .flags = flags, | ||
2000 | .len = sizeof(stat_flags), | ||
2001 | .data = (u8 *) &stat_flags, | ||
2002 | }; | 1995 | }; |
2003 | return iwl_send_cmd(priv, &cmd); | 1996 | |
1997 | if (flags & CMD_ASYNC) | ||
1998 | return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD, | ||
1999 | sizeof(struct iwl_statistics_cmd), | ||
2000 | &statistics_cmd, NULL); | ||
2001 | else | ||
2002 | return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
2003 | sizeof(struct iwl_statistics_cmd), | ||
2004 | &statistics_cmd); | ||
2004 | } | 2005 | } |
2005 | EXPORT_SYMBOL(iwl_send_statistics_request); | 2006 | EXPORT_SYMBOL(iwl_send_statistics_request); |
2006 | 2007 | ||
@@ -2477,6 +2478,16 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2477 | } else { | 2478 | } else { |
2478 | priv->assoc_id = 0; | 2479 | priv->assoc_id = 0; |
2479 | iwl_led_disassociate(priv); | 2480 | iwl_led_disassociate(priv); |
2481 | |||
2482 | /* | ||
2483 | * inform the ucode that there is no longer an | ||
2484 | * association and that no more packets should be | ||
2485 | * send | ||
2486 | */ | ||
2487 | priv->staging_rxon.filter_flags &= | ||
2488 | ~RXON_FILTER_ASSOC_MSK; | ||
2489 | priv->staging_rxon.assoc_id = 0; | ||
2490 | iwlcore_commit_rxon(priv); | ||
2480 | } | 2491 | } |
2481 | } | 2492 | } |
2482 | 2493 | ||
@@ -2492,6 +2503,14 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2492 | } | 2503 | } |
2493 | } | 2504 | } |
2494 | 2505 | ||
2506 | if ((changes & BSS_CHANGED_BEACON_ENABLED) && | ||
2507 | vif->bss_conf.enable_beacon) { | ||
2508 | memcpy(priv->staging_rxon.bssid_addr, | ||
2509 | bss_conf->bssid, ETH_ALEN); | ||
2510 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | ||
2511 | iwlcore_config_ap(priv); | ||
2512 | } | ||
2513 | |||
2495 | mutex_unlock(&priv->mutex); | 2514 | mutex_unlock(&priv->mutex); |
2496 | 2515 | ||
2497 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2516 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -3070,15 +3089,11 @@ const char *get_ctrl_string(int cmd) | |||
3070 | } | 3089 | } |
3071 | } | 3090 | } |
3072 | 3091 | ||
3073 | void iwl_clear_tx_stats(struct iwl_priv *priv) | 3092 | void iwl_clear_traffic_stats(struct iwl_priv *priv) |
3074 | { | 3093 | { |
3075 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); | 3094 | memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); |
3076 | |||
3077 | } | ||
3078 | |||
3079 | void iwl_clear_rx_stats(struct iwl_priv *priv) | ||
3080 | { | ||
3081 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); | 3095 | memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); |
3096 | priv->led_tpt = 0; | ||
3082 | } | 3097 | } |
3083 | 3098 | ||
3084 | /* | 3099 | /* |
@@ -3171,6 +3186,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
3171 | stats->data_cnt++; | 3186 | stats->data_cnt++; |
3172 | stats->data_bytes += len; | 3187 | stats->data_bytes += len; |
3173 | } | 3188 | } |
3189 | iwl_leds_background(priv); | ||
3174 | } | 3190 | } |
3175 | EXPORT_SYMBOL(iwl_update_stats); | 3191 | EXPORT_SYMBOL(iwl_update_stats); |
3176 | #endif | 3192 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3f97036ac29b..cf7d3df0744e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -167,7 +167,7 @@ struct iwl_lib_ops { | |||
167 | int (*is_valid_rtc_data_addr)(u32 addr); | 167 | int (*is_valid_rtc_data_addr)(u32 addr); |
168 | /* 1st ucode load */ | 168 | /* 1st ucode load */ |
169 | int (*load_ucode)(struct iwl_priv *priv); | 169 | int (*load_ucode)(struct iwl_priv *priv); |
170 | void (*dump_nic_event_log)(struct iwl_priv *priv); | 170 | void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); |
171 | void (*dump_nic_error_log)(struct iwl_priv *priv); | 171 | void (*dump_nic_error_log)(struct iwl_priv *priv); |
172 | int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); | 172 | int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); |
173 | /* power management */ | 173 | /* power management */ |
@@ -228,7 +228,7 @@ struct iwl_mod_params { | |||
228 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | 228 | * @chain_noise_num_beacons: number of beacons used to compute chain noise |
229 | * @adv_thermal_throttle: support advance thermal throttle | 229 | * @adv_thermal_throttle: support advance thermal throttle |
230 | * @support_ct_kill_exit: support ct kill exit condition | 230 | * @support_ct_kill_exit: support ct kill exit condition |
231 | * @support_sm_ps: support spatial multiplexing power save | 231 | * @sm_ps_mode: spatial multiplexing power save mode |
232 | * @support_wimax_coexist: support wimax/wifi co-exist | 232 | * @support_wimax_coexist: support wimax/wifi co-exist |
233 | * | 233 | * |
234 | * We enable the driver to be backward compatible wrt API version. The | 234 | * We enable the driver to be backward compatible wrt API version. The |
@@ -285,7 +285,7 @@ struct iwl_cfg { | |||
285 | const bool supports_idle; | 285 | const bool supports_idle; |
286 | bool adv_thermal_throttle; | 286 | bool adv_thermal_throttle; |
287 | bool support_ct_kill_exit; | 287 | bool support_ct_kill_exit; |
288 | bool support_sm_ps; | 288 | u8 sm_ps_mode; |
289 | const bool support_wimax_coexist; | 289 | const bool support_wimax_coexist; |
290 | }; | 290 | }; |
291 | 291 | ||
@@ -353,8 +353,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
353 | u16 length, struct ieee80211_hdr *header); | 353 | u16 length, struct ieee80211_hdr *header); |
354 | const char *get_mgmt_string(int cmd); | 354 | const char *get_mgmt_string(int cmd); |
355 | const char *get_ctrl_string(int cmd); | 355 | const char *get_ctrl_string(int cmd); |
356 | void iwl_clear_tx_stats(struct iwl_priv *priv); | 356 | void iwl_clear_traffic_stats(struct iwl_priv *priv); |
357 | void iwl_clear_rx_stats(struct iwl_priv *priv); | ||
358 | void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, | 357 | void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, |
359 | u16 len); | 358 | u16 len); |
360 | #else | 359 | #else |
@@ -390,6 +389,7 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | |||
390 | /* data */ | 389 | /* data */ |
391 | stats->data_bytes += len; | 390 | stats->data_bytes += len; |
392 | } | 391 | } |
392 | iwl_leds_background(priv); | ||
393 | } | 393 | } |
394 | #endif | 394 | #endif |
395 | /***************************************************** | 395 | /***************************************************** |
@@ -425,6 +425,8 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
425 | struct iwl_rx_mem_buffer *rxb); | 425 | struct iwl_rx_mem_buffer *rxb); |
426 | void iwl_rx_statistics(struct iwl_priv *priv, | 426 | void iwl_rx_statistics(struct iwl_priv *priv, |
427 | struct iwl_rx_mem_buffer *rxb); | 427 | struct iwl_rx_mem_buffer *rxb); |
428 | void iwl_reply_statistics(struct iwl_priv *priv, | ||
429 | struct iwl_rx_mem_buffer *rxb); | ||
428 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | 430 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); |
429 | 431 | ||
430 | /* TX helpers */ | 432 | /* TX helpers */ |
@@ -576,19 +578,11 @@ int iwl_pci_resume(struct pci_dev *pdev); | |||
576 | /***************************************************** | 578 | /***************************************************** |
577 | * Error Handling Debugging | 579 | * Error Handling Debugging |
578 | ******************************************************/ | 580 | ******************************************************/ |
579 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
580 | void iwl_dump_nic_event_log(struct iwl_priv *priv); | ||
581 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 581 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
582 | void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); | ||
583 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
582 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); | 584 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); |
583 | #else | 585 | #else |
584 | static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) | ||
585 | { | ||
586 | } | ||
587 | |||
588 | static inline void iwl_dump_nic_error_log(struct iwl_priv *priv) | ||
589 | { | ||
590 | } | ||
591 | |||
592 | static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) | 586 | static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) |
593 | { | 587 | { |
594 | } | 588 | } |
@@ -669,7 +663,8 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) | |||
669 | 663 | ||
670 | extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); | 664 | extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); |
671 | extern int iwl_send_bt_config(struct iwl_priv *priv); | 665 | extern int iwl_send_bt_config(struct iwl_priv *priv); |
672 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | 666 | extern int iwl_send_statistics_request(struct iwl_priv *priv, |
667 | u8 flags, bool clear); | ||
673 | extern int iwl_verify_ucode(struct iwl_priv *priv); | 668 | extern int iwl_verify_ucode(struct iwl_priv *priv); |
674 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, | 669 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, |
675 | struct iwl_link_quality_cmd *lq, u8 flags); | 670 | struct iwl_link_quality_cmd *lq, u8 flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b6ed5a3147a1..a7bfae01f19b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -62,11 +62,29 @@ | |||
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | #ifndef __iwl_csr_h__ | 63 | #ifndef __iwl_csr_h__ |
64 | #define __iwl_csr_h__ | 64 | #define __iwl_csr_h__ |
65 | /*=== CSR (control and status registers) ===*/ | 65 | /* |
66 | * CSR (control and status registers) | ||
67 | * | ||
68 | * CSR registers are mapped directly into PCI bus space, and are accessible | ||
69 | * whenever platform supplies power to device, even when device is in | ||
70 | * low power states due to driver-invoked device resets | ||
71 | * (e.g. CSR_RESET_REG_FLAG_SW_RESET) or uCode-driven power-saving modes. | ||
72 | * | ||
73 | * Use iwl_write32() and iwl_read32() family to access these registers; | ||
74 | * these provide simple PCI bus access, without waking up the MAC. | ||
75 | * Do not use iwl_write_direct32() family for these registers; | ||
76 | * no need to "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ. | ||
77 | * The MAC (uCode processor, etc.) does not need to be powered up for accessing | ||
78 | * the CSR registers. | ||
79 | * | ||
80 | * NOTE: Newer devices using one-time-programmable (OTP) memory | ||
81 | * require device to be awake in order to read this memory | ||
82 | * via CSR_EEPROM and CSR_OTP registers | ||
83 | */ | ||
66 | #define CSR_BASE (0x000) | 84 | #define CSR_BASE (0x000) |
67 | 85 | ||
68 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ | 86 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ |
69 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ | 87 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ |
70 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ | 88 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ |
71 | #define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ | 89 | #define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ |
72 | #define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ | 90 | #define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ |
@@ -74,42 +92,65 @@ | |||
74 | #define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ | 92 | #define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ |
75 | #define CSR_GP_CNTRL (CSR_BASE+0x024) | 93 | #define CSR_GP_CNTRL (CSR_BASE+0x024) |
76 | 94 | ||
95 | /* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */ | ||
96 | #define CSR_INT_PERIODIC_REG (CSR_BASE+0x005) | ||
97 | |||
77 | /* | 98 | /* |
78 | * Hardware revision info | 99 | * Hardware revision info |
79 | * Bit fields: | 100 | * Bit fields: |
80 | * 31-8: Reserved | 101 | * 31-8: Reserved |
81 | * 7-4: Type of device: 0x0 = 4965, 0xd = 3945 | 102 | * 7-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions |
82 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D | 103 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D |
83 | * 1-0: "Dash" value, as in A-1, etc. | 104 | * 1-0: "Dash" (-) value, as in A-1, etc. |
84 | * | 105 | * |
85 | * NOTE: Revision step affects calculation of CCK txpower for 4965. | 106 | * NOTE: Revision step affects calculation of CCK txpower for 4965. |
107 | * NOTE: See also CSR_HW_REV_WA_REG (work-around for bug in 4965). | ||
86 | */ | 108 | */ |
87 | #define CSR_HW_REV (CSR_BASE+0x028) | 109 | #define CSR_HW_REV (CSR_BASE+0x028) |
88 | 110 | ||
89 | /* EEPROM reads */ | 111 | /* |
112 | * EEPROM and OTP (one-time-programmable) memory reads | ||
113 | * | ||
114 | * NOTE: For (newer) devices using OTP, device must be awake, initialized via | ||
115 | * apm_ops.init() in order to read. Older devices (3945/4965/5000) | ||
116 | * use EEPROM and do not require this. | ||
117 | */ | ||
90 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) | 118 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) |
91 | #define CSR_EEPROM_GP (CSR_BASE+0x030) | 119 | #define CSR_EEPROM_GP (CSR_BASE+0x030) |
92 | #define CSR_OTP_GP_REG (CSR_BASE+0x034) | 120 | #define CSR_OTP_GP_REG (CSR_BASE+0x034) |
121 | |||
93 | #define CSR_GIO_REG (CSR_BASE+0x03C) | 122 | #define CSR_GIO_REG (CSR_BASE+0x03C) |
94 | #define CSR_GP_UCODE_REG (CSR_BASE+0x048) | 123 | #define CSR_GP_UCODE_REG (CSR_BASE+0x048) |
95 | #define CSR_GP_DRIVER_REG (CSR_BASE+0x050) | 124 | #define CSR_GP_DRIVER_REG (CSR_BASE+0x050) |
125 | |||
126 | /* | ||
127 | * UCODE-DRIVER GP (general purpose) mailbox registers. | ||
128 | * SET/CLR registers set/clear bit(s) if "1" is written. | ||
129 | */ | ||
96 | #define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) | 130 | #define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) |
97 | #define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) | 131 | #define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) |
98 | #define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) | 132 | #define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) |
99 | #define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) | 133 | #define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) |
134 | |||
100 | #define CSR_LED_REG (CSR_BASE+0x094) | 135 | #define CSR_LED_REG (CSR_BASE+0x094) |
101 | #define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) | 136 | #define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) |
137 | |||
138 | /* GIO Chicken Bits (PCI Express bus link power management) */ | ||
102 | #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) | 139 | #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) |
103 | 140 | ||
104 | #define CSR_INT_PERIODIC_REG (CSR_BASE+0x005) | ||
105 | /* Analog phase-lock-loop configuration */ | 141 | /* Analog phase-lock-loop configuration */ |
106 | #define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) | 142 | #define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) |
143 | |||
107 | /* | 144 | /* |
108 | * Indicates hardware rev, to determine CCK backoff for txpower calculation. | 145 | * CSR Hardware Revision Workaround Register. Indicates hardware rev; |
146 | * "step" determines CCK backoff for txpower calculation. Used for 4965 only. | ||
147 | * See also CSR_HW_REV register. | ||
109 | * Bit fields: | 148 | * Bit fields: |
110 | * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step | 149 | * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step |
150 | * 1-0: "Dash" (-) value, as in C-1, etc. | ||
111 | */ | 151 | */ |
112 | #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) | 152 | #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) |
153 | |||
113 | #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) | 154 | #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) |
114 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) | 155 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) |
115 | 156 | ||
@@ -126,14 +167,14 @@ | |||
126 | #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) | 167 | #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) |
127 | #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) | 168 | #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) |
128 | 169 | ||
129 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) | 170 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) |
130 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) | 171 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) |
131 | #define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) | 172 | #define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ |
132 | #define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) | 173 | #define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */ |
133 | #define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) | 174 | #define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */ |
134 | 175 | ||
135 | #define CSR_INT_PERIODIC_DIS (0x00) | 176 | #define CSR_INT_PERIODIC_DIS (0x00) /* disable periodic int*/ |
136 | #define CSR_INT_PERIODIC_ENA (0xFF) | 177 | #define CSR_INT_PERIODIC_ENA (0xFF) /* 255*32 usec ~ 8 msec*/ |
137 | 178 | ||
138 | /* interrupt flags in INTA, set by uCode or hardware (e.g. dma), | 179 | /* interrupt flags in INTA, set by uCode or hardware (e.g. dma), |
139 | * acknowledged (reset) by host writing "1" to flagged bits. */ | 180 | * acknowledged (reset) by host writing "1" to flagged bits. */ |
@@ -198,7 +239,44 @@ | |||
198 | #define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) | 239 | #define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) |
199 | #define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000) | 240 | #define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000) |
200 | 241 | ||
201 | /* GP (general purpose) CONTROL */ | 242 | /* |
243 | * GP (general purpose) CONTROL REGISTER | ||
244 | * Bit fields: | ||
245 | * 27: HW_RF_KILL_SW | ||
246 | * Indicates state of (platform's) hardware RF-Kill switch | ||
247 | * 26-24: POWER_SAVE_TYPE | ||
248 | * Indicates current power-saving mode: | ||
249 | * 000 -- No power saving | ||
250 | * 001 -- MAC power-down | ||
251 | * 010 -- PHY (radio) power-down | ||
252 | * 011 -- Error | ||
253 | * 9-6: SYS_CONFIG | ||
254 | * Indicates current system configuration, reflecting pins on chip | ||
255 | * as forced high/low by device circuit board. | ||
256 | * 4: GOING_TO_SLEEP | ||
257 | * Indicates MAC is entering a power-saving sleep power-down. | ||
258 | * Not a good time to access device-internal resources. | ||
259 | * 3: MAC_ACCESS_REQ | ||
260 | * Host sets this to request and maintain MAC wakeup, to allow host | ||
261 | * access to device-internal resources. Host must wait for | ||
262 | * MAC_CLOCK_READY (and !GOING_TO_SLEEP) before accessing non-CSR | ||
263 | * device registers. | ||
264 | * 2: INIT_DONE | ||
265 | * Host sets this to put device into fully operational D0 power mode. | ||
266 | * Host resets this after SW_RESET to put device into low power mode. | ||
267 | * 0: MAC_CLOCK_READY | ||
268 | * Indicates MAC (ucode processor, etc.) is powered up and can run. | ||
269 | * Internal resources are accessible. | ||
270 | * NOTE: This does not indicate that the processor is actually running. | ||
271 | * NOTE: This does not indicate that 4965 or 3945 has completed | ||
272 | * init or post-power-down restore of internal SRAM memory. | ||
273 | * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that | ||
274 | * SRAM is restored and uCode is in normal operation mode. | ||
275 | * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and | ||
276 | * do not need to save/restore it. | ||
277 | * NOTE: After device reset, this bit remains "0" until host sets | ||
278 | * INIT_DONE | ||
279 | */ | ||
202 | #define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) | 280 | #define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) |
203 | #define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) | 281 | #define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) |
204 | #define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) | 282 | #define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) |
@@ -231,28 +309,58 @@ | |||
231 | #define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000) | 309 | #define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000) |
232 | 310 | ||
233 | /* EEPROM GP */ | 311 | /* EEPROM GP */ |
234 | #define CSR_EEPROM_GP_VALID_MSK (0x00000007) | 312 | #define CSR_EEPROM_GP_VALID_MSK (0x00000007) /* signature */ |
235 | #define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) | 313 | #define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) |
314 | #define CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP (0x00000000) | ||
315 | #define CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP (0x00000001) | ||
316 | #define CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K (0x00000002) | ||
317 | #define CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K (0x00000004) | ||
318 | |||
319 | /* One-time-programmable memory general purpose reg */ | ||
236 | #define CSR_OTP_GP_REG_DEVICE_SELECT (0x00010000) /* 0 - EEPROM, 1 - OTP */ | 320 | #define CSR_OTP_GP_REG_DEVICE_SELECT (0x00010000) /* 0 - EEPROM, 1 - OTP */ |
237 | #define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */ | 321 | #define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */ |
238 | #define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK (0x00100000) /* bit 20 */ | 322 | #define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK (0x00100000) /* bit 20 */ |
239 | #define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK (0x00200000) /* bit 21 */ | 323 | #define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK (0x00200000) /* bit 21 */ |
324 | |||
325 | /* GP REG */ | ||
240 | #define CSR_GP_REG_POWER_SAVE_STATUS_MSK (0x03000000) /* bit 24/25 */ | 326 | #define CSR_GP_REG_POWER_SAVE_STATUS_MSK (0x03000000) /* bit 24/25 */ |
241 | #define CSR_GP_REG_NO_POWER_SAVE (0x00000000) | 327 | #define CSR_GP_REG_NO_POWER_SAVE (0x00000000) |
242 | #define CSR_GP_REG_MAC_POWER_SAVE (0x01000000) | 328 | #define CSR_GP_REG_MAC_POWER_SAVE (0x01000000) |
243 | #define CSR_GP_REG_PHY_POWER_SAVE (0x02000000) | 329 | #define CSR_GP_REG_PHY_POWER_SAVE (0x02000000) |
244 | #define CSR_GP_REG_POWER_SAVE_ERROR (0x03000000) | 330 | #define CSR_GP_REG_POWER_SAVE_ERROR (0x03000000) |
245 | 331 | ||
246 | /* EEPROM signature */ | ||
247 | #define CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP (0x00000000) | ||
248 | #define CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP (0x00000001) | ||
249 | #define CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K (0x00000002) | ||
250 | #define CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K (0x00000004) | ||
251 | 332 | ||
252 | /* CSR GIO */ | 333 | /* CSR GIO */ |
253 | #define CSR_GIO_REG_VAL_L0S_ENABLED (0x00000002) | 334 | #define CSR_GIO_REG_VAL_L0S_ENABLED (0x00000002) |
254 | 335 | ||
255 | /* UCODE DRV GP */ | 336 | /* |
337 | * UCODE-DRIVER GP (general purpose) mailbox register 1 | ||
338 | * Host driver and uCode write and/or read this register to communicate with | ||
339 | * each other. | ||
340 | * Bit fields: | ||
341 | * 4: UCODE_DISABLE | ||
342 | * Host sets this to request permanent halt of uCode, same as | ||
343 | * sending CARD_STATE command with "halt" bit set. | ||
344 | * 3: CT_KILL_EXIT | ||
345 | * Host sets this to request exit from CT_KILL state, i.e. host thinks | ||
346 | * device temperature is low enough to continue normal operation. | ||
347 | * 2: CMD_BLOCKED | ||
348 | * Host sets this during RF KILL power-down sequence (HW, SW, CT KILL) | ||
349 | * to release uCode to clear all Tx and command queues, enter | ||
350 | * unassociated mode, and power down. | ||
351 | * NOTE: Some devices also use HBUS_TARG_MBX_C register for this bit. | ||
352 | * 1: SW_BIT_RFKILL | ||
353 | * Host sets this when issuing CARD_STATE command to request | ||
354 | * device sleep. | ||
355 | * 0: MAC_SLEEP | ||
356 | * uCode sets this when preparing a power-saving power-down. | ||
357 | * uCode resets this when power-up is complete and SRAM is sane. | ||
358 | * NOTE: 3945/4965 saves internal SRAM data to host when powering down, | ||
359 | * and must restore this data after powering back up. | ||
360 | * MAC_SLEEP is the best indication that restore is complete. | ||
361 | * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and | ||
362 | * do not need to save/restore it. | ||
363 | */ | ||
256 | #define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) | 364 | #define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) |
257 | #define CSR_UCODE_SW_BIT_RFKILL (0x00000002) | 365 | #define CSR_UCODE_SW_BIT_RFKILL (0x00000002) |
258 | #define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) | 366 | #define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) |
@@ -265,7 +373,7 @@ | |||
265 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) | 373 | #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) |
266 | 374 | ||
267 | 375 | ||
268 | /* GI Chicken Bits */ | 376 | /* GIO Chicken Bits (PCI Express bus link power management) */ |
269 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) | 377 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) |
270 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) | 378 | #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) |
271 | 379 | ||
@@ -285,8 +393,23 @@ | |||
285 | #define CSR_DRAM_INT_TBL_ENABLE (1 << 31) | 393 | #define CSR_DRAM_INT_TBL_ENABLE (1 << 31) |
286 | #define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27) | 394 | #define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27) |
287 | 395 | ||
288 | /*=== HBUS (Host-side Bus) ===*/ | 396 | /* |
397 | * HBUS (Host-side Bus) | ||
398 | * | ||
399 | * HBUS registers are mapped directly into PCI bus space, but are used | ||
400 | * to indirectly access device's internal memory or registers that | ||
401 | * may be powered-down. | ||
402 | * | ||
403 | * Use iwl_write_direct32()/iwl_read_direct32() family for these registers; | ||
404 | * host must "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ | ||
405 | * to make sure the MAC (uCode processor, etc.) is powered up for accessing | ||
406 | * internal resources. | ||
407 | * | ||
408 | * Do not use iwl_write32()/iwl_read32() family to access these registers; | ||
409 | * these provide only simple PCI bus access, without waking up the MAC. | ||
410 | */ | ||
289 | #define HBUS_BASE (0x400) | 411 | #define HBUS_BASE (0x400) |
412 | |||
290 | /* | 413 | /* |
291 | * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM | 414 | * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM |
292 | * structures, error log, event log, verifying uCode load). | 415 | * structures, error log, event log, verifying uCode load). |
@@ -301,6 +424,10 @@ | |||
301 | #define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) | 424 | #define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) |
302 | #define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) | 425 | #define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) |
303 | 426 | ||
427 | /* Mailbox C, used as workaround alternative to CSR_UCODE_DRV_GP1 mailbox */ | ||
428 | #define HBUS_TARG_MBX_C (HBUS_BASE+0x030) | ||
429 | #define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) | ||
430 | |||
304 | /* | 431 | /* |
305 | * Registers for accessing device's internal peripheral registers | 432 | * Registers for accessing device's internal peripheral registers |
306 | * (e.g. SCD, BSM, etc.). First write to address register, | 433 | * (e.g. SCD, BSM, etc.). First write to address register, |
@@ -315,16 +442,12 @@ | |||
315 | #define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) | 442 | #define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) |
316 | 443 | ||
317 | /* | 444 | /* |
318 | * Per-Tx-queue write pointer (index, really!) (3945 and 4965). | 445 | * Per-Tx-queue write pointer (index, really!) |
319 | * Indicates index to next TFD that driver will fill (1 past latest filled). | 446 | * Indicates index to next TFD that driver will fill (1 past latest filled). |
320 | * Bit usage: | 447 | * Bit usage: |
321 | * 0-7: queue write index | 448 | * 0-7: queue write index |
322 | * 11-8: queue selector | 449 | * 11-8: queue selector |
323 | */ | 450 | */ |
324 | #define HBUS_TARG_WRPTR (HBUS_BASE+0x060) | 451 | #define HBUS_TARG_WRPTR (HBUS_BASE+0x060) |
325 | #define HBUS_TARG_MBX_C (HBUS_BASE+0x030) | ||
326 | |||
327 | #define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) | ||
328 | |||
329 | 452 | ||
330 | #endif /* !__iwl_csr_h__ */ | 453 | #endif /* !__iwl_csr_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 96c92eab692a..d61293ab67c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -107,6 +107,8 @@ struct iwl_debugfs { | |||
107 | struct dentry *file_chain_noise; | 107 | struct dentry *file_chain_noise; |
108 | struct dentry *file_tx_power; | 108 | struct dentry *file_tx_power; |
109 | struct dentry *file_power_save_status; | 109 | struct dentry *file_power_save_status; |
110 | struct dentry *file_clear_ucode_statistics; | ||
111 | struct dentry *file_clear_traffic_statistics; | ||
110 | } dbgfs_debug_files; | 112 | } dbgfs_debug_files; |
111 | u32 sram_offset; | 113 | u32 sram_offset; |
112 | u32 sram_len; | 114 | u32 sram_len; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 8784911fd56e..21e0f6699daf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -47,9 +47,9 @@ | |||
47 | goto err; \ | 47 | goto err; \ |
48 | } while (0) | 48 | } while (0) |
49 | 49 | ||
50 | #define DEBUGFS_ADD_FILE(name, parent) do { \ | 50 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
51 | dbgfs->dbgfs_##parent##_files.file_##name = \ | 51 | dbgfs->dbgfs_##parent##_files.file_##name = \ |
52 | debugfs_create_file(#name, S_IWUSR | S_IRUSR, \ | 52 | debugfs_create_file(#name, mode, \ |
53 | dbgfs->dir_##parent, priv, \ | 53 | dbgfs->dir_##parent, priv, \ |
54 | &iwl_dbgfs_##name##_ops); \ | 54 | &iwl_dbgfs_##name##_ops); \ |
55 | if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ | 55 | if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ |
@@ -131,21 +131,22 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, | |||
131 | 131 | ||
132 | int cnt; | 132 | int cnt; |
133 | ssize_t ret; | 133 | ssize_t ret; |
134 | const size_t bufsz = 100 + sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX); | 134 | const size_t bufsz = 100 + |
135 | sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); | ||
135 | buf = kzalloc(bufsz, GFP_KERNEL); | 136 | buf = kzalloc(bufsz, GFP_KERNEL); |
136 | if (!buf) | 137 | if (!buf) |
137 | return -ENOMEM; | 138 | return -ENOMEM; |
138 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); | 139 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); |
139 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { | 140 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { |
140 | pos += scnprintf(buf + pos, bufsz - pos, | 141 | pos += scnprintf(buf + pos, bufsz - pos, |
141 | "\t%s\t\t: %u\n", | 142 | "\t%25s\t\t: %u\n", |
142 | get_mgmt_string(cnt), | 143 | get_mgmt_string(cnt), |
143 | priv->tx_stats.mgmt[cnt]); | 144 | priv->tx_stats.mgmt[cnt]); |
144 | } | 145 | } |
145 | pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); | 146 | pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); |
146 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { | 147 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { |
147 | pos += scnprintf(buf + pos, bufsz - pos, | 148 | pos += scnprintf(buf + pos, bufsz - pos, |
148 | "\t%s\t\t: %u\n", | 149 | "\t%25s\t\t: %u\n", |
149 | get_ctrl_string(cnt), | 150 | get_ctrl_string(cnt), |
150 | priv->tx_stats.ctrl[cnt]); | 151 | priv->tx_stats.ctrl[cnt]); |
151 | } | 152 | } |
@@ -159,7 +160,7 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, | |||
159 | return ret; | 160 | return ret; |
160 | } | 161 | } |
161 | 162 | ||
162 | static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file, | 163 | static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file, |
163 | const char __user *user_buf, | 164 | const char __user *user_buf, |
164 | size_t count, loff_t *ppos) | 165 | size_t count, loff_t *ppos) |
165 | { | 166 | { |
@@ -174,8 +175,7 @@ static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file, | |||
174 | return -EFAULT; | 175 | return -EFAULT; |
175 | if (sscanf(buf, "%x", &clear_flag) != 1) | 176 | if (sscanf(buf, "%x", &clear_flag) != 1) |
176 | return -EFAULT; | 177 | return -EFAULT; |
177 | if (clear_flag == 1) | 178 | iwl_clear_traffic_stats(priv); |
178 | iwl_clear_tx_stats(priv); | ||
179 | 179 | ||
180 | return count; | 180 | return count; |
181 | } | 181 | } |
@@ -190,7 +190,7 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | |||
190 | int cnt; | 190 | int cnt; |
191 | ssize_t ret; | 191 | ssize_t ret; |
192 | const size_t bufsz = 100 + | 192 | const size_t bufsz = 100 + |
193 | sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX); | 193 | sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); |
194 | buf = kzalloc(bufsz, GFP_KERNEL); | 194 | buf = kzalloc(bufsz, GFP_KERNEL); |
195 | if (!buf) | 195 | if (!buf) |
196 | return -ENOMEM; | 196 | return -ENOMEM; |
@@ -198,14 +198,14 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | |||
198 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); | 198 | pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); |
199 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { | 199 | for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { |
200 | pos += scnprintf(buf + pos, bufsz - pos, | 200 | pos += scnprintf(buf + pos, bufsz - pos, |
201 | "\t%s\t\t: %u\n", | 201 | "\t%25s\t\t: %u\n", |
202 | get_mgmt_string(cnt), | 202 | get_mgmt_string(cnt), |
203 | priv->rx_stats.mgmt[cnt]); | 203 | priv->rx_stats.mgmt[cnt]); |
204 | } | 204 | } |
205 | pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); | 205 | pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); |
206 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { | 206 | for (cnt = 0; cnt < CONTROL_MAX; cnt++) { |
207 | pos += scnprintf(buf + pos, bufsz - pos, | 207 | pos += scnprintf(buf + pos, bufsz - pos, |
208 | "\t%s\t\t: %u\n", | 208 | "\t%25s\t\t: %u\n", |
209 | get_ctrl_string(cnt), | 209 | get_ctrl_string(cnt), |
210 | priv->rx_stats.ctrl[cnt]); | 210 | priv->rx_stats.ctrl[cnt]); |
211 | } | 211 | } |
@@ -220,26 +220,6 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | |||
220 | return ret; | 220 | return ret; |
221 | } | 221 | } |
222 | 222 | ||
223 | static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file, | ||
224 | const char __user *user_buf, | ||
225 | size_t count, loff_t *ppos) | ||
226 | { | ||
227 | struct iwl_priv *priv = file->private_data; | ||
228 | u32 clear_flag; | ||
229 | char buf[8]; | ||
230 | int buf_size; | ||
231 | |||
232 | memset(buf, 0, sizeof(buf)); | ||
233 | buf_size = min(count, sizeof(buf) - 1); | ||
234 | if (copy_from_user(buf, user_buf, buf_size)) | ||
235 | return -EFAULT; | ||
236 | if (sscanf(buf, "%x", &clear_flag) != 1) | ||
237 | return -EFAULT; | ||
238 | if (clear_flag == 1) | ||
239 | iwl_clear_rx_stats(priv); | ||
240 | return count; | ||
241 | } | ||
242 | |||
243 | #define BYTE1_MASK 0x000000ff; | 223 | #define BYTE1_MASK 0x000000ff; |
244 | #define BYTE2_MASK 0x0000ffff; | 224 | #define BYTE2_MASK 0x0000ffff; |
245 | #define BYTE3_MASK 0x00ffffff; | 225 | #define BYTE3_MASK 0x00ffffff; |
@@ -248,13 +228,29 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
248 | size_t count, loff_t *ppos) | 228 | size_t count, loff_t *ppos) |
249 | { | 229 | { |
250 | u32 val; | 230 | u32 val; |
251 | char buf[1024]; | 231 | char *buf; |
252 | ssize_t ret; | 232 | ssize_t ret; |
253 | int i; | 233 | int i; |
254 | int pos = 0; | 234 | int pos = 0; |
255 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 235 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
256 | const size_t bufsz = sizeof(buf); | 236 | size_t bufsz; |
257 | 237 | ||
238 | /* default is to dump the entire data segment */ | ||
239 | if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) { | ||
240 | priv->dbgfs->sram_offset = 0x800000; | ||
241 | if (priv->ucode_type == UCODE_INIT) | ||
242 | priv->dbgfs->sram_len = priv->ucode_init_data.len; | ||
243 | else | ||
244 | priv->dbgfs->sram_len = priv->ucode_data.len; | ||
245 | } | ||
246 | bufsz = 30 + priv->dbgfs->sram_len * sizeof(char) * 10; | ||
247 | buf = kmalloc(bufsz, GFP_KERNEL); | ||
248 | if (!buf) | ||
249 | return -ENOMEM; | ||
250 | pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", | ||
251 | priv->dbgfs->sram_len); | ||
252 | pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", | ||
253 | priv->dbgfs->sram_offset); | ||
258 | for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { | 254 | for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { |
259 | val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ | 255 | val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ |
260 | priv->dbgfs->sram_len - i); | 256 | priv->dbgfs->sram_len - i); |
@@ -271,11 +267,14 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
271 | break; | 267 | break; |
272 | } | 268 | } |
273 | } | 269 | } |
270 | if (!(i % 16)) | ||
271 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | ||
274 | pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); | 272 | pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); |
275 | } | 273 | } |
276 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 274 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
277 | 275 | ||
278 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 276 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
277 | kfree(buf); | ||
279 | return ret; | 278 | return ret; |
280 | } | 279 | } |
281 | 280 | ||
@@ -335,8 +334,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
335 | pos += scnprintf(buf + pos, bufsz - pos, | 334 | pos += scnprintf(buf + pos, bufsz - pos, |
336 | "flags: 0x%x\n", | 335 | "flags: 0x%x\n", |
337 | station->sta.station_flags_msk); | 336 | station->sta.station_flags_msk); |
338 | pos += scnprintf(buf + pos, bufsz - pos, | ||
339 | "ps_status: %u\n", station->ps_status); | ||
340 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); | 337 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); |
341 | pos += scnprintf(buf + pos, bufsz - pos, | 338 | pos += scnprintf(buf + pos, bufsz - pos, |
342 | "seq_num\t\ttxq_id"); | 339 | "seq_num\t\ttxq_id"); |
@@ -439,7 +436,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
439 | if (sscanf(buf, "%d", &event_log_flag) != 1) | 436 | if (sscanf(buf, "%d", &event_log_flag) != 1) |
440 | return -EFAULT; | 437 | return -EFAULT; |
441 | if (event_log_flag == 1) | 438 | if (event_log_flag == 1) |
442 | priv->cfg->ops->lib->dump_nic_event_log(priv); | 439 | priv->cfg->ops->lib->dump_nic_event_log(priv, true); |
443 | 440 | ||
444 | return count; | 441 | return count; |
445 | } | 442 | } |
@@ -986,7 +983,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
986 | int pos = 0; | 983 | int pos = 0; |
987 | int cnt; | 984 | int cnt; |
988 | int ret; | 985 | int ret; |
989 | const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues; | 986 | const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; |
990 | 987 | ||
991 | if (!priv->txq) { | 988 | if (!priv->txq) { |
992 | IWL_ERR(priv, "txq not ready\n"); | 989 | IWL_ERR(priv, "txq not ready\n"); |
@@ -1042,10 +1039,6 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, | |||
1042 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1039 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1043 | } | 1040 | } |
1044 | 1041 | ||
1045 | #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) | ||
1046 | #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) | ||
1047 | #define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2) | ||
1048 | |||
1049 | static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, | 1042 | static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, |
1050 | int bufsz) | 1043 | int bufsz) |
1051 | { | 1044 | { |
@@ -1092,7 +1085,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1092 | 1085 | ||
1093 | /* make request to uCode to retrieve statistics information */ | 1086 | /* make request to uCode to retrieve statistics information */ |
1094 | mutex_lock(&priv->mutex); | 1087 | mutex_lock(&priv->mutex); |
1095 | ret = iwl_send_statistics_request(priv, 0); | 1088 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1096 | mutex_unlock(&priv->mutex); | 1089 | mutex_unlock(&priv->mutex); |
1097 | 1090 | ||
1098 | if (ret) { | 1091 | if (ret) { |
@@ -1398,7 +1391,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1398 | 1391 | ||
1399 | /* make request to uCode to retrieve statistics information */ | 1392 | /* make request to uCode to retrieve statistics information */ |
1400 | mutex_lock(&priv->mutex); | 1393 | mutex_lock(&priv->mutex); |
1401 | ret = iwl_send_statistics_request(priv, 0); | 1394 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1402 | mutex_unlock(&priv->mutex); | 1395 | mutex_unlock(&priv->mutex); |
1403 | 1396 | ||
1404 | if (ret) { | 1397 | if (ret) { |
@@ -1542,7 +1535,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1542 | 1535 | ||
1543 | /* make request to uCode to retrieve statistics information */ | 1536 | /* make request to uCode to retrieve statistics information */ |
1544 | mutex_lock(&priv->mutex); | 1537 | mutex_lock(&priv->mutex); |
1545 | ret = iwl_send_statistics_request(priv, 0); | 1538 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1546 | mutex_unlock(&priv->mutex); | 1539 | mutex_unlock(&priv->mutex); |
1547 | 1540 | ||
1548 | if (ret) { | 1541 | if (ret) { |
@@ -1770,7 +1763,7 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file, | |||
1770 | else { | 1763 | else { |
1771 | /* make request to uCode to retrieve statistics information */ | 1764 | /* make request to uCode to retrieve statistics information */ |
1772 | mutex_lock(&priv->mutex); | 1765 | mutex_lock(&priv->mutex); |
1773 | ret = iwl_send_statistics_request(priv, 0); | 1766 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1774 | mutex_unlock(&priv->mutex); | 1767 | mutex_unlock(&priv->mutex); |
1775 | 1768 | ||
1776 | if (ret) { | 1769 | if (ret) { |
@@ -1828,8 +1821,32 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, | |||
1828 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1821 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1829 | } | 1822 | } |
1830 | 1823 | ||
1831 | DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); | 1824 | static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, |
1832 | DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); | 1825 | const char __user *user_buf, |
1826 | size_t count, loff_t *ppos) | ||
1827 | { | ||
1828 | struct iwl_priv *priv = file->private_data; | ||
1829 | char buf[8]; | ||
1830 | int buf_size; | ||
1831 | int clear; | ||
1832 | |||
1833 | memset(buf, 0, sizeof(buf)); | ||
1834 | buf_size = min(count, sizeof(buf) - 1); | ||
1835 | if (copy_from_user(buf, user_buf, buf_size)) | ||
1836 | return -EFAULT; | ||
1837 | if (sscanf(buf, "%d", &clear) != 1) | ||
1838 | return -EFAULT; | ||
1839 | |||
1840 | /* make request to uCode to retrieve statistics information */ | ||
1841 | mutex_lock(&priv->mutex); | ||
1842 | iwl_send_statistics_request(priv, CMD_SYNC, true); | ||
1843 | mutex_unlock(&priv->mutex); | ||
1844 | |||
1845 | return count; | ||
1846 | } | ||
1847 | |||
1848 | DEBUGFS_READ_FILE_OPS(rx_statistics); | ||
1849 | DEBUGFS_READ_FILE_OPS(tx_statistics); | ||
1833 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 1850 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
1834 | DEBUGFS_READ_FILE_OPS(rx_queue); | 1851 | DEBUGFS_READ_FILE_OPS(rx_queue); |
1835 | DEBUGFS_READ_FILE_OPS(tx_queue); | 1852 | DEBUGFS_READ_FILE_OPS(tx_queue); |
@@ -1840,6 +1857,8 @@ DEBUGFS_READ_FILE_OPS(sensitivity); | |||
1840 | DEBUGFS_READ_FILE_OPS(chain_noise); | 1857 | DEBUGFS_READ_FILE_OPS(chain_noise); |
1841 | DEBUGFS_READ_FILE_OPS(tx_power); | 1858 | DEBUGFS_READ_FILE_OPS(tx_power); |
1842 | DEBUGFS_READ_FILE_OPS(power_save_status); | 1859 | DEBUGFS_READ_FILE_OPS(power_save_status); |
1860 | DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); | ||
1861 | DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); | ||
1843 | 1862 | ||
1844 | /* | 1863 | /* |
1845 | * Create the debugfs files and directories | 1864 | * Create the debugfs files and directories |
@@ -1868,32 +1887,34 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1868 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); | 1887 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); |
1869 | DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); | 1888 | DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); |
1870 | DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); | 1889 | DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); |
1871 | DEBUGFS_ADD_FILE(nvm, data); | 1890 | DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); |
1872 | DEBUGFS_ADD_FILE(sram, data); | 1891 | DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); |
1873 | DEBUGFS_ADD_FILE(log_event, data); | 1892 | DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); |
1874 | DEBUGFS_ADD_FILE(stations, data); | 1893 | DEBUGFS_ADD_FILE(stations, data, S_IRUSR); |
1875 | DEBUGFS_ADD_FILE(channels, data); | 1894 | DEBUGFS_ADD_FILE(channels, data, S_IRUSR); |
1876 | DEBUGFS_ADD_FILE(status, data); | 1895 | DEBUGFS_ADD_FILE(status, data, S_IRUSR); |
1877 | DEBUGFS_ADD_FILE(interrupt, data); | 1896 | DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); |
1878 | DEBUGFS_ADD_FILE(qos, data); | 1897 | DEBUGFS_ADD_FILE(qos, data, S_IRUSR); |
1879 | DEBUGFS_ADD_FILE(led, data); | 1898 | DEBUGFS_ADD_FILE(led, data, S_IRUSR); |
1880 | DEBUGFS_ADD_FILE(sleep_level_override, data); | 1899 | DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); |
1881 | DEBUGFS_ADD_FILE(current_sleep_command, data); | 1900 | DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); |
1882 | DEBUGFS_ADD_FILE(thermal_throttling, data); | 1901 | DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); |
1883 | DEBUGFS_ADD_FILE(disable_ht40, data); | 1902 | DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); |
1884 | DEBUGFS_ADD_FILE(rx_statistics, debug); | 1903 | DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); |
1885 | DEBUGFS_ADD_FILE(tx_statistics, debug); | 1904 | DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); |
1886 | DEBUGFS_ADD_FILE(traffic_log, debug); | 1905 | DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); |
1887 | DEBUGFS_ADD_FILE(rx_queue, debug); | 1906 | DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); |
1888 | DEBUGFS_ADD_FILE(tx_queue, debug); | 1907 | DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); |
1889 | DEBUGFS_ADD_FILE(tx_power, debug); | 1908 | DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); |
1890 | DEBUGFS_ADD_FILE(power_save_status, debug); | 1909 | DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); |
1910 | DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); | ||
1911 | DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); | ||
1891 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 1912 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
1892 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug); | 1913 | DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); |
1893 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug); | 1914 | DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); |
1894 | DEBUGFS_ADD_FILE(ucode_general_stats, debug); | 1915 | DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); |
1895 | DEBUGFS_ADD_FILE(sensitivity, debug); | 1916 | DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); |
1896 | DEBUGFS_ADD_FILE(chain_noise, debug); | 1917 | DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); |
1897 | } | 1918 | } |
1898 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 1919 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
1899 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 1920 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
@@ -1941,6 +1962,10 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
1941 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); | 1962 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); |
1942 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); | 1963 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); |
1943 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); | 1964 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); |
1965 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. | ||
1966 | file_clear_ucode_statistics); | ||
1967 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. | ||
1968 | file_clear_traffic_statistics); | ||
1944 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 1969 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
1945 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. | 1970 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. |
1946 | file_ucode_rx_stats); | 1971 | file_ucode_rx_stats); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9dea8fa08c0e..2673e9a4db92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -52,19 +52,16 @@ extern struct iwl_cfg iwl4965_agn_cfg; | |||
52 | extern struct iwl_cfg iwl5300_agn_cfg; | 52 | extern struct iwl_cfg iwl5300_agn_cfg; |
53 | extern struct iwl_cfg iwl5100_agn_cfg; | 53 | extern struct iwl_cfg iwl5100_agn_cfg; |
54 | extern struct iwl_cfg iwl5350_agn_cfg; | 54 | extern struct iwl_cfg iwl5350_agn_cfg; |
55 | extern struct iwl_cfg iwl5100_bg_cfg; | 55 | extern struct iwl_cfg iwl5100_bgn_cfg; |
56 | extern struct iwl_cfg iwl5100_abg_cfg; | 56 | extern struct iwl_cfg iwl5100_abg_cfg; |
57 | extern struct iwl_cfg iwl5150_agn_cfg; | 57 | extern struct iwl_cfg iwl5150_agn_cfg; |
58 | extern struct iwl_cfg iwl6000h_2agn_cfg; | 58 | extern struct iwl_cfg iwl5150_abg_cfg; |
59 | extern struct iwl_cfg iwl6000h_2abg_cfg; | ||
60 | extern struct iwl_cfg iwl6000h_2bg_cfg; | ||
61 | extern struct iwl_cfg iwl6000i_2agn_cfg; | 59 | extern struct iwl_cfg iwl6000i_2agn_cfg; |
62 | extern struct iwl_cfg iwl6000i_2abg_cfg; | 60 | extern struct iwl_cfg iwl6000i_2abg_cfg; |
63 | extern struct iwl_cfg iwl6000i_2bg_cfg; | 61 | extern struct iwl_cfg iwl6000i_2bg_cfg; |
64 | extern struct iwl_cfg iwl6000_3agn_cfg; | 62 | extern struct iwl_cfg iwl6000_3agn_cfg; |
65 | extern struct iwl_cfg iwl6050_2agn_cfg; | 63 | extern struct iwl_cfg iwl6050_2agn_cfg; |
66 | extern struct iwl_cfg iwl6050_2abg_cfg; | 64 | extern struct iwl_cfg iwl6050_2abg_cfg; |
67 | extern struct iwl_cfg iwl6050_3agn_cfg; | ||
68 | extern struct iwl_cfg iwl1000_bgn_cfg; | 65 | extern struct iwl_cfg iwl1000_bgn_cfg; |
69 | extern struct iwl_cfg iwl1000_bg_cfg; | 66 | extern struct iwl_cfg iwl1000_bg_cfg; |
70 | 67 | ||
@@ -295,9 +292,6 @@ struct iwl_channel_info { | |||
295 | 292 | ||
296 | /* HT40 channel info */ | 293 | /* HT40 channel info */ |
297 | s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | 294 | s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ |
298 | s8 ht40_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ | ||
299 | s8 ht40_min_power; /* always 0 */ | ||
300 | s8 ht40_scan_power; /* (dBm) eeprom, direct scans, any rate */ | ||
301 | u8 ht40_flags; /* flags copied from EEPROM */ | 295 | u8 ht40_flags; /* flags copied from EEPROM */ |
302 | u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ | 296 | u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ |
303 | 297 | ||
@@ -518,7 +512,6 @@ struct iwl_ht_config { | |||
518 | bool is_ht; | 512 | bool is_ht; |
519 | bool is_40mhz; | 513 | bool is_40mhz; |
520 | bool single_chain_sufficient; | 514 | bool single_chain_sufficient; |
521 | u8 sm_ps; | ||
522 | /* BSS related data */ | 515 | /* BSS related data */ |
523 | u8 extension_chan_offset; | 516 | u8 extension_chan_offset; |
524 | u8 ht_protection; | 517 | u8 ht_protection; |
@@ -552,23 +545,10 @@ struct iwl_qos_info { | |||
552 | struct iwl_qosparam_cmd def_qos_parm; | 545 | struct iwl_qosparam_cmd def_qos_parm; |
553 | }; | 546 | }; |
554 | 547 | ||
555 | #define STA_PS_STATUS_WAKE 0 | ||
556 | #define STA_PS_STATUS_SLEEP 1 | ||
557 | |||
558 | |||
559 | struct iwl3945_station_entry { | ||
560 | struct iwl3945_addsta_cmd sta; | ||
561 | struct iwl_tid_data tid[MAX_TID_COUNT]; | ||
562 | u8 used; | ||
563 | u8 ps_status; | ||
564 | struct iwl_hw_key keyinfo; | ||
565 | }; | ||
566 | |||
567 | struct iwl_station_entry { | 548 | struct iwl_station_entry { |
568 | struct iwl_addsta_cmd sta; | 549 | struct iwl_addsta_cmd sta; |
569 | struct iwl_tid_data tid[MAX_TID_COUNT]; | 550 | struct iwl_tid_data tid[MAX_TID_COUNT]; |
570 | u8 used; | 551 | u8 used; |
571 | u8 ps_status; | ||
572 | struct iwl_hw_key keyinfo; | 552 | struct iwl_hw_key keyinfo; |
573 | }; | 553 | }; |
574 | 554 | ||
@@ -578,11 +558,12 @@ struct iwl_station_entry { | |||
578 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) | 558 | * When mac80211 creates a station it reserves some space (hw->sta_data_size) |
579 | * in the structure for use by driver. This structure is places in that | 559 | * in the structure for use by driver. This structure is places in that |
580 | * space. | 560 | * space. |
581 | * | ||
582 | * At the moment use it for the station's rate scaling information. | ||
583 | */ | 561 | */ |
584 | struct iwl_station_priv { | 562 | struct iwl_station_priv { |
585 | struct iwl_lq_sta lq_sta; | 563 | struct iwl_lq_sta lq_sta; |
564 | atomic_t pending_frames; | ||
565 | bool client; | ||
566 | bool asleep; | ||
586 | }; | 567 | }; |
587 | 568 | ||
588 | /* one for each uCode image (inst/data, boot/init/runtime) */ | 569 | /* one for each uCode image (inst/data, boot/init/runtime) */ |
@@ -1254,6 +1235,7 @@ struct iwl_priv { | |||
1254 | /* TX Power */ | 1235 | /* TX Power */ |
1255 | s8 tx_power_user_lmt; | 1236 | s8 tx_power_user_lmt; |
1256 | s8 tx_power_device_lmt; | 1237 | s8 tx_power_device_lmt; |
1238 | s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ | ||
1257 | 1239 | ||
1258 | 1240 | ||
1259 | #ifdef CONFIG_IWLWIFI_DEBUG | 1241 | #ifdef CONFIG_IWLWIFI_DEBUG |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 4ef5acaa556d..e7d88d1da15d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #define CREATE_TRACE_POINTS | 5 | #define CREATE_TRACE_POINTS |
6 | #include "iwl-devtrace.h" | 6 | #include "iwl-devtrace.h" |
7 | 7 | ||
8 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); | ||
8 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); | 9 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); |
9 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); | 10 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); |
10 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); | 11 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 8c7159208da1..21361968ab7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -14,7 +14,7 @@ static inline void trace_ ## name(proto) {} | |||
14 | #define PRIV_ASSIGN __entry->priv = priv | 14 | #define PRIV_ASSIGN __entry->priv = priv |
15 | 15 | ||
16 | #undef TRACE_SYSTEM | 16 | #undef TRACE_SYSTEM |
17 | #define TRACE_SYSTEM iwlwifi | 17 | #define TRACE_SYSTEM iwlwifi_io |
18 | 18 | ||
19 | TRACE_EVENT(iwlwifi_dev_ioread32, | 19 | TRACE_EVENT(iwlwifi_dev_ioread32, |
20 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 20 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), |
@@ -32,6 +32,22 @@ TRACE_EVENT(iwlwifi_dev_ioread32, | |||
32 | TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) | 32 | TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) |
33 | ); | 33 | ); |
34 | 34 | ||
35 | TRACE_EVENT(iwlwifi_dev_iowrite8, | ||
36 | TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), | ||
37 | TP_ARGS(priv, offs, val), | ||
38 | TP_STRUCT__entry( | ||
39 | PRIV_ENTRY | ||
40 | __field(u32, offs) | ||
41 | __field(u8, val) | ||
42 | ), | ||
43 | TP_fast_assign( | ||
44 | PRIV_ASSIGN; | ||
45 | __entry->offs = offs; | ||
46 | __entry->val = val; | ||
47 | ), | ||
48 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | ||
49 | ); | ||
50 | |||
35 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 51 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
36 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 52 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), |
37 | TP_ARGS(priv, offs, val), | 53 | TP_ARGS(priv, offs, val), |
@@ -48,6 +64,9 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, | |||
48 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 64 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) |
49 | ); | 65 | ); |
50 | 66 | ||
67 | #undef TRACE_SYSTEM | ||
68 | #define TRACE_SYSTEM iwlwifi | ||
69 | |||
51 | TRACE_EVENT(iwlwifi_dev_hcmd, | 70 | TRACE_EVENT(iwlwifi_dev_hcmd, |
52 | TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), | 71 | TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), |
53 | TP_ARGS(priv, hcmd, len, flags), | 72 | TP_ARGS(priv, hcmd, len, flags), |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 8a0709e81a9f..3946e5c03f81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -518,6 +518,11 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
518 | } | 518 | } |
519 | e = (u16 *)priv->eeprom; | 519 | e = (u16 *)priv->eeprom; |
520 | 520 | ||
521 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | ||
522 | /* OTP reads require powered-up chip */ | ||
523 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
524 | } | ||
525 | |||
521 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); | 526 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); |
522 | if (ret < 0) { | 527 | if (ret < 0) { |
523 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 528 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
@@ -532,10 +537,8 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
532 | ret = -ENOENT; | 537 | ret = -ENOENT; |
533 | goto err; | 538 | goto err; |
534 | } | 539 | } |
535 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | ||
536 | 540 | ||
537 | /* OTP reads require powered-up chip */ | 541 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { |
538 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
539 | 542 | ||
540 | ret = iwl_init_otp_access(priv); | 543 | ret = iwl_init_otp_access(priv); |
541 | if (ret) { | 544 | if (ret) { |
@@ -751,9 +754,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | |||
751 | 754 | ||
752 | ch_info->ht40_eeprom = *eeprom_ch; | 755 | ch_info->ht40_eeprom = *eeprom_ch; |
753 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; | 756 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; |
754 | ch_info->ht40_curr_txpow = eeprom_ch->max_power_avg; | ||
755 | ch_info->ht40_min_power = 0; | ||
756 | ch_info->ht40_scan_power = eeprom_ch->max_power_avg; | ||
757 | ch_info->ht40_flags = eeprom_ch->flags; | 757 | ch_info->ht40_flags = eeprom_ch->flags; |
758 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | 758 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; |
759 | 759 | ||
@@ -765,7 +765,8 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | |||
765 | * find the highest tx power from all chains for the channel | 765 | * find the highest tx power from all chains for the channel |
766 | */ | 766 | */ |
767 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | 767 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, |
768 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element) | 768 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
769 | int element, s8 *max_txpower_in_half_dbm) | ||
769 | { | 770 | { |
770 | s8 max_txpower_avg = 0; /* (dBm) */ | 771 | s8 max_txpower_avg = 0; /* (dBm) */ |
771 | 772 | ||
@@ -797,10 +798,14 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | |||
797 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) | 798 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) |
798 | max_txpower_avg = enhanced_txpower[element].mimo3_max; | 799 | max_txpower_avg = enhanced_txpower[element].mimo3_max; |
799 | 800 | ||
800 | /* max. tx power in EEPROM is in 1/2 dBm format | 801 | /* |
801 | * convert from 1/2 dBm to dBm | 802 | * max. tx power in EEPROM is in 1/2 dBm format |
803 | * convert from 1/2 dBm to dBm (round-up convert) | ||
804 | * but we also do not want to loss 1/2 dBm resolution which | ||
805 | * will impact performance | ||
802 | */ | 806 | */ |
803 | return max_txpower_avg >> 1; | 807 | *max_txpower_in_half_dbm = max_txpower_avg; |
808 | return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); | ||
804 | } | 809 | } |
805 | 810 | ||
806 | /** | 811 | /** |
@@ -809,7 +814,7 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | |||
809 | */ | 814 | */ |
810 | static s8 iwl_update_common_txpower(struct iwl_priv *priv, | 815 | static s8 iwl_update_common_txpower(struct iwl_priv *priv, |
811 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 816 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
812 | int section, int element) | 817 | int section, int element, s8 *max_txpower_in_half_dbm) |
813 | { | 818 | { |
814 | struct iwl_channel_info *ch_info; | 819 | struct iwl_channel_info *ch_info; |
815 | int ch; | 820 | int ch; |
@@ -823,25 +828,25 @@ static s8 iwl_update_common_txpower(struct iwl_priv *priv, | |||
823 | if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) | 828 | if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) |
824 | is_ht40 = true; | 829 | is_ht40 = true; |
825 | max_txpower_avg = | 830 | max_txpower_avg = |
826 | iwl_get_max_txpower_avg(priv, enhanced_txpower, element); | 831 | iwl_get_max_txpower_avg(priv, enhanced_txpower, |
832 | element, max_txpower_in_half_dbm); | ||
833 | |||
827 | ch_info = priv->channel_info; | 834 | ch_info = priv->channel_info; |
828 | 835 | ||
829 | for (ch = 0; ch < priv->channel_count; ch++) { | 836 | for (ch = 0; ch < priv->channel_count; ch++) { |
830 | /* find matching band and update tx power if needed */ | 837 | /* find matching band and update tx power if needed */ |
831 | if ((ch_info->band == enhinfo[section].band) && | 838 | if ((ch_info->band == enhinfo[section].band) && |
832 | (ch_info->max_power_avg < max_txpower_avg) && (!is_ht40)) { | 839 | (ch_info->max_power_avg < max_txpower_avg) && |
840 | (!is_ht40)) { | ||
833 | /* Update regulatory-based run-time data */ | 841 | /* Update regulatory-based run-time data */ |
834 | ch_info->max_power_avg = ch_info->curr_txpow = | 842 | ch_info->max_power_avg = ch_info->curr_txpow = |
835 | max_txpower_avg; | 843 | max_txpower_avg; |
836 | ch_info->scan_power = max_txpower_avg; | 844 | ch_info->scan_power = max_txpower_avg; |
837 | } | 845 | } |
838 | if ((ch_info->band == enhinfo[section].band) && is_ht40 && | 846 | if ((ch_info->band == enhinfo[section].band) && is_ht40 && |
839 | ch_info->ht40_max_power_avg && | ||
840 | (ch_info->ht40_max_power_avg < max_txpower_avg)) { | 847 | (ch_info->ht40_max_power_avg < max_txpower_avg)) { |
841 | /* Update regulatory-based run-time data */ | 848 | /* Update regulatory-based run-time data */ |
842 | ch_info->ht40_max_power_avg = max_txpower_avg; | 849 | ch_info->ht40_max_power_avg = max_txpower_avg; |
843 | ch_info->ht40_curr_txpow = max_txpower_avg; | ||
844 | ch_info->ht40_scan_power = max_txpower_avg; | ||
845 | } | 850 | } |
846 | ch_info++; | 851 | ch_info++; |
847 | } | 852 | } |
@@ -854,7 +859,7 @@ static s8 iwl_update_common_txpower(struct iwl_priv *priv, | |||
854 | */ | 859 | */ |
855 | static s8 iwl_update_channel_txpower(struct iwl_priv *priv, | 860 | static s8 iwl_update_channel_txpower(struct iwl_priv *priv, |
856 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 861 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
857 | int section, int element) | 862 | int section, int element, s8 *max_txpower_in_half_dbm) |
858 | { | 863 | { |
859 | struct iwl_channel_info *ch_info; | 864 | struct iwl_channel_info *ch_info; |
860 | int ch; | 865 | int ch; |
@@ -863,7 +868,8 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, | |||
863 | 868 | ||
864 | channel = enhinfo[section].iwl_eeprom_section_channel[element]; | 869 | channel = enhinfo[section].iwl_eeprom_section_channel[element]; |
865 | max_txpower_avg = | 870 | max_txpower_avg = |
866 | iwl_get_max_txpower_avg(priv, enhanced_txpower, element); | 871 | iwl_get_max_txpower_avg(priv, enhanced_txpower, |
872 | element, max_txpower_in_half_dbm); | ||
867 | 873 | ||
868 | ch_info = priv->channel_info; | 874 | ch_info = priv->channel_info; |
869 | for (ch = 0; ch < priv->channel_count; ch++) { | 875 | for (ch = 0; ch < priv->channel_count; ch++) { |
@@ -877,12 +883,9 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, | |||
877 | ch_info->scan_power = max_txpower_avg; | 883 | ch_info->scan_power = max_txpower_avg; |
878 | } | 884 | } |
879 | if ((enhinfo[section].is_ht40) && | 885 | if ((enhinfo[section].is_ht40) && |
880 | (ch_info->ht40_max_power_avg) && | ||
881 | (ch_info->ht40_max_power_avg < max_txpower_avg)) { | 886 | (ch_info->ht40_max_power_avg < max_txpower_avg)) { |
882 | /* Update regulatory-based run-time data */ | 887 | /* Update regulatory-based run-time data */ |
883 | ch_info->ht40_max_power_avg = max_txpower_avg; | 888 | ch_info->ht40_max_power_avg = max_txpower_avg; |
884 | ch_info->ht40_curr_txpow = max_txpower_avg; | ||
885 | ch_info->ht40_scan_power = max_txpower_avg; | ||
886 | } | 889 | } |
887 | break; | 890 | break; |
888 | } | 891 | } |
@@ -901,6 +904,7 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
901 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; | 904 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; |
902 | u32 offset; | 905 | u32 offset; |
903 | s8 max_txpower_avg; /* (dBm) */ | 906 | s8 max_txpower_avg; /* (dBm) */ |
907 | s8 max_txpower_in_half_dbm; /* (half-dBm) */ | ||
904 | 908 | ||
905 | /* Loop through all the sections | 909 | /* Loop through all the sections |
906 | * adjust bands and channel's max tx power | 910 | * adjust bands and channel's max tx power |
@@ -913,20 +917,43 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
913 | enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) | 917 | enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) |
914 | iwl_eeprom_query_addr(priv, offset); | 918 | iwl_eeprom_query_addr(priv, offset); |
915 | 919 | ||
920 | /* | ||
921 | * check for valid entry - | ||
922 | * different version of EEPROM might contain different set | ||
923 | * of enhanced tx power table | ||
924 | * always check for valid entry before process | ||
925 | * the information | ||
926 | */ | ||
927 | if (!enhanced_txpower->common || enhanced_txpower->reserved) | ||
928 | continue; | ||
929 | |||
916 | for (element = 0; element < eeprom_section_count; element++) { | 930 | for (element = 0; element < eeprom_section_count; element++) { |
917 | if (enhinfo[section].is_common) | 931 | if (enhinfo[section].is_common) |
918 | max_txpower_avg = | 932 | max_txpower_avg = |
919 | iwl_update_common_txpower(priv, | 933 | iwl_update_common_txpower(priv, |
920 | enhanced_txpower, section, element); | 934 | enhanced_txpower, section, |
935 | element, | ||
936 | &max_txpower_in_half_dbm); | ||
921 | else | 937 | else |
922 | max_txpower_avg = | 938 | max_txpower_avg = |
923 | iwl_update_channel_txpower(priv, | 939 | iwl_update_channel_txpower(priv, |
924 | enhanced_txpower, section, element); | 940 | enhanced_txpower, section, |
941 | element, | ||
942 | &max_txpower_in_half_dbm); | ||
925 | 943 | ||
926 | /* Update the tx_power_user_lmt to the highest power | 944 | /* Update the tx_power_user_lmt to the highest power |
927 | * supported by any channel */ | 945 | * supported by any channel */ |
928 | if (max_txpower_avg > priv->tx_power_user_lmt) | 946 | if (max_txpower_avg > priv->tx_power_user_lmt) |
929 | priv->tx_power_user_lmt = max_txpower_avg; | 947 | priv->tx_power_user_lmt = max_txpower_avg; |
948 | |||
949 | /* | ||
950 | * Update the tx_power_lmt_in_half_dbm to | ||
951 | * the highest power supported by any channel | ||
952 | */ | ||
953 | if (max_txpower_in_half_dbm > | ||
954 | priv->tx_power_lmt_in_half_dbm) | ||
955 | priv->tx_power_lmt_in_half_dbm = | ||
956 | max_txpower_in_half_dbm; | ||
930 | } | 957 | } |
931 | } | 958 | } |
932 | } | 959 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 5ba5a4e9e49a..5cd2b66bbe45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -127,19 +127,21 @@ struct iwl_eeprom_channel { | |||
127 | * Enhanced regulatory tx power portion of eeprom image can be broken down | 127 | * Enhanced regulatory tx power portion of eeprom image can be broken down |
128 | * into individual structures; each one is 8 bytes in size and contain the | 128 | * into individual structures; each one is 8 bytes in size and contain the |
129 | * following information | 129 | * following information |
130 | * @common: (desc + channel) not used by driver, should _NOT_ be "zero" | ||
130 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | 131 | * @chain_a_max_pwr: chain a max power in 1/2 dBm |
131 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | 132 | * @chain_b_max_pwr: chain b max power in 1/2 dBm |
132 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | 133 | * @chain_c_max_pwr: chain c max power in 1/2 dBm |
134 | * @reserved: not used, should be "zero" | ||
133 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | 135 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm |
134 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | 136 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm |
135 | * | 137 | * |
136 | */ | 138 | */ |
137 | struct iwl_eeprom_enhanced_txpwr { | 139 | struct iwl_eeprom_enhanced_txpwr { |
138 | u16 reserved; | 140 | u16 common; |
139 | s8 chain_a_max; | 141 | s8 chain_a_max; |
140 | s8 chain_b_max; | 142 | s8 chain_b_max; |
141 | s8 chain_c_max; | 143 | s8 chain_c_max; |
142 | s8 reserved1; | 144 | s8 reserved; |
143 | s8 mimo2_max; | 145 | s8 mimo2_max; |
144 | s8 mimo3_max; | 146 | s8 mimo3_max; |
145 | } __attribute__ ((packed)); | 147 | } __attribute__ ((packed)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index d0a358c9d96b..e552d4c4bdbe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -62,6 +62,26 @@ | |||
62 | * | 62 | * |
63 | */ | 63 | */ |
64 | 64 | ||
65 | static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) | ||
66 | { | ||
67 | trace_iwlwifi_dev_iowrite8(priv, ofs, val); | ||
68 | iowrite8(val, priv->hw_base + ofs); | ||
69 | } | ||
70 | |||
71 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
72 | static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv, | ||
73 | u32 ofs, u8 val) | ||
74 | { | ||
75 | IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l); | ||
76 | _iwl_write8(priv, ofs, val); | ||
77 | } | ||
78 | #define iwl_write8(priv, ofs, val) \ | ||
79 | __iwl_write8(__FILE__, __LINE__, priv, ofs, val) | ||
80 | #else | ||
81 | #define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val) | ||
82 | #endif | ||
83 | |||
84 | |||
65 | static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) | 85 | static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) |
66 | { | 86 | { |
67 | trace_iwlwifi_dev_iowrite32(priv, ofs, val); | 87 | trace_iwlwifi_dev_iowrite32(priv, ofs, val); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 478c90511ebf..46c7a95b88f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -219,7 +219,6 @@ EXPORT_SYMBOL(iwl_leds_background); | |||
219 | void iwl_leds_init(struct iwl_priv *priv) | 219 | void iwl_leds_init(struct iwl_priv *priv) |
220 | { | 220 | { |
221 | priv->last_blink_rate = 0; | 221 | priv->last_blink_rate = 0; |
222 | priv->led_tpt = 0; | ||
223 | priv->last_blink_time = 0; | 222 | priv->last_blink_time = 0; |
224 | priv->allow_blinking = 0; | 223 | priv->allow_blinking = 0; |
225 | } | 224 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 9bce2c1625e3..8ccc0bb1d9ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -506,7 +506,7 @@ static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) | |||
506 | { | 506 | { |
507 | IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); | 507 | IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); |
508 | /* make request to retrieve statistics information */ | 508 | /* make request to retrieve statistics information */ |
509 | iwl_send_statistics_request(priv, 0); | 509 | iwl_send_statistics_request(priv, CMD_SYNC, false); |
510 | /* Reschedule the ct_kill wait timer */ | 510 | /* Reschedule the ct_kill wait timer */ |
511 | mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, | 511 | mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, |
512 | jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); | 512 | jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 61b3b0e6ed73..6090bc15a6d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -477,7 +477,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
477 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | 477 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| |
478 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | 478 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); |
479 | 479 | ||
480 | iwl_write32(priv, CSR_INT_COALESCING, 0x40); | 480 | /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ |
481 | iwl_write8(priv, CSR_INT_COALESCING, 0x40); | ||
481 | 482 | ||
482 | return 0; | 483 | return 0; |
483 | } | 484 | } |
@@ -635,6 +636,24 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
635 | } | 636 | } |
636 | EXPORT_SYMBOL(iwl_rx_statistics); | 637 | EXPORT_SYMBOL(iwl_rx_statistics); |
637 | 638 | ||
639 | void iwl_reply_statistics(struct iwl_priv *priv, | ||
640 | struct iwl_rx_mem_buffer *rxb) | ||
641 | { | ||
642 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
643 | |||
644 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | ||
645 | memset(&priv->statistics, 0, | ||
646 | sizeof(struct iwl_notif_statistics)); | ||
647 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
648 | memset(&priv->accum_statistics, 0, | ||
649 | sizeof(struct iwl_notif_statistics)); | ||
650 | #endif | ||
651 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | ||
652 | } | ||
653 | iwl_rx_statistics(priv, rxb); | ||
654 | } | ||
655 | EXPORT_SYMBOL(iwl_reply_statistics); | ||
656 | |||
638 | #define PERFECT_RSSI (-20) /* dBm */ | 657 | #define PERFECT_RSSI (-20) /* dBm */ |
639 | #define WORST_RSSI (-95) /* dBm */ | 658 | #define WORST_RSSI (-95) /* dBm */ |
640 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | 659 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) |
@@ -1010,7 +1029,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1010 | struct iwl4965_rx_mpdu_res_start *amsdu; | 1029 | struct iwl4965_rx_mpdu_res_start *amsdu; |
1011 | u32 len; | 1030 | u32 len; |
1012 | u32 ampdu_status; | 1031 | u32 ampdu_status; |
1013 | u16 fc; | ||
1014 | u32 rate_n_flags; | 1032 | u32 rate_n_flags; |
1015 | 1033 | ||
1016 | /** | 1034 | /** |
@@ -1143,20 +1161,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1143 | priv->last_tsf = le64_to_cpu(phy_res->timestamp); | 1161 | priv->last_tsf = le64_to_cpu(phy_res->timestamp); |
1144 | } | 1162 | } |
1145 | 1163 | ||
1146 | fc = le16_to_cpu(header->frame_control); | 1164 | iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, |
1147 | switch (fc & IEEE80211_FCTL_FTYPE) { | 1165 | rxb, &rx_status); |
1148 | case IEEE80211_FTYPE_MGMT: | ||
1149 | case IEEE80211_FTYPE_DATA: | ||
1150 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
1151 | iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM, | ||
1152 | header->addr2); | ||
1153 | /* fall through */ | ||
1154 | default: | ||
1155 | iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, | ||
1156 | rxb, &rx_status); | ||
1157 | break; | ||
1158 | |||
1159 | } | ||
1160 | } | 1166 | } |
1161 | EXPORT_SYMBOL(iwl_rx_reply_rx); | 1167 | EXPORT_SYMBOL(iwl_rx_reply_rx); |
1162 | 1168 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index eba36f737388..cd6a6901216e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -1216,7 +1216,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid) | |||
1216 | } | 1216 | } |
1217 | EXPORT_SYMBOL(iwl_sta_rx_agg_stop); | 1217 | EXPORT_SYMBOL(iwl_sta_rx_agg_stop); |
1218 | 1218 | ||
1219 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | 1219 | void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) |
1220 | { | 1220 | { |
1221 | unsigned long flags; | 1221 | unsigned long flags; |
1222 | 1222 | ||
@@ -1224,27 +1224,26 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
1224 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | 1224 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; |
1225 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1225 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; |
1226 | priv->stations[sta_id].sta.sta.modify_mask = 0; | 1226 | priv->stations[sta_id].sta.sta.modify_mask = 0; |
1227 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1227 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1228 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1228 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1229 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1229 | 1230 | ||
1230 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 1231 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
1231 | } | 1232 | } |
1233 | EXPORT_SYMBOL(iwl_sta_modify_ps_wake); | ||
1232 | 1234 | ||
1233 | void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | 1235 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) |
1234 | { | 1236 | { |
1235 | /* FIXME: need locking over ps_status ??? */ | 1237 | unsigned long flags; |
1236 | u8 sta_id = iwl_find_station(priv, addr); | ||
1237 | 1238 | ||
1238 | if (sta_id != IWL_INVALID_STATION) { | 1239 | spin_lock_irqsave(&priv->sta_lock, flags); |
1239 | u8 sta_awake = priv->stations[sta_id]. | 1240 | priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; |
1240 | ps_status == STA_PS_STATUS_WAKE; | 1241 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; |
1242 | priv->stations[sta_id].sta.sta.modify_mask = | ||
1243 | STA_MODIFY_SLEEP_TX_COUNT_MSK; | ||
1244 | priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); | ||
1245 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1246 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1241 | 1247 | ||
1242 | if (sta_awake && ps_bit) | 1248 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
1243 | priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP; | ||
1244 | else if (!sta_awake && !ps_bit) { | ||
1245 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1246 | priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE; | ||
1247 | } | ||
1248 | } | ||
1249 | } | 1249 | } |
1250 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 1c382de80d49..8d052de2d405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -66,5 +66,6 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); | |||
66 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, | 66 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, |
67 | const u8 *addr, int tid, u16 ssn); | 67 | const u8 *addr, int tid, u16 ssn); |
68 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid); | 68 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid); |
69 | void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr); | 69 | void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); |
70 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); | ||
70 | #endif /* __iwl_sta_h__ */ | 71 | #endif /* __iwl_sta_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 6199bf60d313..888a8e9fe9ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -710,6 +710,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
710 | { | 710 | { |
711 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 711 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
712 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 712 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
713 | struct ieee80211_sta *sta = info->control.sta; | ||
714 | struct iwl_station_priv *sta_priv = NULL; | ||
713 | struct iwl_tx_queue *txq; | 715 | struct iwl_tx_queue *txq; |
714 | struct iwl_queue *q; | 716 | struct iwl_queue *q; |
715 | struct iwl_device_cmd *out_cmd; | 717 | struct iwl_device_cmd *out_cmd; |
@@ -772,6 +774,24 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
772 | 774 | ||
773 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); | 775 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); |
774 | 776 | ||
777 | if (sta) | ||
778 | sta_priv = (void *)sta->drv_priv; | ||
779 | |||
780 | if (sta_priv && sta_id != priv->hw_params.bcast_sta_id && | ||
781 | sta_priv->asleep) { | ||
782 | WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); | ||
783 | /* | ||
784 | * This sends an asynchronous command to the device, | ||
785 | * but we can rely on it being processed before the | ||
786 | * next frame is processed -- and the next frame to | ||
787 | * this station is the one that will consume this | ||
788 | * counter. | ||
789 | * For now set the counter to just 1 since we do not | ||
790 | * support uAPSD yet. | ||
791 | */ | ||
792 | iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); | ||
793 | } | ||
794 | |||
775 | txq_id = skb_get_queue_mapping(skb); | 795 | txq_id = skb_get_queue_mapping(skb); |
776 | if (ieee80211_is_data_qos(fc)) { | 796 | if (ieee80211_is_data_qos(fc)) { |
777 | qc = ieee80211_get_qos_ctl(hdr); | 797 | qc = ieee80211_get_qos_ctl(hdr); |
@@ -931,6 +951,17 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
931 | ret = iwl_txq_update_write_ptr(priv, txq); | 951 | ret = iwl_txq_update_write_ptr(priv, txq); |
932 | spin_unlock_irqrestore(&priv->lock, flags); | 952 | spin_unlock_irqrestore(&priv->lock, flags); |
933 | 953 | ||
954 | /* | ||
955 | * At this point the frame is "transmitted" successfully | ||
956 | * and we will get a TX status notification eventually, | ||
957 | * regardless of the value of ret. "ret" only indicates | ||
958 | * whether or not we should update the write pointer. | ||
959 | */ | ||
960 | |||
961 | /* avoid atomic ops if it isn't an associated client */ | ||
962 | if (sta_priv && sta_priv->client) | ||
963 | atomic_inc(&sta_priv->pending_frames); | ||
964 | |||
934 | if (ret) | 965 | if (ret) |
935 | return ret; | 966 | return ret; |
936 | 967 | ||
@@ -992,7 +1023,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
992 | } | 1023 | } |
993 | 1024 | ||
994 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 1025 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
995 | IWL_ERR(priv, "No space for Tx\n"); | 1026 | IWL_ERR(priv, "No space in command queue\n"); |
996 | if (iwl_within_ct_kill_margin(priv)) | 1027 | if (iwl_within_ct_kill_margin(priv)) |
997 | iwl_tt_enter_ct_kill(priv); | 1028 | iwl_tt_enter_ct_kill(priv); |
998 | else { | 1029 | else { |
@@ -1075,6 +1106,24 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1075 | return ret ? ret : idx; | 1106 | return ret ? ret : idx; |
1076 | } | 1107 | } |
1077 | 1108 | ||
1109 | static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | ||
1110 | { | ||
1111 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1112 | struct ieee80211_sta *sta; | ||
1113 | struct iwl_station_priv *sta_priv; | ||
1114 | |||
1115 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | ||
1116 | if (sta) { | ||
1117 | sta_priv = (void *)sta->drv_priv; | ||
1118 | /* avoid atomic ops if this isn't a client */ | ||
1119 | if (sta_priv->client && | ||
1120 | atomic_dec_return(&sta_priv->pending_frames) == 0) | ||
1121 | ieee80211_sta_block_awake(priv->hw, sta, false); | ||
1122 | } | ||
1123 | |||
1124 | ieee80211_tx_status_irqsafe(priv->hw, skb); | ||
1125 | } | ||
1126 | |||
1078 | int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | 1127 | int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) |
1079 | { | 1128 | { |
1080 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 1129 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
@@ -1094,7 +1143,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1094 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 1143 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
1095 | 1144 | ||
1096 | tx_info = &txq->txb[txq->q.read_ptr]; | 1145 | tx_info = &txq->txb[txq->q.read_ptr]; |
1097 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); | 1146 | iwl_tx_status(priv, tx_info->skb[0]); |
1098 | tx_info->skb[0] = NULL; | 1147 | tx_info->skb[0] = NULL; |
1099 | 1148 | ||
1100 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) | 1149 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
@@ -1264,7 +1313,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1264 | if (tid_data->tfds_in_queue == 0) { | 1313 | if (tid_data->tfds_in_queue == 0) { |
1265 | IWL_DEBUG_HT(priv, "HW queue is empty\n"); | 1314 | IWL_DEBUG_HT(priv, "HW queue is empty\n"); |
1266 | tid_data->agg.state = IWL_AGG_ON; | 1315 | tid_data->agg.state = IWL_AGG_ON; |
1267 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid); | 1316 | ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1268 | } else { | 1317 | } else { |
1269 | IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n", | 1318 | IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n", |
1270 | tid_data->tfds_in_queue); | 1319 | tid_data->tfds_in_queue); |
@@ -1329,7 +1378,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1329 | if (ret) | 1378 | if (ret) |
1330 | return ret; | 1379 | return ret; |
1331 | 1380 | ||
1332 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid); | 1381 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1333 | 1382 | ||
1334 | return 0; | 1383 | return 0; |
1335 | } | 1384 | } |
@@ -1353,7 +1402,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1353 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, | 1402 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, |
1354 | ssn, tx_fifo); | 1403 | ssn, tx_fifo); |
1355 | tid_data->agg.state = IWL_AGG_OFF; | 1404 | tid_data->agg.state = IWL_AGG_OFF; |
1356 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid); | 1405 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); |
1357 | } | 1406 | } |
1358 | break; | 1407 | break; |
1359 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 1408 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
@@ -1361,7 +1410,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1361 | if (tid_data->tfds_in_queue == 0) { | 1410 | if (tid_data->tfds_in_queue == 0) { |
1362 | IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); | 1411 | IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); |
1363 | tid_data->agg.state = IWL_AGG_ON; | 1412 | tid_data->agg.state = IWL_AGG_ON; |
1364 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid); | 1413 | ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); |
1365 | } | 1414 | } |
1366 | break; | 1415 | break; |
1367 | } | 1416 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 5d26330b43e8..0db9b79a69a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1483,7 +1483,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) | |||
1483 | tasklet_kill(&priv->irq_tasklet); | 1483 | tasklet_kill(&priv->irq_tasklet); |
1484 | } | 1484 | } |
1485 | 1485 | ||
1486 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1487 | static const char *desc_lookup(int i) | 1486 | static const char *desc_lookup(int i) |
1488 | { | 1487 | { |
1489 | switch (i) { | 1488 | switch (i) { |
@@ -1614,10 +1613,42 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1614 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | 1613 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); |
1615 | } | 1614 | } |
1616 | 1615 | ||
1616 | /** | ||
1617 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog | ||
1618 | */ | ||
1619 | static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | ||
1620 | u32 num_wraps, u32 next_entry, | ||
1621 | u32 size, u32 mode) | ||
1622 | { | ||
1623 | /* | ||
1624 | * display the newest DEFAULT_LOG_ENTRIES entries | ||
1625 | * i.e the entries just before the next ont that uCode would fill. | ||
1626 | */ | ||
1627 | if (num_wraps) { | ||
1628 | if (next_entry < size) { | ||
1629 | iwl3945_print_event_log(priv, | ||
1630 | capacity - (size - next_entry), | ||
1631 | size - next_entry, mode); | ||
1632 | iwl3945_print_event_log(priv, 0, | ||
1633 | next_entry, mode); | ||
1634 | } else | ||
1635 | iwl3945_print_event_log(priv, next_entry - size, | ||
1636 | size, mode); | ||
1637 | } else { | ||
1638 | if (next_entry < size) | ||
1639 | iwl3945_print_event_log(priv, 0, next_entry, mode); | ||
1640 | else | ||
1641 | iwl3945_print_event_log(priv, next_entry - size, | ||
1642 | size, mode); | ||
1643 | } | ||
1644 | } | ||
1645 | |||
1617 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | 1646 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
1618 | #define IWL3945_MAX_EVENT_LOG_SIZE (512) | 1647 | #define IWL3945_MAX_EVENT_LOG_SIZE (512) |
1619 | 1648 | ||
1620 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | 1649 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) |
1650 | |||
1651 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | ||
1621 | { | 1652 | { |
1622 | u32 base; /* SRAM byte address of event log header */ | 1653 | u32 base; /* SRAM byte address of event log header */ |
1623 | u32 capacity; /* event log capacity in # entries */ | 1654 | u32 capacity; /* event log capacity in # entries */ |
@@ -1658,8 +1689,17 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
1658 | return; | 1689 | return; |
1659 | } | 1690 | } |
1660 | 1691 | ||
1661 | IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", | 1692 | #ifdef CONFIG_IWLWIFI_DEBUG |
1662 | size, num_wraps); | 1693 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) |
1694 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | ||
1695 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | ||
1696 | #else | ||
1697 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | ||
1698 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | ||
1699 | #endif | ||
1700 | |||
1701 | IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", | ||
1702 | size); | ||
1663 | 1703 | ||
1664 | /* if uCode has wrapped back to top of log, start at the oldest entry, | 1704 | /* if uCode has wrapped back to top of log, start at the oldest entry, |
1665 | * i.e the next one that uCode would fill. */ | 1705 | * i.e the next one that uCode would fill. */ |
@@ -1670,18 +1710,28 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
1670 | /* (then/else) start at top of log */ | 1710 | /* (then/else) start at top of log */ |
1671 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1711 | iwl3945_print_event_log(priv, 0, next_entry, mode); |
1672 | 1712 | ||
1673 | } | 1713 | #ifdef CONFIG_IWLWIFI_DEBUG |
1714 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | ||
1715 | /* if uCode has wrapped back to top of log, | ||
1716 | * start at the oldest entry, | ||
1717 | * i.e the next one that uCode would fill. | ||
1718 | */ | ||
1719 | if (num_wraps) | ||
1720 | iwl3945_print_event_log(priv, next_entry, | ||
1721 | capacity - next_entry, mode); | ||
1722 | |||
1723 | /* (then/else) start at top of log */ | ||
1724 | iwl3945_print_event_log(priv, 0, next_entry, mode); | ||
1725 | } else | ||
1726 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, | ||
1727 | next_entry, size, mode); | ||
1674 | #else | 1728 | #else |
1675 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | 1729 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, |
1676 | { | 1730 | next_entry, size, mode); |
1677 | } | 1731 | #endif |
1678 | 1732 | ||
1679 | void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | ||
1680 | { | ||
1681 | } | 1733 | } |
1682 | 1734 | ||
1683 | #endif | ||
1684 | |||
1685 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) | 1735 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |
1686 | { | 1736 | { |
1687 | u32 inta, handled = 0; | 1737 | u32 inta, handled = 0; |
@@ -2494,7 +2544,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2494 | priv->active_rate = priv->rates_mask; | 2544 | priv->active_rate = priv->rates_mask; |
2495 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 2545 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
2496 | 2546 | ||
2497 | iwl_power_update_mode(priv, false); | 2547 | iwl_power_update_mode(priv, true); |
2498 | 2548 | ||
2499 | if (iwl_is_associated(priv)) { | 2549 | if (iwl_is_associated(priv)) { |
2500 | struct iwl3945_rxon_cmd *active_rxon = | 2550 | struct iwl3945_rxon_cmd *active_rxon = |
@@ -3650,7 +3700,7 @@ static ssize_t show_statistics(struct device *d, | |||
3650 | return -EAGAIN; | 3700 | return -EAGAIN; |
3651 | 3701 | ||
3652 | mutex_lock(&priv->mutex); | 3702 | mutex_lock(&priv->mutex); |
3653 | rc = iwl_send_statistics_request(priv, 0); | 3703 | rc = iwl_send_statistics_request(priv, CMD_SYNC, false); |
3654 | mutex_unlock(&priv->mutex); | 3704 | mutex_unlock(&priv->mutex); |
3655 | 3705 | ||
3656 | if (rc) { | 3706 | if (rc) { |
@@ -3905,10 +3955,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3905 | BIT(NL80211_IFTYPE_STATION) | | 3955 | BIT(NL80211_IFTYPE_STATION) | |
3906 | BIT(NL80211_IFTYPE_ADHOC); | 3956 | BIT(NL80211_IFTYPE_ADHOC); |
3907 | 3957 | ||
3908 | hw->wiphy->custom_regulatory = true; | 3958 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | |
3909 | 3959 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | |
3910 | /* Firmware does not support this */ | ||
3911 | hw->wiphy->disable_beacon_hints = true; | ||
3912 | 3960 | ||
3913 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; | 3961 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; |
3914 | /* we create the 802.11 header and a zero-length SSID element */ | 3962 | /* we create the 802.11 header and a zero-length SSID element */ |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index fc4ec48eda12..88e41176e7fd 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1146,46 +1146,46 @@ static int __init init_mac80211_hwsim(void) | |||
1146 | break; | 1146 | break; |
1147 | case HWSIM_REGTEST_WORLD_ROAM: | 1147 | case HWSIM_REGTEST_WORLD_ROAM: |
1148 | if (i == 0) { | 1148 | if (i == 0) { |
1149 | hw->wiphy->custom_regulatory = true; | 1149 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1150 | wiphy_apply_custom_regulatory(hw->wiphy, | 1150 | wiphy_apply_custom_regulatory(hw->wiphy, |
1151 | &hwsim_world_regdom_custom_01); | 1151 | &hwsim_world_regdom_custom_01); |
1152 | } | 1152 | } |
1153 | break; | 1153 | break; |
1154 | case HWSIM_REGTEST_CUSTOM_WORLD: | 1154 | case HWSIM_REGTEST_CUSTOM_WORLD: |
1155 | hw->wiphy->custom_regulatory = true; | 1155 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1156 | wiphy_apply_custom_regulatory(hw->wiphy, | 1156 | wiphy_apply_custom_regulatory(hw->wiphy, |
1157 | &hwsim_world_regdom_custom_01); | 1157 | &hwsim_world_regdom_custom_01); |
1158 | break; | 1158 | break; |
1159 | case HWSIM_REGTEST_CUSTOM_WORLD_2: | 1159 | case HWSIM_REGTEST_CUSTOM_WORLD_2: |
1160 | if (i == 0) { | 1160 | if (i == 0) { |
1161 | hw->wiphy->custom_regulatory = true; | 1161 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1162 | wiphy_apply_custom_regulatory(hw->wiphy, | 1162 | wiphy_apply_custom_regulatory(hw->wiphy, |
1163 | &hwsim_world_regdom_custom_01); | 1163 | &hwsim_world_regdom_custom_01); |
1164 | } else if (i == 1) { | 1164 | } else if (i == 1) { |
1165 | hw->wiphy->custom_regulatory = true; | 1165 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1166 | wiphy_apply_custom_regulatory(hw->wiphy, | 1166 | wiphy_apply_custom_regulatory(hw->wiphy, |
1167 | &hwsim_world_regdom_custom_02); | 1167 | &hwsim_world_regdom_custom_02); |
1168 | } | 1168 | } |
1169 | break; | 1169 | break; |
1170 | case HWSIM_REGTEST_STRICT_ALL: | 1170 | case HWSIM_REGTEST_STRICT_ALL: |
1171 | hw->wiphy->strict_regulatory = true; | 1171 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; |
1172 | break; | 1172 | break; |
1173 | case HWSIM_REGTEST_STRICT_FOLLOW: | 1173 | case HWSIM_REGTEST_STRICT_FOLLOW: |
1174 | case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: | 1174 | case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: |
1175 | if (i == 0) | 1175 | if (i == 0) |
1176 | hw->wiphy->strict_regulatory = true; | 1176 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; |
1177 | break; | 1177 | break; |
1178 | case HWSIM_REGTEST_ALL: | 1178 | case HWSIM_REGTEST_ALL: |
1179 | if (i == 0) { | 1179 | if (i == 0) { |
1180 | hw->wiphy->custom_regulatory = true; | 1180 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1181 | wiphy_apply_custom_regulatory(hw->wiphy, | 1181 | wiphy_apply_custom_regulatory(hw->wiphy, |
1182 | &hwsim_world_regdom_custom_01); | 1182 | &hwsim_world_regdom_custom_01); |
1183 | } else if (i == 1) { | 1183 | } else if (i == 1) { |
1184 | hw->wiphy->custom_regulatory = true; | 1184 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
1185 | wiphy_apply_custom_regulatory(hw->wiphy, | 1185 | wiphy_apply_custom_regulatory(hw->wiphy, |
1186 | &hwsim_world_regdom_custom_02); | 1186 | &hwsim_world_regdom_custom_02); |
1187 | } else if (i == 4) | 1187 | } else if (i == 4) |
1188 | hw->wiphy->strict_regulatory = true; | 1188 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; |
1189 | break; | 1189 | break; |
1190 | default: | 1190 | default: |
1191 | break; | 1191 | break; |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 4d486bf9f725..18012dbfb45d 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -579,7 +579,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
579 | * For now, disable PS by default because it affects | 579 | * For now, disable PS by default because it affects |
580 | * link stability significantly. | 580 | * link stability significantly. |
581 | */ | 581 | */ |
582 | dev->wiphy->ps_default = false; | 582 | dev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
583 | 583 | ||
584 | mutex_init(&priv->conf_mutex); | 584 | mutex_init(&priv->conf_mutex); |
585 | mutex_init(&priv->eeprom_mutex); | 585 | mutex_init(&priv->eeprom_mutex); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index aa1880add186..2ecbedb26e15 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -83,11 +83,11 @@ MODULE_PARM_DESC(roamdelta, | |||
83 | "set roaming tendency: 0=aggressive, 1=moderate, " | 83 | "set roaming tendency: 0=aggressive, 1=moderate, " |
84 | "2=conservative (default: moderate)"); | 84 | "2=conservative (default: moderate)"); |
85 | 85 | ||
86 | static int modparam_workaround_interval = 500; | 86 | static int modparam_workaround_interval; |
87 | module_param_named(workaround_interval, modparam_workaround_interval, | 87 | module_param_named(workaround_interval, modparam_workaround_interval, |
88 | int, 0444); | 88 | int, 0444); |
89 | MODULE_PARM_DESC(workaround_interval, | 89 | MODULE_PARM_DESC(workaround_interval, |
90 | "set stall workaround interval in msecs (default: 500)"); | 90 | "set stall workaround interval in msecs (0=disabled) (default: 0)"); |
91 | 91 | ||
92 | 92 | ||
93 | /* various RNDIS OID defs */ | 93 | /* various RNDIS OID defs */ |
@@ -733,12 +733,13 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
733 | le32_to_cpu(u.get_c->status)); | 733 | le32_to_cpu(u.get_c->status)); |
734 | 734 | ||
735 | if (ret == 0) { | 735 | if (ret == 0) { |
736 | memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); | ||
737 | |||
736 | ret = le32_to_cpu(u.get_c->len); | 738 | ret = le32_to_cpu(u.get_c->len); |
737 | if (ret > *len) | 739 | if (ret > *len) |
738 | *len = ret; | 740 | *len = ret; |
739 | memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); | ||
740 | ret = rndis_error_status(u.get_c->status); | ||
741 | 741 | ||
742 | ret = rndis_error_status(u.get_c->status); | ||
742 | if (ret < 0) | 743 | if (ret < 0) |
743 | devdbg(dev, "rndis_query_oid(%s): device returned " | 744 | devdbg(dev, "rndis_query_oid(%s): device returned " |
744 | "error, 0x%08x (%d)", oid_to_string(oid), | 745 | "error, 0x%08x (%d)", oid_to_string(oid), |
@@ -2549,7 +2550,7 @@ static void rndis_device_poller(struct work_struct *work) | |||
2549 | /* Workaround transfer stalls on poor quality links. | 2550 | /* Workaround transfer stalls on poor quality links. |
2550 | * TODO: find right way to fix these stalls (as stalls do not happen | 2551 | * TODO: find right way to fix these stalls (as stalls do not happen |
2551 | * with ndiswrapper/windows driver). */ | 2552 | * with ndiswrapper/windows driver). */ |
2552 | if (priv->last_qual <= 25) { | 2553 | if (priv->param_workaround_interval > 0 && priv->last_qual <= 25) { |
2553 | /* Decrease stats worker interval to catch stalls. | 2554 | /* Decrease stats worker interval to catch stalls. |
2554 | * faster. Faster than 400-500ms causes packet loss, | 2555 | * faster. Faster than 400-500ms causes packet loss, |
2555 | * Slower doesn't catch stalls fast enough. | 2556 | * Slower doesn't catch stalls fast enough. |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b1d63935f44d..9ab15c480701 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -824,17 +824,23 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
824 | { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, | 824 | { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, |
825 | /* Amit */ | 825 | /* Amit */ |
826 | { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, | 826 | { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, |
827 | /* Askey */ | ||
828 | { USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
829 | { USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
830 | { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
827 | /* ASUS */ | 831 | /* ASUS */ |
828 | { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, | 832 | { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) }, |
829 | { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, | 833 | { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) }, |
830 | { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, | 834 | { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) }, |
831 | { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, | 835 | { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) }, |
832 | { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, | 836 | { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) }, |
837 | { USB_DEVICE(0x0b05, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
833 | /* AzureWave */ | 838 | /* AzureWave */ |
834 | { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, | 839 | { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) }, |
835 | { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, | 840 | { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, |
836 | { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, | 841 | { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) }, |
837 | { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, | 842 | { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, |
843 | { USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
838 | /* Belkin */ | 844 | /* Belkin */ |
839 | { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, | 845 | { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, |
840 | { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 846 | { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -843,6 +849,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
843 | /* Buffalo */ | 849 | /* Buffalo */ |
844 | { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, | 850 | { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, |
845 | { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 851 | { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) }, |
852 | /* Cisco */ | ||
853 | { USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
846 | /* Conceptronic */ | 854 | /* Conceptronic */ |
847 | { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, | 855 | { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, |
848 | { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, | 856 | { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -858,6 +866,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
858 | { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 866 | { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
859 | { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 867 | { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, |
860 | { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 868 | { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
869 | { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
870 | { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
861 | { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, | 871 | { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, |
862 | { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, | 872 | { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, |
863 | /* D-Link */ | 873 | /* D-Link */ |
@@ -869,18 +879,24 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
869 | { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 879 | { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
870 | { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, | 880 | { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, |
871 | { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, | 881 | { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, |
882 | { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
872 | /* Edimax */ | 883 | /* Edimax */ |
873 | { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, | 884 | { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, |
874 | { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, | 885 | { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, |
875 | { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, | 886 | { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, |
876 | /* Encore */ | 887 | /* Encore */ |
877 | { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, | 888 | { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, |
889 | { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
890 | { USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
878 | /* EnGenius */ | 891 | /* EnGenius */ |
879 | { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, | 892 | { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, |
880 | { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, | 893 | { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, |
881 | { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, | 894 | { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) }, |
882 | { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, | 895 | { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) }, |
883 | { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, | 896 | { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) }, |
897 | { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
898 | { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
899 | { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
884 | { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, | 900 | { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, |
885 | /* Gemtek */ | 901 | /* Gemtek */ |
886 | { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, | 902 | { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -894,7 +910,10 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
894 | { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, | 910 | { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, |
895 | { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 911 | { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, |
896 | /* I-O DATA */ | 912 | /* I-O DATA */ |
913 | { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
897 | { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, | 914 | { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, |
915 | { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
916 | { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
898 | /* LevelOne */ | 917 | /* LevelOne */ |
899 | { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, | 918 | { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, |
900 | { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, | 919 | { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -909,8 +928,18 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
909 | /* Motorola */ | 928 | /* Motorola */ |
910 | { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, | 929 | { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, |
911 | { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, | 930 | { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, |
931 | /* MSI */ | ||
932 | { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
933 | { USB_DEVICE(0x0db0, 0x3821), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
934 | { USB_DEVICE(0x0db0, 0x3870), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
935 | { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
936 | { USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
937 | { USB_DEVICE(0x0db0, 0x870a), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
938 | { USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
912 | /* Ovislink */ | 939 | /* Ovislink */ |
913 | { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 940 | { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, |
941 | /* Para */ | ||
942 | { USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
914 | /* Pegatron */ | 943 | /* Pegatron */ |
915 | { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, | 944 | { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, |
916 | { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, | 945 | { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -926,8 +955,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
926 | /* Quanta */ | 955 | /* Quanta */ |
927 | { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, | 956 | { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, |
928 | /* Ralink */ | 957 | /* Ralink */ |
929 | { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
930 | { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
931 | { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 958 | { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, |
932 | { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, | 959 | { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, |
933 | { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, | 960 | { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -951,7 +978,12 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
951 | { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, | 978 | { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, |
952 | { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, | 979 | { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, |
953 | { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, | 980 | { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, |
981 | { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
954 | { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, | 982 | { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, |
983 | { USB_DEVICE(0x0df6, 0x0047), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
984 | { USB_DEVICE(0x0df6, 0x0048), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
985 | { USB_DEVICE(0x0df6, 0x004a), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
986 | { USB_DEVICE(0x0df6, 0x004d), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
955 | /* SMC */ | 987 | /* SMC */ |
956 | { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, | 988 | { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, |
957 | { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, | 989 | { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -960,6 +992,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
960 | { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 992 | { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) }, |
961 | { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, | 993 | { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, |
962 | { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, | 994 | { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) }, |
995 | { USB_DEVICE(0x083a, 0xa701), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
996 | { USB_DEVICE(0x083a, 0xa702), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
963 | { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 997 | { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) }, |
964 | { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 998 | { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, |
965 | /* Sparklan */ | 999 | /* Sparklan */ |
@@ -977,6 +1011,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
977 | { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1011 | { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, |
978 | { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1012 | { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, |
979 | { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1013 | { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1014 | { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
980 | { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1015 | { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, |
981 | /* Zyxel */ | 1016 | /* Zyxel */ |
982 | { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1017 | { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 6c6d0ac35549..4a4b7e42fe6e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -205,6 +205,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
205 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | 205 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); |
206 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | 206 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); |
207 | u8 rate_idx, rate_flags, retry_rates; | 207 | u8 rate_idx, rate_flags, retry_rates; |
208 | u8 skbdesc_flags = skbdesc->flags; | ||
208 | unsigned int i; | 209 | unsigned int i; |
209 | bool success; | 210 | bool success; |
210 | 211 | ||
@@ -287,12 +288,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
287 | } | 288 | } |
288 | 289 | ||
289 | /* | 290 | /* |
290 | * Only send the status report to mac80211 when TX status was | 291 | * Only send the status report to mac80211 when it's a frame |
291 | * requested by it. If this was a extra frame coming through | 292 | * that originated in mac80211. If this was a extra frame coming |
292 | * a mac80211 library call (RTS/CTS) then we should not send the | 293 | * through a mac80211 library call (RTS/CTS) then we should not |
293 | * status report back. | 294 | * send the status report back. |
294 | */ | 295 | */ |
295 | if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) | 296 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) |
296 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); | 297 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); |
297 | else | 298 | else |
298 | dev_kfree_skb_irq(entry->skb); | 299 | dev_kfree_skb_irq(entry->skb); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index c1f48acaee41..be2e37fb4071 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -162,8 +162,10 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length); | |||
162 | * rt2x00queue_write_tx_frame - Write TX frame to hardware | 162 | * rt2x00queue_write_tx_frame - Write TX frame to hardware |
163 | * @queue: Queue over which the frame should be send | 163 | * @queue: Queue over which the frame should be send |
164 | * @skb: The skb to send | 164 | * @skb: The skb to send |
165 | * @local: frame is not from mac80211 | ||
165 | */ | 166 | */ |
166 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | 167 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
168 | bool local); | ||
167 | 169 | ||
168 | /** | 170 | /** |
169 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware | 171 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index eed093d34532..9c90ceb0ffcc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -66,7 +66,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
66 | rts_info = IEEE80211_SKB_CB(skb); | 66 | rts_info = IEEE80211_SKB_CB(skb); |
67 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; | 67 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; |
68 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT; | 68 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT; |
69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
70 | 69 | ||
71 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 70 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
72 | rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; | 71 | rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; |
@@ -91,7 +90,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
91 | frag_skb->data, data_length, tx_info, | 90 | frag_skb->data, data_length, tx_info, |
92 | (struct ieee80211_rts *)(skb->data)); | 91 | (struct ieee80211_rts *)(skb->data)); |
93 | 92 | ||
94 | retval = rt2x00queue_write_tx_frame(queue, skb); | 93 | retval = rt2x00queue_write_tx_frame(queue, skb, true); |
95 | if (retval) { | 94 | if (retval) { |
96 | dev_kfree_skb_any(skb); | 95 | dev_kfree_skb_any(skb); |
97 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 96 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
@@ -153,7 +152,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
153 | goto exit_fail; | 152 | goto exit_fail; |
154 | } | 153 | } |
155 | 154 | ||
156 | if (rt2x00queue_write_tx_frame(queue, skb)) | 155 | if (rt2x00queue_write_tx_frame(queue, skb, false)) |
157 | goto exit_fail; | 156 | goto exit_fail; |
158 | 157 | ||
159 | if (rt2x00queue_threshold(queue)) | 158 | if (rt2x00queue_threshold(queue)) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 02972a036bce..eaedee8c05c8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -454,7 +454,8 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
454 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 454 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); |
455 | } | 455 | } |
456 | 456 | ||
457 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | 457 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
458 | bool local) | ||
458 | { | 459 | { |
459 | struct ieee80211_tx_info *tx_info; | 460 | struct ieee80211_tx_info *tx_info; |
460 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 461 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
@@ -495,6 +496,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
495 | skbdesc->tx_rate_idx = rate_idx; | 496 | skbdesc->tx_rate_idx = rate_idx; |
496 | skbdesc->tx_rate_flags = rate_flags; | 497 | skbdesc->tx_rate_flags = rate_flags; |
497 | 498 | ||
499 | if (local) | ||
500 | skbdesc->flags |= SKBDESC_NOT_MAC80211; | ||
501 | |||
498 | /* | 502 | /* |
499 | * When hardware encryption is supported, and this frame | 503 | * When hardware encryption is supported, and this frame |
500 | * is to be encrypted, we should strip the IV/EIV data from | 504 | * is to be encrypted, we should strip the IV/EIV data from |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 97c7895c0ece..70775e5ba1ac 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -94,12 +94,15 @@ enum data_queue_qid { | |||
94 | * mac80211 but was stripped for processing by the driver. | 94 | * mac80211 but was stripped for processing by the driver. |
95 | * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment, | 95 | * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment, |
96 | * the padded bytes are located between header and payload. | 96 | * the padded bytes are located between header and payload. |
97 | * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211, | ||
98 | * don't try to pass it back. | ||
97 | */ | 99 | */ |
98 | enum skb_frame_desc_flags { | 100 | enum skb_frame_desc_flags { |
99 | SKBDESC_DMA_MAPPED_RX = 1 << 0, | 101 | SKBDESC_DMA_MAPPED_RX = 1 << 0, |
100 | SKBDESC_DMA_MAPPED_TX = 1 << 1, | 102 | SKBDESC_DMA_MAPPED_TX = 1 << 1, |
101 | SKBDESC_IV_STRIPPED = 1 << 2, | 103 | SKBDESC_IV_STRIPPED = 1 << 2, |
102 | SKBDESC_L2_PADDED = 1 << 3 | 104 | SKBDESC_L2_PADDED = 1 << 3, |
105 | SKBDESC_NOT_MAC80211 = 1 << 4, | ||
103 | }; | 106 | }; |
104 | 107 | ||
105 | /** | 108 | /** |
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 998e4b6252bd..054533f7a124 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h | |||
@@ -269,6 +269,7 @@ struct wl1251 { | |||
269 | 269 | ||
270 | void (*set_power)(bool enable); | 270 | void (*set_power)(bool enable); |
271 | int irq; | 271 | int irq; |
272 | bool use_eeprom; | ||
272 | 273 | ||
273 | enum wl1251_state state; | 274 | enum wl1251_state state; |
274 | struct mutex mutex; | 275 | struct mutex mutex; |
@@ -354,6 +355,8 @@ struct wl1251 { | |||
354 | /* is firmware in elp mode */ | 355 | /* is firmware in elp mode */ |
355 | bool elp; | 356 | bool elp; |
356 | 357 | ||
358 | struct delayed_work elp_work; | ||
359 | |||
357 | /* we can be in psm, but not in elp, we have to differentiate */ | 360 | /* we can be in psm, but not in elp, we have to differentiate */ |
358 | bool psm; | 361 | bool psm; |
359 | 362 | ||
@@ -374,6 +377,8 @@ struct wl1251 { | |||
374 | u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; | 377 | u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; |
375 | struct wl1251_rx_descriptor *rx_descriptor; | 378 | struct wl1251_rx_descriptor *rx_descriptor; |
376 | 379 | ||
380 | struct ieee80211_vif *vif; | ||
381 | |||
377 | u32 chip_id; | 382 | u32 chip_id; |
378 | char fw_ver[21]; | 383 | char fw_ver[21]; |
379 | }; | 384 | }; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c index 10b26c4532c9..acfa086dbfc5 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl12xx/wl1251_acx.c | |||
@@ -494,7 +494,7 @@ out: | |||
494 | return ret; | 494 | return ret; |
495 | } | 495 | } |
496 | 496 | ||
497 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl) | 497 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter) |
498 | { | 498 | { |
499 | struct acx_beacon_filter_option *beacon_filter; | 499 | struct acx_beacon_filter_option *beacon_filter; |
500 | int ret; | 500 | int ret; |
@@ -507,7 +507,7 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl) | |||
507 | goto out; | 507 | goto out; |
508 | } | 508 | } |
509 | 509 | ||
510 | beacon_filter->enable = 0; | 510 | beacon_filter->enable = enable_filter; |
511 | beacon_filter->max_num_beacons = 0; | 511 | beacon_filter->max_num_beacons = 0; |
512 | 512 | ||
513 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, | 513 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT, |
@@ -525,6 +525,7 @@ out: | |||
525 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl) | 525 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl) |
526 | { | 526 | { |
527 | struct acx_beacon_filter_ie_table *ie_table; | 527 | struct acx_beacon_filter_ie_table *ie_table; |
528 | int idx = 0; | ||
528 | int ret; | 529 | int ret; |
529 | 530 | ||
530 | wl1251_debug(DEBUG_ACX, "acx beacon filter table"); | 531 | wl1251_debug(DEBUG_ACX, "acx beacon filter table"); |
@@ -535,8 +536,10 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl) | |||
535 | goto out; | 536 | goto out; |
536 | } | 537 | } |
537 | 538 | ||
538 | ie_table->num_ie = 0; | 539 | /* configure default beacon pass-through rules */ |
539 | memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE); | 540 | ie_table->num_ie = 1; |
541 | ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN; | ||
542 | ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE; | ||
540 | 543 | ||
541 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, | 544 | ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, |
542 | ie_table, sizeof(*ie_table)); | 545 | ie_table, sizeof(*ie_table)); |
@@ -550,6 +553,35 @@ out: | |||
550 | return ret; | 553 | return ret; |
551 | } | 554 | } |
552 | 555 | ||
556 | int wl1251_acx_conn_monit_params(struct wl1251 *wl) | ||
557 | { | ||
558 | struct acx_conn_monit_params *acx; | ||
559 | int ret; | ||
560 | |||
561 | wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); | ||
562 | |||
563 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
564 | if (!acx) { | ||
565 | ret = -ENOMEM; | ||
566 | goto out; | ||
567 | } | ||
568 | |||
569 | acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; | ||
570 | acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; | ||
571 | |||
572 | ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, | ||
573 | acx, sizeof(*acx)); | ||
574 | if (ret < 0) { | ||
575 | wl1251_warning("failed to set connection monitor " | ||
576 | "parameters: %d", ret); | ||
577 | goto out; | ||
578 | } | ||
579 | |||
580 | out: | ||
581 | kfree(acx); | ||
582 | return ret; | ||
583 | } | ||
584 | |||
553 | int wl1251_acx_sg_enable(struct wl1251 *wl) | 585 | int wl1251_acx_sg_enable(struct wl1251 *wl) |
554 | { | 586 | { |
555 | struct acx_bt_wlan_coex *pta; | 587 | struct acx_bt_wlan_coex *pta; |
@@ -916,3 +948,31 @@ out: | |||
916 | kfree(mem_conf); | 948 | kfree(mem_conf); |
917 | return ret; | 949 | return ret; |
918 | } | 950 | } |
951 | |||
952 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim) | ||
953 | { | ||
954 | struct wl1251_acx_wr_tbtt_and_dtim *acx; | ||
955 | int ret; | ||
956 | |||
957 | wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); | ||
958 | |||
959 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
960 | if (!acx) { | ||
961 | ret = -ENOMEM; | ||
962 | goto out; | ||
963 | } | ||
964 | |||
965 | acx->tbtt = tbtt; | ||
966 | acx->dtim = dtim; | ||
967 | |||
968 | ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM, | ||
969 | acx, sizeof(*acx)); | ||
970 | if (ret < 0) { | ||
971 | wl1251_warning("failed to set tbtt and dtim: %d", ret); | ||
972 | goto out; | ||
973 | } | ||
974 | |||
975 | out: | ||
976 | kfree(acx); | ||
977 | return ret; | ||
978 | } | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index cafb91459504..652371432cd8 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h | |||
@@ -450,6 +450,11 @@ struct acx_beacon_filter_option { | |||
450 | (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ | 450 | (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \ |
451 | BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) | 451 | BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE)) |
452 | 452 | ||
453 | #define BEACON_RULE_PASS_ON_CHANGE BIT(0) | ||
454 | #define BEACON_RULE_PASS_ON_APPEARANCE BIT(1) | ||
455 | |||
456 | #define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN (37) | ||
457 | |||
453 | struct acx_beacon_filter_ie_table { | 458 | struct acx_beacon_filter_ie_table { |
454 | struct acx_header header; | 459 | struct acx_header header; |
455 | 460 | ||
@@ -458,6 +463,16 @@ struct acx_beacon_filter_ie_table { | |||
458 | u8 pad[3]; | 463 | u8 pad[3]; |
459 | } __attribute__ ((packed)); | 464 | } __attribute__ ((packed)); |
460 | 465 | ||
466 | #define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ | ||
467 | #define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */ | ||
468 | |||
469 | struct acx_conn_monit_params { | ||
470 | struct acx_header header; | ||
471 | |||
472 | u32 synch_fail_thold; /* number of beacons missed */ | ||
473 | u32 bss_lose_timeout; /* number of TU's from synch fail */ | ||
474 | }; | ||
475 | |||
461 | enum { | 476 | enum { |
462 | SG_ENABLE = 0, | 477 | SG_ENABLE = 0, |
463 | SG_DISABLE, | 478 | SG_DISABLE, |
@@ -1134,6 +1149,23 @@ struct wl1251_acx_mem_map { | |||
1134 | u32 num_rx_mem_blocks; | 1149 | u32 num_rx_mem_blocks; |
1135 | } __attribute__ ((packed)); | 1150 | } __attribute__ ((packed)); |
1136 | 1151 | ||
1152 | |||
1153 | struct wl1251_acx_wr_tbtt_and_dtim { | ||
1154 | |||
1155 | struct acx_header header; | ||
1156 | |||
1157 | /* Time in TUs between two consecutive beacons */ | ||
1158 | u16 tbtt; | ||
1159 | |||
1160 | /* | ||
1161 | * DTIM period | ||
1162 | * For BSS: Number of TBTTs in a DTIM period (range: 1-10) | ||
1163 | * For IBSS: value shall be set to 1 | ||
1164 | */ | ||
1165 | u8 dtim; | ||
1166 | u8 padding; | ||
1167 | } __attribute__ ((packed)); | ||
1168 | |||
1137 | /************************************************************************* | 1169 | /************************************************************************* |
1138 | 1170 | ||
1139 | Host Interrupt Register (WiLink -> Host) | 1171 | Host Interrupt Register (WiLink -> Host) |
@@ -1273,8 +1305,9 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time); | |||
1273 | int wl1251_acx_group_address_tbl(struct wl1251 *wl); | 1305 | int wl1251_acx_group_address_tbl(struct wl1251 *wl); |
1274 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); | 1306 | int wl1251_acx_service_period_timeout(struct wl1251 *wl); |
1275 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); | 1307 | int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold); |
1276 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl); | 1308 | int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter); |
1277 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl); | 1309 | int wl1251_acx_beacon_filter_table(struct wl1251 *wl); |
1310 | int wl1251_acx_conn_monit_params(struct wl1251 *wl); | ||
1278 | int wl1251_acx_sg_enable(struct wl1251 *wl); | 1311 | int wl1251_acx_sg_enable(struct wl1251 *wl); |
1279 | int wl1251_acx_sg_cfg(struct wl1251 *wl); | 1312 | int wl1251_acx_sg_cfg(struct wl1251 *wl); |
1280 | int wl1251_acx_cca_threshold(struct wl1251 *wl); | 1313 | int wl1251_acx_cca_threshold(struct wl1251 *wl); |
@@ -1288,5 +1321,6 @@ int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats); | |||
1288 | int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); | 1321 | int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); |
1289 | int wl1251_acx_rate_policies(struct wl1251 *wl); | 1322 | int wl1251_acx_rate_policies(struct wl1251 *wl); |
1290 | int wl1251_acx_mem_cfg(struct wl1251 *wl); | 1323 | int wl1251_acx_mem_cfg(struct wl1251 *wl); |
1324 | int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); | ||
1291 | 1325 | ||
1292 | #endif /* __WL1251_ACX_H__ */ | 1326 | #endif /* __WL1251_ACX_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 452d748e42c6..2e733e7bdfd4 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c | |||
@@ -296,8 +296,12 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
296 | WL1251_ACX_INTR_INIT_COMPLETE; | 296 | WL1251_ACX_INTR_INIT_COMPLETE; |
297 | wl1251_boot_target_enable_interrupts(wl); | 297 | wl1251_boot_target_enable_interrupts(wl); |
298 | 298 | ||
299 | /* unmask all mbox events */ | 299 | wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID | |
300 | wl->event_mask = 0xffffffff; | 300 | SYNCHRONIZATION_TIMEOUT_EVENT_ID | |
301 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | | ||
302 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | | ||
303 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | | ||
304 | BT_PTA_PREDICTION_EVENT_ID; | ||
301 | 305 | ||
302 | ret = wl1251_event_unmask(wl); | 306 | ret = wl1251_event_unmask(wl); |
303 | if (ret < 0) { | 307 | if (ret < 0) { |
@@ -314,8 +318,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
314 | static int wl1251_boot_upload_firmware(struct wl1251 *wl) | 318 | static int wl1251_boot_upload_firmware(struct wl1251 *wl) |
315 | { | 319 | { |
316 | int addr, chunk_num, partition_limit; | 320 | int addr, chunk_num, partition_limit; |
317 | size_t fw_data_len; | 321 | size_t fw_data_len, len; |
318 | u8 *p; | 322 | u8 *p, *buf; |
319 | 323 | ||
320 | /* whal_FwCtrl_LoadFwImageSm() */ | 324 | /* whal_FwCtrl_LoadFwImageSm() */ |
321 | 325 | ||
@@ -334,6 +338,12 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
334 | return -EIO; | 338 | return -EIO; |
335 | } | 339 | } |
336 | 340 | ||
341 | buf = kmalloc(CHUNK_SIZE, GFP_KERNEL); | ||
342 | if (!buf) { | ||
343 | wl1251_error("allocation for firmware upload chunk failed"); | ||
344 | return -ENOMEM; | ||
345 | } | ||
346 | |||
337 | wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, | 347 | wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, |
338 | WL1251_PART_DOWN_MEM_SIZE, | 348 | WL1251_PART_DOWN_MEM_SIZE, |
339 | WL1251_PART_DOWN_REG_START, | 349 | WL1251_PART_DOWN_REG_START, |
@@ -364,7 +374,11 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
364 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; | 374 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; |
365 | wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", | 375 | wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", |
366 | p, addr); | 376 | p, addr); |
367 | wl1251_mem_write(wl, addr, p, CHUNK_SIZE); | 377 | |
378 | /* need to copy the chunk for dma */ | ||
379 | len = CHUNK_SIZE; | ||
380 | memcpy(buf, p, len); | ||
381 | wl1251_mem_write(wl, addr, buf, len); | ||
368 | 382 | ||
369 | chunk_num++; | 383 | chunk_num++; |
370 | } | 384 | } |
@@ -372,9 +386,16 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl) | |||
372 | /* 10.4 upload the last chunk */ | 386 | /* 10.4 upload the last chunk */ |
373 | addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; | 387 | addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; |
374 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; | 388 | p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; |
389 | |||
390 | /* need to copy the chunk for dma */ | ||
391 | len = fw_data_len % CHUNK_SIZE; | ||
392 | memcpy(buf, p, len); | ||
393 | |||
375 | wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", | 394 | wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", |
376 | fw_data_len % CHUNK_SIZE, p, addr); | 395 | len, p, addr); |
377 | wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE); | 396 | wl1251_mem_write(wl, addr, buf, len); |
397 | |||
398 | kfree(buf); | ||
378 | 399 | ||
379 | return 0; | 400 | return 0; |
380 | } | 401 | } |
@@ -473,13 +494,19 @@ int wl1251_boot(struct wl1251 *wl) | |||
473 | goto out; | 494 | goto out; |
474 | 495 | ||
475 | /* 2. start processing NVS file */ | 496 | /* 2. start processing NVS file */ |
476 | ret = wl1251_boot_upload_nvs(wl); | 497 | if (wl->use_eeprom) { |
477 | if (ret < 0) | 498 | wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); |
478 | goto out; | 499 | msleep(4000); |
479 | 500 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); | |
480 | /* write firmware's last address (ie. it's length) to | 501 | } else { |
481 | * ACX_EEPROMLESS_IND_REG */ | 502 | ret = wl1251_boot_upload_nvs(wl); |
482 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); | 503 | if (ret < 0) |
504 | goto out; | ||
505 | |||
506 | /* write firmware's last address (ie. it's length) to | ||
507 | * ACX_EEPROMLESS_IND_REG */ | ||
508 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); | ||
509 | } | ||
483 | 510 | ||
484 | /* 6. read the EEPROM parameters */ | 511 | /* 6. read the EEPROM parameters */ |
485 | tmp = wl1251_reg_read32(wl, SCR_PAD2); | 512 | tmp = wl1251_reg_read32(wl, SCR_PAD2); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c index 00076c4a8a21..020d764f9c13 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl12xx/wl1251_event.c | |||
@@ -79,6 +79,21 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { | ||
83 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); | ||
84 | |||
85 | /* indicate to the stack, that beacons have been lost */ | ||
86 | ieee80211_beacon_loss(wl->vif); | ||
87 | } | ||
88 | |||
89 | if (vector & REGAINED_BSS_EVENT_ID) { | ||
90 | if (wl->psm_requested) { | ||
91 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | ||
92 | if (ret < 0) | ||
93 | return ret; | ||
94 | } | ||
95 | } | ||
96 | |||
82 | return 0; | 97 | return 0; |
83 | } | 98 | } |
84 | 99 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c index b2ee4f468fc4..5cb573383eeb 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ b/drivers/net/wireless/wl12xx/wl1251_init.c | |||
@@ -147,7 +147,8 @@ int wl1251_hw_init_beacon_filter(struct wl1251 *wl) | |||
147 | { | 147 | { |
148 | int ret; | 148 | int ret; |
149 | 149 | ||
150 | ret = wl1251_acx_beacon_filter_opt(wl); | 150 | /* disable beacon filtering at this stage */ |
151 | ret = wl1251_acx_beacon_filter_opt(wl, false); | ||
151 | if (ret < 0) | 152 | if (ret < 0) |
152 | return ret; | 153 | return ret; |
153 | 154 | ||
@@ -364,6 +365,11 @@ int wl1251_hw_init(struct wl1251 *wl) | |||
364 | if (ret < 0) | 365 | if (ret < 0) |
365 | goto out_free_data_path; | 366 | goto out_free_data_path; |
366 | 367 | ||
368 | /* Initialize connection monitoring thresholds */ | ||
369 | ret = wl1251_acx_conn_monit_params(wl); | ||
370 | if (ret < 0) | ||
371 | goto out_free_data_path; | ||
372 | |||
367 | /* Beacon filtering */ | 373 | /* Beacon filtering */ |
368 | ret = wl1251_hw_init_beacon_filter(wl); | 374 | ret = wl1251_hw_init_beacon_filter(wl); |
369 | if (ret < 0) | 375 | if (ret < 0) |
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index d03a07e1be7c..ff4be7bf5d36 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/crc32.h> | 29 | #include <linux/crc32.h> |
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/vmalloc.h> | ||
31 | 32 | ||
32 | #include "wl1251.h" | 33 | #include "wl1251.h" |
33 | #include "wl12xx_80211.h" | 34 | #include "wl12xx_80211.h" |
@@ -83,7 +84,7 @@ static int wl1251_fetch_firmware(struct wl1251 *wl) | |||
83 | } | 84 | } |
84 | 85 | ||
85 | wl->fw_len = fw->size; | 86 | wl->fw_len = fw->size; |
86 | wl->fw = kmalloc(wl->fw_len, GFP_KERNEL); | 87 | wl->fw = vmalloc(wl->fw_len); |
87 | 88 | ||
88 | if (!wl->fw) { | 89 | if (!wl->fw) { |
89 | wl1251_error("could not allocate memory for the firmware"); | 90 | wl1251_error("could not allocate memory for the firmware"); |
@@ -211,9 +212,10 @@ out: | |||
211 | return ret; | 212 | return ret; |
212 | } | 213 | } |
213 | 214 | ||
215 | #define WL1251_IRQ_LOOP_COUNT 10 | ||
214 | static void wl1251_irq_work(struct work_struct *work) | 216 | static void wl1251_irq_work(struct work_struct *work) |
215 | { | 217 | { |
216 | u32 intr; | 218 | u32 intr, ctr = WL1251_IRQ_LOOP_COUNT; |
217 | struct wl1251 *wl = | 219 | struct wl1251 *wl = |
218 | container_of(work, struct wl1251, irq_work); | 220 | container_of(work, struct wl1251, irq_work); |
219 | int ret; | 221 | int ret; |
@@ -234,78 +236,86 @@ static void wl1251_irq_work(struct work_struct *work) | |||
234 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); | 236 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); |
235 | wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); | 237 | wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr); |
236 | 238 | ||
237 | if (wl->data_path) { | 239 | do { |
238 | wl->rx_counter = | 240 | if (wl->data_path) { |
239 | wl1251_mem_read32(wl, wl->data_path->rx_control_addr); | 241 | wl->rx_counter = wl1251_mem_read32( |
240 | 242 | wl, wl->data_path->rx_control_addr); | |
241 | /* We handle a frmware bug here */ | 243 | |
242 | switch ((wl->rx_counter - wl->rx_handled) & 0xf) { | 244 | /* We handle a frmware bug here */ |
243 | case 0: | 245 | switch ((wl->rx_counter - wl->rx_handled) & 0xf) { |
244 | wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync"); | 246 | case 0: |
245 | intr &= ~WL1251_ACX_INTR_RX0_DATA; | 247 | wl1251_debug(DEBUG_IRQ, |
246 | intr &= ~WL1251_ACX_INTR_RX1_DATA; | 248 | "RX: FW and host in sync"); |
247 | break; | 249 | intr &= ~WL1251_ACX_INTR_RX0_DATA; |
248 | case 1: | 250 | intr &= ~WL1251_ACX_INTR_RX1_DATA; |
249 | wl1251_debug(DEBUG_IRQ, "RX: FW +1"); | 251 | break; |
250 | intr |= WL1251_ACX_INTR_RX0_DATA; | 252 | case 1: |
251 | intr &= ~WL1251_ACX_INTR_RX1_DATA; | 253 | wl1251_debug(DEBUG_IRQ, "RX: FW +1"); |
252 | break; | 254 | intr |= WL1251_ACX_INTR_RX0_DATA; |
253 | case 2: | 255 | intr &= ~WL1251_ACX_INTR_RX1_DATA; |
254 | wl1251_debug(DEBUG_IRQ, "RX: FW +2"); | 256 | break; |
255 | intr |= WL1251_ACX_INTR_RX0_DATA; | 257 | case 2: |
256 | intr |= WL1251_ACX_INTR_RX1_DATA; | 258 | wl1251_debug(DEBUG_IRQ, "RX: FW +2"); |
257 | break; | 259 | intr |= WL1251_ACX_INTR_RX0_DATA; |
258 | default: | 260 | intr |= WL1251_ACX_INTR_RX1_DATA; |
259 | wl1251_warning("RX: FW and host out of sync: %d", | 261 | break; |
260 | wl->rx_counter - wl->rx_handled); | 262 | default: |
261 | break; | 263 | wl1251_warning( |
262 | } | 264 | "RX: FW and host out of sync: %d", |
263 | 265 | wl->rx_counter - wl->rx_handled); | |
264 | wl->rx_handled = wl->rx_counter; | 266 | break; |
267 | } | ||
265 | 268 | ||
269 | wl->rx_handled = wl->rx_counter; | ||
266 | 270 | ||
267 | wl1251_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter); | 271 | wl1251_debug(DEBUG_IRQ, "RX counter: %d", |
268 | } | 272 | wl->rx_counter); |
273 | } | ||
269 | 274 | ||
270 | intr &= wl->intr_mask; | 275 | intr &= wl->intr_mask; |
271 | 276 | ||
272 | if (intr == 0) { | 277 | if (intr == 0) { |
273 | wl1251_debug(DEBUG_IRQ, "INTR is 0"); | 278 | wl1251_debug(DEBUG_IRQ, "INTR is 0"); |
274 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, | 279 | goto out_sleep; |
275 | ~(wl->intr_mask)); | 280 | } |
276 | 281 | ||
277 | goto out_sleep; | 282 | if (intr & WL1251_ACX_INTR_RX0_DATA) { |
278 | } | 283 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); |
284 | wl1251_rx(wl); | ||
285 | } | ||
279 | 286 | ||
280 | if (intr & WL1251_ACX_INTR_RX0_DATA) { | 287 | if (intr & WL1251_ACX_INTR_RX1_DATA) { |
281 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA"); | 288 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); |
282 | wl1251_rx(wl); | 289 | wl1251_rx(wl); |
283 | } | 290 | } |
284 | 291 | ||
285 | if (intr & WL1251_ACX_INTR_RX1_DATA) { | 292 | if (intr & WL1251_ACX_INTR_TX_RESULT) { |
286 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA"); | 293 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); |
287 | wl1251_rx(wl); | 294 | wl1251_tx_complete(wl); |
288 | } | 295 | } |
289 | 296 | ||
290 | if (intr & WL1251_ACX_INTR_TX_RESULT) { | 297 | if (intr & (WL1251_ACX_INTR_EVENT_A | |
291 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT"); | 298 | WL1251_ACX_INTR_EVENT_B)) { |
292 | wl1251_tx_complete(wl); | 299 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", |
293 | } | 300 | intr); |
301 | if (intr & WL1251_ACX_INTR_EVENT_A) | ||
302 | wl1251_event_handle(wl, 0); | ||
303 | else | ||
304 | wl1251_event_handle(wl, 1); | ||
305 | } | ||
294 | 306 | ||
295 | if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) { | 307 | if (intr & WL1251_ACX_INTR_INIT_COMPLETE) |
296 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr); | 308 | wl1251_debug(DEBUG_IRQ, |
297 | if (intr & WL1251_ACX_INTR_EVENT_A) | 309 | "WL1251_ACX_INTR_INIT_COMPLETE"); |
298 | wl1251_event_handle(wl, 0); | ||
299 | else | ||
300 | wl1251_event_handle(wl, 1); | ||
301 | } | ||
302 | 310 | ||
303 | if (intr & WL1251_ACX_INTR_INIT_COMPLETE) | 311 | if (--ctr == 0) |
304 | wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE"); | 312 | break; |
305 | 313 | ||
306 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); | 314 | intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); |
315 | } while (intr); | ||
307 | 316 | ||
308 | out_sleep: | 317 | out_sleep: |
318 | wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask)); | ||
309 | wl1251_ps_elp_sleep(wl); | 319 | wl1251_ps_elp_sleep(wl); |
310 | 320 | ||
311 | out: | 321 | out: |
@@ -509,6 +519,12 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, | |||
509 | conf->type, conf->mac_addr); | 519 | conf->type, conf->mac_addr); |
510 | 520 | ||
511 | mutex_lock(&wl->mutex); | 521 | mutex_lock(&wl->mutex); |
522 | if (wl->vif) { | ||
523 | ret = -EBUSY; | ||
524 | goto out; | ||
525 | } | ||
526 | |||
527 | wl->vif = conf->vif; | ||
512 | 528 | ||
513 | switch (conf->type) { | 529 | switch (conf->type) { |
514 | case NL80211_IFTYPE_STATION: | 530 | case NL80211_IFTYPE_STATION: |
@@ -538,7 +554,12 @@ out: | |||
538 | static void wl1251_op_remove_interface(struct ieee80211_hw *hw, | 554 | static void wl1251_op_remove_interface(struct ieee80211_hw *hw, |
539 | struct ieee80211_if_init_conf *conf) | 555 | struct ieee80211_if_init_conf *conf) |
540 | { | 556 | { |
557 | struct wl1251 *wl = hw->priv; | ||
558 | |||
559 | mutex_lock(&wl->mutex); | ||
541 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 560 | wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
561 | wl->vif = NULL; | ||
562 | mutex_unlock(&wl->mutex); | ||
542 | } | 563 | } |
543 | 564 | ||
544 | static int wl1251_build_null_data(struct wl1251 *wl) | 565 | static int wl1251_build_null_data(struct wl1251 *wl) |
@@ -555,7 +576,8 @@ static int wl1251_build_null_data(struct wl1251 *wl) | |||
555 | 576 | ||
556 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); | 577 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); |
557 | template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | | 578 | template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | |
558 | IEEE80211_STYPE_NULLFUNC); | 579 | IEEE80211_STYPE_NULLFUNC | |
580 | IEEE80211_FCTL_TODS); | ||
559 | 581 | ||
560 | return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template, | 582 | return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template, |
561 | sizeof(template)); | 583 | sizeof(template)); |
@@ -568,7 +590,10 @@ static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid) | |||
568 | 590 | ||
569 | memcpy(template.bssid, wl->bssid, ETH_ALEN); | 591 | memcpy(template.bssid, wl->bssid, ETH_ALEN); |
570 | memcpy(template.ta, wl->mac_addr, ETH_ALEN); | 592 | memcpy(template.ta, wl->mac_addr, ETH_ALEN); |
571 | template.aid = aid; | 593 | |
594 | /* aid in PS-Poll has its two MSBs each set to 1 */ | ||
595 | template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid); | ||
596 | |||
572 | template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | 597 | template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); |
573 | 598 | ||
574 | return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, | 599 | return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, |
@@ -1090,8 +1115,8 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1090 | wl->beacon_int = bss_conf->beacon_int; | 1115 | wl->beacon_int = bss_conf->beacon_int; |
1091 | wl->dtim_period = bss_conf->dtim_period; | 1116 | wl->dtim_period = bss_conf->dtim_period; |
1092 | 1117 | ||
1093 | /* FIXME: call join */ | 1118 | ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, |
1094 | 1119 | wl->dtim_period); | |
1095 | wl->aid = bss_conf->aid; | 1120 | wl->aid = bss_conf->aid; |
1096 | 1121 | ||
1097 | ret = wl1251_build_ps_poll(wl, wl->aid); | 1122 | ret = wl1251_build_ps_poll(wl, wl->aid); |
@@ -1312,7 +1337,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1312 | 1337 | ||
1313 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1338 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
1314 | IEEE80211_HW_NOISE_DBM | | 1339 | IEEE80211_HW_NOISE_DBM | |
1315 | IEEE80211_HW_SUPPORTS_PS; | 1340 | IEEE80211_HW_SUPPORTS_PS | |
1341 | IEEE80211_HW_BEACON_FILTER; | ||
1316 | 1342 | ||
1317 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | 1343 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); |
1318 | wl->hw->wiphy->max_scan_ssids = 1; | 1344 | wl->hw->wiphy->max_scan_ssids = 1; |
@@ -1355,6 +1381,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1355 | skb_queue_head_init(&wl->tx_queue); | 1381 | skb_queue_head_init(&wl->tx_queue); |
1356 | 1382 | ||
1357 | INIT_WORK(&wl->filter_work, wl1251_filter_work); | 1383 | INIT_WORK(&wl->filter_work, wl1251_filter_work); |
1384 | INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); | ||
1358 | wl->channel = WL1251_DEFAULT_CHANNEL; | 1385 | wl->channel = WL1251_DEFAULT_CHANNEL; |
1359 | wl->scanning = false; | 1386 | wl->scanning = false; |
1360 | wl->default_key = 0; | 1387 | wl->default_key = 0; |
@@ -1372,6 +1399,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1372 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 1399 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
1373 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; | 1400 | wl->beacon_int = WL1251_DEFAULT_BEACON_INT; |
1374 | wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; | 1401 | wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; |
1402 | wl->vif = NULL; | ||
1375 | 1403 | ||
1376 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) | 1404 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) |
1377 | wl->tx_frames[i] = NULL; | 1405 | wl->tx_frames[i] = NULL; |
@@ -1413,7 +1441,7 @@ int wl1251_free_hw(struct wl1251 *wl) | |||
1413 | 1441 | ||
1414 | kfree(wl->target_mem_map); | 1442 | kfree(wl->target_mem_map); |
1415 | kfree(wl->data_path); | 1443 | kfree(wl->data_path); |
1416 | kfree(wl->fw); | 1444 | vfree(wl->fw); |
1417 | wl->fw = NULL; | 1445 | wl->fw = NULL; |
1418 | kfree(wl->nvs); | 1446 | kfree(wl->nvs); |
1419 | wl->nvs = NULL; | 1447 | wl->nvs = NULL; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index c53e28727ed4..9931b197ff77 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c | |||
@@ -28,17 +28,41 @@ | |||
28 | 28 | ||
29 | #define WL1251_WAKEUP_TIMEOUT 2000 | 29 | #define WL1251_WAKEUP_TIMEOUT 2000 |
30 | 30 | ||
31 | /* Routines to toggle sleep mode while in ELP */ | 31 | void wl1251_elp_work(struct work_struct *work) |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
33 | { | 32 | { |
33 | struct delayed_work *dwork; | ||
34 | struct wl1251 *wl; | ||
35 | |||
36 | dwork = container_of(work, struct delayed_work, work); | ||
37 | wl = container_of(dwork, struct wl1251, elp_work); | ||
38 | |||
39 | wl1251_debug(DEBUG_PSM, "elp work"); | ||
40 | |||
41 | mutex_lock(&wl->mutex); | ||
42 | |||
34 | if (wl->elp || !wl->psm) | 43 | if (wl->elp || !wl->psm) |
35 | return; | 44 | goto out; |
36 | 45 | ||
37 | wl1251_debug(DEBUG_PSM, "chip to elp"); | 46 | wl1251_debug(DEBUG_PSM, "chip to elp"); |
38 | |||
39 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); | 47 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); |
40 | |||
41 | wl->elp = true; | 48 | wl->elp = true; |
49 | |||
50 | out: | ||
51 | mutex_unlock(&wl->mutex); | ||
52 | } | ||
53 | |||
54 | #define ELP_ENTRY_DELAY 5 | ||
55 | |||
56 | /* Routines to toggle sleep mode while in ELP */ | ||
57 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
58 | { | ||
59 | unsigned long delay; | ||
60 | |||
61 | if (wl->psm) { | ||
62 | cancel_delayed_work(&wl->elp_work); | ||
63 | delay = msecs_to_jiffies(ELP_ENTRY_DELAY); | ||
64 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); | ||
65 | } | ||
42 | } | 66 | } |
43 | 67 | ||
44 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) | 68 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) |
@@ -119,6 +143,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
119 | case STATION_POWER_SAVE_MODE: | 143 | case STATION_POWER_SAVE_MODE: |
120 | wl1251_debug(DEBUG_PSM, "entering psm"); | 144 | wl1251_debug(DEBUG_PSM, "entering psm"); |
121 | 145 | ||
146 | /* enable beacon filtering */ | ||
147 | ret = wl1251_acx_beacon_filter_opt(wl, true); | ||
148 | if (ret < 0) | ||
149 | return ret; | ||
150 | |||
122 | ret = wl1251_acx_wake_up_conditions(wl, | 151 | ret = wl1251_acx_wake_up_conditions(wl, |
123 | WAKE_UP_EVENT_DTIM_BITMAP, | 152 | WAKE_UP_EVENT_DTIM_BITMAP, |
124 | wl->listen_int); | 153 | wl->listen_int); |
@@ -142,6 +171,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
142 | if (ret < 0) | 171 | if (ret < 0) |
143 | return ret; | 172 | return ret; |
144 | 173 | ||
174 | /* disable beacon filtering */ | ||
175 | ret = wl1251_acx_beacon_filter_opt(wl, false); | ||
176 | if (ret < 0) | ||
177 | return ret; | ||
178 | |||
145 | ret = wl1251_acx_wake_up_conditions(wl, | 179 | ret = wl1251_acx_wake_up_conditions(wl, |
146 | WAKE_UP_EVENT_DTIM_BITMAP, | 180 | WAKE_UP_EVENT_DTIM_BITMAP, |
147 | wl->listen_int); | 181 | wl->listen_int); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h index db036fe12f25..c688ac57aee4 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ b/drivers/net/wireless/wl12xx/wl1251_ps.h | |||
@@ -31,6 +31,7 @@ | |||
31 | int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); | 31 | int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl); | 32 | void wl1251_ps_elp_sleep(struct wl1251 *wl); |
33 | int wl1251_ps_elp_wakeup(struct wl1251 *wl); | 33 | int wl1251_ps_elp_wakeup(struct wl1251 *wl); |
34 | void wl1251_elp_work(struct work_struct *work); | ||
34 | 35 | ||
35 | 36 | ||
36 | #endif /* __WL1251_PS_H__ */ | 37 | #endif /* __WL1251_PS_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h index 06e1bd94a739..0ca3b4326056 100644 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ b/drivers/net/wireless/wl12xx/wl1251_reg.h | |||
@@ -370,6 +370,7 @@ enum wl12xx_acx_int_reg { | |||
370 | EEPROM location specified in the EE_ADDR register. | 370 | EEPROM location specified in the EE_ADDR register. |
371 | The Wlan hardware hardware clears this bit automatically. | 371 | The Wlan hardware hardware clears this bit automatically. |
372 | *===============================================*/ | 372 | *===============================================*/ |
373 | #define EE_CTL (REGISTERS_BASE + 0x2000) | ||
373 | #define ACX_EE_CTL_REG EE_CTL | 374 | #define ACX_EE_CTL_REG EE_CTL |
374 | #define EE_WRITE 0x00000001ul | 375 | #define EE_WRITE 0x00000001ul |
375 | #define EE_READ 0x00000002ul | 376 | #define EE_READ 0x00000002ul |
@@ -380,6 +381,7 @@ enum wl12xx_acx_int_reg { | |||
380 | This register specifies the address | 381 | This register specifies the address |
381 | within the EEPROM from/to which to read/write data. | 382 | within the EEPROM from/to which to read/write data. |
382 | ===============================================*/ | 383 | ===============================================*/ |
384 | #define EE_ADDR (REGISTERS_BASE + 0x2008) | ||
383 | #define ACX_EE_ADDR_REG EE_ADDR | 385 | #define ACX_EE_ADDR_REG EE_ADDR |
384 | 386 | ||
385 | /*=============================================== | 387 | /*=============================================== |
@@ -389,8 +391,12 @@ enum wl12xx_acx_int_reg { | |||
389 | data from the EEPROM or the write data | 391 | data from the EEPROM or the write data |
390 | to be written to the EEPROM. | 392 | to be written to the EEPROM. |
391 | ===============================================*/ | 393 | ===============================================*/ |
394 | #define EE_DATA (REGISTERS_BASE + 0x2004) | ||
392 | #define ACX_EE_DATA_REG EE_DATA | 395 | #define ACX_EE_DATA_REG EE_DATA |
393 | 396 | ||
397 | #define EEPROM_ACCESS_TO 10000 /* timeout counter */ | ||
398 | #define START_EEPROM_MGR 0x00000001 | ||
399 | |||
394 | /*=============================================== | 400 | /*=============================================== |
395 | EEPROM Base Address - 32bit RW | 401 | EEPROM Base Address - 32bit RW |
396 | ------------------------------------------ | 402 | ------------------------------------------ |
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index 601fe0d67827..f84cc89cbffc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c | |||
@@ -72,10 +72,6 @@ static void wl1251_rx_status(struct wl1251 *wl, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | status->signal = desc->rssi; | 74 | status->signal = desc->rssi; |
75 | status->qual = (desc->rssi - WL1251_RX_MIN_RSSI) * 100 / | ||
76 | (WL1251_RX_MAX_RSSI - WL1251_RX_MIN_RSSI); | ||
77 | status->qual = min(status->qual, 100); | ||
78 | status->qual = max(status->qual, 0); | ||
79 | 75 | ||
80 | /* | 76 | /* |
81 | * FIXME: guessing that snr needs to be divided by two, otherwise | 77 | * FIXME: guessing that snr needs to be divided by two, otherwise |
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 2cf8a2169d43..9cc8c323830f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c | |||
@@ -270,6 +270,8 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi) | |||
270 | return -ENODEV; | 270 | return -ENODEV; |
271 | } | 271 | } |
272 | 272 | ||
273 | wl->use_eeprom = pdata->use_eeprom; | ||
274 | |||
273 | ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); | 275 | ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); |
274 | if (ret < 0) { | 276 | if (ret < 0) { |
275 | wl1251_error("request_irq() failed: %d", ret); | 277 | wl1251_error("request_irq() failed: %d", ret); |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 4f1e0cfe609b..891bdab49887 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -381,7 +381,7 @@ static void wl3501_free_tx_buffer(struct wl3501_card *this, u16 ptr) | |||
381 | 381 | ||
382 | static int wl3501_esbq_req_test(struct wl3501_card *this) | 382 | static int wl3501_esbq_req_test(struct wl3501_card *this) |
383 | { | 383 | { |
384 | u8 tmp; | 384 | u8 tmp = 0; |
385 | 385 | ||
386 | wl3501_get_from_wla(this, this->esbq_req_head + 3, &tmp, sizeof(tmp)); | 386 | wl3501_get_from_wla(this, this->esbq_req_head + 3, &tmp, sizeof(tmp)); |
387 | return tmp & 0x80; | 387 | return tmp & 0x80; |