Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

This commit is contained in:
John W. Linville 2013-08-09 15:06:28 -04:00
commit 4f05444892
38 changed files with 246 additions and 148 deletions

View file

@ -8272,7 +8272,7 @@ S: Maintained
F: sound/soc/codecs/twl4030* F: sound/soc/codecs/twl4030*
TI WILINK WIRELESS DRIVERS TI WILINK WIRELESS DRIVERS
M: Luciano Coelho <coelho@ti.com> M: Luciano Coelho <luca@coelho.fi>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/wl12xx W: http://wireless.kernel.org/en/users/Drivers/wl12xx
W: http://wireless.kernel.org/en/users/Drivers/wl1251 W: http://wireless.kernel.org/en/users/Drivers/wl1251

View file

@ -91,6 +91,10 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0489, 0xe04e) }, { USB_DEVICE(0x0489, 0xe04e) },
{ USB_DEVICE(0x0489, 0xe056) }, { USB_DEVICE(0x0489, 0xe056) },
{ USB_DEVICE(0x0489, 0xe04d) }, { USB_DEVICE(0x0489, 0xe04d) },
{ USB_DEVICE(0x04c5, 0x1330) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x0cf3, 0x3121) },
{ USB_DEVICE(0x0cf3, 0xe003) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) },
@ -128,6 +132,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
@ -193,24 +201,44 @@ error:
static int ath3k_get_state(struct usb_device *udev, unsigned char *state) static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
{ {
int pipe = 0; int ret, pipe = 0;
char *buf;
buf = kmalloc(sizeof(*buf), GFP_KERNEL);
if (!buf)
return -ENOMEM;
pipe = usb_rcvctrlpipe(udev, 0); pipe = usb_rcvctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, ATH3K_GETSTATE, ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
state, 0x01, USB_CTRL_SET_TIMEOUT); buf, sizeof(*buf), USB_CTRL_SET_TIMEOUT);
*state = *buf;
kfree(buf);
return ret;
} }
static int ath3k_get_version(struct usb_device *udev, static int ath3k_get_version(struct usb_device *udev,
struct ath3k_version *version) struct ath3k_version *version)
{ {
int pipe = 0; int ret, pipe = 0;
struct ath3k_version *buf;
const int size = sizeof(*buf);
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
pipe = usb_rcvctrlpipe(udev, 0); pipe = usb_rcvctrlpipe(udev, 0);
return usb_control_msg(udev, pipe, ATH3K_GETVERSION, ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
sizeof(struct ath3k_version), buf, size, USB_CTRL_SET_TIMEOUT);
USB_CTRL_SET_TIMEOUT);
memcpy(version, buf, size);
kfree(buf);
return ret;
} }
static int ath3k_load_fwfile(struct usb_device *udev, static int ath3k_load_fwfile(struct usb_device *udev,

View file

@ -154,6 +154,10 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@ -1095,7 +1099,7 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)", BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
hdev->name, cmd->opcode, PTR_ERR(skb)); hdev->name, cmd->opcode, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
/* It ensures that the returned event matches the event data read from /* It ensures that the returned event matches the event data read from
@ -1147,7 +1151,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s sending initial HCI reset command failed (%ld)", BT_ERR("%s sending initial HCI reset command failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
kfree_skb(skb); kfree_skb(skb);
@ -1161,7 +1165,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s reading Intel fw version command failed (%ld)", BT_ERR("%s reading Intel fw version command failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
if (skb->len != sizeof(*ver)) { if (skb->len != sizeof(*ver)) {
@ -1219,7 +1223,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_ERR("%s entering Intel manufacturer mode failed (%ld)", BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
release_firmware(fw); release_firmware(fw);
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
if (skb->data[0]) { if (skb->data[0]) {
@ -1276,7 +1280,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
kfree_skb(skb); kfree_skb(skb);
@ -1292,7 +1296,7 @@ exit_mfg_disable:
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
kfree_skb(skb); kfree_skb(skb);
@ -1310,7 +1314,7 @@ exit_mfg_deactivate:
if (IS_ERR(skb)) { if (IS_ERR(skb)) {
BT_ERR("%s exiting Intel manufacturer mode failed (%ld)", BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
hdev->name, PTR_ERR(skb)); hdev->name, PTR_ERR(skb));
return -PTR_ERR(skb); return PTR_ERR(skb);
} }
kfree_skb(skb); kfree_skb(skb);

View file

@ -1,6 +1,6 @@
config ATH10K config ATH10K
tristate "Atheros 802.11ac wireless cards support" tristate "Atheros 802.11ac wireless cards support"
depends on MAC80211 depends on MAC80211 && HAS_DMA
select ATH_COMMON select ATH_COMMON
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on

View file

@ -1093,8 +1093,11 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n "); brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
err = brcmf_fil_cmd_data_set(vif->ifp, err = brcmf_fil_cmd_data_set(vif->ifp,
BRCMF_C_DISASSOC, NULL, 0); BRCMF_C_DISASSOC, NULL, 0);
if (err) if (err) {
brcmf_err("WLC_DISASSOC failed (%d)\n", err); brcmf_err("WLC_DISASSOC failed (%d)\n", err);
cfg80211_disconnected(vif->wdev.netdev, 0,
NULL, 0, GFP_KERNEL);
}
clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
} }
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);

View file

@ -1406,11 +1406,8 @@ static void cw1200_do_unjoin(struct cw1200_common *priv)
if (!priv->join_status) if (!priv->join_status)
goto done; goto done;
if (priv->join_status > CW1200_JOIN_STATUS_IBSS) { if (priv->join_status == CW1200_JOIN_STATUS_AP)
wiphy_err(priv->hw->wiphy, "Unexpected: join status: %d\n", goto done;
priv->join_status);
BUG_ON(1);
}
cancel_work_sync(&priv->update_filtering_work); cancel_work_sync(&priv->update_filtering_work);
cancel_work_sync(&priv->set_beacon_wakeup_period_work); cancel_work_sync(&priv->set_beacon_wakeup_period_work);

View file

@ -4466,12 +4466,12 @@ il4965_irq_tasklet(struct il_priv *il)
* is killed. Hence update the killswitch state here. The * is killed. Hence update the killswitch state here. The
* rfkill handler will care about restarting if needed. * rfkill handler will care about restarting if needed.
*/ */
if (!test_bit(S_ALIVE, &il->status)) { if (hw_rf_kill) {
if (hw_rf_kill) set_bit(S_RFKILL, &il->status);
set_bit(S_RFKILL, &il->status); } else {
else clear_bit(S_RFKILL, &il->status);
clear_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
il_force_reset(il, true);
} }
handled |= CSR_INT_BIT_RF_KILL; handled |= CSR_INT_BIT_RF_KILL;
@ -5340,6 +5340,9 @@ il4965_alive_start(struct il_priv *il)
il->active_rate = RATES_MASK; il->active_rate = RATES_MASK;
il_power_update_mode(il, true);
D_INFO("Updated power mode\n");
if (il_is_associated(il)) { if (il_is_associated(il)) {
struct il_rxon_cmd *active_rxon = struct il_rxon_cmd *active_rxon =
(struct il_rxon_cmd *)&il->active; (struct il_rxon_cmd *)&il->active;
@ -5370,9 +5373,6 @@ il4965_alive_start(struct il_priv *il)
D_INFO("ALIVE processing complete.\n"); D_INFO("ALIVE processing complete.\n");
wake_up(&il->wait_command_queue); wake_up(&il->wait_command_queue);
il_power_update_mode(il, true);
D_INFO("Updated power mode\n");
return; return;
restart: restart:

View file

@ -4660,6 +4660,7 @@ il_force_reset(struct il_priv *il, bool external)
return 0; return 0;
} }
EXPORT_SYMBOL(il_force_reset);
int int
il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,

View file

@ -97,6 +97,8 @@
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
/* Device system time */ /* Device system time */
#define DEVICE_SYSTEM_TIME_REG 0xA0206C #define DEVICE_SYSTEM_TIME_REG 0xA0206C

View file

@ -134,7 +134,7 @@ struct wowlan_key_data {
struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc; struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
struct iwl_wowlan_tkip_params_cmd *tkip; struct iwl_wowlan_tkip_params_cmd *tkip;
bool error, use_rsc_tsc, use_tkip; bool error, use_rsc_tsc, use_tkip;
int gtk_key_idx; int wep_key_idx;
}; };
static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
@ -188,8 +188,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
wkc.wep_key.key_offset = 0; wkc.wep_key.key_offset = 0;
} else { } else {
/* others start at 1 */ /* others start at 1 */
data->gtk_key_idx++; data->wep_key_idx++;
wkc.wep_key.key_offset = data->gtk_key_idx; wkc.wep_key.key_offset = data->wep_key_idx;
} }
ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC, ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
@ -316,8 +316,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
mvm->ptk_ivlen = key->iv_len; mvm->ptk_ivlen = key->iv_len;
mvm->ptk_icvlen = key->icv_len; mvm->ptk_icvlen = key->icv_len;
} else { } else {
data->gtk_key_idx++; /*
key->hw_key_idx = data->gtk_key_idx; * firmware only supports TSC/RSC for a single key,
* so if there are multiple keep overwriting them
* with new ones -- this relies on mac80211 doing
* list_add_tail().
*/
key->hw_key_idx = 1;
mvm->gtk_ivlen = key->iv_len; mvm->gtk_ivlen = key->iv_len;
mvm->gtk_icvlen = key->icv_len; mvm->gtk_icvlen = key->icv_len;
} }

View file

@ -69,7 +69,6 @@
/* Scan Commands, Responses, Notifications */ /* Scan Commands, Responses, Notifications */
/* Masks for iwl_scan_channel.type flags */ /* Masks for iwl_scan_channel.type flags */
#define SCAN_CHANNEL_TYPE_PASSIVE 0
#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0) #define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
#define SCAN_CHANNEL_NARROW_BAND BIT(22) #define SCAN_CHANNEL_NARROW_BAND BIT(22)

View file

@ -513,6 +513,27 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
if (ret) if (ret)
goto out_unlock; goto out_unlock;
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single MAC.
* If new interface added, disable PM on existing interface.
* P2P device is a special case, since it is handled by FW similary to
* scan. If P2P deviced is added, PM remains enabled on existing
* interface.
* Note: the method below does not count the new interface being added
* at this moment.
*/
if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
mvm->vif_count++;
if (mvm->vif_count > 1) {
IWL_DEBUG_MAC80211(mvm,
"Disable power on existing interfaces\n");
ieee80211_iterate_active_interfaces_atomic(
mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_pm_disable_iterator, mvm);
}
/* /*
* The AP binding flow can be done only after the beacon * The AP binding flow can be done only after the beacon
* template is configured (which happens only in the mac80211 * template is configured (which happens only in the mac80211
@ -537,27 +558,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
goto out_unlock; goto out_unlock;
} }
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single MAC.
* If new interface added, disable PM on existing interface.
* P2P device is a special case, since it is handled by FW similary to
* scan. If P2P deviced is added, PM remains enabled on existing
* interface.
* Note: the method below does not count the new interface being added
* at this moment.
*/
if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
mvm->vif_count++;
if (mvm->vif_count > 1) {
IWL_DEBUG_MAC80211(mvm,
"Disable power on existing interfaces\n");
ieee80211_iterate_active_interfaces_atomic(
mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_pm_disable_iterator, mvm);
}
ret = iwl_mvm_mac_ctxt_add(mvm, vif); ret = iwl_mvm_mac_ctxt_add(mvm, vif);
if (ret) if (ret)
goto out_release; goto out_release;

View file

@ -178,19 +178,12 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
struct iwl_scan_channel *chan = (struct iwl_scan_channel *) struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
(cmd->data + le16_to_cpu(cmd->tx_cmd.len)); (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
int i; int i;
__le32 chan_type_value;
if (req->n_ssids > 0)
chan_type_value = cpu_to_le32(BIT(req->n_ssids) - 1);
else
chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
for (i = 0; i < cmd->channel_count; i++) { for (i = 0; i < cmd->channel_count; i++) {
chan->channel = cpu_to_le16(req->channels[i]->hw_value); chan->channel = cpu_to_le16(req->channels[i]->hw_value);
chan->type = cpu_to_le32(BIT(req->n_ssids) - 1);
if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
chan->type = SCAN_CHANNEL_TYPE_PASSIVE; chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
else
chan->type = chan_type_value;
chan->active_dwell = cpu_to_le16(active_dwell); chan->active_dwell = cpu_to_le16(active_dwell);
chan->passive_dwell = cpu_to_le16(passive_dwell); chan->passive_dwell = cpu_to_le16(passive_dwell);
chan->iteration_count = cpu_to_le16(1); chan->iteration_count = cpu_to_le16(1);

View file

@ -914,6 +914,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
u16 txq_id; u16 txq_id;
enum iwl_mvm_agg_state old_state;
/* /*
* First set the agg state to OFF to avoid calling * First set the agg state to OFF to avoid calling
@ -923,13 +924,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
txq_id = tid_data->txq_id; txq_id = tid_data->txq_id;
IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
mvmsta->sta_id, tid, txq_id, tid_data->state); mvmsta->sta_id, tid, txq_id, tid_data->state);
old_state = tid_data->state;
tid_data->state = IWL_AGG_OFF; tid_data->state = IWL_AGG_OFF;
spin_unlock_bh(&mvmsta->lock); spin_unlock_bh(&mvmsta->lock);
if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) if (old_state >= IWL_AGG_ON) {
IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
}
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
mvm->queue_to_mac80211[tid_data->txq_id] = mvm->queue_to_mac80211[tid_data->txq_id] =
IWL_INVALID_MAC80211_QUEUE; IWL_INVALID_MAC80211_QUEUE;

View file

@ -130,6 +130,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
{IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */ {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
{IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
{IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
{IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */ {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
{IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */

View file

@ -888,6 +888,14 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
if (hw_rfkill) { if (hw_rfkill) {
/*
* Clear the interrupt in APMG if the NIC is going down.
* Note that when the NIC exits RFkill (else branch), we
* can't access prph and the NIC will be reset in
* start_hw anyway.
*/
iwl_write_prph(trans, APMG_RTC_INT_STT_REG,
APMG_RTC_INT_STT_RFKILL);
set_bit(STATUS_RFKILL, &trans_pcie->status); set_bit(STATUS_RFKILL, &trans_pcie->status);
if (test_and_clear_bit(STATUS_HCMD_ACTIVE, if (test_and_clear_bit(STATUS_HCMD_ACTIVE,
&trans_pcie->status)) &trans_pcie->status))

View file

@ -670,6 +670,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
return err; return err;
} }
/* Reset the entire device */
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
usleep_range(10, 15);
iwl_pcie_apm_init(trans); iwl_pcie_apm_init(trans);
/* From now on, the op_mode will be kept updated about RF kill state */ /* From now on, the op_mode will be kept updated about RF kill state */

View file

@ -1727,9 +1727,9 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int ret; int ret;
if (priv->bss_mode != NL80211_IFTYPE_STATION) { if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
wiphy_err(wiphy, wiphy_err(wiphy,
"%s: reject infra assoc request in non-STA mode\n", "%s: reject infra assoc request in non-STA role\n",
dev->name); dev->name);
return -EINVAL; return -EINVAL;
} }

View file

@ -447,7 +447,8 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
u32 k = 0; u32 k = 0;
struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_adapter *adapter = priv->adapter;
if (priv->bss_mode == NL80211_IFTYPE_STATION) { if (priv->bss_mode == NL80211_IFTYPE_STATION ||
priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
switch (adapter->config_bands) { switch (adapter->config_bands) {
case BAND_B: case BAND_B:
dev_dbg(adapter->dev, "info: infra band=%d " dev_dbg(adapter->dev, "info: infra band=%d "

View file

@ -1291,8 +1291,10 @@ int mwifiex_associate(struct mwifiex_private *priv,
{ {
u8 current_bssid[ETH_ALEN]; u8 current_bssid[ETH_ALEN];
/* Return error if the adapter or table entry is not marked as infra */ /* Return error if the adapter is not STA role or table entry
if ((priv->bss_mode != NL80211_IFTYPE_STATION) || * is not marked as infra.
*/
if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
(bss_desc->bss_mode != NL80211_IFTYPE_STATION)) (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
return -1; return -1;

View file

@ -1636,8 +1636,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
/* Allocate buffer and copy payload */ /* Allocate buffer and copy payload */
blk_size = MWIFIEX_SDIO_BLOCK_SIZE; blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
buf_block_len = (pkt_len + blk_size - 1) / blk_size; buf_block_len = (pkt_len + blk_size - 1) / blk_size;
*(u16 *) &payload[0] = (u16) pkt_len; *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
*(u16 *) &payload[2] = type; *(__le16 *)&payload[2] = cpu_to_le16(type);
/* /*
* This is SDIO specific header * This is SDIO specific header

View file

@ -257,10 +257,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
goto done; goto done;
} }
if (priv->bss_mode == NL80211_IFTYPE_STATION) { if (priv->bss_mode == NL80211_IFTYPE_STATION ||
priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
u8 config_bands; u8 config_bands;
/* Infra mode */
ret = mwifiex_deauthenticate(priv, NULL); ret = mwifiex_deauthenticate(priv, NULL);
if (ret) if (ret)
goto done; goto done;

View file

@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
spin_unlock_irqrestore(&queue->index_lock, irqflags); spin_unlock_irqrestore(&queue->index_lock, irqflags);
} }
void rt2x00queue_pause_queue(struct data_queue *queue) void rt2x00queue_pause_queue_nocheck(struct data_queue *queue)
{ {
if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
!test_bit(QUEUE_STARTED, &queue->flags) ||
test_and_set_bit(QUEUE_PAUSED, &queue->flags))
return;
switch (queue->qid) { switch (queue->qid) {
case QID_AC_VO: case QID_AC_VO:
case QID_AC_VI: case QID_AC_VI:
@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue)
break; break;
} }
} }
void rt2x00queue_pause_queue(struct data_queue *queue)
{
if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
!test_bit(QUEUE_STARTED, &queue->flags) ||
test_and_set_bit(QUEUE_PAUSED, &queue->flags))
return;
rt2x00queue_pause_queue_nocheck(queue);
}
EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
void rt2x00queue_unpause_queue(struct data_queue *queue) void rt2x00queue_unpause_queue(struct data_queue *queue)
@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue)
return; return;
} }
rt2x00queue_pause_queue(queue); rt2x00queue_pause_queue_nocheck(queue);
queue->rt2x00dev->ops->lib->stop_queue(queue); queue->rt2x00dev->ops->lib->stop_queue(queue);

View file

@ -59,7 +59,7 @@ struct nfc_hci_ops {
struct nfc_target *target); struct nfc_target *target);
int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
struct sk_buff *skb); struct sk_buff *skb);
int (*fw_upload)(struct nfc_hci_dev *hdev, const char *firmware_name); int (*fw_download)(struct nfc_hci_dev *hdev, const char *firmware_name);
int (*discover_se)(struct nfc_hci_dev *dev); int (*discover_se)(struct nfc_hci_dev *dev);
int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx); int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx);
int (*disable_se)(struct nfc_hci_dev *dev, u32 se_idx); int (*disable_se)(struct nfc_hci_dev *dev, u32 se_idx);

View file

@ -68,7 +68,7 @@ struct nfc_ops {
void *cb_context); void *cb_context);
int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb); int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);
int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target); int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target);
int (*fw_upload)(struct nfc_dev *dev, const char *firmware_name); int (*fw_download)(struct nfc_dev *dev, const char *firmware_name);
/* Secure Element API */ /* Secure Element API */
int (*discover_se)(struct nfc_dev *dev); int (*discover_se)(struct nfc_dev *dev);
@ -127,7 +127,7 @@ struct nfc_dev {
int targets_generation; int targets_generation;
struct device dev; struct device dev;
bool dev_up; bool dev_up;
bool fw_upload_in_progress; bool fw_download_in_progress;
u8 rf_mode; u8 rf_mode;
bool polling; bool polling;
struct nfc_target *active_target; struct nfc_target *active_target;

View file

@ -69,8 +69,8 @@
* starting a poll from a device which has a secure element enabled means * starting a poll from a device which has a secure element enabled means
* we want to do SE based card emulation. * we want to do SE based card emulation.
* @NFC_CMD_DISABLE_SE: Disable the physical link to a specific secure element. * @NFC_CMD_DISABLE_SE: Disable the physical link to a specific secure element.
* @NFC_CMD_FW_UPLOAD: Request to Load/flash firmware, or event to inform that * @NFC_CMD_FW_DOWNLOAD: Request to Load/flash firmware, or event to inform
* some firmware was loaded * that some firmware was loaded
*/ */
enum nfc_commands { enum nfc_commands {
NFC_CMD_UNSPEC, NFC_CMD_UNSPEC,
@ -94,7 +94,7 @@ enum nfc_commands {
NFC_CMD_DISABLE_SE, NFC_CMD_DISABLE_SE,
NFC_CMD_LLC_SDREQ, NFC_CMD_LLC_SDREQ,
NFC_EVENT_LLC_SDRES, NFC_EVENT_LLC_SDRES,
NFC_CMD_FW_UPLOAD, NFC_CMD_FW_DOWNLOAD,
NFC_EVENT_SE_ADDED, NFC_EVENT_SE_ADDED,
NFC_EVENT_SE_REMOVED, NFC_EVENT_SE_REMOVED,
/* private: internal use only */ /* private: internal use only */

View file

@ -513,7 +513,10 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
hci_setup_event_mask(req); hci_setup_event_mask(req);
if (hdev->hci_ver > BLUETOOTH_VER_1_1) /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
* local supported commands HCI command.
*/
if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
if (lmp_ssp_capable(hdev)) { if (lmp_ssp_capable(hdev)) {
@ -2165,10 +2168,6 @@ int hci_register_dev(struct hci_dev *hdev)
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
write_lock(&hci_dev_list_lock);
list_add(&hdev->list, &hci_dev_list);
write_unlock(&hci_dev_list_lock);
hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND | hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
WQ_MEM_RECLAIM, 1, hdev->name); WQ_MEM_RECLAIM, 1, hdev->name);
if (!hdev->workqueue) { if (!hdev->workqueue) {
@ -2203,6 +2202,10 @@ int hci_register_dev(struct hci_dev *hdev)
if (hdev->dev_type != HCI_AMP) if (hdev->dev_type != HCI_AMP)
set_bit(HCI_AUTO_OFF, &hdev->dev_flags); set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
write_lock(&hci_dev_list_lock);
list_add(&hdev->list, &hci_dev_list);
write_unlock(&hci_dev_list_lock);
hci_notify(hdev, HCI_DEV_REG); hci_notify(hdev, HCI_DEV_REG);
hci_dev_hold(hdev); hci_dev_hold(hdev);
@ -2215,9 +2218,6 @@ err_wqueue:
destroy_workqueue(hdev->req_workqueue); destroy_workqueue(hdev->req_workqueue);
err: err:
ida_simple_remove(&hci_index_ida, hdev->id); ida_simple_remove(&hci_index_ida, hdev->id);
write_lock(&hci_dev_list_lock);
list_del(&hdev->list);
write_unlock(&hci_dev_list_lock);
return error; return error;
} }
@ -3399,8 +3399,16 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
*/ */
if (hdev->sent_cmd) { if (hdev->sent_cmd) {
req_complete = bt_cb(hdev->sent_cmd)->req.complete; req_complete = bt_cb(hdev->sent_cmd)->req.complete;
if (req_complete)
if (req_complete) {
/* We must set the complete callback to NULL to
* avoid calling the callback more than once if
* this function gets called again.
*/
bt_cb(hdev->sent_cmd)->req.complete = NULL;
goto call_complete; goto call_complete;
}
} }
/* Remove all pending commands belonging to this request */ /* Remove all pending commands belonging to this request */

View file

@ -229,6 +229,10 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta)
enum nl80211_mesh_power_mode pm; enum nl80211_mesh_power_mode pm;
bool do_buffer; bool do_buffer;
/* For non-assoc STA, prevent buffering or frame transmission */
if (sta->sta_state < IEEE80211_STA_ASSOC)
return;
/* /*
* use peer-specific power mode if peering is established and the * use peer-specific power mode if peering is established and the
* peer's power mode is known * peer's power mode is known

View file

@ -31,10 +31,12 @@
#include "led.h" #include "led.h"
#define IEEE80211_AUTH_TIMEOUT (HZ / 5) #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2)
#define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10) #define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10)
#define IEEE80211_AUTH_MAX_TRIES 3 #define IEEE80211_AUTH_MAX_TRIES 3
#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) #define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_TIMEOUT_LONG (HZ / 2)
#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10) #define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
#define IEEE80211_ASSOC_MAX_TRIES 3 #define IEEE80211_ASSOC_MAX_TRIES 3
@ -209,8 +211,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *channel, struct ieee80211_channel *channel,
const struct ieee80211_ht_operation *ht_oper, const struct ieee80211_ht_operation *ht_oper,
const struct ieee80211_vht_operation *vht_oper, const struct ieee80211_vht_operation *vht_oper,
struct cfg80211_chan_def *chandef, bool verbose) struct cfg80211_chan_def *chandef, bool tracking)
{ {
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct cfg80211_chan_def vht_chandef; struct cfg80211_chan_def vht_chandef;
u32 ht_cfreq, ret; u32 ht_cfreq, ret;
@ -229,7 +232,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
channel->band); channel->band);
/* check that channel matches the right operating channel */ /* check that channel matches the right operating channel */
if (channel->center_freq != ht_cfreq) { if (!tracking && channel->center_freq != ht_cfreq) {
/* /*
* It's possible that some APs are confused here; * It's possible that some APs are confused here;
* Netgear WNDR3700 sometimes reports 4 higher than * Netgear WNDR3700 sometimes reports 4 higher than
@ -237,11 +240,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
* since we look at probe response/beacon data here * since we look at probe response/beacon data here
* it should be OK. * it should be OK.
*/ */
if (verbose) sdata_info(sdata,
sdata_info(sdata, "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
"Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", channel->center_freq, ht_cfreq,
channel->center_freq, ht_cfreq, ht_oper->primary_chan, channel->band);
ht_oper->primary_chan, channel->band);
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
goto out; goto out;
} }
@ -295,7 +297,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
channel->band); channel->band);
break; break;
default: default:
if (verbose) if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
sdata_info(sdata, sdata_info(sdata,
"AP VHT operation IE has invalid channel width (%d), disable VHT\n", "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
vht_oper->chan_width); vht_oper->chan_width);
@ -304,7 +306,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
} }
if (!cfg80211_chandef_valid(&vht_chandef)) { if (!cfg80211_chandef_valid(&vht_chandef)) {
if (verbose) if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
sdata_info(sdata, sdata_info(sdata,
"AP VHT information is invalid, disable VHT\n"); "AP VHT information is invalid, disable VHT\n");
ret = IEEE80211_STA_DISABLE_VHT; ret = IEEE80211_STA_DISABLE_VHT;
@ -317,7 +319,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
} }
if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) { if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
if (verbose) if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
sdata_info(sdata, sdata_info(sdata,
"AP VHT information doesn't match HT, disable VHT\n"); "AP VHT information doesn't match HT, disable VHT\n");
ret = IEEE80211_STA_DISABLE_VHT; ret = IEEE80211_STA_DISABLE_VHT;
@ -333,18 +335,27 @@ out:
if (ret & IEEE80211_STA_DISABLE_VHT) if (ret & IEEE80211_STA_DISABLE_VHT)
vht_chandef = *chandef; vht_chandef = *chandef;
/*
* Ignore the DISABLED flag when we're already connected and only
* tracking the APs beacon for bandwidth changes - otherwise we
* might get disconnected here if we connect to an AP, update our
* regulatory information based on the AP's country IE and the
* information we have is wrong/outdated and disables the channel
* that we're actually using for the connection to the AP.
*/
while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
IEEE80211_CHAN_DISABLED)) { tracking ? 0 :
IEEE80211_CHAN_DISABLED)) {
if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) { if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
ret = IEEE80211_STA_DISABLE_HT | ret = IEEE80211_STA_DISABLE_HT |
IEEE80211_STA_DISABLE_VHT; IEEE80211_STA_DISABLE_VHT;
goto out; break;
} }
ret |= chandef_downgrade(chandef); ret |= chandef_downgrade(chandef);
} }
if (chandef->width != vht_chandef.width && verbose) if (chandef->width != vht_chandef.width && !tracking)
sdata_info(sdata, sdata_info(sdata,
"capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n"); "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
@ -384,7 +395,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
/* calculate new channel (type) based on HT/VHT operation IEs */ /* calculate new channel (type) based on HT/VHT operation IEs */
flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper, flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper,
vht_oper, &chandef, false); vht_oper, &chandef, true);
/* /*
* Downgrade the new channel if we associated with restricted * Downgrade the new channel if we associated with restricted
@ -3395,10 +3406,13 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
if (tx_flags == 0) { if (tx_flags == 0) {
auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
ifmgd->auth_data->timeout_started = true; auth_data->timeout_started = true;
run_again(sdata, auth_data->timeout); run_again(sdata, auth_data->timeout);
} else { } else {
auth_data->timeout_started = false; auth_data->timeout =
round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG);
auth_data->timeout_started = true;
run_again(sdata, auth_data->timeout);
} }
return 0; return 0;
@ -3435,7 +3449,11 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
assoc_data->timeout_started = true; assoc_data->timeout_started = true;
run_again(sdata, assoc_data->timeout); run_again(sdata, assoc_data->timeout);
} else { } else {
assoc_data->timeout_started = false; assoc_data->timeout =
round_jiffies_up(jiffies +
IEEE80211_ASSOC_TIMEOUT_LONG);
assoc_data->timeout_started = true;
run_again(sdata, assoc_data->timeout);
} }
return 0; return 0;
@ -3830,7 +3848,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
cbss->channel, cbss->channel,
ht_oper, vht_oper, ht_oper, vht_oper,
&chandef, true); &chandef, false);
sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
local->rx_chains); local->rx_chains);

View file

@ -99,10 +99,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
} }
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
/* remove all interfaces */ /* remove all interfaces that were created in the driver */
list_for_each_entry(sdata, &local->interfaces, list) { list_for_each_entry(sdata, &local->interfaces, list) {
if (!ieee80211_sdata_running(sdata)) if (!ieee80211_sdata_running(sdata) ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
sdata->vif.type == NL80211_IFTYPE_MONITOR)
continue; continue;
drv_remove_interface(local, sdata); drv_remove_interface(local, sdata);
} }

View file

@ -44,7 +44,7 @@ DEFINE_MUTEX(nfc_devlist_mutex);
/* NFC device ID bitmap */ /* NFC device ID bitmap */
static DEFINE_IDA(nfc_index_ida); static DEFINE_IDA(nfc_index_ida);
int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name) int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name)
{ {
int rc = 0; int rc = 0;
@ -62,28 +62,28 @@ int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name)
goto error; goto error;
} }
if (!dev->ops->fw_upload) { if (!dev->ops->fw_download) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto error; goto error;
} }
dev->fw_upload_in_progress = true; dev->fw_download_in_progress = true;
rc = dev->ops->fw_upload(dev, firmware_name); rc = dev->ops->fw_download(dev, firmware_name);
if (rc) if (rc)
dev->fw_upload_in_progress = false; dev->fw_download_in_progress = false;
error: error:
device_unlock(&dev->dev); device_unlock(&dev->dev);
return rc; return rc;
} }
int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name) int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
{ {
dev->fw_upload_in_progress = false; dev->fw_download_in_progress = false;
return nfc_genl_fw_upload_done(dev, firmware_name); return nfc_genl_fw_download_done(dev, firmware_name);
} }
EXPORT_SYMBOL(nfc_fw_upload_done); EXPORT_SYMBOL(nfc_fw_download_done);
/** /**
* nfc_dev_up - turn on the NFC device * nfc_dev_up - turn on the NFC device
@ -110,7 +110,7 @@ int nfc_dev_up(struct nfc_dev *dev)
goto error; goto error;
} }
if (dev->fw_upload_in_progress) { if (dev->fw_download_in_progress) {
rc = -EBUSY; rc = -EBUSY;
goto error; goto error;
} }

View file

@ -809,14 +809,14 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
} }
} }
static int hci_fw_upload(struct nfc_dev *nfc_dev, const char *firmware_name) static int hci_fw_download(struct nfc_dev *nfc_dev, const char *firmware_name)
{ {
struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
if (!hdev->ops->fw_upload) if (!hdev->ops->fw_download)
return -ENOTSUPP; return -ENOTSUPP;
return hdev->ops->fw_upload(hdev, firmware_name); return hdev->ops->fw_download(hdev, firmware_name);
} }
static struct nfc_ops hci_nfc_ops = { static struct nfc_ops hci_nfc_ops = {
@ -831,7 +831,7 @@ static struct nfc_ops hci_nfc_ops = {
.im_transceive = hci_transceive, .im_transceive = hci_transceive,
.tm_send = hci_tm_send, .tm_send = hci_tm_send,
.check_presence = hci_check_presence, .check_presence = hci_check_presence,
.fw_upload = hci_fw_upload, .fw_download = hci_fw_download,
.discover_se = hci_discover_se, .discover_se = hci_discover_se,
.enable_se = hci_enable_se, .enable_se = hci_enable_se,
.disable_se = hci_disable_se, .disable_se = hci_disable_se,

View file

@ -11,6 +11,7 @@ config NFC_NCI
config NFC_NCI_SPI config NFC_NCI_SPI
depends on NFC_NCI && SPI depends on NFC_NCI && SPI
select CRC_CCITT
bool "NCI over SPI protocol support" bool "NCI over SPI protocol support"
default n default n
help help

View file

@ -1089,7 +1089,7 @@ exit:
return rc; return rc;
} }
static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info) static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
{ {
struct nfc_dev *dev; struct nfc_dev *dev;
int rc; int rc;
@ -1108,13 +1108,13 @@ static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info)
nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME], nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
sizeof(firmware_name)); sizeof(firmware_name));
rc = nfc_fw_upload(dev, firmware_name); rc = nfc_fw_download(dev, firmware_name);
nfc_put_device(dev); nfc_put_device(dev);
return rc; return rc;
} }
int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name) int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
{ {
struct sk_buff *msg; struct sk_buff *msg;
void *hdr; void *hdr;
@ -1124,7 +1124,7 @@ int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
return -ENOMEM; return -ENOMEM;
hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
NFC_CMD_FW_UPLOAD); NFC_CMD_FW_DOWNLOAD);
if (!hdr) if (!hdr)
goto free_msg; goto free_msg;
@ -1251,8 +1251,8 @@ static struct genl_ops nfc_genl_ops[] = {
.policy = nfc_genl_policy, .policy = nfc_genl_policy,
}, },
{ {
.cmd = NFC_CMD_FW_UPLOAD, .cmd = NFC_CMD_FW_DOWNLOAD,
.doit = nfc_genl_fw_upload, .doit = nfc_genl_fw_download,
.policy = nfc_genl_policy, .policy = nfc_genl_policy,
}, },
{ {

View file

@ -123,10 +123,10 @@ static inline void nfc_device_iter_exit(struct class_dev_iter *iter)
class_dev_iter_exit(iter); class_dev_iter_exit(iter);
} }
int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name); int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name);
int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name); int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name); int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
int nfc_dev_up(struct nfc_dev *dev); int nfc_dev_up(struct nfc_dev *dev);

View file

@ -774,6 +774,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
cfg80211_leave_mesh(rdev, dev); cfg80211_leave_mesh(rdev, dev);
break; break;
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
cfg80211_stop_ap(rdev, dev); cfg80211_stop_ap(rdev, dev);
break; break;
default: default:

View file

@ -449,10 +449,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
goto out_unlock; goto out_unlock;
} }
*rdev = wiphy_to_dev((*wdev)->wiphy); *rdev = wiphy_to_dev((*wdev)->wiphy);
cb->args[0] = (*rdev)->wiphy_idx; /* 0 is the first index - add 1 to parse only once */
cb->args[0] = (*rdev)->wiphy_idx + 1;
cb->args[1] = (*wdev)->identifier; cb->args[1] = (*wdev)->identifier;
} else { } else {
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]); /* subtract the 1 again here */
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
struct wireless_dev *tmp; struct wireless_dev *tmp;
if (!wiphy) { if (!wiphy) {

View file

@ -2247,10 +2247,13 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
void wiphy_regulatory_register(struct wiphy *wiphy) void wiphy_regulatory_register(struct wiphy *wiphy)
{ {
struct regulatory_request *lr;
if (!reg_dev_ignore_cell_hint(wiphy)) if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++; reg_num_devs_support_basehint++;
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); lr = get_last_request();
wiphy_update_regulatory(wiphy, lr->initiator);
} }
void wiphy_regulatory_deregister(struct wiphy *wiphy) void wiphy_regulatory_deregister(struct wiphy *wiphy)