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