0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/etherdevice.h>
0009 #include <net/mac80211.h>
0010
0011 #include "data_rx.h"
0012 #include "wfx.h"
0013 #include "bh.h"
0014 #include "sta.h"
0015
0016 static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt)
0017 {
0018 struct ieee80211_vif *vif = wvif_to_vif(wvif);
0019 int params, tid;
0020
0021 if (wfx_api_older_than(wvif->wdev, 3, 6))
0022 return;
0023
0024 switch (mgmt->u.action.u.addba_req.action_code) {
0025 case WLAN_ACTION_ADDBA_REQ:
0026 params = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
0027 tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
0028 ieee80211_start_rx_ba_session_offl(vif, mgmt->sa, tid);
0029 break;
0030 case WLAN_ACTION_DELBA:
0031 params = le16_to_cpu(mgmt->u.action.u.delba.params);
0032 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
0033 ieee80211_stop_rx_ba_session_offl(vif, mgmt->sa, tid);
0034 break;
0035 }
0036 }
0037
0038 void wfx_rx_cb(struct wfx_vif *wvif, const struct wfx_hif_ind_rx *arg, struct sk_buff *skb)
0039 {
0040 struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
0041 struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
0042 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
0043
0044 memset(hdr, 0, sizeof(*hdr));
0045
0046 if (arg->status == HIF_STATUS_RX_FAIL_MIC)
0047 hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED;
0048 else if (arg->status)
0049 goto drop;
0050
0051 if (skb->len < sizeof(struct ieee80211_pspoll)) {
0052 dev_warn(wvif->wdev->dev, "malformed SDU received\n");
0053 goto drop;
0054 }
0055
0056 hdr->band = NL80211_BAND_2GHZ;
0057 hdr->freq = ieee80211_channel_to_frequency(arg->channel_number, hdr->band);
0058
0059 if (arg->rxed_rate >= 14) {
0060 hdr->encoding = RX_ENC_HT;
0061 hdr->rate_idx = arg->rxed_rate - 14;
0062 } else if (arg->rxed_rate >= 4) {
0063 hdr->rate_idx = arg->rxed_rate - 2;
0064 } else {
0065 hdr->rate_idx = arg->rxed_rate;
0066 }
0067
0068 if (!arg->rcpi_rssi) {
0069 hdr->flag |= RX_FLAG_NO_SIGNAL_VAL;
0070 dev_info(wvif->wdev->dev, "received frame without RSSI data\n");
0071 }
0072 hdr->signal = arg->rcpi_rssi / 2 - 110;
0073 hdr->antenna = 0;
0074
0075 if (arg->encryp)
0076 hdr->flag |= RX_FLAG_DECRYPTED;
0077
0078
0079
0080
0081 if (ieee80211_is_action(frame->frame_control) &&
0082 mgmt->u.action.category == WLAN_CATEGORY_BACK &&
0083 skb->len > IEEE80211_MIN_ACTION_SIZE) {
0084 wfx_rx_handle_ba(wvif, mgmt);
0085 goto drop;
0086 }
0087
0088 ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
0089 return;
0090
0091 drop:
0092 dev_kfree_skb(skb);
0093 }