Staging: Add pristine upstream vt6655 driver sources
[pandora-kernel.git] / drivers / staging / vt6655 / wroute.c
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
35 #if !defined(__MAC_H__)
36 #include "mac.h"
37 #endif
38 #if !defined(__TCRC_H__)
39 #include "tcrc.h"
40 #endif
41 #if !defined(__RXTX_H__)
42 #include "rxtx.h"
43 #endif
44 #if !defined(__WROUTE_H__)
45 #include "wroute.h"
46 #endif
47 #if !defined(__CARD_H__)
48 #include "card.h"
49 #endif
50 #if !defined(__BASEBAND_H__)
51 #include "baseband.h"
52 #endif
53 /*---------------------  Static Definitions -------------------------*/
54
55 /*---------------------  Static Classes  ----------------------------*/
56
57 /*---------------------  Static Variables  --------------------------*/
58 static int          msglevel                =MSG_LEVEL_INFO;
59 //static int          msglevel                =MSG_LEVEL_DEBUG;
60 /*---------------------  Static Functions  --------------------------*/
61
62 /*---------------------  Export Variables  --------------------------*/
63
64
65
66 /*
67  * Description:
68  *      Relay packet.  Return TRUE if packet is copy to DMA1
69  *
70  * Parameters:
71  *  In:
72  *      pDevice             -
73  *      pbySkbData          - rx packet skb data
74  *  Out:
75  *      TURE, FALSE
76  *
77  * Return Value: TRUE if packet duplicate; otherwise FALSE
78  *
79  */
80 BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex)
81 {
82     PSMgmtObject    pMgmt = pDevice->pMgmt;
83     PSTxDesc        pHeadTD, pLastTD;
84     UINT            cbFrameBodySize;
85     UINT            uMACfragNum;
86     BYTE            byPktTyp;
87     BOOL            bNeedEncryption = FALSE;
88     SKeyItem        STempKey;
89     PSKeyItem       pTransmitKey = NULL;
90     UINT            cbHeaderSize;
91     UINT            ii;
92     PBYTE           pbyBSSID;
93
94
95
96
97     if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) {
98         DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
99         return FALSE;
100     }
101
102     pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
103
104     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
105
106     memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN);
107
108     cbFrameBodySize = uDataLen - U_HEADER_LEN;
109
110     if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
111         cbFrameBodySize += 8;
112     }
113
114     if (pDevice->bEncryptionEnable == TRUE) {
115         bNeedEncryption = TRUE;
116
117         // get group key
118         pbyBSSID = pDevice->abyBroadcastAddr;
119         if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
120             pTransmitKey = NULL;
121             DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
122         } else {
123             DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
124         }
125     }
126
127     if (pDevice->bEnableHostWEP) {
128         if (uNodeIndex >= 0) {
129             pTransmitKey = &STempKey;
130             pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
131             pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
132             pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
133             pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
134             pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
135             memcpy(pTransmitKey->abyKey,
136                 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
137                 pTransmitKey->uKeyLength
138                 );
139         }
140     }
141
142     uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
143
144     if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) {
145         return FALSE;
146     }
147     byPktTyp = (BYTE)pDevice->byPacketType;
148
149     if (pDevice->bFixRate) {
150         if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
151             if (pDevice->uConnectionRate >= RATE_11M) {
152                 pDevice->wCurrentRate = RATE_11M;
153             } else {
154                 pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
155             }
156         } else {
157             if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
158                 (pDevice->uConnectionRate <= RATE_6M)) {
159                 pDevice->wCurrentRate = RATE_6M;
160             } else {
161                 if (pDevice->uConnectionRate >= RATE_54M)
162                     pDevice->wCurrentRate = RATE_54M;
163                 else
164                     pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
165             }
166         }
167     }
168     else {
169         pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
170     }
171
172     if (pDevice->wCurrentRate <= RATE_11M)
173         byPktTyp = PK_TYPE_11B;
174
175     vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
176                         cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
177                         &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex,
178                         &uMACfragNum,
179                         &cbHeaderSize
180                         );
181
182     if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
183         // Disable PS
184         MACbPSWakeup(pDevice->PortOffset);
185     }
186
187     pDevice->bPWBitOn = FALSE;
188
189     pLastTD = pHeadTD;
190     for (ii = 0; ii < uMACfragNum; ii++) {
191         // Poll Transmit the adapter
192         wmb();
193         pHeadTD->m_td0TD0.f1Owner=OWNED_BY_NIC;
194         wmb();
195         if (ii == (uMACfragNum - 1))
196             pLastTD = pHeadTD;
197         pHeadTD = pHeadTD->next;
198     }
199
200     pLastTD->pTDInfo->skb = 0;
201     pLastTD->pTDInfo->byFlags = 0;
202
203     pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
204
205     MACvTransmitAC0(pDevice->PortOffset);
206
207     return TRUE;
208 }
209
210
211