1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * File: dpc.c
7  *
8  * Purpose: handle dpc rx functions
9  *
10  * Author: Lyndon Chen
11  *
12  * Date: May 20, 2003
13  *
14  * Functions:
15  *
16  * Revision History:
17  *
18  */
19 
20 #include "dpc.h"
21 #include "device.h"
22 #include "mac.h"
23 #include "baseband.h"
24 #include "rf.h"
25 
vnt_rx_data(struct vnt_private * priv,struct vnt_rcb * ptr_rcb,unsigned long bytes_received)26 int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
27 		unsigned long bytes_received)
28 {
29 	struct ieee80211_hw *hw = priv->hw;
30 	struct ieee80211_supported_band *sband;
31 	struct sk_buff *skb;
32 	struct ieee80211_rx_status rx_status = { 0 };
33 	struct ieee80211_hdr *hdr;
34 	__le16 fc;
35 	u8 *rsr, *new_rsr, *rssi;
36 	__le64 *tsf_time;
37 	u32 frame_size;
38 	int ii, r;
39 	u8 *rx_rate, *sq, *sq_3;
40 	u32 wbk_status;
41 	u8 *skb_data;
42 	u16 *pay_load_len;
43 	u16 pay_load_with_padding;
44 	u8 rate_idx = 0;
45 	u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
46 	long rx_dbm;
47 
48 	skb = ptr_rcb->skb;
49 
50 	/* [31:16]RcvByteCount ( not include 4-byte Status ) */
51 	wbk_status = *((u32 *)(skb->data));
52 	frame_size = wbk_status >> 16;
53 	frame_size += 4;
54 
55 	if (bytes_received != frame_size) {
56 		dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n");
57 		return false;
58 	}
59 
60 	if ((bytes_received > 2372) || (bytes_received <= 40)) {
61 		/* Frame Size error drop this packet.*/
62 		dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n");
63 		return false;
64 	}
65 
66 	skb_data = (u8 *)skb->data;
67 
68 	rx_rate = skb_data + 5;
69 
70 	/* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
71 	/* -8TSF - 4RSR - 4SQ3 - ?Padding */
72 
73 	/* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
74 
75 	pay_load_len = (u16 *)(skb_data + 6);
76 
77 	/*Fix hardware bug => PLCP_Length error */
78 	if (((bytes_received - (*pay_load_len)) > 27) ||
79 	    ((bytes_received - (*pay_load_len)) < 24) ||
80 	    (bytes_received < (*pay_load_len))) {
81 		dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
82 			*pay_load_len);
83 		return false;
84 	}
85 
86 	sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
87 
88 	for (r = RATE_1M; r < MAX_RATE; r++) {
89 		if (*rx_rate == rate[r])
90 			break;
91 	}
92 
93 	priv->rx_rate = r;
94 
95 	for (ii = 0; ii < sband->n_bitrates; ii++) {
96 		if (sband->bitrates[ii].hw_value == r) {
97 			rate_idx = ii;
98 				break;
99 		}
100 	}
101 
102 	if (ii == sband->n_bitrates) {
103 		dev_dbg(&priv->usb->dev, "Wrong RxRate %x\n", *rx_rate);
104 		return false;
105 	}
106 
107 	pay_load_with_padding = ((*pay_load_len / 4) +
108 		((*pay_load_len % 4) ? 1 : 0)) * 4;
109 
110 	tsf_time = (__le64 *)(skb_data + 8 + pay_load_with_padding);
111 
112 	priv->tsf_time = le64_to_cpu(*tsf_time);
113 
114 	if (priv->bb_type == BB_TYPE_11G) {
115 		sq_3 = skb_data + 8 + pay_load_with_padding + 12;
116 		sq = sq_3;
117 	} else {
118 		sq = skb_data + 8 + pay_load_with_padding + 8;
119 		sq_3 = sq;
120 	}
121 
122 	new_rsr = skb_data + 8 + pay_load_with_padding + 9;
123 	rssi = skb_data + 8 + pay_load_with_padding + 10;
124 
125 	rsr = skb_data + 8 + pay_load_with_padding + 11;
126 	if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
127 		return false;
128 
129 	frame_size = *pay_load_len;
130 
131 	vnt_rf_rssi_to_dbm(priv, *rssi, &rx_dbm);
132 
133 	priv->bb_pre_ed_rssi = (u8)rx_dbm + 1;
134 	priv->current_rssi = priv->bb_pre_ed_rssi;
135 
136 	skb_pull(skb, 8);
137 	skb_trim(skb, frame_size);
138 
139 	rx_status.mactime = priv->tsf_time;
140 	rx_status.band = hw->conf.chandef.chan->band;
141 	rx_status.signal = rx_dbm;
142 	rx_status.flag = 0;
143 	rx_status.freq = hw->conf.chandef.chan->center_freq;
144 
145 	if (!(*rsr & RSR_CRCOK))
146 		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
147 
148 	hdr = (struct ieee80211_hdr *)(skb->data);
149 	fc = hdr->frame_control;
150 
151 	rx_status.rate_idx = rate_idx;
152 
153 	if (ieee80211_has_protected(fc)) {
154 		if (priv->local_id > REV_ID_VT3253_A1) {
155 			rx_status.flag |= RX_FLAG_DECRYPTED;
156 
157 			/* Drop packet */
158 			if (!(*new_rsr & NEWRSR_DECRYPTOK)) {
159 				dev_kfree_skb(skb);
160 				return true;
161 			}
162 		}
163 	}
164 
165 	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
166 
167 	ieee80211_rx_irqsafe(priv->hw, skb);
168 
169 	return true;
170 }
171