Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Esse commit está contido em:
@@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (mac_addr) {
|
||||
sta = sta_info_get_bss(sdata, mac_addr);
|
||||
if (!sta) {
|
||||
ieee80211_key_free(key);
|
||||
ieee80211_key_free(sdata->local, key);
|
||||
err = -ENOENT;
|
||||
goto out_unlock;
|
||||
}
|
||||
@@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
goto out_unlock;
|
||||
|
||||
if (sta->key) {
|
||||
ieee80211_key_free(sta->key);
|
||||
ieee80211_key_free(sdata->local, sta->key);
|
||||
WARN_ON(sta->key);
|
||||
ret = 0;
|
||||
}
|
||||
@@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ieee80211_key_free(sdata->keys[key_idx]);
|
||||
ieee80211_key_free(sdata->local, sdata->keys[key_idx]);
|
||||
WARN_ON(sdata->keys[key_idx]);
|
||||
|
||||
ret = 0;
|
||||
@@ -324,15 +324,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
u8 key_idx)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
ieee80211_set_default_mgmt_key(sdata, key_idx);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -238,6 +238,7 @@ enum ieee80211_work_type {
|
||||
IEEE80211_WORK_ABORT,
|
||||
IEEE80211_WORK_DIRECT_PROBE,
|
||||
IEEE80211_WORK_AUTH,
|
||||
IEEE80211_WORK_ASSOC_BEACON_WAIT,
|
||||
IEEE80211_WORK_ASSOC,
|
||||
IEEE80211_WORK_REMAIN_ON_CHANNEL,
|
||||
};
|
||||
|
@@ -323,13 +323,15 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key)
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
ieee80211_key_disable_hw_accel(key);
|
||||
if (key->local)
|
||||
ieee80211_key_disable_hw_accel(key);
|
||||
|
||||
if (key->conf.alg == ALG_CCMP)
|
||||
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
||||
if (key->conf.alg == ALG_AES_CMAC)
|
||||
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
||||
ieee80211_debugfs_key_remove(key);
|
||||
if (key->local)
|
||||
ieee80211_debugfs_key_remove(key);
|
||||
|
||||
kfree(key);
|
||||
}
|
||||
@@ -410,15 +412,12 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
|
||||
__ieee80211_key_destroy(key);
|
||||
}
|
||||
|
||||
void ieee80211_key_free(struct ieee80211_key *key)
|
||||
void ieee80211_key_free(struct ieee80211_local *local,
|
||||
struct ieee80211_key *key)
|
||||
{
|
||||
struct ieee80211_local *local;
|
||||
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
local = key->sdata->local;
|
||||
|
||||
mutex_lock(&local->key_mtx);
|
||||
__ieee80211_key_free(key);
|
||||
mutex_unlock(&local->key_mtx);
|
||||
|
@@ -135,7 +135,8 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
|
||||
void ieee80211_key_link(struct ieee80211_key *key,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta);
|
||||
void ieee80211_key_free(struct ieee80211_key *key);
|
||||
void ieee80211_key_free(struct ieee80211_local *local,
|
||||
struct ieee80211_key *key);
|
||||
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
|
||||
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
||||
int idx);
|
||||
|
@@ -107,12 +107,15 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
|
||||
if (scan_chan) {
|
||||
chan = scan_chan;
|
||||
channel_type = NL80211_CHAN_NO_HT;
|
||||
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
|
||||
} else if (local->tmp_channel) {
|
||||
chan = scan_chan = local->tmp_channel;
|
||||
channel_type = local->tmp_channel_type;
|
||||
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
|
||||
} else {
|
||||
chan = local->oper_channel;
|
||||
channel_type = local->_oper_channel_type;
|
||||
local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
|
||||
}
|
||||
|
||||
if (chan != local->hw.conf.channel ||
|
||||
|
@@ -870,6 +870,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_led_assoc(local, 1);
|
||||
|
||||
if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
|
||||
bss_conf->dtim_period = bss->dtim_period;
|
||||
else
|
||||
bss_conf->dtim_period = 0;
|
||||
|
||||
bss_conf->assoc = 1;
|
||||
/*
|
||||
* For now just always ask the driver to update the basic rateset
|
||||
@@ -1751,7 +1756,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
||||
if (wk->sdata != sdata)
|
||||
continue;
|
||||
|
||||
if (wk->type != IEEE80211_WORK_ASSOC)
|
||||
if (wk->type != IEEE80211_WORK_ASSOC &&
|
||||
wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
|
||||
continue;
|
||||
|
||||
if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
|
||||
@@ -2086,6 +2092,8 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct ieee802_11_elems elems;
|
||||
u16 status;
|
||||
|
||||
if (!skb) {
|
||||
@@ -2093,6 +2101,19 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
|
||||
return WORK_DONE_DESTROY;
|
||||
}
|
||||
|
||||
if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
|
||||
mutex_lock(&wk->sdata->u.mgd.mtx);
|
||||
rx_status = (void *) skb->cb;
|
||||
ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
|
||||
ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
|
||||
&elems, true);
|
||||
mutex_unlock(&wk->sdata->u.mgd.mtx);
|
||||
|
||||
wk->type = IEEE80211_WORK_ASSOC;
|
||||
/* not really done yet */
|
||||
return WORK_DONE_REQUEUE;
|
||||
}
|
||||
|
||||
mgmt = (void *)skb->data;
|
||||
status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
|
||||
|
||||
@@ -2206,10 +2227,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
if (req->prev_bssid)
|
||||
memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
|
||||
|
||||
wk->type = IEEE80211_WORK_ASSOC;
|
||||
wk->chan = req->bss->channel;
|
||||
wk->sdata = sdata;
|
||||
wk->done = ieee80211_assoc_done;
|
||||
if (!bss->dtim_period &&
|
||||
sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
|
||||
wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
|
||||
else
|
||||
wk->type = IEEE80211_WORK_ASSOC;
|
||||
|
||||
if (req->use_mfp) {
|
||||
ifmgd->mfp = IEEE80211_MFP_REQUIRED;
|
||||
@@ -2257,7 +2282,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
|
||||
wk->type != IEEE80211_WORK_AUTH &&
|
||||
wk->type != IEEE80211_WORK_ASSOC)
|
||||
wk->type != IEEE80211_WORK_ASSOC &&
|
||||
wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
|
||||
continue;
|
||||
|
||||
if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
|
||||
|
@@ -67,7 +67,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
|
||||
for (i = rix; i >= 0; i--)
|
||||
if (mi->r[i].rix == rix)
|
||||
break;
|
||||
WARN_ON(i < 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@@ -636,7 +636,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
|
||||
int i;
|
||||
|
||||
/* fall back to the old minstrel for legacy stations */
|
||||
if (sta && !sta->ht_cap.ht_supported) {
|
||||
if (!sta->ht_cap.ht_supported) {
|
||||
msp->is_ht = false;
|
||||
memset(&msp->legacy, 0, sizeof(msp->legacy));
|
||||
msp->legacy.r = msp->ratelist;
|
||||
@@ -748,7 +748,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
|
||||
return msp;
|
||||
|
||||
error1:
|
||||
kfree(msp->sample_table);
|
||||
kfree(msp->ratelist);
|
||||
error:
|
||||
kfree(msp);
|
||||
return NULL;
|
||||
|
@@ -114,6 +114,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
||||
bss->dtim_period = tim_ie->dtim_period;
|
||||
}
|
||||
|
||||
/* If the beacon had no TIM IE, or it was invalid, use 1 */
|
||||
if (beacon && !bss->dtim_period)
|
||||
bss->dtim_period = 1;
|
||||
|
||||
/* replace old supported rates if we get new values */
|
||||
srlen = 0;
|
||||
if (elems->supp_rates) {
|
||||
@@ -286,8 +290,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
local->scanning = 0;
|
||||
local->scan_channel = NULL;
|
||||
|
||||
drv_sw_scan_complete(local);
|
||||
|
||||
/* we only have to protect scan_req and hw/sw scan */
|
||||
mutex_unlock(&local->scan_mtx);
|
||||
|
||||
@@ -297,6 +299,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
|
||||
ieee80211_configure_filter(local);
|
||||
|
||||
drv_sw_scan_complete(local);
|
||||
|
||||
ieee80211_offchannel_return(local, true);
|
||||
|
||||
done:
|
||||
|
@@ -647,7 +647,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||
return ret;
|
||||
|
||||
if (sta->key) {
|
||||
ieee80211_key_free(sta->key);
|
||||
ieee80211_key_free(local, sta->key);
|
||||
WARN_ON(sta->key);
|
||||
}
|
||||
|
||||
|
@@ -575,17 +575,6 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
static ieee80211_tx_result debug_noinline
|
||||
ieee80211_tx_h_sta(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
|
||||
if (tx->sta && tx->sta->uploaded)
|
||||
info->control.sta = &tx->sta->sta;
|
||||
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
static ieee80211_tx_result debug_noinline
|
||||
ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
@@ -1307,6 +1296,11 @@ static int __ieee80211_tx(struct ieee80211_local *local,
|
||||
break;
|
||||
}
|
||||
|
||||
if (sta && sta->uploaded)
|
||||
info->control.sta = &sta->sta;
|
||||
else
|
||||
info->control.sta = NULL;
|
||||
|
||||
ret = drv_tx(local, skb);
|
||||
if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
|
||||
dev_kfree_skb(skb);
|
||||
@@ -1346,7 +1340,6 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
|
||||
CALL_TXH(ieee80211_tx_h_check_assoc);
|
||||
CALL_TXH(ieee80211_tx_h_ps_buf);
|
||||
CALL_TXH(ieee80211_tx_h_select_key);
|
||||
CALL_TXH(ieee80211_tx_h_sta);
|
||||
if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
|
||||
CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
|
||||
@@ -1942,11 +1935,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
h_pos += encaps_len;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
if (meshhdrlen > 0) {
|
||||
memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
|
||||
nh_pos += meshhdrlen;
|
||||
h_pos += meshhdrlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ieee80211_is_data_qos(fc)) {
|
||||
__le16 *qos_control;
|
||||
|
@@ -803,8 +803,12 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
/* after reinitialize QoS TX queues setting to default,
|
||||
* disable QoS at all */
|
||||
sdata->vif.bss_conf.qos = sdata->vif.type != NL80211_IFTYPE_STATION;
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
|
||||
sdata->vif.bss_conf.qos =
|
||||
sdata->vif.type != NL80211_IFTYPE_STATION;
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
|
||||
|
@@ -560,6 +560,22 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
|
||||
return WORK_ACT_TIMEOUT;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
|
||||
{
|
||||
if (wk->started)
|
||||
return WORK_ACT_TIMEOUT;
|
||||
|
||||
/*
|
||||
* Wait up to one beacon interval ...
|
||||
* should this be more if we miss one?
|
||||
*/
|
||||
printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
|
||||
wk->sdata->name, wk->filter_ta);
|
||||
wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
|
||||
return WORK_ACT_NONE;
|
||||
}
|
||||
|
||||
static void ieee80211_auth_challenge(struct ieee80211_work *wk,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
size_t len)
|
||||
@@ -709,6 +725,25 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
|
||||
return WORK_ACT_DONE;
|
||||
}
|
||||
|
||||
static enum work_action __must_check
|
||||
ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = wk->sdata;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
ASSERT_WORK_MTX(local);
|
||||
|
||||
if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
|
||||
return WORK_ACT_MISMATCH;
|
||||
|
||||
if (len < 24 + 12)
|
||||
return WORK_ACT_NONE;
|
||||
|
||||
printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
|
||||
return WORK_ACT_DONE;
|
||||
}
|
||||
|
||||
static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@@ -731,6 +766,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
case IEEE80211_WORK_DIRECT_PROBE:
|
||||
case IEEE80211_WORK_AUTH:
|
||||
case IEEE80211_WORK_ASSOC:
|
||||
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
|
||||
bssid = wk->filter_ta;
|
||||
break;
|
||||
default:
|
||||
@@ -745,6 +781,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
|
||||
continue;
|
||||
|
||||
switch (fc & IEEE80211_FCTL_STYPE) {
|
||||
case IEEE80211_STYPE_BEACON:
|
||||
rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_PROBE_RESP:
|
||||
rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
|
||||
rx_status);
|
||||
@@ -916,6 +955,9 @@ static void ieee80211_work_work(struct work_struct *work)
|
||||
case IEEE80211_WORK_REMAIN_ON_CHANNEL:
|
||||
rma = ieee80211_remain_on_channel_timeout(wk);
|
||||
break;
|
||||
case IEEE80211_WORK_ASSOC_BEACON_WAIT:
|
||||
rma = ieee80211_assoc_beacon_wait(wk);
|
||||
break;
|
||||
}
|
||||
|
||||
wk->started = started;
|
||||
@@ -1065,6 +1107,7 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
|
||||
case IEEE80211_STYPE_PROBE_RESP:
|
||||
case IEEE80211_STYPE_ASSOC_RESP:
|
||||
case IEEE80211_STYPE_REASSOC_RESP:
|
||||
case IEEE80211_STYPE_BEACON:
|
||||
skb_queue_tail(&local->work_skb_queue, skb);
|
||||
ieee80211_queue_work(&local->hw, &local->work_work);
|
||||
return RX_QUEUED;
|
||||
|
Referência em uma nova issue
Block a user