mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
This commit is contained in:
commit
aa489f0f26
@ -3984,18 +3984,20 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
|
||||
int quick_drop;
|
||||
s32 t[3], f[3] = {5180, 5500, 5785};
|
||||
|
||||
if (!(pBase->miscConfiguration & BIT(1)))
|
||||
if (!(pBase->miscConfiguration & BIT(4)))
|
||||
return;
|
||||
|
||||
if (freq < 4000)
|
||||
quick_drop = eep->modalHeader2G.quick_drop;
|
||||
else {
|
||||
t[0] = eep->base_ext1.quick_drop_low;
|
||||
t[1] = eep->modalHeader5G.quick_drop;
|
||||
t[2] = eep->base_ext1.quick_drop_high;
|
||||
quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
|
||||
if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) {
|
||||
if (freq < 4000) {
|
||||
quick_drop = eep->modalHeader2G.quick_drop;
|
||||
} else {
|
||||
t[0] = eep->base_ext1.quick_drop_low;
|
||||
t[1] = eep->modalHeader5G.quick_drop;
|
||||
t[2] = eep->base_ext1.quick_drop_high;
|
||||
quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3);
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
|
||||
}
|
||||
|
||||
static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
|
||||
@ -4035,7 +4037,7 @@ static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
u8 bias;
|
||||
|
||||
if (!(eep->baseEepHeader.featureEnable & 0x40))
|
||||
if (!(eep->baseEepHeader.miscConfiguration & 0x40))
|
||||
return;
|
||||
|
||||
if (!AR_SREV_9300(ah))
|
||||
|
@ -146,10 +146,9 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah)
|
||||
else
|
||||
clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
|
||||
|
||||
if (IS_CHAN_HT40(chan))
|
||||
clockrate *= 2;
|
||||
|
||||
if (ah->curchan) {
|
||||
if (chan) {
|
||||
if (IS_CHAN_HT40(chan))
|
||||
clockrate *= 2;
|
||||
if (IS_CHAN_HALF_RATE(chan))
|
||||
clockrate /= 2;
|
||||
if (IS_CHAN_QUARTER_RATE(chan))
|
||||
|
@ -2041,13 +2041,20 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
|
||||
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
|
||||
mutex_lock(&wcn->hal_ind_mutex);
|
||||
msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL);
|
||||
msg_ind->msg_len = len;
|
||||
msg_ind->msg = kmalloc(len, GFP_KERNEL);
|
||||
memcpy(msg_ind->msg, buf, len);
|
||||
list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
|
||||
queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
|
||||
if (msg_ind) {
|
||||
msg_ind->msg_len = len;
|
||||
msg_ind->msg = kmalloc(len, GFP_KERNEL);
|
||||
memcpy(msg_ind->msg, buf, len);
|
||||
list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
|
||||
queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n");
|
||||
}
|
||||
mutex_unlock(&wcn->hal_ind_mutex);
|
||||
if (msg_ind)
|
||||
break;
|
||||
/* FIXME: Do something smarter then just printing an error. */
|
||||
wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
|
||||
msg_header->msg_type);
|
||||
break;
|
||||
default:
|
||||
wcn36xx_err("SMD_EVENT (%d) not supported\n",
|
||||
|
@ -5,6 +5,8 @@ config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on MAC80211
|
||||
depends on BCMA
|
||||
select NEW_LEDS if BCMA_DRIVER_GPIO
|
||||
select LEDS_CLASS if BCMA_DRIVER_GPIO
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
|
@ -109,6 +109,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
|
||||
brcmf_err("Disable F2 failed:%d\n",
|
||||
err_ret);
|
||||
}
|
||||
} else {
|
||||
err_ret = -ENOENT;
|
||||
}
|
||||
} else if ((regaddr == SDIO_CCCR_ABORT) ||
|
||||
(regaddr == SDIO_CCCR_IENx)) {
|
||||
|
@ -67,8 +67,8 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MAX 7
|
||||
#define IWL3160_UCODE_API_MAX 7
|
||||
#define IWL7260_UCODE_API_MAX 8
|
||||
#define IWL3160_UCODE_API_MAX 8
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL7260_UCODE_API_OK 7
|
||||
@ -130,6 +130,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
@ -140,6 +141,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.high_temp = true,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
@ -149,6 +151,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_n_cfg = {
|
||||
@ -158,6 +161,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
@ -167,6 +171,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
@ -176,6 +181,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_n_cfg = {
|
||||
@ -185,6 +191,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
@ -196,5 +203,23 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 7265",
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_n_cfg = {
|
||||
.name = "Intel(R) Wireless N 7265",
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
|
||||
MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
|
||||
|
@ -207,6 +207,8 @@ struct iwl_eeprom_params {
|
||||
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity
|
||||
* @internal_wimax_coex: internal wifi/wimax combo device
|
||||
* @high_temp: Is this NIC is designated to be in high temperature.
|
||||
* @host_interrupt_operation_mode: device needs host interrupt operation
|
||||
* mode set
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt. hardware features.
|
||||
* API differences in uCode shouldn't be handled here but through TLVs
|
||||
@ -235,6 +237,7 @@ struct iwl_cfg {
|
||||
enum iwl_led_mode led_mode;
|
||||
const bool rx_with_siso_diversity;
|
||||
const bool internal_wimax_coex;
|
||||
const bool host_interrupt_operation_mode;
|
||||
bool high_temp;
|
||||
};
|
||||
|
||||
@ -294,6 +297,8 @@ extern const struct iwl_cfg iwl3160_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl3160_2n_cfg;
|
||||
extern const struct iwl_cfg iwl3160_n_cfg;
|
||||
extern const struct iwl_cfg iwl7265_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl7265_2n_cfg;
|
||||
extern const struct iwl_cfg iwl7265_n_cfg;
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
#endif /* __IWL_CONFIG_H__ */
|
||||
|
@ -495,14 +495,11 @@ enum secure_load_status_reg {
|
||||
* the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
|
||||
*
|
||||
* default interrupt coalescing timer is 64 x 32 = 2048 usecs
|
||||
* default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
|
||||
*/
|
||||
#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
|
||||
#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
|
||||
#define IWL_HOST_INT_OPER_MODE BIT(31)
|
||||
|
||||
/*****************************************************************************
|
||||
* 7000/3000 series SHR DTS addresses *
|
||||
|
@ -391,7 +391,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
||||
BT_VALID_LUT |
|
||||
BT_VALID_WIFI_RX_SW_PRIO_BOOST |
|
||||
BT_VALID_WIFI_TX_SW_PRIO_BOOST |
|
||||
BT_VALID_MULTI_PRIO_LUT |
|
||||
BT_VALID_CORUN_LUT_20 |
|
||||
BT_VALID_CORUN_LUT_40 |
|
||||
BT_VALID_ANT_ISOLATION |
|
||||
@ -842,6 +841,11 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
|
||||
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
|
||||
/* This can happen if the station has been removed right now */
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
return;
|
||||
|
||||
mvmsta = (void *)sta->drv_priv;
|
||||
|
||||
data->num_bss_ifaces++;
|
||||
|
@ -895,7 +895,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
|
||||
/* new API returns next, not last-used seqno */
|
||||
if (mvm->fw->ucode_capa.flags &
|
||||
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
|
||||
err -= 0x10;
|
||||
err = (u16) (err - 0x10);
|
||||
}
|
||||
|
||||
iwl_free_resp(&cmd);
|
||||
@ -1549,7 +1549,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
|
||||
if (gtkdata.unhandled_cipher)
|
||||
return false;
|
||||
if (!gtkdata.num_keys)
|
||||
return true;
|
||||
goto out;
|
||||
if (!gtkdata.last_gtk)
|
||||
return false;
|
||||
|
||||
@ -1600,6 +1600,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
|
||||
(void *)&replay_ctr, GFP_KERNEL);
|
||||
}
|
||||
|
||||
out:
|
||||
mvmvif->seqno_valid = true;
|
||||
/* +0x10 because the set API expects next-to-use, not last-used */
|
||||
mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
|
||||
|
@ -119,6 +119,10 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct file *file,
|
||||
|
||||
if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
|
||||
return -EINVAL;
|
||||
if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
|
||||
return -EINVAL;
|
||||
if (drain < 0 || drain > 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
|
@ -176,8 +176,11 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
|
||||
* P2P Device discoveribility, while there are other higher priority
|
||||
* events in the system).
|
||||
*/
|
||||
if (WARN_ONCE(!le32_to_cpu(notif->status),
|
||||
"Failed to schedule time event\n")) {
|
||||
if (!le32_to_cpu(notif->status)) {
|
||||
bool start = le32_to_cpu(notif->action) &
|
||||
TE_V2_NOTIF_HOST_EVENT_START;
|
||||
IWL_WARN(mvm, "Time Event %s notification failure\n",
|
||||
start ? "start" : "end");
|
||||
if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) {
|
||||
iwl_mvm_te_clear_data(mvm, te_data);
|
||||
return;
|
||||
|
@ -353,6 +353,27 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
||||
|
||||
/* 7265 Series */
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5012, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x500A, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
{0}
|
||||
|
@ -477,4 +477,12 @@ static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
|
||||
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
|
||||
}
|
||||
|
||||
static inline void iwl_nic_error(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
set_bit(STATUS_FW_ERROR, &trans_pcie->status);
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
}
|
||||
|
||||
#endif /* __iwl_trans_int_pcie_h__ */
|
||||
|
@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
|
||||
|
||||
/* Set interrupt coalescing timer to default (2048 usecs) */
|
||||
iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
|
||||
|
||||
/* W/A for interrupt coalescing bug in 7260 and 3160 */
|
||||
if (trans->cfg->host_interrupt_operation_mode)
|
||||
iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE);
|
||||
}
|
||||
|
||||
static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
|
||||
@ -796,12 +800,13 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
|
||||
iwl_pcie_dump_csr(trans);
|
||||
iwl_dump_fh(trans, NULL);
|
||||
|
||||
/* set the ERROR bit before we wake up the caller */
|
||||
set_bit(STATUS_FW_ERROR, &trans_pcie->status);
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
|
||||
wake_up(&trans_pcie->wait_command_queue);
|
||||
|
||||
local_bh_disable();
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
iwl_nic_error(trans);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
|
@ -279,9 +279,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
|
||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||
iwl_pcie_apm_init(trans);
|
||||
|
||||
/* Set interrupt coalescing calibration timer to default (512 usecs) */
|
||||
iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
|
||||
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
|
||||
iwl_pcie_set_pwr(trans, false);
|
||||
|
@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
|
||||
IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
|
||||
le32_to_cpu(txq->scratchbufs[i].scratch));
|
||||
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
iwl_nic_error(trans);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1023,7 +1023,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
|
||||
if (nfreed++ > 0) {
|
||||
IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
|
||||
idx, q->write_ptr, q->read_ptr);
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
iwl_nic_error(trans);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1562,7 +1562,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
|
||||
get_cmd_string(trans_pcie, cmd->id));
|
||||
ret = -ETIMEDOUT;
|
||||
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
iwl_nic_error(trans);
|
||||
|
||||
goto cancel;
|
||||
}
|
||||
|
@ -383,6 +383,14 @@ struct hwsim_radiotap_hdr {
|
||||
__le16 rt_chbitmask;
|
||||
} __packed;
|
||||
|
||||
struct hwsim_radiotap_ack_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
u8 rt_flags;
|
||||
u8 pad;
|
||||
__le16 rt_channel;
|
||||
__le16 rt_chbitmask;
|
||||
} __packed;
|
||||
|
||||
/* MAC80211_HWSIM netlinf family */
|
||||
static struct genl_family hwsim_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
@ -500,7 +508,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct hwsim_radiotap_hdr *hdr;
|
||||
struct hwsim_radiotap_ack_hdr *hdr;
|
||||
u16 flags;
|
||||
struct ieee80211_hdr *hdr11;
|
||||
|
||||
@ -511,14 +519,14 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
|
||||
if (skb == NULL)
|
||||
return;
|
||||
|
||||
hdr = (struct hwsim_radiotap_hdr *) skb_put(skb, sizeof(*hdr));
|
||||
hdr = (struct hwsim_radiotap_ack_hdr *) skb_put(skb, sizeof(*hdr));
|
||||
hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
|
||||
hdr->hdr.it_pad = 0;
|
||||
hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
|
||||
hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL));
|
||||
hdr->rt_flags = 0;
|
||||
hdr->rt_rate = 0;
|
||||
hdr->pad = 0;
|
||||
hdr->rt_channel = cpu_to_le16(chan->center_freq);
|
||||
flags = IEEE80211_CHAN_2GHZ;
|
||||
hdr->rt_chbitmask = cpu_to_le16(flags);
|
||||
@ -1230,7 +1238,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
|
||||
HRTIMER_MODE_REL);
|
||||
} else if (!info->enable_beacon) {
|
||||
unsigned int count = 0;
|
||||
ieee80211_iterate_active_interfaces(
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
data->hw, IEEE80211_IFACE_ITER_NORMAL,
|
||||
mac80211_hwsim_bcn_en_iter, &count);
|
||||
wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u",
|
||||
|
@ -319,8 +319,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||
if (bss_desc && bss_desc->ssid.ssid_len &&
|
||||
(!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
|
||||
ssid, &bss_desc->ssid))) {
|
||||
kfree(bss_desc);
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Exit Adhoc mode first */
|
||||
|
@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
changed |=
|
||||
ieee80211_mps_set_sta_local_pm(sta,
|
||||
params->local_pm);
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
|
||||
@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
params->chandef.chan->band)
|
||||
return -EINVAL;
|
||||
|
||||
ifmsh->chsw_init = true;
|
||||
if (!ifmsh->pre_value)
|
||||
ifmsh->pre_value = 1;
|
||||
else
|
||||
ifmsh->pre_value++;
|
||||
|
||||
err = ieee80211_mesh_csa_beacon(sdata, params, true);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
ifmsh->chsw_init = false;
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -823,6 +823,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
/* channel switch is not supported, disconnect */
|
||||
if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
|
||||
goto disconnect;
|
||||
|
||||
params.count = csa_ie.count;
|
||||
params.chandef = csa_ie.chandef;
|
||||
|
||||
|
@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie {
|
||||
u8 mode;
|
||||
u8 count;
|
||||
u8 ttl;
|
||||
u16 pre_value;
|
||||
};
|
||||
|
||||
/* Parsed Information Elements */
|
||||
|
@ -1325,7 +1325,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->vif.bss_conf.bssid = NULL;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
sdata->vif.bss_conf.bssid = sdata->vif.addr;
|
||||
break;
|
||||
|
@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
|
||||
result);
|
||||
|
||||
local->hw.conf.flags = IEEE80211_CONF_IDLE;
|
||||
|
||||
ieee80211_led_init(local);
|
||||
|
||||
rtnl_lock();
|
||||
@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||
|
||||
cancel_work_sync(&local->restart_work);
|
||||
cancel_work_sync(&local->reconfig_filter);
|
||||
flush_work(&local->sched_scan_stopped_work);
|
||||
|
||||
ieee80211_clear_tx_pending(local);
|
||||
rate_control_deinitialize(local);
|
||||
|
@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
||||
params.chandef.chan->center_freq);
|
||||
|
||||
params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
|
||||
if (beacon)
|
||||
if (beacon) {
|
||||
ifmsh->chsw_ttl = csa_ie.ttl - 1;
|
||||
else
|
||||
ifmsh->chsw_ttl = 0;
|
||||
if (ifmsh->pre_value >= csa_ie.pre_value)
|
||||
return false;
|
||||
ifmsh->pre_value = csa_ie.pre_value;
|
||||
}
|
||||
|
||||
if (ifmsh->chsw_ttl > 0)
|
||||
if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) {
|
||||
if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0)
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
sdata->csa_radar_required = params.radar_required;
|
||||
|
||||
@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
|
||||
offset_ttl = (len < 42) ? 7 : 10;
|
||||
*(pos + offset_ttl) -= 1;
|
||||
*(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
|
||||
sdata->u.mesh.chsw_ttl = *(pos + offset_ttl);
|
||||
|
||||
memcpy(mgmt_fwd, mgmt, len);
|
||||
eth_broadcast_addr(mgmt_fwd->da);
|
||||
@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
|
||||
u16 pre_value;
|
||||
bool fwd_csa = true;
|
||||
size_t baselen;
|
||||
u8 *pos, ttl;
|
||||
u8 *pos;
|
||||
|
||||
if (mgmt->u.action.u.measurement.action_code !=
|
||||
WLAN_ACTION_SPCT_CHL_SWITCH)
|
||||
@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
|
||||
u.action.u.chan_switch.variable);
|
||||
ieee802_11_parse_elems(pos, len - baselen, false, &elems);
|
||||
|
||||
ttl = elems.mesh_chansw_params_ie->mesh_ttl;
|
||||
if (!--ttl)
|
||||
ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
|
||||
if (!--ifmsh->chsw_ttl)
|
||||
fwd_csa = false;
|
||||
|
||||
pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
|
||||
|
@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
|
||||
if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
|
||||
already = true;
|
||||
|
||||
ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
|
||||
|
||||
mutex_unlock(&sdata->local->mtx);
|
||||
|
||||
if (already)
|
||||
|
@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)
|
||||
nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
|
||||
nsecs += minstrel_mcs_groups[group].duration[rate];
|
||||
tp = 1000000 * ((mr->probability * 1000) / nsecs);
|
||||
tp = 1000000 * ((prob * 1000) / nsecs);
|
||||
|
||||
mr->cur_tp = MINSTREL_TRUNC(tp);
|
||||
}
|
||||
@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
if (!(mg->supported & BIT(i)))
|
||||
continue;
|
||||
|
||||
index = MCS_GROUP_RATES * group + i;
|
||||
|
||||
/* initialize rates selections starting indexes */
|
||||
if (!mg_rates_valid) {
|
||||
mg->max_tp_rate = mg->max_tp_rate2 =
|
||||
mg->max_prob_rate = i;
|
||||
if (!mi_rates_valid) {
|
||||
mi->max_tp_rate = mi->max_tp_rate2 =
|
||||
mi->max_prob_rate = i;
|
||||
mi->max_prob_rate = index;
|
||||
mi_rates_valid = true;
|
||||
}
|
||||
mg_rates_valid = true;
|
||||
@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
|
||||
mr = &mg->rates[i];
|
||||
mr->retry_updated = false;
|
||||
index = MCS_GROUP_RATES * group + i;
|
||||
minstrel_calc_rate_ewma(mr);
|
||||
minstrel_ht_calc_tp(mi, group, i);
|
||||
|
||||
|
@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
|
||||
u16 sc;
|
||||
u8 tid, ack_policy;
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control) ||
|
||||
is_multicast_ether_addr(hdr->addr1))
|
||||
goto dont_reorder;
|
||||
|
||||
/*
|
||||
|
@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
|
||||
|
||||
trace_api_sched_scan_stopped(local);
|
||||
|
||||
ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
|
||||
schedule_work(&local->sched_scan_stopped_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
|
||||
|
@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
if (elems->mesh_chansw_params_ie) {
|
||||
csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
|
||||
csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
|
||||
csa_ie->pre_value = le16_to_cpu(
|
||||
elems->mesh_chansw_params_ie->mesh_pre_value);
|
||||
}
|
||||
|
||||
new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
|
||||
|
@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_local *local =
|
||||
container_of(work, struct ieee80211_local, radar_detected_work);
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct cfg80211_chan_def chandef = local->hw.conf.chandef;
|
||||
|
||||
ieee80211_dfs_cac_cancel(local);
|
||||
|
||||
if (local->use_chanctx)
|
||||
/* currently not handled */
|
||||
WARN_ON(1);
|
||||
else {
|
||||
chandef = local->hw.conf.chandef;
|
||||
else
|
||||
cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_radar_detected(struct ieee80211_hw *hw)
|
||||
@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
|
||||
WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
|
||||
put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
|
||||
pos += 2;
|
||||
if (!ifmsh->pre_value)
|
||||
ifmsh->pre_value = 1;
|
||||
else
|
||||
ifmsh->pre_value++;
|
||||
pre_value = cpu_to_le16(ifmsh->pre_value);
|
||||
memcpy(pos, &pre_value, 2); /* Precedence Value */
|
||||
pos += 2;
|
||||
ifmsh->chsw_init = true;
|
||||
}
|
||||
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
|
@ -451,6 +451,15 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
int i;
|
||||
u16 ifmodes = wiphy->interface_modes;
|
||||
|
||||
/* support for 5/10 MHz is broken due to nl80211 API mess - disable */
|
||||
wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
|
||||
|
||||
/*
|
||||
* There are major locking problems in nl80211/mac80211 for CSA,
|
||||
* disable for all drivers until this has been reworked.
|
||||
*/
|
||||
wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (WARN_ON(wiphy->wowlan &&
|
||||
(wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
|
||||
|
@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
|
||||
|
||||
/* try to find an IBSS channel if none requested ... */
|
||||
if (!wdev->wext.ibss.chandef.chan) {
|
||||
wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
struct ieee80211_channel *new_chan = NULL;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
struct ieee80211_supported_band *sband;
|
||||
@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
|
||||
continue;
|
||||
if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
wdev->wext.ibss.chandef.chan = chan;
|
||||
wdev->wext.ibss.chandef.center_freq1 =
|
||||
chan->center_freq;
|
||||
new_chan = chan;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wdev->wext.ibss.chandef.chan)
|
||||
if (new_chan)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!wdev->wext.ibss.chandef.chan)
|
||||
if (!new_chan)
|
||||
return -EINVAL;
|
||||
|
||||
cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan,
|
||||
NL80211_CHAN_NO_HT);
|
||||
}
|
||||
|
||||
/* don't join -- SSID is not there */
|
||||
@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
|
||||
return err;
|
||||
|
||||
if (chan) {
|
||||
wdev->wext.ibss.chandef.chan = chan;
|
||||
wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
wdev->wext.ibss.chandef.center_freq1 = freq;
|
||||
cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan,
|
||||
NL80211_CHAN_NO_HT);
|
||||
wdev->wext.ibss.channel_fixed = true;
|
||||
} else {
|
||||
/* cfg80211_ibss_wext_join will pick one if needed */
|
||||
|
@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
|
||||
hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
|
||||
NL80211_CMD_NEW_KEY);
|
||||
if (!hdr)
|
||||
return -ENOBUFS;
|
||||
goto nla_put_failure;
|
||||
|
||||
cookie.msg = msg;
|
||||
cookie.idx = key_idx;
|
||||
@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
err = ieee80211_get_ratemask(wiphy->bands[band],
|
||||
nla_data(attr),
|
||||
nla_len(attr),
|
||||
@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
|
||||
nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (req->flags)
|
||||
nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags);
|
||||
if (req->flags &&
|
||||
nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
|
||||
goto nla_put_failure;
|
||||
|
||||
return 0;
|
||||
nla_put_failure:
|
||||
@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
|
||||
struct nlattr *reasons;
|
||||
|
||||
reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
|
||||
if (!reasons)
|
||||
goto free_msg;
|
||||
|
||||
if (wakeup->disconnect &&
|
||||
nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
|
||||
@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
|
||||
wakeup->pattern_idx))
|
||||
goto free_msg;
|
||||
|
||||
if (wakeup->tcp_match)
|
||||
nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
|
||||
if (wakeup->tcp_match &&
|
||||
nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
|
||||
goto free_msg;
|
||||
|
||||
if (wakeup->tcp_connlost)
|
||||
nla_put_flag(msg,
|
||||
NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
|
||||
if (wakeup->tcp_connlost &&
|
||||
nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
|
||||
goto free_msg;
|
||||
|
||||
if (wakeup->tcp_nomoretokens)
|
||||
nla_put_flag(msg,
|
||||
NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
|
||||
if (wakeup->tcp_nomoretokens &&
|
||||
nla_put_flag(msg,
|
||||
NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
|
||||
goto free_msg;
|
||||
|
||||
if (wakeup->packet) {
|
||||
u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
|
||||
@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev,
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
}
|
||||
if (!hdr)
|
||||
goto out;
|
||||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
|
||||
if (ft_event->ies)
|
||||
nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
|
||||
if (ft_event->ric_ies)
|
||||
nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
|
||||
ft_event->ric_ies);
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
|
||||
goto out;
|
||||
|
||||
if (ft_event->ies &&
|
||||
nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
|
||||
goto out;
|
||||
if (ft_event->ric_ies &&
|
||||
nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
|
||||
ft_event->ric_ies))
|
||||
goto out;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
||||
NL80211_MCGRP_MLME, GFP_KERNEL);
|
||||
return;
|
||||
out:
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ft_event);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user