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:
John W. Linville
2010-07-29 14:47:07 -04:00
145 arquivos alterados com 3891 adições e 2859 exclusões

Ver arquivo

@@ -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;
}

Ver arquivo

@@ -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,
};

Ver arquivo

@@ -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);

Ver arquivo

@@ -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);

Ver arquivo

@@ -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 ||

Ver arquivo

@@ -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))

Ver arquivo

@@ -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;
}

Ver arquivo

@@ -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;

Ver arquivo

@@ -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:

Ver arquivo

@@ -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);
}

Ver arquivo

@@ -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;

Ver arquivo

@@ -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,

Ver arquivo

@@ -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;