cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

data_rx.c (2533B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Data receiving implementation.
      4 *
      5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
      6 * Copyright (c) 2010, ST-Ericsson
      7 */
      8#include <linux/etherdevice.h>
      9#include <net/mac80211.h>
     10
     11#include "data_rx.h"
     12#include "wfx.h"
     13#include "bh.h"
     14#include "sta.h"
     15
     16static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt)
     17{
     18	struct ieee80211_vif *vif = wvif_to_vif(wvif);
     19	int params, tid;
     20
     21	if (wfx_api_older_than(wvif->wdev, 3, 6))
     22		return;
     23
     24	switch (mgmt->u.action.u.addba_req.action_code) {
     25	case WLAN_ACTION_ADDBA_REQ:
     26		params = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
     27		tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
     28		ieee80211_start_rx_ba_session_offl(vif, mgmt->sa, tid);
     29		break;
     30	case WLAN_ACTION_DELBA:
     31		params = le16_to_cpu(mgmt->u.action.u.delba.params);
     32		tid = (params &  IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
     33		ieee80211_stop_rx_ba_session_offl(vif, mgmt->sa, tid);
     34		break;
     35	}
     36}
     37
     38void wfx_rx_cb(struct wfx_vif *wvif, const struct wfx_hif_ind_rx *arg, struct sk_buff *skb)
     39{
     40	struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
     41	struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
     42	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
     43
     44	memset(hdr, 0, sizeof(*hdr));
     45
     46	if (arg->status == HIF_STATUS_RX_FAIL_MIC)
     47		hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED;
     48	else if (arg->status)
     49		goto drop;
     50
     51	if (skb->len < sizeof(struct ieee80211_pspoll)) {
     52		dev_warn(wvif->wdev->dev, "malformed SDU received\n");
     53		goto drop;
     54	}
     55
     56	hdr->band = NL80211_BAND_2GHZ;
     57	hdr->freq = ieee80211_channel_to_frequency(arg->channel_number, hdr->band);
     58
     59	if (arg->rxed_rate >= 14) {
     60		hdr->encoding = RX_ENC_HT;
     61		hdr->rate_idx = arg->rxed_rate - 14;
     62	} else if (arg->rxed_rate >= 4) {
     63		hdr->rate_idx = arg->rxed_rate - 2;
     64	} else {
     65		hdr->rate_idx = arg->rxed_rate;
     66	}
     67
     68	if (!arg->rcpi_rssi) {
     69		hdr->flag |= RX_FLAG_NO_SIGNAL_VAL;
     70		dev_info(wvif->wdev->dev, "received frame without RSSI data\n");
     71	}
     72	hdr->signal = arg->rcpi_rssi / 2 - 110;
     73	hdr->antenna = 0;
     74
     75	if (arg->encryp)
     76		hdr->flag |= RX_FLAG_DECRYPTED;
     77
     78	/* Block ack negotiation is offloaded by the firmware. However, re-ordering must be done by
     79	 * the mac80211.
     80	 */
     81	if (ieee80211_is_action(frame->frame_control) &&
     82	    mgmt->u.action.category == WLAN_CATEGORY_BACK &&
     83	    skb->len > IEEE80211_MIN_ACTION_SIZE) {
     84		wfx_rx_handle_ba(wvif, mgmt);
     85		goto drop;
     86	}
     87
     88	ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
     89	return;
     90
     91drop:
     92	dev_kfree_skb(skb);
     93}