Commit cbe461c5 authored by Gustavo Padovan's avatar Gustavo Padovan

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Conflicts:
	net/bluetooth/hci_event.c
parents 1d0c4da8 1c2e0041
...@@ -139,7 +139,9 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc) ...@@ -139,7 +139,9 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
break; break;
case 0x4331: case 0x4331:
/* BCM4331 workaround is SPROM-related, we put it in sprom.c */ case 43431:
/* Ext PA lines must be enabled for tx on BCM4331 */
bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
break; break;
case 43224: case 43224:
if (bus->chipinfo.rev == 0) { if (bus->chipinfo.rev == 0) {
......
...@@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus) ...@@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus)
if (!sprom) if (!sprom)
return -ENOMEM; return -ENOMEM;
if (bus->chipinfo.id == 0x4331) if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
pr_debug("SPROM offset 0x%x\n", offset); pr_debug("SPROM offset 0x%x\n", offset);
bcma_sprom_read(bus, offset, sprom); bcma_sprom_read(bus, offset, sprom);
if (bus->chipinfo.id == 0x4331) if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
err = bcma_sprom_valid(sprom); err = bcma_sprom_valid(sprom);
......
...@@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) ...@@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
/* redirect, configure ane enable io for interrupt signal */ /* redirect, configure and enable io for interrupt signal */
data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH) if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_SEPINT_ACT_HI; data |= SDIO_SEPINT_ACT_HI;
brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
......
...@@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans, ...@@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
* iwl_get_max_txpower_avg - get the highest tx power from all chains. * iwl_get_max_txpower_avg - get the highest tx power from all chains.
* find the highest tx power from all chains for the channel * find the highest tx power from all chains for the channel
*/ */
static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
int element, s8 *max_txpower_in_half_dbm) int element, s8 *max_txpower_in_half_dbm)
{ {
s8 max_txpower_avg = 0; /* (dBm) */ s8 max_txpower_avg = 0; /* (dBm) */
/* Take the highest tx power from any valid chains */ /* Take the highest tx power from any valid chains */
if ((cfg->valid_tx_ant & ANT_A) && if ((priv->hw_params.valid_tx_ant & ANT_A) &&
(enhanced_txpower[element].chain_a_max > max_txpower_avg)) (enhanced_txpower[element].chain_a_max > max_txpower_avg))
max_txpower_avg = enhanced_txpower[element].chain_a_max; max_txpower_avg = enhanced_txpower[element].chain_a_max;
if ((cfg->valid_tx_ant & ANT_B) && if ((priv->hw_params.valid_tx_ant & ANT_B) &&
(enhanced_txpower[element].chain_b_max > max_txpower_avg)) (enhanced_txpower[element].chain_b_max > max_txpower_avg))
max_txpower_avg = enhanced_txpower[element].chain_b_max; max_txpower_avg = enhanced_txpower[element].chain_b_max;
if ((cfg->valid_tx_ant & ANT_C) && if ((priv->hw_params.valid_tx_ant & ANT_C) &&
(enhanced_txpower[element].chain_c_max > max_txpower_avg)) (enhanced_txpower[element].chain_c_max > max_txpower_avg))
max_txpower_avg = enhanced_txpower[element].chain_c_max; max_txpower_avg = enhanced_txpower[element].chain_c_max;
if (((cfg->valid_tx_ant == ANT_AB) | if (((priv->hw_params.valid_tx_ant == ANT_AB) |
(cfg->valid_tx_ant == ANT_BC) | (priv->hw_params.valid_tx_ant == ANT_BC) |
(cfg->valid_tx_ant == ANT_AC)) && (priv->hw_params.valid_tx_ant == ANT_AC)) &&
(enhanced_txpower[element].mimo2_max > max_txpower_avg)) (enhanced_txpower[element].mimo2_max > max_txpower_avg))
max_txpower_avg = enhanced_txpower[element].mimo2_max; max_txpower_avg = enhanced_txpower[element].mimo2_max;
if ((cfg->valid_tx_ant == ANT_ABC) && if ((priv->hw_params.valid_tx_ant == ANT_ABC) &&
(enhanced_txpower[element].mimo3_max > max_txpower_avg)) (enhanced_txpower[element].mimo3_max > max_txpower_avg))
max_txpower_avg = enhanced_txpower[element].mimo3_max; max_txpower_avg = enhanced_txpower[element].mimo3_max;
...@@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) ...@@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
((txp->delta_20_in_40 & 0xf0) >> 4), ((txp->delta_20_in_40 & 0xf0) >> 4),
(txp->delta_20_in_40 & 0x0f)); (txp->delta_20_in_40 & 0x0f));
max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
&max_txp_avg_halfdbm); &max_txp_avg_halfdbm);
/* /*
......
...@@ -199,6 +199,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -199,6 +199,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_DISABLE_BEACON_HINTS |
WIPHY_FLAG_IBSS_RSN; WIPHY_FLAG_IBSS_RSN;
#ifdef CONFIG_PM_SLEEP
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
priv->trans->ops->wowlan_suspend && priv->trans->ops->wowlan_suspend &&
device_can_wakeup(priv->trans->dev)) { device_can_wakeup(priv->trans->dev)) {
...@@ -217,6 +218,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -217,6 +218,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
hw->wiphy->wowlan.pattern_max_len = hw->wiphy->wowlan.pattern_max_len =
IWLAGN_WOWLAN_MAX_PATTERN_LEN; IWLAGN_WOWLAN_MAX_PATTERN_LEN;
} }
#endif
if (iwlwifi_mod_params.power_save) if (iwlwifi_mod_params.power_save)
hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
......
...@@ -1721,6 +1721,24 @@ static void hwsim_exit_netlink(void) ...@@ -1721,6 +1721,24 @@ static void hwsim_exit_netlink(void)
"unregister family %i\n", ret); "unregister family %i\n", ret);
} }
static const struct ieee80211_iface_limit hwsim_if_limits[] = {
{ .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
};
static const struct ieee80211_iface_combination hwsim_if_comb = {
.limits = hwsim_if_limits,
.n_limits = ARRAY_SIZE(hwsim_if_limits),
.max_interfaces = 2048,
.num_different_channels = 1,
};
static int __init init_mac80211_hwsim(void) static int __init init_mac80211_hwsim(void)
{ {
int i, err = 0; int i, err = 0;
...@@ -1782,6 +1800,9 @@ static int __init init_mac80211_hwsim(void) ...@@ -1782,6 +1800,9 @@ static int __init init_mac80211_hwsim(void)
hw->wiphy->n_addresses = 2; hw->wiphy->n_addresses = 2;
hw->wiphy->addresses = data->addresses; hw->wiphy->addresses = data->addresses;
hw->wiphy->iface_combinations = &hwsim_if_comb;
hw->wiphy->n_iface_combinations = 1;
if (fake_hw_scan) { if (fake_hw_scan) {
hw->wiphy->max_scan_ssids = 255; hw->wiphy->max_scan_ssids = 255;
hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
......
...@@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, ...@@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
bss_cfg->ssid.ssid_len = params->ssid_len; bss_cfg->ssid.ssid_len = params->ssid_len;
} }
switch (params->hidden_ssid) {
case NL80211_HIDDEN_SSID_NOT_IN_USE:
bss_cfg->bcast_ssid_ctl = 1;
break;
case NL80211_HIDDEN_SSID_ZERO_LEN:
bss_cfg->bcast_ssid_ctl = 0;
break;
case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
/* firmware doesn't support this type of hidden SSID */
default:
return -EINVAL;
}
if (mwifiex_set_secure_params(priv, bss_cfg, params)) { if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
kfree(bss_cfg); kfree(bss_cfg);
wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
......
...@@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { ...@@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
#define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
...@@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid { ...@@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid {
u8 ssid[0]; u8 ssid[0];
} __packed; } __packed;
struct host_cmd_tlv_bcast_ssid {
struct host_cmd_tlv tlv;
u8 bcast_ctl;
} __packed;
struct host_cmd_tlv_beacon_period { struct host_cmd_tlv_beacon_period {
struct host_cmd_tlv tlv; struct host_cmd_tlv tlv;
__le16 period; __le16 period;
......
...@@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) ...@@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_dtim_period *dtim_period;
struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_beacon_period *beacon_period;
struct host_cmd_tlv_ssid *ssid; struct host_cmd_tlv_ssid *ssid;
struct host_cmd_tlv_bcast_ssid *bcast_ssid;
struct host_cmd_tlv_channel_band *chan_band; struct host_cmd_tlv_channel_band *chan_band;
struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_frag_threshold *frag_threshold;
struct host_cmd_tlv_rts_threshold *rts_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold;
...@@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) ...@@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
cmd_size += sizeof(struct host_cmd_tlv) + cmd_size += sizeof(struct host_cmd_tlv) +
bss_cfg->ssid.ssid_len; bss_cfg->ssid.ssid_len;
tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len; tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
bcast_ssid->tlv.len =
cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
tlv += sizeof(struct host_cmd_tlv_bcast_ssid);
} }
if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) { if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
chan_band = (struct host_cmd_tlv_channel_band *)tlv; chan_band = (struct host_cmd_tlv_channel_band *)tlv;
...@@ -416,6 +425,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) ...@@ -416,6 +425,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
if (!bss_cfg) if (!bss_cfg)
return -ENOMEM; return -ENOMEM;
mwifiex_set_sys_config_invalid_data(bss_cfg);
bss_cfg->band_cfg = BAND_CONFIG_MANUAL; bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
bss_cfg->channel = channel; bss_cfg->channel = channel;
......
...@@ -396,8 +396,7 @@ struct rt2x00_intf { ...@@ -396,8 +396,7 @@ struct rt2x00_intf {
* for hardware which doesn't support hardware * for hardware which doesn't support hardware
* sequence counting. * sequence counting.
*/ */
spinlock_t seqlock; atomic_t seqno;
u16 seqno;
}; };
static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
......
...@@ -277,7 +277,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, ...@@ -277,7 +277,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
else else
rt2x00dev->intf_sta_count++; rt2x00dev->intf_sta_count++;
spin_lock_init(&intf->seqlock);
mutex_init(&intf->beacon_skb_mutex); mutex_init(&intf->beacon_skb_mutex);
intf->beacon = entry; intf->beacon = entry;
......
...@@ -207,6 +207,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, ...@@ -207,6 +207,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
u16 seqno;
if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
return; return;
...@@ -238,15 +239,13 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, ...@@ -238,15 +239,13 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
* sequence counting per-frame, since those will override the * sequence counting per-frame, since those will override the
* sequence counter given by mac80211. * sequence counter given by mac80211.
*/ */
spin_lock(&intf->seqlock);
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
intf->seqno += 0x10; seqno = atomic_add_return(0x10, &intf->seqno);
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); else
hdr->seq_ctrl |= cpu_to_le16(intf->seqno); seqno = atomic_read(&intf->seqno);
spin_unlock(&intf->seqlock);
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(seqno);
} }
static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev,
......
...@@ -1195,6 +1195,12 @@ struct extended_inquiry_info { ...@@ -1195,6 +1195,12 @@ struct extended_inquiry_info {
__u8 data[240]; __u8 data[240];
} __packed; } __packed;
#define HCI_EV_KEY_REFRESH_COMPLETE 0x30
struct hci_ev_key_refresh_complete {
__u8 status;
__le16 handle;
} __packed;
#define HCI_EV_IO_CAPA_REQUEST 0x31 #define HCI_EV_IO_CAPA_REQUEST 0x31
struct hci_ev_io_capa_request { struct hci_ev_io_capa_request {
bdaddr_t bdaddr; bdaddr_t bdaddr;
......
...@@ -3040,6 +3040,50 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, ...@@ -3040,6 +3040,50 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %u handle %u", hdev->name, ev->status,
__le16_to_cpu(ev->handle));
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (!conn)
goto unlock;
if (!ev->status)
conn->sec_level = conn->pending_sec_level;
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (ev->status && conn->state == BT_CONNECTED) {
hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_put(conn);
goto unlock;
}
if (conn->state == BT_CONFIG) {
if (!ev->status)
conn->state = BT_CONNECTED;
hci_proto_connect_cfm(conn, ev->status);
hci_conn_put(conn);
} else {
hci_auth_cfm(conn, ev->status);
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
hci_conn_put(conn);
}
unlock:
hci_dev_unlock(hdev);
}
static u8 hci_get_auth_req(struct hci_conn *conn) static u8 hci_get_auth_req(struct hci_conn *conn)
{ {
/* If remote requests dedicated bonding follow that lead */ /* If remote requests dedicated bonding follow that lead */
...@@ -3560,6 +3604,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3560,6 +3604,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_extended_inquiry_result_evt(hdev, skb); hci_extended_inquiry_result_evt(hdev, skb);
break; break;
case HCI_EV_KEY_REFRESH_COMPLETE:
hci_key_refresh_complete_evt(hdev, skb);
break;
case HCI_EV_IO_CAPA_REQUEST: case HCI_EV_IO_CAPA_REQUEST:
hci_io_capa_request_evt(hdev, skb); hci_io_capa_request_evt(hdev, skb);
break; break;
......
...@@ -1314,7 +1314,12 @@ static void security_timeout(struct work_struct *work) ...@@ -1314,7 +1314,12 @@ static void security_timeout(struct work_struct *work)
struct l2cap_conn *conn = container_of(work, struct l2cap_conn, struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
security_timer.work); security_timer.work);
l2cap_conn_del(conn->hcon, ETIMEDOUT); BT_DBG("conn %p", conn);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
smp_chan_destroy(conn);
l2cap_conn_del(conn->hcon, ETIMEDOUT);
}
} }
static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
......
...@@ -1873,6 +1873,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) ...@@ -1873,6 +1873,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
pairing_complete(cmd, mgmt_status(status)); pairing_complete(cmd, mgmt_status(status));
} }
static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
{
struct pending_cmd *cmd;
BT_DBG("status %u", status);
if (!status)
return;
cmd = find_pairing(conn);
if (!cmd)
BT_DBG("Unable to find a pending command");
else
pairing_complete(cmd, mgmt_status(status));
}
static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len) u16 len)
{ {
...@@ -1941,6 +1957,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1941,6 +1957,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
/* For LE, just connecting isn't a proof that the pairing finished */ /* For LE, just connecting isn't a proof that the pairing finished */
if (cp->addr.type == BDADDR_BREDR) if (cp->addr.type == BDADDR_BREDR)
conn->connect_cfm_cb = pairing_complete_cb; conn->connect_cfm_cb = pairing_complete_cb;
else
conn->connect_cfm_cb = le_connect_complete_cb;
conn->security_cfm_cb = pairing_complete_cb; conn->security_cfm_cb = pairing_complete_cb;
conn->disconn_cfm_cb = pairing_complete_cb; conn->disconn_cfm_cb = pairing_complete_cb;
......
...@@ -649,7 +649,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -649,7 +649,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
if (ret) if (ret)
return SMP_UNSPECIFIED; return SMP_UNSPECIFIED;
...@@ -704,7 +704,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -704,7 +704,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
return 0; return 0;
} }
static u8 smp_ltk_encrypt(struct l2cap_conn *conn) static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
{ {
struct smp_ltk *key; struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon; struct hci_conn *hcon = conn->hcon;
...@@ -713,6 +713,9 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn) ...@@ -713,6 +713,9 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
if (!key) if (!key)
return 0; return 0;
if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
return 0;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1; return 1;
...@@ -733,7 +736,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -733,7 +736,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
if (smp_ltk_encrypt(conn)) if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
return 0; return 0;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
...@@ -772,7 +775,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) ...@@ -772,7 +775,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
return 1; return 1;
if (hcon->link_mode & HCI_LM_MASTER) if (hcon->link_mode & HCI_LM_MASTER)
if (smp_ltk_encrypt(conn)) if (smp_ltk_encrypt(conn, sec_level))
goto done; goto done;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
......
...@@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) ...@@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
struct tid_ampdu_rx *tid_rx; struct tid_ampdu_rx *tid_rx;
unsigned long timeout; unsigned long timeout;
rcu_read_lock();
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]); tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
if (!tid_rx) if (!tid_rx) {
rcu_read_unlock();
return; return;
}
timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout); timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
if (time_is_after_jiffies(timeout)) { if (time_is_after_jiffies(timeout)) {
mod_timer(&tid_rx->session_timer, timeout); mod_timer(&tid_rx->session_timer, timeout);
rcu_read_unlock();
return; return;
} }
rcu_read_unlock();
#ifdef CONFIG_MAC80211_HT_DEBUG #ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
......
...@@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, ...@@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
sinfo.filled = 0; sinfo.filled = 0;
sta_set_sinfo(sta, &sinfo); sta_set_sinfo(sta, &sinfo);
if (sinfo.filled | STATION_INFO_TX_BITRATE) if (sinfo.filled & STATION_INFO_TX_BITRATE)
data[i] = 100000 * data[i] = 100000 *
cfg80211_calculate_bitrate(&sinfo.txrate); cfg80211_calculate_bitrate(&sinfo.txrate);
i++; i++;
if (sinfo.filled | STATION_INFO_RX_BITRATE) if (sinfo.filled & STATION_INFO_RX_BITRATE)
data[i] = 100000 * data[i] = 100000 *
cfg80211_calculate_bitrate(&sinfo.rxrate); cfg80211_calculate_bitrate(&sinfo.rxrate);
i++; i++;
if (sinfo.filled | STATION_INFO_SIGNAL_AVG) if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
data[i] = (u8)sinfo.signal_avg; data[i] = (u8)sinfo.signal_avg;
i++; i++;
} else { } else {
......
...@@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ...@@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
break; break;
default: default:
mutex_lock(&local->mtx);
if (local->hw_roc_dev == sdata->dev &&
local->hw_roc_channel) {
/* ignore return value since this is racy */
drv_cancel_remain_on_channel(local);
ieee80211_queue_work(&local->hw, &local->hw_roc_done);
}
mutex_unlock(&local->mtx);
flush_work(&local->hw_roc_start);
flush_work(&local->hw_roc_done);
flush_work(&sdata->work); flush_work(&sdata->work);
/* /*
* When we get here, the interface is marked down. * When we get here, the interface is marked down.
......
...@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, ...@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
sdata->vif.bss_conf.qos = true; sdata->vif.bss_conf.qos = true;
} }
static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
{
lockdep_assert_held(&sdata->local->mtx);
sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
IEEE80211_STA_BEACON_POLL);
ieee80211_run_deferred_scan(sdata->local);
}
static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
{
mutex_lock(&sdata->local->mtx);
__ieee80211_stop_poll(sdata);
mutex_unlock(&sdata->local->mtx);
}
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
u16 capab, bool erp_valid, u8 erp) u16 capab, bool erp_valid, u8 erp)
{ {
...@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
/* just to be sure */ /* just to be sure */
sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | ieee80211_stop_poll(sdata);
IEEE80211_STA_BEACON_POLL);
ieee80211_led_assoc(local, 1); ieee80211_led_assoc(local, 1);
...@@ -1456,8 +1471,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) ...@@ -1456,8 +1471,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
return; return;
} }
ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | __ieee80211_stop_poll(sdata);
IEEE80211_STA_BEACON_POLL);
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
ieee80211_recalc_ps(local, -1); ieee80211_recalc_ps(local, -1);
...@@ -1477,7 +1491,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata) ...@@ -1477,7 +1491,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
round_jiffies_up(jiffies + round_jiffies_up(jiffies +
IEEE80211_CONNECTION_IDLE_TIME)); IEEE80211_CONNECTION_IDLE_TIME));
out: out:
ieee80211_run_deferred_scan(local);
mutex_unlock(&local->mtx); mutex_unlock(&local->mtx);
} }
...@@ -2408,7 +2421,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -2408,7 +2421,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n",
sdata->name); sdata->name);
#endif #endif
mutex_lock(&local->mtx);
ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
ieee80211_run_deferred_scan(local);
mutex_unlock(&local->mtx);
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
ieee80211_recalc_ps(local, -1); ieee80211_recalc_ps(local, -1);
mutex_unlock(&local->iflist_mtx); mutex_unlock(&local->iflist_mtx);
...@@ -2595,8 +2612,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, ...@@ -2595,8 +2612,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
u8 frame_buf[DEAUTH_DISASSOC_LEN]; u8 frame_buf[DEAUTH_DISASSOC_LEN];
ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | ieee80211_stop_poll(sdata);
IEEE80211_STA_BEACON_POLL);
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
false, frame_buf); false, frame_buf);
...@@ -2874,8 +2890,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) ...@@ -2874,8 +2890,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
u32 flags; u32 flags;
if (sdata->vif.type == NL80211_IFTYPE_STATION) { if (sdata->vif.type == NL80211_IFTYPE_STATION) {
sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL | __ieee80211_stop_poll(sdata);
IEEE80211_STA_CONNECTION_POLL);
/* let's probe the connection once */ /* let's probe the connection once */
flags = sdata->local->hw.flags; flags = sdata->local->hw.flags;
...@@ -2944,7 +2959,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) ...@@ -2944,7 +2959,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
add_timer(&ifmgd->chswitch_timer); add_timer(&ifmgd->chswitch_timer);
ieee80211_sta_reset_beacon_monitor(sdata); ieee80211_sta_reset_beacon_monitor(sdata);
mutex_lock(&sdata->local->mtx);
ieee80211_restart_sta_timer(sdata); ieee80211_restart_sta_timer(sdata);
mutex_unlock(&sdata->local->mtx);
} }
#endif #endif
......
...@@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work) ...@@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
return; return;
} }
/* was never transmitted */
if (local->hw_roc_skb) {
u64 cookie;
cookie = local->hw_roc_cookie ^ 2;
cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie,
local->hw_roc_skb->data,
local->hw_roc_skb->len, false,
GFP_KERNEL);
kfree_skb(local->hw_roc_skb);
local->hw_roc_skb = NULL;
local->hw_roc_skb_for_status = NULL;
}
if (!local->hw_roc_for_tx) if (!local->hw_roc_for_tx)
cfg80211_remain_on_channel_expired(local->hw_roc_dev, cfg80211_remain_on_channel_expired(local->hw_roc_dev,
local->hw_roc_cookie, local->hw_roc_cookie,
......
...@@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) ...@@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
/* make the station visible */ /* make the station visible */
sta_info_hash_add(local, sta); sta_info_hash_add(local, sta);
list_add(&sta->list, &local->sta_list); list_add_rcu(&sta->list, &local->sta_list);
set_sta_flag(sta, WLAN_STA_INSERTED); set_sta_flag(sta, WLAN_STA_INSERTED);
...@@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) ...@@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
if (ret) if (ret)
return ret; return ret;
list_del(&sta->list); list_del_rcu(&sta->list);
mutex_lock(&local->key_mtx); mutex_lock(&local->key_mtx);
for (i = 0; i < NUM_DEFAULT_KEYS; i++) for (i = 0; i < NUM_DEFAULT_KEYS; i++)
......
...@@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ...@@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
__le16 fc; __le16 fc;
struct ieee80211_hdr hdr; struct ieee80211_hdr hdr;
struct ieee80211s_hdr mesh_hdr __maybe_unused; struct ieee80211s_hdr mesh_hdr __maybe_unused;
struct mesh_path __maybe_unused *mppath = NULL; struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL;
const u8 *encaps_data; const u8 *encaps_data;
int encaps_len, skip_header_bytes; int encaps_len, skip_header_bytes;
int nh_pos, h_pos; int nh_pos, h_pos;
...@@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ...@@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
goto fail; goto fail;
} }
rcu_read_lock(); rcu_read_lock();
if (!is_multicast_ether_addr(skb->data)) if (!is_multicast_ether_addr(skb->data)) {
mppath = mpp_path_lookup(skb->data, sdata); mpath = mesh_path_lookup(skb->data, sdata);
if (!mpath)
mppath = mpp_path_lookup(skb->data, sdata);
}
/* /*
* Use address extension if it is a packet from * Use address extension if it is a packet from
......
...@@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) ...@@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
enum ieee80211_sta_state state; enum ieee80211_sta_state state;
for (state = IEEE80211_STA_NOTEXIST; for (state = IEEE80211_STA_NOTEXIST;
state < sta->sta_state - 1; state++) state < sta->sta_state; state++)
WARN_ON(drv_sta_state(local, sta->sdata, sta, WARN_ON(drv_sta_state(local, sta->sdata, sta,
state, state + 1)); state, state + 1));
} }
......
...@@ -42,6 +42,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) ...@@ -42,6 +42,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
cfg80211_hold_bss(bss_from_pub(bss)); cfg80211_hold_bss(bss_from_pub(bss));
wdev->current_bss = bss_from_pub(bss); wdev->current_bss = bss_from_pub(bss);
wdev->sme_state = CFG80211_SME_CONNECTED;
cfg80211_upload_connect_keys(wdev); cfg80211_upload_connect_keys(wdev);
nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
...@@ -60,7 +61,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) ...@@ -60,7 +61,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
struct cfg80211_event *ev; struct cfg80211_event *ev;
unsigned long flags; unsigned long flags;
CFG80211_DEV_WARN_ON(!wdev->ssid_len); CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
ev = kzalloc(sizeof(*ev), gfp); ev = kzalloc(sizeof(*ev), gfp);
if (!ev) if (!ev)
...@@ -115,9 +116,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, ...@@ -115,9 +116,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
wdev->wext.ibss.channel = params->channel; wdev->wext.ibss.channel = params->channel;
#endif #endif
wdev->sme_state = CFG80211_SME_CONNECTING;
err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
if (err) { if (err) {
wdev->connect_keys = NULL; wdev->connect_keys = NULL;
wdev->sme_state = CFG80211_SME_IDLE;
return err; return err;
} }
...@@ -169,6 +172,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) ...@@ -169,6 +172,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
} }
wdev->current_bss = NULL; wdev->current_bss = NULL;
wdev->sme_state = CFG80211_SME_IDLE;
wdev->ssid_len = 0; wdev->ssid_len = 0;
#ifdef CONFIG_CFG80211_WEXT #ifdef CONFIG_CFG80211_WEXT
if (!nowext) if (!nowext)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment