Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13-rc3 244 lines 8.6 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 * 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: wctl.c 20 * 21 * Purpose: handle WMAC duplicate filter & defragment 22 * 23 * Author: Jerry Chen 24 * 25 * Date: Jun. 27, 2002 26 * 27 * Functions: 28 * WCTLbIsDuplicate - Test if duplicate packet 29 * WCTLuSearchDFCB - Search DeFragment Control Database 30 * WCTLuInsertDFCB - Insert DeFragment Control Database 31 * WCTLbHandleFragment - Handle received fragment packet 32 * 33 * Revision History: 34 * 35 */ 36 37#include "wctl.h" 38#include "device.h" 39#include "card.h" 40#include "tmacro.h" 41 42// static int msglevel =MSG_LEVEL_INFO; 43 44/* 45 * Description: 46 * Scan Rx cache. Return true if packet is duplicate, else 47 * inserts in receive cache and returns false. 48 * 49 * Parameters: 50 * In: 51 * pCache - Receive packets history 52 * pMACHeader - 802.11 MAC Header of received packet 53 * Out: 54 * none 55 * 56 * Return Value: true if packet duplicate; otherwise false 57 * 58 */ 59 60bool WCTLbIsDuplicate (PSCache pCache, struct ieee80211_hdr *pMACHeader) 61{ 62 unsigned int uIndex; 63 unsigned int ii; 64 PSCacheEntry pCacheEntry; 65 66 if (IS_FC_RETRY(pMACHeader)) { 67 68 uIndex = pCache->uInPtr; 69 for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) { 70 pCacheEntry = &(pCache->asCacheEntry[uIndex]); 71 if ((pCacheEntry->wFmSequence == pMACHeader->seq_ctrl) && 72 ether_addr_equal(pCacheEntry->abyAddr2, pMACHeader->addr2) && 73 (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->frame_control)) 74 ) { 75 /* Duplicate match */ 76 return true; 77 } 78 ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH); 79 } 80 } 81 /* Not found in cache - insert */ 82 pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; 83 pCacheEntry->wFmSequence = pMACHeader->seq_ctrl; 84 memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->addr2[0]), ETH_ALEN); 85 pCacheEntry->wFrameCtl = pMACHeader->frame_control; 86 ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); 87 return false; 88} 89 90/* 91 * Description: 92 * Found if sequence number of received fragment packet in Defragment Database 93 * 94 * Parameters: 95 * In: 96 * pDevice - Pointer to adapter 97 * pMACHeader - 802.11 MAC Header of received packet 98 * Out: 99 * none 100 * 101 * Return Value: index number in Defragment Database 102 * 103 */ 104 105unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice, 106 struct ieee80211_hdr *pMACHeader) 107{ 108 unsigned int ii; 109 110 for (ii = 0; ii < pDevice->cbDFCB; ii++) { 111 if ((pDevice->sRxDFCB[ii].bInUse == true) && 112 ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2, 113 pMACHeader->addr2)) { 114 return ii; 115 } 116 } 117 return pDevice->cbDFCB; 118} 119 120/* 121 * Description: 122 * Insert received fragment packet in Defragment Database 123 * 124 * Parameters: 125 * In: 126 * pDevice - Pointer to adapter 127 * pMACHeader - 802.11 MAC Header of received packet 128 * Out: 129 * none 130 * 131 * Return Value: index number in Defragment Database 132 * 133 */ 134unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice, 135 struct ieee80211_hdr *pMACHeader) 136{ 137 unsigned int ii; 138 139 if (pDevice->cbFreeDFCB == 0) 140 return(pDevice->cbDFCB); 141 for (ii = 0; ii < pDevice->cbDFCB; ii++) { 142 if (pDevice->sRxDFCB[ii].bInUse == false) { 143 pDevice->cbFreeDFCB--; 144 pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime; 145 pDevice->sRxDFCB[ii].bInUse = true; 146 pDevice->sRxDFCB[ii].wSequence = (pMACHeader->seq_ctrl >> 4); 147 pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->seq_ctrl & 0x000F); 148 memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), 149 &(pMACHeader->addr2[0]), 150 ETH_ALEN); 151 return(ii); 152 } 153 } 154 return(pDevice->cbDFCB); 155} 156 157/* 158 * Description: 159 * Handle received fragment packet 160 * 161 * Parameters: 162 * In: 163 * pDevice - Pointer to adapter 164 * pMACHeader - 802.11 MAC Header of received packet 165 * cbFrameLength - Frame length 166 * bWEP - is WEP packet 167 * Out: 168 * none 169 * 170 * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false 171 * 172 */ 173bool WCTLbHandleFragment(struct vnt_private *pDevice, struct ieee80211_hdr *pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV) 174{ 175 unsigned int uHeaderSize; 176 177 if (bWEP == true) { 178 uHeaderSize = 28; 179 if (bExtIV) 180 // ExtIV 181 uHeaderSize +=4; 182 } 183 else { 184 uHeaderSize = 24; 185 } 186 187 if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) { 188 pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); 189 if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) { 190 // duplicate, we must flush previous DCB 191 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime; 192 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->seq_ctrl >> 4); 193 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->seq_ctrl & 0x000F); 194 } 195 else { 196 pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader); 197 if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) { 198 return(false); 199 } 200 } 201 // reserve 8 byte to match MAC RX Buffer 202 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8); 203// pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4); 204 memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength); 205 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength; 206 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength; 207 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; 208 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); 209 return(false); 210 } 211 else { 212 pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader); 213 if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) { 214 if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->seq_ctrl >> 4)) && 215 (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->seq_ctrl & 0x000F)) && 216 ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) { 217 218 memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((u8 *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize)); 219 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize); 220 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize); 221 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++; 222 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); 223 } 224 else { 225 // seq error or frag # error flush DFCB 226 pDevice->cbFreeDFCB++; 227 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; 228 return(false); 229 } 230 } 231 else { 232 return(false); 233 } 234 if (IS_LAST_FRAGMENT_PKT(pMACHeader)) { 235 //enq defragcontrolblock 236 pDevice->cbFreeDFCB++; 237 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false; 238 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx); 239 return(true); 240 } 241 return(false); 242 } 243} 244