diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 141 |
1 files changed, 85 insertions, 56 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7391c63fb024..35337b1e7cac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
30 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 33 | #include <linux/module.h> |
32 | #include <linux/init.h> | 34 | #include <linux/init.h> |
@@ -292,9 +294,7 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, | |||
292 | struct ieee80211_hdr *hdr, | 294 | struct ieee80211_hdr *hdr, |
293 | int left) | 295 | int left) |
294 | { | 296 | { |
295 | if (!iwl_is_associated(priv) || !priv->ibss_beacon || | 297 | if (!priv->ibss_beacon) |
296 | ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && | ||
297 | (priv->iw_mode != NL80211_IFTYPE_AP))) | ||
298 | return 0; | 298 | return 0; |
299 | 299 | ||
300 | if (priv->ibss_beacon->len > left) | 300 | if (priv->ibss_beacon->len > left) |
@@ -1692,6 +1692,7 @@ static void iwl_nic_start(struct iwl_priv *priv) | |||
1692 | 1692 | ||
1693 | struct iwlagn_ucode_capabilities { | 1693 | struct iwlagn_ucode_capabilities { |
1694 | u32 max_probe_length; | 1694 | u32 max_probe_length; |
1695 | u32 standard_phy_calibration_size; | ||
1695 | }; | 1696 | }; |
1696 | 1697 | ||
1697 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | 1698 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); |
@@ -1827,7 +1828,6 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
1827 | u32 tlv_len; | 1828 | u32 tlv_len; |
1828 | enum iwl_ucode_tlv_type tlv_type; | 1829 | enum iwl_ucode_tlv_type tlv_type; |
1829 | const u8 *tlv_data; | 1830 | const u8 *tlv_data; |
1830 | int ret = 0; | ||
1831 | 1831 | ||
1832 | if (len < sizeof(*ucode)) { | 1832 | if (len < sizeof(*ucode)) { |
1833 | IWL_ERR(priv, "uCode has invalid length: %zd\n", len); | 1833 | IWL_ERR(priv, "uCode has invalid length: %zd\n", len); |
@@ -1863,9 +1863,8 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
1863 | 1863 | ||
1864 | len -= sizeof(*ucode); | 1864 | len -= sizeof(*ucode); |
1865 | 1865 | ||
1866 | while (len >= sizeof(*tlv) && !ret) { | 1866 | while (len >= sizeof(*tlv)) { |
1867 | u16 tlv_alt; | 1867 | u16 tlv_alt; |
1868 | u32 fixed_tlv_size = 4; | ||
1869 | 1868 | ||
1870 | len -= sizeof(*tlv); | 1869 | len -= sizeof(*tlv); |
1871 | tlv = (void *)data; | 1870 | tlv = (void *)data; |
@@ -1913,59 +1912,57 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
1913 | pieces->boot_size = tlv_len; | 1912 | pieces->boot_size = tlv_len; |
1914 | break; | 1913 | break; |
1915 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | 1914 | case IWL_UCODE_TLV_PROBE_MAX_LEN: |
1916 | if (tlv_len != fixed_tlv_size) | 1915 | if (tlv_len != sizeof(u32)) |
1917 | ret = -EINVAL; | 1916 | goto invalid_tlv_len; |
1918 | else | 1917 | capa->max_probe_length = |
1919 | capa->max_probe_length = | ||
1920 | le32_to_cpup((__le32 *)tlv_data); | 1918 | le32_to_cpup((__le32 *)tlv_data); |
1921 | break; | 1919 | break; |
1922 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | 1920 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: |
1923 | if (tlv_len != fixed_tlv_size) | 1921 | if (tlv_len != sizeof(u32)) |
1924 | ret = -EINVAL; | 1922 | goto invalid_tlv_len; |
1925 | else | 1923 | pieces->init_evtlog_ptr = |
1926 | pieces->init_evtlog_ptr = | ||
1927 | le32_to_cpup((__le32 *)tlv_data); | 1924 | le32_to_cpup((__le32 *)tlv_data); |
1928 | break; | 1925 | break; |
1929 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | 1926 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: |
1930 | if (tlv_len != fixed_tlv_size) | 1927 | if (tlv_len != sizeof(u32)) |
1931 | ret = -EINVAL; | 1928 | goto invalid_tlv_len; |
1932 | else | 1929 | pieces->init_evtlog_size = |
1933 | pieces->init_evtlog_size = | ||
1934 | le32_to_cpup((__le32 *)tlv_data); | 1930 | le32_to_cpup((__le32 *)tlv_data); |
1935 | break; | 1931 | break; |
1936 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | 1932 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: |
1937 | if (tlv_len != fixed_tlv_size) | 1933 | if (tlv_len != sizeof(u32)) |
1938 | ret = -EINVAL; | 1934 | goto invalid_tlv_len; |
1939 | else | 1935 | pieces->init_errlog_ptr = |
1940 | pieces->init_errlog_ptr = | ||
1941 | le32_to_cpup((__le32 *)tlv_data); | 1936 | le32_to_cpup((__le32 *)tlv_data); |
1942 | break; | 1937 | break; |
1943 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | 1938 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: |
1944 | if (tlv_len != fixed_tlv_size) | 1939 | if (tlv_len != sizeof(u32)) |
1945 | ret = -EINVAL; | 1940 | goto invalid_tlv_len; |
1946 | else | 1941 | pieces->inst_evtlog_ptr = |
1947 | pieces->inst_evtlog_ptr = | ||
1948 | le32_to_cpup((__le32 *)tlv_data); | 1942 | le32_to_cpup((__le32 *)tlv_data); |
1949 | break; | 1943 | break; |
1950 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | 1944 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: |
1951 | if (tlv_len != fixed_tlv_size) | 1945 | if (tlv_len != sizeof(u32)) |
1952 | ret = -EINVAL; | 1946 | goto invalid_tlv_len; |
1953 | else | 1947 | pieces->inst_evtlog_size = |
1954 | pieces->inst_evtlog_size = | ||
1955 | le32_to_cpup((__le32 *)tlv_data); | 1948 | le32_to_cpup((__le32 *)tlv_data); |
1956 | break; | 1949 | break; |
1957 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | 1950 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: |
1958 | if (tlv_len != fixed_tlv_size) | 1951 | if (tlv_len != sizeof(u32)) |
1959 | ret = -EINVAL; | 1952 | goto invalid_tlv_len; |
1960 | else | 1953 | pieces->inst_errlog_ptr = |
1961 | pieces->inst_errlog_ptr = | ||
1962 | le32_to_cpup((__le32 *)tlv_data); | 1954 | le32_to_cpup((__le32 *)tlv_data); |
1963 | break; | 1955 | break; |
1964 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | 1956 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: |
1965 | if (tlv_len) | 1957 | if (tlv_len) |
1966 | ret = -EINVAL; | 1958 | goto invalid_tlv_len; |
1967 | else | 1959 | priv->enhance_sensitivity_table = true; |
1968 | priv->enhance_sensitivity_table = true; | 1960 | break; |
1961 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
1962 | if (tlv_len != sizeof(u32)) | ||
1963 | goto invalid_tlv_len; | ||
1964 | capa->standard_phy_calibration_size = | ||
1965 | le32_to_cpup((__le32 *)tlv_data); | ||
1969 | break; | 1966 | break; |
1970 | default: | 1967 | default: |
1971 | IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); | 1968 | IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); |
@@ -1976,14 +1973,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, | |||
1976 | if (len) { | 1973 | if (len) { |
1977 | IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); | 1974 | IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); |
1978 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); | 1975 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); |
1979 | ret = -EINVAL; | 1976 | return -EINVAL; |
1980 | } else if (ret) { | ||
1981 | IWL_ERR(priv, "TLV %d has invalid size: %u\n", | ||
1982 | tlv_type, tlv_len); | ||
1983 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len); | ||
1984 | } | 1977 | } |
1985 | 1978 | ||
1986 | return ret; | 1979 | return 0; |
1980 | |||
1981 | invalid_tlv_len: | ||
1982 | IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
1983 | iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); | ||
1984 | |||
1985 | return -EINVAL; | ||
1987 | } | 1986 | } |
1988 | 1987 | ||
1989 | /** | 1988 | /** |
@@ -2005,6 +2004,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
2005 | u32 build; | 2004 | u32 build; |
2006 | struct iwlagn_ucode_capabilities ucode_capa = { | 2005 | struct iwlagn_ucode_capabilities ucode_capa = { |
2007 | .max_probe_length = 200, | 2006 | .max_probe_length = 200, |
2007 | .standard_phy_calibration_size = | ||
2008 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, | ||
2008 | }; | 2009 | }; |
2009 | 2010 | ||
2010 | memset(&pieces, 0, sizeof(pieces)); | 2011 | memset(&pieces, 0, sizeof(pieces)); |
@@ -2226,6 +2227,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
2226 | pieces.boot_size); | 2227 | pieces.boot_size); |
2227 | memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); | 2228 | memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); |
2228 | 2229 | ||
2230 | /* | ||
2231 | * figure out the offset of chain noise reset and gain commands | ||
2232 | * base on the size of standard phy calibration commands table size | ||
2233 | */ | ||
2234 | if (ucode_capa.standard_phy_calibration_size > | ||
2235 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
2236 | ucode_capa.standard_phy_calibration_size = | ||
2237 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
2238 | |||
2239 | priv->_agn.phy_calib_chain_noise_reset_cmd = | ||
2240 | ucode_capa.standard_phy_calibration_size; | ||
2241 | priv->_agn.phy_calib_chain_noise_gain_cmd = | ||
2242 | ucode_capa.standard_phy_calibration_size + 1; | ||
2243 | |||
2229 | /************************************************** | 2244 | /************************************************** |
2230 | * This is still part of probe() in a sense... | 2245 | * This is still part of probe() in a sense... |
2231 | * | 2246 | * |
@@ -3008,9 +3023,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
3008 | } | 3023 | } |
3009 | 3024 | ||
3010 | if (priv->start_calib) { | 3025 | if (priv->start_calib) { |
3011 | iwl_chain_noise_calibration(priv, &priv->_agn.statistics); | 3026 | if (priv->cfg->bt_statistics) { |
3012 | 3027 | iwl_chain_noise_calibration(priv, | |
3013 | iwl_sensitivity_calibration(priv, &priv->_agn.statistics); | 3028 | (void *)&priv->_agn.statistics_bt); |
3029 | iwl_sensitivity_calibration(priv, | ||
3030 | (void *)&priv->_agn.statistics_bt); | ||
3031 | } else { | ||
3032 | iwl_chain_noise_calibration(priv, | ||
3033 | (void *)&priv->_agn.statistics); | ||
3034 | iwl_sensitivity_calibration(priv, | ||
3035 | (void *)&priv->_agn.statistics); | ||
3036 | } | ||
3014 | } | 3037 | } |
3015 | 3038 | ||
3016 | mutex_unlock(&priv->mutex); | 3039 | mutex_unlock(&priv->mutex); |
@@ -3909,8 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3909 | struct ieee80211_hw *hw; | 3932 | struct ieee80211_hw *hw; |
3910 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 3933 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
3911 | unsigned long flags; | 3934 | unsigned long flags; |
3912 | u16 pci_cmd; | 3935 | u16 pci_cmd, num_mac; |
3913 | u8 perm_addr[ETH_ALEN]; | ||
3914 | 3936 | ||
3915 | /************************ | 3937 | /************************ |
3916 | * 1. Allocating HW data | 3938 | * 1. Allocating HW data |
@@ -4028,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4028 | goto out_free_eeprom; | 4050 | goto out_free_eeprom; |
4029 | 4051 | ||
4030 | /* extract MAC Address */ | 4052 | /* extract MAC Address */ |
4031 | iwl_eeprom_get_mac(priv, perm_addr); | 4053 | iwl_eeprom_get_mac(priv, priv->addresses[0].addr); |
4032 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr); | 4054 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); |
4033 | SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr); | 4055 | priv->hw->wiphy->addresses = priv->addresses; |
4056 | priv->hw->wiphy->n_addresses = 1; | ||
4057 | num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); | ||
4058 | if (num_mac > 1) { | ||
4059 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, | ||
4060 | ETH_ALEN); | ||
4061 | priv->addresses[1].addr[5]++; | ||
4062 | priv->hw->wiphy->n_addresses++; | ||
4063 | } | ||
4034 | 4064 | ||
4035 | /************************ | 4065 | /************************ |
4036 | * 5. Setup HW constants | 4066 | * 5. Setup HW constants |
@@ -4389,19 +4419,18 @@ static int __init iwl_init(void) | |||
4389 | { | 4419 | { |
4390 | 4420 | ||
4391 | int ret; | 4421 | int ret; |
4392 | printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 4422 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
4393 | printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); | 4423 | pr_info(DRV_COPYRIGHT "\n"); |
4394 | 4424 | ||
4395 | ret = iwlagn_rate_control_register(); | 4425 | ret = iwlagn_rate_control_register(); |
4396 | if (ret) { | 4426 | if (ret) { |
4397 | printk(KERN_ERR DRV_NAME | 4427 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
4398 | "Unable to register rate control algorithm: %d\n", ret); | ||
4399 | return ret; | 4428 | return ret; |
4400 | } | 4429 | } |
4401 | 4430 | ||
4402 | ret = pci_register_driver(&iwl_driver); | 4431 | ret = pci_register_driver(&iwl_driver); |
4403 | if (ret) { | 4432 | if (ret) { |
4404 | printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); | 4433 | pr_err("Unable to initialize PCI module\n"); |
4405 | goto error_register; | 4434 | goto error_register; |
4406 | } | 4435 | } |
4407 | 4436 | ||