diff options
author | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-24 18:01:29 -0500 |
commit | 4ba3eb034fb6fd1990ccc5a6d71d5abcda37b905 (patch) | |
tree | 0789ba36d96dba330416a1e6a9a68e891a78802a /drivers/net/wireless/iwlwifi | |
parent | 35700212b45ea9f98fa682cfc1bc1a67c9ccc34b (diff) | |
parent | 18b6c9a2213d3b6e0212e8b225abf95f7564206a (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
27 files changed, 933 insertions, 412 deletions
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 */ |