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 & filterring 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 Variables --------------------------*/ 46static int msglevel =MSG_LEVEL_INFO; 47//static int msglevel =MSG_LEVEL_DEBUG; 48/*--------------------- Static Functions --------------------------*/ 49 50/*--------------------- Export Variables --------------------------*/ 51 52 53 54/* 55 * Description: 56 * Relay packet. Return true if packet is copy to DMA1 57 * 58 * Parameters: 59 * In: 60 * pDevice - 61 * pbySkbData - rx packet skb data 62 * Out: 63 * true, false 64 * 65 * Return Value: true if packet duplicate; otherwise false 66 * 67 */ 68bool ROUTEbRelay (PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex) 69{ 70 PSMgmtObject pMgmt = pDevice->pMgmt; 71 PSTxDesc pHeadTD, pLastTD; 72 unsigned int cbFrameBodySize; 73 unsigned int uMACfragNum; 74 unsigned char byPktType; 75 bool bNeedEncryption = false; 76 SKeyItem STempKey; 77 PSKeyItem pTransmitKey = NULL; 78 unsigned int cbHeaderSize; 79 unsigned int ii; 80 unsigned char *pbyBSSID; 81 82 83 84 85 if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) { 86 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n"); 87 return false; 88 } 89 90 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; 91 92 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); 93 94 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)pbySkbData, ETH_HLEN); 95 96 cbFrameBodySize = uDataLen - ETH_HLEN; 97 98 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { 99 cbFrameBodySize += 8; 100 } 101 102 if (pDevice->bEncryptionEnable == true) { 103 bNeedEncryption = true; 104 105 // get group key 106 pbyBSSID = pDevice->abyBroadcastAddr; 107 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { 108 pTransmitKey = NULL; 109 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); 110 } else { 111 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n"); 112 } 113 } 114 115 if (pDevice->bEnableHostWEP) { 116 if (uNodeIndex < MAX_NODE_NUM + 1) { 117 pTransmitKey = &STempKey; 118 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; 119 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex; 120 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength; 121 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16; 122 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0; 123 memcpy(pTransmitKey->abyKey, 124 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0], 125 pTransmitKey->uKeyLength 126 ); 127 } 128 } 129 130 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); 131 132 if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) { 133 return false; 134 } 135 byPktType = (unsigned char)pDevice->byPacketType; 136 137 if (pDevice->bFixRate) { 138 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { 139 if (pDevice->uConnectionRate >= RATE_11M) { 140 pDevice->wCurrentRate = RATE_11M; 141 } else { 142 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; 143 } 144 } else { 145 if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) && 146 (pDevice->uConnectionRate <= RATE_6M)) { 147 pDevice->wCurrentRate = RATE_6M; 148 } else { 149 if (pDevice->uConnectionRate >= RATE_54M) 150 pDevice->wCurrentRate = RATE_54M; 151 else 152 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate; 153 } 154 } 155 } 156 else { 157 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; 158 } 159 160 if (pDevice->wCurrentRate <= RATE_11M) 161 byPktType = PK_TYPE_11B; 162 163 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption, 164 cbFrameBodySize, TYPE_AC0DMA, pHeadTD, 165 &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex, 166 &uMACfragNum, 167 &cbHeaderSize 168 ); 169 170 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { 171 // Disable PS 172 MACbPSWakeup(pDevice->PortOffset); 173 } 174 175 pDevice->bPWBitOn = false; 176 177 pLastTD = pHeadTD; 178 for (ii = 0; ii < uMACfragNum; ii++) { 179 // Poll Transmit the adapter 180 wmb(); 181 pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC; 182 wmb(); 183 if (ii == (uMACfragNum - 1)) 184 pLastTD = pHeadTD; 185 pHeadTD = pHeadTD->next; 186 } 187 188 pLastTD->pTDInfo->skb = 0; 189 pLastTD->pTDInfo->byFlags = 0; 190 191 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; 192 193 MACvTransmitAC0(pDevice->PortOffset); 194 195 return true; 196} 197 198 199 200