Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/ath/ath9k/Kconfig net/mac80211/iface.c
This commit is contained in:
commit
861bca265e
58 changed files with 603 additions and 309 deletions
|
@ -84,6 +84,8 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = {
|
||||||
{ BCMA_CORE_I2S, "I2S" },
|
{ BCMA_CORE_I2S, "I2S" },
|
||||||
{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
|
{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
|
||||||
{ BCMA_CORE_SHIM, "SHIM" },
|
{ BCMA_CORE_SHIM, "SHIM" },
|
||||||
|
{ BCMA_CORE_PCIE2, "PCIe Gen2" },
|
||||||
|
{ BCMA_CORE_ARM_CR4, "ARM CR4" },
|
||||||
{ BCMA_CORE_DEFAULT, "Default" },
|
{ BCMA_CORE_DEFAULT, "Default" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ config BT_MRVL
|
||||||
The core driver to support Marvell Bluetooth devices.
|
The core driver to support Marvell Bluetooth devices.
|
||||||
|
|
||||||
This driver is required if you want to support
|
This driver is required if you want to support
|
||||||
Marvell Bluetooth devices, such as 8688/8787/8797.
|
Marvell Bluetooth devices, such as 8688/8787/8797/8897.
|
||||||
|
|
||||||
Say Y here to compile Marvell Bluetooth driver
|
Say Y here to compile Marvell Bluetooth driver
|
||||||
into the kernel or say M to compile it as module.
|
into the kernel or say M to compile it as module.
|
||||||
|
@ -214,7 +214,7 @@ config BT_MRVL_SDIO
|
||||||
The driver for Marvell Bluetooth chipsets with SDIO interface.
|
The driver for Marvell Bluetooth chipsets with SDIO interface.
|
||||||
|
|
||||||
This driver is required if you want to use Marvell Bluetooth
|
This driver is required if you want to use Marvell Bluetooth
|
||||||
devices with SDIO interface. Currently SD8688/SD8787/SD8797
|
devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897
|
||||||
chipsets are supported.
|
chipsets are supported.
|
||||||
|
|
||||||
Say Y here to compile support for Marvell BT-over-SDIO driver
|
Say Y here to compile support for Marvell BT-over-SDIO driver
|
||||||
|
|
|
@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
|
||||||
.io_port_2 = 0x7a,
|
.io_port_2 = 0x7a,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
|
||||||
|
.cfg = 0x00,
|
||||||
|
.host_int_mask = 0x02,
|
||||||
|
.host_intstatus = 0x03,
|
||||||
|
.card_status = 0x50,
|
||||||
|
.sq_read_base_addr_a0 = 0x60,
|
||||||
|
.sq_read_base_addr_a1 = 0x61,
|
||||||
|
.card_revision = 0xbc,
|
||||||
|
.card_fw_status0 = 0xc0,
|
||||||
|
.card_fw_status1 = 0xc1,
|
||||||
|
.card_rx_len = 0xc2,
|
||||||
|
.card_rx_unit = 0xc3,
|
||||||
|
.io_port_0 = 0xd8,
|
||||||
|
.io_port_1 = 0xd9,
|
||||||
|
.io_port_2 = 0xda,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
|
||||||
.helper = "mrvl/sd8688_helper.bin",
|
.helper = "mrvl/sd8688_helper.bin",
|
||||||
.firmware = "mrvl/sd8688.bin",
|
.firmware = "mrvl/sd8688.bin",
|
||||||
|
@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
|
||||||
.sd_blksz_fw_dl = 256,
|
.sd_blksz_fw_dl = 256,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
|
||||||
|
.helper = NULL,
|
||||||
|
.firmware = "mrvl/sd8897_uapsta.bin",
|
||||||
|
.reg = &btmrvl_reg_88xx,
|
||||||
|
.sd_blksz_fw_dl = 256,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct sdio_device_id btmrvl_sdio_ids[] = {
|
static const struct sdio_device_id btmrvl_sdio_ids[] = {
|
||||||
/* Marvell SD8688 Bluetooth device */
|
/* Marvell SD8688 Bluetooth device */
|
||||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
|
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
|
||||||
|
@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
|
||||||
/* Marvell SD8797 Bluetooth device */
|
/* Marvell SD8797 Bluetooth device */
|
||||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
|
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
|
||||||
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
|
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
|
||||||
|
/* Marvell SD8897 Bluetooth device */
|
||||||
|
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
|
||||||
|
.driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
|
||||||
|
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8688.bin");
|
MODULE_FIRMWARE("mrvl/sd8688.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
|
||||||
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
|
||||||
|
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
|
||||||
|
|
|
@ -17,7 +17,7 @@ config ATH9K_BTCOEX_SUPPORT
|
||||||
|
|
||||||
config ATH9K
|
config ATH9K
|
||||||
tristate "Atheros 802.11n wireless cards support"
|
tristate "Atheros 802.11n wireless cards support"
|
||||||
depends on MAC80211
|
depends on MAC80211 && HAS_DMA
|
||||||
select ATH9K_HW
|
select ATH9K_HW
|
||||||
select MAC80211_LEDS
|
select MAC80211_LEDS
|
||||||
select LEDS_CLASS
|
select LEDS_CLASS
|
||||||
|
@ -84,13 +84,17 @@ config ATH9K_DFS_CERTIFIED
|
||||||
developed. At this point enabling this option won't do anything
|
developed. At this point enabling this option won't do anything
|
||||||
except increase code size.
|
except increase code size.
|
||||||
|
|
||||||
config ATH9K_RATE_CONTROL
|
config ATH9K_LEGACY_RATE_CONTROL
|
||||||
bool "Atheros ath9k rate control"
|
bool "Atheros ath9k rate control"
|
||||||
depends on ATH9K
|
depends on ATH9K
|
||||||
default y
|
default n
|
||||||
---help---
|
---help---
|
||||||
Say Y, if you want to use the ath9k specific rate control
|
Say Y, if you want to use the ath9k specific rate control
|
||||||
module instead of minstrel_ht.
|
module instead of minstrel_ht. Be warned that there are various
|
||||||
|
issues with the ath9k RC and minstrel is a more robust algorithm.
|
||||||
|
Note that even if this option is selected, "ath9k_rate_control"
|
||||||
|
has to be passed to mac80211 using the module parameter,
|
||||||
|
ieee80211_default_rc_algo.
|
||||||
|
|
||||||
config ATH9K_HTC
|
config ATH9K_HTC
|
||||||
tristate "Atheros HTC based wireless cards support"
|
tristate "Atheros HTC based wireless cards support"
|
||||||
|
|
|
@ -8,7 +8,7 @@ ath9k-y += beacon.o \
|
||||||
antenna.o
|
antenna.o
|
||||||
|
|
||||||
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
|
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
|
||||||
ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
|
ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
|
||||||
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
|
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
|
||||||
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
|
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
|
||||||
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||||
|
|
|
@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
|
||||||
{0x0000a074, 0x00000000},
|
{0x0000a074, 0x00000000},
|
||||||
{0x0000a078, 0x00000000},
|
{0x0000a078, 0x00000000},
|
||||||
{0x0000a07c, 0x00000000},
|
{0x0000a07c, 0x00000000},
|
||||||
{0x0000a080, 0x1a1a1a1a},
|
{0x0000a080, 0x22222229},
|
||||||
{0x0000a084, 0x1a1a1a1a},
|
{0x0000a084, 0x1d1d1d1d},
|
||||||
{0x0000a088, 0x1a1a1a1a},
|
{0x0000a088, 0x1d1d1d1d},
|
||||||
{0x0000a08c, 0x1a1a1a1a},
|
{0x0000a08c, 0x1d1d1d1d},
|
||||||
{0x0000a090, 0x171a1a1a},
|
{0x0000a090, 0x171d1d1d},
|
||||||
{0x0000a094, 0x11111717},
|
{0x0000a094, 0x11111717},
|
||||||
{0x0000a098, 0x00030311},
|
{0x0000a098, 0x00030311},
|
||||||
{0x0000a09c, 0x00000000},
|
{0x0000a09c, 0x00000000},
|
||||||
|
|
|
@ -965,7 +965,7 @@ static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah))
|
if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||||
|
|
|
@ -68,13 +68,16 @@
|
||||||
#define AR9300_BASE_ADDR 0x3ff
|
#define AR9300_BASE_ADDR 0x3ff
|
||||||
#define AR9300_BASE_ADDR_512 0x1ff
|
#define AR9300_BASE_ADDR_512 0x1ff
|
||||||
|
|
||||||
#define AR9300_OTP_BASE (AR_SREV_9340(ah) ? 0x30000 : 0x14000)
|
#define AR9300_OTP_BASE \
|
||||||
#define AR9300_OTP_STATUS (AR_SREV_9340(ah) ? 0x30018 : 0x15f18)
|
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
|
||||||
|
#define AR9300_OTP_STATUS \
|
||||||
|
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
|
||||||
#define AR9300_OTP_STATUS_TYPE 0x7
|
#define AR9300_OTP_STATUS_TYPE 0x7
|
||||||
#define AR9300_OTP_STATUS_VALID 0x4
|
#define AR9300_OTP_STATUS_VALID 0x4
|
||||||
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
|
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
|
||||||
#define AR9300_OTP_STATUS_SM_BUSY 0x1
|
#define AR9300_OTP_STATUS_SM_BUSY 0x1
|
||||||
#define AR9300_OTP_READ_DATA (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c)
|
#define AR9300_OTP_READ_DATA \
|
||||||
|
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
|
||||||
|
|
||||||
enum targetPowerHTRates {
|
enum targetPowerHTRates {
|
||||||
HT_TARGET_RATE_0_8_16,
|
HT_TARGET_RATE_0_8_16,
|
||||||
|
|
|
@ -334,7 +334,8 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
|
||||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||||
AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
|
AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
|
||||||
|
|
||||||
if (REG_READ_FIELD(ah, AR_PHY_MODE,
|
if (!AR_SREV_9340(ah) &&
|
||||||
|
REG_READ_FIELD(ah, AR_PHY_MODE,
|
||||||
AR_PHY_MODE_DYNAMIC) == 0x1)
|
AR_PHY_MODE_DYNAMIC) == 0x1)
|
||||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||||
AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
|
AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
|
||||||
|
|
|
@ -1020,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = {
|
||||||
{0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
|
{0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
|
||||||
{0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
{0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||||
{0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
{0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||||
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
|
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
|
||||||
{0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
|
{0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
|
||||||
{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
|
{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
|
||||||
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||||
|
|
|
@ -251,9 +251,9 @@ struct ath_atx_tid {
|
||||||
int tidno;
|
int tidno;
|
||||||
int baw_head; /* first un-acked tx buffer */
|
int baw_head; /* first un-acked tx buffer */
|
||||||
int baw_tail; /* next unused tx buffer slot */
|
int baw_tail; /* next unused tx buffer slot */
|
||||||
int sched;
|
bool sched;
|
||||||
int paused;
|
bool paused;
|
||||||
u8 state;
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ath_node {
|
struct ath_node {
|
||||||
|
@ -274,10 +274,6 @@ struct ath_node {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AGGR_CLEANUP BIT(1)
|
|
||||||
#define AGGR_ADDBA_COMPLETE BIT(2)
|
|
||||||
#define AGGR_ADDBA_PROGRESS BIT(3)
|
|
||||||
|
|
||||||
struct ath_tx_control {
|
struct ath_tx_control {
|
||||||
struct ath_txq *txq;
|
struct ath_txq *txq;
|
||||||
struct ath_node *an;
|
struct ath_node *an;
|
||||||
|
|
|
@ -1723,6 +1723,14 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,
|
||||||
WARN_ON(i != ATH9K_SSTATS_LEN);
|
WARN_ON(i != ATH9K_SSTATS_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ath9k_deinit_debug(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
|
||||||
|
relay_close(sc->rfs_chan_spec_scan);
|
||||||
|
sc->rfs_chan_spec_scan = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ath9k_init_debug(struct ath_hw *ah)
|
int ath9k_init_debug(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
|
|
|
@ -258,6 +258,7 @@ struct ath9k_debug {
|
||||||
};
|
};
|
||||||
|
|
||||||
int ath9k_init_debug(struct ath_hw *ah);
|
int ath9k_init_debug(struct ath_hw *ah);
|
||||||
|
void ath9k_deinit_debug(struct ath_softc *sc);
|
||||||
|
|
||||||
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
|
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
|
||||||
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||||
|
@ -293,6 +294,10 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ath9k_deinit_debug(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
|
static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
|
||||||
enum ath9k_int status)
|
enum ath9k_int status)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1170,6 +1170,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
|
||||||
static inline void ath9k_hw_set_dma(struct ath_hw *ah)
|
static inline void ath9k_hw_set_dma(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
|
int txbuf_size;
|
||||||
|
|
||||||
ENABLE_REGWRITE_BUFFER(ah);
|
ENABLE_REGWRITE_BUFFER(ah);
|
||||||
|
|
||||||
|
@ -1223,13 +1224,17 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
|
||||||
* So set the usable tx buf size also to half to
|
* So set the usable tx buf size also to half to
|
||||||
* avoid data/delimiter underruns
|
* avoid data/delimiter underruns
|
||||||
*/
|
*/
|
||||||
REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
|
txbuf_size = AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE;
|
||||||
AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
|
} else if (AR_SREV_9340_13_OR_LATER(ah)) {
|
||||||
} else if (!AR_SREV_9271(ah)) {
|
/* Uses fewer entries for AR934x v1.3+ to prevent rx overruns */
|
||||||
REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
|
txbuf_size = AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE;
|
||||||
AR_PCU_TXBUF_CTRL_USABLE_SIZE);
|
} else {
|
||||||
|
txbuf_size = AR_PCU_TXBUF_CTRL_USABLE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!AR_SREV_9271(ah))
|
||||||
|
REG_WRITE(ah, AR_PCU_TXBUF_CTRL, txbuf_size);
|
||||||
|
|
||||||
REGWRITE_BUFFER_FLUSH(ah);
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
|
|
||||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||||
|
@ -1304,9 +1309,13 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
||||||
AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
|
AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
|
||||||
} else {
|
} else {
|
||||||
tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
|
tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
|
||||||
if (tmpReg &
|
if (AR_SREV_9340(ah))
|
||||||
(AR_INTR_SYNC_LOCAL_TIMEOUT |
|
tmpReg &= AR9340_INTR_SYNC_LOCAL_TIMEOUT;
|
||||||
AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
|
else
|
||||||
|
tmpReg &= AR_INTR_SYNC_LOCAL_TIMEOUT |
|
||||||
|
AR_INTR_SYNC_RADM_CPL_TIMEOUT;
|
||||||
|
|
||||||
|
if (tmpReg) {
|
||||||
u32 val;
|
u32 val;
|
||||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
|
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
|
||||||
|
|
||||||
|
|
|
@ -792,7 +792,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||||
hw->wiphy->iface_combinations = if_comb;
|
hw->wiphy->iface_combinations = if_comb;
|
||||||
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
||||||
|
|
||||||
if (AR_SREV_5416(sc->sc_ah))
|
|
||||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||||
|
@ -831,10 +830,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||||
sc->ant_rx = hw->wiphy->available_antennas_rx;
|
sc->ant_rx = hw->wiphy->available_antennas_rx;
|
||||||
sc->ant_tx = hw->wiphy->available_antennas_tx;
|
sc->ant_tx = hw->wiphy->available_antennas_tx;
|
||||||
|
|
||||||
#ifdef CONFIG_ATH9K_RATE_CONTROL
|
|
||||||
hw->rate_control_algorithm = "ath9k_rate_control";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
||||||
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
|
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
|
||||||
&sc->sbands[IEEE80211_BAND_2GHZ];
|
&sc->sbands[IEEE80211_BAND_2GHZ];
|
||||||
|
@ -907,7 +902,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||||
if (!ath_is_world_regd(reg)) {
|
if (!ath_is_world_regd(reg)) {
|
||||||
error = regulatory_hint(hw->wiphy, reg->alpha2);
|
error = regulatory_hint(hw->wiphy, reg->alpha2);
|
||||||
if (error)
|
if (error)
|
||||||
goto unregister;
|
goto debug_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ath_init_leds(sc);
|
ath_init_leds(sc);
|
||||||
|
@ -915,6 +910,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
debug_cleanup:
|
||||||
|
ath9k_deinit_debug(sc);
|
||||||
unregister:
|
unregister:
|
||||||
ieee80211_unregister_hw(hw);
|
ieee80211_unregister_hw(hw);
|
||||||
rx_cleanup:
|
rx_cleanup:
|
||||||
|
@ -943,11 +940,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
|
||||||
sc->dfs_detector->exit(sc->dfs_detector);
|
sc->dfs_detector->exit(sc->dfs_detector);
|
||||||
|
|
||||||
ath9k_eeprom_release(sc);
|
ath9k_eeprom_release(sc);
|
||||||
|
|
||||||
if (config_enabled(CONFIG_ATH9K_DEBUGFS) && sc->rfs_chan_spec_scan) {
|
|
||||||
relay_close(sc->rfs_chan_spec_scan);
|
|
||||||
sc->rfs_chan_spec_scan = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath9k_deinit_device(struct ath_softc *sc)
|
void ath9k_deinit_device(struct ath_softc *sc)
|
||||||
|
@ -961,6 +953,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
|
||||||
|
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
|
|
||||||
|
ath9k_deinit_debug(sc);
|
||||||
ieee80211_unregister_hw(hw);
|
ieee80211_unregister_hw(hw);
|
||||||
ath_rx_cleanup(sc);
|
ath_rx_cleanup(sc);
|
||||||
ath9k_deinit_softc(sc);
|
ath9k_deinit_softc(sc);
|
||||||
|
|
|
@ -410,7 +410,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||||
|
|
||||||
REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
|
REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
|
||||||
|
|
||||||
if (AR_SREV_9340(ah))
|
if (AR_SREV_9340(ah) && !AR_SREV_9340_13_OR_LATER(ah))
|
||||||
REG_WRITE(ah, AR_DMISC(q),
|
REG_WRITE(ah, AR_DMISC(q),
|
||||||
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
|
AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1686,6 +1686,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
||||||
u16 tid, u16 *ssn, u8 buf_size)
|
u16 tid, u16 *ssn, u8 buf_size)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = hw->priv;
|
struct ath_softc *sc = hw->priv;
|
||||||
|
bool flush = false;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&sc->mutex);
|
mutex_lock(&sc->mutex);
|
||||||
|
@ -1702,11 +1703,13 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
||||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
|
||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||||
|
flush = true;
|
||||||
|
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||||
ath9k_ps_wakeup(sc);
|
ath9k_ps_wakeup(sc);
|
||||||
ath_tx_aggr_stop(sc, sta, tid);
|
ath_tx_aggr_stop(sc, sta, tid);
|
||||||
|
if (!flush)
|
||||||
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1227,10 +1227,7 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
txtid = ATH_AN_2_TID(an, tidno);
|
txtid = ATH_AN_2_TID(an, tidno);
|
||||||
|
return !txtid->active;
|
||||||
if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ATH9K_RATE_CONTROL
|
#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
|
||||||
int ath_rate_control_register(void);
|
int ath_rate_control_register(void);
|
||||||
void ath_rate_control_unregister(void);
|
void ath_rate_control_unregister(void);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -798,6 +798,10 @@
|
||||||
#define AR_SREV_REVISION_9485_10 0
|
#define AR_SREV_REVISION_9485_10 0
|
||||||
#define AR_SREV_REVISION_9485_11 1
|
#define AR_SREV_REVISION_9485_11 1
|
||||||
#define AR_SREV_VERSION_9340 0x300
|
#define AR_SREV_VERSION_9340 0x300
|
||||||
|
#define AR_SREV_REVISION_9340_10 0
|
||||||
|
#define AR_SREV_REVISION_9340_11 1
|
||||||
|
#define AR_SREV_REVISION_9340_12 2
|
||||||
|
#define AR_SREV_REVISION_9340_13 3
|
||||||
#define AR_SREV_VERSION_9580 0x1C0
|
#define AR_SREV_VERSION_9580 0x1C0
|
||||||
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
|
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
|
||||||
#define AR_SREV_VERSION_9462 0x280
|
#define AR_SREV_VERSION_9462 0x280
|
||||||
|
@ -897,6 +901,10 @@
|
||||||
#define AR_SREV_9340(_ah) \
|
#define AR_SREV_9340(_ah) \
|
||||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
|
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
|
||||||
|
|
||||||
|
#define AR_SREV_9340_13_OR_LATER(_ah) \
|
||||||
|
(AR_SREV_9340((_ah)) && \
|
||||||
|
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13))
|
||||||
|
|
||||||
#define AR_SREV_9285E_20(_ah) \
|
#define AR_SREV_9285E_20(_ah) \
|
||||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||||
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
|
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
|
||||||
|
@ -1007,6 +1015,8 @@ enum {
|
||||||
AR_INTR_SYNC_LOCAL_TIMEOUT |
|
AR_INTR_SYNC_LOCAL_TIMEOUT |
|
||||||
AR_INTR_SYNC_MAC_SLEEP_ACCESS),
|
AR_INTR_SYNC_MAC_SLEEP_ACCESS),
|
||||||
|
|
||||||
|
AR9340_INTR_SYNC_LOCAL_TIMEOUT = 0x00000010,
|
||||||
|
|
||||||
AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
|
AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1881,6 +1891,7 @@ enum {
|
||||||
#define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF
|
#define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF
|
||||||
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
|
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
|
||||||
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
|
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
|
||||||
|
#define AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE 0x500
|
||||||
|
|
||||||
#define AR_PCU_MISC_MODE2 0x8344
|
#define AR_PCU_MISC_MODE2 0x8344
|
||||||
#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
|
#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
|
||||||
|
|
|
@ -125,24 +125,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
|
||||||
list_add_tail(&ac->list, &txq->axq_acq);
|
list_add_tail(&ac->list, &txq->axq_acq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
|
||||||
{
|
|
||||||
struct ath_txq *txq = tid->ac->txq;
|
|
||||||
|
|
||||||
WARN_ON(!tid->paused);
|
|
||||||
|
|
||||||
ath_txq_lock(sc, txq);
|
|
||||||
tid->paused = false;
|
|
||||||
|
|
||||||
if (skb_queue_empty(&tid->buf_q))
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
ath_tx_queue_tid(txq, tid);
|
|
||||||
ath_txq_schedule(sc, txq);
|
|
||||||
unlock:
|
|
||||||
ath_txq_unlock_complete(sc, txq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
|
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||||
|
@ -201,11 +183,6 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tid->baw_head == tid->baw_tail) {
|
|
||||||
tid->state &= ~AGGR_ADDBA_COMPLETE;
|
|
||||||
tid->state &= ~AGGR_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sendbar) {
|
if (sendbar) {
|
||||||
ath_txq_unlock(sc, txq);
|
ath_txq_unlock(sc, txq);
|
||||||
ath_send_bar(tid, tid->seq_start);
|
ath_send_bar(tid, tid->seq_start);
|
||||||
|
@ -277,9 +254,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
|
|
||||||
list_add_tail(&bf->list, &bf_head);
|
list_add_tail(&bf->list, &bf_head);
|
||||||
|
|
||||||
if (fi->retries)
|
|
||||||
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
|
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
|
||||||
|
|
||||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,19 +466,19 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
tx_info = IEEE80211_SKB_CB(skb);
|
tx_info = IEEE80211_SKB_CB(skb);
|
||||||
fi = get_frame_info(skb);
|
fi = get_frame_info(skb);
|
||||||
|
|
||||||
if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
|
if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
|
||||||
|
/*
|
||||||
|
* Outside of the current BlockAck window,
|
||||||
|
* maybe part of a previous session
|
||||||
|
*/
|
||||||
|
txfail = 1;
|
||||||
|
} else if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
|
||||||
/* transmit completion, subframe is
|
/* transmit completion, subframe is
|
||||||
* acked by block ack */
|
* acked by block ack */
|
||||||
acked_cnt++;
|
acked_cnt++;
|
||||||
} else if (!isaggr && txok) {
|
} else if (!isaggr && txok) {
|
||||||
/* transmit completion */
|
/* transmit completion */
|
||||||
acked_cnt++;
|
acked_cnt++;
|
||||||
} else if (tid->state & AGGR_CLEANUP) {
|
|
||||||
/*
|
|
||||||
* cleanup in progress, just fail
|
|
||||||
* the un-acked sub-frames
|
|
||||||
*/
|
|
||||||
txfail = 1;
|
|
||||||
} else if (flush) {
|
} else if (flush) {
|
||||||
txpending = 1;
|
txpending = 1;
|
||||||
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
|
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
|
||||||
|
@ -527,7 +502,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
if (bf_next != NULL || !bf_last->bf_stale)
|
if (bf_next != NULL || !bf_last->bf_stale)
|
||||||
list_move_tail(&bf->list, &bf_head);
|
list_move_tail(&bf->list, &bf_head);
|
||||||
|
|
||||||
if (!txpending || (tid->state & AGGR_CLEANUP)) {
|
if (!txpending) {
|
||||||
/*
|
/*
|
||||||
* complete the acked-ones/xretried ones; update
|
* complete the acked-ones/xretried ones; update
|
||||||
* block-ack window
|
* block-ack window
|
||||||
|
@ -601,9 +576,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
ath_txq_lock(sc, txq);
|
ath_txq_lock(sc, txq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tid->state & AGGR_CLEANUP)
|
|
||||||
ath_tx_flush_tid(sc, tid);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (needreset)
|
if (needreset)
|
||||||
|
@ -620,6 +592,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
struct ath_tx_status *ts, struct ath_buf *bf,
|
struct ath_tx_status *ts, struct ath_buf *bf,
|
||||||
struct list_head *bf_head)
|
struct list_head *bf_head)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_tx_info *info;
|
||||||
bool txok, flush;
|
bool txok, flush;
|
||||||
|
|
||||||
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
|
txok = !(ts->ts_status & ATH9K_TXERR_MASK);
|
||||||
|
@ -631,8 +604,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
txq->axq_ampdu_depth--;
|
txq->axq_ampdu_depth--;
|
||||||
|
|
||||||
if (!bf_isampdu(bf)) {
|
if (!bf_isampdu(bf)) {
|
||||||
if (!flush)
|
if (!flush) {
|
||||||
|
info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||||
|
memcpy(info->control.rates, bf->rates,
|
||||||
|
sizeof(info->control.rates));
|
||||||
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
|
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
|
||||||
|
}
|
||||||
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
|
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
|
||||||
} else
|
} else
|
||||||
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
|
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok);
|
||||||
|
@ -676,7 +653,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
|
||||||
|
|
||||||
skb = bf->bf_mpdu;
|
skb = bf->bf_mpdu;
|
||||||
tx_info = IEEE80211_SKB_CB(skb);
|
tx_info = IEEE80211_SKB_CB(skb);
|
||||||
rates = tx_info->control.rates;
|
rates = bf->rates;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the lowest frame length among the rate series that will have a
|
* Find the lowest frame length among the rate series that will have a
|
||||||
|
@ -1231,9 +1208,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||||
an = (struct ath_node *)sta->drv_priv;
|
an = (struct ath_node *)sta->drv_priv;
|
||||||
txtid = ATH_AN_2_TID(an, tid);
|
txtid = ATH_AN_2_TID(an, tid);
|
||||||
|
|
||||||
if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
|
|
||||||
return -EAGAIN;
|
|
||||||
|
|
||||||
/* update ampdu factor/density, they may have changed. This may happen
|
/* update ampdu factor/density, they may have changed. This may happen
|
||||||
* in HT IBSS when a beacon with HT-info is received after the station
|
* in HT IBSS when a beacon with HT-info is received after the station
|
||||||
* has already been added.
|
* has already been added.
|
||||||
|
@ -1245,7 +1219,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||||
an->mpdudensity = density;
|
an->mpdudensity = density;
|
||||||
}
|
}
|
||||||
|
|
||||||
txtid->state |= AGGR_ADDBA_PROGRESS;
|
txtid->active = true;
|
||||||
txtid->paused = true;
|
txtid->paused = true;
|
||||||
*ssn = txtid->seq_start = txtid->seq_next;
|
*ssn = txtid->seq_start = txtid->seq_next;
|
||||||
txtid->bar_index = -1;
|
txtid->bar_index = -1;
|
||||||
|
@ -1262,28 +1236,9 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
|
||||||
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
|
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
|
||||||
struct ath_txq *txq = txtid->ac->txq;
|
struct ath_txq *txq = txtid->ac->txq;
|
||||||
|
|
||||||
if (txtid->state & AGGR_CLEANUP)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
|
|
||||||
txtid->state &= ~AGGR_ADDBA_PROGRESS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ath_txq_lock(sc, txq);
|
ath_txq_lock(sc, txq);
|
||||||
|
txtid->active = false;
|
||||||
txtid->paused = true;
|
txtid->paused = true;
|
||||||
|
|
||||||
/*
|
|
||||||
* If frames are still being transmitted for this TID, they will be
|
|
||||||
* cleaned up during tx completion. To prevent race conditions, this
|
|
||||||
* TID can only be reused after all in-progress subframes have been
|
|
||||||
* completed.
|
|
||||||
*/
|
|
||||||
if (txtid->baw_head != txtid->baw_tail)
|
|
||||||
txtid->state |= AGGR_CLEANUP;
|
|
||||||
else
|
|
||||||
txtid->state &= ~AGGR_ADDBA_COMPLETE;
|
|
||||||
|
|
||||||
ath_tx_flush_tid(sc, txtid);
|
ath_tx_flush_tid(sc, txtid);
|
||||||
ath_txq_unlock_complete(sc, txq);
|
ath_txq_unlock_complete(sc, txq);
|
||||||
}
|
}
|
||||||
|
@ -1349,18 +1304,28 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
|
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||||
|
u16 tidno)
|
||||||
{
|
{
|
||||||
struct ath_atx_tid *txtid;
|
struct ath_atx_tid *tid;
|
||||||
struct ath_node *an;
|
struct ath_node *an;
|
||||||
|
struct ath_txq *txq;
|
||||||
|
|
||||||
an = (struct ath_node *)sta->drv_priv;
|
an = (struct ath_node *)sta->drv_priv;
|
||||||
|
tid = ATH_AN_2_TID(an, tidno);
|
||||||
|
txq = tid->ac->txq;
|
||||||
|
|
||||||
txtid = ATH_AN_2_TID(an, tid);
|
ath_txq_lock(sc, txq);
|
||||||
txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
|
||||||
txtid->state |= AGGR_ADDBA_COMPLETE;
|
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
||||||
txtid->state &= ~AGGR_ADDBA_PROGRESS;
|
tid->paused = false;
|
||||||
ath_tx_resume_tid(sc, txtid);
|
|
||||||
|
if (!skb_queue_empty(&tid->buf_q)) {
|
||||||
|
ath_tx_queue_tid(txq, tid);
|
||||||
|
ath_txq_schedule(sc, txq);
|
||||||
|
}
|
||||||
|
|
||||||
|
ath_txq_unlock_complete(sc, txq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************/
|
/********************/
|
||||||
|
@ -2409,12 +2374,10 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||||
tid->baw_head = tid->baw_tail = 0;
|
tid->baw_head = tid->baw_tail = 0;
|
||||||
tid->sched = false;
|
tid->sched = false;
|
||||||
tid->paused = false;
|
tid->paused = false;
|
||||||
tid->state &= ~AGGR_CLEANUP;
|
tid->active = false;
|
||||||
__skb_queue_head_init(&tid->buf_q);
|
__skb_queue_head_init(&tid->buf_q);
|
||||||
acno = TID_TO_WME_AC(tidno);
|
acno = TID_TO_WME_AC(tidno);
|
||||||
tid->ac = &an->ac[acno];
|
tid->ac = &an->ac[acno];
|
||||||
tid->state &= ~AGGR_ADDBA_COMPLETE;
|
|
||||||
tid->state &= ~AGGR_ADDBA_PROGRESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (acno = 0, ac = &an->ac[acno];
|
for (acno = 0, ac = &an->ac[acno];
|
||||||
|
@ -2451,8 +2414,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
|
||||||
}
|
}
|
||||||
|
|
||||||
ath_tid_drain(sc, txq, tid);
|
ath_tid_drain(sc, txq, tid);
|
||||||
tid->state &= ~AGGR_ADDBA_COMPLETE;
|
tid->active = false;
|
||||||
tid->state &= ~AGGR_CLEANUP;
|
|
||||||
|
|
||||||
ath_txq_unlock(sc, txq);
|
ath_txq_unlock(sc, txq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1624,7 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
|
||||||
|
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
|
|
||||||
if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv));
|
if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
|
||||||
printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
|
printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
|
||||||
|
|
||||||
printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
|
printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
|
||||||
|
|
|
@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work)
|
||||||
for (i = 0; i < B43_NR_FWTYPES; i++) {
|
for (i = 0; i < B43_NR_FWTYPES; i++) {
|
||||||
errmsg = ctx->errors[i];
|
errmsg = ctx->errors[i];
|
||||||
if (strlen(errmsg))
|
if (strlen(errmsg))
|
||||||
b43err(dev->wl, errmsg);
|
b43err(dev->wl, "%s", errmsg);
|
||||||
}
|
}
|
||||||
b43_print_fw_helptext(dev->wl, 1);
|
b43_print_fw_helptext(dev->wl, 1);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "tracepoint.h"
|
#include "tracepoint.h"
|
||||||
|
|
||||||
#define PKTFILTER_BUF_SIZE 128
|
#define PKTFILTER_BUF_SIZE 128
|
||||||
#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
|
|
||||||
#define BRCMF_DEFAULT_BCN_TIMEOUT 3
|
#define BRCMF_DEFAULT_BCN_TIMEOUT 3
|
||||||
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
||||||
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
|
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
|
||||||
|
@ -338,23 +337,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to set and enable ARP offload feature, this may fail */
|
|
||||||
err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
|
|
||||||
if (err) {
|
|
||||||
brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
|
|
||||||
BRCMF_ARPOL_MODE, err);
|
|
||||||
err = 0;
|
|
||||||
} else {
|
|
||||||
err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
|
|
||||||
if (err) {
|
|
||||||
brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
|
|
||||||
err);
|
|
||||||
err = 0;
|
|
||||||
} else
|
|
||||||
brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
|
|
||||||
BRCMF_ARPOL_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup packet filter */
|
/* Setup packet filter */
|
||||||
brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
|
brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
|
||||||
brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
|
brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
|
||||||
|
|
|
@ -653,10 +653,13 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
|
||||||
|
|
||||||
brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
|
brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
|
||||||
|
|
||||||
|
ndev->destructor = free_netdev;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
drvr->iflist[ifp->bssidx] = NULL;
|
||||||
ndev->netdev_ops = NULL;
|
ndev->netdev_ops = NULL;
|
||||||
|
free_netdev(ndev);
|
||||||
return -EBADE;
|
return -EBADE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,6 +723,9 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
ifp->drvr->iflist[ifp->bssidx] = NULL;
|
||||||
|
ndev->netdev_ops = NULL;
|
||||||
|
free_netdev(ndev);
|
||||||
return -EBADE;
|
return -EBADE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
|
||||||
struct brcmf_if *ifp;
|
struct brcmf_if *ifp;
|
||||||
|
|
||||||
ifp = drvr->iflist[bssidx];
|
ifp = drvr->iflist[bssidx];
|
||||||
|
drvr->iflist[bssidx] = NULL;
|
||||||
if (!ifp) {
|
if (!ifp) {
|
||||||
brcmf_err("Null interface, idx=%d\n", bssidx);
|
brcmf_err("Null interface, idx=%d\n", bssidx);
|
||||||
return;
|
return;
|
||||||
|
@ -808,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
|
||||||
cancel_work_sync(&ifp->setmacaddr_work);
|
cancel_work_sync(&ifp->setmacaddr_work);
|
||||||
cancel_work_sync(&ifp->multicast_work);
|
cancel_work_sync(&ifp->multicast_work);
|
||||||
}
|
}
|
||||||
|
/* unregister will take care of freeing it */
|
||||||
unregister_netdev(ifp->ndev);
|
unregister_netdev(ifp->ndev);
|
||||||
if (bssidx == 0)
|
if (bssidx == 0)
|
||||||
brcmf_cfg80211_detach(drvr->config);
|
brcmf_cfg80211_detach(drvr->config);
|
||||||
free_netdev(ifp->ndev);
|
|
||||||
} else {
|
} else {
|
||||||
kfree(ifp);
|
kfree(ifp);
|
||||||
}
|
}
|
||||||
drvr->iflist[bssidx] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||||
|
@ -925,8 +930,6 @@ fail:
|
||||||
brcmf_fws_del_interface(ifp);
|
brcmf_fws_del_interface(ifp);
|
||||||
brcmf_fws_deinit(drvr);
|
brcmf_fws_deinit(drvr);
|
||||||
}
|
}
|
||||||
free_netdev(ifp->ndev);
|
|
||||||
drvr->iflist[0] = NULL;
|
|
||||||
if (p2p_ifp) {
|
if (p2p_ifp) {
|
||||||
free_netdev(p2p_ifp->ndev);
|
free_netdev(p2p_ifp->ndev);
|
||||||
drvr->iflist[1] = NULL;
|
drvr->iflist[1] = NULL;
|
||||||
|
@ -934,7 +937,8 @@ fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((brcmf_p2p_enable) && (p2p_ifp))
|
if ((brcmf_p2p_enable) && (p2p_ifp))
|
||||||
brcmf_net_p2p_attach(p2p_ifp);
|
if (brcmf_net_p2p_attach(p2p_ifp) < 0)
|
||||||
|
brcmf_p2p_enable = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
|
||||||
return;
|
return;
|
||||||
brcmf_fws_add_interface(ifp);
|
brcmf_fws_add_interface(ifp);
|
||||||
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
|
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
|
||||||
err = brcmf_net_attach(ifp, false);
|
if (brcmf_net_attach(ifp, false) < 0)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifevent->action == BRCMF_E_IF_CHANGE)
|
if (ifevent->action == BRCMF_E_IF_CHANGE)
|
||||||
|
|
|
@ -23,6 +23,12 @@
|
||||||
|
|
||||||
#define BRCMF_FIL_ACTION_FRAME_SIZE 1800
|
#define BRCMF_FIL_ACTION_FRAME_SIZE 1800
|
||||||
|
|
||||||
|
/* ARP Offload feature flags for arp_ol iovar */
|
||||||
|
#define BRCMF_ARP_OL_AGENT 0x00000001
|
||||||
|
#define BRCMF_ARP_OL_SNOOP 0x00000002
|
||||||
|
#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004
|
||||||
|
#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
|
||||||
|
|
||||||
|
|
||||||
enum brcmf_fil_p2p_if_types {
|
enum brcmf_fil_p2p_if_types {
|
||||||
BRCMF_FIL_P2P_IF_CLIENT,
|
BRCMF_FIL_P2P_IF_CLIENT,
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
|
#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
|
||||||
(channel == SOCIAL_CHAN_2) || \
|
(channel == SOCIAL_CHAN_2) || \
|
||||||
(channel == SOCIAL_CHAN_3))
|
(channel == SOCIAL_CHAN_3))
|
||||||
|
#define BRCMF_P2P_TEMP_CHAN SOCIAL_CHAN_3
|
||||||
#define SOCIAL_CHAN_CNT 3
|
#define SOCIAL_CHAN_CNT 3
|
||||||
#define AF_PEER_SEARCH_CNT 2
|
#define AF_PEER_SEARCH_CNT 2
|
||||||
|
|
||||||
|
@ -1954,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
|
||||||
err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
|
err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
brcmf_err("set p2p_disc error\n");
|
brcmf_err("set p2p_disc error\n");
|
||||||
brcmf_free_vif(p2p_vif);
|
brcmf_free_vif(cfg, p2p_vif);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
/* obtain bsscfg index for P2P discovery */
|
/* obtain bsscfg index for P2P discovery */
|
||||||
err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
|
err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
brcmf_err("retrieving discover bsscfg index failed\n");
|
brcmf_err("retrieving discover bsscfg index failed\n");
|
||||||
brcmf_free_vif(p2p_vif);
|
brcmf_free_vif(cfg, p2p_vif);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
/* Verify that firmware uses same bssidx as driver !! */
|
/* Verify that firmware uses same bssidx as driver !! */
|
||||||
if (p2p_ifp->bssidx != bssidx) {
|
if (p2p_ifp->bssidx != bssidx) {
|
||||||
brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
|
brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
|
||||||
bssidx, p2p_ifp->bssidx);
|
bssidx, p2p_ifp->bssidx);
|
||||||
brcmf_free_vif(p2p_vif);
|
brcmf_free_vif(cfg, p2p_vif);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1996,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
|
||||||
brcmf_p2p_cancel_remain_on_channel(vif->ifp);
|
brcmf_p2p_cancel_remain_on_channel(vif->ifp);
|
||||||
brcmf_p2p_deinit_discovery(p2p);
|
brcmf_p2p_deinit_discovery(p2p);
|
||||||
/* remove discovery interface */
|
/* remove discovery interface */
|
||||||
brcmf_free_vif(vif);
|
brcmf_free_vif(p2p->cfg, vif);
|
||||||
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
|
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
|
||||||
}
|
}
|
||||||
/* just set it all to zero */
|
/* just set it all to zero */
|
||||||
|
@ -2013,17 +2014,30 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p,
|
||||||
u16 *chanspec)
|
u16 *chanspec)
|
||||||
{
|
{
|
||||||
struct brcmf_if *ifp;
|
struct brcmf_if *ifp;
|
||||||
struct brcmf_fil_chan_info_le ci;
|
u8 mac_addr[ETH_ALEN];
|
||||||
struct brcmu_chan ch;
|
struct brcmu_chan ch;
|
||||||
s32 err;
|
struct brcmf_bss_info_le *bi;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
|
ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
|
||||||
|
|
||||||
ch.chnum = 11;
|
if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mac_addr,
|
||||||
|
ETH_ALEN) == 0) {
|
||||||
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci));
|
buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
|
||||||
if (!err)
|
if (buf != NULL) {
|
||||||
ch.chnum = le32_to_cpu(ci.hw_channel);
|
*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
|
||||||
|
if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
|
||||||
|
buf, WL_BSS_INFO_MAX) == 0) {
|
||||||
|
bi = (struct brcmf_bss_info_le *)(buf + 4);
|
||||||
|
*chanspec = le16_to_cpu(bi->chanspec);
|
||||||
|
kfree(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kfree(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Use default channel for P2P */
|
||||||
|
ch.chnum = BRCMF_P2P_TEMP_CHAN;
|
||||||
ch.bw = BRCMU_CHAN_BW_20;
|
ch.bw = BRCMU_CHAN_BW_20;
|
||||||
p2p->cfg->d11inf.encchspec(&ch);
|
p2p->cfg->d11inf.encchspec(&ch);
|
||||||
*chanspec = ch.chspec;
|
*chanspec = ch.chspec;
|
||||||
|
@ -2208,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
|
||||||
return &p2p_vif->wdev;
|
return &p2p_vif->wdev;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
brcmf_free_vif(p2p_vif);
|
brcmf_free_vif(p2p->cfg, p2p_vif);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2217,13 +2231,31 @@ fail:
|
||||||
*
|
*
|
||||||
* @vif: virtual interface object to delete.
|
* @vif: virtual interface object to delete.
|
||||||
*/
|
*/
|
||||||
static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif)
|
static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg,
|
||||||
|
struct brcmf_cfg80211_vif *vif)
|
||||||
{
|
{
|
||||||
struct brcmf_p2p_info *p2p = &vif->ifp->drvr->config->p2p;
|
|
||||||
|
|
||||||
cfg80211_unregister_wdev(&vif->wdev);
|
cfg80211_unregister_wdev(&vif->wdev);
|
||||||
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
|
cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
|
||||||
brcmf_free_vif(vif);
|
brcmf_free_vif(cfg, vif);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* brcmf_p2p_free_p2p_if() - free up net device related data.
|
||||||
|
*
|
||||||
|
* @ndev: net device that needs to be freed.
|
||||||
|
*/
|
||||||
|
static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
|
||||||
|
{
|
||||||
|
struct brcmf_cfg80211_info *cfg;
|
||||||
|
struct brcmf_cfg80211_vif *vif;
|
||||||
|
struct brcmf_if *ifp;
|
||||||
|
|
||||||
|
ifp = netdev_priv(ndev);
|
||||||
|
cfg = ifp->drvr->config;
|
||||||
|
vif = ifp->vif;
|
||||||
|
|
||||||
|
brcmf_free_vif(cfg, vif);
|
||||||
|
free_netdev(ifp->ndev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2303,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
|
||||||
brcmf_err("Registering netdevice failed\n");
|
brcmf_err("Registering netdevice failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
/* override destructor */
|
||||||
|
ifp->ndev->destructor = brcmf_p2p_free_p2p_if;
|
||||||
|
|
||||||
cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
|
cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
|
||||||
/* Disable firmware roaming for P2P interface */
|
/* Disable firmware roaming for P2P interface */
|
||||||
brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
|
brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
|
||||||
|
@ -2314,7 +2349,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
|
||||||
return &ifp->vif->wdev;
|
return &ifp->vif->wdev;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
brcmf_free_vif(vif);
|
brcmf_free_vif(cfg, vif);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2350,7 +2385,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NL80211_IFTYPE_P2P_DEVICE:
|
case NL80211_IFTYPE_P2P_DEVICE:
|
||||||
brcmf_p2p_delete_p2pdev(vif);
|
brcmf_p2p_delete_p2pdev(cfg, vif);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
@ -2378,7 +2413,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||||
brcmf_free_vif(vif);
|
|
||||||
p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
|
p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -459,6 +459,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s32
|
||||||
|
brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
|
||||||
|
{
|
||||||
|
s32 err;
|
||||||
|
u32 mode;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
|
||||||
|
else
|
||||||
|
mode = 0;
|
||||||
|
|
||||||
|
/* Try to set and enable ARP offload feature, this may fail, then it */
|
||||||
|
/* is simply not supported and err 0 will be returned */
|
||||||
|
err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
|
||||||
|
if (err) {
|
||||||
|
brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
|
||||||
|
mode, err);
|
||||||
|
err = 0;
|
||||||
|
} else {
|
||||||
|
err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
|
||||||
|
if (err) {
|
||||||
|
brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
|
||||||
|
enable, err);
|
||||||
|
err = 0;
|
||||||
|
} else
|
||||||
|
brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
|
||||||
|
enable, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
||||||
const char *name,
|
const char *name,
|
||||||
enum nl80211_iftype type,
|
enum nl80211_iftype type,
|
||||||
|
@ -2216,6 +2248,11 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
|
||||||
}
|
}
|
||||||
|
|
||||||
pm = enabled ? PM_FAST : PM_OFF;
|
pm = enabled ? PM_FAST : PM_OFF;
|
||||||
|
/* Do not enable the power save after assoc if it is a p2p interface */
|
||||||
|
if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
|
||||||
|
brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
|
||||||
|
pm = PM_OFF;
|
||||||
|
}
|
||||||
brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
|
brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
|
||||||
|
|
||||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
|
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
|
||||||
|
@ -3639,11 +3676,29 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s32
|
||||||
|
brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
|
||||||
|
struct brcmf_if *ifp,
|
||||||
|
struct ieee80211_channel *channel)
|
||||||
|
{
|
||||||
|
u16 chanspec;
|
||||||
|
s32 err;
|
||||||
|
|
||||||
|
brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
|
||||||
|
channel->center_freq);
|
||||||
|
|
||||||
|
chanspec = channel_to_chanspec(&cfg->d11inf, channel);
|
||||||
|
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static s32
|
static s32
|
||||||
brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||||
struct cfg80211_ap_settings *settings)
|
struct cfg80211_ap_settings *settings)
|
||||||
{
|
{
|
||||||
s32 ie_offset;
|
s32 ie_offset;
|
||||||
|
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||||
struct brcmf_tlv *ssid_ie;
|
struct brcmf_tlv *ssid_ie;
|
||||||
struct brcmf_ssid_le ssid_le;
|
struct brcmf_ssid_le ssid_le;
|
||||||
|
@ -3683,6 +3738,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||||
}
|
}
|
||||||
|
|
||||||
brcmf_set_mpc(ifp, 0);
|
brcmf_set_mpc(ifp, 0);
|
||||||
|
brcmf_configure_arp_offload(ifp, false);
|
||||||
|
|
||||||
/* find the RSN_IE */
|
/* find the RSN_IE */
|
||||||
rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
|
rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
|
||||||
|
@ -3713,6 +3769,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||||
|
|
||||||
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
|
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
|
||||||
|
|
||||||
|
err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
|
||||||
|
if (err < 0) {
|
||||||
|
brcmf_err("Set Channel failed, %d\n", err);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (settings->beacon_interval) {
|
if (settings->beacon_interval) {
|
||||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
|
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
|
||||||
settings->beacon_interval);
|
settings->beacon_interval);
|
||||||
|
@ -3789,8 +3851,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
||||||
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (err)
|
if (err) {
|
||||||
brcmf_set_mpc(ifp, 1);
|
brcmf_set_mpc(ifp, 1);
|
||||||
|
brcmf_configure_arp_offload(ifp, true);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3831,6 +3895,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
|
||||||
brcmf_err("bss_enable config failed %d\n", err);
|
brcmf_err("bss_enable config failed %d\n", err);
|
||||||
}
|
}
|
||||||
brcmf_set_mpc(ifp, 1);
|
brcmf_set_mpc(ifp, 1);
|
||||||
|
brcmf_configure_arp_offload(ifp, true);
|
||||||
set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
|
set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
|
||||||
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||||
|
|
||||||
|
@ -4140,11 +4205,15 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
|
||||||
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
BIT(NL80211_IFTYPE_P2P_GO)
|
BIT(NL80211_IFTYPE_P2P_GO)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.max = 1,
|
||||||
|
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
|
static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
|
||||||
{
|
{
|
||||||
.max_interfaces = BRCMF_IFACE_MAX_CNT,
|
.max_interfaces = BRCMF_IFACE_MAX_CNT,
|
||||||
.num_different_channels = 1, /* no multi-channel for now */
|
.num_different_channels = 2,
|
||||||
.n_limits = ARRAY_SIZE(brcmf_iface_limits),
|
.n_limits = ARRAY_SIZE(brcmf_iface_limits),
|
||||||
.limits = brcmf_iface_limits
|
.limits = brcmf_iface_limits
|
||||||
}
|
}
|
||||||
|
@ -4197,7 +4266,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
|
||||||
BIT(NL80211_IFTYPE_ADHOC) |
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
BIT(NL80211_IFTYPE_AP) |
|
BIT(NL80211_IFTYPE_AP) |
|
||||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
BIT(NL80211_IFTYPE_P2P_GO);
|
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||||
|
BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
wiphy->iface_combinations = brcmf_iface_combos;
|
wiphy->iface_combinations = brcmf_iface_combos;
|
||||||
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
|
wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
|
||||||
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
|
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
|
||||||
|
@ -4251,20 +4321,16 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||||
return vif;
|
return vif;
|
||||||
}
|
}
|
||||||
|
|
||||||
void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
|
void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
|
||||||
|
struct brcmf_cfg80211_vif *vif)
|
||||||
{
|
{
|
||||||
struct brcmf_cfg80211_info *cfg;
|
|
||||||
struct wiphy *wiphy;
|
|
||||||
|
|
||||||
wiphy = vif->wdev.wiphy;
|
|
||||||
cfg = wiphy_priv(wiphy);
|
|
||||||
list_del(&vif->list);
|
list_del(&vif->list);
|
||||||
cfg->vif_cnt--;
|
cfg->vif_cnt--;
|
||||||
|
|
||||||
kfree(vif);
|
kfree(vif);
|
||||||
if (!cfg->vif_cnt) {
|
if (!cfg->vif_cnt) {
|
||||||
wiphy_unregister(wiphy);
|
wiphy_unregister(cfg->wiphy);
|
||||||
wiphy_free(wiphy);
|
wiphy_free(cfg->wiphy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4641,7 +4707,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case BRCMF_E_IF_DEL:
|
case BRCMF_E_IF_DEL:
|
||||||
ifp->vif = NULL;
|
|
||||||
mutex_unlock(&event->vif_event_lock);
|
mutex_unlock(&event->vif_event_lock);
|
||||||
/* event may not be upon user request */
|
/* event may not be upon user request */
|
||||||
if (brcmf_cfg80211_vif_event_armed(cfg))
|
if (brcmf_cfg80211_vif_event_armed(cfg))
|
||||||
|
@ -4847,8 +4912,7 @@ cfg80211_p2p_attach_out:
|
||||||
wl_deinit_priv(cfg);
|
wl_deinit_priv(cfg);
|
||||||
|
|
||||||
cfg80211_attach_out:
|
cfg80211_attach_out:
|
||||||
brcmf_free_vif(vif);
|
brcmf_free_vif(cfg, vif);
|
||||||
wiphy_free(wiphy);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4860,7 +4924,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
|
||||||
wl_deinit_priv(cfg);
|
wl_deinit_priv(cfg);
|
||||||
brcmf_btcoex_detach(cfg);
|
brcmf_btcoex_detach(cfg);
|
||||||
list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
|
list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
|
||||||
brcmf_free_vif(vif);
|
brcmf_free_vif(cfg, vif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5224,6 +5288,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
|
||||||
if (err)
|
if (err)
|
||||||
goto default_conf_out;
|
goto default_conf_out;
|
||||||
|
|
||||||
|
brcmf_configure_arp_offload(ifp, true);
|
||||||
|
|
||||||
cfg->dongle_up = true;
|
cfg->dongle_up = true;
|
||||||
default_conf_out:
|
default_conf_out:
|
||||||
|
|
||||||
|
|
|
@ -487,7 +487,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
|
||||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||||
enum nl80211_iftype type,
|
enum nl80211_iftype type,
|
||||||
bool pm_block);
|
bool pm_block);
|
||||||
void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
|
void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
|
||||||
|
struct brcmf_cfg80211_vif *vif);
|
||||||
|
|
||||||
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
||||||
const u8 *vndr_ie_buf, u32 vndr_ie_len);
|
const u8 *vndr_ie_buf, u32 vndr_ie_len);
|
||||||
|
|
|
@ -1423,7 +1423,7 @@ il_setup_rx_scan_handlers(struct il_priv *il)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(il_setup_rx_scan_handlers);
|
EXPORT_SYMBOL(il_setup_rx_scan_handlers);
|
||||||
|
|
||||||
inline u16
|
u16
|
||||||
il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band,
|
il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band,
|
||||||
u8 n_probes)
|
u8 n_probes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
|
||||||
__le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
|
__le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
|
||||||
u32 beacon_interval);
|
u32 beacon_interval);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM_SLEEP
|
||||||
extern const struct dev_pm_ops il_pm_ops;
|
extern const struct dev_pm_ops il_pm_ops;
|
||||||
|
|
||||||
#define IL_LEGACY_PM_OPS (&il_pm_ops)
|
#define IL_LEGACY_PM_OPS (&il_pm_ops)
|
||||||
|
|
||||||
#else /* !CONFIG_PM */
|
#else /* !CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
#define IL_LEGACY_PM_OPS NULL
|
#define IL_LEGACY_PM_OPS NULL
|
||||||
|
|
||||||
#endif /* !CONFIG_PM */
|
#endif /* !CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* Error Handling Debugging
|
* Error Handling Debugging
|
||||||
|
|
|
@ -26,10 +26,17 @@
|
||||||
static struct dentry *mwifiex_dfs_dir;
|
static struct dentry *mwifiex_dfs_dir;
|
||||||
|
|
||||||
static char *bss_modes[] = {
|
static char *bss_modes[] = {
|
||||||
"Unknown",
|
"UNSPECIFIED",
|
||||||
"Ad-hoc",
|
"ADHOC",
|
||||||
"Managed",
|
"STATION",
|
||||||
"Auto"
|
"AP",
|
||||||
|
"AP_VLAN",
|
||||||
|
"WDS",
|
||||||
|
"MONITOR",
|
||||||
|
"MESH_POINT",
|
||||||
|
"P2P_CLIENT",
|
||||||
|
"P2P_GO",
|
||||||
|
"P2P_DEVICE",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* size/addr for mwifiex_debug_info */
|
/* size/addr for mwifiex_debug_info */
|
||||||
|
@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
|
||||||
p += sprintf(p, "driver_version = %s", fmt);
|
p += sprintf(p, "driver_version = %s", fmt);
|
||||||
p += sprintf(p, "\nverext = %s", priv->version_str);
|
p += sprintf(p, "\nverext = %s", priv->version_str);
|
||||||
p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
|
p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
|
||||||
|
|
||||||
|
if (info.bss_mode >= ARRAY_SIZE(bss_modes))
|
||||||
|
p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
|
||||||
|
else
|
||||||
p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
|
p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
|
||||||
|
|
||||||
p += sprintf(p, "media_state=\"%s\"\n",
|
p += sprintf(p, "media_state=\"%s\"\n",
|
||||||
(!priv->media_connected ? "Disconnected" : "Connected"));
|
(!priv->media_connected ? "Disconnected" : "Connected"));
|
||||||
p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
|
p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
|
||||||
|
|
|
@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||||
"can't alloc skb for rx\n");
|
"can't alloc skb for rx\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
kmemleak_not_leak(new_skb);
|
||||||
|
|
||||||
pci_unmap_single(rtlpci->pdev,
|
pci_unmap_single(rtlpci->pdev,
|
||||||
*((dma_addr_t *) skb->cb),
|
*((dma_addr_t *) skb->cb),
|
||||||
|
|
|
@ -550,7 +550,7 @@ do { \
|
||||||
rxmcs == DESC92C_RATE11M)
|
rxmcs == DESC92C_RATE11M)
|
||||||
|
|
||||||
struct phy_rx_agc_info_t {
|
struct phy_rx_agc_info_t {
|
||||||
#if __LITTLE_ENDIAN
|
#ifdef __LITTLE_ENDIAN
|
||||||
u8 gain:7, trsw:1;
|
u8 gain:7, trsw:1;
|
||||||
#else
|
#else
|
||||||
u8 trsw:1, gain:7;
|
u8 trsw:1, gain:7;
|
||||||
|
@ -574,7 +574,7 @@ struct phy_status_rpt {
|
||||||
u8 stream_target_csi[2];
|
u8 stream_target_csi[2];
|
||||||
u8 sig_evm;
|
u8 sig_evm;
|
||||||
u8 rsvd_3;
|
u8 rsvd_3;
|
||||||
#if __LITTLE_ENDIAN
|
#ifdef __LITTLE_ENDIAN
|
||||||
u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
|
u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
|
||||||
u8 sgi_en:1;
|
u8 sgi_en:1;
|
||||||
u8 rxsc:2;
|
u8 rxsc:2;
|
||||||
|
|
|
@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta)
|
||||||
u8 rssi_level)
|
|
||||||
{
|
{
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||||
u32 ratr_value = (u32) mac->basic_rates;
|
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||||
u8 *mcsrate = mac->mcs;
|
u32 ratr_value;
|
||||||
u8 ratr_index = 0;
|
u8 ratr_index = 0;
|
||||||
u8 nmode = mac->ht_enable;
|
u8 nmode = mac->ht_enable;
|
||||||
u8 mimo_ps = 1;
|
u8 mimo_ps = IEEE80211_SMPS_OFF;
|
||||||
u16 shortgi_rate = 0;
|
u16 shortgi_rate;
|
||||||
u32 tmp_ratr_value = 0;
|
u32 tmp_ratr_value;
|
||||||
u8 curtxbw_40mhz = mac->bw_40;
|
u8 curtxbw_40mhz = mac->bw_40;
|
||||||
u8 curshortgi_40mhz = mac->sgi_40;
|
u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||||
u8 curshortgi_20mhz = mac->sgi_20;
|
1 : 0;
|
||||||
|
u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
|
||||||
|
1 : 0;
|
||||||
enum wireless_mode wirelessmode = mac->mode;
|
enum wireless_mode wirelessmode = mac->mode;
|
||||||
|
|
||||||
ratr_value |= ((*(u16 *) (mcsrate))) << 12;
|
if (rtlhal->current_bandtype == BAND_ON_5G)
|
||||||
|
ratr_value = sta->supp_rates[1] << 4;
|
||||||
|
else
|
||||||
|
ratr_value = sta->supp_rates[0];
|
||||||
|
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||||
|
ratr_value = 0xfff;
|
||||||
|
|
||||||
|
ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
|
||||||
|
sta->ht_cap.mcs.rx_mask[0] << 12);
|
||||||
switch (wirelessmode) {
|
switch (wirelessmode) {
|
||||||
case WIRELESS_MODE_B:
|
case WIRELESS_MODE_B:
|
||||||
if (ratr_value & 0x0000000c)
|
if (ratr_value & 0x0000000c)
|
||||||
|
@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||||
case WIRELESS_MODE_N_24G:
|
case WIRELESS_MODE_N_24G:
|
||||||
case WIRELESS_MODE_N_5G:
|
case WIRELESS_MODE_N_5G:
|
||||||
nmode = 1;
|
nmode = 1;
|
||||||
if (mimo_ps == 0) {
|
if (mimo_ps == IEEE80211_SMPS_STATIC) {
|
||||||
ratr_value &= 0x0007F005;
|
ratr_value &= 0x0007F005;
|
||||||
} else {
|
} else {
|
||||||
u32 ratr_mask;
|
u32 ratr_mask;
|
||||||
|
@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||||
ratr_mask = 0x000ff005;
|
ratr_mask = 0x000ff005;
|
||||||
else
|
else
|
||||||
ratr_mask = 0x0f0ff005;
|
ratr_mask = 0x0f0ff005;
|
||||||
if (curtxbw_40mhz)
|
|
||||||
ratr_mask |= 0x00000010;
|
|
||||||
ratr_value &= ratr_mask;
|
ratr_value &= ratr_mask;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||||
ratr_value &= 0x000ff0ff;
|
ratr_value &= 0x000ff0ff;
|
||||||
else
|
else
|
||||||
ratr_value &= 0x0f0ff0ff;
|
ratr_value &= 0x0f0ff0ff;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ratr_value &= 0x0FFFFFFF;
|
ratr_value &= 0x0FFFFFFF;
|
||||||
if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
|
|
||||||
(!curtxbw_40mhz && curshortgi_20mhz))) {
|
if (nmode && ((curtxbw_40mhz &&
|
||||||
|
curshortgi_40mhz) || (!curtxbw_40mhz &&
|
||||||
|
curshortgi_20mhz))) {
|
||||||
|
|
||||||
ratr_value |= 0x10000000;
|
ratr_value |= 0x10000000;
|
||||||
tmp_ratr_value = (ratr_value >> 12);
|
tmp_ratr_value = (ratr_value >> 12);
|
||||||
|
|
||||||
for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
|
for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
|
||||||
if ((1 << shortgi_rate) & tmp_ratr_value)
|
if ((1 << shortgi_rate) & tmp_ratr_value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
|
shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
|
||||||
(shortgi_rate << 4) | (shortgi_rate);
|
(shortgi_rate << 4) | (shortgi_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
|
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
|
||||||
|
|
||||||
|
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
|
||||||
|
rtl_read_dword(rtlpriv, REG_ARFR0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
u8 rssi_level)
|
||||||
{
|
{
|
||||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||||
u32 ratr_bitmap = (u32) mac->basic_rates;
|
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||||
u8 *p_mcsrate = mac->mcs;
|
struct rtl_sta_info *sta_entry = NULL;
|
||||||
u8 ratr_index = 0;
|
u32 ratr_bitmap;
|
||||||
u8 curtxbw_40mhz = mac->bw_40;
|
u8 ratr_index;
|
||||||
u8 curshortgi_40mhz = mac->sgi_40;
|
u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
|
||||||
u8 curshortgi_20mhz = mac->sgi_20;
|
u8 curshortgi_40mhz = curtxbw_40mhz &&
|
||||||
enum wireless_mode wirelessmode = mac->mode;
|
(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||||
|
1 : 0;
|
||||||
|
u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
|
||||||
|
1 : 0;
|
||||||
|
enum wireless_mode wirelessmode = 0;
|
||||||
bool shortgi = false;
|
bool shortgi = false;
|
||||||
u8 rate_mask[5];
|
u8 rate_mask[5];
|
||||||
u8 macid = 0;
|
u8 macid = 0;
|
||||||
u8 mimops = 1;
|
u8 mimo_ps = IEEE80211_SMPS_OFF;
|
||||||
|
|
||||||
ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
|
sta_entry = (struct rtl_sta_info *) sta->drv_priv;
|
||||||
|
wirelessmode = sta_entry->wireless_mode;
|
||||||
|
if (mac->opmode == NL80211_IFTYPE_STATION ||
|
||||||
|
mac->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||||
|
curtxbw_40mhz = mac->bw_40;
|
||||||
|
else if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||||
|
mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||||
|
macid = sta->aid + 1;
|
||||||
|
|
||||||
|
if (rtlhal->current_bandtype == BAND_ON_5G)
|
||||||
|
ratr_bitmap = sta->supp_rates[1] << 4;
|
||||||
|
else
|
||||||
|
ratr_bitmap = sta->supp_rates[0];
|
||||||
|
if (mac->opmode == NL80211_IFTYPE_ADHOC)
|
||||||
|
ratr_bitmap = 0xfff;
|
||||||
|
ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
|
||||||
|
sta->ht_cap.mcs.rx_mask[0] << 12);
|
||||||
switch (wirelessmode) {
|
switch (wirelessmode) {
|
||||||
case WIRELESS_MODE_B:
|
case WIRELESS_MODE_B:
|
||||||
ratr_index = RATR_INX_WIRELESS_B;
|
ratr_index = RATR_INX_WIRELESS_B;
|
||||||
|
@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||||
break;
|
break;
|
||||||
case WIRELESS_MODE_G:
|
case WIRELESS_MODE_G:
|
||||||
ratr_index = RATR_INX_WIRELESS_GB;
|
ratr_index = RATR_INX_WIRELESS_GB;
|
||||||
|
|
||||||
if (rssi_level == 1)
|
if (rssi_level == 1)
|
||||||
ratr_bitmap &= 0x00000f00;
|
ratr_bitmap &= 0x00000f00;
|
||||||
else if (rssi_level == 2)
|
else if (rssi_level == 2)
|
||||||
|
@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||||
case WIRELESS_MODE_N_24G:
|
case WIRELESS_MODE_N_24G:
|
||||||
case WIRELESS_MODE_N_5G:
|
case WIRELESS_MODE_N_5G:
|
||||||
ratr_index = RATR_INX_WIRELESS_NGB;
|
ratr_index = RATR_INX_WIRELESS_NGB;
|
||||||
if (mimops == 0) {
|
|
||||||
|
if (mimo_ps == IEEE80211_SMPS_STATIC) {
|
||||||
if (rssi_level == 1)
|
if (rssi_level == 1)
|
||||||
ratr_bitmap &= 0x00070000;
|
ratr_bitmap &= 0x00070000;
|
||||||
else if (rssi_level == 2)
|
else if (rssi_level == 2)
|
||||||
|
@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((curtxbw_40mhz && curshortgi_40mhz) ||
|
if ((curtxbw_40mhz && curshortgi_40mhz) ||
|
||||||
(!curtxbw_40mhz && curshortgi_20mhz)) {
|
(!curtxbw_40mhz && curshortgi_20mhz)) {
|
||||||
|
|
||||||
if (macid == 0)
|
if (macid == 0)
|
||||||
shortgi = true;
|
shortgi = true;
|
||||||
else if (macid == 1)
|
else if (macid == 1)
|
||||||
|
@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ratr_index = RATR_INX_WIRELESS_NGB;
|
ratr_index = RATR_INX_WIRELESS_NGB;
|
||||||
|
|
||||||
if (rtlphy->rf_type == RF_1T2R)
|
if (rtlphy->rf_type == RF_1T2R)
|
||||||
ratr_bitmap &= 0x000ff0ff;
|
ratr_bitmap &= 0x000ff0ff;
|
||||||
else
|
else
|
||||||
ratr_bitmap &= 0x0f0ff0ff;
|
ratr_bitmap &= 0x0f0ff0ff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
|
sta_entry->ratr_index = ratr_index;
|
||||||
ratr_bitmap);
|
|
||||||
*(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
|
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
|
||||||
ratr_index << 28);
|
"ratr_bitmap :%x\n", ratr_bitmap);
|
||||||
|
*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
|
||||||
|
(ratr_index << 28);
|
||||||
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
|
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
|
||||||
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
|
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
|
||||||
"Rate_index:%x, ratr_val:%x, %5phC\n",
|
"Rate_index:%x, ratr_val:%x, %5phC\n",
|
||||||
ratr_index, ratr_bitmap, rate_mask);
|
ratr_index, ratr_bitmap, rate_mask);
|
||||||
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
|
memcpy(rtlpriv->rate_mask, rate_mask, 5);
|
||||||
|
/* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
|
||||||
|
* "scheduled while atomic" if called directly */
|
||||||
|
schedule_work(&rtlpriv->works.fill_h2c_cmd);
|
||||||
|
|
||||||
|
if (macid != 0)
|
||||||
|
sta_entry->ratr_index = ratr_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
u8 rssi_level)
|
||||||
|
{
|
||||||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
|
||||||
|
if (rtlpriv->dm.useramask)
|
||||||
|
rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
|
||||||
|
else
|
||||||
|
rtl92cu_update_hal_rate_table(hw, sta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
|
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
|
||||||
|
|
|
@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||||
u32 add_msr, u32 rm_msr);
|
u32 add_msr, u32 rm_msr);
|
||||||
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||||
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||||
void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
|
||||||
struct ieee80211_sta *sta,
|
|
||||||
u8 rssi_level);
|
|
||||||
void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
|
|
||||||
|
|
||||||
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
|
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||||
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
|
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
|
||||||
|
|
|
@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
|
||||||
macaddr = cam_const_broad;
|
macaddr = cam_const_broad;
|
||||||
entry_id = key_index;
|
entry_id = key_index;
|
||||||
} else {
|
} else {
|
||||||
key_index = PAIRWISE_KEYIDX;
|
if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||||
|
mac->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||||
|
entry_id = rtl_cam_get_free_entry(hw,
|
||||||
|
p_macaddr);
|
||||||
|
if (entry_id >= TOTAL_CAM_ENTRY) {
|
||||||
|
RT_TRACE(rtlpriv, COMP_SEC,
|
||||||
|
DBG_EMERG,
|
||||||
|
"Can not find free hw security cam entry\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
entry_id = CAM_PAIRWISE_KEY_POSITION;
|
entry_id = CAM_PAIRWISE_KEY_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_index = PAIRWISE_KEYIDX;
|
||||||
is_pairwise = true;
|
is_pairwise = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rtlpriv->sec.key_len[key_index] == 0) {
|
if (rtlpriv->sec.key_len[key_index] == 0) {
|
||||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||||
"delete one entry\n");
|
"delete one entry\n");
|
||||||
|
if (mac->opmode == NL80211_IFTYPE_AP ||
|
||||||
|
mac->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||||
|
rtl_cam_del_entry(hw, p_macaddr);
|
||||||
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
|
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
|
||||||
} else {
|
} else {
|
||||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||||
|
|
|
@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||||||
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
|
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
|
||||||
.get_hw_reg = rtl92cu_get_hw_reg,
|
.get_hw_reg = rtl92cu_get_hw_reg,
|
||||||
.set_hw_reg = rtl92cu_set_hw_reg,
|
.set_hw_reg = rtl92cu_set_hw_reg,
|
||||||
.update_rate_tbl = rtl92cu_update_hal_rate_table,
|
.update_rate_tbl = rtl92cu_update_hal_rate_tbl,
|
||||||
.update_rate_mask = rtl92cu_update_hal_rate_mask,
|
|
||||||
.fill_tx_desc = rtl92cu_tx_fill_desc,
|
.fill_tx_desc = rtl92cu_tx_fill_desc,
|
||||||
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
|
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
|
||||||
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
|
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
|
||||||
|
@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||||||
.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
|
.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
|
||||||
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
|
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
|
||||||
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
|
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
|
||||||
|
.fill_h2c_cmd = rtl92c_fill_h2c_cmd,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rtl_mod_params rtl92cu_mod_params = {
|
static struct rtl_mod_params rtl92cu_mod_params = {
|
||||||
|
@ -349,6 +349,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
|
||||||
{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
|
{RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/
|
||||||
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
|
{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
|
||||||
{RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
|
{RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
|
||||||
|
{RTL_USB_DEVICE(0x0846, 0xf001, rtl92cu_hal_cfg)}, /*On Netwrks N300MA*/
|
||||||
{RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
|
{RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
|
||||||
{RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
|
{RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
|
||||||
{RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/
|
{RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/
|
||||||
|
|
|
@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
|
||||||
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
|
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
|
||||||
enum radio_path rfpath, u32 regaddr, u32 bitmask);
|
enum radio_path rfpath, u32 regaddr, u32 bitmask);
|
||||||
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
|
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
|
||||||
|
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
u8 rssi_level);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
/* should after adapter start and interrupt enable. */
|
/* should after adapter start and interrupt enable. */
|
||||||
set_hal_stop(rtlhal);
|
set_hal_stop(rtlhal);
|
||||||
|
cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
|
||||||
/* Enable software */
|
/* Enable software */
|
||||||
SET_USB_STOP(rtlusb);
|
SET_USB_STOP(rtlusb);
|
||||||
rtl_usb_deinit(hw);
|
rtl_usb_deinit(hw);
|
||||||
|
@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct rtl_works *rtlworks =
|
||||||
|
container_of(work, struct rtl_works, fill_h2c_cmd);
|
||||||
|
struct ieee80211_hw *hw = rtlworks->hw;
|
||||||
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||||
|
|
||||||
|
rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask);
|
||||||
|
}
|
||||||
|
|
||||||
static struct rtl_intf_ops rtl_usb_ops = {
|
static struct rtl_intf_ops rtl_usb_ops = {
|
||||||
.adapter_start = rtl_usb_start,
|
.adapter_start = rtl_usb_start,
|
||||||
.adapter_stop = rtl_usb_stop,
|
.adapter_stop = rtl_usb_stop,
|
||||||
|
@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf,
|
||||||
|
|
||||||
/* this spin lock must be initialized early */
|
/* this spin lock must be initialized early */
|
||||||
spin_lock_init(&rtlpriv->locks.usb_lock);
|
spin_lock_init(&rtlpriv->locks.usb_lock);
|
||||||
|
INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
|
||||||
|
rtl_fill_h2c_cmd_work_callback);
|
||||||
|
|
||||||
rtlpriv->usb_data_index = 0;
|
rtlpriv->usb_data_index = 0;
|
||||||
init_completion(&rtlpriv->firmware_loading_complete);
|
init_completion(&rtlpriv->firmware_loading_complete);
|
||||||
|
|
|
@ -1736,6 +1736,8 @@ struct rtl_hal_ops {
|
||||||
void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
|
void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
|
||||||
bool mstate);
|
bool mstate);
|
||||||
void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
|
void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
|
||||||
|
void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
|
||||||
|
u32 cmd_len, u8 *p_cmdbuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl_intf_ops {
|
struct rtl_intf_ops {
|
||||||
|
@ -1869,6 +1871,7 @@ struct rtl_works {
|
||||||
struct delayed_work fwevt_wq;
|
struct delayed_work fwevt_wq;
|
||||||
|
|
||||||
struct work_struct lps_change_work;
|
struct work_struct lps_change_work;
|
||||||
|
struct work_struct fill_h2c_cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtl_debug {
|
struct rtl_debug {
|
||||||
|
@ -2048,6 +2051,7 @@ struct rtl_priv {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
bool enter_ps; /* true when entering PS */
|
bool enter_ps; /* true when entering PS */
|
||||||
|
u8 rate_mask[5];
|
||||||
|
|
||||||
/*This must be the last item so
|
/*This must be the last item so
|
||||||
that it points to the data allocated
|
that it points to the data allocated
|
||||||
|
|
|
@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
|
||||||
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
||||||
sizeof(cmd->channels_2));
|
sizeof(cmd->channels_2));
|
||||||
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
||||||
sizeof(cmd->channels_2));
|
sizeof(cmd->channels_5));
|
||||||
/* channels_4 are not supported, so no need to copy them */
|
/* channels_4 are not supported, so no need to copy them */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
#define WL127X_IFTYPE_SR_VER 3
|
#define WL127X_IFTYPE_SR_VER 3
|
||||||
#define WL127X_MAJOR_SR_VER 10
|
#define WL127X_MAJOR_SR_VER 10
|
||||||
#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
||||||
#define WL127X_MINOR_SR_VER 115
|
#define WL127X_MINOR_SR_VER 133
|
||||||
/* minimum multi-role FW version for wl127x */
|
/* minimum multi-role FW version for wl127x */
|
||||||
#define WL127X_IFTYPE_MR_VER 5
|
#define WL127X_IFTYPE_MR_VER 5
|
||||||
#define WL127X_MAJOR_MR_VER 7
|
#define WL127X_MAJOR_MR_VER 7
|
||||||
#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
|
#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
|
||||||
#define WL127X_MINOR_MR_VER 115
|
#define WL127X_MINOR_MR_VER 42
|
||||||
|
|
||||||
/* FW chip version for wl128x */
|
/* FW chip version for wl128x */
|
||||||
#define WL128X_CHIP_VER 7
|
#define WL128X_CHIP_VER 7
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
#define WL128X_IFTYPE_SR_VER 3
|
#define WL128X_IFTYPE_SR_VER 3
|
||||||
#define WL128X_MAJOR_SR_VER 10
|
#define WL128X_MAJOR_SR_VER 10
|
||||||
#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
|
||||||
#define WL128X_MINOR_SR_VER 115
|
#define WL128X_MINOR_SR_VER 133
|
||||||
/* minimum multi-role FW version for wl128x */
|
/* minimum multi-role FW version for wl128x */
|
||||||
#define WL128X_IFTYPE_MR_VER 5
|
#define WL128X_IFTYPE_MR_VER 5
|
||||||
#define WL128X_MAJOR_MR_VER 7
|
#define WL128X_MAJOR_MR_VER 7
|
||||||
|
|
|
@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd,
|
||||||
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
memcpy(cmd->channels_2, cmd_channels->channels_2,
|
||||||
sizeof(cmd->channels_2));
|
sizeof(cmd->channels_2));
|
||||||
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
memcpy(cmd->channels_5, cmd_channels->channels_5,
|
||||||
sizeof(cmd->channels_2));
|
sizeof(cmd->channels_5));
|
||||||
/* channels_4 are not supported, so no need to copy them */
|
/* channels_4 are not supported, so no need to copy them */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ config NFC_WILINK
|
||||||
|
|
||||||
config NFC_MEI_PHY
|
config NFC_MEI_PHY
|
||||||
tristate "MEI bus NFC device support"
|
tristate "MEI bus NFC device support"
|
||||||
depends on INTEL_MEI_BUS_NFC && NFC_HCI
|
depends on INTEL_MEI && NFC_HCI
|
||||||
help
|
help
|
||||||
This adds support to use an mei bus nfc device. Select this if you
|
This adds support to use an mei bus nfc device. Select this if you
|
||||||
will use an HCI NFC driver for an NFC chip connected behind an
|
will use an HCI NFC driver for an NFC chip connected behind an
|
||||||
|
|
|
@ -64,6 +64,15 @@ int nfc_mei_phy_enable(void *phy_id)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
|
||||||
|
if (r) {
|
||||||
|
pr_err("MEY_PHY: Event cb registration failed\n");
|
||||||
|
mei_cl_disable_device(phy->device);
|
||||||
|
phy->powered = 0;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
phy->powered = 1;
|
phy->powered = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -43,24 +43,16 @@ static int microread_mei_probe(struct mei_cl_device *device,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
|
|
||||||
if (r) {
|
|
||||||
pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
|
r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
|
||||||
MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
|
MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
|
||||||
&phy->hdev);
|
&phy->hdev);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
nfc_mei_phy_free(phy);
|
nfc_mei_phy_free(phy);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int microread_mei_remove(struct mei_cl_device *device)
|
static int microread_mei_remove(struct mei_cl_device *device)
|
||||||
|
@ -71,8 +63,6 @@ static int microread_mei_remove(struct mei_cl_device *device)
|
||||||
|
|
||||||
microread_remove(phy->hdev);
|
microread_remove(phy->hdev);
|
||||||
|
|
||||||
nfc_mei_phy_disable(phy);
|
|
||||||
|
|
||||||
nfc_mei_phy_free(phy);
|
nfc_mei_phy_free(phy);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -43,24 +43,16 @@ static int pn544_mei_probe(struct mei_cl_device *device,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
|
|
||||||
if (r) {
|
|
||||||
pr_err(PN544_DRIVER_NAME ": event cb registration failed\n");
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
|
r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
|
||||||
MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
|
MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
|
||||||
&phy->hdev);
|
&phy->hdev);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
nfc_mei_phy_free(phy);
|
nfc_mei_phy_free(phy);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pn544_mei_remove(struct mei_cl_device *device)
|
static int pn544_mei_remove(struct mei_cl_device *device)
|
||||||
|
@ -71,8 +63,6 @@ static int pn544_mei_remove(struct mei_cl_device *device)
|
||||||
|
|
||||||
pn544_hci_remove(phy->hdev);
|
pn544_hci_remove(phy->hdev);
|
||||||
|
|
||||||
nfc_mei_phy_disable(phy);
|
|
||||||
|
|
||||||
nfc_mei_phy_free(phy);
|
nfc_mei_phy_free(phy);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -134,7 +134,10 @@ struct bcma_host_ops {
|
||||||
#define BCMA_CORE_I2S 0x834
|
#define BCMA_CORE_I2S 0x834
|
||||||
#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
|
#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
|
||||||
#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
|
#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
|
||||||
#define BCMA_CORE_ARM_CR4 0x83e
|
#define BCMA_CORE_PHY_AC 0x83B
|
||||||
|
#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */
|
||||||
|
#define BCMA_CORE_USB30_DEV 0x83D
|
||||||
|
#define BCMA_CORE_ARM_CR4 0x83E
|
||||||
#define BCMA_CORE_DEFAULT 0xFFF
|
#define BCMA_CORE_DEFAULT 0xFFF
|
||||||
|
|
||||||
#define BCMA_MAX_NR_CORES 16
|
#define BCMA_MAX_NR_CORES 16
|
||||||
|
|
|
@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
|
||||||
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
|
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
|
||||||
int mgmt_index_added(struct hci_dev *hdev);
|
int mgmt_index_added(struct hci_dev *hdev);
|
||||||
int mgmt_index_removed(struct hci_dev *hdev);
|
int mgmt_index_removed(struct hci_dev *hdev);
|
||||||
|
int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
|
||||||
int mgmt_powered(struct hci_dev *hdev, u8 powered);
|
int mgmt_powered(struct hci_dev *hdev, u8 powered);
|
||||||
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
|
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
|
||||||
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
|
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#define MGMT_STATUS_NOT_POWERED 0x0f
|
#define MGMT_STATUS_NOT_POWERED 0x0f
|
||||||
#define MGMT_STATUS_CANCELLED 0x10
|
#define MGMT_STATUS_CANCELLED 0x10
|
||||||
#define MGMT_STATUS_INVALID_INDEX 0x11
|
#define MGMT_STATUS_INVALID_INDEX 0x11
|
||||||
|
#define MGMT_STATUS_RFKILLED 0x12
|
||||||
|
|
||||||
struct mgmt_hdr {
|
struct mgmt_hdr {
|
||||||
__le16 opcode;
|
__le16 opcode;
|
||||||
|
|
|
@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = {
|
||||||
static void hci_power_on(struct work_struct *work)
|
static void hci_power_on(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
|
struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
|
||||||
|
int err;
|
||||||
|
|
||||||
BT_DBG("%s", hdev->name);
|
BT_DBG("%s", hdev->name);
|
||||||
|
|
||||||
if (hci_dev_open(hdev->id) < 0)
|
err = hci_dev_open(hdev->id);
|
||||||
|
if (err < 0) {
|
||||||
|
mgmt_set_powered_failed(hdev, err);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
|
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
|
||||||
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
|
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
|
||||||
|
|
|
@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_command_rej(struct l2cap_conn *conn,
|
static inline int l2cap_command_rej(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
|
struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
|
||||||
|
|
||||||
|
if (cmd_len < sizeof(*rej))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
|
if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3829,11 +3833,14 @@ sendresp:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_connect_req(struct l2cap_conn *conn,
|
static int l2cap_connect_req(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = conn->hcon->hdev;
|
struct hci_dev *hdev = conn->hcon->hdev;
|
||||||
struct hci_conn *hcon = conn->hcon;
|
struct hci_conn *hcon = conn->hcon;
|
||||||
|
|
||||||
|
if (cmd_len < sizeof(struct l2cap_conn_req))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
hci_dev_lock(hdev);
|
||||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
|
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
|
||||||
|
@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
|
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
|
||||||
u16 scid, dcid, result, status;
|
u16 scid, dcid, result, status;
|
||||||
|
@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
||||||
u8 req[128];
|
u8 req[128];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (cmd_len < sizeof(*rsp))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
scid = __le16_to_cpu(rsp->scid);
|
scid = __le16_to_cpu(rsp->scid);
|
||||||
dcid = __le16_to_cpu(rsp->dcid);
|
dcid = __le16_to_cpu(rsp->dcid);
|
||||||
result = __le16_to_cpu(rsp->result);
|
result = __le16_to_cpu(rsp->result);
|
||||||
|
@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
||||||
struct l2cap_chan *chan;
|
struct l2cap_chan *chan;
|
||||||
int len, err = 0;
|
int len, err = 0;
|
||||||
|
|
||||||
|
if (cmd_len < sizeof(*req))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
dcid = __le16_to_cpu(req->dcid);
|
dcid = __le16_to_cpu(req->dcid);
|
||||||
flags = __le16_to_cpu(req->flags);
|
flags = __le16_to_cpu(req->flags);
|
||||||
|
|
||||||
|
@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
||||||
|
|
||||||
/* Reject if config buffer is too small. */
|
/* Reject if config buffer is too small. */
|
||||||
len = cmd_len - sizeof(*req);
|
len = cmd_len - sizeof(*req);
|
||||||
if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
|
if (chan->conf_len + len > sizeof(chan->conf_req)) {
|
||||||
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
|
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
|
||||||
l2cap_build_conf_rsp(chan, rsp,
|
l2cap_build_conf_rsp(chan, rsp,
|
||||||
L2CAP_CONF_REJECT, flags), rsp);
|
L2CAP_CONF_REJECT, flags), rsp);
|
||||||
|
@ -4053,14 +4067,18 @@ unlock:
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
static inline int l2cap_config_rsp(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
|
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
|
||||||
u16 scid, flags, result;
|
u16 scid, flags, result;
|
||||||
struct l2cap_chan *chan;
|
struct l2cap_chan *chan;
|
||||||
int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
|
int len = cmd_len - sizeof(*rsp);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
if (cmd_len < sizeof(*rsp))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
scid = __le16_to_cpu(rsp->scid);
|
scid = __le16_to_cpu(rsp->scid);
|
||||||
flags = __le16_to_cpu(rsp->flags);
|
flags = __le16_to_cpu(rsp->flags);
|
||||||
result = __le16_to_cpu(rsp->result);
|
result = __le16_to_cpu(rsp->result);
|
||||||
|
@ -4161,7 +4179,8 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
|
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
|
||||||
struct l2cap_disconn_rsp rsp;
|
struct l2cap_disconn_rsp rsp;
|
||||||
|
@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
||||||
struct l2cap_chan *chan;
|
struct l2cap_chan *chan;
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
|
|
||||||
|
if (cmd_len != sizeof(*req))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
scid = __le16_to_cpu(req->scid);
|
scid = __le16_to_cpu(req->scid);
|
||||||
dcid = __le16_to_cpu(req->dcid);
|
dcid = __le16_to_cpu(req->dcid);
|
||||||
|
|
||||||
|
@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
|
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
|
||||||
u16 dcid, scid;
|
u16 dcid, scid;
|
||||||
struct l2cap_chan *chan;
|
struct l2cap_chan *chan;
|
||||||
|
|
||||||
|
if (cmd_len != sizeof(*rsp))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
scid = __le16_to_cpu(rsp->scid);
|
scid = __le16_to_cpu(rsp->scid);
|
||||||
dcid = __le16_to_cpu(rsp->dcid);
|
dcid = __le16_to_cpu(rsp->dcid);
|
||||||
|
|
||||||
|
@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_information_req(struct l2cap_conn *conn,
|
static inline int l2cap_information_req(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_info_req *req = (struct l2cap_info_req *) data;
|
struct l2cap_info_req *req = (struct l2cap_info_req *) data;
|
||||||
u16 type;
|
u16 type;
|
||||||
|
|
||||||
|
if (cmd_len != sizeof(*req))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
type = __le16_to_cpu(req->type);
|
type = __le16_to_cpu(req->type);
|
||||||
|
|
||||||
BT_DBG("type 0x%4.4x", type);
|
BT_DBG("type 0x%4.4x", type);
|
||||||
|
@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int l2cap_information_rsp(struct l2cap_conn *conn,
|
static inline int l2cap_information_rsp(struct l2cap_conn *conn,
|
||||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
||||||
|
u8 *data)
|
||||||
{
|
{
|
||||||
struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
|
struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
|
||||||
u16 type, result;
|
u16 type, result;
|
||||||
|
|
||||||
|
if (cmd_len != sizeof(*rsp))
|
||||||
|
return -EPROTO;
|
||||||
|
|
||||||
type = __le16_to_cpu(rsp->type);
|
type = __le16_to_cpu(rsp->type);
|
||||||
result = __le16_to_cpu(rsp->result);
|
result = __le16_to_cpu(rsp->result);
|
||||||
|
|
||||||
|
@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
||||||
|
|
||||||
switch (cmd->code) {
|
switch (cmd->code) {
|
||||||
case L2CAP_COMMAND_REJ:
|
case L2CAP_COMMAND_REJ:
|
||||||
l2cap_command_rej(conn, cmd, data);
|
l2cap_command_rej(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONN_REQ:
|
case L2CAP_CONN_REQ:
|
||||||
err = l2cap_connect_req(conn, cmd, data);
|
err = l2cap_connect_req(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONN_RSP:
|
case L2CAP_CONN_RSP:
|
||||||
case L2CAP_CREATE_CHAN_RSP:
|
case L2CAP_CREATE_CHAN_RSP:
|
||||||
err = l2cap_connect_create_rsp(conn, cmd, data);
|
err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_REQ:
|
case L2CAP_CONF_REQ:
|
||||||
|
@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CONF_RSP:
|
case L2CAP_CONF_RSP:
|
||||||
err = l2cap_config_rsp(conn, cmd, data);
|
err = l2cap_config_rsp(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DISCONN_REQ:
|
case L2CAP_DISCONN_REQ:
|
||||||
err = l2cap_disconnect_req(conn, cmd, data);
|
err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_DISCONN_RSP:
|
case L2CAP_DISCONN_RSP:
|
||||||
err = l2cap_disconnect_rsp(conn, cmd, data);
|
err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_ECHO_REQ:
|
case L2CAP_ECHO_REQ:
|
||||||
|
@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INFO_REQ:
|
case L2CAP_INFO_REQ:
|
||||||
err = l2cap_information_req(conn, cmd, data);
|
err = l2cap_information_req(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_INFO_RSP:
|
case L2CAP_INFO_RSP:
|
||||||
err = l2cap_information_rsp(conn, cmd, data);
|
err = l2cap_information_rsp(conn, cmd, cmd_len, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_CREATE_CHAN_REQ:
|
case L2CAP_CREATE_CHAN_REQ:
|
||||||
|
|
|
@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DISCOV_TYPE_LE:
|
case DISCOV_TYPE_LE:
|
||||||
if (!lmp_host_le_capable(hdev)) {
|
if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
|
||||||
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
||||||
MGMT_STATUS_NOT_SUPPORTED);
|
MGMT_STATUS_NOT_SUPPORTED);
|
||||||
mgmt_pending_remove(cmd);
|
mgmt_pending_remove(cmd);
|
||||||
|
@ -3418,6 +3418,27 @@ new_settings:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mgmt_set_powered_failed(struct hci_dev *hdev, int err)
|
||||||
|
{
|
||||||
|
struct pending_cmd *cmd;
|
||||||
|
u8 status;
|
||||||
|
|
||||||
|
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
|
||||||
|
if (!cmd)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (err == -ERFKILL)
|
||||||
|
status = MGMT_STATUS_RFKILLED;
|
||||||
|
else
|
||||||
|
status = MGMT_STATUS_FAILED;
|
||||||
|
|
||||||
|
err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
|
||||||
|
|
||||||
|
mgmt_pending_remove(cmd);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
|
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
|
||||||
{
|
{
|
||||||
struct cmd_lookup match = { NULL, hdev };
|
struct cmd_lookup match = { NULL, hdev };
|
||||||
|
|
|
@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
||||||
|
|
||||||
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
|
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
|
||||||
|
|
||||||
if (!lmp_host_le_capable(hcon->hdev))
|
if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (sec_level == BT_SECURITY_LOW)
|
if (sec_level == BT_SECURITY_LOW)
|
||||||
|
@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||||
__u8 reason;
|
__u8 reason;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!lmp_host_le_capable(conn->hcon->hdev)) {
|
if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) {
|
||||||
err = -ENOTSUPP;
|
err = -ENOTSUPP;
|
||||||
reason = SMP_PAIRING_NOTSUPP;
|
reason = SMP_PAIRING_NOTSUPP;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
@ -159,10 +159,11 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
|
static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
||||||
bool check_dup)
|
bool check_dup)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
struct ieee80211_sub_if_data *iter;
|
||||||
u64 new, mask, tmp;
|
u64 new, mask, tmp;
|
||||||
u8 *m;
|
u8 *m;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -184,12 +185,15 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&local->iflist_mtx);
|
mutex_lock(&local->iflist_mtx);
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
list_for_each_entry(iter, &local->interfaces, list) {
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
if (iter == sdata)
|
||||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m = sdata->vif.addr;
|
if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||||
|
!(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m = iter->vif.addr;
|
||||||
tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
|
tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
|
||||||
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
||||||
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
||||||
|
@ -218,7 +222,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
|
||||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||||
check_dup = false;
|
check_dup = false;
|
||||||
|
|
||||||
ret = ieee80211_verify_mac(sdata->local, sa->sa_data, check_dup);
|
ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1503,7 +1507,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pick address of existing interface in case user changed
|
||||||
|
* MAC address manually, default to perm_addr.
|
||||||
|
*/
|
||||||
m = local->hw.wiphy->perm_addr;
|
m = local->hw.wiphy->perm_addr;
|
||||||
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
|
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
||||||
|
continue;
|
||||||
|
m = sdata->vif.addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
|
start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
|
||||||
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
||||||
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
obj-$(CONFIG_NFC) += nfc.o
|
obj-$(CONFIG_NFC) += nfc.o
|
||||||
obj-$(CONFIG_NFC_NCI) += nci/
|
obj-$(CONFIG_NFC_NCI) += nci/
|
||||||
obj-$(CONFIG_NFC_HCI) += hci/
|
obj-$(CONFIG_NFC_HCI) += hci/
|
||||||
#obj-$(CONFIG_NFC_LLCP) += llcp/
|
|
||||||
|
|
||||||
nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
|
nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
|
||||||
llcp_sock.o
|
llcp_sock.o
|
||||||
|
|
Loading…
Add table
Reference in a new issue