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 | |
| 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')
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; |
