diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-04 23:16:00 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-04 23:16:00 +0900 |
commit | 0e833d8cfcb52b5ee3ead22cabbab81dea32c3f0 (patch) | |
tree | 0c64533ba9181c014a4b2dcda75c273ae0437dd6 /drivers/net/wireless | |
parent | 4f1ba49efafccbc73017f824efa2505c81b247cd (diff) | |
parent | 7b29dc21ea084be7ddfb536994a9cfae95337690 (diff) | |
download | kernel_samsung_aries-0e833d8cfcb52b5ee3ead22cabbab81dea32c3f0.zip kernel_samsung_aries-0e833d8cfcb52b5ee3ead22cabbab81dea32c3f0.tar.gz kernel_samsung_aries-0e833d8cfcb52b5ee3ead22cabbab81dea32c3f0.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (40 commits)
tg3: Fix tg3_skb_error_unmap()
net: tracepoint of net_dev_xmit sees freed skb and causes panic
drivers/net/can/flexcan.c: add missing clk_put
net: dm9000: Get the chip in a known good state before enabling interrupts
drivers/net/davinci_emac.c: add missing clk_put
af-packet: Add flag to distinguish VID 0 from no-vlan.
caif: Fix race when conditionally taking rtnl lock
usbnet/cdc_ncm: add missing .reset_resume hook
vlan: fix typo in vlan_dev_hard_start_xmit()
net/ipv4: Check for mistakenly passed in non-IPv4 address
iwl4965: correctly validate temperature value
bluetooth l2cap: fix locking in l2cap_global_chan_by_psm
ath9k: fix two more bugs in tx power
cfg80211: don't drop p2p probe responses
Revert "net: fix section mismatches"
drivers/net/usb/catc.c: Fix potential deadlock in catc_ctrl_run()
sctp: stop pending timers and purge queues when peer restart asoc
drivers/net: ks8842 Fix crash on received packet when in PIO mode.
ip_options_compile: properly handle unaligned pointer
iwlagn: fix incorrect PCI subsystem id for 6150 devices
...
Diffstat (limited to 'drivers/net/wireless')
24 files changed, 185 insertions, 72 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index d9ff841..d9c08c6 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -26,7 +26,6 @@ config ATH9K config ATH9K_PCI bool "Atheros ath9k PCI/PCIe bus support" depends on ATH9K && PCI - default PCI ---help--- This option enables the PCI bus support in ath9k. diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 015d974..2d4c091 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -829,7 +829,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) if (AR_SREV_9271(ah)) { if (!ar9285_hw_cl_cal(ah, chan)) return false; - } else if (AR_SREV_9285_12_OR_LATER(ah)) { + } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) { if (!ar9285_hw_clc(ah, chan)) return false; } else { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 0ca7635..ff8150e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4645,10 +4645,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, case 1: break; case 2: - scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + else + scaledPower = 0; break; case 3: - scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + else + scaledPower = 0; break; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eee23ec..892c48b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1381,3 +1381,25 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) "==== BB update: done ====\n\n"); } EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); + +void ar9003_hw_disable_phy_restart(struct ath_hw *ah) +{ + u32 val; + + /* While receiving unsupported rate frame rx state machine + * gets into a state 0xb and if phy_restart happens in that + * state, BB would go hang. If RXSM is in 0xb state after + * first bb panic, ensure to disable the phy_restart. + */ + if (!((MS(ah->bb_watchdog_last_status, + AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) || + ah->bb_hang_rx_ofdm)) + return; + + ah->bb_hang_rx_ofdm = true; + val = REG_READ(ah, AR_PHY_RESTART); + val &= ~AR_PHY_RESTART_ENA; + + REG_WRITE(ah, AR_PHY_RESTART, val); +} +EXPORT_SYMBOL(ar9003_hw_disable_phy_restart); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 7856f0d..343fc9f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -524,10 +524,16 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, case 1: break; case 2: - scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + else + scaledPower = 0; break; case 3: - scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + else + scaledPower = 0; break; } scaledPower = max((u16)0, scaledPower); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 72543ce..1be7c8b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1555,9 +1555,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (ah->btcoex_hw.enabled) ath9k_hw_btcoex_enable(ah); - if (AR_SREV_9300_20_OR_LATER(ah)) + if (AR_SREV_9300_20_OR_LATER(ah)) { ar9003_hw_bb_watchdog_config(ah); + ar9003_hw_disable_phy_restart(ah); + } + ath9k_hw_apply_gpio_override(ah); return 0; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 57435ce..4b157c5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -842,6 +842,7 @@ struct ath_hw { u32 bb_watchdog_last_status; u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ + u8 bb_hang_rx_ofdm; /* true if bb hang due to rx_ofdm */ unsigned int paprd_target_power; unsigned int paprd_training_power; @@ -990,6 +991,7 @@ void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); +void ar9003_hw_disable_phy_restart(struct ath_hw *ah); void ar9003_paprd_enable(struct ath_hw *ah, bool val); void ar9003_paprd_populate_single_table(struct ath_hw *ah, struct ath9k_hw_cal_data *caldata, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a198ee3..2ca351f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -670,7 +670,8 @@ void ath9k_tasklet(unsigned long data) u32 status = sc->intrstatus; u32 rxmask; - if (status & ATH9K_INT_FATAL) { + if ((status & ATH9K_INT_FATAL) || + (status & ATH9K_INT_BB_WATCHDOG)) { ath_reset(sc, true); return; } @@ -737,6 +738,7 @@ irqreturn_t ath_isr(int irq, void *dev) { #define SCHED_INTR ( \ ATH9K_INT_FATAL | \ + ATH9K_INT_BB_WATCHDOG | \ ATH9K_INT_RXORN | \ ATH9K_INT_RXEOL | \ ATH9K_INT_RX | \ diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 1754221..ba7f36a 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -689,7 +689,8 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table, if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { rate->flags |= IEEE80211_TX_RC_MCS; - if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) + if (WLAN_RC_PHY_40(rate_table->info[rix].phy) && + conf_is_ht40(&txrc->hw->conf)) rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) rate->flags |= IEEE80211_TX_RC_SHORT_GI; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9ed6515..05960dd 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3093,7 +3093,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, int freq; bool avoid = false; u8 length; - u16 tmp, core, type, count, max, numb, last, cmd; + u16 tmp, core, type, count, max, numb, last = 0, cmd; const u16 *table; bool phy6or5x; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index 7e5e85a..a7a4739 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -628,11 +628,11 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, /* rx_status carries information about the packet to mac80211 */ rx_status.mactime = le64_to_cpu(phy_res->timestamp); + rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; rx_status.freq = ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), rx_status.band); - rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; rx_status.rate_idx = iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); rx_status.flag = 0; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f5433c7..f9db25b 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1543,7 +1543,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv) s32 temp; temp = iwl4965_hw_get_temperature(priv); - if (temp < 0) + if (IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp)) return; if (priv->temperature != temp) { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f8c710d..fda6fe0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -603,19 +603,27 @@ struct iwl_cfg iwl6050_2abg_cfg = { IWL_DEVICE_6050, }; +#define IWL_DEVICE_6150 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .ops = &iwl6150_ops, \ + .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ + .base_params = &iwl6050_base_params, \ + .need_dc_calib = true, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", - .fw_name_pre = IWL6050_FW_PRE, - .ucode_api_max = IWL6050_UCODE_API_MAX, - .ucode_api_min = IWL6050_UCODE_API_MIN, - .eeprom_ver = EEPROM_6150_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, - .ops = &iwl6150_ops, - .base_params = &iwl6050_base_params, + IWL_DEVICE_6150, .ht_params = &iwl6000_ht_params, - .need_dc_calib = true, - .led_mode = IWL_LED_RF_STATE, - .internal_wimax_coex = true, +}; + +struct iwl_cfg iwl6150_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", + IWL_DEVICE_6150, }; struct iwl_cfg iwl6000_3agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 11c6c11..a662adc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3831,11 +3831,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { /* 6150 WiFi/WiMax Series */ {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, - {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, /* 1000 Series WiFi */ {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2495fe7..d171684 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -89,6 +89,7 @@ extern struct iwl_cfg iwl6000_3agn_cfg; extern struct iwl_cfg iwl6050_2agn_cfg; extern struct iwl_cfg iwl6050_2abg_cfg; extern struct iwl_cfg iwl6150_bgn_cfg; +extern struct iwl_cfg iwl6150_bg_cfg; extern struct iwl_cfg iwl1000_bgn_cfg; extern struct iwl_cfg iwl1000_bg_cfg; extern struct iwl_cfg iwl100_bgn_cfg; diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 84566db..71c8f3f 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -994,6 +994,8 @@ static void lbs_submit_command(struct lbs_private *priv, cmd = cmdnode->cmdbuf; spin_lock_irqsave(&priv->driver_lock, flags); + priv->seqnum++; + cmd->seqnum = cpu_to_le16(priv->seqnum); priv->cur_cmd = cmdnode; spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -1621,11 +1623,9 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, /* Copy the incoming command to the buffer */ memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); - /* Set sequence number, clean result, move to buffer */ - priv->seqnum++; + /* Set command, clean result, move to buffer */ cmdnode->cmdbuf->command = cpu_to_le16(command); cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); - cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); cmdnode->cmdbuf->result = 0; lbs_deb_host("PREP_CMD: command 0x%04x\n", command); diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index a0e9bc5..4e97e90 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -167,8 +167,8 @@ /* Rx unit register */ #define CARD_RX_UNIT_REG 0x63 -/* Event header Len*/ -#define MWIFIEX_EVENT_HEADER_LEN 8 +/* Event header len w/o 4 bytes of interface header */ +#define MWIFIEX_EVENT_HEADER_LEN 4 /* Max retry number of CMD53 write */ #define MAX_WRITE_IOMEM_RETRY 2 diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 9def1e5..b2f8b8f 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -166,7 +166,6 @@ config RT2800USB_RT35XX config RT2800USB_RT53XX bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" depends on EXPERIMENTAL - default y ---help--- This adds support for rt53xx wireless chipset family to the rt2800pci driver. diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index a409528..89100e7 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -669,11 +669,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) &rx_status, (u8 *) pdesc, skb); - pci_unmap_single(rtlpci->pdev, - *((dma_addr_t *) skb->cb), - rtlpci->rxbuffersize, - PCI_DMA_FROMDEVICE); - skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false, HW_DESC_RXPKT_LEN)); @@ -690,6 +685,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) hdr = rtl_get_hdr(skb); fc = rtl_get_fc(skb); + /* try for new buffer - if allocation fails, drop + * frame and reuse old buffer + */ + new_skb = dev_alloc_skb(rtlpci->rxbuffersize); + if (unlikely(!new_skb)) { + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), + DBG_DMESG, + ("can't alloc skb for rx\n")); + goto done; + } + pci_unmap_single(rtlpci->pdev, + *((dma_addr_t *) skb->cb), + rtlpci->rxbuffersize, + PCI_DMA_FROMDEVICE); + if (!stats.crc || !stats.hwerror) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); @@ -758,15 +768,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) rtl_lps_leave(hw); } - new_skb = dev_alloc_skb(rtlpci->rxbuffersize); - if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); - goto done; - } skb = new_skb; - /*skb->dev = dev; */ rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> rx_ring @@ -1113,6 +1115,13 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) rtlpci->rx_ring[rx_queue_idx].idx = 0; + /* If amsdu_8k is disabled, set buffersize to 4096. This + * change will reduce memory fragmentation. + */ + if (rtlpci->rxbuffersize > 4096 && + rtlpriv->rtlhal.disable_amsdu_8k) + rtlpci->rxbuffersize = 4096; + for (i = 0; i < rtlpci->rxringcount; i++) { struct sk_buff *skb = dev_alloc_skb(rtlpci->rxbuffersize); diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 1ab6c86..c83fefb 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1157,6 +1157,9 @@ struct conf_sched_scan_settings { /* time to wait on the channel for passive scans (in TUs) */ u32 dwell_time_passive; + /* time to wait on the channel for DFS scans (in TUs) */ + u32 dwell_time_dfs; + /* number of probe requests to send on each channel in active scans */ u8 num_probe_reqs; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index bc00e52..e6497dc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -311,6 +311,7 @@ static struct conf_drv_settings default_conf = { .min_dwell_time_active = 8, .max_dwell_time_active = 30, .dwell_time_passive = 100, + .dwell_time_dfs = 150, .num_probe_reqs = 2, .rssi_threshold = -90, .snr_threshold = 0, diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index f37e5a3..56f76ab 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -331,16 +331,22 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, j; u32 flags; + bool force_passive = !req->n_ssids; for (i = 0, j = start; i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; i++) { flags = req->channels[i]->flags; - if (!(flags & IEEE80211_CHAN_DISABLED) && - ((flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive) && - ((flags & IEEE80211_CHAN_RADAR) == radar) && - (req->channels[i]->band == band)) { + if (force_passive) + flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + if ((req->channels[i]->band == band) && + !(flags & IEEE80211_CHAN_DISABLED) && + (!!(flags & IEEE80211_CHAN_RADAR) == radar) && + /* if radar is set, we ignore the passive flag */ + (radar || + !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", req->channels[i]->band, req->channels[i]->center_freq); @@ -350,7 +356,12 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, wl1271_debug(DEBUG_SCAN, "max_power %d", req->channels[i]->max_power); - if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { + if (flags & IEEE80211_CHAN_RADAR) { + channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; + channels[j].passive_duration = + cpu_to_le16(c->dwell_time_dfs); + } + else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { channels[j].passive_duration = cpu_to_le16(c->dwell_time_passive); } else { @@ -359,7 +370,7 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, channels[j].max_duration = cpu_to_le16(c->max_dwell_time_active); } - channels[j].tx_power_att = req->channels[j]->max_power; + channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; j++; @@ -386,7 +397,11 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, IEEE80211_BAND_2GHZ, false, false, idx); - idx += cfg->active[0]; + /* + * 5GHz channels always start at position 14, not immediately + * after the last 2.4GHz channel + */ + idx = 14; cfg->passive[1] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, @@ -394,22 +409,23 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, false, true, idx); idx += cfg->passive[1]; - cfg->active[1] = + cfg->dfs = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, IEEE80211_BAND_5GHZ, - false, false, 14); - idx += cfg->active[1]; + true, true, idx); + idx += cfg->dfs; - cfg->dfs = + cfg->active[1] = wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, IEEE80211_BAND_5GHZ, - true, false, idx); - idx += cfg->dfs; + false, false, idx); + idx += cfg->active[1]; wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", cfg->active[0], cfg->passive[0]); wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", cfg->active[1], cfg->passive[1]); + wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); return idx; } @@ -421,6 +437,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct wl1271_cmd_sched_scan_config *cfg = NULL; struct conf_sched_scan_settings *c = &wl->conf.sched_scan; int i, total_channels, ret; + bool force_passive = !req->n_ssids; wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); @@ -444,7 +461,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) cfg->intervals[i] = cpu_to_le32(req->interval); - if (req->ssids[0].ssid_len && req->ssids[0].ssid) { + if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; cfg->ssid_len = req->ssids[0].ssid_len; memcpy(cfg->ssid, req->ssids[0].ssid, @@ -461,7 +478,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, goto out; } - if (cfg->active[0]) { + if (!force_passive && cfg->active[0]) { ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[IEEE80211_BAND_2GHZ], @@ -473,7 +490,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, } } - if (cfg->active[1]) { + if (!force_passive && cfg->active[1]) { ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, req->ssids[0].ssid_len, ies->ie[IEEE80211_BAND_5GHZ], diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h index c833195..a0b6c5d 100644 --- a/drivers/net/wireless/wl12xx/scan.h +++ b/drivers/net/wireless/wl12xx/scan.h @@ -137,6 +137,9 @@ enum { SCAN_BSS_TYPE_ANY, }; +#define SCAN_CHANNEL_FLAGS_DFS BIT(0) +#define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1) + struct conn_scan_ch_params { __le16 min_duration; __le16 max_duration; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 0e81994..631194d 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1533,6 +1533,31 @@ static void __exit usb_exit(void) module_init(usb_init); module_exit(usb_exit); +static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len, + int *actual_length, int timeout) +{ + /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in + * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint + * descriptor. + */ + struct usb_host_endpoint *ep; + unsigned int pipe; + + pipe = usb_sndintpipe(udev, EP_REGS_OUT); + ep = usb_pipe_endpoint(udev, pipe); + if (!ep) + return -EINVAL; + + if (usb_endpoint_xfer_int(&ep->desc)) { + return usb_interrupt_msg(udev, pipe, data, len, + actual_length, timeout); + } else { + pipe = usb_sndbulkpipe(udev, EP_REGS_OUT); + return usb_bulk_msg(udev, pipe, data, len, actual_length, + timeout); + } +} + static int usb_int_regs_length(unsigned int count) { return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); @@ -1648,15 +1673,14 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, udev = zd_usb_to_usbdev(usb); prepare_read_regs_int(usb); - r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg(). Error number %d\n", r); + "error in zd_ep_regs_out_msg(). Error number %d\n", r); goto error; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" + dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; @@ -1818,9 +1842,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, rw->value = cpu_to_le16(ioreqs[i].value); } - usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, iowrite16v_urb_complete, usb, - ep->desc.bInterval); + /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode + * endpoint is bulk. Select correct type URB by endpoint descriptor. + */ + if (usb_endpoint_xfer_int(&ep->desc)) + usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), + req, req_len, iowrite16v_urb_complete, usb, + ep->desc.bInterval); + else + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT), + req, req_len, iowrite16v_urb_complete, usb); + urb->transfer_flags |= URB_FREE_BUFFER; /* Submit previous URB */ @@ -1924,15 +1956,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) } udev = zd_usb_to_usbdev(usb); - r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg(). Error number %d\n", r); + "error in zd_ep_regs_out_msg(). Error number %d\n", r); goto out; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" + dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; |