diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-12 10:57:04 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-12 10:57:04 -0400 |
commit | 42d887a68013b0a04f7b8ebfa4999a8d5df6775c (patch) | |
tree | 8cbd8cebe7420f3bcee87e3be0421aed215db450 | |
parent | b79462a8b9f9a452edc20c64a70a89ba3b0a6a88 (diff) | |
parent | e0e29b683d6784ef59bbc914eac85a04b650e63c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
27 files changed, 294 insertions, 95 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index fdfd61a2d523..11a6104a1e4f 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -201,7 +201,7 @@ config BT_MRVL | |||
201 | The core driver to support Marvell Bluetooth devices. | 201 | The core driver to support Marvell Bluetooth devices. |
202 | 202 | ||
203 | This driver is required if you want to support | 203 | This driver is required if you want to support |
204 | Marvell Bluetooth devices, such as 8688/8787/8797. | 204 | Marvell Bluetooth devices, such as 8688/8787/8797/8897. |
205 | 205 | ||
206 | Say Y here to compile Marvell Bluetooth driver | 206 | Say Y here to compile Marvell Bluetooth driver |
207 | into the kernel or say M to compile it as module. | 207 | into the kernel or say M to compile it as module. |
@@ -214,7 +214,7 @@ config BT_MRVL_SDIO | |||
214 | The driver for Marvell Bluetooth chipsets with SDIO interface. | 214 | The driver for Marvell Bluetooth chipsets with SDIO interface. |
215 | 215 | ||
216 | This driver is required if you want to use Marvell Bluetooth | 216 | This driver is required if you want to use Marvell Bluetooth |
217 | devices with SDIO interface. Currently SD8688/SD8787/SD8797 | 217 | devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897 |
218 | chipsets are supported. | 218 | chipsets are supported. |
219 | 219 | ||
220 | Say Y here to compile support for Marvell BT-over-SDIO driver | 220 | Say Y here to compile support for Marvell BT-over-SDIO driver |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index c63488c54f4a..13693b7a0d5c 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { | |||
82 | .io_port_2 = 0x7a, | 82 | .io_port_2 = 0x7a, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { | ||
86 | .cfg = 0x00, | ||
87 | .host_int_mask = 0x02, | ||
88 | .host_intstatus = 0x03, | ||
89 | .card_status = 0x50, | ||
90 | .sq_read_base_addr_a0 = 0x60, | ||
91 | .sq_read_base_addr_a1 = 0x61, | ||
92 | .card_revision = 0xbc, | ||
93 | .card_fw_status0 = 0xc0, | ||
94 | .card_fw_status1 = 0xc1, | ||
95 | .card_rx_len = 0xc2, | ||
96 | .card_rx_unit = 0xc3, | ||
97 | .io_port_0 = 0xd8, | ||
98 | .io_port_1 = 0xd9, | ||
99 | .io_port_2 = 0xda, | ||
100 | }; | ||
101 | |||
85 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { | 102 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { |
86 | .helper = "mrvl/sd8688_helper.bin", | 103 | .helper = "mrvl/sd8688_helper.bin", |
87 | .firmware = "mrvl/sd8688.bin", | 104 | .firmware = "mrvl/sd8688.bin", |
@@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { | |||
103 | .sd_blksz_fw_dl = 256, | 120 | .sd_blksz_fw_dl = 256, |
104 | }; | 121 | }; |
105 | 122 | ||
123 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { | ||
124 | .helper = NULL, | ||
125 | .firmware = "mrvl/sd8897_uapsta.bin", | ||
126 | .reg = &btmrvl_reg_88xx, | ||
127 | .sd_blksz_fw_dl = 256, | ||
128 | }; | ||
129 | |||
106 | static const struct sdio_device_id btmrvl_sdio_ids[] = { | 130 | static const struct sdio_device_id btmrvl_sdio_ids[] = { |
107 | /* Marvell SD8688 Bluetooth device */ | 131 | /* Marvell SD8688 Bluetooth device */ |
108 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), | 132 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), |
@@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { | |||
116 | /* Marvell SD8797 Bluetooth device */ | 140 | /* Marvell SD8797 Bluetooth device */ |
117 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), | 141 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), |
118 | .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, | 142 | .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, |
143 | /* Marvell SD8897 Bluetooth device */ | ||
144 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E), | ||
145 | .driver_data = (unsigned long) &btmrvl_sdio_sd8897 }, | ||
119 | 146 | ||
120 | { } /* Terminating entry */ | 147 | { } /* Terminating entry */ |
121 | }; | 148 | }; |
@@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); | |||
1194 | MODULE_FIRMWARE("mrvl/sd8688.bin"); | 1221 | MODULE_FIRMWARE("mrvl/sd8688.bin"); |
1195 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); | 1222 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); |
1196 | MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); | 1223 | MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); |
1224 | MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); | ||
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index f3dc124c60c7..3c2cbc9d6295 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG | |||
92 | This option enables collection of statistics for Rx/Tx status | 92 | This option enables collection of statistics for Rx/Tx status |
93 | data and some other MAC related statistics | 93 | data and some other MAC related statistics |
94 | 94 | ||
95 | config ATH9K_RATE_CONTROL | 95 | config ATH9K_LEGACY_RATE_CONTROL |
96 | bool "Atheros ath9k rate control" | 96 | bool "Atheros ath9k rate control" |
97 | depends on ATH9K | 97 | depends on ATH9K |
98 | default y | 98 | default n |
99 | ---help--- | 99 | ---help--- |
100 | Say Y, if you want to use the ath9k specific rate control | 100 | Say Y, if you want to use the ath9k specific rate control |
101 | module instead of minstrel_ht. | 101 | module instead of minstrel_ht. Be warned that there are various |
102 | issues with the ath9k RC and minstrel is a more robust algorithm. | ||
103 | Note that even if this option is selected, "ath9k_rate_control" | ||
104 | has to be passed to mac80211 using the module parameter, | ||
105 | ieee80211_default_rc_algo. | ||
102 | 106 | ||
103 | config ATH9K_HTC | 107 | config ATH9K_HTC |
104 | tristate "Atheros HTC based wireless cards support" | 108 | tristate "Atheros HTC based wireless cards support" |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 2ad8f9474ba1..75ee9e7704ce 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -8,7 +8,7 @@ ath9k-y += beacon.o \ | |||
8 | antenna.o | 8 | antenna.o |
9 | 9 | ||
10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o | 10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o |
11 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 11 | ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o |
12 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o | 12 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
13 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o | 13 | ath9k-$(CONFIG_ATH9K_AHB) += ahb.o |
14 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | 14 | ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index db5ffada2217..7546b9a7dcbf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { | |||
958 | {0x0000a074, 0x00000000}, | 958 | {0x0000a074, 0x00000000}, |
959 | {0x0000a078, 0x00000000}, | 959 | {0x0000a078, 0x00000000}, |
960 | {0x0000a07c, 0x00000000}, | 960 | {0x0000a07c, 0x00000000}, |
961 | {0x0000a080, 0x1a1a1a1a}, | 961 | {0x0000a080, 0x22222229}, |
962 | {0x0000a084, 0x1a1a1a1a}, | 962 | {0x0000a084, 0x1d1d1d1d}, |
963 | {0x0000a088, 0x1a1a1a1a}, | 963 | {0x0000a088, 0x1d1d1d1d}, |
964 | {0x0000a08c, 0x1a1a1a1a}, | 964 | {0x0000a08c, 0x1d1d1d1d}, |
965 | {0x0000a090, 0x171a1a1a}, | 965 | {0x0000a090, 0x171d1d1d}, |
966 | {0x0000a094, 0x11111717}, | 966 | {0x0000a094, 0x11111717}, |
967 | {0x0000a098, 0x00030311}, | 967 | {0x0000a098, 0x00030311}, |
968 | {0x0000a09c, 0x00000000}, | 968 | {0x0000a09c, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index aba415103f94..2ba494567777 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -787,8 +787,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
787 | hw->wiphy->iface_combinations = if_comb; | 787 | hw->wiphy->iface_combinations = if_comb; |
788 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); | 788 | hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); |
789 | 789 | ||
790 | if (AR_SREV_5416(sc->sc_ah)) | 790 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
791 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
792 | 791 | ||
793 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 792 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
794 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | 793 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; |
@@ -830,10 +829,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
830 | sc->ant_rx = hw->wiphy->available_antennas_rx; | 829 | sc->ant_rx = hw->wiphy->available_antennas_rx; |
831 | sc->ant_tx = hw->wiphy->available_antennas_tx; | 830 | sc->ant_tx = hw->wiphy->available_antennas_tx; |
832 | 831 | ||
833 | #ifdef CONFIG_ATH9K_RATE_CONTROL | ||
834 | hw->rate_control_algorithm = "ath9k_rate_control"; | ||
835 | #endif | ||
836 | |||
837 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) | 832 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) |
838 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 833 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
839 | &sc->sbands[IEEE80211_BAND_2GHZ]; | 834 | &sc->sbands[IEEE80211_BAND_2GHZ]; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 267dbfcfaa96..b9a87383cb43 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | |||
231 | } | 231 | } |
232 | #endif | 232 | #endif |
233 | 233 | ||
234 | #ifdef CONFIG_ATH9K_RATE_CONTROL | 234 | #ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL |
235 | int ath_rate_control_register(void); | 235 | int ath_rate_control_register(void); |
236 | void ath_rate_control_unregister(void); | 236 | void ath_rate_control_unregister(void); |
237 | #else | 237 | #else |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6dd07e2ec595..a95b77ab360e 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work) | |||
2458 | for (i = 0; i < B43_NR_FWTYPES; i++) { | 2458 | for (i = 0; i < B43_NR_FWTYPES; i++) { |
2459 | errmsg = ctx->errors[i]; | 2459 | errmsg = ctx->errors[i]; |
2460 | if (strlen(errmsg)) | 2460 | if (strlen(errmsg)) |
2461 | b43err(dev->wl, errmsg); | 2461 | b43err(dev->wl, "%s", errmsg); |
2462 | } | 2462 | } |
2463 | b43_print_fw_helptext(dev->wl, 1); | 2463 | b43_print_fw_helptext(dev->wl, 1); |
2464 | goto out; | 2464 | goto out; |
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index f8246f2d88f9..4caaf52986a4 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h | |||
@@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval); | |||
1832 | __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon, | 1832 | __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon, |
1833 | u32 beacon_interval); | 1833 | u32 beacon_interval); |
1834 | 1834 | ||
1835 | #ifdef CONFIG_PM | 1835 | #ifdef CONFIG_PM_SLEEP |
1836 | extern const struct dev_pm_ops il_pm_ops; | 1836 | extern const struct dev_pm_ops il_pm_ops; |
1837 | 1837 | ||
1838 | #define IL_LEGACY_PM_OPS (&il_pm_ops) | 1838 | #define IL_LEGACY_PM_OPS (&il_pm_ops) |
1839 | 1839 | ||
1840 | #else /* !CONFIG_PM */ | 1840 | #else /* !CONFIG_PM_SLEEP */ |
1841 | 1841 | ||
1842 | #define IL_LEGACY_PM_OPS NULL | 1842 | #define IL_LEGACY_PM_OPS NULL |
1843 | 1843 | ||
1844 | #endif /* !CONFIG_PM */ | 1844 | #endif /* !CONFIG_PM_SLEEP */ |
1845 | 1845 | ||
1846 | /***************************************************** | 1846 | /***************************************************** |
1847 | * Error Handling Debugging | 1847 | * Error Handling Debugging |
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 753b5682d53f..a5f9875cfd6e 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c | |||
@@ -26,10 +26,17 @@ | |||
26 | static struct dentry *mwifiex_dfs_dir; | 26 | static struct dentry *mwifiex_dfs_dir; |
27 | 27 | ||
28 | static char *bss_modes[] = { | 28 | static char *bss_modes[] = { |
29 | "Unknown", | 29 | "UNSPECIFIED", |
30 | "Ad-hoc", | 30 | "ADHOC", |
31 | "Managed", | 31 | "STATION", |
32 | "Auto" | 32 | "AP", |
33 | "AP_VLAN", | ||
34 | "WDS", | ||
35 | "MONITOR", | ||
36 | "MESH_POINT", | ||
37 | "P2P_CLIENT", | ||
38 | "P2P_GO", | ||
39 | "P2P_DEVICE", | ||
33 | }; | 40 | }; |
34 | 41 | ||
35 | /* size/addr for mwifiex_debug_info */ | 42 | /* size/addr for mwifiex_debug_info */ |
@@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf, | |||
200 | p += sprintf(p, "driver_version = %s", fmt); | 207 | p += sprintf(p, "driver_version = %s", fmt); |
201 | p += sprintf(p, "\nverext = %s", priv->version_str); | 208 | p += sprintf(p, "\nverext = %s", priv->version_str); |
202 | p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); | 209 | p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); |
203 | p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); | 210 | |
211 | if (info.bss_mode >= ARRAY_SIZE(bss_modes)) | ||
212 | p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode); | ||
213 | else | ||
214 | p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); | ||
215 | |||
204 | p += sprintf(p, "media_state=\"%s\"\n", | 216 | p += sprintf(p, "media_state=\"%s\"\n", |
205 | (!priv->media_connected ? "Disconnected" : "Connected")); | 217 | (!priv->media_connected ? "Disconnected" : "Connected")); |
206 | p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr); | 218 | p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr); |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 999ffc12578b..c97e9d327331 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
764 | "can't alloc skb for rx\n"); | 764 | "can't alloc skb for rx\n"); |
765 | goto done; | 765 | goto done; |
766 | } | 766 | } |
767 | kmemleak_not_leak(new_skb); | ||
767 | 768 | ||
768 | pci_unmap_single(rtlpci->pdev, | 769 | pci_unmap_single(rtlpci->pdev, |
769 | *((dma_addr_t *) skb->cb), | 770 | *((dma_addr_t *) skb->cb), |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 3d0498e69c8c..189ba124a8c6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1973 | } | 1973 | } |
1974 | } | 1974 | } |
1975 | 1975 | ||
1976 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, | 1976 | static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
1977 | struct ieee80211_sta *sta, | 1977 | struct ieee80211_sta *sta) |
1978 | u8 rssi_level) | ||
1979 | { | 1978 | { |
1980 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1979 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1981 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1980 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
1982 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1981 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1983 | u32 ratr_value = (u32) mac->basic_rates; | 1982 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
1984 | u8 *mcsrate = mac->mcs; | 1983 | u32 ratr_value; |
1985 | u8 ratr_index = 0; | 1984 | u8 ratr_index = 0; |
1986 | u8 nmode = mac->ht_enable; | 1985 | u8 nmode = mac->ht_enable; |
1987 | u8 mimo_ps = 1; | 1986 | u8 mimo_ps = IEEE80211_SMPS_OFF; |
1988 | u16 shortgi_rate = 0; | 1987 | u16 shortgi_rate; |
1989 | u32 tmp_ratr_value = 0; | 1988 | u32 tmp_ratr_value; |
1990 | u8 curtxbw_40mhz = mac->bw_40; | 1989 | u8 curtxbw_40mhz = mac->bw_40; |
1991 | u8 curshortgi_40mhz = mac->sgi_40; | 1990 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
1992 | u8 curshortgi_20mhz = mac->sgi_20; | 1991 | 1 : 0; |
1992 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
1993 | 1 : 0; | ||
1993 | enum wireless_mode wirelessmode = mac->mode; | 1994 | enum wireless_mode wirelessmode = mac->mode; |
1994 | 1995 | ||
1995 | ratr_value |= ((*(u16 *) (mcsrate))) << 12; | 1996 | if (rtlhal->current_bandtype == BAND_ON_5G) |
1997 | ratr_value = sta->supp_rates[1] << 4; | ||
1998 | else | ||
1999 | ratr_value = sta->supp_rates[0]; | ||
2000 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
2001 | ratr_value = 0xfff; | ||
2002 | |||
2003 | ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
2004 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
1996 | switch (wirelessmode) { | 2005 | switch (wirelessmode) { |
1997 | case WIRELESS_MODE_B: | 2006 | case WIRELESS_MODE_B: |
1998 | if (ratr_value & 0x0000000c) | 2007 | if (ratr_value & 0x0000000c) |
@@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, | |||
2006 | case WIRELESS_MODE_N_24G: | 2015 | case WIRELESS_MODE_N_24G: |
2007 | case WIRELESS_MODE_N_5G: | 2016 | case WIRELESS_MODE_N_5G: |
2008 | nmode = 1; | 2017 | nmode = 1; |
2009 | if (mimo_ps == 0) { | 2018 | if (mimo_ps == IEEE80211_SMPS_STATIC) { |
2010 | ratr_value &= 0x0007F005; | 2019 | ratr_value &= 0x0007F005; |
2011 | } else { | 2020 | } else { |
2012 | u32 ratr_mask; | 2021 | u32 ratr_mask; |
@@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, | |||
2016 | ratr_mask = 0x000ff005; | 2025 | ratr_mask = 0x000ff005; |
2017 | else | 2026 | else |
2018 | ratr_mask = 0x0f0ff005; | 2027 | ratr_mask = 0x0f0ff005; |
2019 | if (curtxbw_40mhz) | 2028 | |
2020 | ratr_mask |= 0x00000010; | ||
2021 | ratr_value &= ratr_mask; | 2029 | ratr_value &= ratr_mask; |
2022 | } | 2030 | } |
2023 | break; | 2031 | break; |
@@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, | |||
2026 | ratr_value &= 0x000ff0ff; | 2034 | ratr_value &= 0x000ff0ff; |
2027 | else | 2035 | else |
2028 | ratr_value &= 0x0f0ff0ff; | 2036 | ratr_value &= 0x0f0ff0ff; |
2037 | |||
2029 | break; | 2038 | break; |
2030 | } | 2039 | } |
2040 | |||
2031 | ratr_value &= 0x0FFFFFFF; | 2041 | ratr_value &= 0x0FFFFFFF; |
2032 | if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || | 2042 | |
2033 | (!curtxbw_40mhz && curshortgi_20mhz))) { | 2043 | if (nmode && ((curtxbw_40mhz && |
2044 | curshortgi_40mhz) || (!curtxbw_40mhz && | ||
2045 | curshortgi_20mhz))) { | ||
2046 | |||
2034 | ratr_value |= 0x10000000; | 2047 | ratr_value |= 0x10000000; |
2035 | tmp_ratr_value = (ratr_value >> 12); | 2048 | tmp_ratr_value = (ratr_value >> 12); |
2049 | |||
2036 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { | 2050 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { |
2037 | if ((1 << shortgi_rate) & tmp_ratr_value) | 2051 | if ((1 << shortgi_rate) & tmp_ratr_value) |
2038 | break; | 2052 | break; |
2039 | } | 2053 | } |
2054 | |||
2040 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | | 2055 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | |
2041 | (shortgi_rate << 4) | (shortgi_rate); | 2056 | (shortgi_rate << 4) | (shortgi_rate); |
2042 | } | 2057 | } |
2058 | |||
2043 | rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); | 2059 | rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); |
2060 | |||
2061 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", | ||
2062 | rtl_read_dword(rtlpriv, REG_ARFR0)); | ||
2044 | } | 2063 | } |
2045 | 2064 | ||
2046 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | 2065 | static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, |
2066 | struct ieee80211_sta *sta, | ||
2067 | u8 rssi_level) | ||
2047 | { | 2068 | { |
2048 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 2069 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
2049 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 2070 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
2050 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 2071 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
2051 | u32 ratr_bitmap = (u32) mac->basic_rates; | 2072 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
2052 | u8 *p_mcsrate = mac->mcs; | 2073 | struct rtl_sta_info *sta_entry = NULL; |
2053 | u8 ratr_index = 0; | 2074 | u32 ratr_bitmap; |
2054 | u8 curtxbw_40mhz = mac->bw_40; | 2075 | u8 ratr_index; |
2055 | u8 curshortgi_40mhz = mac->sgi_40; | 2076 | u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; |
2056 | u8 curshortgi_20mhz = mac->sgi_20; | 2077 | u8 curshortgi_40mhz = curtxbw_40mhz && |
2057 | enum wireless_mode wirelessmode = mac->mode; | 2078 | (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
2079 | 1 : 0; | ||
2080 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
2081 | 1 : 0; | ||
2082 | enum wireless_mode wirelessmode = 0; | ||
2058 | bool shortgi = false; | 2083 | bool shortgi = false; |
2059 | u8 rate_mask[5]; | 2084 | u8 rate_mask[5]; |
2060 | u8 macid = 0; | 2085 | u8 macid = 0; |
2061 | u8 mimops = 1; | 2086 | u8 mimo_ps = IEEE80211_SMPS_OFF; |
2062 | 2087 | ||
2063 | ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); | 2088 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
2089 | wirelessmode = sta_entry->wireless_mode; | ||
2090 | if (mac->opmode == NL80211_IFTYPE_STATION || | ||
2091 | mac->opmode == NL80211_IFTYPE_MESH_POINT) | ||
2092 | curtxbw_40mhz = mac->bw_40; | ||
2093 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
2094 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
2095 | macid = sta->aid + 1; | ||
2096 | |||
2097 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
2098 | ratr_bitmap = sta->supp_rates[1] << 4; | ||
2099 | else | ||
2100 | ratr_bitmap = sta->supp_rates[0]; | ||
2101 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
2102 | ratr_bitmap = 0xfff; | ||
2103 | ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
2104 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
2064 | switch (wirelessmode) { | 2105 | switch (wirelessmode) { |
2065 | case WIRELESS_MODE_B: | 2106 | case WIRELESS_MODE_B: |
2066 | ratr_index = RATR_INX_WIRELESS_B; | 2107 | ratr_index = RATR_INX_WIRELESS_B; |
@@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
2071 | break; | 2112 | break; |
2072 | case WIRELESS_MODE_G: | 2113 | case WIRELESS_MODE_G: |
2073 | ratr_index = RATR_INX_WIRELESS_GB; | 2114 | ratr_index = RATR_INX_WIRELESS_GB; |
2115 | |||
2074 | if (rssi_level == 1) | 2116 | if (rssi_level == 1) |
2075 | ratr_bitmap &= 0x00000f00; | 2117 | ratr_bitmap &= 0x00000f00; |
2076 | else if (rssi_level == 2) | 2118 | else if (rssi_level == 2) |
@@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
2085 | case WIRELESS_MODE_N_24G: | 2127 | case WIRELESS_MODE_N_24G: |
2086 | case WIRELESS_MODE_N_5G: | 2128 | case WIRELESS_MODE_N_5G: |
2087 | ratr_index = RATR_INX_WIRELESS_NGB; | 2129 | ratr_index = RATR_INX_WIRELESS_NGB; |
2088 | if (mimops == 0) { | 2130 | |
2131 | if (mimo_ps == IEEE80211_SMPS_STATIC) { | ||
2089 | if (rssi_level == 1) | 2132 | if (rssi_level == 1) |
2090 | ratr_bitmap &= 0x00070000; | 2133 | ratr_bitmap &= 0x00070000; |
2091 | else if (rssi_level == 2) | 2134 | else if (rssi_level == 2) |
@@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
2128 | } | 2171 | } |
2129 | } | 2172 | } |
2130 | } | 2173 | } |
2174 | |||
2131 | if ((curtxbw_40mhz && curshortgi_40mhz) || | 2175 | if ((curtxbw_40mhz && curshortgi_40mhz) || |
2132 | (!curtxbw_40mhz && curshortgi_20mhz)) { | 2176 | (!curtxbw_40mhz && curshortgi_20mhz)) { |
2177 | |||
2133 | if (macid == 0) | 2178 | if (macid == 0) |
2134 | shortgi = true; | 2179 | shortgi = true; |
2135 | else if (macid == 1) | 2180 | else if (macid == 1) |
@@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
2138 | break; | 2183 | break; |
2139 | default: | 2184 | default: |
2140 | ratr_index = RATR_INX_WIRELESS_NGB; | 2185 | ratr_index = RATR_INX_WIRELESS_NGB; |
2186 | |||
2141 | if (rtlphy->rf_type == RF_1T2R) | 2187 | if (rtlphy->rf_type == RF_1T2R) |
2142 | ratr_bitmap &= 0x000ff0ff; | 2188 | ratr_bitmap &= 0x000ff0ff; |
2143 | else | 2189 | else |
2144 | ratr_bitmap &= 0x0f0ff0ff; | 2190 | ratr_bitmap &= 0x0f0ff0ff; |
2145 | break; | 2191 | break; |
2146 | } | 2192 | } |
2147 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", | 2193 | sta_entry->ratr_index = ratr_index; |
2148 | ratr_bitmap); | 2194 | |
2149 | *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | | 2195 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
2150 | ratr_index << 28); | 2196 | "ratr_bitmap :%x\n", ratr_bitmap); |
2197 | *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | | ||
2198 | (ratr_index << 28); | ||
2151 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | 2199 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
2152 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 2200 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
2153 | "Rate_index:%x, ratr_val:%x, %5phC\n", | 2201 | "Rate_index:%x, ratr_val:%x, %5phC\n", |
2154 | ratr_index, ratr_bitmap, rate_mask); | 2202 | ratr_index, ratr_bitmap, rate_mask); |
2155 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | 2203 | memcpy(rtlpriv->rate_mask, rate_mask, 5); |
2204 | /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a | ||
2205 | * "scheduled while atomic" if called directly */ | ||
2206 | schedule_work(&rtlpriv->works.fill_h2c_cmd); | ||
2207 | |||
2208 | if (macid != 0) | ||
2209 | sta_entry->ratr_index = ratr_index; | ||
2210 | } | ||
2211 | |||
2212 | void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
2213 | struct ieee80211_sta *sta, | ||
2214 | u8 rssi_level) | ||
2215 | { | ||
2216 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2217 | |||
2218 | if (rtlpriv->dm.useramask) | ||
2219 | rtl92cu_update_hal_rate_mask(hw, sta, rssi_level); | ||
2220 | else | ||
2221 | rtl92cu_update_hal_rate_table(hw, sta); | ||
2156 | } | 2222 | } |
2157 | 2223 | ||
2158 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) | 2224 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index f41a3aa4a26f..8e3ec1e25644 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | |||
@@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, | |||
98 | u32 add_msr, u32 rm_msr); | 98 | u32 add_msr, u32 rm_msr); |
99 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 99 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
100 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 100 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
101 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, | ||
102 | struct ieee80211_sta *sta, | ||
103 | u8 rssi_level); | ||
104 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); | ||
105 | 101 | ||
106 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); | 102 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); |
107 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); | 103 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 85b6bdb163c0..da4f587199ee 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | |||
@@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, | |||
289 | macaddr = cam_const_broad; | 289 | macaddr = cam_const_broad; |
290 | entry_id = key_index; | 290 | entry_id = key_index; |
291 | } else { | 291 | } else { |
292 | if (mac->opmode == NL80211_IFTYPE_AP || | ||
293 | mac->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
294 | entry_id = rtl_cam_get_free_entry(hw, | ||
295 | p_macaddr); | ||
296 | if (entry_id >= TOTAL_CAM_ENTRY) { | ||
297 | RT_TRACE(rtlpriv, COMP_SEC, | ||
298 | DBG_EMERG, | ||
299 | "Can not find free hw security cam entry\n"); | ||
300 | return; | ||
301 | } | ||
302 | } else { | ||
303 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
304 | } | ||
305 | |||
292 | key_index = PAIRWISE_KEYIDX; | 306 | key_index = PAIRWISE_KEYIDX; |
293 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
294 | is_pairwise = true; | 307 | is_pairwise = true; |
295 | } | 308 | } |
296 | } | 309 | } |
297 | if (rtlpriv->sec.key_len[key_index] == 0) { | 310 | if (rtlpriv->sec.key_len[key_index] == 0) { |
298 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 311 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
299 | "delete one entry\n"); | 312 | "delete one entry\n"); |
313 | if (mac->opmode == NL80211_IFTYPE_AP || | ||
314 | mac->opmode == NL80211_IFTYPE_MESH_POINT) | ||
315 | rtl_cam_del_entry(hw, p_macaddr); | ||
300 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); | 316 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); |
301 | } else { | 317 | } else { |
302 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | 318 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 938b1e670b93..826f085c29dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { | |||
106 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, | 106 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, |
107 | .get_hw_reg = rtl92cu_get_hw_reg, | 107 | .get_hw_reg = rtl92cu_get_hw_reg, |
108 | .set_hw_reg = rtl92cu_set_hw_reg, | 108 | .set_hw_reg = rtl92cu_set_hw_reg, |
109 | .update_rate_tbl = rtl92cu_update_hal_rate_table, | 109 | .update_rate_tbl = rtl92cu_update_hal_rate_tbl, |
110 | .update_rate_mask = rtl92cu_update_hal_rate_mask, | ||
111 | .fill_tx_desc = rtl92cu_tx_fill_desc, | 110 | .fill_tx_desc = rtl92cu_tx_fill_desc, |
112 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, | 111 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, |
113 | .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, | 112 | .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, |
@@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { | |||
137 | .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, | 136 | .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, |
138 | .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, | 137 | .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, |
139 | .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, | 138 | .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, |
139 | .fill_h2c_cmd = rtl92c_fill_h2c_cmd, | ||
140 | }; | 140 | }; |
141 | 141 | ||
142 | static struct rtl_mod_params rtl92cu_mod_params = { | 142 | static struct rtl_mod_params rtl92cu_mod_params = { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index a1310abd0d54..262e1e4c6e5b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | |||
@@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
49 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, | 49 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, |
50 | enum radio_path rfpath, u32 regaddr, u32 bitmask); | 50 | enum radio_path rfpath, u32 regaddr, u32 bitmask); |
51 | void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | 51 | void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); |
52 | void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
53 | struct ieee80211_sta *sta, | ||
54 | u8 rssi_level); | ||
52 | 55 | ||
53 | #endif | 56 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 76732b0cd221..a3532e077871 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) | |||
824 | 824 | ||
825 | /* should after adapter start and interrupt enable. */ | 825 | /* should after adapter start and interrupt enable. */ |
826 | set_hal_stop(rtlhal); | 826 | set_hal_stop(rtlhal); |
827 | cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); | ||
827 | /* Enable software */ | 828 | /* Enable software */ |
828 | SET_USB_STOP(rtlusb); | 829 | SET_USB_STOP(rtlusb); |
829 | rtl_usb_deinit(hw); | 830 | rtl_usb_deinit(hw); |
@@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, | |||
1026 | return false; | 1027 | return false; |
1027 | } | 1028 | } |
1028 | 1029 | ||
1030 | static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work) | ||
1031 | { | ||
1032 | struct rtl_works *rtlworks = | ||
1033 | container_of(work, struct rtl_works, fill_h2c_cmd); | ||
1034 | struct ieee80211_hw *hw = rtlworks->hw; | ||
1035 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1036 | |||
1037 | rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask); | ||
1038 | } | ||
1039 | |||
1029 | static struct rtl_intf_ops rtl_usb_ops = { | 1040 | static struct rtl_intf_ops rtl_usb_ops = { |
1030 | .adapter_start = rtl_usb_start, | 1041 | .adapter_start = rtl_usb_start, |
1031 | .adapter_stop = rtl_usb_stop, | 1042 | .adapter_stop = rtl_usb_stop, |
@@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf, | |||
1057 | 1068 | ||
1058 | /* this spin lock must be initialized early */ | 1069 | /* this spin lock must be initialized early */ |
1059 | spin_lock_init(&rtlpriv->locks.usb_lock); | 1070 | spin_lock_init(&rtlpriv->locks.usb_lock); |
1071 | INIT_WORK(&rtlpriv->works.fill_h2c_cmd, | ||
1072 | rtl_fill_h2c_cmd_work_callback); | ||
1060 | 1073 | ||
1061 | rtlpriv->usb_data_index = 0; | 1074 | rtlpriv->usb_data_index = 0; |
1062 | init_completion(&rtlpriv->firmware_loading_complete); | 1075 | init_completion(&rtlpriv->firmware_loading_complete); |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 44328baa6389..cc03e7c87cbe 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -1736,6 +1736,8 @@ struct rtl_hal_ops { | |||
1736 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, | 1736 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, |
1737 | bool mstate); | 1737 | bool mstate); |
1738 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); | 1738 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); |
1739 | void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id, | ||
1740 | u32 cmd_len, u8 *p_cmdbuffer); | ||
1739 | }; | 1741 | }; |
1740 | 1742 | ||
1741 | struct rtl_intf_ops { | 1743 | struct rtl_intf_ops { |
@@ -1869,6 +1871,7 @@ struct rtl_works { | |||
1869 | struct delayed_work fwevt_wq; | 1871 | struct delayed_work fwevt_wq; |
1870 | 1872 | ||
1871 | struct work_struct lps_change_work; | 1873 | struct work_struct lps_change_work; |
1874 | struct work_struct fill_h2c_cmd; | ||
1872 | }; | 1875 | }; |
1873 | 1876 | ||
1874 | struct rtl_debug { | 1877 | struct rtl_debug { |
@@ -2048,6 +2051,7 @@ struct rtl_priv { | |||
2048 | }; | 2051 | }; |
2049 | }; | 2052 | }; |
2050 | bool enter_ps; /* true when entering PS */ | 2053 | bool enter_ps; /* true when entering PS */ |
2054 | u8 rate_mask[5]; | ||
2051 | 2055 | ||
2052 | /*This must be the last item so | 2056 | /*This must be the last item so |
2053 | that it points to the data allocated | 2057 | that it points to the data allocated |
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c index affdb3ec6225..4a0bbb13806b 100644 --- a/drivers/net/wireless/ti/wl12xx/scan.c +++ b/drivers/net/wireless/ti/wl12xx/scan.c | |||
@@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd, | |||
310 | memcpy(cmd->channels_2, cmd_channels->channels_2, | 310 | memcpy(cmd->channels_2, cmd_channels->channels_2, |
311 | sizeof(cmd->channels_2)); | 311 | sizeof(cmd->channels_2)); |
312 | memcpy(cmd->channels_5, cmd_channels->channels_5, | 312 | memcpy(cmd->channels_5, cmd_channels->channels_5, |
313 | sizeof(cmd->channels_2)); | 313 | sizeof(cmd->channels_5)); |
314 | /* channels_4 are not supported, so no need to copy them */ | 314 | /* channels_4 are not supported, so no need to copy them */ |
315 | } | 315 | } |
316 | 316 | ||
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 222d03540200..9e5484a73667 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h | |||
@@ -36,12 +36,12 @@ | |||
36 | #define WL127X_IFTYPE_SR_VER 3 | 36 | #define WL127X_IFTYPE_SR_VER 3 |
37 | #define WL127X_MAJOR_SR_VER 10 | 37 | #define WL127X_MAJOR_SR_VER 10 |
38 | #define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE | 38 | #define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE |
39 | #define WL127X_MINOR_SR_VER 115 | 39 | #define WL127X_MINOR_SR_VER 133 |
40 | /* minimum multi-role FW version for wl127x */ | 40 | /* minimum multi-role FW version for wl127x */ |
41 | #define WL127X_IFTYPE_MR_VER 5 | 41 | #define WL127X_IFTYPE_MR_VER 5 |
42 | #define WL127X_MAJOR_MR_VER 7 | 42 | #define WL127X_MAJOR_MR_VER 7 |
43 | #define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE | 43 | #define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE |
44 | #define WL127X_MINOR_MR_VER 115 | 44 | #define WL127X_MINOR_MR_VER 42 |
45 | 45 | ||
46 | /* FW chip version for wl128x */ | 46 | /* FW chip version for wl128x */ |
47 | #define WL128X_CHIP_VER 7 | 47 | #define WL128X_CHIP_VER 7 |
@@ -49,7 +49,7 @@ | |||
49 | #define WL128X_IFTYPE_SR_VER 3 | 49 | #define WL128X_IFTYPE_SR_VER 3 |
50 | #define WL128X_MAJOR_SR_VER 10 | 50 | #define WL128X_MAJOR_SR_VER 10 |
51 | #define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE | 51 | #define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE |
52 | #define WL128X_MINOR_SR_VER 115 | 52 | #define WL128X_MINOR_SR_VER 133 |
53 | /* minimum multi-role FW version for wl128x */ | 53 | /* minimum multi-role FW version for wl128x */ |
54 | #define WL128X_IFTYPE_MR_VER 5 | 54 | #define WL128X_IFTYPE_MR_VER 5 |
55 | #define WL128X_MAJOR_MR_VER 7 | 55 | #define WL128X_MAJOR_MR_VER 7 |
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c index 09d944505ac0..2b642f8c9266 100644 --- a/drivers/net/wireless/ti/wl18xx/scan.c +++ b/drivers/net/wireless/ti/wl18xx/scan.c | |||
@@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd, | |||
34 | memcpy(cmd->channels_2, cmd_channels->channels_2, | 34 | memcpy(cmd->channels_2, cmd_channels->channels_2, |
35 | sizeof(cmd->channels_2)); | 35 | sizeof(cmd->channels_2)); |
36 | memcpy(cmd->channels_5, cmd_channels->channels_5, | 36 | memcpy(cmd->channels_5, cmd_channels->channels_5, |
37 | sizeof(cmd->channels_2)); | 37 | sizeof(cmd->channels_5)); |
38 | /* channels_4 are not supported, so no need to copy them */ | 38 | /* channels_4 are not supported, so no need to copy them */ |
39 | } | 39 | } |
40 | 40 | ||
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 35a57cd1704c..7cb6d360d147 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); | |||
1117 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 1117 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
1118 | int mgmt_index_added(struct hci_dev *hdev); | 1118 | int mgmt_index_added(struct hci_dev *hdev); |
1119 | int mgmt_index_removed(struct hci_dev *hdev); | 1119 | int mgmt_index_removed(struct hci_dev *hdev); |
1120 | int mgmt_set_powered_failed(struct hci_dev *hdev, int err); | ||
1120 | int mgmt_powered(struct hci_dev *hdev, u8 powered); | 1121 | int mgmt_powered(struct hci_dev *hdev, u8 powered); |
1121 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); | 1122 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); |
1122 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable); | 1123 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable); |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 22980a7c3873..9944c3e68c5d 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #define MGMT_STATUS_NOT_POWERED 0x0f | 42 | #define MGMT_STATUS_NOT_POWERED 0x0f |
43 | #define MGMT_STATUS_CANCELLED 0x10 | 43 | #define MGMT_STATUS_CANCELLED 0x10 |
44 | #define MGMT_STATUS_INVALID_INDEX 0x11 | 44 | #define MGMT_STATUS_INVALID_INDEX 0x11 |
45 | #define MGMT_STATUS_RFKILLED 0x12 | ||
45 | 46 | ||
46 | struct mgmt_hdr { | 47 | struct mgmt_hdr { |
47 | __le16 opcode; | 48 | __le16 opcode; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 33843c5c4939..d817c932d634 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = { | |||
1555 | static void hci_power_on(struct work_struct *work) | 1555 | static void hci_power_on(struct work_struct *work) |
1556 | { | 1556 | { |
1557 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); | 1557 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); |
1558 | int err; | ||
1558 | 1559 | ||
1559 | BT_DBG("%s", hdev->name); | 1560 | BT_DBG("%s", hdev->name); |
1560 | 1561 | ||
1561 | if (hci_dev_open(hdev->id) < 0) | 1562 | err = hci_dev_open(hdev->id); |
1563 | if (err < 0) { | ||
1564 | mgmt_set_powered_failed(hdev, err); | ||
1562 | return; | 1565 | return; |
1566 | } | ||
1563 | 1567 | ||
1564 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | 1568 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) |
1565 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, | 1569 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a76d1ac0321b..24bee07ee4ce 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) | |||
3677 | } | 3677 | } |
3678 | 3678 | ||
3679 | static inline int l2cap_command_rej(struct l2cap_conn *conn, | 3679 | static inline int l2cap_command_rej(struct l2cap_conn *conn, |
3680 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3680 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
3681 | u8 *data) | ||
3681 | { | 3682 | { |
3682 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; | 3683 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
3683 | 3684 | ||
3685 | if (cmd_len < sizeof(*rej)) | ||
3686 | return -EPROTO; | ||
3687 | |||
3684 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) | 3688 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) |
3685 | return 0; | 3689 | return 0; |
3686 | 3690 | ||
@@ -3829,11 +3833,14 @@ sendresp: | |||
3829 | } | 3833 | } |
3830 | 3834 | ||
3831 | static int l2cap_connect_req(struct l2cap_conn *conn, | 3835 | static int l2cap_connect_req(struct l2cap_conn *conn, |
3832 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3836 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) |
3833 | { | 3837 | { |
3834 | struct hci_dev *hdev = conn->hcon->hdev; | 3838 | struct hci_dev *hdev = conn->hcon->hdev; |
3835 | struct hci_conn *hcon = conn->hcon; | 3839 | struct hci_conn *hcon = conn->hcon; |
3836 | 3840 | ||
3841 | if (cmd_len < sizeof(struct l2cap_conn_req)) | ||
3842 | return -EPROTO; | ||
3843 | |||
3837 | hci_dev_lock(hdev); | 3844 | hci_dev_lock(hdev); |
3838 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | 3845 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && |
3839 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) | 3846 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) |
@@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn, | |||
3847 | } | 3854 | } |
3848 | 3855 | ||
3849 | static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | 3856 | static int l2cap_connect_create_rsp(struct l2cap_conn *conn, |
3850 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3857 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
3858 | u8 *data) | ||
3851 | { | 3859 | { |
3852 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; | 3860 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; |
3853 | u16 scid, dcid, result, status; | 3861 | u16 scid, dcid, result, status; |
@@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | |||
3855 | u8 req[128]; | 3863 | u8 req[128]; |
3856 | int err; | 3864 | int err; |
3857 | 3865 | ||
3866 | if (cmd_len < sizeof(*rsp)) | ||
3867 | return -EPROTO; | ||
3868 | |||
3858 | scid = __le16_to_cpu(rsp->scid); | 3869 | scid = __le16_to_cpu(rsp->scid); |
3859 | dcid = __le16_to_cpu(rsp->dcid); | 3870 | dcid = __le16_to_cpu(rsp->dcid); |
3860 | result = __le16_to_cpu(rsp->result); | 3871 | result = __le16_to_cpu(rsp->result); |
@@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
3952 | struct l2cap_chan *chan; | 3963 | struct l2cap_chan *chan; |
3953 | int len, err = 0; | 3964 | int len, err = 0; |
3954 | 3965 | ||
3966 | if (cmd_len < sizeof(*req)) | ||
3967 | return -EPROTO; | ||
3968 | |||
3955 | dcid = __le16_to_cpu(req->dcid); | 3969 | dcid = __le16_to_cpu(req->dcid); |
3956 | flags = __le16_to_cpu(req->flags); | 3970 | flags = __le16_to_cpu(req->flags); |
3957 | 3971 | ||
@@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
3975 | 3989 | ||
3976 | /* Reject if config buffer is too small. */ | 3990 | /* Reject if config buffer is too small. */ |
3977 | len = cmd_len - sizeof(*req); | 3991 | len = cmd_len - sizeof(*req); |
3978 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { | 3992 | if (chan->conf_len + len > sizeof(chan->conf_req)) { |
3979 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3993 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
3980 | l2cap_build_conf_rsp(chan, rsp, | 3994 | l2cap_build_conf_rsp(chan, rsp, |
3981 | L2CAP_CONF_REJECT, flags), rsp); | 3995 | L2CAP_CONF_REJECT, flags), rsp); |
@@ -4053,14 +4067,18 @@ unlock: | |||
4053 | } | 4067 | } |
4054 | 4068 | ||
4055 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, | 4069 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, |
4056 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4070 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4071 | u8 *data) | ||
4057 | { | 4072 | { |
4058 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; | 4073 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; |
4059 | u16 scid, flags, result; | 4074 | u16 scid, flags, result; |
4060 | struct l2cap_chan *chan; | 4075 | struct l2cap_chan *chan; |
4061 | int len = le16_to_cpu(cmd->len) - sizeof(*rsp); | 4076 | int len = cmd_len - sizeof(*rsp); |
4062 | int err = 0; | 4077 | int err = 0; |
4063 | 4078 | ||
4079 | if (cmd_len < sizeof(*rsp)) | ||
4080 | return -EPROTO; | ||
4081 | |||
4064 | scid = __le16_to_cpu(rsp->scid); | 4082 | scid = __le16_to_cpu(rsp->scid); |
4065 | flags = __le16_to_cpu(rsp->flags); | 4083 | flags = __le16_to_cpu(rsp->flags); |
4066 | result = __le16_to_cpu(rsp->result); | 4084 | result = __le16_to_cpu(rsp->result); |
@@ -4161,7 +4179,8 @@ done: | |||
4161 | } | 4179 | } |
4162 | 4180 | ||
4163 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | 4181 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
4164 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4182 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4183 | u8 *data) | ||
4165 | { | 4184 | { |
4166 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; | 4185 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; |
4167 | struct l2cap_disconn_rsp rsp; | 4186 | struct l2cap_disconn_rsp rsp; |
@@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4169 | struct l2cap_chan *chan; | 4188 | struct l2cap_chan *chan; |
4170 | struct sock *sk; | 4189 | struct sock *sk; |
4171 | 4190 | ||
4191 | if (cmd_len != sizeof(*req)) | ||
4192 | return -EPROTO; | ||
4193 | |||
4172 | scid = __le16_to_cpu(req->scid); | 4194 | scid = __le16_to_cpu(req->scid); |
4173 | dcid = __le16_to_cpu(req->dcid); | 4195 | dcid = __le16_to_cpu(req->dcid); |
4174 | 4196 | ||
@@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4208 | } | 4230 | } |
4209 | 4231 | ||
4210 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | 4232 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, |
4211 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4233 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4234 | u8 *data) | ||
4212 | { | 4235 | { |
4213 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; | 4236 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; |
4214 | u16 dcid, scid; | 4237 | u16 dcid, scid; |
4215 | struct l2cap_chan *chan; | 4238 | struct l2cap_chan *chan; |
4216 | 4239 | ||
4240 | if (cmd_len != sizeof(*rsp)) | ||
4241 | return -EPROTO; | ||
4242 | |||
4217 | scid = __le16_to_cpu(rsp->scid); | 4243 | scid = __le16_to_cpu(rsp->scid); |
4218 | dcid = __le16_to_cpu(rsp->dcid); | 4244 | dcid = __le16_to_cpu(rsp->dcid); |
4219 | 4245 | ||
@@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | |||
4243 | } | 4269 | } |
4244 | 4270 | ||
4245 | static inline int l2cap_information_req(struct l2cap_conn *conn, | 4271 | static inline int l2cap_information_req(struct l2cap_conn *conn, |
4246 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4272 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4273 | u8 *data) | ||
4247 | { | 4274 | { |
4248 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; | 4275 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; |
4249 | u16 type; | 4276 | u16 type; |
4250 | 4277 | ||
4278 | if (cmd_len != sizeof(*req)) | ||
4279 | return -EPROTO; | ||
4280 | |||
4251 | type = __le16_to_cpu(req->type); | 4281 | type = __le16_to_cpu(req->type); |
4252 | 4282 | ||
4253 | BT_DBG("type 0x%4.4x", type); | 4283 | BT_DBG("type 0x%4.4x", type); |
@@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, | |||
4294 | } | 4324 | } |
4295 | 4325 | ||
4296 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, | 4326 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, |
4297 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4327 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4328 | u8 *data) | ||
4298 | { | 4329 | { |
4299 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 4330 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
4300 | u16 type, result; | 4331 | u16 type, result; |
4301 | 4332 | ||
4333 | if (cmd_len != sizeof(*rsp)) | ||
4334 | return -EPROTO; | ||
4335 | |||
4302 | type = __le16_to_cpu(rsp->type); | 4336 | type = __le16_to_cpu(rsp->type); |
4303 | result = __le16_to_cpu(rsp->result); | 4337 | result = __le16_to_cpu(rsp->result); |
4304 | 4338 | ||
@@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5164 | 5198 | ||
5165 | switch (cmd->code) { | 5199 | switch (cmd->code) { |
5166 | case L2CAP_COMMAND_REJ: | 5200 | case L2CAP_COMMAND_REJ: |
5167 | l2cap_command_rej(conn, cmd, data); | 5201 | l2cap_command_rej(conn, cmd, cmd_len, data); |
5168 | break; | 5202 | break; |
5169 | 5203 | ||
5170 | case L2CAP_CONN_REQ: | 5204 | case L2CAP_CONN_REQ: |
5171 | err = l2cap_connect_req(conn, cmd, data); | 5205 | err = l2cap_connect_req(conn, cmd, cmd_len, data); |
5172 | break; | 5206 | break; |
5173 | 5207 | ||
5174 | case L2CAP_CONN_RSP: | 5208 | case L2CAP_CONN_RSP: |
5175 | case L2CAP_CREATE_CHAN_RSP: | 5209 | case L2CAP_CREATE_CHAN_RSP: |
5176 | err = l2cap_connect_create_rsp(conn, cmd, data); | 5210 | err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data); |
5177 | break; | 5211 | break; |
5178 | 5212 | ||
5179 | case L2CAP_CONF_REQ: | 5213 | case L2CAP_CONF_REQ: |
@@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5181 | break; | 5215 | break; |
5182 | 5216 | ||
5183 | case L2CAP_CONF_RSP: | 5217 | case L2CAP_CONF_RSP: |
5184 | err = l2cap_config_rsp(conn, cmd, data); | 5218 | err = l2cap_config_rsp(conn, cmd, cmd_len, data); |
5185 | break; | 5219 | break; |
5186 | 5220 | ||
5187 | case L2CAP_DISCONN_REQ: | 5221 | case L2CAP_DISCONN_REQ: |
5188 | err = l2cap_disconnect_req(conn, cmd, data); | 5222 | err = l2cap_disconnect_req(conn, cmd, cmd_len, data); |
5189 | break; | 5223 | break; |
5190 | 5224 | ||
5191 | case L2CAP_DISCONN_RSP: | 5225 | case L2CAP_DISCONN_RSP: |
5192 | err = l2cap_disconnect_rsp(conn, cmd, data); | 5226 | err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data); |
5193 | break; | 5227 | break; |
5194 | 5228 | ||
5195 | case L2CAP_ECHO_REQ: | 5229 | case L2CAP_ECHO_REQ: |
@@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5200 | break; | 5234 | break; |
5201 | 5235 | ||
5202 | case L2CAP_INFO_REQ: | 5236 | case L2CAP_INFO_REQ: |
5203 | err = l2cap_information_req(conn, cmd, data); | 5237 | err = l2cap_information_req(conn, cmd, cmd_len, data); |
5204 | break; | 5238 | break; |
5205 | 5239 | ||
5206 | case L2CAP_INFO_RSP: | 5240 | case L2CAP_INFO_RSP: |
5207 | err = l2cap_information_rsp(conn, cmd, data); | 5241 | err = l2cap_information_rsp(conn, cmd, cmd_len, data); |
5208 | break; | 5242 | break; |
5209 | 5243 | ||
5210 | case L2CAP_CREATE_CHAN_REQ: | 5244 | case L2CAP_CREATE_CHAN_REQ: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 35fef22703e9..f8ecbc70293d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2700 | break; | 2700 | break; |
2701 | 2701 | ||
2702 | case DISCOV_TYPE_LE: | 2702 | case DISCOV_TYPE_LE: |
2703 | if (!lmp_host_le_capable(hdev)) { | 2703 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2705 | MGMT_STATUS_NOT_SUPPORTED); | 2705 | MGMT_STATUS_NOT_SUPPORTED); |
2706 | mgmt_pending_remove(cmd); | 2706 | mgmt_pending_remove(cmd); |
@@ -3418,6 +3418,27 @@ new_settings: | |||
3418 | return err; | 3418 | return err; |
3419 | } | 3419 | } |
3420 | 3420 | ||
3421 | int mgmt_set_powered_failed(struct hci_dev *hdev, int err) | ||
3422 | { | ||
3423 | struct pending_cmd *cmd; | ||
3424 | u8 status; | ||
3425 | |||
3426 | cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | ||
3427 | if (!cmd) | ||
3428 | return -ENOENT; | ||
3429 | |||
3430 | if (err == -ERFKILL) | ||
3431 | status = MGMT_STATUS_RFKILLED; | ||
3432 | else | ||
3433 | status = MGMT_STATUS_FAILED; | ||
3434 | |||
3435 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); | ||
3436 | |||
3437 | mgmt_pending_remove(cmd); | ||
3438 | |||
3439 | return err; | ||
3440 | } | ||
3441 | |||
3421 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | 3442 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
3422 | { | 3443 | { |
3423 | struct cmd_lookup match = { NULL, hdev }; | 3444 | struct cmd_lookup match = { NULL, hdev }; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index b2296d3857a0..b5562abdd6e0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
770 | 770 | ||
771 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 771 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
772 | 772 | ||
773 | if (!lmp_host_le_capable(hcon->hdev)) | 773 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) |
774 | return 1; | 774 | return 1; |
775 | 775 | ||
776 | if (sec_level == BT_SECURITY_LOW) | 776 | if (sec_level == BT_SECURITY_LOW) |
@@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
851 | __u8 reason; | 851 | __u8 reason; |
852 | int err = 0; | 852 | int err = 0; |
853 | 853 | ||
854 | if (!lmp_host_le_capable(conn->hcon->hdev)) { | 854 | if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { |
855 | err = -ENOTSUPP; | 855 | err = -ENOTSUPP; |
856 | reason = SMP_PAIRING_NOTSUPP; | 856 | reason = SMP_PAIRING_NOTSUPP; |
857 | goto done; | 857 | goto done; |