mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-05 17:01:17 +00:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
This commit is contained in:
commit
75c8ec71fb
@ -1349,7 +1349,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
|
|||||||
* right now, so it's not too bad...
|
* right now, so it's not too bad...
|
||||||
*/
|
*/
|
||||||
rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp);
|
rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp);
|
||||||
rxs->flag |= RX_FLAG_MACTIME_MPDU;
|
rxs->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
rxs->freq = ah->curchan->center_freq;
|
rxs->freq = ah->curchan->center_freq;
|
||||||
rxs->band = ah->curchan->band;
|
rxs->band = ah->curchan->band;
|
||||||
|
@ -1082,7 +1082,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
|
|||||||
rx_status->freq = hw->conf.channel->center_freq;
|
rx_status->freq = hw->conf.channel->center_freq;
|
||||||
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
|
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
|
||||||
rx_status->antenna = rxbuf->rxstatus.rs_antenna;
|
rx_status->antenna = rxbuf->rxstatus.rs_antenna;
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -976,7 +976,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
|
|||||||
rx_status->freq = hw->conf.channel->center_freq;
|
rx_status->freq = hw->conf.channel->center_freq;
|
||||||
rx_status->signal = ah->noise + rx_stats->rs_rssi;
|
rx_status->signal = ah->noise + rx_stats->rs_rssi;
|
||||||
rx_status->antenna = rx_stats->rs_antenna;
|
rx_status->antenna = rx_stats->rs_antenna;
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
if (rx_stats->rs_moreaggr)
|
if (rx_stats->rs_moreaggr)
|
||||||
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||||
|
|
||||||
|
@ -796,7 +796,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||||||
status.mactime += mactime;
|
status.mactime += mactime;
|
||||||
if (low_mactime_now <= mactime)
|
if (low_mactime_now <= mactime)
|
||||||
status.mactime -= 0x10000;
|
status.mactime -= 0x10000;
|
||||||
status.flag |= RX_FLAG_MACTIME_MPDU;
|
status.flag |= RX_FLAG_MACTIME_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
|
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
|
||||||
|
@ -557,7 +557,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
|
|||||||
status.mactime += mactime;
|
status.mactime += mactime;
|
||||||
if (low_mactime_now <= mactime)
|
if (low_mactime_now <= mactime)
|
||||||
status.mactime -= 0x10000;
|
status.mactime -= 0x10000;
|
||||||
status.flag |= RX_FLAG_MACTIME_MPDU;
|
status.flag |= RX_FLAG_MACTIME_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
|
chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
|
||||||
|
@ -7084,7 +7084,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
|
|||||||
|
|
||||||
/* fill in TSF and flag its presence */
|
/* fill in TSF and flag its presence */
|
||||||
rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
|
rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
|
channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
|
||||||
|
|
||||||
|
@ -686,7 +686,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
|||||||
|
|
||||||
/* TSF isn't reliable. In order to allow smooth user experience,
|
/* TSF isn't reliable. In order to allow smooth user experience,
|
||||||
* this W/A doesn't propagate it to the mac80211 */
|
* this W/A doesn't propagate it to the mac80211 */
|
||||||
/*rx_status.flag |= RX_FLAG_MACTIME_MPDU; */
|
/*rx_status.flag |= RX_FLAG_MACTIME_START; */
|
||||||
|
|
||||||
il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
|
il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
|
||||||
|
|
||||||
|
@ -1035,6 +1035,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_channel *channel,
|
struct ieee80211_channel *channel,
|
||||||
enum nl80211_channel_type channel_type,
|
enum nl80211_channel_type channel_type,
|
||||||
int duration)
|
int duration)
|
||||||
|
@ -949,7 +949,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
|
|||||||
|
|
||||||
/* TSF isn't reliable. In order to allow smooth user experience,
|
/* TSF isn't reliable. In order to allow smooth user experience,
|
||||||
* this W/A doesn't propagate it to the mac80211 */
|
* this W/A doesn't propagate it to the mac80211 */
|
||||||
/*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
|
/*rx_status.flag |= RX_FLAG_MACTIME_START;*/
|
||||||
|
|
||||||
priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
|
priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
|
struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
|
||||||
|
|
||||||
memset(&rx_status, 0, sizeof(rx_status));
|
memset(&rx_status, 0, sizeof(rx_status));
|
||||||
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status.flag |= RX_FLAG_MACTIME_START;
|
||||||
rx_status.freq = chan->center_freq;
|
rx_status.freq = chan->center_freq;
|
||||||
rx_status.band = chan->band;
|
rx_status.band = chan->band;
|
||||||
rx_status.rate_idx = info->control.rates[0].idx;
|
rx_status.rate_idx = info->control.rates[0].idx;
|
||||||
@ -751,7 +751,11 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nskb = skb_copy(skb, GFP_ATOMIC);
|
/*
|
||||||
|
* reserve some space for our vendor and the normal
|
||||||
|
* radiotap header, since we're copying anyway
|
||||||
|
*/
|
||||||
|
nskb = skb_copy_expand(skb, 64, 0, GFP_ATOMIC);
|
||||||
if (nskb == NULL)
|
if (nskb == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -769,6 +773,33 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
|||||||
(data->tsf_offset - data2->tsf_offset) +
|
(data->tsf_offset - data2->tsf_offset) +
|
||||||
24 * 8 * 10 / txrate->bitrate);
|
24 * 8 * 10 / txrate->bitrate);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* Don't enable this code by default as the OUI 00:00:00
|
||||||
|
* is registered to Xerox so we shouldn't use it here, it
|
||||||
|
* might find its way into pcap files.
|
||||||
|
* Note that this code requires the headroom in the SKB
|
||||||
|
* that was allocated earlier.
|
||||||
|
*/
|
||||||
|
rx_status.vendor_radiotap_oui[0] = 0x00;
|
||||||
|
rx_status.vendor_radiotap_oui[1] = 0x00;
|
||||||
|
rx_status.vendor_radiotap_oui[2] = 0x00;
|
||||||
|
rx_status.vendor_radiotap_subns = 127;
|
||||||
|
/*
|
||||||
|
* Radiotap vendor namespaces can (and should) also be
|
||||||
|
* split into fields by using the standard radiotap
|
||||||
|
* presence bitmap mechanism. Use just BIT(0) here for
|
||||||
|
* the presence bitmap.
|
||||||
|
*/
|
||||||
|
rx_status.vendor_radiotap_bitmap = BIT(0);
|
||||||
|
/* We have 8 bytes of (dummy) data */
|
||||||
|
rx_status.vendor_radiotap_len = 8;
|
||||||
|
/* For testing, also require it to be aligned */
|
||||||
|
rx_status.vendor_radiotap_align = 8;
|
||||||
|
/* push the data */
|
||||||
|
memcpy(skb_push(nskb, 8), "ABCDEFGH", 8);
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
|
memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
|
||||||
ieee80211_rx_irqsafe(data2->hw, nskb);
|
ieee80211_rx_irqsafe(data2->hw, nskb);
|
||||||
}
|
}
|
||||||
@ -1422,6 +1453,7 @@ static void hw_roc_done(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
|
static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_channel *chan,
|
struct ieee80211_channel *chan,
|
||||||
enum nl80211_channel_type channel_type,
|
enum nl80211_channel_type channel_type,
|
||||||
int duration)
|
int duration)
|
||||||
|
@ -369,7 +369,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
|
|||||||
rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
|
rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
|
||||||
priv->tsf_low32 = tsf32;
|
priv->tsf_low32 = tsf32;
|
||||||
|
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
|
if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
|
||||||
header_len += hdr->align[0];
|
header_len += hdr->align[0];
|
||||||
|
@ -150,7 +150,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
|||||||
rx_status.freq = dev->conf.channel->center_freq;
|
rx_status.freq = dev->conf.channel->center_freq;
|
||||||
rx_status.band = dev->conf.channel->band;
|
rx_status.band = dev->conf.channel->band;
|
||||||
rx_status.mactime = le64_to_cpu(entry->tsft);
|
rx_status.mactime = le64_to_cpu(entry->tsft);
|
||||||
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status.flag |= RX_FLAG_MACTIME_START;
|
||||||
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
||||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ static void rtl8187_rx_cb(struct urb *urb)
|
|||||||
rx_status.rate_idx = rate;
|
rx_status.rate_idx = rate;
|
||||||
rx_status.freq = dev->conf.channel->center_freq;
|
rx_status.freq = dev->conf.channel->center_freq;
|
||||||
rx_status.band = dev->conf.channel->band;
|
rx_status.band = dev->conf.channel->band;
|
||||||
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status.flag |= RX_FLAG_MACTIME_START;
|
||||||
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
||||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
|
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
|
||||||
|
@ -559,7 +559,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
|
|||||||
if (GET_RX_DESC_RXHT(pdesc))
|
if (GET_RX_DESC_RXHT(pdesc))
|
||||||
rx_status->flag |= RX_FLAG_HT;
|
rx_status->flag |= RX_FLAG_HT;
|
||||||
|
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
if (stats->decrypted)
|
if (stats->decrypted)
|
||||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||||
|
@ -334,7 +334,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
|
|||||||
rx_status->flag |= RX_FLAG_40MHZ;
|
rx_status->flag |= RX_FLAG_40MHZ;
|
||||||
if (GET_RX_DESC_RX_HT(pdesc))
|
if (GET_RX_DESC_RX_HT(pdesc))
|
||||||
rx_status->flag |= RX_FLAG_HT;
|
rx_status->flag |= RX_FLAG_HT;
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
if (stats->decrypted)
|
if (stats->decrypted)
|
||||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||||
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
|
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
|
||||||
|
@ -509,7 +509,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
|||||||
rx_status->flag |= RX_FLAG_40MHZ;
|
rx_status->flag |= RX_FLAG_40MHZ;
|
||||||
if (GET_RX_DESC_RXHT(pdesc))
|
if (GET_RX_DESC_RXHT(pdesc))
|
||||||
rx_status->flag |= RX_FLAG_HT;
|
rx_status->flag |= RX_FLAG_HT;
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
if (stats->decrypted)
|
if (stats->decrypted)
|
||||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||||
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
|
rx_status->rate_idx = rtlwifi_rate_mapping(hw,
|
||||||
|
@ -553,7 +553,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
|||||||
if (stats->is_ht)
|
if (stats->is_ht)
|
||||||
rx_status->flag |= RX_FLAG_HT;
|
rx_status->flag |= RX_FLAG_HT;
|
||||||
|
|
||||||
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
|
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
/* hw will set stats->decrypted true, if it finds the
|
/* hw will set stats->decrypted true, if it finds the
|
||||||
* frame is open data frame or mgmt frame,
|
* frame is open data frame or mgmt frame,
|
||||||
|
@ -81,7 +81,7 @@ static void wl1251_rx_status(struct wl1251 *wl,
|
|||||||
status->freq = ieee80211_channel_to_frequency(desc->channel,
|
status->freq = ieee80211_channel_to_frequency(desc->channel,
|
||||||
status->band);
|
status->band);
|
||||||
|
|
||||||
status->flag |= RX_FLAG_MACTIME_MPDU;
|
status->flag |= RX_FLAG_MACTIME_START;
|
||||||
|
|
||||||
if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
|
if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
|
||||||
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
|
status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
|
||||||
|
@ -131,6 +131,8 @@
|
|||||||
|
|
||||||
#define IEEE80211_MAX_MESH_ID_LEN 32
|
#define IEEE80211_MAX_MESH_ID_LEN 32
|
||||||
|
|
||||||
|
#define IEEE80211_NUM_TIDS 16
|
||||||
|
|
||||||
#define IEEE80211_QOS_CTL_LEN 2
|
#define IEEE80211_QOS_CTL_LEN 2
|
||||||
/* 1d tag mask */
|
/* 1d tag mask */
|
||||||
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
|
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
|
||||||
|
@ -3593,6 +3593,25 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
|
|||||||
void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
|
void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
|
||||||
enum nl80211_channel_type type);
|
enum nl80211_channel_type type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cfg80211_tdls_oper_request - request userspace to perform TDLS operation
|
||||||
|
* @dev: the device on which the operation is requested
|
||||||
|
* @peer: the MAC address of the peer device
|
||||||
|
* @oper: the requested TDLS operation (NL80211_TDLS_SETUP or
|
||||||
|
* NL80211_TDLS_TEARDOWN)
|
||||||
|
* @reason_code: the reason code for teardown request
|
||||||
|
* @gfp: allocation flags
|
||||||
|
*
|
||||||
|
* This function is used to request userspace to perform TDLS operation that
|
||||||
|
* requires knowledge of keys, i.e., link setup or teardown when the AP
|
||||||
|
* connection uses encryption. This is optional mechanism for the driver to use
|
||||||
|
* if it can automatically determine when a TDLS link could be useful (e.g.,
|
||||||
|
* based on traffic and signal strength for a peer).
|
||||||
|
*/
|
||||||
|
void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
|
||||||
|
enum nl80211_tdls_operation oper,
|
||||||
|
u16 reason_code, gfp_t gfp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
|
* cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
|
||||||
* @rate: given rate_info to calculate bitrate from
|
* @rate: given rate_info to calculate bitrate from
|
||||||
|
@ -711,10 +711,13 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
|||||||
* the frame.
|
* the frame.
|
||||||
* @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
|
* @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
|
||||||
* the frame.
|
* the frame.
|
||||||
* @RX_FLAG_MACTIME_MPDU: The timestamp passed in the RX status (@mactime
|
* @RX_FLAG_MACTIME_START: The timestamp passed in the RX status (@mactime
|
||||||
* field) is valid and contains the time the first symbol of the MPDU
|
* field) is valid and contains the time the first symbol of the MPDU
|
||||||
* was received. This is useful in monitor mode and for proper IBSS
|
* was received. This is useful in monitor mode and for proper IBSS
|
||||||
* merging.
|
* merging.
|
||||||
|
* @RX_FLAG_MACTIME_END: The timestamp passed in the RX status (@mactime
|
||||||
|
* field) is valid and contains the time the last symbol of the MPDU
|
||||||
|
* (including FCS) was received.
|
||||||
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame
|
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame
|
||||||
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
|
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
|
||||||
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
|
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
|
||||||
@ -745,7 +748,7 @@ enum mac80211_rx_flags {
|
|||||||
RX_FLAG_IV_STRIPPED = BIT(4),
|
RX_FLAG_IV_STRIPPED = BIT(4),
|
||||||
RX_FLAG_FAILED_FCS_CRC = BIT(5),
|
RX_FLAG_FAILED_FCS_CRC = BIT(5),
|
||||||
RX_FLAG_FAILED_PLCP_CRC = BIT(6),
|
RX_FLAG_FAILED_PLCP_CRC = BIT(6),
|
||||||
RX_FLAG_MACTIME_MPDU = BIT(7),
|
RX_FLAG_MACTIME_START = BIT(7),
|
||||||
RX_FLAG_SHORTPRE = BIT(8),
|
RX_FLAG_SHORTPRE = BIT(8),
|
||||||
RX_FLAG_HT = BIT(9),
|
RX_FLAG_HT = BIT(9),
|
||||||
RX_FLAG_40MHZ = BIT(10),
|
RX_FLAG_40MHZ = BIT(10),
|
||||||
@ -759,6 +762,7 @@ enum mac80211_rx_flags {
|
|||||||
RX_FLAG_AMPDU_IS_LAST = BIT(18),
|
RX_FLAG_AMPDU_IS_LAST = BIT(18),
|
||||||
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
|
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
|
||||||
RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
|
RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
|
||||||
|
RX_FLAG_MACTIME_END = BIT(21),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -785,12 +789,21 @@ enum mac80211_rx_flags {
|
|||||||
* @ampdu_reference: A-MPDU reference number, must be a different value for
|
* @ampdu_reference: A-MPDU reference number, must be a different value for
|
||||||
* each A-MPDU but the same for each subframe within one A-MPDU
|
* each A-MPDU but the same for each subframe within one A-MPDU
|
||||||
* @ampdu_delimiter_crc: A-MPDU delimiter CRC
|
* @ampdu_delimiter_crc: A-MPDU delimiter CRC
|
||||||
|
* @vendor_radiotap_bitmap: radiotap vendor namespace presence bitmap
|
||||||
|
* @vendor_radiotap_len: radiotap vendor namespace length
|
||||||
|
* @vendor_radiotap_align: radiotap vendor namespace alignment. Note
|
||||||
|
* that the actual data must be at the start of the SKB data
|
||||||
|
* already.
|
||||||
|
* @vendor_radiotap_oui: radiotap vendor namespace OUI
|
||||||
|
* @vendor_radiotap_subns: radiotap vendor sub namespace
|
||||||
*/
|
*/
|
||||||
struct ieee80211_rx_status {
|
struct ieee80211_rx_status {
|
||||||
u64 mactime;
|
u64 mactime;
|
||||||
u32 device_timestamp;
|
u32 device_timestamp;
|
||||||
u32 ampdu_reference;
|
u32 ampdu_reference;
|
||||||
u32 flag;
|
u32 flag;
|
||||||
|
u32 vendor_radiotap_bitmap;
|
||||||
|
u16 vendor_radiotap_len;
|
||||||
u16 freq;
|
u16 freq;
|
||||||
u8 rate_idx;
|
u8 rate_idx;
|
||||||
u8 rx_flags;
|
u8 rx_flags;
|
||||||
@ -798,6 +811,9 @@ struct ieee80211_rx_status {
|
|||||||
u8 antenna;
|
u8 antenna;
|
||||||
s8 signal;
|
s8 signal;
|
||||||
u8 ampdu_delimiter_crc;
|
u8 ampdu_delimiter_crc;
|
||||||
|
u8 vendor_radiotap_align;
|
||||||
|
u8 vendor_radiotap_oui[3];
|
||||||
|
u8 vendor_radiotap_subns;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2192,6 +2208,14 @@ enum ieee80211_rate_control_changed {
|
|||||||
* @sta_remove: Notifies low level driver about removal of an associated
|
* @sta_remove: Notifies low level driver about removal of an associated
|
||||||
* station, AP, IBSS/WDS/mesh peer etc. This callback can sleep.
|
* station, AP, IBSS/WDS/mesh peer etc. This callback can sleep.
|
||||||
*
|
*
|
||||||
|
* @sta_add_debugfs: Drivers can use this callback to add debugfs files
|
||||||
|
* when a station is added to mac80211's station list. This callback
|
||||||
|
* and @sta_remove_debugfs should be within a CONFIG_MAC80211_DEBUGFS
|
||||||
|
* conditional. This callback can sleep.
|
||||||
|
*
|
||||||
|
* @sta_remove_debugfs: Remove the debugfs files which were added using
|
||||||
|
* @sta_add_debugfs. This callback can sleep.
|
||||||
|
*
|
||||||
* @sta_notify: Notifies low level driver about power state transition of an
|
* @sta_notify: Notifies low level driver about power state transition of an
|
||||||
* associated station, AP, IBSS/WDS/mesh peer etc. For a VIF operating
|
* associated station, AP, IBSS/WDS/mesh peer etc. For a VIF operating
|
||||||
* in AP mode, this callback will not be called when the flag
|
* in AP mode, this callback will not be called when the flag
|
||||||
@ -2473,6 +2497,16 @@ struct ieee80211_ops {
|
|||||||
struct ieee80211_sta *sta);
|
struct ieee80211_sta *sta);
|
||||||
int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta);
|
struct ieee80211_sta *sta);
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
void (*sta_add_debugfs)(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
struct dentry *dir);
|
||||||
|
void (*sta_remove_debugfs)(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
struct dentry *dir);
|
||||||
|
#endif
|
||||||
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
enum sta_notify_cmd, struct ieee80211_sta *sta);
|
||||||
int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
@ -2514,6 +2548,7 @@ struct ieee80211_ops {
|
|||||||
int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
||||||
|
|
||||||
int (*remain_on_channel)(struct ieee80211_hw *hw,
|
int (*remain_on_channel)(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_channel *chan,
|
struct ieee80211_channel *chan,
|
||||||
enum nl80211_channel_type channel_type,
|
enum nl80211_channel_type channel_type,
|
||||||
int duration);
|
int duration);
|
||||||
|
@ -526,6 +526,12 @@
|
|||||||
* of PMKSA caching dandidates.
|
* of PMKSA caching dandidates.
|
||||||
*
|
*
|
||||||
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
|
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
|
||||||
|
* In addition, this can be used as an event to request userspace to take
|
||||||
|
* actions on TDLS links (set up a new link or tear down an existing one).
|
||||||
|
* In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested
|
||||||
|
* operation, %NL80211_ATTR_MAC contains the peer MAC address, and
|
||||||
|
* %NL80211_ATTR_REASON_CODE the reason code to be used (only with
|
||||||
|
* %NL80211_TDLS_TEARDOWN).
|
||||||
* @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
|
* @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame.
|
||||||
*
|
*
|
||||||
* @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
|
* @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
|
||||||
@ -3057,6 +3063,9 @@ enum nl80211_ap_sme_features {
|
|||||||
* @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
|
* @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
|
||||||
* @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
|
* @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
|
||||||
* @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting
|
* @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting
|
||||||
|
* @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
|
||||||
|
* OBSS scans and generate 20/40 BSS coex reports. This flag is used only
|
||||||
|
* for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
|
||||||
*/
|
*/
|
||||||
enum nl80211_feature_flags {
|
enum nl80211_feature_flags {
|
||||||
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
|
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
|
||||||
@ -3069,6 +3078,7 @@ enum nl80211_feature_flags {
|
|||||||
NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
|
NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
|
||||||
NL80211_FEATURE_AP_SCAN = 1 << 8,
|
NL80211_FEATURE_AP_SCAN = 1 << 8,
|
||||||
NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
|
NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
|
||||||
|
NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,7 +118,7 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < STA_TID_NUM; i++)
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||||
if (ba_rx_bitmap & BIT(i))
|
if (ba_rx_bitmap & BIT(i))
|
||||||
set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
|
set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
|
|||||||
if (WARN_ON(!local->ops->ampdu_action))
|
if (WARN_ON(!local->ops->ampdu_action))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if ((tid >= STA_TID_NUM) ||
|
if ((tid >= IEEE80211_NUM_TIDS) ||
|
||||||
!(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
|
!(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) ||
|
||||||
(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
|
(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -605,9 +605,9 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
|
|||||||
|
|
||||||
trace_api_start_tx_ba_cb(sdata, ra, tid);
|
trace_api_start_tx_ba_cb(sdata, ra, tid);
|
||||||
|
|
||||||
if (tid >= STA_TID_NUM) {
|
if (tid >= IEEE80211_NUM_TIDS) {
|
||||||
ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
|
ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
|
||||||
tid, STA_TID_NUM);
|
tid, IEEE80211_NUM_TIDS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
|
|||||||
if (!local->ops->ampdu_action)
|
if (!local->ops->ampdu_action)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (tid >= STA_TID_NUM)
|
if (tid >= IEEE80211_NUM_TIDS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
spin_lock_bh(&sta->lock);
|
spin_lock_bh(&sta->lock);
|
||||||
@ -722,9 +722,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
|
|||||||
|
|
||||||
trace_api_stop_tx_ba_cb(sdata, ra, tid);
|
trace_api_stop_tx_ba_cb(sdata, ra, tid);
|
||||||
|
|
||||||
if (tid >= STA_TID_NUM) {
|
if (tid >= IEEE80211_NUM_TIDS) {
|
||||||
ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
|
ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
|
||||||
tid, STA_TID_NUM);
|
tid, IEEE80211_NUM_TIDS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2287,7 +2287,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||||||
if (!duration)
|
if (!duration)
|
||||||
duration = 10;
|
duration = 10;
|
||||||
|
|
||||||
ret = drv_remain_on_channel(local, channel, channel_type, duration);
|
ret = drv_remain_on_channel(local, sdata, channel, channel_type,
|
||||||
|
duration);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(roc);
|
kfree(roc);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2298,7 +2299,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||||||
|
|
||||||
out_check_combine:
|
out_check_combine:
|
||||||
list_for_each_entry(tmp, &local->roc_list, list) {
|
list_for_each_entry(tmp, &local->roc_list, list) {
|
||||||
if (tmp->chan != channel || tmp->chan_type != channel_type)
|
if (tmp->chan != channel || tmp->chan_type != channel_type ||
|
||||||
|
tmp->sdata != sdata)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -116,7 +116,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
|
|||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
struct ieee80211_key *key = file->private_data;
|
struct ieee80211_key *key = file->private_data;
|
||||||
char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
|
char buf[14*IEEE80211_NUM_TIDS+1], *p = buf;
|
||||||
int i, len;
|
int i, len;
|
||||||
const u8 *rpn;
|
const u8 *rpn;
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
|
|||||||
len = scnprintf(buf, sizeof(buf), "\n");
|
len = scnprintf(buf, sizeof(buf), "\n");
|
||||||
break;
|
break;
|
||||||
case WLAN_CIPHER_SUITE_TKIP:
|
case WLAN_CIPHER_SUITE_TKIP:
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||||
p += scnprintf(p, sizeof(buf)+buf-p,
|
p += scnprintf(p, sizeof(buf)+buf-p,
|
||||||
"%08x %04x\n",
|
"%08x %04x\n",
|
||||||
key->u.tkip.rx[i].iv32,
|
key->u.tkip.rx[i].iv32,
|
||||||
@ -134,7 +134,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
|
|||||||
len = p - buf;
|
len = p - buf;
|
||||||
break;
|
break;
|
||||||
case WLAN_CIPHER_SUITE_CCMP:
|
case WLAN_CIPHER_SUITE_CCMP:
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
|
||||||
rpn = key->u.ccmp.rx_pn[i];
|
rpn = key->u.ccmp.rx_pn[i];
|
||||||
p += scnprintf(p, sizeof(buf)+buf-p,
|
p += scnprintf(p, sizeof(buf)+buf-p,
|
||||||
"%02x%02x%02x%02x%02x%02x\n",
|
"%02x%02x%02x%02x%02x%02x\n",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "debugfs.h"
|
#include "debugfs.h"
|
||||||
#include "debugfs_sta.h"
|
#include "debugfs_sta.h"
|
||||||
#include "sta_info.h"
|
#include "sta_info.h"
|
||||||
|
#include "driver-ops.h"
|
||||||
|
|
||||||
/* sta attributtes */
|
/* sta attributtes */
|
||||||
|
|
||||||
@ -131,10 +132,10 @@ STA_OPS(connected_time);
|
|||||||
static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
|
static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
|
char buf[15*IEEE80211_NUM_TIDS], *p = buf;
|
||||||
int i;
|
int i;
|
||||||
struct sta_info *sta = file->private_data;
|
struct sta_info *sta = file->private_data;
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||||
p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
|
p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
|
||||||
le16_to_cpu(sta->last_seq_ctrl[i]));
|
le16_to_cpu(sta->last_seq_ctrl[i]));
|
||||||
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
||||||
@ -145,7 +146,7 @@ STA_OPS(last_seq_ctrl);
|
|||||||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
char buf[71 + STA_TID_NUM * 40], *p = buf;
|
char buf[71 + IEEE80211_NUM_TIDS * 40], *p = buf;
|
||||||
int i;
|
int i;
|
||||||
struct sta_info *sta = file->private_data;
|
struct sta_info *sta = file->private_data;
|
||||||
struct tid_ampdu_rx *tid_rx;
|
struct tid_ampdu_rx *tid_rx;
|
||||||
@ -158,7 +159,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
|||||||
p += scnprintf(p, sizeof(buf) + buf - p,
|
p += scnprintf(p, sizeof(buf) + buf - p,
|
||||||
"TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
|
"TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
|
||||||
|
|
||||||
for (i = 0; i < STA_TID_NUM; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
|
tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
|
||||||
tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]);
|
tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]);
|
||||||
|
|
||||||
@ -220,7 +221,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
|
|||||||
|
|
||||||
tid = simple_strtoul(buf, NULL, 0);
|
tid = simple_strtoul(buf, NULL, 0);
|
||||||
|
|
||||||
if (tid >= STA_TID_NUM)
|
if (tid >= IEEE80211_NUM_TIDS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (tx) {
|
if (tx) {
|
||||||
@ -334,6 +335,8 @@ STA_OPS(ht_capa);
|
|||||||
|
|
||||||
void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_local *local = sta->local;
|
||||||
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations;
|
struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations;
|
||||||
u8 mac[3*ETH_ALEN];
|
u8 mac[3*ETH_ALEN];
|
||||||
|
|
||||||
@ -379,10 +382,16 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
|||||||
DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
|
DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
|
||||||
DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
|
DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
|
||||||
DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
|
DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
|
||||||
|
|
||||||
|
drv_sta_add_debugfs(local, sdata, &sta->sta, sta->debugfs.dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_sta_debugfs_remove(struct sta_info *sta)
|
void ieee80211_sta_debugfs_remove(struct sta_info *sta)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_local *local = sta->local;
|
||||||
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
|
|
||||||
|
drv_sta_remove_debugfs(local, sdata, &sta->sta, sta->debugfs.dir);
|
||||||
debugfs_remove_recursive(sta->debugfs.dir);
|
debugfs_remove_recursive(sta->debugfs.dir);
|
||||||
sta->debugfs.dir = NULL;
|
sta->debugfs.dir = NULL;
|
||||||
}
|
}
|
||||||
|
@ -490,6 +490,38 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
|
|||||||
trace_drv_return_void(local);
|
trace_drv_return_void(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
struct dentry *dir)
|
||||||
|
{
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
|
sdata = get_bss_sdata(sdata);
|
||||||
|
check_sdata_in_driver(sdata);
|
||||||
|
|
||||||
|
if (local->ops->sta_add_debugfs)
|
||||||
|
local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
|
||||||
|
sta, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct ieee80211_sta *sta,
|
||||||
|
struct dentry *dir)
|
||||||
|
{
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
|
sdata = get_bss_sdata(sdata);
|
||||||
|
check_sdata_in_driver(sdata);
|
||||||
|
|
||||||
|
if (local->ops->sta_remove_debugfs)
|
||||||
|
local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
|
||||||
|
sta, dir);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline __must_check
|
static inline __must_check
|
||||||
int drv_sta_state(struct ieee80211_local *local,
|
int drv_sta_state(struct ieee80211_local *local,
|
||||||
struct ieee80211_sub_if_data *sdata,
|
struct ieee80211_sub_if_data *sdata,
|
||||||
@ -704,6 +736,7 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int drv_remain_on_channel(struct ieee80211_local *local,
|
static inline int drv_remain_on_channel(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_channel *chan,
|
struct ieee80211_channel *chan,
|
||||||
enum nl80211_channel_type chantype,
|
enum nl80211_channel_type chantype,
|
||||||
unsigned int duration)
|
unsigned int duration)
|
||||||
@ -712,9 +745,9 @@ static inline int drv_remain_on_channel(struct ieee80211_local *local,
|
|||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
trace_drv_remain_on_channel(local, chan, chantype, duration);
|
trace_drv_remain_on_channel(local, sdata, chan, chantype, duration);
|
||||||
ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
|
ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
|
||||||
duration);
|
chan, chantype, duration);
|
||||||
trace_drv_return_int(local, ret);
|
trace_drv_return_int(local, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -185,7 +185,7 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
|
|||||||
|
|
||||||
cancel_work_sync(&sta->ampdu_mlme.work);
|
cancel_work_sync(&sta->ampdu_mlme.work);
|
||||||
|
|
||||||
for (i = 0; i < STA_TID_NUM; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
__ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
|
__ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx);
|
||||||
__ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
|
__ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
|
||||||
WLAN_REASON_QSTA_LEAVE_QBSS, tx);
|
WLAN_REASON_QSTA_LEAVE_QBSS, tx);
|
||||||
@ -209,7 +209,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||||
for (tid = 0; tid < STA_TID_NUM; tid++) {
|
for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
|
||||||
if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
|
if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
|
||||||
___ieee80211_stop_rx_ba_session(
|
___ieee80211_stop_rx_ba_session(
|
||||||
sta, tid, WLAN_BACK_RECIPIENT,
|
sta, tid, WLAN_BACK_RECIPIENT,
|
||||||
|
@ -543,30 +543,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||||||
if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid))
|
if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid))
|
||||||
goto put_bss;
|
goto put_bss;
|
||||||
|
|
||||||
if (rx_status->flag & RX_FLAG_MACTIME_MPDU) {
|
if (ieee80211_have_rx_timestamp(rx_status)) {
|
||||||
/*
|
/* time when timestamp field was received */
|
||||||
* For correct IBSS merging we need mactime; since mactime is
|
rx_timestamp =
|
||||||
* defined as the time the first data symbol of the frame hits
|
ieee80211_calculate_rx_timestamp(local, rx_status,
|
||||||
* the PHY, and the timestamp of the beacon is defined as "the
|
len + FCS_LEN, 24);
|
||||||
* time that the data symbol containing the first bit of the
|
|
||||||
* timestamp is transmitted to the PHY plus the transmitting
|
|
||||||
* STA's delays through its local PHY from the MAC-PHY
|
|
||||||
* interface to its interface with the WM" (802.11 11.1.2)
|
|
||||||
* - equals the time this bit arrives at the receiver - we have
|
|
||||||
* to take into account the offset between the two.
|
|
||||||
*
|
|
||||||
* E.g. at 1 MBit that means mactime is 192 usec earlier
|
|
||||||
* (=24 bytes * 8 usecs/byte) than the beacon timestamp.
|
|
||||||
*/
|
|
||||||
int rate;
|
|
||||||
|
|
||||||
if (rx_status->flag & RX_FLAG_HT)
|
|
||||||
rate = 65; /* TODO: HT rates */
|
|
||||||
else
|
|
||||||
rate = local->hw.wiphy->bands[band]->
|
|
||||||
bitrates[rx_status->rate_idx].bitrate;
|
|
||||||
|
|
||||||
rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* second best option: get current TSF
|
* second best option: get current TSF
|
||||||
|
@ -1259,7 +1259,18 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
|
|||||||
is_broadcast_ether_addr(raddr);
|
is_broadcast_ether_addr(raddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
|
||||||
|
{
|
||||||
|
WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START &&
|
||||||
|
status->flag & RX_FLAG_MACTIME_END);
|
||||||
|
return status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_rx_status *status,
|
||||||
|
unsigned int mpdu_len,
|
||||||
|
unsigned int mpdu_offset);
|
||||||
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
|
int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
|
||||||
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
|
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
|
||||||
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||||
|
@ -339,7 +339,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||||||
key->conf.iv_len = TKIP_IV_LEN;
|
key->conf.iv_len = TKIP_IV_LEN;
|
||||||
key->conf.icv_len = TKIP_ICV_LEN;
|
key->conf.icv_len = TKIP_ICV_LEN;
|
||||||
if (seq) {
|
if (seq) {
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
key->u.tkip.rx[i].iv32 =
|
key->u.tkip.rx[i].iv32 =
|
||||||
get_unaligned_le32(&seq[2]);
|
get_unaligned_le32(&seq[2]);
|
||||||
key->u.tkip.rx[i].iv16 =
|
key->u.tkip.rx[i].iv16 =
|
||||||
@ -352,7 +352,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||||||
key->conf.iv_len = CCMP_HDR_LEN;
|
key->conf.iv_len = CCMP_HDR_LEN;
|
||||||
key->conf.icv_len = CCMP_MIC_LEN;
|
key->conf.icv_len = CCMP_MIC_LEN;
|
||||||
if (seq) {
|
if (seq) {
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++)
|
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
|
||||||
for (j = 0; j < CCMP_PN_LEN; j++)
|
for (j = 0; j < CCMP_PN_LEN; j++)
|
||||||
key->u.ccmp.rx_pn[i][j] =
|
key->u.ccmp.rx_pn[i][j] =
|
||||||
seq[CCMP_PN_LEN - j - 1];
|
seq[CCMP_PN_LEN - j - 1];
|
||||||
@ -372,8 +372,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||||||
key->conf.iv_len = 0;
|
key->conf.iv_len = 0;
|
||||||
key->conf.icv_len = sizeof(struct ieee80211_mmie);
|
key->conf.icv_len = sizeof(struct ieee80211_mmie);
|
||||||
if (seq)
|
if (seq)
|
||||||
for (j = 0; j < 6; j++)
|
for (j = 0; j < CMAC_PN_LEN; j++)
|
||||||
key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
|
key->u.aes_cmac.rx_pn[j] =
|
||||||
|
seq[CMAC_PN_LEN - j - 1];
|
||||||
/*
|
/*
|
||||||
* Initialize AES key state here as an optimization so that
|
* Initialize AES key state here as an optimization so that
|
||||||
* it does not need to be initialized for every packet.
|
* it does not need to be initialized for every packet.
|
||||||
@ -654,16 +655,16 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
|
|||||||
|
|
||||||
switch (key->conf.cipher) {
|
switch (key->conf.cipher) {
|
||||||
case WLAN_CIPHER_SUITE_TKIP:
|
case WLAN_CIPHER_SUITE_TKIP:
|
||||||
if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES))
|
if (WARN_ON(tid < 0 || tid >= IEEE80211_NUM_TIDS))
|
||||||
return;
|
return;
|
||||||
seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
|
seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
|
||||||
seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
|
seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
|
||||||
break;
|
break;
|
||||||
case WLAN_CIPHER_SUITE_CCMP:
|
case WLAN_CIPHER_SUITE_CCMP:
|
||||||
if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES))
|
if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
|
||||||
return;
|
return;
|
||||||
if (tid < 0)
|
if (tid < 0)
|
||||||
pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES];
|
pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS];
|
||||||
else
|
else
|
||||||
pn = key->u.ccmp.rx_pn[tid];
|
pn = key->u.ccmp.rx_pn[tid];
|
||||||
memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
|
memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
#define TKIP_ICV_LEN 4
|
#define TKIP_ICV_LEN 4
|
||||||
#define CMAC_PN_LEN 6
|
#define CMAC_PN_LEN 6
|
||||||
|
|
||||||
#define NUM_RX_DATA_QUEUES 16
|
|
||||||
|
|
||||||
struct ieee80211_local;
|
struct ieee80211_local;
|
||||||
struct ieee80211_sub_if_data;
|
struct ieee80211_sub_if_data;
|
||||||
struct sta_info;
|
struct sta_info;
|
||||||
@ -82,17 +80,17 @@ struct ieee80211_key {
|
|||||||
struct tkip_ctx tx;
|
struct tkip_ctx tx;
|
||||||
|
|
||||||
/* last received RSC */
|
/* last received RSC */
|
||||||
struct tkip_ctx rx[NUM_RX_DATA_QUEUES];
|
struct tkip_ctx rx[IEEE80211_NUM_TIDS];
|
||||||
} tkip;
|
} tkip;
|
||||||
struct {
|
struct {
|
||||||
atomic64_t tx_pn;
|
atomic64_t tx_pn;
|
||||||
/*
|
/*
|
||||||
* Last received packet number. The first
|
* Last received packet number. The first
|
||||||
* NUM_RX_DATA_QUEUES counters are used with Data
|
* IEEE80211_NUM_TIDS counters are used with Data
|
||||||
* frames and the last counter is used with Robust
|
* frames and the last counter is used with Robust
|
||||||
* Management frames.
|
* Management frames.
|
||||||
*/
|
*/
|
||||||
u8 rx_pn[NUM_RX_DATA_QUEUES + 1][CCMP_PN_LEN];
|
u8 rx_pn[IEEE80211_NUM_TIDS + 1][CCMP_PN_LEN];
|
||||||
struct crypto_cipher *tfm;
|
struct crypto_cipher *tfm;
|
||||||
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
||||||
} ccmp;
|
} ccmp;
|
||||||
|
@ -116,43 +116,13 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
|
|||||||
goto no_sync;
|
goto no_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_status->flag & RX_FLAG_MACTIME_MPDU && rx_status->mactime) {
|
if (ieee80211_have_rx_timestamp(rx_status))
|
||||||
/*
|
/* time when timestamp field was received */
|
||||||
* The mactime is defined as the time the first data symbol
|
t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
|
||||||
* of the frame hits the PHY, and the timestamp of the beacon
|
24 + 12 +
|
||||||
* is defined as "the time that the data symbol containing the
|
elems->total_len +
|
||||||
* first bit of the timestamp is transmitted to the PHY plus
|
FCS_LEN,
|
||||||
* the transmitting STA's delays through its local PHY from the
|
24);
|
||||||
* MAC-PHY interface to its interface with the WM" (802.11
|
|
||||||
* 11.1.2)
|
|
||||||
*
|
|
||||||
* T_r, in 13.13.2.2.2, is just defined as "the frame reception
|
|
||||||
* time" but we unless we interpret that time to be the same
|
|
||||||
* time of the beacon timestamp, the offset calculation will be
|
|
||||||
* off. Below we adjust t_r to be "the time at which the first
|
|
||||||
* symbol of the timestamp element in the beacon is received".
|
|
||||||
* This correction depends on the rate.
|
|
||||||
*
|
|
||||||
* Based on similar code in ibss.c
|
|
||||||
*/
|
|
||||||
int rate;
|
|
||||||
|
|
||||||
if (rx_status->flag & RX_FLAG_HT) {
|
|
||||||
/* TODO:
|
|
||||||
* In principle there could be HT-beacons (Dual Beacon
|
|
||||||
* HT Operation options), but for now ignore them and
|
|
||||||
* just use the primary (i.e. non-HT) beacons for
|
|
||||||
* synchronization.
|
|
||||||
* */
|
|
||||||
goto no_sync;
|
|
||||||
} else
|
|
||||||
rate = local->hw.wiphy->bands[rx_status->band]->
|
|
||||||
bitrates[rx_status->rate_idx].bitrate;
|
|
||||||
|
|
||||||
/* 24 bytes of header * 8 bits/byte *
|
|
||||||
* 10*(100 Kbps)/Mbps / rate (100 Kbps)*/
|
|
||||||
t_r = rx_status->mactime + (24 * 8 * 10 / rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Timing offset calculation (see 13.13.2.2.2) */
|
/* Timing offset calculation (see 13.13.2.2.2) */
|
||||||
t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
|
t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
|
||||||
|
@ -283,7 +283,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
|
|||||||
if (!duration)
|
if (!duration)
|
||||||
duration = 10;
|
duration = 10;
|
||||||
|
|
||||||
ret = drv_remain_on_channel(local, roc->chan,
|
ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
|
||||||
roc->chan_type,
|
roc->chan_type,
|
||||||
duration);
|
duration);
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||||||
struct ieee80211_local *local = hw_to_local(hw);
|
struct ieee80211_local *local = hw_to_local(hw);
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
struct ieee80211_chanctx *ctx;
|
||||||
|
|
||||||
if (!local->open_count)
|
if (!local->open_count)
|
||||||
goto suspend;
|
goto suspend;
|
||||||
@ -139,14 +140,51 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||||||
rcu_access_pointer(sdata->u.ap.beacon))
|
rcu_access_pointer(sdata->u.ap.beacon))
|
||||||
drv_stop_ap(local, sdata);
|
drv_stop_ap(local, sdata);
|
||||||
|
|
||||||
/* the interface is leaving the channel and is removed */
|
if (local->use_chanctx) {
|
||||||
ieee80211_vif_release_channel(sdata);
|
struct ieee80211_chanctx_conf *conf;
|
||||||
|
|
||||||
|
mutex_lock(&local->chanctx_mtx);
|
||||||
|
conf = rcu_dereference_protected(
|
||||||
|
sdata->vif.chanctx_conf,
|
||||||
|
lockdep_is_held(&local->chanctx_mtx));
|
||||||
|
if (conf) {
|
||||||
|
ctx = container_of(conf,
|
||||||
|
struct ieee80211_chanctx,
|
||||||
|
conf);
|
||||||
|
drv_unassign_vif_chanctx(local, sdata, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
}
|
||||||
drv_remove_interface(local, sdata);
|
drv_remove_interface(local, sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
sdata = rtnl_dereference(local->monitor_sdata);
|
sdata = rtnl_dereference(local->monitor_sdata);
|
||||||
if (sdata)
|
if (sdata) {
|
||||||
|
if (local->use_chanctx) {
|
||||||
|
struct ieee80211_chanctx_conf *conf;
|
||||||
|
|
||||||
|
mutex_lock(&local->chanctx_mtx);
|
||||||
|
conf = rcu_dereference_protected(
|
||||||
|
sdata->vif.chanctx_conf,
|
||||||
|
lockdep_is_held(&local->chanctx_mtx));
|
||||||
|
if (conf) {
|
||||||
|
ctx = container_of(conf,
|
||||||
|
struct ieee80211_chanctx,
|
||||||
|
conf);
|
||||||
|
drv_unassign_vif_chanctx(local, sdata, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
drv_remove_interface(local, sdata);
|
drv_remove_interface(local, sdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&local->chanctx_mtx);
|
||||||
|
list_for_each_entry(ctx, &local->chanctx_list, list)
|
||||||
|
drv_remove_chanctx(local, ctx);
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
|
||||||
/* stop hardware - this must stop RX */
|
/* stop hardware - this must stop RX */
|
||||||
if (local->open_count)
|
if (local->open_count)
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
|
static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||||
|
|
||||||
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
|
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
|
||||||
if (likely(skb->len > FCS_LEN))
|
if (likely(skb->len > FCS_LEN))
|
||||||
__pskb_trim(skb, skb->len - FCS_LEN);
|
__pskb_trim(skb, skb->len - FCS_LEN);
|
||||||
@ -51,6 +53,9 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status->vendor_radiotap_len)
|
||||||
|
__pskb_pull(skb, status->vendor_radiotap_len);
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,32 +78,48 @@ static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ieee80211_rx_radiotap_len(struct ieee80211_local *local,
|
ieee80211_rx_radiotap_space(struct ieee80211_local *local,
|
||||||
struct ieee80211_rx_status *status)
|
struct ieee80211_rx_status *status)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* always present fields */
|
/* always present fields */
|
||||||
len = sizeof(struct ieee80211_radiotap_header) + 9;
|
len = sizeof(struct ieee80211_radiotap_header) + 9;
|
||||||
|
|
||||||
if (status->flag & RX_FLAG_MACTIME_MPDU)
|
/* allocate extra bitmap */
|
||||||
|
if (status->vendor_radiotap_len)
|
||||||
|
len += 4;
|
||||||
|
|
||||||
|
if (ieee80211_have_rx_timestamp(status)) {
|
||||||
|
len = ALIGN(len, 8);
|
||||||
len += 8;
|
len += 8;
|
||||||
|
}
|
||||||
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
|
if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
|
||||||
len += 1;
|
len += 1;
|
||||||
|
|
||||||
if (len & 1) /* padding for RX_FLAGS if necessary */
|
/* padding for RX_FLAGS if necessary */
|
||||||
len++;
|
len = ALIGN(len, 2);
|
||||||
|
|
||||||
if (status->flag & RX_FLAG_HT) /* HT info */
|
if (status->flag & RX_FLAG_HT) /* HT info */
|
||||||
len += 3;
|
len += 3;
|
||||||
|
|
||||||
if (status->flag & RX_FLAG_AMPDU_DETAILS) {
|
if (status->flag & RX_FLAG_AMPDU_DETAILS) {
|
||||||
/* padding */
|
len = ALIGN(len, 4);
|
||||||
while (len & 3)
|
|
||||||
len++;
|
|
||||||
len += 8;
|
len += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status->vendor_radiotap_len) {
|
||||||
|
if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
|
||||||
|
status->vendor_radiotap_align = 1;
|
||||||
|
/* align standard part of vendor namespace */
|
||||||
|
len = ALIGN(len, 2);
|
||||||
|
/* allocate standard part of vendor namespace */
|
||||||
|
len += 6;
|
||||||
|
/* align vendor-defined part */
|
||||||
|
len = ALIGN(len, status->vendor_radiotap_align);
|
||||||
|
/* vendor-defined part is already in skb */
|
||||||
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +138,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||||||
struct ieee80211_radiotap_header *rthdr;
|
struct ieee80211_radiotap_header *rthdr;
|
||||||
unsigned char *pos;
|
unsigned char *pos;
|
||||||
u16 rx_flags = 0;
|
u16 rx_flags = 0;
|
||||||
|
int mpdulen;
|
||||||
|
|
||||||
|
mpdulen = skb->len;
|
||||||
|
if (!(has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)))
|
||||||
|
mpdulen += FCS_LEN;
|
||||||
|
|
||||||
rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
|
rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
|
||||||
memset(rthdr, 0, rtap_len);
|
memset(rthdr, 0, rtap_len);
|
||||||
@ -127,15 +153,29 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) |
|
(1 << IEEE80211_RADIOTAP_CHANNEL) |
|
||||||
(1 << IEEE80211_RADIOTAP_ANTENNA) |
|
(1 << IEEE80211_RADIOTAP_ANTENNA) |
|
||||||
(1 << IEEE80211_RADIOTAP_RX_FLAGS));
|
(1 << IEEE80211_RADIOTAP_RX_FLAGS));
|
||||||
rthdr->it_len = cpu_to_le16(rtap_len);
|
rthdr->it_len = cpu_to_le16(rtap_len + status->vendor_radiotap_len);
|
||||||
|
|
||||||
pos = (unsigned char *)(rthdr + 1);
|
pos = (unsigned char *)(rthdr + 1);
|
||||||
|
|
||||||
|
if (status->vendor_radiotap_len) {
|
||||||
|
rthdr->it_present |=
|
||||||
|
cpu_to_le32(BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) |
|
||||||
|
cpu_to_le32(BIT(IEEE80211_RADIOTAP_EXT));
|
||||||
|
put_unaligned_le32(status->vendor_radiotap_bitmap, pos);
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
/* the order of the following fields is important */
|
/* the order of the following fields is important */
|
||||||
|
|
||||||
/* IEEE80211_RADIOTAP_TSFT */
|
/* IEEE80211_RADIOTAP_TSFT */
|
||||||
if (status->flag & RX_FLAG_MACTIME_MPDU) {
|
if (ieee80211_have_rx_timestamp(status)) {
|
||||||
put_unaligned_le64(status->mactime, pos);
|
/* padding */
|
||||||
|
while ((pos - (u8 *)rthdr) & 7)
|
||||||
|
*pos++ = 0;
|
||||||
|
put_unaligned_le64(
|
||||||
|
ieee80211_calculate_rx_timestamp(local, status,
|
||||||
|
mpdulen, 0),
|
||||||
|
pos);
|
||||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
|
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
|
||||||
pos += 8;
|
pos += 8;
|
||||||
}
|
}
|
||||||
@ -203,7 +243,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||||||
/* IEEE80211_RADIOTAP_RX_FLAGS */
|
/* IEEE80211_RADIOTAP_RX_FLAGS */
|
||||||
/* ensure 2 byte alignment for the 2 byte field as required */
|
/* ensure 2 byte alignment for the 2 byte field as required */
|
||||||
if ((pos - (u8 *)rthdr) & 1)
|
if ((pos - (u8 *)rthdr) & 1)
|
||||||
pos++;
|
*pos++ = 0;
|
||||||
if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
|
if (status->flag & RX_FLAG_FAILED_PLCP_CRC)
|
||||||
rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
|
rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
|
||||||
put_unaligned_le16(rx_flags, pos);
|
put_unaligned_le16(rx_flags, pos);
|
||||||
@ -253,6 +293,21 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||||||
*pos++ = 0;
|
*pos++ = 0;
|
||||||
*pos++ = 0;
|
*pos++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status->vendor_radiotap_len) {
|
||||||
|
/* ensure 2 byte alignment for the vendor field as required */
|
||||||
|
if ((pos - (u8 *)rthdr) & 1)
|
||||||
|
*pos++ = 0;
|
||||||
|
*pos++ = status->vendor_radiotap_oui[0];
|
||||||
|
*pos++ = status->vendor_radiotap_oui[1];
|
||||||
|
*pos++ = status->vendor_radiotap_oui[2];
|
||||||
|
*pos++ = status->vendor_radiotap_subns;
|
||||||
|
put_unaligned_le16(status->vendor_radiotap_len, pos);
|
||||||
|
pos += 2;
|
||||||
|
/* align the actual payload as requested */
|
||||||
|
while ((pos - (u8 *)rthdr) & (status->vendor_radiotap_align - 1))
|
||||||
|
*pos++ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -281,7 +336,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* room for the radiotap header based on driver features */
|
/* room for the radiotap header based on driver features */
|
||||||
needed_headroom = ieee80211_rx_radiotap_len(local, status);
|
needed_headroom = ieee80211_rx_radiotap_space(local, status);
|
||||||
|
|
||||||
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
|
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
|
||||||
present_fcs_len = FCS_LEN;
|
present_fcs_len = FCS_LEN;
|
||||||
@ -400,10 +455,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
|
|||||||
*
|
*
|
||||||
* We also use that counter for non-QoS STAs.
|
* We also use that counter for non-QoS STAs.
|
||||||
*/
|
*/
|
||||||
seqno_idx = NUM_RX_DATA_QUEUES;
|
seqno_idx = IEEE80211_NUM_TIDS;
|
||||||
security_idx = 0;
|
security_idx = 0;
|
||||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||||
security_idx = NUM_RX_DATA_QUEUES;
|
security_idx = IEEE80211_NUM_TIDS;
|
||||||
tid = 0;
|
tid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2585,7 +2640,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
|||||||
goto out_free_skb;
|
goto out_free_skb;
|
||||||
|
|
||||||
/* room for the radiotap header based on driver features */
|
/* room for the radiotap header based on driver features */
|
||||||
needed_headroom = ieee80211_rx_radiotap_len(local, status);
|
needed_headroom = ieee80211_rx_radiotap_space(local, status);
|
||||||
|
|
||||||
if (skb_headroom(skb) < needed_headroom &&
|
if (skb_headroom(skb) < needed_headroom &&
|
||||||
pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
|
pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
|
||||||
|
@ -142,7 +142,7 @@ static void free_sta_work(struct work_struct *wk)
|
|||||||
* drivers have to handle aggregation stop being requested, followed
|
* drivers have to handle aggregation stop being requested, followed
|
||||||
* directly by station destruction.
|
* directly by station destruction.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < STA_TID_NUM; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
|
tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
|
||||||
if (!tid_tx)
|
if (!tid_tx)
|
||||||
continue;
|
continue;
|
||||||
@ -330,7 +330,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < STA_TID_NUM; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
/*
|
/*
|
||||||
* timer_to_tid must be initialized with identity mapping
|
* timer_to_tid must be initialized with identity mapping
|
||||||
* to enable session_timer's data differentiation. See
|
* to enable session_timer's data differentiation. See
|
||||||
@ -343,7 +343,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||||||
skb_queue_head_init(&sta->tx_filtered[i]);
|
skb_queue_head_init(&sta->tx_filtered[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||||
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
|
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
|
||||||
|
|
||||||
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
|
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
|
||||||
@ -986,7 +986,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
|||||||
|
|
||||||
clear_sta_flag(sta, WLAN_STA_SP);
|
clear_sta_flag(sta, WLAN_STA_SP);
|
||||||
|
|
||||||
BUILD_BUG_ON(BITS_TO_LONGS(STA_TID_NUM) > 1);
|
BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
|
||||||
sta->driver_buffered_tids = 0;
|
sta->driver_buffered_tids = 0;
|
||||||
|
|
||||||
if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
|
if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
|
||||||
@ -1374,7 +1374,7 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
|
|||||||
{
|
{
|
||||||
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
||||||
|
|
||||||
if (WARN_ON(tid >= STA_TID_NUM))
|
if (WARN_ON(tid >= IEEE80211_NUM_TIDS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (buffered)
|
if (buffered)
|
||||||
|
@ -80,7 +80,6 @@ enum ieee80211_sta_info_flags {
|
|||||||
WLAN_STA_TOFFSET_KNOWN,
|
WLAN_STA_TOFFSET_KNOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define STA_TID_NUM 16
|
|
||||||
#define ADDBA_RESP_INTERVAL HZ
|
#define ADDBA_RESP_INTERVAL HZ
|
||||||
#define HT_AGG_MAX_RETRIES 15
|
#define HT_AGG_MAX_RETRIES 15
|
||||||
#define HT_AGG_BURST_RETRIES 3
|
#define HT_AGG_BURST_RETRIES 3
|
||||||
@ -197,15 +196,15 @@ struct tid_ampdu_rx {
|
|||||||
struct sta_ampdu_mlme {
|
struct sta_ampdu_mlme {
|
||||||
struct mutex mtx;
|
struct mutex mtx;
|
||||||
/* rx */
|
/* rx */
|
||||||
struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
|
struct tid_ampdu_rx __rcu *tid_rx[IEEE80211_NUM_TIDS];
|
||||||
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
|
unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||||
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(STA_TID_NUM)];
|
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)];
|
||||||
/* tx */
|
/* tx */
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];
|
struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS];
|
||||||
struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM];
|
struct tid_ampdu_tx *tid_start_tx[IEEE80211_NUM_TIDS];
|
||||||
unsigned long last_addba_req_time[STA_TID_NUM];
|
unsigned long last_addba_req_time[IEEE80211_NUM_TIDS];
|
||||||
u8 addba_req_num[STA_TID_NUM];
|
u8 addba_req_num[IEEE80211_NUM_TIDS];
|
||||||
u8 dialog_token_allocator;
|
u8 dialog_token_allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -330,7 +329,7 @@ struct sta_info {
|
|||||||
int last_signal;
|
int last_signal;
|
||||||
struct ewma avg_signal;
|
struct ewma avg_signal;
|
||||||
/* Plus 1 for non-QoS frames */
|
/* Plus 1 for non-QoS frames */
|
||||||
__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1];
|
__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
|
||||||
|
|
||||||
/* Updated from TX status path only, no locking requirements */
|
/* Updated from TX status path only, no locking requirements */
|
||||||
unsigned long tx_filtered_count;
|
unsigned long tx_filtered_count;
|
||||||
@ -351,7 +350,7 @@ struct sta_info {
|
|||||||
* Aggregation information, locked with lock.
|
* Aggregation information, locked with lock.
|
||||||
*/
|
*/
|
||||||
struct sta_ampdu_mlme ampdu_mlme;
|
struct sta_ampdu_mlme ampdu_mlme;
|
||||||
u8 timer_to_tid[STA_TID_NUM];
|
u8 timer_to_tid[IEEE80211_NUM_TIDS];
|
||||||
|
|
||||||
#ifdef CONFIG_MAC80211_MESH
|
#ifdef CONFIG_MAC80211_MESH
|
||||||
/*
|
/*
|
||||||
|
@ -1019,13 +1019,16 @@ TRACE_EVENT(drv_get_antenna,
|
|||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(drv_remain_on_channel,
|
TRACE_EVENT(drv_remain_on_channel,
|
||||||
TP_PROTO(struct ieee80211_local *local, struct ieee80211_channel *chan,
|
TP_PROTO(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct ieee80211_channel *chan,
|
||||||
enum nl80211_channel_type chantype, unsigned int duration),
|
enum nl80211_channel_type chantype, unsigned int duration),
|
||||||
|
|
||||||
TP_ARGS(local, chan, chantype, duration),
|
TP_ARGS(local, sdata, chan, chantype, duration),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
LOCAL_ENTRY
|
LOCAL_ENTRY
|
||||||
|
VIF_ENTRY
|
||||||
__field(int, center_freq)
|
__field(int, center_freq)
|
||||||
__field(int, channel_type)
|
__field(int, channel_type)
|
||||||
__field(unsigned int, duration)
|
__field(unsigned int, duration)
|
||||||
@ -1033,14 +1036,16 @@ TRACE_EVENT(drv_remain_on_channel,
|
|||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
LOCAL_ASSIGN;
|
LOCAL_ASSIGN;
|
||||||
|
VIF_ASSIGN;
|
||||||
__entry->center_freq = chan->center_freq;
|
__entry->center_freq = chan->center_freq;
|
||||||
__entry->channel_type = chantype;
|
__entry->channel_type = chantype;
|
||||||
__entry->duration = duration;
|
__entry->duration = duration;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk(
|
TP_printk(
|
||||||
LOCAL_PR_FMT " freq:%dMHz duration:%dms",
|
LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms",
|
||||||
LOCAL_PR_ARG, __entry->center_freq, __entry->duration
|
LOCAL_PR_ARG, VIF_PR_ARG,
|
||||||
|
__entry->center_freq, __entry->duration
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1417,10 +1417,12 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add channel contexts */
|
/* add channel contexts */
|
||||||
mutex_lock(&local->chanctx_mtx);
|
if (local->use_chanctx) {
|
||||||
list_for_each_entry(ctx, &local->chanctx_list, list)
|
mutex_lock(&local->chanctx_mtx);
|
||||||
WARN_ON(drv_add_chanctx(local, ctx));
|
list_for_each_entry(ctx, &local->chanctx_list, list)
|
||||||
mutex_unlock(&local->chanctx_mtx);
|
WARN_ON(drv_add_chanctx(local, ctx));
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||||
struct ieee80211_chanctx_conf *ctx_conf;
|
struct ieee80211_chanctx_conf *ctx_conf;
|
||||||
@ -1439,6 +1441,21 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||||||
mutex_unlock(&local->chanctx_mtx);
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sdata = rtnl_dereference(local->monitor_sdata);
|
||||||
|
if (sdata && local->use_chanctx && ieee80211_sdata_running(sdata)) {
|
||||||
|
struct ieee80211_chanctx_conf *ctx_conf;
|
||||||
|
|
||||||
|
mutex_lock(&local->chanctx_mtx);
|
||||||
|
ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
|
||||||
|
lockdep_is_held(&local->chanctx_mtx));
|
||||||
|
if (ctx_conf) {
|
||||||
|
ctx = container_of(ctx_conf, struct ieee80211_chanctx,
|
||||||
|
conf);
|
||||||
|
drv_assign_vif_chanctx(local, sdata, ctx);
|
||||||
|
}
|
||||||
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
/* add STAs back */
|
/* add STAs back */
|
||||||
mutex_lock(&local->sta_mtx);
|
mutex_lock(&local->sta_mtx);
|
||||||
list_for_each_entry(sta, &local->sta_list, list) {
|
list_for_each_entry(sta, &local->sta_list, list) {
|
||||||
@ -2015,3 +2032,54 @@ u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
|
|||||||
return 2;
|
return 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ieee80211_calculate_rx_timestamp - calculate timestamp in frame
|
||||||
|
* @local: mac80211 hw info struct
|
||||||
|
* @status: RX status
|
||||||
|
* @mpdu_len: total MPDU length (including FCS)
|
||||||
|
* @mpdu_offset: offset into MPDU to calculate timestamp at
|
||||||
|
*
|
||||||
|
* This function calculates the RX timestamp at the given MPDU offset, taking
|
||||||
|
* into account what the RX timestamp was. An offset of 0 will just normalize
|
||||||
|
* the timestamp to TSF at beginning of MPDU reception.
|
||||||
|
*/
|
||||||
|
u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_rx_status *status,
|
||||||
|
unsigned int mpdu_len,
|
||||||
|
unsigned int mpdu_offset)
|
||||||
|
{
|
||||||
|
u64 ts = status->mactime;
|
||||||
|
struct rate_info ri;
|
||||||
|
u16 rate;
|
||||||
|
|
||||||
|
if (WARN_ON(!ieee80211_have_rx_timestamp(status)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&ri, 0, sizeof(ri));
|
||||||
|
|
||||||
|
/* Fill cfg80211 rate info */
|
||||||
|
if (status->flag & RX_FLAG_HT) {
|
||||||
|
ri.mcs = status->rate_idx;
|
||||||
|
ri.flags |= RATE_INFO_FLAGS_MCS;
|
||||||
|
if (status->flag & RX_FLAG_40MHZ)
|
||||||
|
ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||||
|
if (status->flag & RX_FLAG_SHORT_GI)
|
||||||
|
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||||
|
} else {
|
||||||
|
struct ieee80211_supported_band *sband;
|
||||||
|
|
||||||
|
sband = local->hw.wiphy->bands[status->band];
|
||||||
|
ri.legacy = sband->bitrates[status->rate_idx].bitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
rate = cfg80211_calculate_bitrate(&ri);
|
||||||
|
|
||||||
|
/* rewind from end of MPDU */
|
||||||
|
if (status->flag & RX_FLAG_MACTIME_END)
|
||||||
|
ts -= mpdu_len * 8 * 10 / rate;
|
||||||
|
|
||||||
|
ts += mpdu_offset * 8 * 10 / rate;
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
@ -9027,6 +9027,53 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cfg80211_report_obss_beacon);
|
EXPORT_SYMBOL(cfg80211_report_obss_beacon);
|
||||||
|
|
||||||
|
void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
|
||||||
|
enum nl80211_tdls_operation oper,
|
||||||
|
u16 reason_code, gfp_t gfp)
|
||||||
|
{
|
||||||
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||||
|
struct sk_buff *msg;
|
||||||
|
void *hdr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
|
||||||
|
reason_code);
|
||||||
|
|
||||||
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||||
|
if (!msg)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
|
||||||
|
if (!hdr) {
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||||
|
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
|
||||||
|
nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
|
||||||
|
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
|
||||||
|
(reason_code > 0 &&
|
||||||
|
nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
err = genlmsg_end(msg, hdr);
|
||||||
|
if (err < 0) {
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
|
||||||
|
nl80211_mlme_mcgrp.id, gfp);
|
||||||
|
return;
|
||||||
|
|
||||||
|
nla_put_failure:
|
||||||
|
genlmsg_cancel(msg, hdr);
|
||||||
|
nlmsg_free(msg);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cfg80211_tdls_oper_request);
|
||||||
|
|
||||||
static int nl80211_netlink_notify(struct notifier_block * nb,
|
static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||||
unsigned long state,
|
unsigned long state,
|
||||||
void *_notify)
|
void *_notify)
|
||||||
|
@ -2157,6 +2157,29 @@ TRACE_EVENT(cfg80211_report_obss_beacon,
|
|||||||
WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm)
|
WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TRACE_EVENT(cfg80211_tdls_oper_request,
|
||||||
|
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *peer,
|
||||||
|
enum nl80211_tdls_operation oper, u16 reason_code),
|
||||||
|
TP_ARGS(wiphy, netdev, peer, oper, reason_code),
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
WIPHY_ENTRY
|
||||||
|
NETDEV_ENTRY
|
||||||
|
MAC_ENTRY(peer)
|
||||||
|
__field(enum nl80211_tdls_operation, oper)
|
||||||
|
__field(u16, reason_code)
|
||||||
|
),
|
||||||
|
TP_fast_assign(
|
||||||
|
WIPHY_ASSIGN;
|
||||||
|
NETDEV_ASSIGN;
|
||||||
|
MAC_ASSIGN(peer, peer);
|
||||||
|
__entry->oper = oper;
|
||||||
|
__entry->reason_code = reason_code;
|
||||||
|
),
|
||||||
|
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", oper: %d, reason_code %u",
|
||||||
|
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper,
|
||||||
|
__entry->reason_code)
|
||||||
|
);
|
||||||
|
|
||||||
TRACE_EVENT(cfg80211_scan_done,
|
TRACE_EVENT(cfg80211_scan_done,
|
||||||
TP_PROTO(struct cfg80211_scan_request *request, bool aborted),
|
TP_PROTO(struct cfg80211_scan_request *request, bool aborted),
|
||||||
TP_ARGS(request, aborted),
|
TP_ARGS(request, aborted),
|
||||||
|
Loading…
Reference in New Issue
Block a user