aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c165
1 files changed, 127 insertions, 38 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3368cfd25a99..66c83b24884f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -859,6 +859,24 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
859 return 0; 859 return 0;
860} 860}
861 861
862static void iwl_bg_tx_flush(struct work_struct *work)
863{
864 struct iwl_priv *priv =
865 container_of(work, struct iwl_priv, tx_flush);
866
867 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
868 return;
869
870 /* do nothing if rf-kill is on */
871 if (!iwl_is_ready_rf(priv))
872 return;
873
874 if (priv->cfg->ops->lib->txfifo_flush) {
875 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
876 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
877 }
878}
879
862/** 880/**
863 * iwl_setup_rx_handlers - Initialize Rx handler callbacks 881 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
864 * 882 *
@@ -1806,12 +1824,21 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1806 const u8 *data; 1824 const u8 *data;
1807 int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp; 1825 int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
1808 u64 alternatives; 1826 u64 alternatives;
1827 u32 tlv_len;
1828 enum iwl_ucode_tlv_type tlv_type;
1829 const u8 *tlv_data;
1830 int ret = 0;
1809 1831
1810 if (len < sizeof(*ucode)) 1832 if (len < sizeof(*ucode)) {
1833 IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
1811 return -EINVAL; 1834 return -EINVAL;
1835 }
1812 1836
1813 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) 1837 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
1838 IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
1839 le32_to_cpu(ucode->magic));
1814 return -EINVAL; 1840 return -EINVAL;
1841 }
1815 1842
1816 /* 1843 /*
1817 * Check which alternatives are present, and "downgrade" 1844 * Check which alternatives are present, and "downgrade"
@@ -1836,11 +1863,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1836 1863
1837 len -= sizeof(*ucode); 1864 len -= sizeof(*ucode);
1838 1865
1839 while (len >= sizeof(*tlv)) { 1866 while (len >= sizeof(*tlv) && !ret) {
1840 u32 tlv_len;
1841 enum iwl_ucode_tlv_type tlv_type;
1842 u16 tlv_alt; 1867 u16 tlv_alt;
1843 const u8 *tlv_data; 1868 u32 fixed_tlv_size = 4;
1844 1869
1845 len -= sizeof(*tlv); 1870 len -= sizeof(*tlv);
1846 tlv = (void *)data; 1871 tlv = (void *)data;
@@ -1850,8 +1875,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1850 tlv_alt = le16_to_cpu(tlv->alternative); 1875 tlv_alt = le16_to_cpu(tlv->alternative);
1851 tlv_data = tlv->data; 1876 tlv_data = tlv->data;
1852 1877
1853 if (len < tlv_len) 1878 if (len < tlv_len) {
1879 IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
1880 len, tlv_len);
1854 return -EINVAL; 1881 return -EINVAL;
1882 }
1855 len -= ALIGN(tlv_len, 4); 1883 len -= ALIGN(tlv_len, 4);
1856 data += sizeof(*tlv) + ALIGN(tlv_len, 4); 1884 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
1857 1885
@@ -1885,56 +1913,77 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1885 pieces->boot_size = tlv_len; 1913 pieces->boot_size = tlv_len;
1886 break; 1914 break;
1887 case IWL_UCODE_TLV_PROBE_MAX_LEN: 1915 case IWL_UCODE_TLV_PROBE_MAX_LEN:
1888 if (tlv_len != 4) 1916 if (tlv_len != fixed_tlv_size)
1889 return -EINVAL; 1917 ret = -EINVAL;
1890 capa->max_probe_length = 1918 else
1891 le32_to_cpup((__le32 *)tlv_data); 1919 capa->max_probe_length =
1920 le32_to_cpup((__le32 *)tlv_data);
1892 break; 1921 break;
1893 case IWL_UCODE_TLV_INIT_EVTLOG_PTR: 1922 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1894 if (tlv_len != 4) 1923 if (tlv_len != fixed_tlv_size)
1895 return -EINVAL; 1924 ret = -EINVAL;
1896 pieces->init_evtlog_ptr = 1925 else
1897 le32_to_cpup((__le32 *)tlv_data); 1926 pieces->init_evtlog_ptr =
1927 le32_to_cpup((__le32 *)tlv_data);
1898 break; 1928 break;
1899 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: 1929 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1900 if (tlv_len != 4) 1930 if (tlv_len != fixed_tlv_size)
1901 return -EINVAL; 1931 ret = -EINVAL;
1902 pieces->init_evtlog_size = 1932 else
1903 le32_to_cpup((__le32 *)tlv_data); 1933 pieces->init_evtlog_size =
1934 le32_to_cpup((__le32 *)tlv_data);
1904 break; 1935 break;
1905 case IWL_UCODE_TLV_INIT_ERRLOG_PTR: 1936 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1906 if (tlv_len != 4) 1937 if (tlv_len != fixed_tlv_size)
1907 return -EINVAL; 1938 ret = -EINVAL;
1908 pieces->init_errlog_ptr = 1939 else
1909 le32_to_cpup((__le32 *)tlv_data); 1940 pieces->init_errlog_ptr =
1941 le32_to_cpup((__le32 *)tlv_data);
1910 break; 1942 break;
1911 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: 1943 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1912 if (tlv_len != 4) 1944 if (tlv_len != fixed_tlv_size)
1913 return -EINVAL; 1945 ret = -EINVAL;
1914 pieces->inst_evtlog_ptr = 1946 else
1915 le32_to_cpup((__le32 *)tlv_data); 1947 pieces->inst_evtlog_ptr =
1948 le32_to_cpup((__le32 *)tlv_data);
1916 break; 1949 break;
1917 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: 1950 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1918 if (tlv_len != 4) 1951 if (tlv_len != fixed_tlv_size)
1919 return -EINVAL; 1952 ret = -EINVAL;
1920 pieces->inst_evtlog_size = 1953 else
1921 le32_to_cpup((__le32 *)tlv_data); 1954 pieces->inst_evtlog_size =
1955 le32_to_cpup((__le32 *)tlv_data);
1922 break; 1956 break;
1923 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: 1957 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1924 if (tlv_len != 4) 1958 if (tlv_len != fixed_tlv_size)
1925 return -EINVAL; 1959 ret = -EINVAL;
1926 pieces->inst_errlog_ptr = 1960 else
1927 le32_to_cpup((__le32 *)tlv_data); 1961 pieces->inst_errlog_ptr =
1962 le32_to_cpup((__le32 *)tlv_data);
1963 break;
1964 case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
1965 if (tlv_len)
1966 ret = -EINVAL;
1967 else
1968 priv->enhance_sensitivity_table = true;
1928 break; 1969 break;
1929 default: 1970 default:
1971 IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
1930 break; 1972 break;
1931 } 1973 }
1932 } 1974 }
1933 1975
1934 if (len) 1976 if (len) {
1935 return -EINVAL; 1977 IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
1978 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
1979 ret = -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 }
1936 1985
1937 return 0; 1986 return ret;
1938} 1987}
1939 1988
1940/** 1989/**
@@ -3614,6 +3663,44 @@ out_exit:
3614 IWL_DEBUG_MAC80211(priv, "leave\n"); 3663 IWL_DEBUG_MAC80211(priv, "leave\n");
3615} 3664}
3616 3665
3666static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
3667{
3668 struct iwl_priv *priv = hw->priv;
3669
3670 mutex_lock(&priv->mutex);
3671 IWL_DEBUG_MAC80211(priv, "enter\n");
3672
3673 /* do not support "flush" */
3674 if (!priv->cfg->ops->lib->txfifo_flush)
3675 goto done;
3676
3677 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
3678 IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
3679 goto done;
3680 }
3681 if (iwl_is_rfkill(priv)) {
3682 IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
3683 goto done;
3684 }
3685
3686 /*
3687 * mac80211 will not push any more frames for transmit
3688 * until the flush is completed
3689 */
3690 if (drop) {
3691 IWL_DEBUG_MAC80211(priv, "send flush command\n");
3692 if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
3693 IWL_ERR(priv, "flush request fail\n");
3694 goto done;
3695 }
3696 }
3697 IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
3698 iwlagn_wait_tx_queue_empty(priv);
3699done:
3700 mutex_unlock(&priv->mutex);
3701 IWL_DEBUG_MAC80211(priv, "leave\n");
3702}
3703
3617/***************************************************************************** 3704/*****************************************************************************
3618 * 3705 *
3619 * driver setup and teardown 3706 * driver setup and teardown
@@ -3630,6 +3717,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3630 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3717 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3631 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3718 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
3632 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); 3719 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
3720 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
3633 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); 3721 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
3634 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 3722 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
3635 3723
@@ -3787,6 +3875,7 @@ static struct ieee80211_ops iwl_hw_ops = {
3787 .sta_add = iwlagn_mac_sta_add, 3875 .sta_add = iwlagn_mac_sta_add,
3788 .sta_remove = iwl_mac_sta_remove, 3876 .sta_remove = iwl_mac_sta_remove,
3789 .channel_switch = iwl_mac_channel_switch, 3877 .channel_switch = iwl_mac_channel_switch,
3878 .flush = iwl_mac_flush,
3790}; 3879};
3791 3880
3792static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3881static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)