Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 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 | * |
Justin P. Mattock | 789d1ae | 2012-08-20 08:43:13 -0700 | [diff] [blame] | 21 | * Purpose: handle WMAC frame relay & filtering |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 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 | |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 34 | #include "mac.h" |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 35 | #include "tcrc.h" |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 36 | #include "rxtx.h" |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 37 | #include "wroute.h" |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 38 | #include "card.h" |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 39 | #include "baseband.h" |
Jim Lieb | a7ad322 | 2009-08-12 14:54:09 -0700 | [diff] [blame] | 40 | |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 41 | /*--------------------- Static Definitions -------------------------*/ |
| 42 | |
| 43 | /*--------------------- Static Classes ----------------------------*/ |
| 44 | |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 45 | /*--------------------- Static Functions --------------------------*/ |
| 46 | |
| 47 | /*--------------------- Export Variables --------------------------*/ |
| 48 | |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 49 | /* |
| 50 | * Description: |
Charles Clément | 1b12068 | 2010-08-01 17:15:48 +0200 | [diff] [blame] | 51 | * Relay packet. Return true if packet is copy to DMA1 |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 52 | * |
| 53 | * Parameters: |
| 54 | * In: |
| 55 | * pDevice - |
| 56 | * pbySkbData - rx packet skb data |
| 57 | * Out: |
Charles Clément | 5a5a2a6 | 2010-08-01 17:15:49 +0200 | [diff] [blame] | 58 | * true, false |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 59 | * |
Charles Clément | 5a5a2a6 | 2010-08-01 17:15:49 +0200 | [diff] [blame] | 60 | * Return Value: true if packet duplicate; otherwise false |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 61 | * |
| 62 | */ |
Malcolm Priestley | 6af4336 | 2014-08-10 15:47:01 +0100 | [diff] [blame] | 63 | bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, |
Martin Hofmann | 0027d9a | 2014-01-07 13:11:48 +0100 | [diff] [blame] | 64 | unsigned int uDataLen, unsigned int uNodeIndex) |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 65 | { |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 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; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 77 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 78 | if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { |
Joe Perches | 48caf5a | 2014-08-17 09:17:04 -0700 | [diff] [blame] | 79 | pr_debug("Relay can't allocate TD1..\n"); |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 80 | return false; |
| 81 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 82 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 83 | pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA]; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 84 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 85 | pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP); |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 86 | |
Martin Hofmann | 85d396b | 2014-01-07 13:11:46 +0100 | [diff] [blame] | 87 | memcpy(pDevice->sTxEthHeader.abyDstAddr, pbySkbData, ETH_HLEN); |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 88 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 89 | cbFrameBodySize = uDataLen - ETH_HLEN; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 90 | |
Martin Hofmann | ed07c0e | 2014-01-07 13:11:47 +0100 | [diff] [blame] | 91 | if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 92 | cbFrameBodySize += 8; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 93 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 94 | if (pDevice->bEncryptionEnable == true) { |
| 95 | bNeedEncryption = true; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 96 | |
Sarah Khan | 861374f | 2014-10-23 22:52:33 +0530 | [diff] [blame] | 97 | /* get group key */ |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 98 | pbyBSSID = pDevice->abyBroadcastAddr; |
Martin Hofmann | 0027d9a | 2014-01-07 13:11:48 +0100 | [diff] [blame] | 99 | if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, |
| 100 | GROUP_KEY, &pTransmitKey) == false) { |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 101 | pTransmitKey = NULL; |
Joe Perches | 48caf5a | 2014-08-17 09:17:04 -0700 | [diff] [blame] | 102 | pr_debug("KEY is NULL. [%d]\n", |
| 103 | pDevice->pMgmt->eCurrMode); |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 104 | } else { |
Joe Perches | 48caf5a | 2014-08-17 09:17:04 -0700 | [diff] [blame] | 105 | pr_debug("Get GTK\n"); |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 106 | } |
| 107 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 108 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 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], |
Martin Hofmann | 0027d9a | 2014-01-07 13:11:48 +0100 | [diff] [blame] | 119 | pTransmitKey->uKeyLength); |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 120 | } |
| 121 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 122 | |
Martin Hofmann | 0027d9a | 2014-01-07 13:11:48 +0100 | [diff] [blame] | 123 | uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, |
| 124 | cbFrameBodySize, &pDevice->sTxEthHeader); |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 125 | |
Martin Hofmann | ed07c0e | 2014-01-07 13:11:47 +0100 | [diff] [blame] | 126 | if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 127 | return false; |
Martin Hofmann | ed07c0e | 2014-01-07 13:11:47 +0100 | [diff] [blame] | 128 | |
Martin Hofmann | 85d396b | 2014-01-07 13:11:46 +0100 | [diff] [blame] | 129 | byPktType = pDevice->byPacketType; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 130 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 131 | if (pDevice->bFixRate) { |
| 132 | if (pDevice->eCurrentPHYType == PHY_TYPE_11B) { |
Martin Hofmann | ed07c0e | 2014-01-07 13:11:47 +0100 | [diff] [blame] | 133 | if (pDevice->uConnectionRate >= RATE_11M) |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 134 | pDevice->wCurrentRate = RATE_11M; |
Martin Hofmann | ed07c0e | 2014-01-07 13:11:47 +0100 | [diff] [blame] | 135 | else |
Martin Hofmann | 85d396b | 2014-01-07 13:11:46 +0100 | [diff] [blame] | 136 | pDevice->wCurrentRate = pDevice->uConnectionRate; |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 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 |
Martin Hofmann | 85d396b | 2014-01-07 13:11:46 +0100 | [diff] [blame] | 145 | pDevice->wCurrentRate = pDevice->uConnectionRate; |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 146 | } |
| 147 | } |
Joe Perches | 5e0cc8a | 2013-03-18 20:55:37 -0700 | [diff] [blame] | 148 | } else { |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 149 | pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; |
| 150 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 151 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 152 | if (pDevice->wCurrentRate <= RATE_11M) |
| 153 | byPktType = PK_TYPE_11B; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 154 | |
Martin Hofmann | 0027d9a | 2014-01-07 13:11:48 +0100 | [diff] [blame] | 155 | vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, |
| 156 | bNeedEncryption, cbFrameBodySize, TYPE_AC0DMA, |
| 157 | pHeadTD, &pDevice->sTxEthHeader, pbySkbData, |
| 158 | pTransmitKey, uNodeIndex, &uMACfragNum, |
| 159 | &cbHeaderSize); |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 160 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 161 | if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) { |
Sarah Khan | 861374f | 2014-10-23 22:52:33 +0530 | [diff] [blame] | 162 | /* Disable PS */ |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 163 | MACbPSWakeup(pDevice->PortOffset); |
| 164 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 165 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 166 | pDevice->bPWBitOn = false; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 167 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 168 | pLastTD = pHeadTD; |
| 169 | for (ii = 0; ii < uMACfragNum; ii++) { |
Sarah Khan | 861374f | 2014-10-23 22:52:33 +0530 | [diff] [blame] | 170 | /* Poll Transmit the adapter */ |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 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 | } |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 178 | |
Sachin Kamat | b806ad4 | 2013-10-09 15:58:31 +0530 | [diff] [blame] | 179 | pLastTD->pTDInfo->skb = NULL; |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 180 | pLastTD->pTDInfo->byFlags = 0; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 181 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 182 | pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 183 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 184 | MACvTransmitAC0(pDevice->PortOffset); |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 185 | |
Joe Perches | 180071a | 2013-03-18 10:45:15 -0700 | [diff] [blame] | 186 | return true; |
Forest Bond | 5449c68 | 2009-04-25 10:30:44 -0400 | [diff] [blame] | 187 | } |