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