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

rx.c (5348B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * This file is part of wl1251
      4 *
      5 * Copyright (c) 1998-2007 Texas Instruments Incorporated
      6 * Copyright (C) 2008 Nokia Corporation
      7 */
      8
      9#include <linux/skbuff.h>
     10#include <linux/gfp.h>
     11#include <net/mac80211.h>
     12
     13#include "wl1251.h"
     14#include "reg.h"
     15#include "io.h"
     16#include "rx.h"
     17#include "cmd.h"
     18#include "acx.h"
     19
     20static void wl1251_rx_header(struct wl1251 *wl,
     21			     struct wl1251_rx_descriptor *desc)
     22{
     23	u32 rx_packet_ring_addr;
     24
     25	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
     26	if (wl->rx_current_buffer)
     27		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
     28
     29	wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
     30}
     31
     32static void wl1251_rx_status(struct wl1251 *wl,
     33			     struct wl1251_rx_descriptor *desc,
     34			     struct ieee80211_rx_status *status,
     35			     u8 beacon)
     36{
     37	u64 mactime;
     38	int ret;
     39
     40	memset(status, 0, sizeof(struct ieee80211_rx_status));
     41
     42	status->band = NL80211_BAND_2GHZ;
     43	status->mactime = desc->timestamp;
     44
     45	/*
     46	 * The rx status timestamp is a 32 bits value while the TSF is a
     47	 * 64 bits one.
     48	 * For IBSS merging, TSF is mandatory, so we have to get it
     49	 * somehow, so we ask for ACX_TSF_INFO.
     50	 * That could be moved to the get_tsf() hook, but unfortunately,
     51	 * this one must be atomic, while our SPI routines can sleep.
     52	 */
     53	if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
     54		ret = wl1251_acx_tsf_info(wl, &mactime);
     55		if (ret == 0)
     56			status->mactime = mactime;
     57	}
     58
     59	status->signal = desc->rssi;
     60
     61	/*
     62	 * FIXME: guessing that snr needs to be divided by two, otherwise
     63	 * the values don't make any sense
     64	 */
     65	wl->noise = desc->rssi - desc->snr / 2;
     66
     67	status->freq = ieee80211_channel_to_frequency(desc->channel,
     68						      status->band);
     69
     70	status->flag |= RX_FLAG_MACTIME_START;
     71
     72	if (!wl->monitor_present && (desc->flags & RX_DESC_ENCRYPTION_MASK)) {
     73		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
     74
     75		if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
     76			status->flag |= RX_FLAG_DECRYPTED;
     77
     78		if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
     79			status->flag |= RX_FLAG_MMIC_ERROR;
     80	}
     81
     82	if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
     83		status->flag |= RX_FLAG_FAILED_FCS_CRC;
     84
     85	switch (desc->rate) {
     86		/* skip 1 and 12 Mbps because they have same value 0x0a */
     87	case RATE_2MBPS:
     88		status->rate_idx = 1;
     89		break;
     90	case RATE_5_5MBPS:
     91		status->rate_idx = 2;
     92		break;
     93	case RATE_11MBPS:
     94		status->rate_idx = 3;
     95		break;
     96	case RATE_6MBPS:
     97		status->rate_idx = 4;
     98		break;
     99	case RATE_9MBPS:
    100		status->rate_idx = 5;
    101		break;
    102	case RATE_18MBPS:
    103		status->rate_idx = 7;
    104		break;
    105	case RATE_24MBPS:
    106		status->rate_idx = 8;
    107		break;
    108	case RATE_36MBPS:
    109		status->rate_idx = 9;
    110		break;
    111	case RATE_48MBPS:
    112		status->rate_idx = 10;
    113		break;
    114	case RATE_54MBPS:
    115		status->rate_idx = 11;
    116		break;
    117	}
    118
    119	/* for 1 and 12 Mbps we have to check the modulation */
    120	if (desc->rate == RATE_1MBPS) {
    121		if (!(desc->mod_pre & OFDM_RATE_BIT))
    122			/* CCK -> RATE_1MBPS */
    123			status->rate_idx = 0;
    124		else
    125			/* OFDM -> RATE_12MBPS */
    126			status->rate_idx = 6;
    127	}
    128
    129	if (desc->mod_pre & SHORT_PREAMBLE_BIT)
    130		status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
    131}
    132
    133static void wl1251_rx_body(struct wl1251 *wl,
    134			   struct wl1251_rx_descriptor *desc)
    135{
    136	struct sk_buff *skb;
    137	struct ieee80211_rx_status status;
    138	u8 *rx_buffer, beacon = 0;
    139	u16 length, *fc;
    140	u32 curr_id, last_id_inc, rx_packet_ring_addr;
    141
    142	length = WL1251_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
    143	curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
    144	last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
    145
    146	if (last_id_inc != curr_id) {
    147		wl1251_warning("curr ID:%d, last ID inc:%d",
    148			       curr_id, last_id_inc);
    149		wl->rx_last_id = curr_id;
    150	} else {
    151		wl->rx_last_id = last_id_inc;
    152	}
    153
    154	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
    155		sizeof(struct wl1251_rx_descriptor) + 20;
    156	if (wl->rx_current_buffer)
    157		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
    158
    159	skb = __dev_alloc_skb(length, GFP_KERNEL);
    160	if (!skb) {
    161		wl1251_error("Couldn't allocate RX frame");
    162		return;
    163	}
    164
    165	rx_buffer = skb_put(skb, length);
    166	wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
    167
    168	/* The actual length doesn't include the target's alignment */
    169	skb_trim(skb, desc->length - PLCP_HEADER_LENGTH);
    170
    171	fc = (u16 *)skb->data;
    172
    173	if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
    174		beacon = 1;
    175
    176	wl1251_rx_status(wl, desc, &status, beacon);
    177
    178	wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
    179		     beacon ? "beacon" : "");
    180
    181	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
    182	ieee80211_rx_ni(wl->hw, skb);
    183}
    184
    185static void wl1251_rx_ack(struct wl1251 *wl)
    186{
    187	u32 data, addr;
    188
    189	if (wl->rx_current_buffer) {
    190		addr = ACX_REG_INTERRUPT_TRIG_H;
    191		data = INTR_TRIG_RX_PROC1;
    192	} else {
    193		addr = ACX_REG_INTERRUPT_TRIG;
    194		data = INTR_TRIG_RX_PROC0;
    195	}
    196
    197	wl1251_reg_write32(wl, addr, data);
    198
    199	/* Toggle buffer ring */
    200	wl->rx_current_buffer = !wl->rx_current_buffer;
    201}
    202
    203
    204void wl1251_rx(struct wl1251 *wl)
    205{
    206	struct wl1251_rx_descriptor *rx_desc;
    207
    208	if (wl->state != WL1251_STATE_ON)
    209		return;
    210
    211	rx_desc = wl->rx_descriptor;
    212
    213	/* We first read the frame's header */
    214	wl1251_rx_header(wl, rx_desc);
    215
    216	/* Now we can read the body */
    217	wl1251_rx_body(wl, rx_desc);
    218
    219	/* Finally, we need to ACK the RX */
    220	wl1251_rx_ack(wl);
    221}