mirror of
https://github.com/morrownr/8821cu-20210916.git
synced 2024-11-22 05:24:47 +00:00
monitor mode enhancements
This commit is contained in:
parent
309059e9d7
commit
578958e9b7
@ -12240,6 +12240,11 @@ static void rtw_mlmeext_disconnect(_adapter *padapter)
|
||||
self_action = MLME_STA_DISCONNECTED;
|
||||
else if (MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter))
|
||||
self_action = MLME_ADHOC_STOPPED;
|
||||
/* nrm */
|
||||
#ifdef CONFIG_WIFI_MONITOR
|
||||
else if (MLME_IS_MONITOR(padapter))
|
||||
self_action = MLME_ACTION_NONE;
|
||||
#endif
|
||||
else {
|
||||
RTW_INFO("state:0x%x\n", MLME_STATE(padapter));
|
||||
rtw_warn_on(1);
|
||||
|
@ -231,6 +231,10 @@ bool rtw_pwr_unassociated_idle(_adapter *adapter)
|
||||
|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
|
||||
|| MLME_IS_AP(iface)
|
||||
|| MLME_IS_MESH(iface)
|
||||
/* nrm */
|
||||
#ifdef CONFIG_WIFI_MONITOR
|
||||
|| MLME_IS_MONITOR(iface)
|
||||
#endif
|
||||
|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
|
||||
#if defined(CONFIG_IOCTL_CFG80211)
|
||||
|| rtw_cfg80211_get_is_roch(iface) == _TRUE
|
||||
@ -663,7 +667,10 @@ u8 PS_RDY_CHECK(_adapter *padapter)
|
||||
|| check_fwstate(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)
|
||||
|| MLME_IS_AP(padapter)
|
||||
|| MLME_IS_MESH(padapter)
|
||||
/* nrm */
|
||||
#ifdef CONFIG_WIFI_MONITOR
|
||||
|| MLME_IS_MONITOR(padapter)
|
||||
#endif
|
||||
|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)
|
||||
#if defined(CONFIG_IOCTL_CFG80211)
|
||||
|| rtw_cfg80211_get_is_roch(padapter) == _TRUE
|
||||
|
280
core/rtw_xmit.c
280
core/rtw_xmit.c
@ -4866,7 +4866,8 @@ static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
|
||||
s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
|
||||
{
|
||||
u16 frame_ctl;
|
||||
struct ieee80211_radiotap_header rtap_hdr;
|
||||
/* nrm */
|
||||
// struct ieee80211_radiotap_header rtap_hdr;
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
|
||||
struct pkt_file pktfile;
|
||||
struct rtw_ieee80211_hdr *pwlanhdr;
|
||||
@ -4875,36 +4876,84 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
|
||||
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
|
||||
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
|
||||
unsigned char *pframe;
|
||||
u8 dummybuf[32];
|
||||
int len = skb->len, rtap_len;
|
||||
|
||||
/* nrm */
|
||||
// u8 dummybuf[32];
|
||||
// int len = skb->len, rtap_len;
|
||||
int len = skb->len, rtap_len, rtap_remain, alloc_tries, ret;
|
||||
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
|
||||
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
|
||||
u8 rtap_buf[256];
|
||||
|
||||
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
|
||||
|
||||
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
|
||||
if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
|
||||
goto fail;
|
||||
/* nrm */
|
||||
// if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
|
||||
// goto fail;
|
||||
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) {
|
||||
if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
|
||||
goto fail;
|
||||
|
||||
_rtw_open_pktfile((_pkt *)skb, &pktfile);
|
||||
_rtw_pktfile_read(&pktfile, (u8 *)(&rtap_hdr), sizeof(struct ieee80211_radiotap_header));
|
||||
rtap_len = ieee80211_get_radiotap_len((u8 *)(&rtap_hdr));
|
||||
if (unlikely(rtap_hdr.it_version))
|
||||
goto fail;
|
||||
/* nrm */
|
||||
// _rtw_open_pktfile((_pkt *)skb, &pktfile);
|
||||
// _rtw_pktfile_read(&pktfile, (u8 *)(&rtap_hdr), sizeof(struct ieee80211_radiotap_header));
|
||||
// rtap_len = ieee80211_get_radiotap_len((u8 *)(&rtap_hdr));
|
||||
// if (unlikely(rtap_hdr.it_version))
|
||||
// goto fail;
|
||||
_rtw_open_pktfile((_pkt *)skb, &pktfile);
|
||||
_rtw_pktfile_read(&pktfile, rtap_buf, sizeof(struct ieee80211_radiotap_header));
|
||||
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
|
||||
rtap_len = ieee80211_get_radiotap_len(rtap_buf);
|
||||
|
||||
if (unlikely(skb->len < rtap_len))
|
||||
goto fail;
|
||||
/* nrm */
|
||||
// if (unlikely(skb->len < rtap_len))
|
||||
// goto fail;
|
||||
if (unlikely(rtap_hdr->it_version))
|
||||
goto fail;
|
||||
|
||||
if (rtap_len != 12) {
|
||||
RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
|
||||
goto fail;
|
||||
/* nrm */
|
||||
// if (rtap_len != 12) {
|
||||
// RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
|
||||
// goto fail;
|
||||
|
||||
if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header)))
|
||||
goto fail;
|
||||
|
||||
len -= sizeof(struct ieee80211_radiotap_header);
|
||||
rtap_remain = rtap_len - sizeof(struct ieee80211_radiotap_header);
|
||||
|
||||
if (rtap_remain > 0) {
|
||||
_rtw_pktfile_read(&pktfile, &rtap_buf[sizeof(struct ieee80211_radiotap_header)], rtap_remain);
|
||||
len -= rtap_remain;
|
||||
}
|
||||
|
||||
// NOTE: we process the radiotap header details later
|
||||
}
|
||||
_rtw_pktfile_read(&pktfile, dummybuf, rtap_len-sizeof(struct ieee80211_radiotap_header));
|
||||
len = len - rtap_len;
|
||||
|
||||
/* nrm */
|
||||
// _rtw_pktfile_read(&pktfile, dummybuf, rtap_len-sizeof(struct ieee80211_radiotap_header));
|
||||
// len = len - rtap_len;
|
||||
#endif
|
||||
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
|
||||
if (pmgntframe == NULL) {
|
||||
rtw_udelay_os(500);
|
||||
goto fail;
|
||||
|
||||
/* nrm */
|
||||
// pmgntframe = alloc_mgtxmitframe(pxmitpriv);
|
||||
// if (pmgntframe == NULL) {
|
||||
// rtw_udelay_os(500);
|
||||
// goto fail;
|
||||
// v5.2.20 had an allocation wrapper (monitor_alloc_mgtxmitframe) that performed a few
|
||||
// tries to allocate an xmit frame before giving up. This can be beneficial when there
|
||||
// is a rapid-fire sequence of injected frames. Without it, frames can be randomly
|
||||
// dropped. So this recreates the same functionality.
|
||||
|
||||
for (alloc_tries=3; alloc_tries > 0; alloc_tries--) {
|
||||
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
|
||||
if (pmgntframe != NULL)
|
||||
break;
|
||||
if (alloc_tries <= 1) {
|
||||
rtw_udelay_os(500);
|
||||
goto fail;
|
||||
}
|
||||
rtw_udelay_os(100);
|
||||
}
|
||||
|
||||
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
|
||||
@ -4912,17 +4961,24 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
|
||||
// _rtw_memcpy(pframe, (void *)checking, len);
|
||||
_rtw_pktfile_read(&pktfile, pframe, len);
|
||||
|
||||
|
||||
/* Check DATA/MGNT frames */
|
||||
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
|
||||
frame_ctl = le16_to_cpu(pwlanhdr->frame_ctl);
|
||||
/* nrm */
|
||||
// frame_ctl = le16_to_cpu(pwlanhdr->frame_ctl);
|
||||
if (unlikely(len < sizeof(struct rtw_ieee80211_hdr_3addr)))
|
||||
frame_ctl = 0;
|
||||
else
|
||||
frame_ctl = le16_to_cpu(pwlanhdr->frame_ctl);
|
||||
|
||||
if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
|
||||
|
||||
pattrib = &pmgntframe->attrib;
|
||||
update_monitor_frame_attrib(padapter, pattrib);
|
||||
|
||||
if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
|
||||
pattrib->rate = MGN_24M;
|
||||
/* nrm */
|
||||
// if (is_broadcast_mac_addr(pwlanhdr->addr3) || is_broadcast_mac_addr(pwlanhdr->addr1))
|
||||
// pattrib->rate = MGN_24M;
|
||||
pattrib->rate = MGN_1M; // Override a more practical default rate
|
||||
|
||||
} else {
|
||||
|
||||
@ -4937,7 +4993,179 @@ s32 rtw_monitor_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
|
||||
pmlmeext->mgnt_seq++;
|
||||
pattrib->last_txcmdsz = pattrib->pktlen;
|
||||
|
||||
/* nrm */
|
||||
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
|
||||
|
||||
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) {
|
||||
// Parse radiotap for injection items and overwrite attribs as needed.
|
||||
// This code should probably live in core/monitor/rtw_radiotap.c, but we would have to
|
||||
// pass pointers to a large number of things simply for the sake of organization,
|
||||
// and it isn't worth it at this preliminary point to get things up and running.
|
||||
// Let's call it a possible FUTURE-TODO.
|
||||
|
||||
ret = ieee80211_radiotap_iterator_init(&iterator, rtap_hdr, rtap_len, NULL);
|
||||
while (!ret) {
|
||||
ret = ieee80211_radiotap_iterator_next(&iterator);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
switch (iterator.this_arg_index) {
|
||||
case IEEE80211_RADIOTAP_RATE:
|
||||
// This is basic 802.11b/g rate; use MCS/VHT for higher rates
|
||||
pattrib->rate = *iterator.this_arg;
|
||||
#ifdef CONFIG_80211AC_VHT
|
||||
pattrib->raid = RATEID_IDX_BGN_40M_1SS;
|
||||
#else
|
||||
if (pattrib->rate == IEEE80211_CCK_RATE_1MB
|
||||
|| pattrib->rate == IEEE80211_CCK_RATE_2MB
|
||||
|| pattrib->rate == IEEE80211_CCK_RATE_5MB
|
||||
|| pattrib->rate == IEEE80211_CCK_RATE_11MB )
|
||||
pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11B);
|
||||
else
|
||||
pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
|
||||
#endif
|
||||
|
||||
// We have to reset other attributes that may have been set prior for MCS/VHT rates
|
||||
pattrib->ht_en = _FALSE;
|
||||
pattrib->ampdu_en = _FALSE;
|
||||
pattrib->sgi = _FALSE;
|
||||
pattrib->ldpc = _FALSE;
|
||||
pattrib->stbc = 0;
|
||||
pattrib->bwmode = CHANNEL_WIDTH_20;
|
||||
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
|
||||
|
||||
break;
|
||||
|
||||
case IEEE80211_RADIOTAP_TX_FLAGS: {
|
||||
u16 txflags = get_unaligned_le16(iterator.this_arg);
|
||||
|
||||
if ((txflags & IEEE80211_RADIOTAP_F_TX_NOACK) == 0)
|
||||
pattrib->retry_ctrl = _TRUE; // Note; already _FALSE by default
|
||||
|
||||
if (txflags & 0x0010) { // Use preconfigured seq num
|
||||
if (len >= sizeof(struct rtw_ieee80211_hdr_3addr)) {
|
||||
pattrib->seqnum = GetSequence(pwlanhdr);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IEEE80211_RADIOTAP_MCS: {
|
||||
u8 mcs_have = iterator.this_arg[0];
|
||||
|
||||
// Set up defaults
|
||||
pattrib->rate = MGN_MCS0;
|
||||
pattrib->bwmode = IEEE80211_RADIOTAP_MCS_BW_20;
|
||||
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
|
||||
pattrib->ht_en = _TRUE;
|
||||
pattrib->sgi = _FALSE;
|
||||
pattrib->ldpc = _FALSE;
|
||||
pattrib->stbc = 0;
|
||||
|
||||
if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
|
||||
|
||||
u8 bw = (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_BW_MASK);
|
||||
if (bw == IEEE80211_RADIOTAP_MCS_BW_20L) {
|
||||
bw = IEEE80211_RADIOTAP_MCS_BW_20;
|
||||
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
|
||||
}
|
||||
if (bw == IEEE80211_RADIOTAP_MCS_BW_20U) {
|
||||
bw = IEEE80211_RADIOTAP_MCS_BW_20;
|
||||
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
|
||||
}
|
||||
|
||||
pattrib->bwmode = bw;
|
||||
}
|
||||
|
||||
if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
|
||||
u8 fixed_rate = iterator.this_arg[2] & 0x7f;
|
||||
if(fixed_rate > 31)
|
||||
fixed_rate = 0;
|
||||
fixed_rate += MGN_MCS0;
|
||||
pattrib->rate = fixed_rate;
|
||||
}
|
||||
|
||||
if ((mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_GI) && (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_SGI))
|
||||
pattrib->sgi = _TRUE;
|
||||
|
||||
if ((mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_FEC) && (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_FEC_LDPC))
|
||||
pattrib->ldpc = _TRUE;
|
||||
|
||||
if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
|
||||
u8 stbc = (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
|
||||
pattrib->stbc = stbc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_80211AC_VHT
|
||||
case IEEE80211_RADIOTAP_VHT: {
|
||||
unsigned int mcs, nss;
|
||||
|
||||
u8 known = iterator.this_arg[0];
|
||||
u8 flags = iterator.this_arg[2];
|
||||
|
||||
// Set up defaults
|
||||
pattrib->stbc = 0;
|
||||
pattrib->sgi = _FALSE;
|
||||
pattrib->bwmode = CHANNEL_WIDTH_20;
|
||||
pattrib->ldpc = _FALSE;
|
||||
pattrib->rate = MGN_VHT1SS_MCS0;
|
||||
pattrib->raid = RATEID_IDX_VHT_1SS;
|
||||
|
||||
// NOTE: this code currently only supports 1SS for radiotap defined rates
|
||||
|
||||
if ((known & IEEE80211_RADIOTAP_VHT_KNOWN_STBC) && (flags & IEEE80211_RADIOTAP_VHT_FLAG_STBC))
|
||||
pattrib->stbc = 1;
|
||||
|
||||
if ((known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) && (flags & IEEE80211_RADIOTAP_VHT_FLAG_SGI))
|
||||
pattrib->sgi = _TRUE;
|
||||
|
||||
if (known & IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) {
|
||||
u8 bw = iterator.this_arg[3] & 0x1F;
|
||||
// NOTE: there are various L and U, but we just use straight 20/40/80
|
||||
// since it's not clear how to set CHNL_OFFSET_LOWER/_UPPER with different
|
||||
// sideband sizes/configurations. TODO.
|
||||
// Also, any 160 is treated as 80 due to lack of WIDTH_160.
|
||||
if (bw == 0)
|
||||
pattrib->bwmode = CHANNEL_WIDTH_20;
|
||||
else if (bw >=1 && bw <= 3)
|
||||
pattrib->bwmode = CHANNEL_WIDTH_40;
|
||||
else if (bw >=4 && bw <= 10)
|
||||
pattrib->bwmode = CHANNEL_WIDTH_80;
|
||||
else if (bw >= 11 && bw <= 25)
|
||||
pattrib->bwmode = CHANNEL_WIDTH_80; // Supposed to be 160Mhz, we use 80Mhz
|
||||
}
|
||||
|
||||
// User 0
|
||||
nss = iterator.this_arg[4] & 0x0F; // Number of spatial streams
|
||||
if (nss > 0) {
|
||||
if (nss > 4) nss = 4;
|
||||
mcs = (iterator.this_arg[4]>>4) & 0x0F; // MCS rate index
|
||||
if (mcs > 8) mcs = 9;
|
||||
pattrib->rate = MGN_VHT1SS_MCS0 + ((nss-1)*10 + mcs);
|
||||
|
||||
if (iterator.this_arg[8] & IEEE80211_RADIOTAP_CODING_LDPC_USER0)
|
||||
pattrib->ldpc = _TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
#endif // CONFIG_80211AC_VHT
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_CUSTOMER_ALIBABA_GENERAL
|
||||
|
||||
dump_mgntframe(padapter, pmgntframe);
|
||||
/* nrm */
|
||||
pxmitpriv->tx_pkts++;
|
||||
pxmitpriv->tx_bytes += skb->len;
|
||||
|
||||
fail:
|
||||
rtw_skb_free(skb);
|
||||
|
@ -3216,7 +3216,8 @@ static void fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
|
||||
if (pattrib->retry_ctrl == _TRUE)
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(pbuf, 6);
|
||||
else
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(pbuf, 12);
|
||||
/* nrm */
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(pbuf, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XMIT_ACK
|
||||
|
@ -314,7 +314,8 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
|
||||
if (pattrib->retry_ctrl == _TRUE)
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(ptxdesc, 6);
|
||||
else
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(ptxdesc, 12);
|
||||
/* nrm */
|
||||
SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(ptxdesc, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XMIT_ACK
|
||||
|
Loading…
Reference in New Issue
Block a user