diff options
Diffstat (limited to 'drivers/staging/r8188eu/core/rtw_recv.c')
-rw-r--r-- | drivers/staging/r8188eu/core/rtw_recv.c | 319 |
1 files changed, 133 insertions, 186 deletions
diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c index 8800ea4825ff..df518439aea2 100644 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ b/drivers/staging/r8188eu/core/rtw_recv.c @@ -71,7 +71,6 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) list_add_tail(&precvframe->list, &precvpriv->free_recv_queue.queue); - precvframe->pkt_newalloc = NULL; precvframe->pkt = NULL; precvframe->len = 0; @@ -81,8 +80,6 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) } precvpriv->rx_pending_cnt = 1; - sema_init(&precvpriv->allrxreturnevt, 0); - res = rtl8188eu_init_recv_priv(padapter); timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl, 0); @@ -749,6 +746,7 @@ static int sta2ap_data_frame(struct adapter *adapter, struct sta_priv *pstapriv = &adapter->stapriv; struct mlme_priv *pmlmepriv = &adapter->mlmepriv; u8 *ptr = precv_frame->rx_data; + __le16 fc = *(__le16 *)ptr; unsigned char *mybssid = get_bssid(pmlmepriv); int ret = _SUCCESS; @@ -769,9 +767,8 @@ static int sta2ap_data_frame(struct adapter *adapter, process_pwrbit_data(adapter, precv_frame); - if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { + if (ieee80211_is_data_qos(fc)) process_wmmps_data(adapter, precv_frame); - } if (GetFrameSubType(ptr) & BIT(6)) { /* No data, will not indicate to upper layer, temporily count it here */ @@ -795,143 +792,135 @@ exit: return ret; } -static int validate_recv_ctrl_frame(struct adapter *padapter, - struct recv_frame *precv_frame) +static void validate_recv_ctrl_frame(struct adapter *padapter, + struct recv_frame *precv_frame) { struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct sta_priv *pstapriv = &padapter->stapriv; - u8 *pframe = precv_frame->rx_data; - /* uint len = precv_frame->len; */ - - if (GetFrameType(pframe) != WIFI_CTRL_TYPE) - return _FAIL; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; + struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)hdr; + u8 wmmps_ac; + struct sta_info *psta; /* receive the frames that ra(a1) is my address */ - if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN)) - return _FAIL; + if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN)) + return; /* only handle ps-poll */ - if (GetFrameSubType(pframe) == WIFI_PSPOLL) { - u16 aid; - u8 wmmps_ac = 0; - struct sta_info *psta = NULL; + if (!ieee80211_is_pspoll(hdr->frame_control)) + return; - aid = GetAid(pframe); - psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); + psta = rtw_get_stainfo(pstapriv, hdr->addr2); + if (!psta || psta->aid != (le16_to_cpu(pspoll->aid) & 0x3FFF)) + return; - if (!psta || psta->aid != aid) - return _FAIL; + /* for rx pkt statistics */ + psta->sta_stats.rx_ctrl_pkts++; - /* for rx pkt statistics */ - psta->sta_stats.rx_ctrl_pkts++; + switch (pattrib->priority) { + case 1: + case 2: + wmmps_ac = psta->uapsd_bk & BIT(0); + break; + case 4: + case 5: + wmmps_ac = psta->uapsd_vi & BIT(0); + break; + case 6: + case 7: + wmmps_ac = psta->uapsd_vo & BIT(0); + break; + case 0: + case 3: + default: + wmmps_ac = psta->uapsd_be & BIT(0); + break; + } - switch (pattrib->priority) { - case 1: - case 2: - wmmps_ac = psta->uapsd_bk & BIT(0); - break; - case 4: - case 5: - wmmps_ac = psta->uapsd_vi & BIT(0); - break; - case 6: - case 7: - wmmps_ac = psta->uapsd_vo & BIT(0); - break; - case 0: - case 3: - default: - wmmps_ac = psta->uapsd_be & BIT(0); - break; - } + if (wmmps_ac) + return; - if (wmmps_ac) - return _FAIL; + if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { + psta->expire_to = pstapriv->expire_to; + psta->state ^= WIFI_STA_ALIVE_CHK_STATE; + } - if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { - psta->expire_to = pstapriv->expire_to; - psta->state ^= WIFI_STA_ALIVE_CHK_STATE; - } + if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) { + struct list_head *xmitframe_plist, *xmitframe_phead; + struct xmit_frame *pxmitframe = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) { - struct list_head *xmitframe_plist, *xmitframe_phead; - struct xmit_frame *pxmitframe = NULL; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + spin_lock_bh(&pxmitpriv->lock); - spin_lock_bh(&pxmitpriv->lock); + xmitframe_phead = get_list_head(&psta->sleep_q); + xmitframe_plist = xmitframe_phead->next; - xmitframe_phead = get_list_head(&psta->sleep_q); - xmitframe_plist = xmitframe_phead->next; + if (xmitframe_phead != xmitframe_plist) { + pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); - if (xmitframe_phead != xmitframe_plist) { - pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); + xmitframe_plist = xmitframe_plist->next; - xmitframe_plist = xmitframe_plist->next; + list_del_init(&pxmitframe->list); - list_del_init(&pxmitframe->list); + psta->sleepq_len--; - psta->sleepq_len--; + if (psta->sleepq_len > 0) + pxmitframe->attrib.mdata = 1; + else + pxmitframe->attrib.mdata = 0; - if (psta->sleepq_len > 0) - pxmitframe->attrib.mdata = 1; - else - pxmitframe->attrib.mdata = 0; + pxmitframe->attrib.triggered = 1; - pxmitframe->attrib.triggered = 1; + if (psta->sleepq_len == 0) { + pstapriv->tim_bitmap &= ~BIT(psta->aid); - if (psta->sleepq_len == 0) { - pstapriv->tim_bitmap &= ~BIT(psta->aid); + /* upate BCN for TIM IE */ + /* update_BCNTIM(padapter); */ + update_beacon(padapter, _TIM_IE_, NULL, false); + } + } else { + if (pstapriv->tim_bitmap & BIT(psta->aid)) { + if (psta->sleepq_len == 0) + /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ + issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); + else + psta->sleepq_len = 0; - /* upate BCN for TIM IE */ - /* update_BCNTIM(padapter); */ - update_beacon(padapter, _TIM_IE_, NULL, false); - } - } else { - if (pstapriv->tim_bitmap & BIT(psta->aid)) { - if (psta->sleepq_len == 0) - /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ - issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); - else - psta->sleepq_len = 0; - - pstapriv->tim_bitmap &= ~BIT(psta->aid); - - /* upate BCN for TIM IE */ - /* update_BCNTIM(padapter); */ - update_beacon(padapter, _TIM_IE_, NULL, false); - } + pstapriv->tim_bitmap &= ~BIT(psta->aid); + + /* upate BCN for TIM IE */ + /* update_BCNTIM(padapter); */ + update_beacon(padapter, _TIM_IE_, NULL, false); } - spin_unlock_bh(&pxmitpriv->lock); } + spin_unlock_bh(&pxmitpriv->lock); } - - return _FAIL; } struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame); -static int validate_recv_mgnt_frame(struct adapter *padapter, - struct recv_frame *precv_frame) +static void validate_recv_mgnt_frame(struct adapter *padapter, + struct recv_frame *precv_frame) { struct sta_info *psta; + struct ieee80211_hdr *hdr; precv_frame = recvframe_chk_defrag(padapter, precv_frame); if (!precv_frame) - return _SUCCESS; + return; - /* for rx pkt statistics */ - psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->rx_data)); + hdr = (struct ieee80211_hdr *)precv_frame->rx_data; + psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2); if (psta) { psta->sta_stats.rx_mgnt_pkts++; - if (GetFrameSubType(precv_frame->rx_data) == WIFI_BEACON) { + if (ieee80211_is_beacon(hdr->frame_control)) psta->sta_stats.rx_beacon_pkts++; - } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBEREQ) { + else if (ieee80211_is_probe_req(hdr->frame_control)) psta->sta_stats.rx_probereq_pkts++; - } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBERSP) { - if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->rx_data), ETH_ALEN)) + else if (ieee80211_is_probe_resp(hdr->frame_control)) { + if (!memcmp(padapter->eeprompriv.mac_addr, hdr->addr1, ETH_ALEN)) psta->sta_stats.rx_probersp_pkts++; - else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)) || - is_multicast_mac_addr(GetAddr1Ptr(precv_frame->rx_data))) + else if (is_broadcast_mac_addr(hdr->addr1) || is_multicast_mac_addr(hdr->addr1)) psta->sta_stats.rx_probersp_bm_pkts++; else psta->sta_stats.rx_probersp_uo_pkts++; @@ -939,72 +928,44 @@ static int validate_recv_mgnt_frame(struct adapter *padapter, } mgt_dispatcher(padapter, precv_frame); - - return _SUCCESS; } static int validate_recv_data_frame(struct adapter *adapter, struct recv_frame *precv_frame) { - u8 bretry; - u8 *psa, *pda, *pbssid; struct sta_info *psta = NULL; u8 *ptr = precv_frame->rx_data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; struct security_priv *psecuritypriv = &adapter->securitypriv; - int ret = _SUCCESS; - - bretry = GetRetry(ptr); - pda = get_da(ptr); - psa = get_sa(ptr); - pbssid = get_hdr_bssid(ptr); + int ret; - if (!pbssid) { - ret = _FAIL; - goto exit; - } + memcpy(pattrib->dst, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(pattrib->src, ieee80211_get_SA(hdr), ETH_ALEN); - memcpy(pattrib->dst, pda, ETH_ALEN); - memcpy(pattrib->src, psa, ETH_ALEN); + /* address4 is used only if both to_ds and from_ds are set */ + if (ieee80211_has_a4(hdr->frame_control)) + return _FAIL; - memcpy(pattrib->bssid, pbssid, ETH_ALEN); + memcpy(pattrib->ra, hdr->addr1, ETH_ALEN); + memcpy(pattrib->ta, hdr->addr2, ETH_ALEN); - switch (pattrib->to_fr_ds) { - case 0: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); - ret = sta2sta_data_frame(adapter, precv_frame, &psta); - break; - case 1: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, pbssid, ETH_ALEN); + if (ieee80211_has_fromds(hdr->frame_control)) { + memcpy(pattrib->bssid, hdr->addr2, ETH_ALEN); ret = ap2sta_data_frame(adapter, precv_frame, &psta); - break; - case 2: - memcpy(pattrib->ra, pbssid, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); + } else if (ieee80211_has_tods(hdr->frame_control)) { + memcpy(pattrib->bssid, hdr->addr1, ETH_ALEN); ret = sta2ap_data_frame(adapter, precv_frame, &psta); - break; - case 3: - memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); - ret = _FAIL; - break; - default: - ret = _FAIL; - break; + } else { + memcpy(pattrib->bssid, hdr->addr3, ETH_ALEN); + ret = sta2sta_data_frame(adapter, precv_frame, &psta); } - if (ret == _FAIL) { - goto exit; - } else if (ret == RTW_RX_HANDLED) { - goto exit; - } + if (ret == _FAIL || ret == RTW_RX_HANDLED) + return ret; - if (!psta) { - ret = _FAIL; - goto exit; - } + if (!psta) + return _FAIL; /* psta->rssi = prxcmd->rssi; */ /* psta->signal_quality = prxcmd->sq; */ @@ -1014,16 +975,16 @@ static int validate_recv_data_frame(struct adapter *adapter, pattrib->ack_policy = 0; /* parsing QC field */ if (pattrib->qos) { - pattrib->priority = GetPriority((ptr + 24)); + pattrib->priority = ieee80211_get_tid(hdr); pattrib->ack_policy = GetAckpolicy((ptr + 24)); pattrib->amsdu = GetAMsdu((ptr + 24)); - pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; + pattrib->hdrlen = 26; if (pattrib->priority != 0 && pattrib->priority != 3) adapter->recvpriv.bIsAnyNonBEPkts = true; } else { pattrib->priority = 0; - pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24; + pattrib->hdrlen = 24; } if (pattrib->order)/* HT-CTRL 11n */ @@ -1032,10 +993,9 @@ static int validate_recv_data_frame(struct adapter *adapter, precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; /* decache, drop duplicate recv packets */ - if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) { - ret = _FAIL; - goto exit; - } + if (recv_decache(precv_frame, ieee80211_has_retry(hdr->frame_control), + &psta->sta_recvpriv.rxcache) == _FAIL) + return _FAIL; if (pattrib->privacy) { GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra)); @@ -1047,9 +1007,7 @@ static int validate_recv_data_frame(struct adapter *adapter, pattrib->icv_len = 0; } -exit: - - return ret; + return _SUCCESS; } static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv_frame) @@ -1059,11 +1017,8 @@ static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv /* then call check if rx seq/frag. duplicated. */ int retval = _FAIL; - u8 bDumpRxPkt; struct rx_pkt_attrib *pattrib = &precv_frame->attrib; - u8 *ptr = precv_frame->rx_data; - __le16 fc = *(__le16 *)ptr; - u8 ver = (unsigned char)(*ptr) & 0x3; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { @@ -1072,32 +1027,26 @@ static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv pmlmeext->channel_set[ch_set_idx].rx_count++; } - /* add version chk */ - if (ver != 0) + if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_VERS)) != 0) return _FAIL; - pattrib->to_fr_ds = get_tofr_ds(ptr); - - pattrib->frag_num = GetFragNum(ptr); - pattrib->seq_num = GetSequence(ptr); + pattrib->frag_num = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; + pattrib->seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - pattrib->pw_save = GetPwrMgt(ptr); - pattrib->mfrag = ieee80211_has_morefrags(fc); - pattrib->mdata = ieee80211_has_moredata(fc); - pattrib->privacy = ieee80211_has_protected(fc); - pattrib->order = ieee80211_has_order(fc); - - /* Dump rx packets */ - GetHalDefVar8188EUsb(adapter, HAL_DEF_DBG_DUMP_RXPKT, &bDumpRxPkt); + pattrib->pw_save = ieee80211_has_pm(hdr->frame_control); + pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control); + pattrib->mdata = ieee80211_has_moredata(hdr->frame_control); + pattrib->privacy = ieee80211_has_protected(hdr->frame_control); + pattrib->order = ieee80211_has_order(hdr->frame_control); /* We return _SUCCESS only for data frames. */ - if (ieee80211_is_mgmt(fc)) + if (ieee80211_is_mgmt(hdr->frame_control)) validate_recv_mgnt_frame(adapter, precv_frame); - else if (ieee80211_is_ctl(fc)) + else if (ieee80211_is_ctl(hdr->frame_control)) validate_recv_ctrl_frame(adapter, precv_frame); - else if (ieee80211_is_data(fc)) { + else if (ieee80211_is_data(hdr->frame_control)) { rtw_led_control(adapter, LED_CTL_RX); - pattrib->qos = ieee80211_is_data_qos(fc); + pattrib->qos = ieee80211_is_data_qos(hdr->frame_control); retval = validate_recv_data_frame(adapter, precv_frame); if (retval == _FAIL) { struct recv_priv *precvpriv = &adapter->recvpriv; @@ -1284,8 +1233,9 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_fr psta_addr = pfhdr->attrib.ta; psta = rtw_get_stainfo(pstapriv, psta_addr); if (!psta) { - u8 type = GetFrameType(pfhdr->rx_data); - if (type != WIFI_DATA_TYPE) { + __le16 fc = *(__le16 *)pfhdr->rx_data; + + if (ieee80211_is_data(fc)) { psta = rtw_get_bcmc_stainfo(padapter); pdefrag_q = &psta->sta_recvpriv.defrag_q; } else { @@ -1723,12 +1673,9 @@ static int recv_func_prehandle(struct adapter *padapter, struct recv_frame *rfra /* check the frame crtl field and decache */ ret = validate_recv_frame(padapter, rframe); - if (ret != _SUCCESS) { + if (ret != _SUCCESS) rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ - goto exit; - } -exit: return ret; } |