blob: fe6de98856aead92126e67ed9b04194f0e431c77 [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: device_main.c
20 *
21 * Purpose: driver entry for initial, open, close, tx and rx.
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: Jan 8, 2003
26 *
27 * Functions:
28 *
Charles Clément013a4682010-06-15 10:39:24 -070029 * vt6655_probe - module initial (insmod) driver entry
30 * vt6655_remove - module remove entry
31 * vt6655_init_info - device structure resource allocation function
Forest Bond5449c682009-04-25 10:30:44 -040032 * device_free_info - device structure resource free function
33 * device_get_pci_info - get allocated pci io/mem resource
34 * device_print_info - print out resource
35 * device_open - allocate dma/descripter resource & initial mac/bbp function
36 * device_xmit - asynchrous data tx function
37 * device_intr - interrupt handle function
38 * device_set_multi - set mac filter
39 * device_ioctl - ioctl entry
40 * device_close - shutdown mac/bbp & free dma/descripter resource
41 * device_rx_srv - rx service function
42 * device_receive_frame - rx data function
43 * device_alloc_rx_buf - rx buffer pre-allocated function
44 * device_alloc_frag_buf - rx fragement pre-allocated function
45 * device_free_tx_buf - free tx buffer function
46 * device_free_frag_buf- free de-fragement buffer
47 * device_dma0_tx_80211- tx 802.11 frame via dma0
48 * device_dma0_xmit- tx PS bufferred frame via dma0
49 * device_init_rd0_ring- initial rd dma0 ring
50 * device_init_rd1_ring- initial rd dma1 ring
51 * device_init_td0_ring- initial tx dma0 ring buffer
52 * device_init_td1_ring- initial tx dma1 ring buffer
53 * device_init_registers- initial MAC & BBP & RF internal registers.
54 * device_init_rings- initial tx/rx ring buffer
55 * device_init_defrag_cb- initial & allocate de-fragement buffer.
56 * device_free_rings- free all allocated ring buffer
57 * device_tx_srv- tx interrupt service function
58 *
59 * Revision History:
60 */
61#undef __NO_VERSION__
62
Al Virof8054422013-04-06 18:11:22 -040063#include <linux/file.h>
Forest Bond5449c682009-04-25 10:30:44 -040064#include "device.h"
Forest Bond5449c682009-04-25 10:30:44 -040065#include "card.h"
Charles Clément79566eb2010-06-21 10:39:51 -070066#include "channel.h"
Forest Bond5449c682009-04-25 10:30:44 -040067#include "baseband.h"
Forest Bond5449c682009-04-25 10:30:44 -040068#include "mac.h"
Forest Bond5449c682009-04-25 10:30:44 -040069#include "tether.h"
Forest Bond5449c682009-04-25 10:30:44 -040070#include "wmgr.h"
Forest Bond5449c682009-04-25 10:30:44 -040071#include "wctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040072#include "power.h"
Forest Bond5449c682009-04-25 10:30:44 -040073#include "wcmd.h"
Forest Bond5449c682009-04-25 10:30:44 -040074#include "iocmd.h"
Forest Bond5449c682009-04-25 10:30:44 -040075#include "tcrc.h"
Forest Bond5449c682009-04-25 10:30:44 -040076#include "rxtx.h"
Forest Bond5449c682009-04-25 10:30:44 -040077#include "wroute.h"
Forest Bond5449c682009-04-25 10:30:44 -040078#include "bssdb.h"
Forest Bond5449c682009-04-25 10:30:44 -040079#include "hostap.h"
Forest Bond5449c682009-04-25 10:30:44 -040080#include "wpactl.h"
Forest Bond5449c682009-04-25 10:30:44 -040081#include "ioctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040082#include "iwctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040083#include "dpc.h"
Forest Bond5449c682009-04-25 10:30:44 -040084#include "datarate.h"
Forest Bond5449c682009-04-25 10:30:44 -040085#include "rf.h"
Forest Bond5449c682009-04-25 10:30:44 -040086#include "iowpa.h"
Forest Bond5449c682009-04-25 10:30:44 -040087#include <linux/delay.h>
88#include <linux/kthread.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090089#include <linux/slab.h>
Forest Bond5449c682009-04-25 10:30:44 -040090
Forest Bond5449c682009-04-25 10:30:44 -040091/*--------------------- Static Definitions -------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -040092static int msglevel = MSG_LEVEL_INFO;
93
Forest Bond5449c682009-04-25 10:30:44 -040094//
95// Define module options
96//
Forest Bond5449c682009-04-25 10:30:44 -040097MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
98MODULE_LICENSE("GPL");
99MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
Forest Bond5449c682009-04-25 10:30:44 -0400100
Joe Perches915006c2013-03-18 10:44:47 -0700101#define DEVICE_PARAM(N, D)
Forest Bond5449c682009-04-25 10:30:44 -0400102
103#define RX_DESC_MIN0 16
104#define RX_DESC_MAX0 128
105#define RX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700106DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400107
108#define RX_DESC_MIN1 16
109#define RX_DESC_MAX1 128
110#define RX_DESC_DEF1 32
Joe Perches915006c2013-03-18 10:44:47 -0700111DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400112
113#define TX_DESC_MIN0 16
114#define TX_DESC_MAX0 128
115#define TX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700116DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400117
118#define TX_DESC_MIN1 16
119#define TX_DESC_MAX1 128
120#define TX_DESC_DEF1 64
Joe Perches915006c2013-03-18 10:44:47 -0700121DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400122
Forest Bond5449c682009-04-25 10:30:44 -0400123#define IP_ALIG_DEF 0
Charles Clément0f4c60d2010-06-24 11:02:25 -0700124/* IP_byte_align[] is used for IP header unsigned long byte aligned
125 0: indicate the IP header won't be unsigned long byte aligned.(Default) .
126 1: indicate the IP header will be unsigned long byte aligned.
Joe Perches915006c2013-03-18 10:44:47 -0700127 In some environment, the IP header should be unsigned long byte aligned,
128 or the packet will be droped when we receive it. (eg: IPVS)
Forest Bond5449c682009-04-25 10:30:44 -0400129*/
Joe Perches915006c2013-03-18 10:44:47 -0700130DEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned");
Forest Bond5449c682009-04-25 10:30:44 -0400131
Forest Bond5449c682009-04-25 10:30:44 -0400132#define INT_WORKS_DEF 20
133#define INT_WORKS_MIN 10
134#define INT_WORKS_MAX 64
135
Joe Perches915006c2013-03-18 10:44:47 -0700136DEVICE_PARAM(int_works, "Number of packets per interrupt services");
Forest Bond5449c682009-04-25 10:30:44 -0400137
138#define CHANNEL_MIN 1
139#define CHANNEL_MAX 14
140#define CHANNEL_DEF 6
141
142DEVICE_PARAM(Channel, "Channel number");
143
Forest Bond5449c682009-04-25 10:30:44 -0400144/* PreambleType[] is the preamble length used for transmit.
145 0: indicate allows long preamble type
146 1: indicate allows short preamble type
147*/
148
149#define PREAMBLE_TYPE_DEF 1
150
151DEVICE_PARAM(PreambleType, "Preamble Type");
152
Forest Bond5449c682009-04-25 10:30:44 -0400153#define RTS_THRESH_MIN 512
154#define RTS_THRESH_MAX 2347
155#define RTS_THRESH_DEF 2347
156
157DEVICE_PARAM(RTSThreshold, "RTS threshold");
158
Forest Bond5449c682009-04-25 10:30:44 -0400159#define FRAG_THRESH_MIN 256
160#define FRAG_THRESH_MAX 2346
161#define FRAG_THRESH_DEF 2346
162
163DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
164
Forest Bond5449c682009-04-25 10:30:44 -0400165#define DATA_RATE_MIN 0
166#define DATA_RATE_MAX 13
167#define DATA_RATE_DEF 13
168/* datarate[] index
169 0: indicate 1 Mbps 0x02
170 1: indicate 2 Mbps 0x04
171 2: indicate 5.5 Mbps 0x0B
172 3: indicate 11 Mbps 0x16
173 4: indicate 6 Mbps 0x0c
174 5: indicate 9 Mbps 0x12
175 6: indicate 12 Mbps 0x18
176 7: indicate 18 Mbps 0x24
177 8: indicate 24 Mbps 0x30
178 9: indicate 36 Mbps 0x48
Joe Perches915006c2013-03-18 10:44:47 -0700179 10: indicate 48 Mbps 0x60
180 11: indicate 54 Mbps 0x6c
181 12: indicate 72 Mbps 0x90
182 13: indicate auto rate
Forest Bond5449c682009-04-25 10:30:44 -0400183*/
184
185DEVICE_PARAM(ConnectionRate, "Connection data rate");
186
187#define OP_MODE_DEF 0
188
189DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
190
191/* OpMode[] is used for transmit.
192 0: indicate infrastruct mode used
193 1: indicate adhoc mode used
194 2: indicate AP mode used
195*/
196
Forest Bond5449c682009-04-25 10:30:44 -0400197/* PSMode[]
198 0: indicate disable power saving mode
199 1: indicate enable power saving mode
200*/
201
202#define PS_MODE_DEF 0
203
204DEVICE_PARAM(PSMode, "Power saving mode");
205
Forest Bond5449c682009-04-25 10:30:44 -0400206#define SHORT_RETRY_MIN 0
207#define SHORT_RETRY_MAX 31
208#define SHORT_RETRY_DEF 8
209
Forest Bond5449c682009-04-25 10:30:44 -0400210DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
211
212#define LONG_RETRY_MIN 0
213#define LONG_RETRY_MAX 15
214#define LONG_RETRY_DEF 4
215
Forest Bond5449c682009-04-25 10:30:44 -0400216DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
217
Forest Bond5449c682009-04-25 10:30:44 -0400218/* BasebandType[] baseband type selected
219 0: indicate 802.11a type
220 1: indicate 802.11b type
221 2: indicate 802.11g type
222*/
223#define BBP_TYPE_MIN 0
224#define BBP_TYPE_MAX 2
225#define BBP_TYPE_DEF 2
226
227DEVICE_PARAM(BasebandType, "baseband type");
228
Forest Bond5449c682009-04-25 10:30:44 -0400229/* 80211hEnable[]
230 0: indicate disable 802.11h
231 1: indicate enable 802.11h
232*/
233
234#define X80211h_MODE_DEF 0
235
236DEVICE_PARAM(b80211hEnable, "802.11h mode");
237
238/* 80211hEnable[]
239 0: indicate disable 802.11h
240 1: indicate enable 802.11h
241*/
242
243#define DIVERSITY_ANT_DEF 0
244
245DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
246
Forest Bond5449c682009-04-25 10:30:44 -0400247//
248// Static vars definitions
249//
250
Joe Perches915006c2013-03-18 10:44:47 -0700251static int device_nics = 0;
252static PSDevice pDevice_Infos = NULL;
Forest Bond5449c682009-04-25 10:30:44 -0400253static struct net_device *root_device_dev = NULL;
254
Joe Perches915006c2013-03-18 10:44:47 -0700255static CHIP_INFO chip_info_table[] = {
256 { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ",
257 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN },
258 {0, NULL}
Forest Bond5449c682009-04-25 10:30:44 -0400259};
260
Guillaume Clement9e4c5c22014-07-22 22:08:28 +0200261static const struct pci_device_id vt6655_pci_id_table[] = {
Jim Liebdb6cb902009-07-23 17:20:49 -0700262 { PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
263 { 0, }
Forest Bond5449c682009-04-25 10:30:44 -0400264};
Forest Bond5449c682009-04-25 10:30:44 -0400265
266/*--------------------- Static Functions --------------------------*/
267
Charles Clément013a4682010-06-15 10:39:24 -0700268static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
Joe Perches915006c2013-03-18 10:44:47 -0700269static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, PCHIP_INFO);
Forest Bond5449c682009-04-25 10:30:44 -0400270static void device_free_info(PSDevice pDevice);
Joe Perches915006c2013-03-18 10:44:47 -0700271static bool device_get_pci_info(PSDevice, struct pci_dev *pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400272static void device_print_info(PSDevice pDevice);
273static struct net_device_stats *device_get_stats(struct net_device *dev);
274static void device_init_diversity_timer(PSDevice pDevice);
275static int device_open(struct net_device *dev);
276static int device_xmit(struct sk_buff *skb, struct net_device *dev);
Joe Perches915006c2013-03-18 10:44:47 -0700277static irqreturn_t device_intr(int irq, void *dev_instance);
Forest Bond5449c682009-04-25 10:30:44 -0400278static void device_set_multi(struct net_device *dev);
279static int device_close(struct net_device *dev);
280static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
281
Forest Bond5449c682009-04-25 10:30:44 -0400282#ifdef CONFIG_PM
283static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
Alan Coxf408ade2009-06-10 17:30:49 +0100284static int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
Forest Bond5449c682009-04-25 10:30:44 -0400285static int viawget_resume(struct pci_dev *pcid);
Guillaume Clement9e4c5c22014-07-22 22:08:28 +0200286static struct notifier_block device_notifier = {
Peter Huewe34381c22011-01-10 23:28:06 +0100287 .notifier_call = device_notify_reboot,
288 .next = NULL,
289 .priority = 0,
Forest Bond5449c682009-04-25 10:30:44 -0400290};
291#endif
Forest Bond5449c682009-04-25 10:30:44 -0400292
Forest Bond5449c682009-04-25 10:30:44 -0400293static void device_init_rd0_ring(PSDevice pDevice);
294static void device_init_rd1_ring(PSDevice pDevice);
295static void device_init_defrag_cb(PSDevice pDevice);
296static void device_init_td0_ring(PSDevice pDevice);
297static void device_init_td1_ring(PSDevice pDevice);
298
Forest Bond5449c682009-04-25 10:30:44 -0400299static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
Forest Bond5449c682009-04-25 10:30:44 -0400300//2008-0714<Add>by Mike Liu
Charles Clément7b6a0012010-08-01 17:15:50 +0200301static bool device_release_WPADEV(PSDevice pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400302
James A Shacklefordebc43d02014-05-31 20:09:05 -0400303static int ethtool_ioctl(struct net_device *dev, void __user *useraddr);
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700304static int device_rx_srv(PSDevice pDevice, unsigned int uIdx);
305static int device_tx_srv(PSDevice pDevice, unsigned int uIdx);
Charles Clément7b6a0012010-08-01 17:15:50 +0200306static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
Forest Bond5449c682009-04-25 10:30:44 -0400307static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
308static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
309static void device_free_td0_ring(PSDevice pDevice);
310static void device_free_td1_ring(PSDevice pDevice);
311static void device_free_rd0_ring(PSDevice pDevice);
312static void device_free_rd1_ring(PSDevice pDevice);
313static void device_free_rings(PSDevice pDevice);
314static void device_free_frag_buf(PSDevice pDevice);
Charles Clément5c9824e2010-06-02 09:51:59 -0700315static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -0700316 unsigned char *dest, unsigned char *source);
Forest Bond5449c682009-04-25 10:30:44 -0400317
Forest Bond5449c682009-04-25 10:30:44 -0400318/*--------------------- Export Variables --------------------------*/
319
320/*--------------------- Export Functions --------------------------*/
321
Joe Perches915006c2013-03-18 10:44:47 -0700322static char *get_chip_name(int chip_id)
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530323{
324 int i;
Guillaume Clement6b711272014-07-25 01:06:16 +0200325
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530326 for (i = 0; chip_info_table[i].name != NULL; i++)
327 if (chip_info_table[i].chip_id == chip_id)
328 break;
329 return chip_info_table[i].name;
Forest Bond5449c682009-04-25 10:30:44 -0400330}
331
Bill Pembertonf4e1b7c2012-11-19 13:26:53 -0500332static void vt6655_remove(struct pci_dev *pcid)
Forest Bond5449c682009-04-25 10:30:44 -0400333{
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530334 PSDevice pDevice = pci_get_drvdata(pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400335
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530336 if (pDevice == NULL)
337 return;
338 device_free_info(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400339}
340
Joe Perches915006c2013-03-18 10:44:47 -0700341static void device_get_options(PSDevice pDevice, int index, char *devname)
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530342{
343 POPTIONS pOpts = &(pDevice->sOpts);
Forest Bond5449c682009-04-25 10:30:44 -0400344
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530345 pOpts->nRxDescs0 = RX_DESC_DEF0;
346 pOpts->nRxDescs1 = RX_DESC_DEF1;
347 pOpts->nTxDescs[0] = TX_DESC_DEF0;
348 pOpts->nTxDescs[1] = TX_DESC_DEF1;
349 pOpts->flags |= DEVICE_FLAGS_IP_ALIGN;
350 pOpts->int_works = INT_WORKS_DEF;
351 pOpts->rts_thresh = RTS_THRESH_DEF;
352 pOpts->frag_thresh = FRAG_THRESH_DEF;
353 pOpts->data_rate = DATA_RATE_DEF;
354 pOpts->channel_num = CHANNEL_DEF;
Forest Bond5449c682009-04-25 10:30:44 -0400355
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530356 pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE;
357 pOpts->flags |= DEVICE_FLAGS_OP_MODE;
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530358 pOpts->short_retry = SHORT_RETRY_DEF;
359 pOpts->long_retry = LONG_RETRY_DEF;
360 pOpts->bbp_type = BBP_TYPE_DEF;
361 pOpts->flags |= DEVICE_FLAGS_80211h_MODE;
362 pOpts->flags |= DEVICE_FLAGS_DiversityANT;
Forest Bond5449c682009-04-25 10:30:44 -0400363}
364
365static void
366device_set_options(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -0700367 unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
368 unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
369 unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond5449c682009-04-25 10:30:44 -0400370
Joe Perches915006c2013-03-18 10:44:47 -0700371 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
372 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
373 memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
Forest Bond5449c682009-04-25 10:30:44 -0400374
Joe Perches915006c2013-03-18 10:44:47 -0700375 pDevice->uChannel = pDevice->sOpts.channel_num;
376 pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh;
377 pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh;
378 pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
379 pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
380 pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
381 pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0;
382 pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0;
383 pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0;
384 pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
385 pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
386 pDevice->uConnectionRate = pDevice->sOpts.data_rate;
Guillaume Clementa1613422014-07-25 01:06:22 +0200387 if (pDevice->uConnectionRate < RATE_AUTO)
388 pDevice->bFixRate = true;
Joe Perches915006c2013-03-18 10:44:47 -0700389 pDevice->byBBType = pDevice->sOpts.bbp_type;
390 pDevice->byPacketType = pDevice->byBBType;
Forest Bond5449c682009-04-25 10:30:44 -0400391
392//PLICE_DEBUG->
393 pDevice->byAutoFBCtrl = AUTO_FB_0;
Forest Bond5449c682009-04-25 10:30:44 -0400394//PLICE_DEBUG<-
Joe Perches915006c2013-03-18 10:44:47 -0700395 pDevice->bUpdateBBVGA = true;
396 pDevice->byFOETuning = 0;
397 pDevice->wCTSDuration = 0;
398 pDevice->byPreambleType = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400399
Joe Perches915006c2013-03-18 10:44:47 -0700400 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uChannel= %d\n", (int)pDevice->uChannel);
401 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byOpMode= %d\n", (int)pDevice->byOpMode);
402 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ePSMode= %d\n", (int)pDevice->ePSMode);
403 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold);
404 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit);
405 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit);
406 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byPreambleType= %d\n", (int)pDevice->byPreambleType);
407 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
408 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uConnectionRate= %d\n", (int)pDevice->uConnectionRate);
409 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byBBType= %d\n", (int)pDevice->byBBType);
410 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable);
411 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON);
Forest Bond5449c682009-04-25 10:30:44 -0400412}
413
Joe Perches915006c2013-03-18 10:44:47 -0700414static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult)
Forest Bond5449c682009-04-25 10:30:44 -0400415{
Joe Perches915006c2013-03-18 10:44:47 -0700416 unsigned int ii;
417 unsigned long dwDuration = 0;
418 unsigned char byRPI0 = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400419
Joe Perches915006c2013-03-18 10:44:47 -0700420 for (ii = 1; ii < 8; ii++) {
421 pDevice->dwRPIs[ii] *= 255;
422 dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration));
423 dwDuration <<= 10;
424 pDevice->dwRPIs[ii] /= dwDuration;
425 pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii];
426 byRPI0 += pDevice->abyRPIs[ii];
427 }
428 pDevice->abyRPIs[0] = (0xFF - byRPI0);
Forest Bond5449c682009-04-25 10:30:44 -0400429
Joe Perches915006c2013-03-18 10:44:47 -0700430 if (pDevice->uNumOfMeasureEIDs == 0) {
431 VNTWIFIbMeasureReport(pDevice->pMgmt,
432 true,
433 pDevice->pCurrMeasureEID,
434 byResult,
435 pDevice->byBasicMap,
436 pDevice->byCCAFraction,
437 pDevice->abyRPIs
438 );
439 } else {
440 VNTWIFIbMeasureReport(pDevice->pMgmt,
441 false,
442 pDevice->pCurrMeasureEID,
443 byResult,
444 pDevice->byBasicMap,
445 pDevice->byCCAFraction,
446 pDevice->abyRPIs
447 );
448 CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs);
449 }
Forest Bond5449c682009-04-25 10:30:44 -0400450}
451
Forest Bond5449c682009-04-25 10:30:44 -0400452//
Justin P. Mattock789d1ae2012-08-20 08:43:13 -0700453// Initialisation of MAC & BBP registers
Forest Bond5449c682009-04-25 10:30:44 -0400454//
455
456static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
457{
Joe Perches915006c2013-03-18 10:44:47 -0700458 unsigned int ii;
459 unsigned char byValue;
460 unsigned char byValue1;
461 unsigned char byCCKPwrdBm = 0;
462 unsigned char byOFDMPwrdBm = 0;
463 int zonetype = 0;
464 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
Guillaume Clement6b711272014-07-25 01:06:16 +0200465
Joe Perches915006c2013-03-18 10:44:47 -0700466 MACbShutdown(pDevice->PortOffset);
467 BBvSoftwareReset(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400468
Joe Perches915006c2013-03-18 10:44:47 -0700469 if ((InitType == DEVICE_INIT_COLD) ||
470 (InitType == DEVICE_INIT_DXPL)) {
471 // Do MACbSoftwareReset in MACvInitialize
472 MACbSoftwareReset(pDevice->PortOffset);
473 // force CCK
474 pDevice->bCCK = true;
475 pDevice->bAES = false;
476 pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE
477 pDevice->bNonERPPresent = false;
478 pDevice->bBarkerPreambleMd = false;
479 pDevice->wCurrentRate = RATE_1M;
480 pDevice->byTopOFDMBasicRate = RATE_24M;
481 pDevice->byTopCCKBasicRate = RATE_1M;
Forest Bond5449c682009-04-25 10:30:44 -0400482
Joe Perches915006c2013-03-18 10:44:47 -0700483 pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
Forest Bond5449c682009-04-25 10:30:44 -0400484
Joe Perches915006c2013-03-18 10:44:47 -0700485 // init MAC
486 MACvInitialize(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400487
Joe Perches915006c2013-03-18 10:44:47 -0700488 // Get Local ID
489 VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID));
Forest Bond5449c682009-04-25 10:30:44 -0400490
Joe Perches915006c2013-03-18 10:44:47 -0700491 spin_lock_irq(&pDevice->lock);
492 SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
Forest Bond5449c682009-04-25 10:30:44 -0400493
Joe Perches915006c2013-03-18 10:44:47 -0700494 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -0400495
Joe Perches915006c2013-03-18 10:44:47 -0700496 // Get Channel range
Forest Bond5449c682009-04-25 10:30:44 -0400497
Joe Perches915006c2013-03-18 10:44:47 -0700498 pDevice->byMinChannel = 1;
499 pDevice->byMaxChannel = CB_MAX_CHANNEL;
Forest Bond5449c682009-04-25 10:30:44 -0400500
Joe Perches915006c2013-03-18 10:44:47 -0700501 // Get Antena
502 byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
503 if (byValue & EEP_ANTINV)
504 pDevice->bTxRxAntInv = true;
505 else
506 pDevice->bTxRxAntInv = false;
Forest Bond5449c682009-04-25 10:30:44 -0400507
Joe Perches915006c2013-03-18 10:44:47 -0700508 byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
509 if (byValue == 0) // if not set default is All
510 byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
Joe Perchesf2046f92013-03-18 20:55:36 -0700511
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300512 pDevice->ulDiversityNValue = 100*260;
513 pDevice->ulDiversityMValue = 100*16;
514 pDevice->byTMax = 1;
515 pDevice->byTMax2 = 4;
516 pDevice->ulSQ3TH = 0;
517 pDevice->byTMax3 = 64;
Forest Bond5449c682009-04-25 10:30:44 -0400518
Joe Perches915006c2013-03-18 10:44:47 -0700519 if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
520 pDevice->byAntennaCount = 2;
521 pDevice->byTxAntennaMode = ANT_B;
522 pDevice->dwTxAntennaSel = 1;
523 pDevice->dwRxAntennaSel = 1;
Teodora Baluta1208f142013-11-10 17:12:42 +0200524 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700525 pDevice->byRxAntennaMode = ANT_A;
526 else
527 pDevice->byRxAntennaMode = ANT_B;
528 // chester for antenna
529 byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
Joe Perches915006c2013-03-18 10:44:47 -0700530 if ((byValue1 & 0x08) == 0)
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300531 pDevice->bDiversityEnable = false;
Joe Perches915006c2013-03-18 10:44:47 -0700532 else
533 pDevice->bDiversityEnable = true;
Joe Perches915006c2013-03-18 10:44:47 -0700534 } else {
535 pDevice->bDiversityEnable = false;
536 pDevice->byAntennaCount = 1;
537 pDevice->dwTxAntennaSel = 0;
538 pDevice->dwRxAntennaSel = 0;
539 if (byValue & EEP_ANTENNA_AUX) {
540 pDevice->byTxAntennaMode = ANT_A;
Teodora Baluta1208f142013-11-10 17:12:42 +0200541 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700542 pDevice->byRxAntennaMode = ANT_B;
543 else
544 pDevice->byRxAntennaMode = ANT_A;
545 } else {
546 pDevice->byTxAntennaMode = ANT_B;
Teodora Baluta1208f142013-11-10 17:12:42 +0200547 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700548 pDevice->byRxAntennaMode = ANT_A;
549 else
550 pDevice->byRxAntennaMode = ANT_B;
551 }
552 }
Joe Perches915006c2013-03-18 10:44:47 -0700553 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
554 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2);
Forest Bond5449c682009-04-25 10:30:44 -0400555
Forest Bond5449c682009-04-25 10:30:44 -0400556//2008-8-4 <add> by chester
557//zonetype initial
Joe Perches915006c2013-03-18 10:44:47 -0700558 pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
559 zonetype = Config_FileOperation(pDevice, false, NULL);
560 if (zonetype >= 0) { //read zonetype file ok!
561 if ((zonetype == 0) &&
562 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { //for USA
563 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
564 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
565 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700566 } else if ((zonetype == 1) &&
Joe Perches915006c2013-03-18 10:44:47 -0700567 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { //for Japan
568 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
569 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700570 } else if ((zonetype == 2) &&
Joe Perches915006c2013-03-18 10:44:47 -0700571 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { //for Europe
572 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
573 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
574 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n");
575 }
Forest Bond5449c682009-04-25 10:30:44 -0400576
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700577 else {
Joe Perches915006c2013-03-18 10:44:47 -0700578 if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
Guillaume Clement941ead92014-07-25 01:06:21 +0200579 pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", zonetype, pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
Joe Perches915006c2013-03-18 10:44:47 -0700580 else
Guillaume Clement941ead92014-07-25 01:06:21 +0200581 pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n", zonetype);
Joe Perches915006c2013-03-18 10:44:47 -0700582 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700583 } else
Guillaume Clement941ead92014-07-25 01:06:21 +0200584 pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n", SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
Forest Bond5449c682009-04-25 10:30:44 -0400585
Joe Perches915006c2013-03-18 10:44:47 -0700586 // Get RFType
587 pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
Forest Bond5449c682009-04-25 10:30:44 -0400588
Joe Perches915006c2013-03-18 10:44:47 -0700589 if ((pDevice->byRFType & RF_EMU) != 0) {
590 // force change RevID for VT3253 emu
591 pDevice->byRevId = 0x80;
592 }
Forest Bond5449c682009-04-25 10:30:44 -0400593
Joe Perches915006c2013-03-18 10:44:47 -0700594 pDevice->byRFType &= RF_MASK;
595 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
Forest Bond5449c682009-04-25 10:30:44 -0400596
Guido Martínezbc5cf652014-04-19 16:45:00 -0300597 if (!pDevice->bZoneRegExist)
Joe Perches915006c2013-03-18 10:44:47 -0700598 pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
Guido Martínezbc5cf652014-04-19 16:45:00 -0300599
Joe Perches915006c2013-03-18 10:44:47 -0700600 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
Forest Bond5449c682009-04-25 10:30:44 -0400601
Joe Perches915006c2013-03-18 10:44:47 -0700602 //Init RF module
603 RFbInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400604
Joe Perches915006c2013-03-18 10:44:47 -0700605 //Get Desire Power Value
606 pDevice->byCurPwr = 0xFF;
607 pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
608 pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
Joe Perchesf2046f92013-03-18 20:55:36 -0700609
Forest Bond5449c682009-04-25 10:30:44 -0400610 // Load power Table
611
Joe Perches915006c2013-03-18 10:44:47 -0700612 for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
613 pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
Guido Martínezbc5cf652014-04-19 16:45:00 -0300614 if (pDevice->abyCCKPwrTbl[ii + 1] == 0)
Joe Perches915006c2013-03-18 10:44:47 -0700615 pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300616
Joe Perches915006c2013-03-18 10:44:47 -0700617 pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
Guido Martínezbc5cf652014-04-19 16:45:00 -0300618 if (pDevice->abyOFDMPwrTbl[ii + 1] == 0)
Joe Perches915006c2013-03-18 10:44:47 -0700619 pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300620
Joe Perches915006c2013-03-18 10:44:47 -0700621 pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
622 pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
623 }
Forest Bond5449c682009-04-25 10:30:44 -0400624 //2008-8-4 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -0700625 //recover 12,13 ,14channel for EUROPE by 11 channel
626 if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
627 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
628 (pDevice->byOriginalZonetype == ZoneType_USA)) {
629 for (ii = 11; ii < 14; ii++) {
630 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
631 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
Forest Bond5449c682009-04-25 10:30:44 -0400632
Joe Perches915006c2013-03-18 10:44:47 -0700633 }
634 }
Forest Bond5449c682009-04-25 10:30:44 -0400635
Joe Perches915006c2013-03-18 10:44:47 -0700636 // Load OFDM A Power Table
637 for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
638 pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
639 pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
640 }
641 init_channel_table((void *)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400642
Joe Perches915006c2013-03-18 10:44:47 -0700643 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
644 MACvSelectPage1(pDevice->PortOffset);
645 VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
646 MACvSelectPage0(pDevice->PortOffset);
647 }
Forest Bond5449c682009-04-25 10:30:44 -0400648
Joe Perches915006c2013-03-18 10:44:47 -0700649 // use relative tx timeout and 802.11i D4
650 MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
Forest Bond5449c682009-04-25 10:30:44 -0400651
Joe Perches915006c2013-03-18 10:44:47 -0700652 // set performance parameter by registry
653 MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
654 MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
Forest Bond5449c682009-04-25 10:30:44 -0400655
Joe Perches915006c2013-03-18 10:44:47 -0700656 // reset TSF counter
657 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
658 // enable TSF counter
659 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
Forest Bond5449c682009-04-25 10:30:44 -0400660
Joe Perches915006c2013-03-18 10:44:47 -0700661 // initialize BBP registers
662 BBbVT3253Init(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400663
Joe Perches915006c2013-03-18 10:44:47 -0700664 if (pDevice->bUpdateBBVGA) {
665 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
666 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
667 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
668 }
Joe Perches915006c2013-03-18 10:44:47 -0700669 BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
670 BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
Forest Bond5449c682009-04-25 10:30:44 -0400671
Joe Perches915006c2013-03-18 10:44:47 -0700672 pDevice->byCurrentCh = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400673
Joe Perches915006c2013-03-18 10:44:47 -0700674 // Set BB and packet type at the same time.
675 // Set Short Slot Time, xIFS, and RSPINF.
Guido Martínezbc5cf652014-04-19 16:45:00 -0300676 if (pDevice->uConnectionRate == RATE_AUTO)
Joe Perches915006c2013-03-18 10:44:47 -0700677 pDevice->wCurrentRate = RATE_54M;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300678 else
Joe Perches915006c2013-03-18 10:44:47 -0700679 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Forest Bond5449c682009-04-25 10:30:44 -0400680
Joe Perches915006c2013-03-18 10:44:47 -0700681 // default G Mode
682 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
683 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
Forest Bond5449c682009-04-25 10:30:44 -0400684
Joe Perches915006c2013-03-18 10:44:47 -0700685 pDevice->bRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400686
Joe Perches915006c2013-03-18 10:44:47 -0700687 pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
688 pDevice->bHWRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400689
Joe Perches915006c2013-03-18 10:44:47 -0700690 if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
691 // Get GPIO
692 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
Forest Bond5449c682009-04-25 10:30:44 -0400693//2008-4-14 <add> by chester for led issue
Joe Perches915006c2013-03-18 10:44:47 -0700694#ifdef FOR_LED_ON_NOTEBOOK
Guido Martínezbc5cf652014-04-19 16:45:00 -0300695 if (pDevice->byGPIO & GPIO0_DATA)
696 pDevice->bHWRadioOff = true;
Forest Bond5449c682009-04-25 10:30:44 -0400697
Guido Martínezbc5cf652014-04-19 16:45:00 -0300698 if (!(pDevice->byGPIO & GPIO0_DATA))
699 pDevice->bHWRadioOff = false;
Joe Perches915006c2013-03-18 10:44:47 -0700700 }
Guido Martínezbc5cf652014-04-19 16:45:00 -0300701
702 if (pDevice->bRadioControlOff)
Joe Perches915006c2013-03-18 10:44:47 -0700703 CARDbRadioPowerOff(pDevice);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300704 else
705 CARDbRadioPowerOn(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400706#else
Joe Perches915006c2013-03-18 10:44:47 -0700707 if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
708 (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
709 pDevice->bHWRadioOff = true;
710 }
711 }
Guido Martínezbc5cf652014-04-19 16:45:00 -0300712 if (pDevice->bHWRadioOff || pDevice->bRadioControlOff)
Joe Perches915006c2013-03-18 10:44:47 -0700713 CARDbRadioPowerOff(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400714
715#endif
Joe Perches915006c2013-03-18 10:44:47 -0700716}
717pMgmt->eScanType = WMAC_SCAN_PASSIVE;
718// get Permanent network address
719SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
720DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n",
721 pDevice->abyCurrentNetAddr);
Forest Bond5449c682009-04-25 10:30:44 -0400722
Joe Perches915006c2013-03-18 10:44:47 -0700723// reset Tx pointer
724CARDvSafeResetRx(pDevice);
725// reset Rx pointer
726CARDvSafeResetTx(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400727
Guido Martínezbc5cf652014-04-19 16:45:00 -0300728if (pDevice->byLocalID <= REV_ID_VT3253_A1)
Joe Perches915006c2013-03-18 10:44:47 -0700729 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
Forest Bond5449c682009-04-25 10:30:44 -0400730
Joe Perches915006c2013-03-18 10:44:47 -0700731pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Forest Bond5449c682009-04-25 10:30:44 -0400732
Joe Perches915006c2013-03-18 10:44:47 -0700733// Turn On Rx DMA
734MACvReceive0(pDevice->PortOffset);
735MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400736
Joe Perches915006c2013-03-18 10:44:47 -0700737// start the adapter
738MACvStart(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400739
Joe Perches915006c2013-03-18 10:44:47 -0700740netif_stop_queue(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400741}
742
Guillaume Clement84b50762014-07-25 01:06:18 +0200743static void device_init_diversity_timer(PSDevice pDevice)
744{
Joe Perches915006c2013-03-18 10:44:47 -0700745 init_timer(&pDevice->TimerSQ3Tmax1);
746 pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
747 pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
748 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400749
Joe Perches915006c2013-03-18 10:44:47 -0700750 init_timer(&pDevice->TimerSQ3Tmax2);
751 pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
752 pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
753 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400754
Joe Perches915006c2013-03-18 10:44:47 -0700755 init_timer(&pDevice->TimerSQ3Tmax3);
756 pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
757 pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
758 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400759}
760
Charles Clément7b6a0012010-08-01 17:15:50 +0200761static bool device_release_WPADEV(PSDevice pDevice)
Forest Bond5449c682009-04-25 10:30:44 -0400762{
Joe Perches915006c2013-03-18 10:44:47 -0700763 viawget_wpa_header *wpahdr;
764 int ii = 0;
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300765
Joe Perches915006c2013-03-18 10:44:47 -0700766 //send device close to wpa_supplicnat layer
Teodora Baluta1208f142013-11-10 17:12:42 +0200767 if (pDevice->bWPADEVUp) {
Joe Perches915006c2013-03-18 10:44:47 -0700768 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
769 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
770 wpahdr->resp_ie_len = 0;
771 wpahdr->req_ie_len = 0;
772 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
773 pDevice->skb->dev = pDevice->wpadev;
774 skb_reset_mac_header(pDevice->skb);
775 pDevice->skb->pkt_type = PACKET_HOST;
776 pDevice->skb->protocol = htons(ETH_P_802_2);
777 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
778 netif_rx(pDevice->skb);
779 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Forest Bond5449c682009-04-25 10:30:44 -0400780
Teodora Baluta1208f142013-11-10 17:12:42 +0200781 while (pDevice->bWPADEVUp) {
Joe Perches915006c2013-03-18 10:44:47 -0700782 set_current_state(TASK_UNINTERRUPTIBLE);
783 schedule_timeout(HZ / 20); //wait 50ms
784 ii++;
785 if (ii > 20)
786 break;
787 }
788 }
789 return true;
Forest Bond5449c682009-04-25 10:30:44 -0400790}
791
Forest Bond57211352009-06-02 14:44:33 -0400792static const struct net_device_ops device_netdev_ops = {
Devendra Naga502eb532012-09-07 00:08:04 +0530793 .ndo_open = device_open,
794 .ndo_stop = device_close,
795 .ndo_do_ioctl = device_ioctl,
796 .ndo_get_stats = device_get_stats,
797 .ndo_start_xmit = device_xmit,
798 .ndo_set_rx_mode = device_set_multi,
Forest Bond57211352009-06-02 14:44:33 -0400799};
800
Bill Pembertona1179b22012-11-19 13:21:54 -0500801static int
Charles Clément013a4682010-06-15 10:39:24 -0700802vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
Forest Bond5449c682009-04-25 10:30:44 -0400803{
Joe Perches915006c2013-03-18 10:44:47 -0700804 static bool bFirst = true;
805 struct net_device *dev = NULL;
806 PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data;
807 PSDevice pDevice;
808 int rc;
Guillaume Clement941ead92014-07-25 01:06:21 +0200809
Joe Perches915006c2013-03-18 10:44:47 -0700810 if (device_nics++ >= MAX_UINTS) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200811 pr_notice(DEVICE_NAME ": already found %d NICs\n", device_nics);
Joe Perches915006c2013-03-18 10:44:47 -0700812 return -ENODEV;
813 }
Forest Bond5449c682009-04-25 10:30:44 -0400814
Joe Perches915006c2013-03-18 10:44:47 -0700815 dev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -0400816
Joe Perches915006c2013-03-18 10:44:47 -0700817 pDevice = (PSDevice) netdev_priv(dev);
Forest Bondc9d03522009-06-01 20:00:14 -0400818
Joe Perches915006c2013-03-18 10:44:47 -0700819 if (dev == NULL) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200820 pr_err(DEVICE_NAME ": allocate net device failed\n");
Joe Perches915006c2013-03-18 10:44:47 -0700821 return -ENOMEM;
822 }
Forest Bond5449c682009-04-25 10:30:44 -0400823
Joe Perches915006c2013-03-18 10:44:47 -0700824 // Chain it all together
Joe Perches915006c2013-03-18 10:44:47 -0700825 SET_NETDEV_DEV(dev, &pcid->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400826
Joe Perches915006c2013-03-18 10:44:47 -0700827 if (bFirst) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200828 pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
829 pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
Joe Perches915006c2013-03-18 10:44:47 -0700830 bFirst = false;
831 }
Forest Bond5449c682009-04-25 10:30:44 -0400832
Joe Perches915006c2013-03-18 10:44:47 -0700833 vt6655_init_info(pcid, &pDevice, pChip_info);
834 pDevice->dev = dev;
835 pDevice->next_module = root_device_dev;
836 root_device_dev = dev;
Forest Bond5449c682009-04-25 10:30:44 -0400837
Joe Perches915006c2013-03-18 10:44:47 -0700838 if (pci_enable_device(pcid)) {
839 device_free_info(pDevice);
840 return -ENODEV;
841 }
842 dev->irq = pcid->irq;
Kulikov Vasiliy13b631a2010-08-03 19:44:20 +0400843
Forest Bond5449c682009-04-25 10:30:44 -0400844#ifdef DEBUG
Guillaume Clement941ead92014-07-25 01:06:21 +0200845 pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr);
Forest Bond5449c682009-04-25 10:30:44 -0400846#endif
Teodora Baluta1208f142013-11-10 17:12:42 +0200847 if (!device_get_pci_info(pDevice, pcid)) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200848 pr_err(DEVICE_NAME ": Failed to find PCI device.\n");
Joe Perches915006c2013-03-18 10:44:47 -0700849 device_free_info(pDevice);
850 return -ENODEV;
851 }
Forest Bond5449c682009-04-25 10:30:44 -0400852
853#if 1
854
855#ifdef DEBUG
856
Guillaume Clement941ead92014-07-25 01:06:21 +0200857 pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size);
Forest Bond5449c682009-04-25 10:30:44 -0400858 {
859 int i;
Joe Perches915006c2013-03-18 10:44:47 -0700860 u32 bar, len;
Forest Bond5449c682009-04-25 10:30:44 -0400861 u32 address[] = {
Joe Perches915006c2013-03-18 10:44:47 -0700862 PCI_BASE_ADDRESS_0,
863 PCI_BASE_ADDRESS_1,
864 PCI_BASE_ADDRESS_2,
865 PCI_BASE_ADDRESS_3,
866 PCI_BASE_ADDRESS_4,
867 PCI_BASE_ADDRESS_5,
868 0};
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700869 for (i = 0; address[i]; i++) {
Forest Bond5449c682009-04-25 10:30:44 -0400870 pci_read_config_dword(pcid, address[i], &bar);
Guillaume Clement941ead92014-07-25 01:06:21 +0200871 pr_debug("bar %d is %x\n", i, bar);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700872 if (!bar) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200873 pr_debug("bar %d not implemented\n", i);
Forest Bond5449c682009-04-25 10:30:44 -0400874 continue;
875 }
876 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
Joe Perches915006c2013-03-18 10:44:47 -0700877 /* This is IO */
Forest Bond5449c682009-04-25 10:30:44 -0400878
Joe Perches915006c2013-03-18 10:44:47 -0700879 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
880 len = len & ~(len - 1);
Forest Bond5449c682009-04-25 10:30:44 -0400881
Guillaume Clement941ead92014-07-25 01:06:21 +0200882 pr_debug("IO space: len in IO %x, BAR %d\n", len, i);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700883 } else {
Forest Bond5449c682009-04-25 10:30:44 -0400884 len = bar & 0xFFFFFFF0;
885 len = ~len + 1;
886
Guillaume Clement941ead92014-07-25 01:06:21 +0200887 pr_debug("len in MEM %x, BAR %d\n", len, i);
Forest Bond5449c682009-04-25 10:30:44 -0400888 }
889 }
890 }
891#endif
892
Forest Bond5449c682009-04-25 10:30:44 -0400893#endif
894
Guillaume Clement16834402014-07-22 22:08:26 +0200895 pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
Forest Bond5449c682009-04-25 10:30:44 -0400896
Guillaume Clement16834402014-07-22 22:08:26 +0200897 if (pDevice->PortOffset == NULL) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200898 pr_err(DEVICE_NAME ": Failed to IO remapping ..\n");
Joe Perches915006c2013-03-18 10:44:47 -0700899 device_free_info(pDevice);
900 return -ENODEV;
901 }
Forest Bond5449c682009-04-25 10:30:44 -0400902
Joe Perches915006c2013-03-18 10:44:47 -0700903 rc = pci_request_regions(pcid, DEVICE_NAME);
904 if (rc) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200905 pr_err(DEVICE_NAME ": Failed to find PCI device\n");
Joe Perches915006c2013-03-18 10:44:47 -0700906 device_free_info(pDevice);
907 return -ENODEV;
908 }
Forest Bond5449c682009-04-25 10:30:44 -0400909
Joe Perches915006c2013-03-18 10:44:47 -0700910 dev->base_addr = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400911#ifdef PLICE_DEBUG
Joe Perches915006c2013-03-18 10:44:47 -0700912 unsigned char value;
Forest Bond5449c682009-04-25 10:30:44 -0400913
914 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Guillaume Clement941ead92014-07-25 01:06:21 +0200915 pr_debug("Before write: value is %x\n", value);
Joe Perches915006c2013-03-18 10:44:47 -0700916 VNSvOutPortB(pDevice->PortOffset, value);
Forest Bond5449c682009-04-25 10:30:44 -0400917 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Guillaume Clement941ead92014-07-25 01:06:21 +0200918 pr_debug("After write: value is %x\n", value);
Forest Bond5449c682009-04-25 10:30:44 -0400919#endif
920
Forest Bond5449c682009-04-25 10:30:44 -0400921#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -0700922 pDevice->PortOffset = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400923#endif
Joe Perches915006c2013-03-18 10:44:47 -0700924 // do reset
925 if (!MACbSoftwareReset(pDevice->PortOffset)) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200926 pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n");
Joe Perches915006c2013-03-18 10:44:47 -0700927 device_free_info(pDevice);
928 return -ENODEV;
929 }
930 // initial to reload eeprom
931 MACvInitialize(pDevice->PortOffset);
932 MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -0400933
Joe Perches915006c2013-03-18 10:44:47 -0700934 device_get_options(pDevice, device_nics-1, dev->name);
935 device_set_options(pDevice);
936 //Mask out the options cannot be set to the chip
937 pDevice->sOpts.flags &= pChip_info->flags;
Forest Bond5449c682009-04-25 10:30:44 -0400938
Joe Perches915006c2013-03-18 10:44:47 -0700939 //Enable the chip specified capabilities
940 pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL);
941 pDevice->tx_80211 = device_dma0_tx_80211;
942 pDevice->sMgmtObj.pAdapter = (void *)pDevice;
943 pDevice->pMgmt = &(pDevice->sMgmtObj);
Forest Bond5449c682009-04-25 10:30:44 -0400944
Joe Perches915006c2013-03-18 10:44:47 -0700945 dev->irq = pcid->irq;
946 dev->netdev_ops = &device_netdev_ops;
Forest Bond5449c682009-04-25 10:30:44 -0400947
Forest Bond5449c682009-04-25 10:30:44 -0400948 dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
Forest Bond5449c682009-04-25 10:30:44 -0400949
Joe Perches915006c2013-03-18 10:44:47 -0700950 rc = register_netdev(dev);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700951 if (rc) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200952 pr_err(DEVICE_NAME " Failed to register netdev\n");
Joe Perches915006c2013-03-18 10:44:47 -0700953 device_free_info(pDevice);
954 return -ENODEV;
955 }
956 device_print_info(pDevice);
957 pci_set_drvdata(pcid, pDevice);
958 return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400959}
960
961static void device_print_info(PSDevice pDevice)
962{
Joe Perches915006c2013-03-18 10:44:47 -0700963 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -0400964
Joe Perches915006c2013-03-18 10:44:47 -0700965 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id));
966 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -0400967#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -0700968 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx ", (unsigned long)pDevice->ioaddr);
Guillaume Clementbfd7a282014-07-25 01:06:17 +0200969 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -0400970#else
Joe Perches915006c2013-03-18 10:44:47 -0700971 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ",
972 (unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset);
Guillaume Clementbfd7a282014-07-25 01:06:17 +0200973 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -0400974#endif
Forest Bond5449c682009-04-25 10:30:44 -0400975}
976
Joe Perches915006c2013-03-18 10:44:47 -0700977static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice,
978 PCHIP_INFO pChip_info) {
Joe Perches915006c2013-03-18 10:44:47 -0700979 PSDevice p;
Forest Bond5449c682009-04-25 10:30:44 -0400980
Joe Perches915006c2013-03-18 10:44:47 -0700981 memset(*ppDevice, 0, sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -0400982
Joe Perches915006c2013-03-18 10:44:47 -0700983 if (pDevice_Infos == NULL) {
984 pDevice_Infos = *ppDevice;
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700985 } else {
Joe Perches915006c2013-03-18 10:44:47 -0700986 for (p = pDevice_Infos; p->next != NULL; p = p->next)
987 do {} while (0);
988 p->next = *ppDevice;
989 (*ppDevice)->prev = p;
990 }
Forest Bond5449c682009-04-25 10:30:44 -0400991
Joe Perches915006c2013-03-18 10:44:47 -0700992 (*ppDevice)->pcid = pcid;
993 (*ppDevice)->chip_id = pChip_info->chip_id;
994 (*ppDevice)->io_size = pChip_info->io_size;
995 (*ppDevice)->nTxQueues = pChip_info->nTxQueue;
996 (*ppDevice)->multicast_limit = 32;
Forest Bond5449c682009-04-25 10:30:44 -0400997
Joe Perches915006c2013-03-18 10:44:47 -0700998 spin_lock_init(&((*ppDevice)->lock));
Forest Bond5449c682009-04-25 10:30:44 -0400999}
1000
Guillaume Clement84b50762014-07-25 01:06:18 +02001001static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid)
1002{
Joe Perches915006c2013-03-18 10:44:47 -07001003 u16 pci_cmd;
1004 u8 b;
1005 unsigned int cis_addr;
Forest Bond5449c682009-04-25 10:30:44 -04001006#ifdef PLICE_DEBUG
Charles Clément3fc9b582010-06-24 11:02:27 -07001007 unsigned char pci_config[256];
Joe Perches915006c2013-03-18 10:44:47 -07001008 unsigned char value = 0x00;
1009 int ii, j;
1010 u16 max_lat = 0x0000;
Guillaume Clement6b711272014-07-25 01:06:16 +02001011
Joe Perches915006c2013-03-18 10:44:47 -07001012 memset(pci_config, 0x00, 256);
Forest Bond5449c682009-04-25 10:30:44 -04001013#endif
1014
Joe Perches915006c2013-03-18 10:44:47 -07001015 pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId);
1016 pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pDevice->SubSystemID);
1017 pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID);
1018 pci_read_config_word(pcid, PCI_COMMAND, (u16 *)&(pci_cmd));
Forest Bond5449c682009-04-25 10:30:44 -04001019
Joe Perches915006c2013-03-18 10:44:47 -07001020 pci_set_master(pcid);
Forest Bond5449c682009-04-25 10:30:44 -04001021
Joe Perches915006c2013-03-18 10:44:47 -07001022 pDevice->memaddr = pci_resource_start(pcid, 0);
1023 pDevice->ioaddr = pci_resource_start(pcid, 1);
Forest Bond5449c682009-04-25 10:30:44 -04001024
Joe Perches915006c2013-03-18 10:44:47 -07001025 cis_addr = pci_resource_start(pcid, 2);
Forest Bond5449c682009-04-25 10:30:44 -04001026
Joe Perches915006c2013-03-18 10:44:47 -07001027 pDevice->pcid = pcid;
Forest Bond5449c682009-04-25 10:30:44 -04001028
Joe Perches915006c2013-03-18 10:44:47 -07001029 pci_read_config_byte(pcid, PCI_COMMAND, &b);
1030 pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER));
Forest Bond5449c682009-04-25 10:30:44 -04001031
1032#ifdef PLICE_DEBUG
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001033 for (ii = 0; ii < 0xFF; ii++) {
Joe Perches915006c2013-03-18 10:44:47 -07001034 pci_read_config_byte(pcid, ii, &value);
Forest Bond5449c682009-04-25 10:30:44 -04001035 pci_config[ii] = value;
1036 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001037 for (ii = 0, j = 1; ii < 0x100; ii++, j++) {
1038 if (j % 16 == 0) {
Guillaume Clement941ead92014-07-25 01:06:21 +02001039 pr_debug("%x:", pci_config[ii]);
1040 pr_debug("\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001041 } else {
Guillaume Clement941ead92014-07-25 01:06:21 +02001042 pr_debug("%x:", pci_config[ii]);
Forest Bond5449c682009-04-25 10:30:44 -04001043 }
1044 }
1045#endif
Joe Perches915006c2013-03-18 10:44:47 -07001046 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001047}
1048
Guillaume Clement84b50762014-07-25 01:06:18 +02001049static void device_free_info(PSDevice pDevice)
1050{
Joe Perches915006c2013-03-18 10:44:47 -07001051 PSDevice ptr;
1052 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001053
Joe Perches915006c2013-03-18 10:44:47 -07001054 ASSERT(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001055//2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001056 device_release_WPADEV(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001057
1058//2008-07-21-01<Add>by MikeLiu
1059//unregister wpadev
Joe Perches915006c2013-03-18 10:44:47 -07001060 if (wpa_set_wpadev(pDevice, 0) != 0)
Guillaume Clement941ead92014-07-25 01:06:21 +02001061 pr_err("unregister wpadev fail?\n");
Forest Bond5449c682009-04-25 10:30:44 -04001062
Joe Perches915006c2013-03-18 10:44:47 -07001063 if (pDevice_Infos == NULL)
1064 return;
Forest Bond5449c682009-04-25 10:30:44 -04001065
Joe Perches915006c2013-03-18 10:44:47 -07001066 for (ptr = pDevice_Infos; ptr && (ptr != pDevice); ptr = ptr->next)
1067 do {} while (0);
Forest Bond5449c682009-04-25 10:30:44 -04001068
Joe Perches915006c2013-03-18 10:44:47 -07001069 if (ptr == pDevice) {
1070 if (ptr == pDevice_Infos)
1071 pDevice_Infos = ptr->next;
1072 else
1073 ptr->prev->next = ptr->next;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001074 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001075 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
1076 return;
1077 }
Forest Bond5449c682009-04-25 10:30:44 -04001078#ifdef HOSTAP
Joe Perches915006c2013-03-18 10:44:47 -07001079 if (dev)
1080 vt6655_hostap_set_hostapd(pDevice, 0, 0);
Forest Bond5449c682009-04-25 10:30:44 -04001081#endif
Joe Perches915006c2013-03-18 10:44:47 -07001082 if (dev)
1083 unregister_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001084
Joe Perches915006c2013-03-18 10:44:47 -07001085 if (pDevice->PortOffset)
Guillaume Clement16834402014-07-22 22:08:26 +02001086 iounmap(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04001087
Joe Perches915006c2013-03-18 10:44:47 -07001088 if (pDevice->pcid)
1089 pci_release_regions(pDevice->pcid);
1090 if (dev)
1091 free_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001092}
Forest Bond5449c682009-04-25 10:30:44 -04001093
Guillaume Clement84b50762014-07-25 01:06:18 +02001094static bool device_init_rings(PSDevice pDevice)
1095{
Joe Perches915006c2013-03-18 10:44:47 -07001096 void *vir_pool;
Forest Bond5449c682009-04-25 10:30:44 -04001097
Joe Perches915006c2013-03-18 10:44:47 -07001098 /*allocate all RD/TD rings a single pool*/
1099 vir_pool = pci_alloc_consistent(pDevice->pcid,
1100 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1101 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1102 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1103 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1104 &pDevice->pool_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001105
Joe Perches915006c2013-03-18 10:44:47 -07001106 if (vir_pool == NULL) {
1107 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
1108 return false;
1109 }
Forest Bond5449c682009-04-25 10:30:44 -04001110
Joe Perches915006c2013-03-18 10:44:47 -07001111 memset(vir_pool, 0,
1112 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1113 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1114 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1115 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1116 );
Forest Bond5449c682009-04-25 10:30:44 -04001117
Joe Perches915006c2013-03-18 10:44:47 -07001118 pDevice->aRD0Ring = vir_pool;
1119 pDevice->aRD1Ring = vir_pool +
1120 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001121
Joe Perches915006c2013-03-18 10:44:47 -07001122 pDevice->rd0_pool_dma = pDevice->pool_dma;
1123 pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
1124 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001125
Joe Perches915006c2013-03-18 10:44:47 -07001126 pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid,
1127 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1128 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1129 CB_BEACON_BUF_SIZE +
1130 CB_MAX_BUF_SIZE,
1131 &pDevice->tx_bufs_dma0);
Forest Bond5449c682009-04-25 10:30:44 -04001132
Joe Perches915006c2013-03-18 10:44:47 -07001133 if (pDevice->tx0_bufs == NULL) {
1134 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
1135 pci_free_consistent(pDevice->pcid,
1136 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1137 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1138 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1139 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1140 vir_pool, pDevice->pool_dma
1141 );
1142 return false;
1143 }
Forest Bond5449c682009-04-25 10:30:44 -04001144
Joe Perches915006c2013-03-18 10:44:47 -07001145 memset(pDevice->tx0_bufs, 0,
1146 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1147 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1148 CB_BEACON_BUF_SIZE +
1149 CB_MAX_BUF_SIZE
1150 );
Forest Bond5449c682009-04-25 10:30:44 -04001151
Joe Perches915006c2013-03-18 10:44:47 -07001152 pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
1153 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001154
Joe Perches915006c2013-03-18 10:44:47 -07001155 pDevice->td1_pool_dma = pDevice->td0_pool_dma +
1156 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001157
Joe Perches915006c2013-03-18 10:44:47 -07001158 // vir_pool: pvoid type
1159 pDevice->apTD0Rings = vir_pool
1160 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1161 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001162
Joe Perches915006c2013-03-18 10:44:47 -07001163 pDevice->apTD1Rings = vir_pool
1164 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1165 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
1166 + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001167
Joe Perches915006c2013-03-18 10:44:47 -07001168 pDevice->tx1_bufs = pDevice->tx0_bufs +
1169 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001170
Joe Perches915006c2013-03-18 10:44:47 -07001171 pDevice->tx_beacon_bufs = pDevice->tx1_bufs +
1172 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001173
Joe Perches915006c2013-03-18 10:44:47 -07001174 pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs +
1175 CB_BEACON_BUF_SIZE;
Forest Bond5449c682009-04-25 10:30:44 -04001176
Joe Perches915006c2013-03-18 10:44:47 -07001177 pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 +
1178 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001179
Joe Perches915006c2013-03-18 10:44:47 -07001180 pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 +
1181 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001182
Joe Perches915006c2013-03-18 10:44:47 -07001183 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001184}
1185
Guillaume Clement84b50762014-07-25 01:06:18 +02001186static void device_free_rings(PSDevice pDevice)
1187{
Joe Perches915006c2013-03-18 10:44:47 -07001188 pci_free_consistent(pDevice->pcid,
1189 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1190 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1191 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1192 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1193 ,
1194 pDevice->aRD0Ring, pDevice->pool_dma
1195 );
Forest Bond5449c682009-04-25 10:30:44 -04001196
Joe Perches915006c2013-03-18 10:44:47 -07001197 if (pDevice->tx0_bufs)
1198 pci_free_consistent(pDevice->pcid,
1199 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1200 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1201 CB_BEACON_BUF_SIZE +
1202 CB_MAX_BUF_SIZE,
1203 pDevice->tx0_bufs, pDevice->tx_bufs_dma0
1204 );
Forest Bond5449c682009-04-25 10:30:44 -04001205}
1206
Guillaume Clement84b50762014-07-25 01:06:18 +02001207static void device_init_rd0_ring(PSDevice pDevice)
1208{
Joe Perches915006c2013-03-18 10:44:47 -07001209 int i;
1210 dma_addr_t curr = pDevice->rd0_pool_dma;
1211 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001212
Joe Perches915006c2013-03-18 10:44:47 -07001213 /* Init the RD0 ring entries */
1214 for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
1215 pDesc = &(pDevice->aRD0Ring[i]);
1216 pDesc->pRDInfo = alloc_rd_info();
1217 ASSERT(pDesc->pRDInfo);
1218 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1219 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1220 pDevice->dev->name);
1221 }
1222 pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
1223 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1224 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1225 }
Forest Bond5449c682009-04-25 10:30:44 -04001226
Joe Perches915006c2013-03-18 10:44:47 -07001227 if (i > 0)
1228 pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
1229 pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001230}
1231
Guillaume Clement84b50762014-07-25 01:06:18 +02001232static void device_init_rd1_ring(PSDevice pDevice)
1233{
Joe Perches915006c2013-03-18 10:44:47 -07001234 int i;
1235 dma_addr_t curr = pDevice->rd1_pool_dma;
1236 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001237
Joe Perches915006c2013-03-18 10:44:47 -07001238 /* Init the RD1 ring entries */
1239 for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
1240 pDesc = &(pDevice->aRD1Ring[i]);
1241 pDesc->pRDInfo = alloc_rd_info();
1242 ASSERT(pDesc->pRDInfo);
1243 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1244 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1245 pDevice->dev->name);
1246 }
1247 pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
1248 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1249 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1250 }
Forest Bond5449c682009-04-25 10:30:44 -04001251
Joe Perches915006c2013-03-18 10:44:47 -07001252 if (i > 0)
1253 pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
1254 pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001255}
1256
Guillaume Clement84b50762014-07-25 01:06:18 +02001257static void device_init_defrag_cb(PSDevice pDevice)
1258{
Joe Perches915006c2013-03-18 10:44:47 -07001259 int i;
1260 PSDeFragControlBlock pDeF;
Forest Bond5449c682009-04-25 10:30:44 -04001261
Joe Perches915006c2013-03-18 10:44:47 -07001262 /* Init the fragment ctl entries */
1263 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1264 pDeF = &(pDevice->sRxDFCB[i]);
1265 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1266 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc frag bufs\n",
1267 pDevice->dev->name);
1268 }
1269 }
1270 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1271 pDevice->cbFreeDFCB = pDevice->cbDFCB;
Forest Bond5449c682009-04-25 10:30:44 -04001272}
1273
Guillaume Clement84b50762014-07-25 01:06:18 +02001274static void device_free_rd0_ring(PSDevice pDevice)
1275{
Joe Perches915006c2013-03-18 10:44:47 -07001276 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001277
Joe Perches915006c2013-03-18 10:44:47 -07001278 for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
1279 PSRxDesc pDesc = &(pDevice->aRD0Ring[i]);
1280 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001281
Joe Perches915006c2013-03-18 10:44:47 -07001282 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1283 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001284
Joe Perches915006c2013-03-18 10:44:47 -07001285 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001286
Joe Perches915006c2013-03-18 10:44:47 -07001287 kfree((void *)pDesc->pRDInfo);
1288 }
Forest Bond5449c682009-04-25 10:30:44 -04001289}
1290
Guillaume Clement84b50762014-07-25 01:06:18 +02001291static void device_free_rd1_ring(PSDevice pDevice)
1292{
Joe Perches915006c2013-03-18 10:44:47 -07001293 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001294
Joe Perches915006c2013-03-18 10:44:47 -07001295 for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
1296 PSRxDesc pDesc = &(pDevice->aRD1Ring[i]);
1297 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001298
Joe Perches915006c2013-03-18 10:44:47 -07001299 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1300 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001301
Joe Perches915006c2013-03-18 10:44:47 -07001302 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001303
Joe Perches915006c2013-03-18 10:44:47 -07001304 kfree((void *)pDesc->pRDInfo);
1305 }
Forest Bond5449c682009-04-25 10:30:44 -04001306}
1307
Guillaume Clement84b50762014-07-25 01:06:18 +02001308static void device_free_frag_buf(PSDevice pDevice)
1309{
Joe Perches915006c2013-03-18 10:44:47 -07001310 PSDeFragControlBlock pDeF;
1311 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001312
Joe Perches915006c2013-03-18 10:44:47 -07001313 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
Joe Perches915006c2013-03-18 10:44:47 -07001314 pDeF = &(pDevice->sRxDFCB[i]);
Forest Bond5449c682009-04-25 10:30:44 -04001315
Joe Perches915006c2013-03-18 10:44:47 -07001316 if (pDeF->skb)
1317 dev_kfree_skb(pDeF->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001318
Joe Perches915006c2013-03-18 10:44:47 -07001319 }
Forest Bond5449c682009-04-25 10:30:44 -04001320}
1321
Guillaume Clement84b50762014-07-25 01:06:18 +02001322static void device_init_td0_ring(PSDevice pDevice)
1323{
Joe Perches915006c2013-03-18 10:44:47 -07001324 int i;
1325 dma_addr_t curr;
1326 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001327
Joe Perches915006c2013-03-18 10:44:47 -07001328 curr = pDevice->td0_pool_dma;
1329 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) {
1330 pDesc = &(pDevice->apTD0Rings[i]);
1331 pDesc->pTDInfo = alloc_td_info();
1332 ASSERT(pDesc->pTDInfo);
1333 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1334 pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ;
1335 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ;
1336 }
1337 pDesc->next = &(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]);
1338 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1339 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1340 }
Forest Bond5449c682009-04-25 10:30:44 -04001341
Joe Perches915006c2013-03-18 10:44:47 -07001342 if (i > 0)
1343 pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
1344 pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001345}
1346
Guillaume Clement84b50762014-07-25 01:06:18 +02001347static void device_init_td1_ring(PSDevice pDevice)
1348{
Joe Perches915006c2013-03-18 10:44:47 -07001349 int i;
1350 dma_addr_t curr;
1351 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001352
Joe Perches915006c2013-03-18 10:44:47 -07001353 /* Init the TD ring entries */
1354 curr = pDevice->td1_pool_dma;
1355 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr += sizeof(STxDesc)) {
1356 pDesc = &(pDevice->apTD1Rings[i]);
1357 pDesc->pTDInfo = alloc_td_info();
1358 ASSERT(pDesc->pTDInfo);
1359 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1360 pDesc->pTDInfo->buf = pDevice->tx1_bufs + (i) * PKT_BUF_SZ;
1361 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma1 + (i) * PKT_BUF_SZ;
1362 }
1363 pDesc->next = &(pDevice->apTD1Rings[(i + 1) % pDevice->sOpts.nTxDescs[1]]);
1364 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1365 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1366 }
Forest Bond5449c682009-04-25 10:30:44 -04001367
Joe Perches915006c2013-03-18 10:44:47 -07001368 if (i > 0)
1369 pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
1370 pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001371}
1372
Guillaume Clement84b50762014-07-25 01:06:18 +02001373static void device_free_td0_ring(PSDevice pDevice)
1374{
Joe Perches915006c2013-03-18 10:44:47 -07001375 int i;
Guillaume Clement6b711272014-07-25 01:06:16 +02001376
Joe Perches915006c2013-03-18 10:44:47 -07001377 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
1378 PSTxDesc pDesc = &(pDevice->apTD0Rings[i]);
1379 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001380
Joe Perches915006c2013-03-18 10:44:47 -07001381 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1382 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1383 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001384
Joe Perches915006c2013-03-18 10:44:47 -07001385 if (pTDInfo->skb)
1386 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001387
Joe Perches915006c2013-03-18 10:44:47 -07001388 kfree((void *)pDesc->pTDInfo);
1389 }
Forest Bond5449c682009-04-25 10:30:44 -04001390}
1391
Guillaume Clement84b50762014-07-25 01:06:18 +02001392static void device_free_td1_ring(PSDevice pDevice)
1393{
Joe Perches915006c2013-03-18 10:44:47 -07001394 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001395
Joe Perches915006c2013-03-18 10:44:47 -07001396 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
1397 PSTxDesc pDesc = &(pDevice->apTD1Rings[i]);
1398 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001399
Joe Perches915006c2013-03-18 10:44:47 -07001400 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1401 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1402 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001403
Joe Perches915006c2013-03-18 10:44:47 -07001404 if (pTDInfo->skb)
1405 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001406
Joe Perches915006c2013-03-18 10:44:47 -07001407 kfree((void *)pDesc->pTDInfo);
1408 }
Forest Bond5449c682009-04-25 10:30:44 -04001409}
1410
Forest Bond5449c682009-04-25 10:30:44 -04001411/*-----------------------------------------------------------------*/
1412
Guillaume Clement84b50762014-07-25 01:06:18 +02001413static int device_rx_srv(PSDevice pDevice, unsigned int uIdx)
1414{
Joe Perches915006c2013-03-18 10:44:47 -07001415 PSRxDesc pRD;
1416 int works = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001417
Joe Perches915006c2013-03-18 10:44:47 -07001418 for (pRD = pDevice->pCurrRD[uIdx];
1419 pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
1420 pRD = pRD->next) {
Joe Perches915006c2013-03-18 10:44:47 -07001421 if (works++ > 15)
1422 break;
1423 if (device_receive_frame(pDevice, pRD)) {
1424 if (!device_alloc_rx_buf(pDevice, pRD)) {
1425 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1426 "%s: can not allocate rx buf\n", pDevice->dev->name);
1427 break;
1428 }
1429 }
1430 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1431 pDevice->dev->last_rx = jiffies;
1432 }
Forest Bond5449c682009-04-25 10:30:44 -04001433
Joe Perches915006c2013-03-18 10:44:47 -07001434 pDevice->pCurrRD[uIdx] = pRD;
Forest Bond5449c682009-04-25 10:30:44 -04001435
Joe Perches915006c2013-03-18 10:44:47 -07001436 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001437}
1438
Guillaume Clement84b50762014-07-25 01:06:18 +02001439static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD)
1440{
Joe Perches915006c2013-03-18 10:44:47 -07001441 PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001442
Joe Perches915006c2013-03-18 10:44:47 -07001443 pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Joe Perches915006c2013-03-18 10:44:47 -07001444 if (pRDInfo->skb == NULL)
1445 return false;
1446 ASSERT(pRDInfo->skb);
1447 pRDInfo->skb->dev = pDevice->dev;
1448 pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
1449 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
1450 *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */
Forest Bond5449c682009-04-25 10:30:44 -04001451
Joe Perches915006c2013-03-18 10:44:47 -07001452 pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
1453 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1454 pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
1455 pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001456
Joe Perches915006c2013-03-18 10:44:47 -07001457 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001458}
1459
Guillaume Clement84b50762014-07-25 01:06:18 +02001460bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF)
1461{
Joe Perches915006c2013-03-18 10:44:47 -07001462 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1463 if (pDeF->skb == NULL)
1464 return false;
1465 ASSERT(pDeF->skb);
1466 pDeF->skb->dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001467
Joe Perches915006c2013-03-18 10:44:47 -07001468 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001469}
1470
Guillaume Clement84b50762014-07-25 01:06:18 +02001471static int device_tx_srv(PSDevice pDevice, unsigned int uIdx)
1472{
Joe Perches915006c2013-03-18 10:44:47 -07001473 PSTxDesc pTD;
1474 bool bFull = false;
1475 int works = 0;
1476 unsigned char byTsr0;
1477 unsigned char byTsr1;
1478 unsigned int uFrameSize, uFIFOHeaderSize;
1479 PSTxBufHead pTxBufHead;
1480 struct net_device_stats *pStats = &pDevice->stats;
1481 struct sk_buff *skb;
1482 unsigned int uNodeIndex;
1483 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04001484
Joe Perches915006c2013-03-18 10:44:47 -07001485 for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) {
Joe Perches915006c2013-03-18 10:44:47 -07001486 if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC)
1487 break;
1488 if (works++ > 15)
1489 break;
Forest Bond5449c682009-04-25 10:30:44 -04001490
Joe Perches915006c2013-03-18 10:44:47 -07001491 byTsr0 = pTD->m_td0TD0.byTSR0;
1492 byTsr1 = pTD->m_td0TD0.byTSR1;
Forest Bond5449c682009-04-25 10:30:44 -04001493
Joe Perches915006c2013-03-18 10:44:47 -07001494 //Only the status of first TD in the chain is correct
1495 if (pTD->m_td1TD1.byTCR & TCR_STP) {
Joe Perches915006c2013-03-18 10:44:47 -07001496 if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
1497 uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
1498 uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
1499 pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
1500 // Update the statistics based on the Transmit status
1501 // now, we DONT check TSR0_CDH
Forest Bond5449c682009-04-25 10:30:44 -04001502
Joe Perches915006c2013-03-18 10:44:47 -07001503 STAvUpdateTDStatCounter(&pDevice->scStatistic,
1504 byTsr0, byTsr1,
1505 (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize),
1506 uFrameSize, uIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001507
Joe Perches915006c2013-03-18 10:44:47 -07001508 BSSvUpdateNodeTxCounter(pDevice,
1509 byTsr0, byTsr1,
1510 (unsigned char *)(pTD->pTDInfo->buf),
1511 uFIFOHeaderSize
1512 );
Forest Bond5449c682009-04-25 10:30:44 -04001513
Joe Perches915006c2013-03-18 10:44:47 -07001514 if (!(byTsr1 & TSR1_TERR)) {
1515 if (byTsr0 != 0) {
1516 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
1517 (int)uIdx, byTsr1, byTsr0);
1518 }
Guido Martínezbc5cf652014-04-19 16:45:00 -03001519 if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG)
Joe Perches915006c2013-03-18 10:44:47 -07001520 pDevice->s802_11Counter.TransmittedFragmentCount++;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001521
Joe Perches915006c2013-03-18 10:44:47 -07001522 pStats->tx_packets++;
1523 pStats->tx_bytes += pTD->pTDInfo->skb->len;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001524 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001525 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
1526 (int)uIdx, byTsr1, byTsr0);
1527 pStats->tx_errors++;
1528 pStats->tx_dropped++;
1529 }
1530 }
Forest Bond5449c682009-04-25 10:30:44 -04001531
Joe Perches915006c2013-03-18 10:44:47 -07001532 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1533 if (pDevice->bEnableHostapd) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001534 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001535 skb = pTD->pTDInfo->skb;
1536 skb->dev = pDevice->apdev;
1537 skb_reset_mac_header(skb);
1538 skb->pkt_type = PACKET_OTHERHOST;
Joe Perches915006c2013-03-18 10:44:47 -07001539 memset(skb->cb, 0, sizeof(skb->cb));
1540 netif_rx(skb);
1541 }
1542 }
Forest Bond5449c682009-04-25 10:30:44 -04001543
Joe Perches915006c2013-03-18 10:44:47 -07001544 if (byTsr1 & TSR1_TERR) {
1545 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1546 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
1547 (int)uIdx, byTsr1, byTsr0);
1548 }
Forest Bond5449c682009-04-25 10:30:44 -04001549
Forest Bond5449c682009-04-25 10:30:44 -04001550
Joe Perches915006c2013-03-18 10:44:47 -07001551 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
1552 (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
1553 unsigned short wAID;
1554 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
Forest Bond5449c682009-04-25 10:30:44 -04001555
Joe Perches915006c2013-03-18 10:44:47 -07001556 skb = pTD->pTDInfo->skb;
1557 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1558 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1559 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1560 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1561 // set tx map
1562 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1563 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
1564 pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
1565 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
1566 , (int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
1567 pStats->tx_errors--;
1568 pStats->tx_dropped--;
1569 }
1570 }
1571 }
1572 }
1573 device_free_tx_buf(pDevice, pTD);
1574 pDevice->iTDUsed[uIdx]--;
1575 }
1576 }
Forest Bond5449c682009-04-25 10:30:44 -04001577
Joe Perches915006c2013-03-18 10:44:47 -07001578 if (uIdx == TYPE_AC0DMA) {
1579 // RESERV_AC0DMA reserved for relay
Forest Bond5449c682009-04-25 10:30:44 -04001580
Joe Perches915006c2013-03-18 10:44:47 -07001581 if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
1582 bFull = true;
1583 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
1584 }
Guido Martínezbc5cf652014-04-19 16:45:00 -03001585 if (netif_queue_stopped(pDevice->dev) && !bFull)
Joe Perches915006c2013-03-18 10:44:47 -07001586 netif_wake_queue(pDevice->dev);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001587
Joe Perches915006c2013-03-18 10:44:47 -07001588 }
Forest Bond5449c682009-04-25 10:30:44 -04001589
Joe Perches915006c2013-03-18 10:44:47 -07001590 pDevice->apTailTD[uIdx] = pTD;
Forest Bond5449c682009-04-25 10:30:44 -04001591
Joe Perches915006c2013-03-18 10:44:47 -07001592 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001593}
1594
Guillaume Clement84b50762014-07-25 01:06:18 +02001595static void device_error(PSDevice pDevice, unsigned short status)
1596{
Joe Perches915006c2013-03-18 10:44:47 -07001597 if (status & ISR_FETALERR) {
1598 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1599 "%s: Hardware fatal error.\n",
1600 pDevice->dev->name);
1601 netif_stop_queue(pDevice->dev);
1602 del_timer(&pDevice->sTimerCommand);
1603 del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
1604 pDevice->bCmdRunning = false;
1605 MACbShutdown(pDevice->PortOffset);
1606 return;
1607 }
Forest Bond5449c682009-04-25 10:30:44 -04001608}
1609
Guillaume Clement84b50762014-07-25 01:06:18 +02001610static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc)
1611{
Joe Perches915006c2013-03-18 10:44:47 -07001612 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
1613 struct sk_buff *skb = pTDInfo->skb;
Forest Bond5449c682009-04-25 10:30:44 -04001614
Joe Perches915006c2013-03-18 10:44:47 -07001615 // pre-allocated buf_dma can't be unmapped.
1616 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) {
1617 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len,
1618 PCI_DMA_TODEVICE);
1619 }
Forest Bond5449c682009-04-25 10:30:44 -04001620
Joe Perches915006c2013-03-18 10:44:47 -07001621 if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0)
1622 dev_kfree_skb_irq(skb);
Forest Bond5449c682009-04-25 10:30:44 -04001623
Joe Perches915006c2013-03-18 10:44:47 -07001624 pTDInfo->skb_dma = 0;
Guillaume Clement70ae5432014-07-25 01:06:28 +02001625 pTDInfo->skb = NULL;
Joe Perches915006c2013-03-18 10:44:47 -07001626 pTDInfo->byFlags = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001627}
1628
Guillaume Clement84b50762014-07-25 01:06:18 +02001629static int device_open(struct net_device *dev)
1630{
Joe Perches915006c2013-03-18 10:44:47 -07001631 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1632 int i;
Jim Liebdb6cb902009-07-23 17:20:49 -07001633#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001634 extern SWPAResult wpa_Result;
Jim Liebdb6cb902009-07-23 17:20:49 -07001635#endif
1636
Joe Perches915006c2013-03-18 10:44:47 -07001637 pDevice->rx_buf_sz = PKT_BUF_SZ;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001638 if (!device_init_rings(pDevice))
Joe Perches915006c2013-03-18 10:44:47 -07001639 return -ENOMEM;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001640
Forest Bond5449c682009-04-25 10:30:44 -04001641//2008-5-13 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -07001642 i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
1643 if (i)
1644 return i;
Joe Perchesf2046f92013-03-18 20:55:36 -07001645
Forest Bond5449c682009-04-25 10:30:44 -04001646#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001647 memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
1648 wpa_Result.proto = 0;
1649 wpa_Result.key_mgmt = 0;
1650 wpa_Result.eap_type = 0;
1651 wpa_Result.authenticated = false;
1652 pDevice->fWPA_Authened = false;
Forest Bond5449c682009-04-25 10:30:44 -04001653#endif
Joe Perches915006c2013-03-18 10:44:47 -07001654 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
1655 device_init_rd0_ring(pDevice);
1656 device_init_rd1_ring(pDevice);
1657 device_init_defrag_cb(pDevice);
1658 device_init_td0_ring(pDevice);
1659 device_init_td1_ring(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001660
Guido Martínezbc5cf652014-04-19 16:45:00 -03001661 if (pDevice->bDiversityRegCtlON)
Joe Perches915006c2013-03-18 10:44:47 -07001662 device_init_diversity_timer(pDevice);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001663
Joe Perches915006c2013-03-18 10:44:47 -07001664 vMgrObjectInit(pDevice);
1665 vMgrTimerInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001666
Joe Perches915006c2013-03-18 10:44:47 -07001667 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
Forest Bond5449c682009-04-25 10:30:44 -04001668 device_init_registers(pDevice, DEVICE_INIT_COLD);
Joe Perches915006c2013-03-18 10:44:47 -07001669 MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
1670 memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1671 device_set_multi(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -04001672
Joe Perches915006c2013-03-18 10:44:47 -07001673 // Init for Key Management
1674 KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
1675 add_timer(&(pDevice->pMgmt->sTimerSecondCallback));
Forest Bond5449c682009-04-25 10:30:44 -04001676
Joe Perches915006c2013-03-18 10:44:47 -07001677#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Joe Perches915006c2013-03-18 10:44:47 -07001678 pDevice->bwextcount = 0;
1679 pDevice->bWPASuppWextEnabled = false;
Forest Bond5449c682009-04-25 10:30:44 -04001680#endif
Joe Perches915006c2013-03-18 10:44:47 -07001681 pDevice->byReAssocCount = 0;
1682 pDevice->bWPADEVUp = false;
1683 // Patch: if WEP key already set by iwconfig but device not yet open
Teodora Baluta1208f142013-11-10 17:12:42 +02001684 if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) {
Joe Perches915006c2013-03-18 10:44:47 -07001685 KeybSetDefaultKey(&(pDevice->sKey),
1686 (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
1687 pDevice->uKeyLength,
1688 NULL,
1689 pDevice->abyKey,
1690 KEY_CTL_WEP,
1691 pDevice->PortOffset,
1692 pDevice->byLocalID
1693 );
1694 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1695 }
Forest Bond5449c682009-04-25 10:30:44 -04001696
Joe Perches915006c2013-03-18 10:44:47 -07001697 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
Forest Bond5449c682009-04-25 10:30:44 -04001698 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
1699
Joe Perches915006c2013-03-18 10:44:47 -07001700 if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1701 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001702 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001703 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1704 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
1705 }
1706 pDevice->flags |= DEVICE_FLAGS_OPENED;
Forest Bond5449c682009-04-25 10:30:44 -04001707
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001708 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001709 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001710}
1711
Guillaume Clement84b50762014-07-25 01:06:18 +02001712static int device_close(struct net_device *dev)
1713{
Joe Perches915006c2013-03-18 10:44:47 -07001714 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1715 PSMgmtObject pMgmt = pDevice->pMgmt;
1716 //PLICE_DEBUG->
Forest Bond5449c682009-04-25 10:30:44 -04001717//PLICE_DEBUG<-
1718//2007-1121-02<Add>by EinsnLiu
Joe Perches915006c2013-03-18 10:44:47 -07001719 if (pDevice->bLinkPass) {
1720 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
1721 mdelay(30);
1722 }
Forest Bond5449c682009-04-25 10:30:44 -04001723#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07001724 del_timer(&pDevice->sTimerTxData);
Forest Bond5449c682009-04-25 10:30:44 -04001725#endif
Joe Perches915006c2013-03-18 10:44:47 -07001726 del_timer(&pDevice->sTimerCommand);
1727 del_timer(&pMgmt->sTimerSecondCallback);
1728 if (pDevice->bDiversityRegCtlON) {
1729 del_timer(&pDevice->TimerSQ3Tmax1);
1730 del_timer(&pDevice->TimerSQ3Tmax2);
1731 del_timer(&pDevice->TimerSQ3Tmax3);
1732 }
Forest Bond5449c682009-04-25 10:30:44 -04001733
Joe Perches915006c2013-03-18 10:44:47 -07001734 netif_stop_queue(dev);
1735 pDevice->bCmdRunning = false;
1736 MACbShutdown(pDevice->PortOffset);
1737 MACbSoftwareReset(pDevice->PortOffset);
1738 CARDbRadioPowerOff(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001739
Joe Perches915006c2013-03-18 10:44:47 -07001740 pDevice->bLinkPass = false;
1741 memset(pMgmt->abyCurrBSSID, 0, 6);
1742 pMgmt->eCurrState = WMAC_STATE_IDLE;
1743 device_free_td0_ring(pDevice);
1744 device_free_td1_ring(pDevice);
1745 device_free_rd0_ring(pDevice);
1746 device_free_rd1_ring(pDevice);
1747 device_free_frag_buf(pDevice);
1748 device_free_rings(pDevice);
1749 BSSvClearNodeDBTable(pDevice, 0);
1750 free_irq(dev->irq, dev);
1751 pDevice->flags &= (~DEVICE_FLAGS_OPENED);
Forest Bond5449c682009-04-25 10:30:44 -04001752 //2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001753 device_release_WPADEV(pDevice);
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001754
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001755 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001756 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001757}
1758
Guillaume Clement84b50762014-07-25 01:06:18 +02001759static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1760{
Joe Perches915006c2013-03-18 10:44:47 -07001761 PSDevice pDevice = netdev_priv(dev);
1762 unsigned char *pbMPDU;
1763 unsigned int cbMPDULen = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001764
Joe Perches915006c2013-03-18 10:44:47 -07001765 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
1766 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001767
Joe Perches915006c2013-03-18 10:44:47 -07001768 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1769 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
1770 dev_kfree_skb_irq(skb);
1771 spin_unlock_irq(&pDevice->lock);
1772 return 0;
1773 }
Forest Bond5449c682009-04-25 10:30:44 -04001774
Teodora Baluta1208f142013-11-10 17:12:42 +02001775 if (pDevice->bStopTx0Pkt) {
Joe Perches915006c2013-03-18 10:44:47 -07001776 dev_kfree_skb_irq(skb);
1777 spin_unlock_irq(&pDevice->lock);
1778 return 0;
1779 }
Forest Bond5449c682009-04-25 10:30:44 -04001780
Joe Perches915006c2013-03-18 10:44:47 -07001781 cbMPDULen = skb->len;
1782 pbMPDU = skb->data;
Forest Bond5449c682009-04-25 10:30:44 -04001783
Joe Perches915006c2013-03-18 10:44:47 -07001784 vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
Forest Bond5449c682009-04-25 10:30:44 -04001785
Joe Perches915006c2013-03-18 10:44:47 -07001786 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001787
Joe Perches915006c2013-03-18 10:44:47 -07001788 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001789}
1790
Guillaume Clement84b50762014-07-25 01:06:18 +02001791bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex)
1792{
Joe Perches915006c2013-03-18 10:44:47 -07001793 PSMgmtObject pMgmt = pDevice->pMgmt;
1794 PSTxDesc pHeadTD, pLastTD;
1795 unsigned int cbFrameBodySize;
1796 unsigned int uMACfragNum;
1797 unsigned char byPktType;
1798 bool bNeedEncryption = false;
1799 PSKeyItem pTransmitKey = NULL;
1800 unsigned int cbHeaderSize;
1801 unsigned int ii;
1802 SKeyItem STempKey;
Forest Bond5449c682009-04-25 10:30:44 -04001803
Teodora Baluta1208f142013-11-10 17:12:42 +02001804 if (pDevice->bStopTx0Pkt) {
Joe Perches915006c2013-03-18 10:44:47 -07001805 dev_kfree_skb_irq(skb);
1806 return false;
1807 }
Forest Bond5449c682009-04-25 10:30:44 -04001808
Joe Perches915006c2013-03-18 10:44:47 -07001809 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1810 dev_kfree_skb_irq(skb);
1811 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
1812 return false;
1813 }
Forest Bond5449c682009-04-25 10:30:44 -04001814
Joe Perches915006c2013-03-18 10:44:47 -07001815 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1816 if (pDevice->uAssocCount == 0) {
1817 dev_kfree_skb_irq(skb);
1818 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
1819 return false;
1820 }
1821 }
Forest Bond5449c682009-04-25 10:30:44 -04001822
Joe Perches915006c2013-03-18 10:44:47 -07001823 pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
Forest Bond5449c682009-04-25 10:30:44 -04001824
Joe Perches915006c2013-03-18 10:44:47 -07001825 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04001826
Joe Perches915006c2013-03-18 10:44:47 -07001827 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
1828 cbFrameBodySize = skb->len - ETH_HLEN;
Forest Bond5449c682009-04-25 10:30:44 -04001829
Joe Perches915006c2013-03-18 10:44:47 -07001830 // 802.1H
Guido Martínezbc5cf652014-04-19 16:45:00 -03001831 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
Joe Perches915006c2013-03-18 10:44:47 -07001832 cbFrameBodySize += 8;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001833
Joe Perches915006c2013-03-18 10:44:47 -07001834 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04001835
Joe Perches915006c2013-03-18 10:44:47 -07001836 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
1837 dev_kfree_skb_irq(skb);
1838 return false;
1839 }
1840 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04001841
Joe Perches915006c2013-03-18 10:44:47 -07001842 if (pDevice->bFixRate) {
1843 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03001844 if (pDevice->uConnectionRate >= RATE_11M)
Joe Perches915006c2013-03-18 10:44:47 -07001845 pDevice->wCurrentRate = RATE_11M;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001846 else
Joe Perches915006c2013-03-18 10:44:47 -07001847 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Joe Perches915006c2013-03-18 10:44:47 -07001848 } else {
1849 if (pDevice->uConnectionRate >= RATE_54M)
1850 pDevice->wCurrentRate = RATE_54M;
1851 else
1852 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1853 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001854 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001855 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
1856 }
Forest Bond5449c682009-04-25 10:30:44 -04001857
Joe Perches915006c2013-03-18 10:44:47 -07001858 //preamble type
Guido Martínezbc5cf652014-04-19 16:45:00 -03001859 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
Joe Perches915006c2013-03-18 10:44:47 -07001860 pDevice->byPreambleType = pDevice->byShortPreamble;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001861 else
Joe Perches915006c2013-03-18 10:44:47 -07001862 pDevice->byPreambleType = PREAMBLE_LONG;
Forest Bond5449c682009-04-25 10:30:44 -04001863
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001864 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001865
Joe Perches915006c2013-03-18 10:44:47 -07001866 if (pDevice->wCurrentRate <= RATE_11M) {
1867 byPktType = PK_TYPE_11B;
1868 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1869 byPktType = PK_TYPE_11A;
1870 } else {
Guido Martínezbc5cf652014-04-19 16:45:00 -03001871 if (pDevice->bProtectMode)
Joe Perches915006c2013-03-18 10:44:47 -07001872 byPktType = PK_TYPE_11GB;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001873 else
Joe Perches915006c2013-03-18 10:44:47 -07001874 byPktType = PK_TYPE_11GA;
Joe Perches915006c2013-03-18 10:44:47 -07001875 }
Forest Bond5449c682009-04-25 10:30:44 -04001876
Teodora Baluta1208f142013-11-10 17:12:42 +02001877 if (pDevice->bEncryptionEnable)
Joe Perches915006c2013-03-18 10:44:47 -07001878 bNeedEncryption = true;
Forest Bond5449c682009-04-25 10:30:44 -04001879
Joe Perches915006c2013-03-18 10:44:47 -07001880 if (pDevice->bEnableHostWEP) {
1881 pTransmitKey = &STempKey;
1882 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
1883 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
1884 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
1885 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
1886 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
1887 memcpy(pTransmitKey->abyKey,
1888 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
1889 pTransmitKey->uKeyLength
1890 );
1891 }
1892 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
1893 cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
1894 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
1895 &uMACfragNum,
1896 &cbHeaderSize
1897 );
Forest Bond5449c682009-04-25 10:30:44 -04001898
Joe Perches915006c2013-03-18 10:44:47 -07001899 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
1900 // Disable PS
1901 MACbPSWakeup(pDevice->PortOffset);
1902 }
Forest Bond5449c682009-04-25 10:30:44 -04001903
Joe Perches915006c2013-03-18 10:44:47 -07001904 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04001905
Joe Perches915006c2013-03-18 10:44:47 -07001906 pLastTD = pHeadTD;
1907 for (ii = 0; ii < uMACfragNum; ii++) {
1908 // Poll Transmit the adapter
1909 wmb();
1910 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
1911 wmb();
1912 if (ii == (uMACfragNum - 1))
1913 pLastTD = pHeadTD;
1914 pHeadTD = pHeadTD->next;
1915 }
Forest Bond5449c682009-04-25 10:30:44 -04001916
Joe Perches915006c2013-03-18 10:44:47 -07001917 // Save the information needed by the tx interrupt handler
1918 // to complete the Send request
1919 pLastTD->pTDInfo->skb = skb;
1920 pLastTD->pTDInfo->byFlags = 0;
1921 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04001922
Joe Perches915006c2013-03-18 10:44:47 -07001923 pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001924
Joe Perches915006c2013-03-18 10:44:47 -07001925 MACvTransmit0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04001926
Joe Perches915006c2013-03-18 10:44:47 -07001927 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001928}
1929
1930//TYPE_AC0DMA data tx
Guillaume Clement84b50762014-07-25 01:06:18 +02001931static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1932{
Joe Perches915006c2013-03-18 10:44:47 -07001933 PSDevice pDevice = netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001934
Joe Perches915006c2013-03-18 10:44:47 -07001935 PSMgmtObject pMgmt = pDevice->pMgmt;
1936 PSTxDesc pHeadTD, pLastTD;
1937 unsigned int uNodeIndex = 0;
1938 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
1939 unsigned short wAID;
1940 unsigned int uMACfragNum = 1;
1941 unsigned int cbFrameBodySize;
1942 unsigned char byPktType;
1943 unsigned int cbHeaderSize;
1944 bool bNeedEncryption = false;
1945 PSKeyItem pTransmitKey = NULL;
1946 SKeyItem STempKey;
1947 unsigned int ii;
1948 bool bTKIP_UseGTK = false;
1949 bool bNeedDeAuth = false;
1950 unsigned char *pbyBSSID;
1951 bool bNodeExist = false;
Forest Bond5449c682009-04-25 10:30:44 -04001952
Joe Perches915006c2013-03-18 10:44:47 -07001953 spin_lock_irq(&pDevice->lock);
Teodora Baluta1208f142013-11-10 17:12:42 +02001954 if (!pDevice->bLinkPass) {
Joe Perches915006c2013-03-18 10:44:47 -07001955 dev_kfree_skb_irq(skb);
1956 spin_unlock_irq(&pDevice->lock);
1957 return 0;
1958 }
Forest Bond5449c682009-04-25 10:30:44 -04001959
Joe Perches915006c2013-03-18 10:44:47 -07001960 if (pDevice->bStopDataPkt) {
1961 dev_kfree_skb_irq(skb);
1962 spin_unlock_irq(&pDevice->lock);
1963 return 0;
1964 }
Forest Bond5449c682009-04-25 10:30:44 -04001965
Joe Perches915006c2013-03-18 10:44:47 -07001966 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1967 if (pDevice->uAssocCount == 0) {
1968 dev_kfree_skb_irq(skb);
1969 spin_unlock_irq(&pDevice->lock);
1970 return 0;
1971 }
1972 if (is_multicast_ether_addr((unsigned char *)(skb->data))) {
1973 uNodeIndex = 0;
1974 bNodeExist = true;
1975 if (pMgmt->sNodeDBTable[0].bPSEnable) {
1976 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
1977 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
1978 // set tx map
1979 pMgmt->abyPSTxMap[0] |= byMask[0];
1980 spin_unlock_irq(&pDevice->lock);
1981 return 0;
1982 }
1983 } else {
1984 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1985 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1986 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1987 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1988 // set tx map
1989 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1990 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
1991 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
1992 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
1993 spin_unlock_irq(&pDevice->lock);
1994 return 0;
1995 }
Forest Bond5449c682009-04-25 10:30:44 -04001996
Guido Martínezbc5cf652014-04-19 16:45:00 -03001997 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
Joe Perches915006c2013-03-18 10:44:47 -07001998 pDevice->byPreambleType = pDevice->byShortPreamble;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001999 else
Joe Perches915006c2013-03-18 10:44:47 -07002000 pDevice->byPreambleType = PREAMBLE_LONG;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002001
Joe Perches915006c2013-03-18 10:44:47 -07002002 bNodeExist = true;
Forest Bond5449c682009-04-25 10:30:44 -04002003
Joe Perches915006c2013-03-18 10:44:47 -07002004 }
2005 }
Forest Bond5449c682009-04-25 10:30:44 -04002006
Teodora Baluta1208f142013-11-10 17:12:42 +02002007 if (!bNodeExist) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002008 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB\n");
Joe Perches915006c2013-03-18 10:44:47 -07002009 dev_kfree_skb_irq(skb);
2010 spin_unlock_irq(&pDevice->lock);
2011 return 0;
2012 }
2013 }
Forest Bond5449c682009-04-25 10:30:44 -04002014
Joe Perches915006c2013-03-18 10:44:47 -07002015 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
Forest Bond5449c682009-04-25 10:30:44 -04002016
Joe Perches915006c2013-03-18 10:44:47 -07002017 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04002018
Joe Perches915006c2013-03-18 10:44:47 -07002019 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
2020 cbFrameBodySize = skb->len - ETH_HLEN;
2021 // 802.1H
Guido Martínezbc5cf652014-04-19 16:45:00 -03002022 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
Joe Perches915006c2013-03-18 10:44:47 -07002023 cbFrameBodySize += 8;
Forest Bond5449c682009-04-25 10:30:44 -04002024
Teodora Baluta1208f142013-11-10 17:12:42 +02002025 if (pDevice->bEncryptionEnable) {
Joe Perches915006c2013-03-18 10:44:47 -07002026 bNeedEncryption = true;
2027 // get Transmit key
2028 do {
2029 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2030 (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2031 pbyBSSID = pDevice->abyBSSID;
2032 // get pairwise key
2033 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
2034 // get group key
2035 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2036 bTKIP_UseGTK = true;
2037 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2038 break;
2039 }
2040 } else {
2041 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get PTK.\n");
2042 break;
2043 }
2044 } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Joe Perches915006c2013-03-18 10:44:47 -07002045 pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002046 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key:\n");
Joe Perches915006c2013-03-18 10:44:47 -07002047 for (ii = 0; ii < 6; ii++)
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002048 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x\n", *(pbyBSSID+ii));
Joe Perches915006c2013-03-18 10:44:47 -07002049 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n");
Forest Bond5449c682009-04-25 10:30:44 -04002050
Joe Perches915006c2013-03-18 10:44:47 -07002051 // get pairwise key
2052 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
2053 break;
2054 }
2055 // get group key
2056 pbyBSSID = pDevice->abyBroadcastAddr;
2057 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
2058 pTransmitKey = NULL;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002059 if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
Joe Perches915006c2013-03-18 10:44:47 -07002060 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002061 else
Joe Perches915006c2013-03-18 10:44:47 -07002062 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
2063 } else {
2064 bTKIP_UseGTK = true;
2065 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2066 }
2067 } while (false);
2068 }
Forest Bond5449c682009-04-25 10:30:44 -04002069
Joe Perches915006c2013-03-18 10:44:47 -07002070 if (pDevice->bEnableHostWEP) {
2071 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex);
Teodora Baluta1208f142013-11-10 17:12:42 +02002072 if (pDevice->bEncryptionEnable) {
Joe Perches915006c2013-03-18 10:44:47 -07002073 pTransmitKey = &STempKey;
2074 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2075 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2076 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2077 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2078 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2079 memcpy(pTransmitKey->abyKey,
2080 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2081 pTransmitKey->uKeyLength
2082 );
2083 }
2084 }
Forest Bond5449c682009-04-25 10:30:44 -04002085
Joe Perches915006c2013-03-18 10:44:47 -07002086 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04002087
Joe Perches915006c2013-03-18 10:44:47 -07002088 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
2089 DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
2090 dev_kfree_skb_irq(skb);
2091 spin_unlock_irq(&pDevice->lock);
2092 return 0;
2093 }
Forest Bond5449c682009-04-25 10:30:44 -04002094
Joe Perches915006c2013-03-18 10:44:47 -07002095 if (pTransmitKey != NULL) {
2096 if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) &&
2097 (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) {
2098 uMACfragNum = 1; //WEP256 doesn't support fragment
2099 }
2100 }
Forest Bond5449c682009-04-25 10:30:44 -04002101
Joe Perches915006c2013-03-18 10:44:47 -07002102 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04002103
Joe Perches915006c2013-03-18 10:44:47 -07002104 if (pDevice->bFixRate) {
Forest Bond5449c682009-04-25 10:30:44 -04002105#ifdef PLICE_DEBUG
Guillaume Clement941ead92014-07-25 01:06:21 +02002106 pr_debug("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate);
Forest Bond5449c682009-04-25 10:30:44 -04002107#endif
2108
Joe Perches915006c2013-03-18 10:44:47 -07002109 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002110 if (pDevice->uConnectionRate >= RATE_11M)
Joe Perches915006c2013-03-18 10:44:47 -07002111 pDevice->wCurrentRate = RATE_11M;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002112 else
Joe Perches915006c2013-03-18 10:44:47 -07002113 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Joe Perches915006c2013-03-18 10:44:47 -07002114 } else {
2115 if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
2116 (pDevice->uConnectionRate <= RATE_6M)) {
2117 pDevice->wCurrentRate = RATE_6M;
2118 } else {
2119 if (pDevice->uConnectionRate >= RATE_54M)
2120 pDevice->wCurrentRate = RATE_54M;
2121 else
2122 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Forest Bond5449c682009-04-25 10:30:44 -04002123
Joe Perches915006c2013-03-18 10:44:47 -07002124 }
2125 }
2126 pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate;
2127 pDevice->byTopCCKBasicRate = RATE_1M;
2128 pDevice->byTopOFDMBasicRate = RATE_6M;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002129 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002130 //auto rate
2131 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2132 if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
2133 pDevice->wCurrentRate = RATE_1M;
2134 pDevice->byACKRate = RATE_1M;
2135 pDevice->byTopCCKBasicRate = RATE_1M;
2136 pDevice->byTopOFDMBasicRate = RATE_6M;
2137 } else {
2138 pDevice->wCurrentRate = RATE_6M;
2139 pDevice->byACKRate = RATE_6M;
2140 pDevice->byTopCCKBasicRate = RATE_1M;
2141 pDevice->byTopOFDMBasicRate = RATE_6M;
2142 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002143 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002144 VNTWIFIvGetTxRate(pDevice->pMgmt,
2145 pDevice->sTxEthHeader.abyDstAddr,
2146 &(pDevice->wCurrentRate),
2147 &(pDevice->byACKRate),
2148 &(pDevice->byTopCCKBasicRate),
2149 &(pDevice->byTopOFDMBasicRate));
Forest Bond5449c682009-04-25 10:30:44 -04002150
Forest Bond5449c682009-04-25 10:30:44 -04002151 }
Joe Perches915006c2013-03-18 10:44:47 -07002152 }
Forest Bond5449c682009-04-25 10:30:44 -04002153
Forest Bond5449c682009-04-25 10:30:44 -04002154
Joe Perches915006c2013-03-18 10:44:47 -07002155 if (pDevice->wCurrentRate <= RATE_11M) {
2156 byPktType = PK_TYPE_11B;
2157 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2158 byPktType = PK_TYPE_11A;
2159 } else {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002160 if (pDevice->bProtectMode)
Joe Perches915006c2013-03-18 10:44:47 -07002161 byPktType = PK_TYPE_11GB;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002162 else
Joe Perches915006c2013-03-18 10:44:47 -07002163 byPktType = PK_TYPE_11GA;
Joe Perches915006c2013-03-18 10:44:47 -07002164 }
Forest Bond5449c682009-04-25 10:30:44 -04002165
Teodora Baluta1208f142013-11-10 17:12:42 +02002166 if (bNeedEncryption) {
Joe Perches915006c2013-03-18 10:44:47 -07002167 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
2168 if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
2169 bNeedEncryption = false;
2170 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
2171 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2172 if (pTransmitKey == NULL) {
2173 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002174 } else {
Teodora Baluta1208f142013-11-10 17:12:42 +02002175 if (bTKIP_UseGTK) {
Joe Perches915006c2013-03-18 10:44:47 -07002176 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002177 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002178 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2179 bNeedEncryption = true;
2180 }
2181 }
2182 }
Forest Bond5449c682009-04-25 10:30:44 -04002183
Joe Perches915006c2013-03-18 10:44:47 -07002184 if (pDevice->byCntMeasure == 2) {
2185 bNeedDeAuth = true;
2186 pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
2187 }
Forest Bond5449c682009-04-25 10:30:44 -04002188
Joe Perches915006c2013-03-18 10:44:47 -07002189 if (pDevice->bEnableHostWEP) {
2190 if ((uNodeIndex != 0) &&
2191 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
2192 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2193 bNeedEncryption = true;
2194 }
2195 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002196 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002197 if (pTransmitKey == NULL) {
2198 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return no tx key\n");
2199 dev_kfree_skb_irq(skb);
2200 spin_unlock_irq(&pDevice->lock);
2201 return 0;
2202 }
2203 }
2204 }
Forest Bond5449c682009-04-25 10:30:44 -04002205
Joe Perches915006c2013-03-18 10:44:47 -07002206 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
2207 cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
2208 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
2209 &uMACfragNum,
2210 &cbHeaderSize
2211 );
Forest Bond5449c682009-04-25 10:30:44 -04002212
Joe Perches915006c2013-03-18 10:44:47 -07002213 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2214 // Disable PS
2215 MACbPSWakeup(pDevice->PortOffset);
2216 }
2217 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002218
Joe Perches915006c2013-03-18 10:44:47 -07002219 pLastTD = pHeadTD;
2220 for (ii = 0; ii < uMACfragNum; ii++) {
2221 // Poll Transmit the adapter
2222 wmb();
2223 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2224 wmb();
2225 if (ii == uMACfragNum - 1)
2226 pLastTD = pHeadTD;
2227 pHeadTD = pHeadTD->next;
2228 }
Forest Bond5449c682009-04-25 10:30:44 -04002229
Joe Perches915006c2013-03-18 10:44:47 -07002230 // Save the information needed by the tx interrupt handler
2231 // to complete the Send request
2232 pLastTD->pTDInfo->skb = skb;
2233 pLastTD->pTDInfo->byFlags = 0;
2234 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04002235#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07002236 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
2237#endif
Guido Martínezbc5cf652014-04-19 16:45:00 -03002238 if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1)
Joe Perches915006c2013-03-18 10:44:47 -07002239 netif_stop_queue(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002240
Joe Perches915006c2013-03-18 10:44:47 -07002241 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002242
Guido Martínezbc5cf652014-04-19 16:45:00 -03002243 if (pDevice->bFixRate)
Guillaume Clement941ead92014-07-25 01:06:21 +02002244 pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
Forest Bond5449c682009-04-25 10:30:44 -04002245
Joe Perches915006c2013-03-18 10:44:47 -07002246 {
2247 unsigned char Protocol_Version; //802.1x Authentication
2248 unsigned char Packet_Type; //802.1x Authentication
2249 unsigned char Descriptor_type;
2250 unsigned short Key_info;
2251 bool bTxeapol_key = false;
Guillaume Clement6b711272014-07-25 01:06:16 +02002252
Joe Perches915006c2013-03-18 10:44:47 -07002253 Protocol_Version = skb->data[ETH_HLEN];
2254 Packet_Type = skb->data[ETH_HLEN+1];
2255 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2256 Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
2257 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2258 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2259 (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer
2260 bTxeapol_key = true;
2261 if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN
2262 if (!(Key_info & BIT3) && //group-key challenge
2263 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2264 pDevice->fWPA_Authened = true;
2265 if (Descriptor_type == 254)
Guillaume Clement941ead92014-07-25 01:06:21 +02002266 pr_debug("WPA ");
Joe Perches915006c2013-03-18 10:44:47 -07002267 else
Guillaume Clement941ead92014-07-25 01:06:21 +02002268 pr_debug("WPA2 ");
2269 pr_debug("Authentication completed!!\n");
Joe Perches915006c2013-03-18 10:44:47 -07002270 }
2271 }
2272 }
2273 }
2274 }
Forest Bond5449c682009-04-25 10:30:44 -04002275
Joe Perches915006c2013-03-18 10:44:47 -07002276 MACvTransmitAC0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002277
Joe Perches915006c2013-03-18 10:44:47 -07002278 dev->trans_start = jiffies;
Forest Bond5449c682009-04-25 10:30:44 -04002279
Joe Perches915006c2013-03-18 10:44:47 -07002280 spin_unlock_irq(&pDevice->lock);
2281 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04002282}
2283
Guillaume Clement84b50762014-07-25 01:06:18 +02002284static irqreturn_t device_intr(int irq, void *dev_instance)
2285{
Joe Perches915006c2013-03-18 10:44:47 -07002286 struct net_device *dev = dev_instance;
2287 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002288
Joe Perches915006c2013-03-18 10:44:47 -07002289 int max_count = 0;
2290 unsigned long dwMIBCounter = 0;
2291 PSMgmtObject pMgmt = pDevice->pMgmt;
2292 unsigned char byOrgPageSel = 0;
2293 int handled = 0;
2294 unsigned char byData = 0;
2295 int ii = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002296
Joe Perches915006c2013-03-18 10:44:47 -07002297 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002298
Joe Perches915006c2013-03-18 10:44:47 -07002299 if (pDevice->dwIsr == 0)
2300 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002301
Joe Perches915006c2013-03-18 10:44:47 -07002302 if (pDevice->dwIsr == 0xffffffff) {
2303 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
2304 return IRQ_RETVAL(handled);
2305 }
Forest Bond5449c682009-04-25 10:30:44 -04002306
Joe Perches915006c2013-03-18 10:44:47 -07002307 handled = 1;
2308 MACvIntDisable(pDevice->PortOffset);
2309 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04002310
Joe Perches915006c2013-03-18 10:44:47 -07002311 //Make sure current page is 0
2312 VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002313 if (byOrgPageSel == 1)
Joe Perches915006c2013-03-18 10:44:47 -07002314 MACvSelectPage0(pDevice->PortOffset);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002315 else
Joe Perches915006c2013-03-18 10:44:47 -07002316 byOrgPageSel = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002317
Joe Perches915006c2013-03-18 10:44:47 -07002318 MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
2319 // TBD....
2320 // Must do this after doing rx/tx, cause ISR bit is slow
2321 // than RD/TD write back
2322 // update ISR counter
2323 STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
2324 while (pDevice->dwIsr != 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002325 STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
2326 MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002327
Joe Perches915006c2013-03-18 10:44:47 -07002328 if (pDevice->dwIsr & ISR_FETALERR) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002329 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR\n");
Joe Perches915006c2013-03-18 10:44:47 -07002330 VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
2331 VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
2332 device_error(pDevice, pDevice->dwIsr);
2333 }
Forest Bond5449c682009-04-25 10:30:44 -04002334
Joe Perches915006c2013-03-18 10:44:47 -07002335 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
Joe Perches915006c2013-03-18 10:44:47 -07002336 if (pDevice->dwIsr & ISR_MEASURESTART) {
2337 // 802.11h measure start
2338 pDevice->byOrgChannel = pDevice->byCurrentCh;
2339 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
2340 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR));
2341 MACvSelectPage1(pDevice->PortOffset);
2342 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0));
2343 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
2344 MACvSelectPage0(pDevice->PortOffset);
2345 //xxxx
Teodora Baluta1208f142013-11-10 17:12:42 +02002346 if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) {
Joe Perches915006c2013-03-18 10:44:47 -07002347 pDevice->bMeasureInProgress = true;
2348 MACvSelectPage1(pDevice->PortOffset);
2349 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
2350 MACvSelectPage0(pDevice->PortOffset);
2351 pDevice->byBasicMap = 0;
2352 pDevice->byCCAFraction = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002353 for (ii = 0; ii < 8; ii++)
Joe Perches915006c2013-03-18 10:44:47 -07002354 pDevice->dwRPIs[ii] = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002355
Joe Perches915006c2013-03-18 10:44:47 -07002356 } else {
2357 // can not measure because set channel fail
Joe Perches915006c2013-03-18 10:44:47 -07002358 // clear measure control
2359 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2360 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE);
2361 MACvSelectPage1(pDevice->PortOffset);
2362 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2363 MACvSelectPage0(pDevice->PortOffset);
2364 }
2365 }
2366 if (pDevice->dwIsr & ISR_MEASUREEND) {
2367 // 802.11h measure end
2368 pDevice->bMeasureInProgress = false;
2369 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
2370 MACvSelectPage1(pDevice->PortOffset);
2371 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
2372 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
2373 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData);
2374 pDevice->byBasicMap |= (byData >> 4);
2375 VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction);
2376 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData);
2377 // clear measure control
2378 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2379 MACvSelectPage0(pDevice->PortOffset);
2380 set_channel(pDevice, pDevice->byOrgChannel);
Joe Perches915006c2013-03-18 10:44:47 -07002381 MACvSelectPage1(pDevice->PortOffset);
2382 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2383 MACvSelectPage0(pDevice->PortOffset);
2384 if (byData & MSRCTL_FINISH) {
2385 // measure success
2386 s_vCompleteCurrentMeasure(pDevice, 0);
2387 } else {
2388 // can not measure because not ready before end of measure time
2389 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
2390 }
2391 }
2392 if (pDevice->dwIsr & ISR_QUIETSTART) {
2393 do {
2394 ;
Teodora Baluta1208f142013-11-10 17:12:42 +02002395 } while (!CARDbStartQuiet(pDevice));
Joe Perches915006c2013-03-18 10:44:47 -07002396 }
2397 }
Forest Bond5449c682009-04-25 10:30:44 -04002398
Joe Perches915006c2013-03-18 10:44:47 -07002399 if (pDevice->dwIsr & ISR_TBTT) {
Teodora Baluta1208f142013-11-10 17:12:42 +02002400 if (pDevice->bEnableFirstQuiet) {
Joe Perches915006c2013-03-18 10:44:47 -07002401 pDevice->byQuietStartCount--;
2402 if (pDevice->byQuietStartCount == 0) {
2403 pDevice->bEnableFirstQuiet = false;
2404 MACvSelectPage1(pDevice->PortOffset);
2405 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
2406 MACvSelectPage0(pDevice->PortOffset);
2407 }
2408 }
Teodora Baluta1208f142013-11-10 17:12:42 +02002409 if (pDevice->bChannelSwitch &&
Joe Perches915006c2013-03-18 10:44:47 -07002410 (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
2411 pDevice->byChannelSwitchCount--;
2412 if (pDevice->byChannelSwitchCount == 0) {
2413 pDevice->bChannelSwitch = false;
2414 set_channel(pDevice, pDevice->byNewChannel);
2415 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2416 MACvSelectPage1(pDevice->PortOffset);
2417 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2418 MACvSelectPage0(pDevice->PortOffset);
2419 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
Forest Bond5449c682009-04-25 10:30:44 -04002420
Joe Perches915006c2013-03-18 10:44:47 -07002421 }
2422 }
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002423 if (pDevice->eOPMode != OP_MODE_ADHOC) {
Teodora Baluta1208f142013-11-10 17:12:42 +02002424 if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) {
Joe Perches915006c2013-03-18 10:44:47 -07002425 long ldBm;
Forest Bond5449c682009-04-25 10:30:44 -04002426
Joe Perches915006c2013-03-18 10:44:47 -07002427 RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
2428 for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
2429 if (ldBm < pDevice->ldBmThreshold[ii]) {
2430 pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
2431 break;
2432 }
2433 }
2434 if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
2435 pDevice->uBBVGADiffCount++;
2436 if (pDevice->uBBVGADiffCount == 1) {
2437 // first VGA diff gain
2438 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2439 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2440 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2441 }
2442 if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
2443 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2444 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2445 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2446 }
2447 } else {
2448 pDevice->uBBVGADiffCount = 1;
2449 }
2450 }
2451 }
Forest Bond5449c682009-04-25 10:30:44 -04002452
Joe Perches915006c2013-03-18 10:44:47 -07002453 pDevice->bBeaconSent = false;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002454 if (pDevice->bEnablePSMode)
Joe Perches915006c2013-03-18 10:44:47 -07002455 PSbIsNextTBTTWakeUp((void *)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04002456
Joe Perches915006c2013-03-18 10:44:47 -07002457 if ((pDevice->eOPMode == OP_MODE_AP) ||
2458 (pDevice->eOPMode == OP_MODE_ADHOC)) {
Joe Perches915006c2013-03-18 10:44:47 -07002459 MACvOneShotTimer1MicroSec(pDevice->PortOffset,
2460 (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10);
2461 }
Forest Bond5449c682009-04-25 10:30:44 -04002462
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002463 /* TODO: adhoc PS mode */
Forest Bond5449c682009-04-25 10:30:44 -04002464
Joe Perches915006c2013-03-18 10:44:47 -07002465 }
Forest Bond5449c682009-04-25 10:30:44 -04002466
Joe Perches915006c2013-03-18 10:44:47 -07002467 if (pDevice->dwIsr & ISR_BNTX) {
Joe Perches915006c2013-03-18 10:44:47 -07002468 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2469 pDevice->bIsBeaconBufReadySet = false;
2470 pDevice->cbBeaconBufReadySetCnt = 0;
2471 }
Forest Bond5449c682009-04-25 10:30:44 -04002472
Joe Perches915006c2013-03-18 10:44:47 -07002473 if (pDevice->eOPMode == OP_MODE_AP) {
2474 if (pMgmt->byDTIMCount > 0) {
2475 pMgmt->byDTIMCount--;
2476 pMgmt->sNodeDBTable[0].bRxPSPoll = false;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002477 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002478 if (pMgmt->byDTIMCount == 0) {
2479 // check if mutltcast tx bufferring
2480 pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2481 pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2482 bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
2483 }
2484 }
2485 }
2486 pDevice->bBeaconSent = true;
Forest Bond5449c682009-04-25 10:30:44 -04002487
Teodora Baluta1208f142013-11-10 17:12:42 +02002488 if (pDevice->bChannelSwitch) {
Joe Perches915006c2013-03-18 10:44:47 -07002489 pDevice->byChannelSwitchCount--;
2490 if (pDevice->byChannelSwitchCount == 0) {
2491 pDevice->bChannelSwitch = false;
2492 set_channel(pDevice, pDevice->byNewChannel);
2493 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2494 MACvSelectPage1(pDevice->PortOffset);
2495 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2496 MACvSelectPage0(pDevice->PortOffset);
Joe Perches915006c2013-03-18 10:44:47 -07002497 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
2498 }
2499 }
Forest Bond5449c682009-04-25 10:30:44 -04002500
Joe Perches915006c2013-03-18 10:44:47 -07002501 }
Forest Bond5449c682009-04-25 10:30:44 -04002502
Guido Martínezbc5cf652014-04-19 16:45:00 -03002503 if (pDevice->dwIsr & ISR_RXDMA0)
Joe Perches915006c2013-03-18 10:44:47 -07002504 max_count += device_rx_srv(pDevice, TYPE_RXDMA0);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002505
2506 if (pDevice->dwIsr & ISR_RXDMA1)
Joe Perches915006c2013-03-18 10:44:47 -07002507 max_count += device_rx_srv(pDevice, TYPE_RXDMA1);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002508
2509 if (pDevice->dwIsr & ISR_TXDMA0)
Joe Perches915006c2013-03-18 10:44:47 -07002510 max_count += device_tx_srv(pDevice, TYPE_TXDMA0);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002511
2512 if (pDevice->dwIsr & ISR_AC0DMA)
Joe Perches915006c2013-03-18 10:44:47 -07002513 max_count += device_tx_srv(pDevice, TYPE_AC0DMA);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002514
Joe Perches915006c2013-03-18 10:44:47 -07002515 if (pDevice->dwIsr & ISR_SOFTTIMER1) {
2516 if (pDevice->eOPMode == OP_MODE_AP) {
2517 if (pDevice->bShortSlotTime)
2518 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
2519 else
2520 pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1));
2521 }
2522 bMgrPrepareBeaconToSend(pDevice, pMgmt);
2523 pDevice->byCntMeasure = 0;
2524 }
Forest Bond5449c682009-04-25 10:30:44 -04002525
Joe Perches915006c2013-03-18 10:44:47 -07002526 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002527
Joe Perches915006c2013-03-18 10:44:47 -07002528 MACvReceive0(pDevice->PortOffset);
2529 MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002530
Joe Perches915006c2013-03-18 10:44:47 -07002531 if (max_count > pDevice->sOpts.int_works)
2532 break;
2533 }
Forest Bond5449c682009-04-25 10:30:44 -04002534
Guido Martínezbc5cf652014-04-19 16:45:00 -03002535 if (byOrgPageSel == 1)
Joe Perches915006c2013-03-18 10:44:47 -07002536 MACvSelectPage1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002537
Joe Perches915006c2013-03-18 10:44:47 -07002538 spin_unlock_irq(&pDevice->lock);
2539 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
Forest Bond5449c682009-04-25 10:30:44 -04002540
Joe Perches915006c2013-03-18 10:44:47 -07002541 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002542}
2543
Forest Bond5449c682009-04-25 10:30:44 -04002544static unsigned const ethernet_polynomial = 0x04c11db7U;
2545static inline u32 ether_crc(int length, unsigned char *data)
2546{
Joe Perches915006c2013-03-18 10:44:47 -07002547 int crc = -1;
Forest Bond5449c682009-04-25 10:30:44 -04002548
Joe Perches915006c2013-03-18 10:44:47 -07002549 while (--length >= 0) {
2550 unsigned char current_octet = *data++;
2551 int bit;
Guillaume Clement6b711272014-07-25 01:06:16 +02002552
Joe Perches915006c2013-03-18 10:44:47 -07002553 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
2554 crc = (crc << 1) ^
2555 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
2556 }
2557 }
2558 return crc;
Forest Bond5449c682009-04-25 10:30:44 -04002559}
2560
2561//2008-8-4 <add> by chester
Charles Clément5c9824e2010-06-02 09:51:59 -07002562static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -07002563 unsigned char *dest, unsigned char *source)
Forest Bond5449c682009-04-25 10:30:44 -04002564{
Joe Perches915006c2013-03-18 10:44:47 -07002565 unsigned char buf1[100];
2566 int source_len = strlen(source);
Forest Bond5449c682009-04-25 10:30:44 -04002567
Joe Perches915006c2013-03-18 10:44:47 -07002568 memset(buf1, 0, 100);
2569 strcat(buf1, string);
2570 strcat(buf1, "=");
2571 source += strlen(buf1);
Forest Bond5449c682009-04-25 10:30:44 -04002572
Joe Perches915006c2013-03-18 10:44:47 -07002573 memcpy(dest, source, source_len - strlen(buf1));
2574 return true;
Forest Bond5449c682009-04-25 10:30:44 -04002575}
2576
Guillaume Clementfa138492014-07-25 01:06:24 +02002577int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter)
Al Virof8054422013-04-06 18:11:22 -04002578{
2579 unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
Joe Perches915006c2013-03-18 10:44:47 -07002580 unsigned char tmpbuffer[20];
Al Virof8054422013-04-06 18:11:22 -04002581 struct file *file;
Guillaume Clementfa138492014-07-25 01:06:24 +02002582 int result = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002583
Al Virof8054422013-04-06 18:11:22 -04002584 if (!buffer) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002585 pr_err("allocate mem for file fail?\n");
Al Virof8054422013-04-06 18:11:22 -04002586 return -1;
2587 }
2588 file = filp_open(CONFIG_PATH, O_RDONLY, 0);
2589 if (IS_ERR(file)) {
2590 kfree(buffer);
Guillaume Clement941ead92014-07-25 01:06:21 +02002591 pr_err("Config_FileOperation:open file fail?\n");
Al Virof8054422013-04-06 18:11:22 -04002592 return -1;
Joe Perches915006c2013-03-18 10:44:47 -07002593 }
Forest Bond5449c682009-04-25 10:30:44 -04002594
Al Virof8054422013-04-06 18:11:22 -04002595 if (kernel_read(file, 0, buffer, 1024) < 0) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002596 pr_err("read file error?\n");
Joe Perches915006c2013-03-18 10:44:47 -07002597 result = -1;
2598 goto error1;
2599 }
Forest Bond5449c682009-04-25 10:30:44 -04002600
Al Virof8054422013-04-06 18:11:22 -04002601 if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002602 pr_err("get parameter error?\n");
Joe Perches915006c2013-03-18 10:44:47 -07002603 result = -1;
2604 goto error1;
2605 }
Forest Bond5449c682009-04-25 10:30:44 -04002606
Guillaume Clementfa138492014-07-25 01:06:24 +02002607 if (memcmp(tmpbuffer, "USA", 3) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002608 result = ZoneType_USA;
Guillaume Clementfa138492014-07-25 01:06:24 +02002609 } else if(memcmp(tmpbuffer, "JAPAN", 5) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002610 result = ZoneType_Japan;
Guillaume Clementfa138492014-07-25 01:06:24 +02002611 } else if(memcmp(tmpbuffer, "EUROPE", 5) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002612 result = ZoneType_Europe;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002613 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002614 result = -1;
Guillaume Clement941ead92014-07-25 01:06:21 +02002615 pr_err("Unknown Zonetype[%s]?\n", tmpbuffer);
Joe Perches915006c2013-03-18 10:44:47 -07002616 }
Forest Bond5449c682009-04-25 10:30:44 -04002617
2618error1:
Joe Perches915006c2013-03-18 10:44:47 -07002619 kfree(buffer);
Al Virof8054422013-04-06 18:11:22 -04002620 fput(file);
Joe Perches915006c2013-03-18 10:44:47 -07002621 return result;
Forest Bond5449c682009-04-25 10:30:44 -04002622}
2623
Guillaume Clement84b50762014-07-25 01:06:18 +02002624static void device_set_multi(struct net_device *dev)
2625{
Joe Perches915006c2013-03-18 10:44:47 -07002626 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002627
Joe Perches915006c2013-03-18 10:44:47 -07002628 PSMgmtObject pMgmt = pDevice->pMgmt;
2629 u32 mc_filter[2];
2630 struct netdev_hw_addr *ha;
Forest Bond5449c682009-04-25 10:30:44 -04002631
Joe Perches915006c2013-03-18 10:44:47 -07002632 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
Forest Bond5449c682009-04-25 10:30:44 -04002633
Joe Perches915006c2013-03-18 10:44:47 -07002634 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
2635 DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
2636 /* Unconditionally log net taps. */
2637 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002638 } else if ((netdev_mc_count(dev) > pDevice->multicast_limit)
Joe Perches915006c2013-03-18 10:44:47 -07002639 || (dev->flags & IFF_ALLMULTI)) {
2640 MACvSelectPage1(pDevice->PortOffset);
2641 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
2642 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
2643 MACvSelectPage0(pDevice->PortOffset);
2644 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002645 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002646 memset(mc_filter, 0, sizeof(mc_filter));
2647 netdev_for_each_mc_addr(ha, dev) {
2648 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Guillaume Clement6b711272014-07-25 01:06:16 +02002649
Joe Perches915006c2013-03-18 10:44:47 -07002650 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
2651 }
2652 MACvSelectPage1(pDevice->PortOffset);
2653 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]);
2654 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]);
2655 MACvSelectPage0(pDevice->PortOffset);
2656 pDevice->byRxMode &= ~(RCR_UNICAST);
2657 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2658 }
Forest Bond5449c682009-04-25 10:30:44 -04002659
Joe Perches915006c2013-03-18 10:44:47 -07002660 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2661 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
2662 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2663 pDevice->byRxMode &= ~(RCR_UNICAST);
2664 }
Forest Bond5449c682009-04-25 10:30:44 -04002665
Joe Perches915006c2013-03-18 10:44:47 -07002666 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
2667 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode);
Forest Bond5449c682009-04-25 10:30:44 -04002668}
2669
Guillaume Clement84b50762014-07-25 01:06:18 +02002670static struct net_device_stats *device_get_stats(struct net_device *dev)
2671{
Joe Perches915006c2013-03-18 10:44:47 -07002672 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002673
Joe Perches915006c2013-03-18 10:44:47 -07002674 return &pDevice->stats;
Forest Bond5449c682009-04-25 10:30:44 -04002675}
2676
Guillaume Clement84b50762014-07-25 01:06:18 +02002677static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2678{
Forest Bondc9d03522009-06-01 20:00:14 -04002679 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002680
Joe Perches915006c2013-03-18 10:44:47 -07002681 struct iwreq *wrq = (struct iwreq *)rq;
2682 int rc = 0;
2683 PSMgmtObject pMgmt = pDevice->pMgmt;
2684 PSCmdRequest pReq;
Forest Bond5449c682009-04-25 10:30:44 -04002685
Joe Perches915006c2013-03-18 10:44:47 -07002686 if (pMgmt == NULL) {
2687 rc = -EFAULT;
2688 return rc;
2689 }
Forest Bond5449c682009-04-25 10:30:44 -04002690
Joe Perches915006c2013-03-18 10:44:47 -07002691 switch (cmd) {
Forest Bond5449c682009-04-25 10:30:44 -04002692 case SIOCGIWNAME:
2693 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
2694 break;
2695
2696 case SIOCGIWNWID: //0x8b03 support
Marcos Paulo de Souza428c1fb2011-11-28 19:16:37 +00002697 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002698 break;
2699
2700 // Set frequency/channel
2701 case SIOCSIWFREQ:
Joe Perches915006c2013-03-18 10:44:47 -07002702 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002703 break;
2704
2705 // Get frequency/channel
2706 case SIOCGIWFREQ:
2707 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
2708 break;
2709
2710 // Set desired network name (ESSID)
2711 case SIOCSIWESSID:
2712
Joe Perches915006c2013-03-18 10:44:47 -07002713 {
2714 char essid[IW_ESSID_MAX_SIZE+1];
Guillaume Clement6b711272014-07-25 01:06:16 +02002715
Joe Perches915006c2013-03-18 10:44:47 -07002716 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
2717 rc = -E2BIG;
2718 break;
Forest Bond5449c682009-04-25 10:30:44 -04002719 }
Joe Perches915006c2013-03-18 10:44:47 -07002720 if (copy_from_user(essid, wrq->u.essid.pointer,
2721 wrq->u.essid.length)) {
2722 rc = -EFAULT;
2723 break;
2724 }
2725 rc = iwctl_siwessid(dev, NULL,
2726 &(wrq->u.essid), essid);
2727 }
2728 break;
Forest Bond5449c682009-04-25 10:30:44 -04002729
Joe Perches915006c2013-03-18 10:44:47 -07002730 // Get current network name (ESSID)
Forest Bond5449c682009-04-25 10:30:44 -04002731 case SIOCGIWESSID:
2732
Joe Perches915006c2013-03-18 10:44:47 -07002733 {
2734 char essid[IW_ESSID_MAX_SIZE+1];
Guillaume Clement6b711272014-07-25 01:06:16 +02002735
Joe Perches915006c2013-03-18 10:44:47 -07002736 if (wrq->u.essid.pointer)
2737 rc = iwctl_giwessid(dev, NULL,
2738 &(wrq->u.essid), essid);
2739 if (copy_to_user(wrq->u.essid.pointer,
2740 essid,
2741 wrq->u.essid.length))
2742 rc = -EFAULT;
2743 }
2744 break;
Forest Bond5449c682009-04-25 10:30:44 -04002745
2746 case SIOCSIWAP:
2747
2748 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2749 break;
2750
Forest Bond5449c682009-04-25 10:30:44 -04002751 // Get current Access Point (BSSID)
2752 case SIOCGIWAP:
2753 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2754 break;
2755
Forest Bond5449c682009-04-25 10:30:44 -04002756 // Set desired station name
2757 case SIOCSIWNICKN:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002758 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN\n");
Joe Perches915006c2013-03-18 10:44:47 -07002759 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002760 break;
2761
2762 // Get current station name
2763 case SIOCGIWNICKN:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002764 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN\n");
Joe Perches915006c2013-03-18 10:44:47 -07002765 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002766 break;
2767
2768 // Set the desired bit-rate
2769 case SIOCSIWRATE:
2770 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2771 break;
2772
Joe Perches915006c2013-03-18 10:44:47 -07002773 // Get the current bit-rate
Forest Bond5449c682009-04-25 10:30:44 -04002774 case SIOCGIWRATE:
2775
2776 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2777 break;
2778
Joe Perches915006c2013-03-18 10:44:47 -07002779 // Set the desired RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002780 case SIOCSIWRTS:
2781
2782 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
2783 break;
2784
Joe Perches915006c2013-03-18 10:44:47 -07002785 // Get the current RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002786 case SIOCGIWRTS:
2787
2788 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
2789 break;
2790
2791 // Set the desired fragmentation threshold
2792 case SIOCSIWFRAG:
2793
2794 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
Joe Perches915006c2013-03-18 10:44:47 -07002795 break;
Forest Bond5449c682009-04-25 10:30:44 -04002796
Joe Perches915006c2013-03-18 10:44:47 -07002797 // Get the current fragmentation threshold
Forest Bond5449c682009-04-25 10:30:44 -04002798 case SIOCGIWFRAG:
2799
2800 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
2801 break;
2802
2803 // Set mode of operation
2804 case SIOCSIWMODE:
Joe Perches915006c2013-03-18 10:44:47 -07002805 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002806 break;
2807
2808 // Get mode of operation
2809 case SIOCGIWMODE:
2810 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
2811 break;
2812
2813 // Set WEP keys and mode
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002814 case SIOCSIWENCODE: {
Joe Perches915006c2013-03-18 10:44:47 -07002815 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04002816
Joe Perches915006c2013-03-18 10:44:47 -07002817 if (wrq->u.encoding.pointer) {
Joe Perches915006c2013-03-18 10:44:47 -07002818 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
2819 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04002820 break;
2821 }
Joe Perches915006c2013-03-18 10:44:47 -07002822 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
2823 if (copy_from_user(abyKey,
2824 wrq->u.encoding.pointer,
2825 wrq->u.encoding.length)) {
2826 rc = -EFAULT;
2827 break;
2828 }
2829 } else if (wrq->u.encoding.length != 0) {
2830 rc = -EINVAL;
2831 break;
Forest Bond5449c682009-04-25 10:30:44 -04002832 }
Joe Perches915006c2013-03-18 10:44:47 -07002833 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
2834 }
2835 break;
Forest Bond5449c682009-04-25 10:30:44 -04002836
Joe Perches915006c2013-03-18 10:44:47 -07002837 // Get the WEP keys and mode
Forest Bond5449c682009-04-25 10:30:44 -04002838 case SIOCGIWENCODE:
2839
2840 if (!capable(CAP_NET_ADMIN)) {
2841 rc = -EPERM;
2842 break;
2843 }
2844 {
Joe Perches915006c2013-03-18 10:44:47 -07002845 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04002846
Joe Perches915006c2013-03-18 10:44:47 -07002847 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
Guillaume Clementa1613422014-07-25 01:06:22 +02002848 if (rc != 0)
2849 break;
Forest Bond5449c682009-04-25 10:30:44 -04002850 if (wrq->u.encoding.pointer) {
2851 if (copy_to_user(wrq->u.encoding.pointer,
Joe Perches915006c2013-03-18 10:44:47 -07002852 abyKey,
2853 wrq->u.encoding.length))
Forest Bond5449c682009-04-25 10:30:44 -04002854 rc = -EFAULT;
2855 }
2856 }
2857 break;
2858
Forest Bond5449c682009-04-25 10:30:44 -04002859 // Get the current Tx-Power
2860 case SIOCGIWTXPOW:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002861 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW\n");
Joe Perches915006c2013-03-18 10:44:47 -07002862 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002863 break;
2864
2865 case SIOCSIWTXPOW:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002866 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW\n");
Joe Perches915006c2013-03-18 10:44:47 -07002867 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002868 break;
2869
Forest Bond5449c682009-04-25 10:30:44 -04002870 case SIOCSIWRETRY:
2871
2872 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
2873 break;
2874
2875 case SIOCGIWRETRY:
2876
2877 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
2878 break;
2879
Forest Bond5449c682009-04-25 10:30:44 -04002880 // Get range of parameters
2881 case SIOCGIWRANGE:
2882
Joe Perches915006c2013-03-18 10:44:47 -07002883 {
2884 struct iw_range range;
Forest Bond5449c682009-04-25 10:30:44 -04002885
Joe Perches915006c2013-03-18 10:44:47 -07002886 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range);
2887 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
2888 rc = -EFAULT;
2889 }
Forest Bond5449c682009-04-25 10:30:44 -04002890
Joe Perches915006c2013-03-18 10:44:47 -07002891 break;
Forest Bond5449c682009-04-25 10:30:44 -04002892
2893 case SIOCGIWPOWER:
2894
2895 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
2896 break;
2897
Forest Bond5449c682009-04-25 10:30:44 -04002898 case SIOCSIWPOWER:
2899
2900 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
2901 break;
2902
Forest Bond5449c682009-04-25 10:30:44 -04002903 case SIOCGIWSENS:
2904
Joe Perches915006c2013-03-18 10:44:47 -07002905 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002906 break;
2907
2908 case SIOCSIWSENS:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002909 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS\n");
Forest Bond5449c682009-04-25 10:30:44 -04002910 rc = -EOPNOTSUPP;
2911 break;
2912
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002913 case SIOCGIWAPLIST: {
Joe Perches915006c2013-03-18 10:44:47 -07002914 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
Forest Bond5449c682009-04-25 10:30:44 -04002915
Joe Perches915006c2013-03-18 10:44:47 -07002916 if (wrq->u.data.pointer) {
2917 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
2918 if (rc == 0) {
2919 if (copy_to_user(wrq->u.data.pointer,
2920 buffer,
2921 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
2922 ))
2923 rc = -EFAULT;
2924 }
2925 }
2926 }
2927 break;
Forest Bond5449c682009-04-25 10:30:44 -04002928
Forest Bond5449c682009-04-25 10:30:44 -04002929#ifdef WIRELESS_SPY
Joe Perches915006c2013-03-18 10:44:47 -07002930 // Set the spy list
Forest Bond5449c682009-04-25 10:30:44 -04002931 case SIOCSIWSPY:
2932
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002933 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY\n");
Forest Bond5449c682009-04-25 10:30:44 -04002934 rc = -EOPNOTSUPP;
2935 break;
2936
2937 // Get the spy list
2938 case SIOCGIWSPY:
2939
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002940 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY\n");
Forest Bond5449c682009-04-25 10:30:44 -04002941 rc = -EOPNOTSUPP;
2942 break;
2943
2944#endif // WIRELESS_SPY
2945
2946 case SIOCGIWPRIV:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002947 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV\n");
Forest Bond5449c682009-04-25 10:30:44 -04002948 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002949 break;
2950
Forest Bond5449c682009-04-25 10:30:44 -04002951//2008-0409-07, <Add> by Einsn Liu
Joe Perches915006c2013-03-18 10:44:47 -07002952#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond5449c682009-04-25 10:30:44 -04002953 case SIOCSIWAUTH:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002954 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond5449c682009-04-25 10:30:44 -04002955 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
2956 break;
2957
2958 case SIOCGIWAUTH:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002959 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH\n");
Forest Bond5449c682009-04-25 10:30:44 -04002960 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
2961 break;
2962
2963 case SIOCSIWGENIE:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002964 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE\n");
Forest Bond5449c682009-04-25 10:30:44 -04002965 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2966 break;
2967
2968 case SIOCGIWGENIE:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002969 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE\n");
Forest Bond5449c682009-04-25 10:30:44 -04002970 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2971 break;
2972
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002973 case SIOCSIWENCODEEXT: {
Joe Perches915006c2013-03-18 10:44:47 -07002974 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002975
2976 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT\n");
Joe Perches915006c2013-03-18 10:44:47 -07002977 if (wrq->u.encoding.pointer) {
2978 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1);
2979 if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) {
2980 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04002981 break;
2982 }
Joe Perches915006c2013-03-18 10:44:47 -07002983 if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) {
2984 rc = -EFAULT;
2985 break;
2986 }
2987 } else if (wrq->u.encoding.length != 0) {
2988 rc = -EINVAL;
2989 break;
Forest Bond5449c682009-04-25 10:30:44 -04002990 }
Joe Perches915006c2013-03-18 10:44:47 -07002991 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
2992 }
2993 break;
Forest Bond5449c682009-04-25 10:30:44 -04002994
2995 case SIOCGIWENCODEEXT:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002996 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT\n");
Forest Bond5449c682009-04-25 10:30:44 -04002997 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
2998 break;
2999
3000 case SIOCSIWMLME:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02003001 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
Forest Bond5449c682009-04-25 10:30:44 -04003002 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
3003 break;
3004
3005#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
3006//End Add -- //2008-0409-07, <Add> by Einsn Liu
3007
Joe Perches915006c2013-03-18 10:44:47 -07003008 case IOCTL_CMD_TEST:
Forest Bond5449c682009-04-25 10:30:44 -04003009
3010 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
Joe Perches915006c2013-03-18 10:44:47 -07003011 rc = -EFAULT;
3012 break;
Forest Bond5449c682009-04-25 10:30:44 -04003013 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003014 rc = 0;
Forest Bond5449c682009-04-25 10:30:44 -04003015 }
Joe Perches915006c2013-03-18 10:44:47 -07003016 pReq = (PSCmdRequest)rq;
3017 pReq->wResult = MAGIC_CODE;
3018 break;
Forest Bond5449c682009-04-25 10:30:44 -04003019
Joe Perches915006c2013-03-18 10:44:47 -07003020 case IOCTL_CMD_SET:
Forest Bond5449c682009-04-25 10:30:44 -04003021
Joe Perches915006c2013-03-18 10:44:47 -07003022#ifdef SndEvt_ToAPI
3023 if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) &&
3024 !(pDevice->flags & DEVICE_FLAGS_OPENED))
3025#else
3026 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
3027 (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA))
3028#endif
3029 {
3030 rc = -EFAULT;
3031 break;
3032 } else {
3033 rc = 0;
3034 }
3035
Guido Martínezbc5cf652014-04-19 16:45:00 -03003036 if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy)))
Joe Perches915006c2013-03-18 10:44:47 -07003037 return -EBUSY;
Guido Martínezbc5cf652014-04-19 16:45:00 -03003038
Joe Perches915006c2013-03-18 10:44:47 -07003039 rc = private_ioctl(pDevice, rq);
3040 clear_bit(0, (void *)&(pMgmt->uCmdBusy));
3041 break;
Forest Bond5449c682009-04-25 10:30:44 -04003042
Joe Perches915006c2013-03-18 10:44:47 -07003043 case IOCTL_CMD_HOSTAPD:
Forest Bond5449c682009-04-25 10:30:44 -04003044
Joe Perches915006c2013-03-18 10:44:47 -07003045 rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data);
3046 break;
Forest Bond5449c682009-04-25 10:30:44 -04003047
Joe Perches915006c2013-03-18 10:44:47 -07003048 case IOCTL_CMD_WPA:
Forest Bond5449c682009-04-25 10:30:44 -04003049
Joe Perches915006c2013-03-18 10:44:47 -07003050 rc = wpa_ioctl(pDevice, &wrq->u.data);
3051 break;
Forest Bond5449c682009-04-25 10:30:44 -04003052
3053 case SIOCETHTOOL:
James A Shacklefordebc43d02014-05-31 20:09:05 -04003054 return ethtool_ioctl(dev, rq->ifr_data);
Joe Perches915006c2013-03-18 10:44:47 -07003055 // All other calls are currently unsupported
Forest Bond5449c682009-04-25 10:30:44 -04003056
3057 default:
3058 rc = -EOPNOTSUPP;
Joe Perches915006c2013-03-18 10:44:47 -07003059 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
Forest Bond5449c682009-04-25 10:30:44 -04003060
Joe Perches915006c2013-03-18 10:44:47 -07003061 }
Forest Bond5449c682009-04-25 10:30:44 -04003062
Joe Perches915006c2013-03-18 10:44:47 -07003063 if (pDevice->bCommit) {
3064 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
3065 netif_stop_queue(pDevice->dev);
3066 spin_lock_irq(&pDevice->lock);
3067 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
3068 spin_unlock_irq(&pDevice->lock);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003069 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003070 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
3071 spin_lock_irq(&pDevice->lock);
3072 pDevice->bLinkPass = false;
3073 memset(pMgmt->abyCurrBSSID, 0, 6);
3074 pMgmt->eCurrState = WMAC_STATE_IDLE;
3075 netif_stop_queue(pDevice->dev);
3076#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
3077 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Teodora Baluta1208f142013-11-10 17:12:42 +02003078 if (!pDevice->bWPASuppWextEnabled)
Joe Perches915006c2013-03-18 10:44:47 -07003079#endif
3080 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
3081 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3082 spin_unlock_irq(&pDevice->lock);
3083 }
3084 pDevice->bCommit = false;
3085 }
Forest Bond5449c682009-04-25 10:30:44 -04003086
Joe Perches915006c2013-03-18 10:44:47 -07003087 return rc;
Forest Bond5449c682009-04-25 10:30:44 -04003088}
3089
James A Shacklefordebc43d02014-05-31 20:09:05 -04003090static int ethtool_ioctl(struct net_device *dev, void __user *useraddr)
Forest Bond5449c682009-04-25 10:30:44 -04003091{
3092 u32 ethcmd;
3093
3094 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
3095 return -EFAULT;
3096
Joe Perches915006c2013-03-18 10:44:47 -07003097 switch (ethcmd) {
Forest Bond5449c682009-04-25 10:30:44 -04003098 case ETHTOOL_GDRVINFO: {
3099 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
Guillaume Clement6b711272014-07-25 01:06:16 +02003100
Forest Bond5449c682009-04-25 10:30:44 -04003101 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
3102 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
3103 if (copy_to_user(useraddr, &info, sizeof(info)))
3104 return -EFAULT;
3105 return 0;
3106 }
3107
Joe Perches915006c2013-03-18 10:44:47 -07003108 }
Forest Bond5449c682009-04-25 10:30:44 -04003109
3110 return -EOPNOTSUPP;
3111}
3112
3113/*------------------------------------------------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -04003114
Charles Clément013a4682010-06-15 10:39:24 -07003115MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
Forest Bond5449c682009-04-25 10:30:44 -04003116
3117static struct pci_driver device_driver = {
Peter Huewe34381c22011-01-10 23:28:06 +01003118 .name = DEVICE_NAME,
3119 .id_table = vt6655_pci_id_table,
3120 .probe = vt6655_probe,
3121 .remove = vt6655_remove,
Forest Bond5449c682009-04-25 10:30:44 -04003122#ifdef CONFIG_PM
Peter Huewe34381c22011-01-10 23:28:06 +01003123 .suspend = viawget_suspend,
3124 .resume = viawget_resume,
Forest Bond5449c682009-04-25 10:30:44 -04003125#endif
Forest Bond5449c682009-04-25 10:30:44 -04003126};
3127
Charles Clément013a4682010-06-15 10:39:24 -07003128static int __init vt6655_init_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003129{
Joe Perches915006c2013-03-18 10:44:47 -07003130 int ret;
Forest Bond5449c682009-04-25 10:30:44 -04003131
Forest Bond5449c682009-04-25 10:30:44 -04003132 ret = pci_register_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003133#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003134 if (ret >= 0)
3135 register_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003136#endif
Forest Bond5449c682009-04-25 10:30:44 -04003137
Joe Perches915006c2013-03-18 10:44:47 -07003138 return ret;
Forest Bond5449c682009-04-25 10:30:44 -04003139}
3140
Charles Clément013a4682010-06-15 10:39:24 -07003141static void __exit vt6655_cleanup_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003142{
Forest Bond5449c682009-04-25 10:30:44 -04003143#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003144 unregister_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003145#endif
Joe Perches915006c2013-03-18 10:44:47 -07003146 pci_unregister_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003147}
3148
Charles Clément013a4682010-06-15 10:39:24 -07003149module_init(vt6655_init_module);
3150module_exit(vt6655_cleanup_module);
Forest Bond5449c682009-04-25 10:30:44 -04003151
Forest Bond5449c682009-04-25 10:30:44 -04003152#ifdef CONFIG_PM
3153static int
3154device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
3155{
Joe Perches915006c2013-03-18 10:44:47 -07003156 struct pci_dev *pdev = NULL;
Guillaume Clement6b711272014-07-25 01:06:16 +02003157
Joe Perches915006c2013-03-18 10:44:47 -07003158 switch (event) {
3159 case SYS_DOWN:
3160 case SYS_HALT:
3161 case SYS_POWER_OFF:
3162 for_each_pci_dev(pdev) {
3163 if (pci_dev_driver(pdev) == &device_driver) {
3164 if (pci_get_drvdata(pdev))
3165 viawget_suspend(pdev, PMSG_HIBERNATE);
3166 }
3167 }
3168 }
3169 return NOTIFY_DONE;
Forest Bond5449c682009-04-25 10:30:44 -04003170}
3171
3172static int
Alan Coxf408ade2009-06-10 17:30:49 +01003173viawget_suspend(struct pci_dev *pcid, pm_message_t state)
Forest Bond5449c682009-04-25 10:30:44 -04003174{
Joe Perches915006c2013-03-18 10:44:47 -07003175 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003176
Joe Perches915006c2013-03-18 10:44:47 -07003177 PSDevice pDevice = pci_get_drvdata(pcid);
3178 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04003179
Joe Perches915006c2013-03-18 10:44:47 -07003180 netif_stop_queue(pDevice->dev);
3181 spin_lock_irq(&pDevice->lock);
3182 pci_save_state(pcid);
3183 del_timer(&pDevice->sTimerCommand);
3184 del_timer(&pMgmt->sTimerSecondCallback);
3185 pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
3186 pDevice->uCmdDequeueIdx = 0;
3187 pDevice->uCmdEnqueueIdx = 0;
3188 pDevice->bCmdRunning = false;
3189 MACbShutdown(pDevice->PortOffset);
3190 MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
3191 pDevice->bLinkPass = false;
3192 memset(pMgmt->abyCurrBSSID, 0, 6);
3193 pMgmt->eCurrState = WMAC_STATE_IDLE;
3194 pci_disable_device(pcid);
3195 power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state));
3196 spin_unlock_irq(&pDevice->lock);
3197 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003198}
3199
3200static int
3201viawget_resume(struct pci_dev *pcid)
3202{
Joe Perches915006c2013-03-18 10:44:47 -07003203 PSDevice pDevice = pci_get_drvdata(pcid);
3204 PSMgmtObject pMgmt = pDevice->pMgmt;
3205 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003206
Yijing Wang6496c042013-06-27 20:57:23 +08003207 power_status = pci_set_power_state(pcid, PCI_D0);
3208 power_status = pci_enable_wake(pcid, PCI_D0, 0);
Joe Perches915006c2013-03-18 10:44:47 -07003209 pci_restore_state(pcid);
3210 if (netif_running(pDevice->dev)) {
3211 spin_lock_irq(&pDevice->lock);
3212 MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
3213 device_init_registers(pDevice, DEVICE_INIT_DXPL);
Teodora Baluta1208f142013-11-10 17:12:42 +02003214 if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
Joe Perches915006c2013-03-18 10:44:47 -07003215 pMgmt->sNodeDBTable[0].bActive = false;
3216 pDevice->bLinkPass = false;
3217 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3218 // In Adhoc, BSS state set back to started.
3219 pMgmt->eCurrState = WMAC_STATE_STARTED;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003220 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003221 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
3222 pMgmt->eCurrState = WMAC_STATE_IDLE;
3223 }
3224 }
3225 init_timer(&pMgmt->sTimerSecondCallback);
3226 init_timer(&pDevice->sTimerCommand);
3227 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
3228 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
3229 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
3230 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3231 spin_unlock_irq(&pDevice->lock);
3232 }
3233 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003234}
3235
3236#endif