blob: 6606a1c239ee9ee0af4bd3c7b8de061af1cfb96a [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -04001/*
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. Mattock789d1ae2012-08-20 08:43:13 -070021 * Purpose: handle WMAC frame relay & filtering
Forest Bond5449c682009-04-25 10:30:44 -040022 *
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 Bond5449c682009-04-25 10:30:44 -040034#include "mac.h"
Forest Bond5449c682009-04-25 10:30:44 -040035#include "tcrc.h"
Forest Bond5449c682009-04-25 10:30:44 -040036#include "rxtx.h"
Forest Bond5449c682009-04-25 10:30:44 -040037#include "wroute.h"
Forest Bond5449c682009-04-25 10:30:44 -040038#include "card.h"
Forest Bond5449c682009-04-25 10:30:44 -040039#include "baseband.h"
Jim Lieba7ad3222009-08-12 14:54:09 -070040
Forest Bond5449c682009-04-25 10:30:44 -040041/*--------------------- Static Definitions -------------------------*/
42
43/*--------------------- Static Classes ----------------------------*/
44
Forest Bond5449c682009-04-25 10:30:44 -040045/*--------------------- Static Functions --------------------------*/
46
47/*--------------------- Export Variables --------------------------*/
48
Forest Bond5449c682009-04-25 10:30:44 -040049/*
50 * Description:
Charles Clément1b120682010-08-01 17:15:48 +020051 * Relay packet. Return true if packet is copy to DMA1
Forest Bond5449c682009-04-25 10:30:44 -040052 *
53 * Parameters:
54 * In:
55 * pDevice -
56 * pbySkbData - rx packet skb data
57 * Out:
Charles Clément5a5a2a62010-08-01 17:15:49 +020058 * true, false
Forest Bond5449c682009-04-25 10:30:44 -040059 *
Charles Clément5a5a2a62010-08-01 17:15:49 +020060 * Return Value: true if packet duplicate; otherwise false
Forest Bond5449c682009-04-25 10:30:44 -040061 *
62 */
Malcolm Priestley6af43362014-08-10 15:47:01 +010063bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData,
Martin Hofmann0027d9a2014-01-07 13:11:48 +010064 unsigned int uDataLen, unsigned int uNodeIndex)
Forest Bond5449c682009-04-25 10:30:44 -040065{
Joe Perches180071a2013-03-18 10:45:15 -070066 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 Bond5449c682009-04-25 10:30:44 -040077
Joe Perches180071a2013-03-18 10:45:15 -070078 if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) {
Joe Perches48caf5a2014-08-17 09:17:04 -070079 pr_debug("Relay can't allocate TD1..\n");
Joe Perches180071a2013-03-18 10:45:15 -070080 return false;
81 }
Forest Bond5449c682009-04-25 10:30:44 -040082
Joe Perches180071a2013-03-18 10:45:15 -070083 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
Forest Bond5449c682009-04-25 10:30:44 -040084
Joe Perches180071a2013-03-18 10:45:15 -070085 pHeadTD->m_td1TD1.byTCR = (TCR_EDP | TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -040086
Martin Hofmann85d396b2014-01-07 13:11:46 +010087 memcpy(pDevice->sTxEthHeader.abyDstAddr, pbySkbData, ETH_HLEN);
Forest Bond5449c682009-04-25 10:30:44 -040088
Joe Perches180071a2013-03-18 10:45:15 -070089 cbFrameBodySize = uDataLen - ETH_HLEN;
Forest Bond5449c682009-04-25 10:30:44 -040090
Martin Hofmanned07c0e2014-01-07 13:11:47 +010091 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
Joe Perches180071a2013-03-18 10:45:15 -070092 cbFrameBodySize += 8;
Forest Bond5449c682009-04-25 10:30:44 -040093
Joe Perches180071a2013-03-18 10:45:15 -070094 if (pDevice->bEncryptionEnable == true) {
95 bNeedEncryption = true;
Forest Bond5449c682009-04-25 10:30:44 -040096
Sarah Khan861374f2014-10-23 22:52:33 +053097 /* get group key */
Joe Perches180071a2013-03-18 10:45:15 -070098 pbyBSSID = pDevice->abyBroadcastAddr;
Martin Hofmann0027d9a2014-01-07 13:11:48 +010099 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID,
100 GROUP_KEY, &pTransmitKey) == false) {
Joe Perches180071a2013-03-18 10:45:15 -0700101 pTransmitKey = NULL;
Joe Perches48caf5a2014-08-17 09:17:04 -0700102 pr_debug("KEY is NULL. [%d]\n",
103 pDevice->pMgmt->eCurrMode);
Joe Perches180071a2013-03-18 10:45:15 -0700104 } else {
Joe Perches48caf5a2014-08-17 09:17:04 -0700105 pr_debug("Get GTK\n");
Joe Perches180071a2013-03-18 10:45:15 -0700106 }
107 }
Forest Bond5449c682009-04-25 10:30:44 -0400108
Joe Perches180071a2013-03-18 10:45:15 -0700109 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 Hofmann0027d9a2014-01-07 13:11:48 +0100119 pTransmitKey->uKeyLength);
Joe Perches180071a2013-03-18 10:45:15 -0700120 }
121 }
Forest Bond5449c682009-04-25 10:30:44 -0400122
Martin Hofmann0027d9a2014-01-07 13:11:48 +0100123 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey,
124 cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -0400125
Martin Hofmanned07c0e2014-01-07 13:11:47 +0100126 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA))
Joe Perches180071a2013-03-18 10:45:15 -0700127 return false;
Martin Hofmanned07c0e2014-01-07 13:11:47 +0100128
Martin Hofmann85d396b2014-01-07 13:11:46 +0100129 byPktType = pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -0400130
Joe Perches180071a2013-03-18 10:45:15 -0700131 if (pDevice->bFixRate) {
132 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
Martin Hofmanned07c0e2014-01-07 13:11:47 +0100133 if (pDevice->uConnectionRate >= RATE_11M)
Joe Perches180071a2013-03-18 10:45:15 -0700134 pDevice->wCurrentRate = RATE_11M;
Martin Hofmanned07c0e2014-01-07 13:11:47 +0100135 else
Martin Hofmann85d396b2014-01-07 13:11:46 +0100136 pDevice->wCurrentRate = pDevice->uConnectionRate;
Joe Perches180071a2013-03-18 10:45:15 -0700137 } 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 Hofmann85d396b2014-01-07 13:11:46 +0100145 pDevice->wCurrentRate = pDevice->uConnectionRate;
Joe Perches180071a2013-03-18 10:45:15 -0700146 }
147 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700148 } else {
Joe Perches180071a2013-03-18 10:45:15 -0700149 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
150 }
Forest Bond5449c682009-04-25 10:30:44 -0400151
Joe Perches180071a2013-03-18 10:45:15 -0700152 if (pDevice->wCurrentRate <= RATE_11M)
153 byPktType = PK_TYPE_11B;
Forest Bond5449c682009-04-25 10:30:44 -0400154
Martin Hofmann0027d9a2014-01-07 13:11:48 +0100155 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff,
156 bNeedEncryption, cbFrameBodySize, TYPE_AC0DMA,
157 pHeadTD, &pDevice->sTxEthHeader, pbySkbData,
158 pTransmitKey, uNodeIndex, &uMACfragNum,
159 &cbHeaderSize);
Forest Bond5449c682009-04-25 10:30:44 -0400160
Joe Perches180071a2013-03-18 10:45:15 -0700161 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
Sarah Khan861374f2014-10-23 22:52:33 +0530162 /* Disable PS */
Joe Perches180071a2013-03-18 10:45:15 -0700163 MACbPSWakeup(pDevice->PortOffset);
164 }
Forest Bond5449c682009-04-25 10:30:44 -0400165
Joe Perches180071a2013-03-18 10:45:15 -0700166 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -0400167
Joe Perches180071a2013-03-18 10:45:15 -0700168 pLastTD = pHeadTD;
169 for (ii = 0; ii < uMACfragNum; ii++) {
Sarah Khan861374f2014-10-23 22:52:33 +0530170 /* Poll Transmit the adapter */
Joe Perches180071a2013-03-18 10:45:15 -0700171 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 Bond5449c682009-04-25 10:30:44 -0400178
Sachin Kamatb806ad42013-10-09 15:58:31 +0530179 pLastTD->pTDInfo->skb = NULL;
Joe Perches180071a2013-03-18 10:45:15 -0700180 pLastTD->pTDInfo->byFlags = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400181
Joe Perches180071a2013-03-18 10:45:15 -0700182 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -0400183
Joe Perches180071a2013-03-18 10:45:15 -0700184 MACvTransmitAC0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400185
Joe Perches180071a2013-03-18 10:45:15 -0700186 return true;
Forest Bond5449c682009-04-25 10:30:44 -0400187}