mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
10be7eb36b
125 changed files with 3770 additions and 2018 deletions
|
|
@ -120,36 +120,38 @@ STA_OPS(last_seq_ctrl);
|
|||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[30 + STA_TID_NUM * 70], *p = buf;
|
||||
char buf[64 + STA_TID_NUM * 40], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
|
||||
spin_lock_bh(&sta->lock);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "next dialog_token is %#02x\n",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
|
||||
sta->ampdu_mlme.dialog_token_allocator + 1);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p,
|
||||
"TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
|
||||
for (i = 0; i < STA_TID_NUM; i++) {
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "TID %02d:", i);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, " RX=%x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
sta->ampdu_mlme.tid_state_rx[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_state_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
sta->ampdu_mlme.tid_state_rx[i] ?
|
||||
sta->ampdu_mlme.tid_rx[i]->ssn : 0);
|
||||
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, " TX=%x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
|
||||
sta->ampdu_mlme.tid_state_tx[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
sta->ampdu_mlme.tid_tx[i]->ssn : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "/pending=%03d",
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\t%03d",
|
||||
sta->ampdu_mlme.tid_state_tx[i] ?
|
||||
skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
||||
p += scnprintf(p, sizeof(buf) + buf - p, "\n");
|
||||
}
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
|
|||
if (_cond) \
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\t" _str "\n"); \
|
||||
} while (0)
|
||||
char buf[1024], *p = buf;
|
||||
char buf[512], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct ieee80211_sta_ht_cap *htc = &sta->sta.ht_cap;
|
||||
|
|
|
|||
|
|
@ -137,16 +137,20 @@ static inline int drv_set_key(struct ieee80211_local *local,
|
|||
}
|
||||
|
||||
static inline void drv_update_tkip_key(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_key_conf *conf,
|
||||
const u8 *address, u32 iv32,
|
||||
struct sta_info *sta, u32 iv32,
|
||||
u16 *phase1key)
|
||||
{
|
||||
might_sleep();
|
||||
struct ieee80211_sta *ista = NULL;
|
||||
|
||||
if (sta)
|
||||
ista = &sta->sta;
|
||||
|
||||
if (local->ops->update_tkip_key)
|
||||
local->ops->update_tkip_key(&local->hw, conf, address,
|
||||
iv32, phase1key);
|
||||
trace_drv_update_tkip_key(local, conf, address, iv32);
|
||||
local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
|
||||
ista, iv32, phase1key);
|
||||
trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
|
||||
}
|
||||
|
||||
static inline int drv_hw_scan(struct ieee80211_local *local,
|
||||
|
|
|
|||
|
|
@ -331,26 +331,29 @@ TRACE_EVENT(drv_set_key,
|
|||
|
||||
TRACE_EVENT(drv_update_tkip_key,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_key_conf *conf,
|
||||
const u8 *address, u32 iv32),
|
||||
struct ieee80211_sta *sta, u32 iv32),
|
||||
|
||||
TP_ARGS(local, conf, address, iv32),
|
||||
TP_ARGS(local, sdata, conf, sta, iv32),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
__array(u8, addr, 6)
|
||||
VIF_ENTRY
|
||||
STA_ENTRY
|
||||
__field(u32, iv32)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
memcpy(__entry->addr, address, 6);
|
||||
VIF_ASSIGN;
|
||||
STA_ASSIGN;
|
||||
__entry->iv32 = iv32;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT " addr:%pM iv32:%#x",
|
||||
LOCAL_PR_ARG, __entry->addr, __entry->iv32
|
||||
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " iv32:%#x",
|
||||
LOCAL_PR_ARG,VIF_PR_ARG,STA_PR_ARG, __entry->iv32
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -293,12 +293,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* check if we need to merge IBSS */
|
||||
|
||||
/* merge only on beacons (???) */
|
||||
if (!beacon)
|
||||
goto put_bss;
|
||||
|
||||
/* we use a fixed BSSID */
|
||||
if (sdata->u.ibss.bssid)
|
||||
if (sdata->u.ibss.fixed_bssid)
|
||||
goto put_bss;
|
||||
|
||||
/* not an IBSS */
|
||||
|
|
@ -454,6 +450,9 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
return active;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called with state == IEEE80211_IBSS_MLME_JOINED
|
||||
*/
|
||||
|
||||
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
|
|
@ -519,6 +518,10 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
capability, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called with state == IEEE80211_IBSS_MLME_SEARCH
|
||||
*/
|
||||
|
||||
static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
|
@ -575,18 +578,14 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
|
||||
|
||||
/* Selected IBSS not found in current scan results - try to scan */
|
||||
if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
|
||||
!ieee80211_sta_active_ibss(sdata)) {
|
||||
mod_timer(&ifibss->timer,
|
||||
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
|
||||
} else if (time_after(jiffies, ifibss->last_scan_completed +
|
||||
if (time_after(jiffies, ifibss->last_scan_completed +
|
||||
IEEE80211_SCAN_INTERVAL)) {
|
||||
printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
|
||||
"join\n", sdata->name);
|
||||
|
||||
ieee80211_request_internal_scan(sdata, ifibss->ssid,
|
||||
ifibss->ssid_len);
|
||||
} else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
|
||||
} else {
|
||||
int interval = IEEE80211_SCAN_INTERVAL;
|
||||
|
||||
if (time_after(jiffies, ifibss->ibss_join_req +
|
||||
|
|
@ -604,7 +603,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
interval = IEEE80211_SCAN_INTERVAL_SLOW;
|
||||
}
|
||||
|
||||
ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
|
||||
mod_timer(&ifibss->timer,
|
||||
round_jiffies(jiffies + interval));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,6 @@ struct ieee80211_work {
|
|||
} assoc;
|
||||
struct {
|
||||
u32 duration;
|
||||
bool started;
|
||||
} remain;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -695,10 +695,14 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
|
|||
|
||||
hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
if (!ieee80211_is_data(hdr->frame_control)) {
|
||||
skb->priority = 7;
|
||||
return ieee802_1d_to_ac[skb->priority];
|
||||
}
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
skb->priority = 0;
|
||||
return ieee802_1d_to_ac[skb->priority];
|
||||
}
|
||||
|
||||
p = ieee80211_get_qos_ctl(hdr);
|
||||
skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
|
|
|
|||
|
|
@ -484,6 +484,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
|
|||
|
||||
if (count == 1 && found->u.mgd.powersave &&
|
||||
found->u.mgd.associated &&
|
||||
found->u.mgd.associated->beacon_ies &&
|
||||
!(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
|
||||
IEEE80211_STA_CONNECTION_POLL))) {
|
||||
s32 beaconint_us;
|
||||
|
|
@ -497,14 +498,22 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
|
|||
if (beaconint_us > latency) {
|
||||
local->ps_sdata = NULL;
|
||||
} else {
|
||||
u8 dtimper = found->vif.bss_conf.dtim_period;
|
||||
struct ieee80211_bss *bss;
|
||||
int maxslp = 1;
|
||||
u8 dtimper;
|
||||
|
||||
if (dtimper > 1)
|
||||
bss = (void *)found->u.mgd.associated->priv;
|
||||
dtimper = bss->dtim_period;
|
||||
|
||||
/* If the TIM IE is invalid, pretend the value is 1 */
|
||||
if (!dtimper)
|
||||
dtimper = 1;
|
||||
else if (dtimper > 1)
|
||||
maxslp = min_t(int, dtimper,
|
||||
latency / beaconint_us);
|
||||
|
||||
local->hw.conf.max_sleep_period = maxslp;
|
||||
local->hw.conf.ps_dtim_period = dtimper;
|
||||
local->ps_sdata = found;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -702,7 +711,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||
/* set timing information */
|
||||
sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
|
||||
sdata->vif.bss_conf.timestamp = cbss->tsf;
|
||||
sdata->vif.bss_conf.dtim_period = bss->dtim_period;
|
||||
|
||||
bss_info_changed |= BSS_CHANGED_BEACON_INT;
|
||||
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
|
||||
|
|
@ -1168,6 +1176,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
int freq;
|
||||
struct ieee80211_bss *bss;
|
||||
struct ieee80211_channel *channel;
|
||||
bool need_ps = false;
|
||||
|
||||
if (sdata->u.mgd.associated) {
|
||||
bss = (void *)sdata->u.mgd.associated->priv;
|
||||
/* not previously set so we may need to recalc */
|
||||
need_ps = !bss->dtim_period;
|
||||
}
|
||||
|
||||
if (elems->ds_params && elems->ds_params_len == 1)
|
||||
freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
|
||||
|
|
@ -1187,6 +1202,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
if (!sdata->u.mgd.associated)
|
||||
return;
|
||||
|
||||
if (need_ps) {
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
ieee80211_recalc_ps(local, -1);
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
}
|
||||
|
||||
if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
|
||||
(memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
|
||||
ETH_ALEN) == 0)) {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
|
|||
struct rate_control_ref *ref = local->rate_ctrl;
|
||||
struct ieee80211_sta *ista = &sta->sta;
|
||||
void *priv_sta = sta->rate_ctrl_priv;
|
||||
|
||||
if (!ref)
|
||||
return;
|
||||
|
||||
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,9 +157,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
|
|||
|
||||
/* In case nothing happened during the previous control interval, turn
|
||||
* the sharpening factor on. */
|
||||
period = (HZ * pinfo->sampling_period + 500) / 1000;
|
||||
if (!period)
|
||||
period = 1;
|
||||
period = msecs_to_jiffies(pinfo->sampling_period);
|
||||
if (jiffies - spinfo->last_sample > 2 * period)
|
||||
spinfo->sharp_cnt = pinfo->sharpen_duration;
|
||||
|
||||
|
|
@ -252,9 +250,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
|
|||
}
|
||||
|
||||
/* Update PID controller state. */
|
||||
period = (HZ * pinfo->sampling_period + 500) / 1000;
|
||||
if (!period)
|
||||
period = 1;
|
||||
period = msecs_to_jiffies(pinfo->sampling_period);
|
||||
if (time_after(jiffies, spinfo->last_sample + period))
|
||||
rate_control_pid_sample(pinfo, sband, sta, spinfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2348,22 +2348,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
continue;
|
||||
|
||||
rx.sta = sta_info_get(sdata, hdr->addr2);
|
||||
|
||||
rx.flags |= IEEE80211_RX_RA_MATCH;
|
||||
prepares = prepare_for_handlers(sdata, &rx, hdr);
|
||||
|
||||
if (!prepares)
|
||||
continue;
|
||||
|
||||
if (status->flag & RX_FLAG_MMIC_ERROR) {
|
||||
rx.sdata = sdata;
|
||||
if (rx.flags & IEEE80211_RX_RA_MATCH)
|
||||
ieee80211_rx_michael_mic_report(hdr,
|
||||
&rx);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* frame is destined for this interface, but if it's
|
||||
* not also for the previous one we handle that after
|
||||
|
|
@ -2375,6 +2359,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|||
continue;
|
||||
}
|
||||
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
|
||||
rx.flags |= IEEE80211_RX_RA_MATCH;
|
||||
prepares = prepare_for_handlers(prev, &rx, hdr);
|
||||
|
||||
if (!prepares)
|
||||
goto next;
|
||||
|
||||
if (status->flag & RX_FLAG_MMIC_ERROR) {
|
||||
rx.sdata = prev;
|
||||
if (rx.flags & IEEE80211_RX_RA_MATCH)
|
||||
ieee80211_rx_michael_mic_report(hdr,
|
||||
&rx);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/*
|
||||
* frame was destined for the previous interface
|
||||
* so invoke RX handlers for it
|
||||
|
|
@ -2387,11 +2387,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|||
"multicast frame for %s\n",
|
||||
wiphy_name(local->hw.wiphy),
|
||||
prev->name);
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
|
||||
next:
|
||||
prev = sdata;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
rx.sta = sta_info_get_bss(prev, hdr->addr2);
|
||||
|
||||
rx.flags |= IEEE80211_RX_RA_MATCH;
|
||||
prepares = prepare_for_handlers(prev, &rx, hdr);
|
||||
|
||||
if (!prepares)
|
||||
prev = NULL;
|
||||
}
|
||||
}
|
||||
if (prev)
|
||||
ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
|
||||
|
|
|
|||
|
|
@ -111,10 +111,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
|||
bss->dtim_period = tim_ie->dtim_period;
|
||||
}
|
||||
|
||||
/* set default value for buggy AP/no TIM element */
|
||||
if (bss->dtim_period == 0)
|
||||
bss->dtim_period = 1;
|
||||
|
||||
bss->supp_rates_len = 0;
|
||||
if (elems->supp_rates) {
|
||||
clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
|
||||
|
|
|
|||
|
|
@ -45,29 +45,19 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
|
|||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
/*
|
||||
* XXX: This is temporary!
|
||||
*
|
||||
* The problem here is that when we get here, the driver will
|
||||
* quite likely have pretty much overwritten info->control by
|
||||
* using info->driver_data or info->rate_driver_data. Thus,
|
||||
* when passing out the frame to the driver again, we would be
|
||||
* passing completely bogus data since the driver would then
|
||||
* expect a properly filled info->control. In mac80211 itself
|
||||
* the same problem occurs, since we need info->control.vif
|
||||
* internally.
|
||||
*
|
||||
* To fix this, we should send the frame through TX processing
|
||||
* again. However, it's not that simple, since the frame will
|
||||
* have been software-encrypted (if applicable) already, and
|
||||
* encrypting it again doesn't do much good. So to properly do
|
||||
* that, we not only have to skip the actual 'raw' encryption
|
||||
* (key selection etc. still has to be done!) but also the
|
||||
* sequence number assignment since that impacts the crypto
|
||||
* encapsulation, of course.
|
||||
*
|
||||
* Hence, for now, fix the bug by just dropping the frame.
|
||||
* This skb 'survived' a round-trip through the driver, and
|
||||
* hopefully the driver didn't mangle it too badly. However,
|
||||
* we can definitely not rely on the the control information
|
||||
* being correct. Clear it so we don't get junk there, and
|
||||
* indicate that it needs new processing, but must not be
|
||||
* modified/encrypted again.
|
||||
*/
|
||||
goto drop;
|
||||
memset(&info->control, 0, sizeof(info->control));
|
||||
|
||||
info->control.jiffies = jiffies;
|
||||
info->control.vif = &sta->sdata->vif;
|
||||
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING |
|
||||
IEEE80211_TX_INTFL_RETRANSMISSION;
|
||||
|
||||
sta->tx_filtered_count++;
|
||||
|
||||
|
|
@ -122,7 +112,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
|
|||
return;
|
||||
}
|
||||
|
||||
drop:
|
||||
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
|
||||
if (net_ratelimit())
|
||||
printk(KERN_DEBUG "%s: dropped TX filtered frame, "
|
||||
|
|
|
|||
|
|
@ -195,11 +195,13 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_tkip_key);
|
||||
|
||||
/* Encrypt packet payload with TKIP using @key. @pos is a pointer to the
|
||||
/*
|
||||
* Encrypt packet payload with TKIP using @key. @pos is a pointer to the
|
||||
* beginning of the buffer containing payload. This payload must include
|
||||
* headroom of eight octets for IV and Ext. IV and taildroom of four octets
|
||||
* for ICV. @payload_len is the length of payload (_not_ including extra
|
||||
* headroom and tailroom). @ta is the transmitter addresses. */
|
||||
* the IV/Ext.IV and space for (taildroom) four octets for ICV.
|
||||
* @payload_len is the length of payload (_not_ including IV/ICV length).
|
||||
* @ta is the transmitter addresses.
|
||||
*/
|
||||
void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
|
||||
struct ieee80211_key *key,
|
||||
u8 *pos, size_t payload_len, u8 *ta)
|
||||
|
|
@ -214,7 +216,6 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
|
|||
|
||||
tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
|
||||
|
||||
pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
|
||||
ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
|
||||
}
|
||||
|
||||
|
|
@ -303,14 +304,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
|
|||
if (key->local->ops->update_tkip_key &&
|
||||
key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
|
||||
key->u.tkip.rx[queue].state != TKIP_STATE_PHASE1_HW_UPLOADED) {
|
||||
static const u8 bcast[ETH_ALEN] =
|
||||
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const u8 *sta_addr = key->sta->sta.addr;
|
||||
struct ieee80211_sub_if_data *sdata = key->sdata;
|
||||
|
||||
if (is_multicast_ether_addr(ra))
|
||||
sta_addr = bcast;
|
||||
|
||||
drv_update_tkip_key(key->local, &key->conf, sta_addr,
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
sdata = container_of(key->sdata->bss,
|
||||
struct ieee80211_sub_if_data, u.ap);
|
||||
drv_update_tkip_key(key->local, sdata, &key->conf, key->sta,
|
||||
iv32, key->u.tkip.rx[queue].p1k);
|
||||
key->u.tkip.rx[queue].state = TKIP_STATE_PHASE1_HW_UPLOADED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -529,6 +529,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
|
|||
tx->key = NULL;
|
||||
|
||||
if (tx->key) {
|
||||
bool skip_hw = false;
|
||||
|
||||
tx->key->tx_rx_count++;
|
||||
/* TODO: add threshold stuff again */
|
||||
|
||||
|
|
@ -545,16 +547,32 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
|
|||
!ieee80211_use_mfp(hdr->frame_control, tx->sta,
|
||||
tx->skb))
|
||||
tx->key = NULL;
|
||||
else
|
||||
skip_hw = (tx->key->conf.flags &
|
||||
IEEE80211_KEY_FLAG_SW_MGMT) &&
|
||||
ieee80211_is_mgmt(hdr->frame_control);
|
||||
break;
|
||||
case ALG_AES_CMAC:
|
||||
if (!ieee80211_is_mgmt(hdr->frame_control))
|
||||
tx->key = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skip_hw && tx->key &&
|
||||
tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
}
|
||||
|
||||
if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||
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)
|
||||
info->control.sta = &tx->sta->sta;
|
||||
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
|
@ -733,17 +751,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
|
|||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
static ieee80211_tx_result debug_noinline
|
||||
ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
|
||||
if (tx->sta)
|
||||
info->control.sta = &tx->sta->sta;
|
||||
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
static ieee80211_tx_result debug_noinline
|
||||
ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
|
|
@ -1101,7 +1108,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
tx->flags |= IEEE80211_TX_FRAGMENTED;
|
||||
|
||||
/* process and remove the injection radiotap header */
|
||||
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
|
||||
if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) {
|
||||
if (!__ieee80211_parse_tx_radiotap(tx, skb))
|
||||
return TX_DROP;
|
||||
|
||||
|
|
@ -1110,6 +1117,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
* the radiotap header that was present and pre-filled
|
||||
* 'tx' with tx control information.
|
||||
*/
|
||||
info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1125,6 +1133,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
|
|||
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||
if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
|
||||
return TX_DROP;
|
||||
} else if (info->flags & IEEE80211_TX_CTL_INJECTED) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
if (!tx->sta)
|
||||
tx->sta = sta_info_get(sdata, hdr->addr1);
|
||||
|
|
@ -1279,6 +1289,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
|
|||
static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
|
||||
{
|
||||
struct sk_buff *skb = tx->skb;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
ieee80211_tx_result res = TX_DROP;
|
||||
|
||||
#define CALL_TXH(txh) \
|
||||
|
|
@ -1292,10 +1303,14 @@ 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_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sta);
|
||||
if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
|
||||
CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
CALL_TXH(ieee80211_tx_h_misc);
|
||||
|
||||
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION))
|
||||
goto txh_done;
|
||||
|
||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sequence);
|
||||
CALL_TXH(ieee80211_tx_h_fragment);
|
||||
/* handlers after fragment must be aware of tx info fragmentation! */
|
||||
|
|
@ -1487,7 +1502,8 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
|
|||
int hdrlen;
|
||||
u16 len_rthdr;
|
||||
|
||||
info->flags |= IEEE80211_TX_CTL_INJECTED;
|
||||
info->flags |= IEEE80211_TX_CTL_INJECTED |
|
||||
IEEE80211_TX_INTFL_HAS_RADIOTAP;
|
||||
|
||||
len_rthdr = ieee80211_get_radiotap_len(skb->data);
|
||||
hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
|
||||
|
|
|
|||
|
|
@ -305,20 +305,19 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
|
||||
if (!info->control.hw_key) {
|
||||
if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
|
||||
tx->key->conf.keylen,
|
||||
tx->key->conf.keyidx))
|
||||
return -1;
|
||||
} else {
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
|
||||
if (!ieee80211_wep_add_iv(tx->local, skb,
|
||||
tx->key->conf.keylen,
|
||||
tx->key->conf.keyidx))
|
||||
return -1;
|
||||
}
|
||||
} else if (info->control.hw_key->flags &
|
||||
IEEE80211_KEY_FLAG_GENERATE_IV) {
|
||||
if (!ieee80211_wep_add_iv(tx->local, skb,
|
||||
tx->key->conf.keylen,
|
||||
tx->key->conf.keyidx))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -535,8 +535,7 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
|
|||
* First time we run, do nothing -- the generic code will
|
||||
* have switched to the right channel etc.
|
||||
*/
|
||||
if (!wk->remain.started) {
|
||||
wk->remain.started = true;
|
||||
if (!wk->started) {
|
||||
wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
|
||||
|
||||
cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
|
||||
|
|
@ -821,15 +820,17 @@ static void ieee80211_work_work(struct work_struct *work)
|
|||
mutex_lock(&local->work_mtx);
|
||||
|
||||
list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
|
||||
bool started = wk->started;
|
||||
|
||||
/* mark work as started if it's on the current off-channel */
|
||||
if (!wk->started && local->tmp_channel &&
|
||||
if (!started && local->tmp_channel &&
|
||||
wk->chan == local->tmp_channel &&
|
||||
wk->chan_type == local->tmp_channel_type) {
|
||||
wk->started = true;
|
||||
started = true;
|
||||
wk->timeout = jiffies;
|
||||
}
|
||||
|
||||
if (!wk->started && !local->tmp_channel) {
|
||||
if (!started && !local->tmp_channel) {
|
||||
/*
|
||||
* TODO: could optimize this by leaving the
|
||||
* station vifs in awake mode if they
|
||||
|
|
@ -842,12 +843,12 @@ static void ieee80211_work_work(struct work_struct *work)
|
|||
local->tmp_channel = wk->chan;
|
||||
local->tmp_channel_type = wk->chan_type;
|
||||
ieee80211_hw_config(local, 0);
|
||||
wk->started = true;
|
||||
started = true;
|
||||
wk->timeout = jiffies;
|
||||
}
|
||||
|
||||
/* don't try to work with items that aren't started */
|
||||
if (!wk->started)
|
||||
if (!started)
|
||||
continue;
|
||||
|
||||
if (time_is_after_jiffies(wk->timeout)) {
|
||||
|
|
@ -882,6 +883,8 @@ static void ieee80211_work_work(struct work_struct *work)
|
|||
break;
|
||||
}
|
||||
|
||||
wk->started = started;
|
||||
|
||||
switch (rma) {
|
||||
case WORK_ACT_NONE:
|
||||
/* might have changed the timeout */
|
||||
|
|
@ -1022,8 +1025,6 @@ 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_DEAUTH:
|
||||
case IEEE80211_STYPE_DISASSOC:
|
||||
skb_queue_tail(&local->work_skb_queue, skb);
|
||||
ieee80211_queue_work(&local->hw, &local->work_work);
|
||||
return RX_QUEUED;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
|
|||
unsigned int hdrlen;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *skb = tx->skb;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
int authenticator;
|
||||
int wpa_test = 0;
|
||||
int tail;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
|
@ -47,16 +47,15 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
|
|||
data = skb->data + hdrlen;
|
||||
data_len = skb->len - hdrlen;
|
||||
|
||||
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
|
||||
if (info->control.hw_key &&
|
||||
!(tx->flags & IEEE80211_TX_FRAGMENTED) &&
|
||||
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
|
||||
!wpa_test) {
|
||||
/* hwaccel - with no need for preallocated room for MMIC */
|
||||
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
|
||||
/* hwaccel - with no need for SW-generated MMIC */
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
tail = MICHAEL_MIC_LEN;
|
||||
if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
if (!info->control.hw_key)
|
||||
tail += TKIP_ICV_LEN;
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < tail ||
|
||||
|
|
@ -147,17 +146,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
int len, tail;
|
||||
u8 *pos;
|
||||
|
||||
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
|
||||
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
|
||||
/* hwaccel - with no need for preallocated room for IV/ICV */
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
if (info->control.hw_key &&
|
||||
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
|
||||
/* hwaccel - with no need for software-generated IV */
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
len = skb->len - hdrlen;
|
||||
|
||||
if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
||||
if (info->control.hw_key)
|
||||
tail = 0;
|
||||
else
|
||||
tail = TKIP_ICV_LEN;
|
||||
|
|
@ -175,13 +173,11 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
if (key->u.tkip.tx.iv16 == 0)
|
||||
key->u.tkip.tx.iv32++;
|
||||
|
||||
if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
|
||||
/* hwaccel - with preallocated room for IV */
|
||||
ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
|
||||
pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
|
||||
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
/* hwaccel - with software IV */
|
||||
if (info->control.hw_key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add room for ICV */
|
||||
skb_put(skb, TKIP_ICV_LEN);
|
||||
|
|
@ -363,24 +359,20 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
int hdrlen, len, tail;
|
||||
u8 *pos, *pn;
|
||||
int i;
|
||||
bool skip_hw;
|
||||
|
||||
skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) &&
|
||||
ieee80211_is_mgmt(hdr->frame_control);
|
||||
|
||||
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
|
||||
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
|
||||
!skip_hw) {
|
||||
/* hwaccel - with no need for preallocated room for CCMP
|
||||
* header or MIC fields */
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
if (info->control.hw_key &&
|
||||
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
|
||||
/*
|
||||
* hwaccel has no need for preallocated room for CCMP
|
||||
* header or MIC fields
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
len = skb->len - hdrlen;
|
||||
|
||||
if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
||||
if (info->control.hw_key)
|
||||
tail = 0;
|
||||
else
|
||||
tail = CCMP_MIC_LEN;
|
||||
|
|
@ -405,11 +397,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
|
||||
ccmp_pn2hdr(pos, pn, key->conf.keyidx);
|
||||
|
||||
if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) {
|
||||
/* hwaccel - with preallocated room for CCMP header */
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
/* hwaccel - with software CCMP header */
|
||||
if (info->control.hw_key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos += CCMP_HDR_LEN;
|
||||
ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
|
||||
|
|
@ -525,11 +515,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
|
|||
u8 *pn, aad[20];
|
||||
int i;
|
||||
|
||||
if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
|
||||
/* hwaccel */
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
if (info->control.hw_key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
|
||||
return TX_DROP;
|
||||
|
|
|
|||
Loading…
Reference in a new issue