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: wroute.c 20 * 21 * Purpose: handle WMAC frame relay & filtering 22 * 23 * Author: Lyndon Chen 24 * 25 * Date: May 20, 2003 26 * 27 * Functions: 28 * ROUTEbRelay - Relay packet 29 * 30 * Revision History: 31 * 32 */ 33 34#include "mac.h" 35#include "tcrc.h" 36#include "rxtx.h" 37#include "wroute.h" 38#include "card.h" 39#include "baseband.h" 40 41/*--------------------- Static Definitions -------------------------*/ 42 43/*--------------------- Static Classes ----------------------------*/ 44 45/*--------------------- Static Functions --------------------------*/ 46 47/*--------------------- Export Variables --------------------------*/ 48 49/* 50 * Description: 51 * Relay packet. Return true if packet is copy to DMA1 52 * 53 * Parameters: 54 * In: 55 * pDevice - 56 * pbySkbData - rx packet skb data 57 * Out: 58 * true, false 59 * 60 * Return Value: true if packet duplicate; otherwise false 61 * 62 */ 63bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, 64 unsigned int uDataLen, unsigned int uNodeIndex) 65{ 66 PSMgmtObject pMgmt = pDevice->pMgmt; 67 PSTxDesc pHeadTD, pLastTD; 68 unsigned int cbFrameBodySize; 69 unsigned int uMACfragNum; 70 unsigned char byPktType; 71 bool bNeedEncryption = false; 72 SKeyItem STempKey; 73 PSKeyItem pTransmitKey = NULL; 74 unsigned int cbHeaderSize; 75 unsigned int ii; 76 unsigned char *pbyBSSID; 77 78 if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { 79 pr_debug("Relay can't allocate TD1..\n"); 80 return false; 81 } 82 83 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; 84 85 pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP); 86 87 memcpy(pDevice->sTxEthHeader.abyDstAddr, pbySkbData, ETH_HLEN); 88 89 cbFrameBodySize = uDataLen - ETH_HLEN; 90 91 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) 92 cbFrameBodySize += 8; 93 94 if (pDevice->bEncryptionEnable == true) { 95 bNeedEncryption = true; 96 97 // get group key 98 pbyBSSID = pDevice->abyBroadcastAddr; 99 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, 100 GROUP_KEY, &pTransmitKey) == false) { 101 pTransmitKey = NULL; 102 pr_debug("KEY is NULL. [%d]\n", 103 pDevice->pMgmt->eCurrMode); 104 } else { 105 pr_debug("Get GTK\n"); 106 } 107 } 108 109 if (pDevice->bEnableHostWEP) { 110 if (uNodeIndex < MAX_NODE_NUM + 1) { 111 pTransmitKey = &STempKey; 112 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; 113 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; 114 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; 115 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; 116 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; 117 memcpy(pTransmitKey->abyKey, 118 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], 119 pTransmitKey->uKeyLength); 120 } 121 } 122 123 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, 124 cbFrameBodySize, &pDevice->sTxEthHeader); 125 126 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) 127 return false; 128 129 byPktType = pDevice->byPacketType; 130 131 if (pDevice->bFixRate) { 132 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { 133 if (pDevice->uConnectionRate >= RATE_11M) 134 pDevice->wCurrentRate = RATE_11M; 135 else 136 pDevice->wCurrentRate = pDevice->uConnectionRate; 137 } else { 138 if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && 139 (pDevice->uConnectionRate <= RATE_6M)) { 140 pDevice->wCurrentRate = RATE_6M; 141 } else { 142 if (pDevice->uConnectionRate >= RATE_54M) 143 pDevice->wCurrentRate = RATE_54M; 144 else 145 pDevice->wCurrentRate = pDevice->uConnectionRate; 146 } 147 } 148 } else { 149 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; 150 } 151 152 if (pDevice->wCurrentRate <= RATE_11M) 153 byPktType = PK_TYPE_11B; 154 155 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, 156 bNeedEncryption, cbFrameBodySize, TYPE_AC0DMA, 157 pHeadTD, &pDevice->sTxEthHeader, pbySkbData, 158 pTransmitKey, uNodeIndex, &uMACfragNum, 159 &cbHeaderSize); 160 161 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { 162 // Disable PS 163 MACbPSWakeup(pDevice->PortOffset); 164 } 165 166 pDevice->bPWBitOn = false; 167 168 pLastTD = pHeadTD; 169 for (ii = 0; ii < uMACfragNum; ii++) { 170 // Poll Transmit the adapter 171 wmb(); 172 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC; 173 wmb(); 174 if (ii == (uMACfragNum - 1)) 175 pLastTD = pHeadTD; 176 pHeadTD = pHeadTD->next; 177 } 178 179 pLastTD->pTDInfo->skb = NULL; 180 pLastTD->pTDInfo->byFlags = 0; 181 182 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; 183 184 MACvTransmitAC0(pDevice->PortOffset); 185 186 return true; 187} 188