]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/staging/vt6656/dpc.c
Merge tag 'for-linus-5.6-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / staging / vt6656 / dpc.c
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
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;
33         struct vnt_rx_header *head;
34         struct vnt_rx_tail *tail;
35         u32 frame_size;
36         int ii;
37         u16 rx_bitrate, pay_load_with_padding;
38         u8 rate_idx = 0;
39         long rx_dbm;
40
41         skb = ptr_rcb->skb;
42         rx_status = IEEE80211_SKB_RXCB(skb);
43
44         /* [31:16]RcvByteCount ( not include 4-byte Status ) */
45         head = (struct vnt_rx_header *)skb->data;
46         frame_size = head->wbk_status >> 16;
47         frame_size += 4;
48
49         if (bytes_received != frame_size) {
50                 dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n");
51                 return false;
52         }
53
54         if ((bytes_received > 2372) || (bytes_received <= 40)) {
55                 /* Frame Size error drop this packet.*/
56                 dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n");
57                 return false;
58         }
59
60         /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
61         /* -8TSF - 4RSR - 4SQ3 - ?Padding */
62
63         /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
64
65         /*Fix hardware bug => PLCP_Length error */
66         if (((bytes_received - head->pay_load_len) > 27) ||
67             ((bytes_received - head->pay_load_len) < 24) ||
68             (bytes_received < head->pay_load_len)) {
69                 dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
70                         head->pay_load_len);
71                 return false;
72         }
73
74         sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
75         rx_bitrate = head->rx_rate * 5; /* rx_rate * 5 */
76
77         for (ii = 0; ii < sband->n_bitrates; ii++) {
78                 if (sband->bitrates[ii].bitrate == rx_bitrate) {
79                         rate_idx = ii;
80                                 break;
81                 }
82         }
83
84         if (ii == sband->n_bitrates) {
85                 dev_dbg(&priv->usb->dev, "Wrong Rx Bit Rate %d\n", rx_bitrate);
86                 return false;
87         }
88
89         pay_load_with_padding = ((head->pay_load_len / 4) +
90                 ((head->pay_load_len % 4) ? 1 : 0)) * 4;
91
92         tail = (struct vnt_rx_tail *)(skb->data +
93                                       sizeof(*head) + pay_load_with_padding);
94         priv->tsf_time = le64_to_cpu(tail->tsf_time);
95
96         if (tail->rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
97                 return false;
98
99         vnt_rf_rssi_to_dbm(priv, tail->rssi, &rx_dbm);
100
101         priv->bb_pre_ed_rssi = (u8)-rx_dbm + 1;
102         priv->current_rssi = priv->bb_pre_ed_rssi;
103
104         skb_pull(skb, sizeof(*head));
105         skb_trim(skb, head->pay_load_len);
106
107         rx_status->mactime = priv->tsf_time;
108         rx_status->band = hw->conf.chandef.chan->band;
109         rx_status->signal = rx_dbm;
110         rx_status->flag = 0;
111         rx_status->freq = hw->conf.chandef.chan->center_freq;
112
113         if (!(tail->rsr & RSR_CRCOK))
114                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
115
116         rx_status->rate_idx = rate_idx;
117
118         if (tail->new_rsr & NEWRSR_DECRYPTOK)
119                 rx_status->flag |= RX_FLAG_DECRYPTED;
120
121         ieee80211_rx_irqsafe(priv->hw, skb);
122
123         return true;
124 }