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

usbpipe.c (11640B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
      4 * All rights reserved.
      5 *
      6 * Purpose: Handle USB control endpoint
      7 *
      8 * Author: Warren Hsu
      9 *
     10 * Date: Mar. 29, 2005
     11 *
     12 * Functions:
     13 *	vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM
     14 *	vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM
     15 *	vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM
     16 *	vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM
     17 *
     18 * Revision History:
     19 *      04-05-2004 Jerry Chen: Initial release
     20 *      11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,
     21 *                             ControlvMaskByte
     22 *
     23 */
     24
     25#include "rxtx.h"
     26#include "desc.h"
     27#include "device.h"
     28#include "usbpipe.h"
     29#include "mac.h"
     30#include "rf.h"
     31
     32#define USB_CTL_WAIT	500 /* ms */
     33
     34int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
     35		    u16 index, u16 length, const u8 *buffer)
     36{
     37	int ret = 0;
     38	u8 *usb_buffer;
     39
     40	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) {
     41		ret = -EINVAL;
     42		goto end;
     43	}
     44
     45	mutex_lock(&priv->usb_lock);
     46
     47	usb_buffer = kmemdup(buffer, length, GFP_KERNEL);
     48	if (!usb_buffer) {
     49		ret = -ENOMEM;
     50		goto end_unlock;
     51	}
     52
     53	ret = usb_control_msg(priv->usb,
     54			      usb_sndctrlpipe(priv->usb, 0),
     55			      request, 0x40, value,
     56			      index, usb_buffer, length, USB_CTL_WAIT);
     57
     58	kfree(usb_buffer);
     59
     60	if (ret == (int)length)
     61		ret = 0;
     62	else
     63		ret = -EIO;
     64
     65end_unlock:
     66	mutex_unlock(&priv->usb_lock);
     67end:
     68	return ret;
     69}
     70
     71int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data)
     72{
     73	return vnt_control_out(priv, MESSAGE_TYPE_WRITE,
     74			       reg_off, reg, sizeof(u8), &data);
     75}
     76
     77int vnt_control_out_blocks(struct vnt_private *priv,
     78			   u16 block, u8 reg, u16 length, const u8 *data)
     79{
     80	int ret = 0, i;
     81
     82	for (i = 0; i < length; i += block) {
     83		u16 len = min_t(int, length - i, block);
     84
     85		ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE,
     86				      i, reg, len, data + i);
     87		if (ret)
     88			goto end;
     89	}
     90end:
     91	return ret;
     92}
     93
     94int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
     95		   u16 index, u16 length, u8 *buffer)
     96{
     97	int ret = 0;
     98	u8 *usb_buffer;
     99
    100	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) {
    101		ret = -EINVAL;
    102		goto end;
    103	}
    104
    105	mutex_lock(&priv->usb_lock);
    106
    107	usb_buffer = kmalloc(length, GFP_KERNEL);
    108	if (!usb_buffer) {
    109		ret = -ENOMEM;
    110		goto end_unlock;
    111	}
    112
    113	ret = usb_control_msg(priv->usb,
    114			      usb_rcvctrlpipe(priv->usb, 0),
    115			      request, 0xc0, value,
    116			      index, usb_buffer, length, USB_CTL_WAIT);
    117
    118	if (ret == length)
    119		memcpy(buffer, usb_buffer, length);
    120
    121	kfree(usb_buffer);
    122
    123	if (ret == (int)length)
    124		ret = 0;
    125	else
    126		ret = -EIO;
    127
    128end_unlock:
    129	mutex_unlock(&priv->usb_lock);
    130end:
    131	return ret;
    132}
    133
    134int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data)
    135{
    136	return vnt_control_in(priv, MESSAGE_TYPE_READ,
    137			      reg_off, reg, sizeof(u8), data);
    138}
    139
    140static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr)
    141{
    142	struct vnt_usb_send_context *context;
    143	struct ieee80211_tx_info *info;
    144	u8 tx_retry = (tsr & 0xf0) >> 4;
    145	s8 idx;
    146
    147	if (pkt_no >= priv->num_tx_context)
    148		return -EINVAL;
    149
    150	context = priv->tx_context[pkt_no];
    151
    152	if (!context->skb)
    153		return -EINVAL;
    154
    155	info = IEEE80211_SKB_CB(context->skb);
    156	idx = info->control.rates[0].idx;
    157
    158	ieee80211_tx_info_clear_status(info);
    159
    160	info->status.rates[0].count = tx_retry;
    161
    162	if (!(tsr & TSR_TMO)) {
    163		info->status.rates[0].idx = idx;
    164
    165		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
    166			info->flags |= IEEE80211_TX_STAT_ACK;
    167	}
    168
    169	ieee80211_tx_status_irqsafe(priv->hw, context->skb);
    170
    171	context->in_use = false;
    172
    173	return 0;
    174}
    175
    176static void vnt_int_process_data(struct vnt_private *priv)
    177{
    178	struct vnt_interrupt_data *int_data;
    179	struct ieee80211_low_level_stats *low_stats = &priv->low_stats;
    180
    181	dev_dbg(&priv->usb->dev, "---->s_nsInterruptProcessData\n");
    182
    183	int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf;
    184
    185	if (int_data->tsr0 & TSR_VALID)
    186		vnt_int_report_rate(priv, int_data->pkt0, int_data->tsr0);
    187
    188	if (int_data->tsr1 & TSR_VALID)
    189		vnt_int_report_rate(priv, int_data->pkt1, int_data->tsr1);
    190
    191	if (int_data->tsr2 & TSR_VALID)
    192		vnt_int_report_rate(priv, int_data->pkt2, int_data->tsr2);
    193
    194	if (int_data->tsr3 & TSR_VALID)
    195		vnt_int_report_rate(priv, int_data->pkt3, int_data->tsr3);
    196
    197	if (!int_data->isr0)
    198		return;
    199
    200	if (int_data->isr0 & ISR_BNTX && priv->op_mode == NL80211_IFTYPE_AP)
    201		vnt_schedule_command(priv, WLAN_CMD_BECON_SEND);
    202
    203	priv->current_tsf = le64_to_cpu(int_data->tsf);
    204
    205	low_stats->dot11RTSSuccessCount += int_data->rts_success;
    206	low_stats->dot11RTSFailureCount += int_data->rts_fail;
    207	low_stats->dot11ACKFailureCount += int_data->ack_fail;
    208	low_stats->dot11FCSErrorCount += int_data->fcs_err;
    209}
    210
    211static void vnt_start_interrupt_urb_complete(struct urb *urb)
    212{
    213	struct vnt_private *priv = urb->context;
    214	int status = urb->status;
    215
    216	switch (status) {
    217	case 0:
    218	case -ETIMEDOUT:
    219		break;
    220	case -ECONNRESET:
    221	case -ENOENT:
    222	case -ESHUTDOWN:
    223		return;
    224	default:
    225		break;
    226	}
    227
    228	if (status)
    229		dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status);
    230	else
    231		vnt_int_process_data(priv);
    232
    233	if (!test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
    234		status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC);
    235
    236	if (status)
    237		dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
    238}
    239
    240int vnt_start_interrupt_urb(struct vnt_private *priv)
    241{
    242	int ret = 0;
    243
    244	dev_dbg(&priv->usb->dev, "---->Interrupt Polling Thread\n");
    245
    246	usb_fill_int_urb(priv->interrupt_urb,
    247			 priv->usb,
    248			 usb_rcvintpipe(priv->usb, 1),
    249			 priv->int_buf.data_buf,
    250			 MAX_INTERRUPT_SIZE,
    251			 vnt_start_interrupt_urb_complete,
    252			 priv,
    253			 priv->int_interval);
    254
    255	ret = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC);
    256	if (ret)
    257		dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", ret);
    258
    259	return ret;
    260}
    261
    262static int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
    263		       unsigned long bytes_received)
    264{
    265	struct ieee80211_hw *hw = priv->hw;
    266	struct ieee80211_supported_band *sband;
    267	struct sk_buff *skb;
    268	struct ieee80211_rx_status *rx_status;
    269	struct vnt_rx_header *head;
    270	struct vnt_rx_tail *tail;
    271	u32 frame_size;
    272	int ii;
    273	u16 rx_bitrate, pay_load_with_padding;
    274	u8 rate_idx = 0;
    275	long rx_dbm;
    276
    277	skb = ptr_rcb->skb;
    278	rx_status = IEEE80211_SKB_RXCB(skb);
    279
    280	/* [31:16]RcvByteCount ( not include 4-byte Status ) */
    281	head = (struct vnt_rx_header *)skb->data;
    282	frame_size = head->wbk_status >> 16;
    283	frame_size += 4;
    284
    285	if (bytes_received != frame_size) {
    286		dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n");
    287		return false;
    288	}
    289
    290	if ((bytes_received > 2372) || (bytes_received <= 40)) {
    291		/* Frame Size error drop this packet.*/
    292		dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n");
    293		return false;
    294	}
    295
    296	/* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
    297	/* -8TSF - 4RSR - 4SQ3 - ?Padding */
    298
    299	/* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
    300
    301	/*Fix hardware bug => PLCP_Length error */
    302	if (((bytes_received - head->pay_load_len) > 27) ||
    303	    ((bytes_received - head->pay_load_len) < 24) ||
    304	    (bytes_received < head->pay_load_len)) {
    305		dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
    306			head->pay_load_len);
    307		return false;
    308	}
    309
    310	sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
    311	rx_bitrate = head->rx_rate * 5; /* rx_rate * 5 */
    312
    313	for (ii = 0; ii < sband->n_bitrates; ii++) {
    314		if (sband->bitrates[ii].bitrate == rx_bitrate) {
    315			rate_idx = ii;
    316				break;
    317		}
    318	}
    319
    320	if (ii == sband->n_bitrates) {
    321		dev_dbg(&priv->usb->dev, "Wrong Rx Bit Rate %d\n", rx_bitrate);
    322		return false;
    323	}
    324
    325	pay_load_with_padding = ((head->pay_load_len / 4) +
    326		((head->pay_load_len % 4) ? 1 : 0)) * 4;
    327
    328	tail = (struct vnt_rx_tail *)(skb->data +
    329				      sizeof(*head) + pay_load_with_padding);
    330	priv->tsf_time = le64_to_cpu(tail->tsf_time);
    331
    332	if (tail->rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
    333		return false;
    334
    335	vnt_rf_rssi_to_dbm(priv, tail->rssi, &rx_dbm);
    336
    337	priv->bb_pre_ed_rssi = (u8)-rx_dbm + 1;
    338	priv->current_rssi = priv->bb_pre_ed_rssi;
    339
    340	skb_pull(skb, sizeof(*head));
    341	skb_trim(skb, head->pay_load_len);
    342
    343	rx_status->mactime = priv->tsf_time;
    344	rx_status->band = hw->conf.chandef.chan->band;
    345	rx_status->signal = rx_dbm;
    346	rx_status->flag = 0;
    347	rx_status->freq = hw->conf.chandef.chan->center_freq;
    348
    349	if (!(tail->rsr & RSR_CRCOK))
    350		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
    351
    352	rx_status->rate_idx = rate_idx;
    353
    354	if (tail->new_rsr & NEWRSR_DECRYPTOK)
    355		rx_status->flag |= RX_FLAG_DECRYPTED;
    356
    357	ieee80211_rx_irqsafe(priv->hw, skb);
    358
    359	return true;
    360}
    361
    362static void vnt_submit_rx_urb_complete(struct urb *urb)
    363{
    364	struct vnt_rcb *rcb = urb->context;
    365	struct vnt_private *priv = rcb->priv;
    366
    367	switch (urb->status) {
    368	case 0:
    369		break;
    370	case -ECONNRESET:
    371	case -ENOENT:
    372	case -ESHUTDOWN:
    373		return;
    374	case -ETIMEDOUT:
    375	default:
    376		dev_dbg(&priv->usb->dev, "BULK In failed %d\n", urb->status);
    377		break;
    378	}
    379
    380	if (urb->actual_length) {
    381		if (vnt_rx_data(priv, rcb, urb->actual_length)) {
    382			rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
    383			if (!rcb->skb)
    384				return;
    385		} else {
    386			skb_push(rcb->skb, skb_headroom(rcb->skb));
    387			skb_trim(rcb->skb, 0);
    388		}
    389
    390		urb->transfer_buffer = skb_put(rcb->skb,
    391					       skb_tailroom(rcb->skb));
    392	}
    393
    394	if (usb_submit_urb(urb, GFP_ATOMIC))
    395		dev_dbg(&priv->usb->dev, "Failed to re submit rx skb\n");
    396}
    397
    398int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb)
    399{
    400	int ret = 0;
    401	struct urb *urb = rcb->urb;
    402
    403	if (!rcb->skb) {
    404		dev_dbg(&priv->usb->dev, "rcb->skb is null\n");
    405		ret = -EINVAL;
    406		goto end;
    407	}
    408
    409	usb_fill_bulk_urb(urb,
    410			  priv->usb,
    411			  usb_rcvbulkpipe(priv->usb, 2),
    412			  skb_put(rcb->skb, skb_tailroom(rcb->skb)),
    413			  MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
    414			  vnt_submit_rx_urb_complete,
    415			  rcb);
    416
    417	ret = usb_submit_urb(urb, GFP_ATOMIC);
    418	if (ret)
    419		dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", ret);
    420end:
    421	return ret;
    422}
    423
    424static void vnt_tx_context_complete(struct urb *urb)
    425{
    426	struct vnt_usb_send_context *context = urb->context;
    427	struct vnt_private *priv = context->priv;
    428
    429	switch (urb->status) {
    430	case 0:
    431		dev_dbg(&priv->usb->dev,
    432			"Write %d bytes\n", urb->actual_length);
    433		break;
    434	case -ECONNRESET:
    435	case -ENOENT:
    436	case -ESHUTDOWN:
    437		context->in_use = false;
    438		return;
    439	case -ETIMEDOUT:
    440	default:
    441		dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status);
    442		break;
    443	}
    444
    445	if (context->type == CONTEXT_DATA_PACKET)
    446		ieee80211_wake_queues(priv->hw);
    447
    448	if (urb->status || context->type == CONTEXT_BEACON_PACKET) {
    449		if (context->skb)
    450			ieee80211_free_txskb(priv->hw, context->skb);
    451
    452		context->in_use = false;
    453	}
    454}
    455
    456int vnt_tx_context(struct vnt_private *priv,
    457		   struct vnt_usb_send_context *context,
    458		   struct sk_buff *skb)
    459{
    460	struct vnt_tx_usb_header *usb;
    461	struct urb *urb;
    462	int status;
    463	u16 count = skb->len;
    464
    465	usb = skb_push(skb, sizeof(*usb));
    466	usb->tx_byte_count = cpu_to_le16(count);
    467	usb->pkt_no = context->pkt_no;
    468	usb->type = context->type;
    469
    470	if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) {
    471		context->in_use = false;
    472		return -ENODEV;
    473	}
    474
    475	if (skb->len > MAX_TOTAL_SIZE_WITH_ALL_HEADERS) {
    476		context->in_use = false;
    477		return -E2BIG;
    478	}
    479
    480	urb = usb_alloc_urb(0, GFP_ATOMIC);
    481	if (!urb) {
    482		context->in_use = false;
    483		return -ENOMEM;
    484	}
    485
    486	usb_fill_bulk_urb(urb,
    487			  priv->usb,
    488			  usb_sndbulkpipe(priv->usb, 3),
    489			  skb->data,
    490			  skb->len,
    491			  vnt_tx_context_complete,
    492			  context);
    493
    494	usb_anchor_urb(urb, &priv->tx_submitted);
    495
    496	status = usb_submit_urb(urb, GFP_ATOMIC);
    497	if (status) {
    498		dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status);
    499		usb_unanchor_urb(urb);
    500		context->in_use = false;
    501	}
    502
    503	usb_free_urb(urb);
    504
    505	return status;
    506}