diff options
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; |
