diff options
| -rw-r--r-- | MAINTAINERS | 5 | ||||
| -rw-r--r-- | drivers/net/8139too.c | 1 | ||||
| -rw-r--r-- | drivers/net/r8169.c | 5 | ||||
| -rw-r--r-- | drivers/net/usb/asix.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 7 | ||||
| -rw-r--r-- | drivers/net/wireless/hostap/hostap_hw.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 30 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 318 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 39 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 56 | ||||
| -rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_sdio.c | 1 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ip6mr.c | 6 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 5 | ||||
| -rw-r--r-- | net/mac80211/driver-ops.h | 2 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 92 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 3 |
22 files changed, 380 insertions, 223 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 67accd730ac9..6d119c98b89b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2978,7 +2978,6 @@ F: drivers/net/ixgb/ | |||
| 2978 | F: drivers/net/ixgbe/ | 2978 | F: drivers/net/ixgbe/ |
| 2979 | 2979 | ||
| 2980 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT | 2980 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT |
| 2981 | M: Zhu Yi <yi.zhu@intel.com> | ||
| 2982 | M: Reinette Chatre <reinette.chatre@intel.com> | 2981 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 2983 | M: Intel Linux Wireless <ilw@linux.intel.com> | 2982 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 2984 | L: linux-wireless@vger.kernel.org | 2983 | L: linux-wireless@vger.kernel.org |
| @@ -2988,7 +2987,6 @@ F: Documentation/networking/README.ipw2100 | |||
| 2988 | F: drivers/net/wireless/ipw2x00/ipw2100.* | 2987 | F: drivers/net/wireless/ipw2x00/ipw2100.* |
| 2989 | 2988 | ||
| 2990 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT | 2989 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT |
| 2991 | M: Zhu Yi <yi.zhu@intel.com> | ||
| 2992 | M: Reinette Chatre <reinette.chatre@intel.com> | 2990 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 2993 | M: Intel Linux Wireless <ilw@linux.intel.com> | 2991 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 2994 | L: linux-wireless@vger.kernel.org | 2992 | L: linux-wireless@vger.kernel.org |
| @@ -3019,8 +3017,8 @@ F: drivers/net/wimax/i2400m/ | |||
| 3019 | F: include/linux/wimax/i2400m.h | 3017 | F: include/linux/wimax/i2400m.h |
| 3020 | 3018 | ||
| 3021 | INTEL WIRELESS WIFI LINK (iwlwifi) | 3019 | INTEL WIRELESS WIFI LINK (iwlwifi) |
| 3022 | M: Zhu Yi <yi.zhu@intel.com> | ||
| 3023 | M: Reinette Chatre <reinette.chatre@intel.com> | 3020 | M: Reinette Chatre <reinette.chatre@intel.com> |
| 3021 | M: Wey-Yi Guy <wey-yi.w.guy@intel.com> | ||
| 3024 | M: Intel Linux Wireless <ilw@linux.intel.com> | 3022 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 3025 | L: linux-wireless@vger.kernel.org | 3023 | L: linux-wireless@vger.kernel.org |
| 3026 | W: http://intellinuxwireless.org | 3024 | W: http://intellinuxwireless.org |
| @@ -3030,7 +3028,6 @@ F: drivers/net/wireless/iwlwifi/ | |||
| 3030 | 3028 | ||
| 3031 | INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi) | 3029 | INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi) |
| 3032 | M: Samuel Ortiz <samuel.ortiz@intel.com> | 3030 | M: Samuel Ortiz <samuel.ortiz@intel.com> |
| 3033 | M: Zhu Yi <yi.zhu@intel.com> | ||
| 3034 | M: Intel Linux Wireless <ilw@linux.intel.com> | 3031 | M: Intel Linux Wireless <ilw@linux.intel.com> |
| 3035 | L: linux-wireless@vger.kernel.org | 3032 | L: linux-wireless@vger.kernel.org |
| 3036 | S: Supported | 3033 | S: Supported |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 4ba72933f0da..80cd074d3817 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
| @@ -860,6 +860,7 @@ retry: | |||
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | /* if unknown chip, assume array element #0, original RTL-8139 in this case */ | 862 | /* if unknown chip, assume array element #0, original RTL-8139 in this case */ |
| 863 | i = 0; | ||
| 863 | dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n"); | 864 | dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n"); |
| 864 | dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig)); | 865 | dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig)); |
| 865 | tp->chipset = 0; | 866 | tp->chipset = 0; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 217e709bda3e..03a8318d90a2 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -559,6 +559,11 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value) | |||
| 559 | break; | 559 | break; |
| 560 | udelay(25); | 560 | udelay(25); |
| 561 | } | 561 | } |
| 562 | /* | ||
| 563 | * Some configurations require a small delay even after the write | ||
| 564 | * completed indication or the next write might fail. | ||
| 565 | */ | ||
| 566 | udelay(25); | ||
| 562 | } | 567 | } |
| 563 | 568 | ||
| 564 | static int mdio_read(void __iomem *ioaddr, int reg_addr) | 569 | static int mdio_read(void __iomem *ioaddr, int reg_addr) |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1f802e90474c..9516f382a6ba 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
| @@ -344,7 +344,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 344 | return 2; | 344 | return 2; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | if (size > ETH_FRAME_LEN) { | 347 | if (size > dev->net->mtu + ETH_HLEN) { |
| 348 | netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", | 348 | netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", |
| 349 | size); | 349 | size); |
| 350 | return 0; | 350 | return 0; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2978359c4366..648972df369d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = { | |||
| 195 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, | 195 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, |
| 196 | const struct pci_device_id *id); | 196 | const struct pci_device_id *id); |
| 197 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | 197 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); |
| 198 | #ifdef CONFIG_PM | 198 | #ifdef CONFIG_PM_SLEEP |
| 199 | static int ath5k_pci_suspend(struct device *dev); | 199 | static int ath5k_pci_suspend(struct device *dev); |
| 200 | static int ath5k_pci_resume(struct device *dev); | 200 | static int ath5k_pci_resume(struct device *dev); |
| 201 | 201 | ||
| @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | |||
| 203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | 203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) |
| 204 | #else | 204 | #else |
| 205 | #define ATH5K_PM_OPS NULL | 205 | #define ATH5K_PM_OPS NULL |
| 206 | #endif /* CONFIG_PM */ | 206 | #endif /* CONFIG_PM_SLEEP */ |
| 207 | 207 | ||
| 208 | static struct pci_driver ath5k_pci_driver = { | 208 | static struct pci_driver ath5k_pci_driver = { |
| 209 | .name = KBUILD_MODNAME, | 209 | .name = KBUILD_MODNAME, |
| @@ -708,7 +708,7 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
| 708 | ieee80211_free_hw(hw); | 708 | ieee80211_free_hw(hw); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | #ifdef CONFIG_PM | 711 | #ifdef CONFIG_PM_SLEEP |
| 712 | static int ath5k_pci_suspend(struct device *dev) | 712 | static int ath5k_pci_suspend(struct device *dev) |
| 713 | { | 713 | { |
| 714 | struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); | 714 | struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); |
| @@ -734,7 +734,7 @@ static int ath5k_pci_resume(struct device *dev) | |||
| 734 | ath5k_led_enable(sc); | 734 | ath5k_led_enable(sc); |
| 735 | return 0; | 735 | return 0; |
| 736 | } | 736 | } |
| 737 | #endif /* CONFIG_PM */ | 737 | #endif /* CONFIG_PM_SLEEP */ |
| 738 | 738 | ||
| 739 | 739 | ||
| 740 | /***********************\ | 740 | /***********************\ |
| @@ -3140,13 +3140,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
| 3140 | 3140 | ||
| 3141 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 3141 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { |
| 3142 | if (*new_flags & FIF_PROMISC_IN_BSS) { | 3142 | if (*new_flags & FIF_PROMISC_IN_BSS) { |
| 3143 | rfilt |= AR5K_RX_FILTER_PROM; | ||
| 3144 | __set_bit(ATH_STAT_PROMISC, sc->status); | 3143 | __set_bit(ATH_STAT_PROMISC, sc->status); |
| 3145 | } else { | 3144 | } else { |
| 3146 | __clear_bit(ATH_STAT_PROMISC, sc->status); | 3145 | __clear_bit(ATH_STAT_PROMISC, sc->status); |
| 3147 | } | 3146 | } |
| 3148 | } | 3147 | } |
| 3149 | 3148 | ||
| 3149 | if (test_bit(ATH_STAT_PROMISC, sc->status)) | ||
| 3150 | rfilt |= AR5K_RX_FILTER_PROM; | ||
| 3151 | |||
| 3150 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ | 3152 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ |
| 3151 | if (*new_flags & FIF_ALLMULTI) { | 3153 | if (*new_flags & FIF_ALLMULTI) { |
| 3152 | mfilt[0] = ~0; | 3154 | mfilt[0] = ~0; |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 1b81c4778800..492cbb15720d 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
| @@ -1814,6 +1814,13 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
| 1814 | u8 def_ant, tx_ant, ee_mode; | 1814 | u8 def_ant, tx_ant, ee_mode; |
| 1815 | u32 sta_id1 = 0; | 1815 | u32 sta_id1 = 0; |
| 1816 | 1816 | ||
| 1817 | /* if channel is not initialized yet we can't set the antennas | ||
| 1818 | * so just store the mode. it will be set on the next reset */ | ||
| 1819 | if (channel == NULL) { | ||
| 1820 | ah->ah_ant_mode = ant_mode; | ||
| 1821 | return; | ||
| 1822 | } | ||
| 1823 | |||
| 1817 | def_ant = ah->ah_def_ant; | 1824 | def_ant = ah->ah_def_ant; |
| 1818 | 1825 | ||
| 1819 | ATH5K_TRACE(ah->ah_sc); | 1826 | ATH5K_TRACE(ah->ah_sc); |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index d70732819423..ff9b5c882184 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
| @@ -2618,15 +2618,6 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) | |||
| 2618 | int events = 0; | 2618 | int events = 0; |
| 2619 | u16 ev; | 2619 | u16 ev; |
| 2620 | 2620 | ||
| 2621 | /* Detect early interrupt before driver is fully configued */ | ||
| 2622 | if (!dev->base_addr) { | ||
| 2623 | if (net_ratelimit()) { | ||
| 2624 | printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", | ||
| 2625 | dev->name); | ||
| 2626 | } | ||
| 2627 | return IRQ_HANDLED; | ||
| 2628 | } | ||
| 2629 | |||
| 2630 | iface = netdev_priv(dev); | 2621 | iface = netdev_priv(dev); |
| 2631 | local = iface->local; | 2622 | local = iface->local; |
| 2632 | 2623 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 068f7f8435c5..c44a303e62ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
| @@ -2852,6 +2852,7 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
| 2852 | .isr = iwl_isr_legacy, | 2852 | .isr = iwl_isr_legacy, |
| 2853 | .config_ap = iwl3945_config_ap, | 2853 | .config_ap = iwl3945_config_ap, |
| 2854 | .manage_ibss_station = iwl3945_manage_ibss_station, | 2854 | .manage_ibss_station = iwl3945_manage_ibss_station, |
| 2855 | .recover_from_tx_stall = iwl_bg_monitor_recover, | ||
| 2855 | .check_plcp_health = iwl3945_good_plcp_health, | 2856 | .check_plcp_health = iwl3945_good_plcp_health, |
| 2856 | 2857 | ||
| 2857 | .debugfs_ops = { | 2858 | .debugfs_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 1004cfc403b1..0f292a210ed9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
| @@ -1119,10 +1119,9 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | |||
| 1119 | struct iwl_scan_channel *scan_ch) | 1119 | struct iwl_scan_channel *scan_ch) |
| 1120 | { | 1120 | { |
| 1121 | const struct ieee80211_supported_band *sband; | 1121 | const struct ieee80211_supported_band *sband; |
| 1122 | const struct iwl_channel_info *ch_info; | ||
| 1123 | u16 passive_dwell = 0; | 1122 | u16 passive_dwell = 0; |
| 1124 | u16 active_dwell = 0; | 1123 | u16 active_dwell = 0; |
| 1125 | int i, added = 0; | 1124 | int added = 0; |
| 1126 | u16 channel = 0; | 1125 | u16 channel = 0; |
| 1127 | 1126 | ||
| 1128 | sband = iwl_get_hw_mode(priv, band); | 1127 | sband = iwl_get_hw_mode(priv, band); |
| @@ -1137,32 +1136,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | |||
| 1137 | if (passive_dwell <= active_dwell) | 1136 | if (passive_dwell <= active_dwell) |
| 1138 | passive_dwell = active_dwell + 1; | 1137 | passive_dwell = active_dwell + 1; |
| 1139 | 1138 | ||
| 1140 | /* only scan single channel, good enough to reset the RF */ | 1139 | channel = iwl_get_single_channel_number(priv, band); |
| 1141 | /* pick the first valid not in-use channel */ | ||
| 1142 | if (band == IEEE80211_BAND_5GHZ) { | ||
| 1143 | for (i = 14; i < priv->channel_count; i++) { | ||
| 1144 | if (priv->channel_info[i].channel != | ||
| 1145 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
| 1146 | channel = priv->channel_info[i].channel; | ||
| 1147 | ch_info = iwl_get_channel_info(priv, | ||
| 1148 | band, channel); | ||
| 1149 | if (is_channel_valid(ch_info)) | ||
| 1150 | break; | ||
| 1151 | } | ||
| 1152 | } | ||
| 1153 | } else { | ||
| 1154 | for (i = 0; i < 14; i++) { | ||
| 1155 | if (priv->channel_info[i].channel != | ||
| 1156 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
| 1157 | channel = | ||
| 1158 | priv->channel_info[i].channel; | ||
| 1159 | ch_info = iwl_get_channel_info(priv, | ||
| 1160 | band, channel); | ||
| 1161 | if (is_channel_valid(ch_info)) | ||
| 1162 | break; | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | } | ||
| 1166 | if (channel) { | 1140 | if (channel) { |
| 1167 | scan_ch->channel = cpu_to_le16(channel); | 1141 | scan_ch->channel = cpu_to_le16(channel); |
| 1168 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | 1142 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c402bfc83f36..a732f1094e5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
| @@ -1125,6 +1125,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 1125 | struct ieee80211_sta *sta; | 1125 | struct ieee80211_sta *sta; |
| 1126 | struct iwl_station_priv *sta_priv; | 1126 | struct iwl_station_priv *sta_priv; |
| 1127 | 1127 | ||
| 1128 | rcu_read_lock(); | ||
| 1128 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | 1129 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); |
| 1129 | if (sta) { | 1130 | if (sta) { |
| 1130 | sta_priv = (void *)sta->drv_priv; | 1131 | sta_priv = (void *)sta->drv_priv; |
| @@ -1133,6 +1134,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | |||
| 1133 | atomic_dec_return(&sta_priv->pending_frames) == 0) | 1134 | atomic_dec_return(&sta_priv->pending_frames) == 0) |
| 1134 | ieee80211_sta_block_awake(priv->hw, sta, false); | 1135 | ieee80211_sta_block_awake(priv->hw, sta, false); |
| 1135 | } | 1136 | } |
| 1137 | rcu_read_unlock(); | ||
| 1136 | 1138 | ||
| 1137 | ieee80211_tx_status_irqsafe(priv->hw, skb); | 1139 | ieee80211_tx_status_irqsafe(priv->hw, skb); |
| 1138 | } | 1140 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index aef4f71f1981..7726e67044c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -1484,6 +1484,156 @@ bool iwl_good_ack_health(struct iwl_priv *priv, | |||
| 1484 | } | 1484 | } |
| 1485 | 1485 | ||
| 1486 | 1486 | ||
| 1487 | /***************************************************************************** | ||
| 1488 | * | ||
| 1489 | * sysfs attributes | ||
| 1490 | * | ||
| 1491 | *****************************************************************************/ | ||
| 1492 | |||
| 1493 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 1494 | |||
| 1495 | /* | ||
| 1496 | * The following adds a new attribute to the sysfs representation | ||
| 1497 | * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) | ||
| 1498 | * used for controlling the debug level. | ||
| 1499 | * | ||
| 1500 | * See the level definitions in iwl for details. | ||
| 1501 | * | ||
| 1502 | * The debug_level being managed using sysfs below is a per device debug | ||
| 1503 | * level that is used instead of the global debug level if it (the per | ||
| 1504 | * device debug level) is set. | ||
| 1505 | */ | ||
| 1506 | static ssize_t show_debug_level(struct device *d, | ||
| 1507 | struct device_attribute *attr, char *buf) | ||
| 1508 | { | ||
| 1509 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1510 | return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); | ||
| 1511 | } | ||
| 1512 | static ssize_t store_debug_level(struct device *d, | ||
| 1513 | struct device_attribute *attr, | ||
| 1514 | const char *buf, size_t count) | ||
| 1515 | { | ||
| 1516 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1517 | unsigned long val; | ||
| 1518 | int ret; | ||
| 1519 | |||
| 1520 | ret = strict_strtoul(buf, 0, &val); | ||
| 1521 | if (ret) | ||
| 1522 | IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); | ||
| 1523 | else { | ||
| 1524 | priv->debug_level = val; | ||
| 1525 | if (iwl_alloc_traffic_mem(priv)) | ||
| 1526 | IWL_ERR(priv, | ||
| 1527 | "Not enough memory to generate traffic log\n"); | ||
| 1528 | } | ||
| 1529 | return strnlen(buf, count); | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, | ||
| 1533 | show_debug_level, store_debug_level); | ||
| 1534 | |||
| 1535 | |||
| 1536 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
| 1537 | |||
| 1538 | |||
| 1539 | static ssize_t show_temperature(struct device *d, | ||
| 1540 | struct device_attribute *attr, char *buf) | ||
| 1541 | { | ||
| 1542 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1543 | |||
| 1544 | if (!iwl_is_alive(priv)) | ||
| 1545 | return -EAGAIN; | ||
| 1546 | |||
| 1547 | return sprintf(buf, "%d\n", priv->temperature); | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | ||
| 1551 | |||
| 1552 | static ssize_t show_tx_power(struct device *d, | ||
| 1553 | struct device_attribute *attr, char *buf) | ||
| 1554 | { | ||
| 1555 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1556 | |||
| 1557 | if (!iwl_is_ready_rf(priv)) | ||
| 1558 | return sprintf(buf, "off\n"); | ||
| 1559 | else | ||
| 1560 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | static ssize_t store_tx_power(struct device *d, | ||
| 1564 | struct device_attribute *attr, | ||
| 1565 | const char *buf, size_t count) | ||
| 1566 | { | ||
| 1567 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1568 | unsigned long val; | ||
| 1569 | int ret; | ||
| 1570 | |||
| 1571 | ret = strict_strtoul(buf, 10, &val); | ||
| 1572 | if (ret) | ||
| 1573 | IWL_INFO(priv, "%s is not in decimal form.\n", buf); | ||
| 1574 | else { | ||
| 1575 | ret = iwl_set_tx_power(priv, val, false); | ||
| 1576 | if (ret) | ||
| 1577 | IWL_ERR(priv, "failed setting tx power (0x%d).\n", | ||
| 1578 | ret); | ||
| 1579 | else | ||
| 1580 | ret = count; | ||
| 1581 | } | ||
| 1582 | return ret; | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | ||
| 1586 | |||
| 1587 | static ssize_t show_rts_ht_protection(struct device *d, | ||
| 1588 | struct device_attribute *attr, char *buf) | ||
| 1589 | { | ||
| 1590 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1591 | |||
| 1592 | return sprintf(buf, "%s\n", | ||
| 1593 | priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | static ssize_t store_rts_ht_protection(struct device *d, | ||
| 1597 | struct device_attribute *attr, | ||
| 1598 | const char *buf, size_t count) | ||
| 1599 | { | ||
| 1600 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 1601 | unsigned long val; | ||
| 1602 | int ret; | ||
| 1603 | |||
| 1604 | ret = strict_strtoul(buf, 10, &val); | ||
| 1605 | if (ret) | ||
| 1606 | IWL_INFO(priv, "Input is not in decimal form.\n"); | ||
| 1607 | else { | ||
| 1608 | if (!iwl_is_associated(priv)) | ||
| 1609 | priv->cfg->use_rts_for_ht = val ? true : false; | ||
| 1610 | else | ||
| 1611 | IWL_ERR(priv, "Sta associated with AP - " | ||
| 1612 | "Change protection mechanism is not allowed\n"); | ||
| 1613 | ret = count; | ||
| 1614 | } | ||
| 1615 | return ret; | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, | ||
| 1619 | show_rts_ht_protection, store_rts_ht_protection); | ||
| 1620 | |||
| 1621 | |||
| 1622 | static struct attribute *iwl_sysfs_entries[] = { | ||
| 1623 | &dev_attr_temperature.attr, | ||
| 1624 | &dev_attr_tx_power.attr, | ||
| 1625 | &dev_attr_rts_ht_protection.attr, | ||
| 1626 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 1627 | &dev_attr_debug_level.attr, | ||
| 1628 | #endif | ||
| 1629 | NULL | ||
| 1630 | }; | ||
| 1631 | |||
| 1632 | static struct attribute_group iwl_attribute_group = { | ||
| 1633 | .name = NULL, /* put in device directory */ | ||
| 1634 | .attrs = iwl_sysfs_entries, | ||
| 1635 | }; | ||
| 1636 | |||
| 1487 | /****************************************************************************** | 1637 | /****************************************************************************** |
| 1488 | * | 1638 | * |
| 1489 | * uCode download functions | 1639 | * uCode download functions |
| @@ -1965,6 +2115,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 1965 | if (err) | 2115 | if (err) |
| 1966 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | 2116 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
| 1967 | 2117 | ||
| 2118 | err = sysfs_create_group(&priv->pci_dev->dev.kobj, | ||
| 2119 | &iwl_attribute_group); | ||
| 2120 | if (err) { | ||
| 2121 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); | ||
| 2122 | goto out_unbind; | ||
| 2123 | } | ||
| 2124 | |||
| 1968 | /* We have our copies now, allow OS release its copies */ | 2125 | /* We have our copies now, allow OS release its copies */ |
| 1969 | release_firmware(ucode_raw); | 2126 | release_firmware(ucode_raw); |
| 1970 | complete(&priv->_agn.firmware_loading_complete); | 2127 | complete(&priv->_agn.firmware_loading_complete); |
| @@ -3264,141 +3421,6 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
| 3264 | 3421 | ||
| 3265 | /***************************************************************************** | 3422 | /***************************************************************************** |
| 3266 | * | 3423 | * |
| 3267 | * sysfs attributes | ||
| 3268 | * | ||
| 3269 | *****************************************************************************/ | ||
| 3270 | |||
| 3271 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 3272 | |||
| 3273 | /* | ||
| 3274 | * The following adds a new attribute to the sysfs representation | ||
| 3275 | * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) | ||
| 3276 | * used for controlling the debug level. | ||
| 3277 | * | ||
| 3278 | * See the level definitions in iwl for details. | ||
| 3279 | * | ||
| 3280 | * The debug_level being managed using sysfs below is a per device debug | ||
| 3281 | * level that is used instead of the global debug level if it (the per | ||
| 3282 | * device debug level) is set. | ||
| 3283 | */ | ||
| 3284 | static ssize_t show_debug_level(struct device *d, | ||
| 3285 | struct device_attribute *attr, char *buf) | ||
| 3286 | { | ||
| 3287 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3288 | return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); | ||
| 3289 | } | ||
| 3290 | static ssize_t store_debug_level(struct device *d, | ||
| 3291 | struct device_attribute *attr, | ||
| 3292 | const char *buf, size_t count) | ||
| 3293 | { | ||
| 3294 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3295 | unsigned long val; | ||
| 3296 | int ret; | ||
| 3297 | |||
| 3298 | ret = strict_strtoul(buf, 0, &val); | ||
| 3299 | if (ret) | ||
| 3300 | IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); | ||
| 3301 | else { | ||
| 3302 | priv->debug_level = val; | ||
| 3303 | if (iwl_alloc_traffic_mem(priv)) | ||
| 3304 | IWL_ERR(priv, | ||
| 3305 | "Not enough memory to generate traffic log\n"); | ||
| 3306 | } | ||
| 3307 | return strnlen(buf, count); | ||
| 3308 | } | ||
| 3309 | |||
| 3310 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, | ||
| 3311 | show_debug_level, store_debug_level); | ||
| 3312 | |||
| 3313 | |||
| 3314 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
| 3315 | |||
| 3316 | |||
| 3317 | static ssize_t show_temperature(struct device *d, | ||
| 3318 | struct device_attribute *attr, char *buf) | ||
| 3319 | { | ||
| 3320 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3321 | |||
| 3322 | if (!iwl_is_alive(priv)) | ||
| 3323 | return -EAGAIN; | ||
| 3324 | |||
| 3325 | return sprintf(buf, "%d\n", priv->temperature); | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | ||
| 3329 | |||
| 3330 | static ssize_t show_tx_power(struct device *d, | ||
| 3331 | struct device_attribute *attr, char *buf) | ||
| 3332 | { | ||
| 3333 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3334 | |||
| 3335 | if (!iwl_is_ready_rf(priv)) | ||
| 3336 | return sprintf(buf, "off\n"); | ||
| 3337 | else | ||
| 3338 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); | ||
| 3339 | } | ||
| 3340 | |||
| 3341 | static ssize_t store_tx_power(struct device *d, | ||
| 3342 | struct device_attribute *attr, | ||
| 3343 | const char *buf, size_t count) | ||
| 3344 | { | ||
| 3345 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3346 | unsigned long val; | ||
| 3347 | int ret; | ||
| 3348 | |||
| 3349 | ret = strict_strtoul(buf, 10, &val); | ||
| 3350 | if (ret) | ||
| 3351 | IWL_INFO(priv, "%s is not in decimal form.\n", buf); | ||
| 3352 | else { | ||
| 3353 | ret = iwl_set_tx_power(priv, val, false); | ||
| 3354 | if (ret) | ||
| 3355 | IWL_ERR(priv, "failed setting tx power (0x%d).\n", | ||
| 3356 | ret); | ||
| 3357 | else | ||
| 3358 | ret = count; | ||
| 3359 | } | ||
| 3360 | return ret; | ||
| 3361 | } | ||
| 3362 | |||
| 3363 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | ||
| 3364 | |||
| 3365 | static ssize_t show_rts_ht_protection(struct device *d, | ||
| 3366 | struct device_attribute *attr, char *buf) | ||
| 3367 | { | ||
| 3368 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3369 | |||
| 3370 | return sprintf(buf, "%s\n", | ||
| 3371 | priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self"); | ||
| 3372 | } | ||
| 3373 | |||
| 3374 | static ssize_t store_rts_ht_protection(struct device *d, | ||
| 3375 | struct device_attribute *attr, | ||
| 3376 | const char *buf, size_t count) | ||
| 3377 | { | ||
| 3378 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
| 3379 | unsigned long val; | ||
| 3380 | int ret; | ||
| 3381 | |||
| 3382 | ret = strict_strtoul(buf, 10, &val); | ||
| 3383 | if (ret) | ||
| 3384 | IWL_INFO(priv, "Input is not in decimal form.\n"); | ||
| 3385 | else { | ||
| 3386 | if (!iwl_is_associated(priv)) | ||
| 3387 | priv->cfg->use_rts_for_ht = val ? true : false; | ||
| 3388 | else | ||
| 3389 | IWL_ERR(priv, "Sta associated with AP - " | ||
| 3390 | "Change protection mechanism is not allowed\n"); | ||
| 3391 | ret = count; | ||
| 3392 | } | ||
| 3393 | return ret; | ||
| 3394 | } | ||
| 3395 | |||
| 3396 | static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO, | ||
| 3397 | show_rts_ht_protection, store_rts_ht_protection); | ||
| 3398 | |||
| 3399 | |||
| 3400 | /***************************************************************************** | ||
| 3401 | * | ||
| 3402 | * driver setup and teardown | 3424 | * driver setup and teardown |
| 3403 | * | 3425 | * |
| 3404 | *****************************************************************************/ | 3426 | *****************************************************************************/ |
| @@ -3550,21 +3572,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
| 3550 | kfree(priv->scan_cmd); | 3572 | kfree(priv->scan_cmd); |
| 3551 | } | 3573 | } |
| 3552 | 3574 | ||
| 3553 | static struct attribute *iwl_sysfs_entries[] = { | ||
| 3554 | &dev_attr_temperature.attr, | ||
| 3555 | &dev_attr_tx_power.attr, | ||
| 3556 | &dev_attr_rts_ht_protection.attr, | ||
| 3557 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
| 3558 | &dev_attr_debug_level.attr, | ||
| 3559 | #endif | ||
| 3560 | NULL | ||
| 3561 | }; | ||
| 3562 | |||
| 3563 | static struct attribute_group iwl_attribute_group = { | ||
| 3564 | .name = NULL, /* put in device directory */ | ||
| 3565 | .attrs = iwl_sysfs_entries, | ||
| 3566 | }; | ||
| 3567 | |||
| 3568 | static struct ieee80211_ops iwl_hw_ops = { | 3575 | static struct ieee80211_ops iwl_hw_ops = { |
| 3569 | .tx = iwl_mac_tx, | 3576 | .tx = iwl_mac_tx, |
| 3570 | .start = iwl_mac_start, | 3577 | .start = iwl_mac_start, |
| @@ -3750,11 +3757,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3750 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | 3757 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); |
| 3751 | goto out_disable_msi; | 3758 | goto out_disable_msi; |
| 3752 | } | 3759 | } |
| 3753 | err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); | ||
| 3754 | if (err) { | ||
| 3755 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); | ||
| 3756 | goto out_free_irq; | ||
| 3757 | } | ||
| 3758 | 3760 | ||
| 3759 | iwl_setup_deferred_work(priv); | 3761 | iwl_setup_deferred_work(priv); |
| 3760 | iwl_setup_rx_handlers(priv); | 3762 | iwl_setup_rx_handlers(priv); |
| @@ -3788,15 +3790,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3788 | 3790 | ||
| 3789 | err = iwl_request_firmware(priv, true); | 3791 | err = iwl_request_firmware(priv, true); |
| 3790 | if (err) | 3792 | if (err) |
| 3791 | goto out_remove_sysfs; | 3793 | goto out_destroy_workqueue; |
| 3792 | 3794 | ||
| 3793 | return 0; | 3795 | return 0; |
| 3794 | 3796 | ||
| 3795 | out_remove_sysfs: | 3797 | out_destroy_workqueue: |
| 3796 | destroy_workqueue(priv->workqueue); | 3798 | destroy_workqueue(priv->workqueue); |
| 3797 | priv->workqueue = NULL; | 3799 | priv->workqueue = NULL; |
| 3798 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); | ||
| 3799 | out_free_irq: | ||
| 3800 | free_irq(priv->pci_dev->irq, priv); | 3800 | free_irq(priv->pci_dev->irq, priv); |
| 3801 | iwl_free_isr_ict(priv); | 3801 | iwl_free_isr_ict(priv); |
| 3802 | out_disable_msi: | 3802 | out_disable_msi: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5a7eca8fb789..426e95567de3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -854,6 +854,45 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) | |||
| 854 | } | 854 | } |
| 855 | EXPORT_SYMBOL(iwl_set_rxon_chain); | 855 | EXPORT_SYMBOL(iwl_set_rxon_chain); |
| 856 | 856 | ||
| 857 | /* Return valid channel */ | ||
| 858 | u8 iwl_get_single_channel_number(struct iwl_priv *priv, | ||
| 859 | enum ieee80211_band band) | ||
| 860 | { | ||
| 861 | const struct iwl_channel_info *ch_info; | ||
| 862 | int i; | ||
| 863 | u8 channel = 0; | ||
| 864 | |||
| 865 | /* only scan single channel, good enough to reset the RF */ | ||
| 866 | /* pick the first valid not in-use channel */ | ||
| 867 | if (band == IEEE80211_BAND_5GHZ) { | ||
| 868 | for (i = 14; i < priv->channel_count; i++) { | ||
| 869 | if (priv->channel_info[i].channel != | ||
| 870 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
| 871 | channel = priv->channel_info[i].channel; | ||
| 872 | ch_info = iwl_get_channel_info(priv, | ||
| 873 | band, channel); | ||
| 874 | if (is_channel_valid(ch_info)) | ||
| 875 | break; | ||
| 876 | } | ||
| 877 | } | ||
| 878 | } else { | ||
| 879 | for (i = 0; i < 14; i++) { | ||
| 880 | if (priv->channel_info[i].channel != | ||
| 881 | le16_to_cpu(priv->staging_rxon.channel)) { | ||
| 882 | channel = | ||
| 883 | priv->channel_info[i].channel; | ||
| 884 | ch_info = iwl_get_channel_info(priv, | ||
| 885 | band, channel); | ||
| 886 | if (is_channel_valid(ch_info)) | ||
| 887 | break; | ||
| 888 | } | ||
| 889 | } | ||
| 890 | } | ||
| 891 | |||
| 892 | return channel; | ||
| 893 | } | ||
| 894 | EXPORT_SYMBOL(iwl_get_single_channel_number); | ||
| 895 | |||
| 857 | /** | 896 | /** |
| 858 | * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON | 897 | * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON |
| 859 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz | 898 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7e5a5ba41fd2..31775bd9c361 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
| @@ -343,6 +343,8 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv); | |||
| 343 | int iwl_full_rxon_required(struct iwl_priv *priv); | 343 | int iwl_full_rxon_required(struct iwl_priv *priv); |
| 344 | void iwl_set_rxon_chain(struct iwl_priv *priv); | 344 | void iwl_set_rxon_chain(struct iwl_priv *priv); |
| 345 | int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); | 345 | int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); |
| 346 | u8 iwl_get_single_channel_number(struct iwl_priv *priv, | ||
| 347 | enum ieee80211_band band); | ||
| 346 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); | 348 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); |
| 347 | u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | 349 | u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, |
| 348 | struct ieee80211_sta_ht_cap *sta_ht_inf); | 350 | struct ieee80211_sta_ht_cap *sta_ht_inf); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3e5bffb6034f..6c353cacc8d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
| @@ -1844,6 +1844,49 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) | |||
| 1844 | #endif | 1844 | #endif |
| 1845 | } | 1845 | } |
| 1846 | 1846 | ||
| 1847 | static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, | ||
| 1848 | struct ieee80211_vif *vif, | ||
| 1849 | enum ieee80211_band band, | ||
| 1850 | struct iwl3945_scan_channel *scan_ch) | ||
| 1851 | { | ||
| 1852 | const struct ieee80211_supported_band *sband; | ||
| 1853 | u16 passive_dwell = 0; | ||
| 1854 | u16 active_dwell = 0; | ||
| 1855 | int added = 0; | ||
| 1856 | u8 channel = 0; | ||
| 1857 | |||
| 1858 | sband = iwl_get_hw_mode(priv, band); | ||
| 1859 | if (!sband) { | ||
| 1860 | IWL_ERR(priv, "invalid band\n"); | ||
| 1861 | return added; | ||
| 1862 | } | ||
| 1863 | |||
| 1864 | active_dwell = iwl_get_active_dwell_time(priv, band, 0); | ||
| 1865 | passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); | ||
| 1866 | |||
| 1867 | if (passive_dwell <= active_dwell) | ||
| 1868 | passive_dwell = active_dwell + 1; | ||
| 1869 | |||
| 1870 | |||
| 1871 | channel = iwl_get_single_channel_number(priv, band); | ||
| 1872 | |||
| 1873 | if (channel) { | ||
| 1874 | scan_ch->channel = channel; | ||
| 1875 | scan_ch->type = 0; /* passive */ | ||
| 1876 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
| 1877 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
| 1878 | /* Set txpower levels to defaults */ | ||
| 1879 | scan_ch->tpc.dsp_atten = 110; | ||
| 1880 | if (band == IEEE80211_BAND_5GHZ) | ||
| 1881 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
| 1882 | else | ||
| 1883 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | ||
| 1884 | added++; | ||
| 1885 | } else | ||
| 1886 | IWL_ERR(priv, "no valid channel found\n"); | ||
| 1887 | return added; | ||
| 1888 | } | ||
| 1889 | |||
| 1847 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, | 1890 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, |
| 1848 | enum ieee80211_band band, | 1891 | enum ieee80211_band band, |
| 1849 | u8 is_active, u8 n_probes, | 1892 | u8 is_active, u8 n_probes, |
| @@ -2992,9 +3035,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 2992 | /* select Rx antennas */ | 3035 | /* select Rx antennas */ |
| 2993 | scan->flags |= iwl3945_get_antenna_flags(priv); | 3036 | scan->flags |= iwl3945_get_antenna_flags(priv); |
| 2994 | 3037 | ||
| 2995 | scan->channel_count = | 3038 | if (priv->is_internal_short_scan) { |
| 2996 | iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, | 3039 | scan->channel_count = |
| 2997 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); | 3040 | iwl3945_get_single_channel_for_scan(priv, vif, band, |
| 3041 | (void *)&scan->data[le16_to_cpu( | ||
| 3042 | scan->tx_cmd.len)]); | ||
| 3043 | } else { | ||
| 3044 | scan->channel_count = | ||
| 3045 | iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, | ||
| 3046 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); | ||
| 3047 | } | ||
| 2998 | 3048 | ||
| 2999 | if (scan->channel_count == 0) { | 3049 | if (scan->channel_count == 0) { |
| 3000 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); | 3050 | IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5b197b4d5bb..73073259f508 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
| @@ -80,6 +80,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
| 80 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ | 80 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ |
| 81 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | 81 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ |
| 82 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | 82 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ |
| 83 | {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ | ||
| 83 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ | 84 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ |
| 84 | {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ | 85 | {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ |
| 85 | {} | 86 | {} |
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index d234285c2c81..c561332e7009 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c | |||
| @@ -259,6 +259,7 @@ disable: | |||
| 259 | sdio_disable_func(func); | 259 | sdio_disable_func(func); |
| 260 | release: | 260 | release: |
| 261 | sdio_release_host(func); | 261 | sdio_release_host(func); |
| 262 | wl1251_free_hw(wl); | ||
| 262 | return ret; | 263 | return ret; |
| 263 | } | 264 | } |
| 264 | 265 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 856123fe32f9..757f25eb9b4b 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -267,8 +267,10 @@ static void __net_exit ipmr_rules_exit(struct net *net) | |||
| 267 | { | 267 | { |
| 268 | struct mr_table *mrt, *next; | 268 | struct mr_table *mrt, *next; |
| 269 | 269 | ||
| 270 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) | 270 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { |
| 271 | list_del(&mrt->list); | ||
| 271 | kfree(mrt); | 272 | kfree(mrt); |
| 273 | } | ||
| 272 | fib_rules_unregister(net->ipv4.mr_rules_ops); | 274 | fib_rules_unregister(net->ipv4.mr_rules_ops); |
| 273 | } | 275 | } |
| 274 | #else | 276 | #else |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 073071f2b75b..66078dad7fe8 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -120,7 +120,7 @@ static void mroute_clean_tables(struct mr6_table *mrt); | |||
| 120 | static void ipmr_expire_process(unsigned long arg); | 120 | static void ipmr_expire_process(unsigned long arg); |
| 121 | 121 | ||
| 122 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES | 122 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES |
| 123 | #define ip6mr_for_each_table(mrt, met) \ | 123 | #define ip6mr_for_each_table(mrt, net) \ |
| 124 | list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list) | 124 | list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list) |
| 125 | 125 | ||
| 126 | static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) | 126 | static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) |
| @@ -254,8 +254,10 @@ static void __net_exit ip6mr_rules_exit(struct net *net) | |||
| 254 | { | 254 | { |
| 255 | struct mr6_table *mrt, *next; | 255 | struct mr6_table *mrt, *next; |
| 256 | 256 | ||
| 257 | list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) | 257 | list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) { |
| 258 | list_del(&mrt->list); | ||
| 258 | ip6mr_free_table(mrt); | 259 | ip6mr_free_table(mrt); |
| 260 | } | ||
| 259 | fib_rules_unregister(net->ipv6.mr6_rules_ops); | 261 | fib_rules_unregister(net->ipv6.mr6_rules_ops); |
| 260 | } | 262 | } |
| 261 | #else | 263 | #else |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 59f1881968c7..ab1622d7d409 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1356,7 +1356,10 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
| 1356 | IPV6_TLV_PADN, 0 }; | 1356 | IPV6_TLV_PADN, 0 }; |
| 1357 | 1357 | ||
| 1358 | /* we assume size > sizeof(ra) here */ | 1358 | /* we assume size > sizeof(ra) here */ |
| 1359 | skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err); | 1359 | size += LL_ALLOCATED_SPACE(dev); |
| 1360 | /* limit our allocations to order-0 page */ | ||
| 1361 | size = min_t(int, size, SKB_MAX_ORDER(0, 0)); | ||
| 1362 | skb = sock_alloc_send_skb(sk, size, 1, &err); | ||
| 1360 | 1363 | ||
| 1361 | if (!skb) | 1364 | if (!skb) |
| 1362 | return NULL; | 1365 | return NULL; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4f2271316650..9c1da0809160 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
| @@ -349,7 +349,7 @@ static inline int drv_get_survey(struct ieee80211_local *local, int idx, | |||
| 349 | struct survey_info *survey) | 349 | struct survey_info *survey) |
| 350 | { | 350 | { |
| 351 | int ret = -EOPNOTSUPP; | 351 | int ret = -EOPNOTSUPP; |
| 352 | if (local->ops->conf_tx) | 352 | if (local->ops->get_survey) |
| 353 | ret = local->ops->get_survey(&local->hw, idx, survey); | 353 | ret = local->ops->get_survey(&local->hw, idx, survey); |
| 354 | /* trace_drv_get_survey(local, idx, survey, ret); */ | 354 | /* trace_drv_get_survey(local, idx, survey, ret); */ |
| 355 | return ret; | 355 | return ret; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0839c4e8fd2e..f803f8b72a93 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1692,14 +1692,52 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 1692 | rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); | 1692 | rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); |
| 1693 | break; | 1693 | break; |
| 1694 | case IEEE80211_STYPE_ACTION: | 1694 | case IEEE80211_STYPE_ACTION: |
| 1695 | if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) | 1695 | switch (mgmt->u.action.category) { |
| 1696 | case WLAN_CATEGORY_BACK: { | ||
| 1697 | struct ieee80211_local *local = sdata->local; | ||
| 1698 | int len = skb->len; | ||
| 1699 | struct sta_info *sta; | ||
| 1700 | |||
| 1701 | rcu_read_lock(); | ||
| 1702 | sta = sta_info_get(sdata, mgmt->sa); | ||
| 1703 | if (!sta) { | ||
| 1704 | rcu_read_unlock(); | ||
| 1705 | break; | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | local_bh_disable(); | ||
| 1709 | |||
| 1710 | switch (mgmt->u.action.u.addba_req.action_code) { | ||
| 1711 | case WLAN_ACTION_ADDBA_REQ: | ||
| 1712 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1713 | sizeof(mgmt->u.action.u.addba_req))) | ||
| 1714 | break; | ||
| 1715 | ieee80211_process_addba_request(local, sta, mgmt, len); | ||
| 1716 | break; | ||
| 1717 | case WLAN_ACTION_ADDBA_RESP: | ||
| 1718 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1719 | sizeof(mgmt->u.action.u.addba_resp))) | ||
| 1720 | break; | ||
| 1721 | ieee80211_process_addba_resp(local, sta, mgmt, len); | ||
| 1722 | break; | ||
| 1723 | case WLAN_ACTION_DELBA: | ||
| 1724 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 1725 | sizeof(mgmt->u.action.u.delba))) | ||
| 1726 | break; | ||
| 1727 | ieee80211_process_delba(sdata, sta, mgmt, len); | ||
| 1728 | break; | ||
| 1729 | } | ||
| 1730 | local_bh_enable(); | ||
| 1731 | rcu_read_unlock(); | ||
| 1696 | break; | 1732 | break; |
| 1697 | 1733 | } | |
| 1698 | ieee80211_sta_process_chanswitch(sdata, | 1734 | case WLAN_CATEGORY_SPECTRUM_MGMT: |
| 1699 | &mgmt->u.action.u.chan_switch.sw_elem, | 1735 | ieee80211_sta_process_chanswitch(sdata, |
| 1700 | (void *)ifmgd->associated->priv, | 1736 | &mgmt->u.action.u.chan_switch.sw_elem, |
| 1701 | rx_status->mactime); | 1737 | (void *)ifmgd->associated->priv, |
| 1702 | break; | 1738 | rx_status->mactime); |
| 1739 | break; | ||
| 1740 | } | ||
| 1703 | } | 1741 | } |
| 1704 | mutex_unlock(&ifmgd->mtx); | 1742 | mutex_unlock(&ifmgd->mtx); |
| 1705 | 1743 | ||
| @@ -1722,9 +1760,45 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 1722 | mutex_unlock(&ifmgd->mtx); | 1760 | mutex_unlock(&ifmgd->mtx); |
| 1723 | 1761 | ||
| 1724 | if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && | 1762 | if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && |
| 1725 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) | 1763 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { |
| 1726 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | 1764 | struct ieee80211_local *local = sdata->local; |
| 1765 | struct ieee80211_work *wk; | ||
| 1766 | |||
| 1767 | mutex_lock(&local->work_mtx); | ||
| 1768 | list_for_each_entry(wk, &local->work_list, list) { | ||
| 1769 | if (wk->sdata != sdata) | ||
| 1770 | continue; | ||
| 1771 | |||
| 1772 | if (wk->type != IEEE80211_WORK_ASSOC) | ||
| 1773 | continue; | ||
| 1774 | |||
| 1775 | if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) | ||
| 1776 | continue; | ||
| 1777 | if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN)) | ||
| 1778 | continue; | ||
| 1727 | 1779 | ||
| 1780 | /* | ||
| 1781 | * Printing the message only here means we can't | ||
| 1782 | * spuriously print it, but it also means that it | ||
| 1783 | * won't be printed when the frame comes in before | ||
| 1784 | * we even tried to associate or in similar cases. | ||
| 1785 | * | ||
| 1786 | * Ultimately, I suspect cfg80211 should print the | ||
| 1787 | * messages instead. | ||
| 1788 | */ | ||
| 1789 | printk(KERN_DEBUG | ||
| 1790 | "%s: deauthenticated from %pM (Reason: %u)\n", | ||
| 1791 | sdata->name, mgmt->bssid, | ||
| 1792 | le16_to_cpu(mgmt->u.deauth.reason_code)); | ||
| 1793 | |||
| 1794 | list_del_rcu(&wk->list); | ||
| 1795 | free_work(wk); | ||
| 1796 | break; | ||
| 1797 | } | ||
| 1798 | mutex_unlock(&local->work_mtx); | ||
| 1799 | |||
| 1800 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | ||
| 1801 | } | ||
| 1728 | out: | 1802 | out: |
| 1729 | kfree_skb(skb); | 1803 | kfree_skb(skb); |
| 1730 | } | 1804 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5e0b65406c44..be9abc2e6348 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1944,6 +1944,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
| 1944 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | 1944 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) |
| 1945 | break; | 1945 | break; |
| 1946 | 1946 | ||
| 1947 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
| 1948 | return ieee80211_sta_rx_mgmt(sdata, rx->skb); | ||
| 1949 | |||
| 1947 | switch (mgmt->u.action.u.addba_req.action_code) { | 1950 | switch (mgmt->u.action.u.addba_req.action_code) { |
| 1948 | case WLAN_ACTION_ADDBA_REQ: | 1951 | case WLAN_ACTION_ADDBA_REQ: |
| 1949 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 1952 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
