blob: 08b250f01dae6e7fd2f323cf9f7a06920266fe11 [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 -------------------------*/
92//static int msglevel =MSG_LEVEL_DEBUG;
93static int msglevel = MSG_LEVEL_INFO;
94
Forest Bond5449c682009-04-25 10:30:44 -040095//
96// Define module options
97//
Forest Bond5449c682009-04-25 10:30:44 -040098MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
99MODULE_LICENSE("GPL");
100MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
Forest Bond5449c682009-04-25 10:30:44 -0400101
Joe Perches915006c2013-03-18 10:44:47 -0700102static int mlme_kill;
103//static struct task_struct * mlme_task;
Forest Bond5449c682009-04-25 10:30:44 -0400104
Joe Perches915006c2013-03-18 10:44:47 -0700105#define DEVICE_PARAM(N, D)
Forest Bond5449c682009-04-25 10:30:44 -0400106/*
Joe Perches915006c2013-03-18 10:44:47 -0700107 static const int N[MAX_UINTS]=OPTION_DEFAULT;\
108 MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UINTS) "i");\
109 MODULE_PARM_DESC(N, D);
Forest Bond5449c682009-04-25 10:30:44 -0400110*/
111
112#define RX_DESC_MIN0 16
113#define RX_DESC_MAX0 128
114#define RX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700115DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400116
117#define RX_DESC_MIN1 16
118#define RX_DESC_MAX1 128
119#define RX_DESC_DEF1 32
Joe Perches915006c2013-03-18 10:44:47 -0700120DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400121
122#define TX_DESC_MIN0 16
123#define TX_DESC_MAX0 128
124#define TX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700125DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400126
127#define TX_DESC_MIN1 16
128#define TX_DESC_MAX1 128
129#define TX_DESC_DEF1 64
Joe Perches915006c2013-03-18 10:44:47 -0700130DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400131
Forest Bond5449c682009-04-25 10:30:44 -0400132#define IP_ALIG_DEF 0
Charles Clément0f4c60d2010-06-24 11:02:25 -0700133/* IP_byte_align[] is used for IP header unsigned long byte aligned
134 0: indicate the IP header won't be unsigned long byte aligned.(Default) .
135 1: indicate the IP header will be unsigned long byte aligned.
Joe Perches915006c2013-03-18 10:44:47 -0700136 In some environment, the IP header should be unsigned long byte aligned,
137 or the packet will be droped when we receive it. (eg: IPVS)
Forest Bond5449c682009-04-25 10:30:44 -0400138*/
Joe Perches915006c2013-03-18 10:44:47 -0700139DEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned");
Forest Bond5449c682009-04-25 10:30:44 -0400140
Forest Bond5449c682009-04-25 10:30:44 -0400141#define INT_WORKS_DEF 20
142#define INT_WORKS_MIN 10
143#define INT_WORKS_MAX 64
144
Joe Perches915006c2013-03-18 10:44:47 -0700145DEVICE_PARAM(int_works, "Number of packets per interrupt services");
Forest Bond5449c682009-04-25 10:30:44 -0400146
147#define CHANNEL_MIN 1
148#define CHANNEL_MAX 14
149#define CHANNEL_DEF 6
150
151DEVICE_PARAM(Channel, "Channel number");
152
Forest Bond5449c682009-04-25 10:30:44 -0400153/* PreambleType[] is the preamble length used for transmit.
154 0: indicate allows long preamble type
155 1: indicate allows short preamble type
156*/
157
158#define PREAMBLE_TYPE_DEF 1
159
160DEVICE_PARAM(PreambleType, "Preamble Type");
161
Forest Bond5449c682009-04-25 10:30:44 -0400162#define RTS_THRESH_MIN 512
163#define RTS_THRESH_MAX 2347
164#define RTS_THRESH_DEF 2347
165
166DEVICE_PARAM(RTSThreshold, "RTS threshold");
167
Forest Bond5449c682009-04-25 10:30:44 -0400168#define FRAG_THRESH_MIN 256
169#define FRAG_THRESH_MAX 2346
170#define FRAG_THRESH_DEF 2346
171
172DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
173
Forest Bond5449c682009-04-25 10:30:44 -0400174#define DATA_RATE_MIN 0
175#define DATA_RATE_MAX 13
176#define DATA_RATE_DEF 13
177/* datarate[] index
178 0: indicate 1 Mbps 0x02
179 1: indicate 2 Mbps 0x04
180 2: indicate 5.5 Mbps 0x0B
181 3: indicate 11 Mbps 0x16
182 4: indicate 6 Mbps 0x0c
183 5: indicate 9 Mbps 0x12
184 6: indicate 12 Mbps 0x18
185 7: indicate 18 Mbps 0x24
186 8: indicate 24 Mbps 0x30
187 9: indicate 36 Mbps 0x48
Joe Perches915006c2013-03-18 10:44:47 -0700188 10: indicate 48 Mbps 0x60
189 11: indicate 54 Mbps 0x6c
190 12: indicate 72 Mbps 0x90
191 13: indicate auto rate
Forest Bond5449c682009-04-25 10:30:44 -0400192*/
193
194DEVICE_PARAM(ConnectionRate, "Connection data rate");
195
196#define OP_MODE_DEF 0
197
198DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
199
200/* OpMode[] is used for transmit.
201 0: indicate infrastruct mode used
202 1: indicate adhoc mode used
203 2: indicate AP mode used
204*/
205
Forest Bond5449c682009-04-25 10:30:44 -0400206/* PSMode[]
207 0: indicate disable power saving mode
208 1: indicate enable power saving mode
209*/
210
211#define PS_MODE_DEF 0
212
213DEVICE_PARAM(PSMode, "Power saving mode");
214
Forest Bond5449c682009-04-25 10:30:44 -0400215#define SHORT_RETRY_MIN 0
216#define SHORT_RETRY_MAX 31
217#define SHORT_RETRY_DEF 8
218
Forest Bond5449c682009-04-25 10:30:44 -0400219DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
220
221#define LONG_RETRY_MIN 0
222#define LONG_RETRY_MAX 15
223#define LONG_RETRY_DEF 4
224
Forest Bond5449c682009-04-25 10:30:44 -0400225DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
226
Forest Bond5449c682009-04-25 10:30:44 -0400227/* BasebandType[] baseband type selected
228 0: indicate 802.11a type
229 1: indicate 802.11b type
230 2: indicate 802.11g type
231*/
232#define BBP_TYPE_MIN 0
233#define BBP_TYPE_MAX 2
234#define BBP_TYPE_DEF 2
235
236DEVICE_PARAM(BasebandType, "baseband type");
237
Forest Bond5449c682009-04-25 10:30:44 -0400238/* 80211hEnable[]
239 0: indicate disable 802.11h
240 1: indicate enable 802.11h
241*/
242
243#define X80211h_MODE_DEF 0
244
245DEVICE_PARAM(b80211hEnable, "802.11h mode");
246
247/* 80211hEnable[]
248 0: indicate disable 802.11h
249 1: indicate enable 802.11h
250*/
251
252#define DIVERSITY_ANT_DEF 0
253
254DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
255
Forest Bond5449c682009-04-25 10:30:44 -0400256//
257// Static vars definitions
258//
259
Joe Perches915006c2013-03-18 10:44:47 -0700260static int device_nics = 0;
261static PSDevice pDevice_Infos = NULL;
Forest Bond5449c682009-04-25 10:30:44 -0400262static struct net_device *root_device_dev = NULL;
263
Joe Perches915006c2013-03-18 10:44:47 -0700264static CHIP_INFO chip_info_table[] = {
265 { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ",
266 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN },
267 {0, NULL}
Forest Bond5449c682009-04-25 10:30:44 -0400268};
269
Charles Clément013a4682010-06-15 10:39:24 -0700270DEFINE_PCI_DEVICE_TABLE(vt6655_pci_id_table) = {
Jim Liebdb6cb902009-07-23 17:20:49 -0700271 { PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
272 { 0, }
Forest Bond5449c682009-04-25 10:30:44 -0400273};
Forest Bond5449c682009-04-25 10:30:44 -0400274
275/*--------------------- Static Functions --------------------------*/
276
Charles Clément013a4682010-06-15 10:39:24 -0700277static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
Joe Perches915006c2013-03-18 10:44:47 -0700278static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, PCHIP_INFO);
Forest Bond5449c682009-04-25 10:30:44 -0400279static void device_free_info(PSDevice pDevice);
Joe Perches915006c2013-03-18 10:44:47 -0700280static bool device_get_pci_info(PSDevice, struct pci_dev *pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400281static void device_print_info(PSDevice pDevice);
282static struct net_device_stats *device_get_stats(struct net_device *dev);
283static void device_init_diversity_timer(PSDevice pDevice);
284static int device_open(struct net_device *dev);
285static int device_xmit(struct sk_buff *skb, struct net_device *dev);
Joe Perches915006c2013-03-18 10:44:47 -0700286static irqreturn_t device_intr(int irq, void *dev_instance);
Forest Bond5449c682009-04-25 10:30:44 -0400287static void device_set_multi(struct net_device *dev);
288static int device_close(struct net_device *dev);
289static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
290
Forest Bond5449c682009-04-25 10:30:44 -0400291#ifdef CONFIG_PM
292static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
Alan Coxf408ade2009-06-10 17:30:49 +0100293static int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
Forest Bond5449c682009-04-25 10:30:44 -0400294static int viawget_resume(struct pci_dev *pcid);
295struct notifier_block device_notifier = {
Peter Huewe34381c22011-01-10 23:28:06 +0100296 .notifier_call = device_notify_reboot,
297 .next = NULL,
298 .priority = 0,
Forest Bond5449c682009-04-25 10:30:44 -0400299};
300#endif
Forest Bond5449c682009-04-25 10:30:44 -0400301
Forest Bond5449c682009-04-25 10:30:44 -0400302static void device_init_rd0_ring(PSDevice pDevice);
303static void device_init_rd1_ring(PSDevice pDevice);
304static void device_init_defrag_cb(PSDevice pDevice);
305static void device_init_td0_ring(PSDevice pDevice);
306static void device_init_td1_ring(PSDevice pDevice);
307
Forest Bond5449c682009-04-25 10:30:44 -0400308static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
Forest Bond5449c682009-04-25 10:30:44 -0400309//2008-0714<Add>by Mike Liu
Charles Clément7b6a0012010-08-01 17:15:50 +0200310static bool device_release_WPADEV(PSDevice pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400311
312static int ethtool_ioctl(struct net_device *dev, void *useraddr);
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700313static int device_rx_srv(PSDevice pDevice, unsigned int uIdx);
314static int device_tx_srv(PSDevice pDevice, unsigned int uIdx);
Charles Clément7b6a0012010-08-01 17:15:50 +0200315static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
Forest Bond5449c682009-04-25 10:30:44 -0400316static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
317static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
318static void device_free_td0_ring(PSDevice pDevice);
319static void device_free_td1_ring(PSDevice pDevice);
320static void device_free_rd0_ring(PSDevice pDevice);
321static void device_free_rd1_ring(PSDevice pDevice);
322static void device_free_rings(PSDevice pDevice);
323static void device_free_frag_buf(PSDevice pDevice);
Charles Clément5c9824e2010-06-02 09:51:59 -0700324static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -0700325 unsigned char *dest, unsigned char *source);
Forest Bond5449c682009-04-25 10:30:44 -0400326
Forest Bond5449c682009-04-25 10:30:44 -0400327/*--------------------- Export Variables --------------------------*/
328
329/*--------------------- Export Functions --------------------------*/
330
Joe Perches915006c2013-03-18 10:44:47 -0700331static char *get_chip_name(int chip_id)
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530332{
333 int i;
334 for (i = 0; chip_info_table[i].name != NULL; i++)
335 if (chip_info_table[i].chip_id == chip_id)
336 break;
337 return chip_info_table[i].name;
Forest Bond5449c682009-04-25 10:30:44 -0400338}
339
Bill Pembertonf4e1b7c2012-11-19 13:26:53 -0500340static void vt6655_remove(struct pci_dev *pcid)
Forest Bond5449c682009-04-25 10:30:44 -0400341{
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530342 PSDevice pDevice = pci_get_drvdata(pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400343
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530344 if (pDevice == NULL)
345 return;
346 device_free_info(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400347}
348
Forest Bond5449c682009-04-25 10:30:44 -0400349/*
Joe Perches915006c2013-03-18 10:44:47 -0700350 static void
351 device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char* devname) {
352 if (val==-1)
353 *opt=def;
354 else if (val<min || val>max) {
355 DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" ,
356 devname,name, min,max);
357 *opt=def;
358 } else {
359 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
360 devname, name, val);
361 *opt=val;
362 }
363 }
Forest Bond5449c682009-04-25 10:30:44 -0400364
Joe Perches915006c2013-03-18 10:44:47 -0700365 static void
366 device_set_bool_opt(unsigned int *opt, int val,bool def,u32 flag, char* name,char* devname) {
367 (*opt)&=(~flag);
368 if (val==-1)
369 *opt|=(def ? flag : 0);
370 else if (val<0 || val>1) {
371 DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE
372 "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",devname,name);
373 *opt|=(def ? flag : 0);
374 } else {
375 DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n",
376 devname,name , val ? "true" : "false");
377 *opt|=(val ? flag : 0);
378 }
379 }
Forest Bond5449c682009-04-25 10:30:44 -0400380*/
Joe Perches915006c2013-03-18 10:44:47 -0700381static void device_get_options(PSDevice pDevice, int index, char *devname)
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530382{
383 POPTIONS pOpts = &(pDevice->sOpts);
Forest Bond5449c682009-04-25 10:30:44 -0400384
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530385 pOpts->nRxDescs0 = RX_DESC_DEF0;
386 pOpts->nRxDescs1 = RX_DESC_DEF1;
387 pOpts->nTxDescs[0] = TX_DESC_DEF0;
388 pOpts->nTxDescs[1] = TX_DESC_DEF1;
389 pOpts->flags |= DEVICE_FLAGS_IP_ALIGN;
390 pOpts->int_works = INT_WORKS_DEF;
391 pOpts->rts_thresh = RTS_THRESH_DEF;
392 pOpts->frag_thresh = FRAG_THRESH_DEF;
393 pOpts->data_rate = DATA_RATE_DEF;
394 pOpts->channel_num = CHANNEL_DEF;
Forest Bond5449c682009-04-25 10:30:44 -0400395
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530396 pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE;
397 pOpts->flags |= DEVICE_FLAGS_OP_MODE;
398 //pOpts->flags|=DEVICE_FLAGS_PS_MODE;
399 pOpts->short_retry = SHORT_RETRY_DEF;
400 pOpts->long_retry = LONG_RETRY_DEF;
401 pOpts->bbp_type = BBP_TYPE_DEF;
402 pOpts->flags |= DEVICE_FLAGS_80211h_MODE;
403 pOpts->flags |= DEVICE_FLAGS_DiversityANT;
Forest Bond5449c682009-04-25 10:30:44 -0400404}
405
406static void
407device_set_options(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -0700408 unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
409 unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
410 unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond5449c682009-04-25 10:30:44 -0400411
Joe Perches915006c2013-03-18 10:44:47 -0700412 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
413 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
414 memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
Forest Bond5449c682009-04-25 10:30:44 -0400415
Joe Perches915006c2013-03-18 10:44:47 -0700416 pDevice->uChannel = pDevice->sOpts.channel_num;
417 pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh;
418 pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh;
419 pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
420 pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
421 pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
422 pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0;
423 pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0;
424 pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0;
425 pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
426 pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
427 pDevice->uConnectionRate = pDevice->sOpts.data_rate;
428 if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true;
429 pDevice->byBBType = pDevice->sOpts.bbp_type;
430 pDevice->byPacketType = pDevice->byBBType;
Forest Bond5449c682009-04-25 10:30:44 -0400431
432//PLICE_DEBUG->
433 pDevice->byAutoFBCtrl = AUTO_FB_0;
434 //pDevice->byAutoFBCtrl = AUTO_FB_1;
435//PLICE_DEBUG<-
Joe Perches915006c2013-03-18 10:44:47 -0700436 pDevice->bUpdateBBVGA = true;
437 pDevice->byFOETuning = 0;
438 pDevice->wCTSDuration = 0;
439 pDevice->byPreambleType = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400440
Joe Perches915006c2013-03-18 10:44:47 -0700441 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uChannel= %d\n", (int)pDevice->uChannel);
442 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byOpMode= %d\n", (int)pDevice->byOpMode);
443 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ePSMode= %d\n", (int)pDevice->ePSMode);
444 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold);
445 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit);
446 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit);
447 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byPreambleType= %d\n", (int)pDevice->byPreambleType);
448 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
449 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uConnectionRate= %d\n", (int)pDevice->uConnectionRate);
450 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byBBType= %d\n", (int)pDevice->byBBType);
451 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable);
452 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON);
Forest Bond5449c682009-04-25 10:30:44 -0400453}
454
Joe Perches915006c2013-03-18 10:44:47 -0700455static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult)
Forest Bond5449c682009-04-25 10:30:44 -0400456{
Joe Perches915006c2013-03-18 10:44:47 -0700457 unsigned int ii;
458 unsigned long dwDuration = 0;
459 unsigned char byRPI0 = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400460
Joe Perches915006c2013-03-18 10:44:47 -0700461 for (ii = 1; ii < 8; ii++) {
462 pDevice->dwRPIs[ii] *= 255;
463 dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration));
464 dwDuration <<= 10;
465 pDevice->dwRPIs[ii] /= dwDuration;
466 pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii];
467 byRPI0 += pDevice->abyRPIs[ii];
468 }
469 pDevice->abyRPIs[0] = (0xFF - byRPI0);
Forest Bond5449c682009-04-25 10:30:44 -0400470
Joe Perches915006c2013-03-18 10:44:47 -0700471 if (pDevice->uNumOfMeasureEIDs == 0) {
472 VNTWIFIbMeasureReport(pDevice->pMgmt,
473 true,
474 pDevice->pCurrMeasureEID,
475 byResult,
476 pDevice->byBasicMap,
477 pDevice->byCCAFraction,
478 pDevice->abyRPIs
479 );
480 } else {
481 VNTWIFIbMeasureReport(pDevice->pMgmt,
482 false,
483 pDevice->pCurrMeasureEID,
484 byResult,
485 pDevice->byBasicMap,
486 pDevice->byCCAFraction,
487 pDevice->abyRPIs
488 );
489 CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs);
490 }
Forest Bond5449c682009-04-25 10:30:44 -0400491}
492
Forest Bond5449c682009-04-25 10:30:44 -0400493//
Justin P. Mattock789d1ae2012-08-20 08:43:13 -0700494// Initialisation of MAC & BBP registers
Forest Bond5449c682009-04-25 10:30:44 -0400495//
496
497static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
498{
Joe Perches915006c2013-03-18 10:44:47 -0700499 unsigned int ii;
500 unsigned char byValue;
501 unsigned char byValue1;
502 unsigned char byCCKPwrdBm = 0;
503 unsigned char byOFDMPwrdBm = 0;
504 int zonetype = 0;
505 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
506 MACbShutdown(pDevice->PortOffset);
507 BBvSoftwareReset(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400508
Joe Perches915006c2013-03-18 10:44:47 -0700509 if ((InitType == DEVICE_INIT_COLD) ||
510 (InitType == DEVICE_INIT_DXPL)) {
511 // Do MACbSoftwareReset in MACvInitialize
512 MACbSoftwareReset(pDevice->PortOffset);
513 // force CCK
514 pDevice->bCCK = true;
515 pDevice->bAES = false;
516 pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE
517 pDevice->bNonERPPresent = false;
518 pDevice->bBarkerPreambleMd = false;
519 pDevice->wCurrentRate = RATE_1M;
520 pDevice->byTopOFDMBasicRate = RATE_24M;
521 pDevice->byTopCCKBasicRate = RATE_1M;
Forest Bond5449c682009-04-25 10:30:44 -0400522
Joe Perches915006c2013-03-18 10:44:47 -0700523 pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
Forest Bond5449c682009-04-25 10:30:44 -0400524
Joe Perches915006c2013-03-18 10:44:47 -0700525 // init MAC
526 MACvInitialize(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400527
Joe Perches915006c2013-03-18 10:44:47 -0700528 // Get Local ID
529 VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID));
Forest Bond5449c682009-04-25 10:30:44 -0400530
Joe Perches915006c2013-03-18 10:44:47 -0700531 spin_lock_irq(&pDevice->lock);
532 SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
Forest Bond5449c682009-04-25 10:30:44 -0400533
Joe Perches915006c2013-03-18 10:44:47 -0700534 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -0400535
Joe Perches915006c2013-03-18 10:44:47 -0700536 // Get Channel range
Forest Bond5449c682009-04-25 10:30:44 -0400537
Joe Perches915006c2013-03-18 10:44:47 -0700538 pDevice->byMinChannel = 1;
539 pDevice->byMaxChannel = CB_MAX_CHANNEL;
Forest Bond5449c682009-04-25 10:30:44 -0400540
Joe Perches915006c2013-03-18 10:44:47 -0700541 // Get Antena
542 byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
543 if (byValue & EEP_ANTINV)
544 pDevice->bTxRxAntInv = true;
545 else
546 pDevice->bTxRxAntInv = false;
Forest Bond5449c682009-04-25 10:30:44 -0400547
Joe Perches915006c2013-03-18 10:44:47 -0700548 byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
549 if (byValue == 0) // if not set default is All
550 byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
Joe Perchesf2046f92013-03-18 20:55:36 -0700551
Joe Perches915006c2013-03-18 10:44:47 -0700552 pDevice->ulDiversityNValue = 100*260;//100*SROMbyReadEmbedded(pDevice->PortOffset, 0x51);
553 pDevice->ulDiversityMValue = 100*16;//SROMbyReadEmbedded(pDevice->PortOffset, 0x52);
554 pDevice->byTMax = 1;//SROMbyReadEmbedded(pDevice->PortOffset, 0x53);
555 pDevice->byTMax2 = 4;//SROMbyReadEmbedded(pDevice->PortOffset, 0x54);
556 pDevice->ulSQ3TH = 0;//(unsigned long) SROMbyReadEmbedded(pDevice->PortOffset, 0x55);
557 pDevice->byTMax3 = 64;//SROMbyReadEmbedded(pDevice->PortOffset, 0x56);
Forest Bond5449c682009-04-25 10:30:44 -0400558
Joe Perches915006c2013-03-18 10:44:47 -0700559 if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
560 pDevice->byAntennaCount = 2;
561 pDevice->byTxAntennaMode = ANT_B;
562 pDevice->dwTxAntennaSel = 1;
563 pDevice->dwRxAntennaSel = 1;
564 if (pDevice->bTxRxAntInv == true)
565 pDevice->byRxAntennaMode = ANT_A;
566 else
567 pDevice->byRxAntennaMode = ANT_B;
568 // chester for antenna
569 byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
Joe Perches915006c2013-03-18 10:44:47 -0700570 if ((byValue1 & 0x08) == 0)
571 pDevice->bDiversityEnable = false;//SROMbyReadEmbedded(pDevice->PortOffset, 0x50);
572 else
573 pDevice->bDiversityEnable = true;
Joe Perches915006c2013-03-18 10:44:47 -0700574 } else {
575 pDevice->bDiversityEnable = false;
576 pDevice->byAntennaCount = 1;
577 pDevice->dwTxAntennaSel = 0;
578 pDevice->dwRxAntennaSel = 0;
579 if (byValue & EEP_ANTENNA_AUX) {
580 pDevice->byTxAntennaMode = ANT_A;
581 if (pDevice->bTxRxAntInv == true)
582 pDevice->byRxAntennaMode = ANT_B;
583 else
584 pDevice->byRxAntennaMode = ANT_A;
585 } else {
586 pDevice->byTxAntennaMode = ANT_B;
587 if (pDevice->bTxRxAntInv == true)
588 pDevice->byRxAntennaMode = ANT_A;
589 else
590 pDevice->byRxAntennaMode = ANT_B;
591 }
592 }
Joe Perches915006c2013-03-18 10:44:47 -0700593 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
594 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2);
Forest Bond5449c682009-04-25 10:30:44 -0400595
596//#ifdef ZoneType_DefaultSetting
597//2008-8-4 <add> by chester
598//zonetype initial
Joe Perches915006c2013-03-18 10:44:47 -0700599 pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
600 zonetype = Config_FileOperation(pDevice, false, NULL);
601 if (zonetype >= 0) { //read zonetype file ok!
602 if ((zonetype == 0) &&
603 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { //for USA
604 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
605 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
606 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700607 } else if ((zonetype == 1) &&
Joe Perches915006c2013-03-18 10:44:47 -0700608 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { //for Japan
609 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
610 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700611 } else if ((zonetype == 2) &&
Joe Perches915006c2013-03-18 10:44:47 -0700612 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { //for Europe
613 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
614 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
615 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n");
616 }
Forest Bond5449c682009-04-25 10:30:44 -0400617
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700618 else {
Joe Perches915006c2013-03-18 10:44:47 -0700619 if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
620 printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", zonetype, pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
621 else
622 printk("Read Zonetype file success,use default zonetype setting[%02x]\n", zonetype);
623 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700624 } else
Joe Perches915006c2013-03-18 10:44:47 -0700625 printk("Read Zonetype file fail,use default zonetype setting[%02x]\n", SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
Forest Bond5449c682009-04-25 10:30:44 -0400626
Joe Perches915006c2013-03-18 10:44:47 -0700627 // Get RFType
628 pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
Forest Bond5449c682009-04-25 10:30:44 -0400629
Joe Perches915006c2013-03-18 10:44:47 -0700630 if ((pDevice->byRFType & RF_EMU) != 0) {
631 // force change RevID for VT3253 emu
632 pDevice->byRevId = 0x80;
633 }
Forest Bond5449c682009-04-25 10:30:44 -0400634
Joe Perches915006c2013-03-18 10:44:47 -0700635 pDevice->byRFType &= RF_MASK;
636 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
Forest Bond5449c682009-04-25 10:30:44 -0400637
Joe Perches915006c2013-03-18 10:44:47 -0700638 if (pDevice->bZoneRegExist == false) {
639 pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
640 }
641 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
Forest Bond5449c682009-04-25 10:30:44 -0400642
Joe Perches915006c2013-03-18 10:44:47 -0700643 //Init RF module
644 RFbInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400645
Joe Perches915006c2013-03-18 10:44:47 -0700646 //Get Desire Power Value
647 pDevice->byCurPwr = 0xFF;
648 pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
649 pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
650 //byCCKPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_CCK_PWR_dBm);
Forest Bond5449c682009-04-25 10:30:44 -0400651
Joe Perches915006c2013-03-18 10:44:47 -0700652 //byOFDMPwrdBm = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_OFDM_PWR_dBm);
Joe Perchesf2046f92013-03-18 20:55:36 -0700653
Forest Bond5449c682009-04-25 10:30:44 -0400654 // Load power Table
655
Joe Perches915006c2013-03-18 10:44:47 -0700656 for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
657 pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
658 if (pDevice->abyCCKPwrTbl[ii + 1] == 0) {
659 pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
660 }
661 pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
662 if (pDevice->abyOFDMPwrTbl[ii + 1] == 0) {
663 pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
664 }
665 pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
666 pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
667 }
Forest Bond5449c682009-04-25 10:30:44 -0400668 //2008-8-4 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -0700669 //recover 12,13 ,14channel for EUROPE by 11 channel
670 if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
671 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
672 (pDevice->byOriginalZonetype == ZoneType_USA)) {
673 for (ii = 11; ii < 14; ii++) {
674 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
675 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
Forest Bond5449c682009-04-25 10:30:44 -0400676
Joe Perches915006c2013-03-18 10:44:47 -0700677 }
678 }
Forest Bond5449c682009-04-25 10:30:44 -0400679
Joe Perches915006c2013-03-18 10:44:47 -0700680 // Load OFDM A Power Table
681 for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
682 pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
683 pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
684 }
685 init_channel_table((void *)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400686
Joe Perches915006c2013-03-18 10:44:47 -0700687 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
688 MACvSelectPage1(pDevice->PortOffset);
689 VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
690 MACvSelectPage0(pDevice->PortOffset);
691 }
Forest Bond5449c682009-04-25 10:30:44 -0400692
Joe Perches915006c2013-03-18 10:44:47 -0700693 // use relative tx timeout and 802.11i D4
694 MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
Forest Bond5449c682009-04-25 10:30:44 -0400695
Joe Perches915006c2013-03-18 10:44:47 -0700696 // set performance parameter by registry
697 MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
698 MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
Forest Bond5449c682009-04-25 10:30:44 -0400699
Joe Perches915006c2013-03-18 10:44:47 -0700700 // reset TSF counter
701 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
702 // enable TSF counter
703 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
Forest Bond5449c682009-04-25 10:30:44 -0400704
Joe Perches915006c2013-03-18 10:44:47 -0700705 // initialize BBP registers
706 BBbVT3253Init(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400707
Joe Perches915006c2013-03-18 10:44:47 -0700708 if (pDevice->bUpdateBBVGA) {
709 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
710 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
711 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
712 }
Joe Perches915006c2013-03-18 10:44:47 -0700713 BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
714 BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
Forest Bond5449c682009-04-25 10:30:44 -0400715
Joe Perches915006c2013-03-18 10:44:47 -0700716 pDevice->byCurrentCh = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400717
Joe Perches915006c2013-03-18 10:44:47 -0700718 //pDevice->NetworkType = Ndis802_11Automode;
719 // Set BB and packet type at the same time.
720 // Set Short Slot Time, xIFS, and RSPINF.
721 if (pDevice->uConnectionRate == RATE_AUTO) {
722 pDevice->wCurrentRate = RATE_54M;
723 } else {
724 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
725 }
Forest Bond5449c682009-04-25 10:30:44 -0400726
Joe Perches915006c2013-03-18 10:44:47 -0700727 // default G Mode
728 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
729 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
Forest Bond5449c682009-04-25 10:30:44 -0400730
Joe Perches915006c2013-03-18 10:44:47 -0700731 pDevice->bRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400732
Joe Perches915006c2013-03-18 10:44:47 -0700733 pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
734 pDevice->bHWRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400735
Joe Perches915006c2013-03-18 10:44:47 -0700736 if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
737 // Get GPIO
738 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
Forest Bond5449c682009-04-25 10:30:44 -0400739//2008-4-14 <add> by chester for led issue
Joe Perches915006c2013-03-18 10:44:47 -0700740#ifdef FOR_LED_ON_NOTEBOOK
741 if (pDevice->byGPIO & GPIO0_DATA) { pDevice->bHWRadioOff = true; }
742 if (!(pDevice->byGPIO & GPIO0_DATA)) { pDevice->bHWRadioOff = false; }
Forest Bond5449c682009-04-25 10:30:44 -0400743
Joe Perches915006c2013-03-18 10:44:47 -0700744 }
745 if ((pDevice->bRadioControlOff == true)) {
746 CARDbRadioPowerOff(pDevice);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700747 } else CARDbRadioPowerOn(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400748#else
Joe Perches915006c2013-03-18 10:44:47 -0700749 if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
750 (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
751 pDevice->bHWRadioOff = true;
752 }
753 }
754 if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
755 CARDbRadioPowerOff(pDevice);
756 }
Forest Bond5449c682009-04-25 10:30:44 -0400757
758#endif
Joe Perches915006c2013-03-18 10:44:47 -0700759}
760pMgmt->eScanType = WMAC_SCAN_PASSIVE;
761// get Permanent network address
762SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
763DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n",
764 pDevice->abyCurrentNetAddr);
Forest Bond5449c682009-04-25 10:30:44 -0400765
Joe Perches915006c2013-03-18 10:44:47 -0700766// reset Tx pointer
767CARDvSafeResetRx(pDevice);
768// reset Rx pointer
769CARDvSafeResetTx(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400770
Joe Perches915006c2013-03-18 10:44:47 -0700771if (pDevice->byLocalID <= REV_ID_VT3253_A1) {
772 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
773}
Forest Bond5449c682009-04-25 10:30:44 -0400774
Joe Perches915006c2013-03-18 10:44:47 -0700775pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Forest Bond5449c682009-04-25 10:30:44 -0400776
Joe Perches915006c2013-03-18 10:44:47 -0700777// Turn On Rx DMA
778MACvReceive0(pDevice->PortOffset);
779MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400780
Joe Perches915006c2013-03-18 10:44:47 -0700781// start the adapter
782MACvStart(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400783
Joe Perches915006c2013-03-18 10:44:47 -0700784netif_stop_queue(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400785}
786
Charles Clément6b35b7b2010-05-07 12:30:19 -0700787static void device_init_diversity_timer(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -0700788 init_timer(&pDevice->TimerSQ3Tmax1);
789 pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
790 pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
791 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400792
Joe Perches915006c2013-03-18 10:44:47 -0700793 init_timer(&pDevice->TimerSQ3Tmax2);
794 pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
795 pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
796 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400797
Joe Perches915006c2013-03-18 10:44:47 -0700798 init_timer(&pDevice->TimerSQ3Tmax3);
799 pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
800 pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
801 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400802
Joe Perches915006c2013-03-18 10:44:47 -0700803 return;
Forest Bond5449c682009-04-25 10:30:44 -0400804}
805
Charles Clément7b6a0012010-08-01 17:15:50 +0200806static bool device_release_WPADEV(PSDevice pDevice)
Forest Bond5449c682009-04-25 10:30:44 -0400807{
Joe Perches915006c2013-03-18 10:44:47 -0700808 viawget_wpa_header *wpahdr;
809 int ii = 0;
810 // wait_queue_head_t Set_wait;
811 //send device close to wpa_supplicnat layer
812 if (pDevice->bWPADEVUp == true) {
813 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
814 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
815 wpahdr->resp_ie_len = 0;
816 wpahdr->req_ie_len = 0;
817 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
818 pDevice->skb->dev = pDevice->wpadev;
819 skb_reset_mac_header(pDevice->skb);
820 pDevice->skb->pkt_type = PACKET_HOST;
821 pDevice->skb->protocol = htons(ETH_P_802_2);
822 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
823 netif_rx(pDevice->skb);
824 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Forest Bond5449c682009-04-25 10:30:44 -0400825
Joe Perches915006c2013-03-18 10:44:47 -0700826 //wait release WPADEV
827 // init_waitqueue_head(&Set_wait);
828 // wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ); //1s wait
829 while ((pDevice->bWPADEVUp == true)) {
830 set_current_state(TASK_UNINTERRUPTIBLE);
831 schedule_timeout(HZ / 20); //wait 50ms
832 ii++;
833 if (ii > 20)
834 break;
835 }
836 }
837 return true;
Forest Bond5449c682009-04-25 10:30:44 -0400838}
839
Forest Bond57211352009-06-02 14:44:33 -0400840static const struct net_device_ops device_netdev_ops = {
Devendra Naga502eb532012-09-07 00:08:04 +0530841 .ndo_open = device_open,
842 .ndo_stop = device_close,
843 .ndo_do_ioctl = device_ioctl,
844 .ndo_get_stats = device_get_stats,
845 .ndo_start_xmit = device_xmit,
846 .ndo_set_rx_mode = device_set_multi,
Forest Bond57211352009-06-02 14:44:33 -0400847};
848
Bill Pembertona1179b22012-11-19 13:21:54 -0500849static int
Charles Clément013a4682010-06-15 10:39:24 -0700850vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
Forest Bond5449c682009-04-25 10:30:44 -0400851{
Joe Perches915006c2013-03-18 10:44:47 -0700852 static bool bFirst = true;
853 struct net_device *dev = NULL;
854 PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data;
855 PSDevice pDevice;
856 int rc;
857 if (device_nics++ >= MAX_UINTS) {
858 printk(KERN_NOTICE DEVICE_NAME ": already found %d NICs\n", device_nics);
859 return -ENODEV;
860 }
Forest Bond5449c682009-04-25 10:30:44 -0400861
Joe Perches915006c2013-03-18 10:44:47 -0700862 dev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -0400863
Joe Perches915006c2013-03-18 10:44:47 -0700864 pDevice = (PSDevice) netdev_priv(dev);
Forest Bondc9d03522009-06-01 20:00:14 -0400865
Joe Perches915006c2013-03-18 10:44:47 -0700866 if (dev == NULL) {
867 printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
868 return -ENOMEM;
869 }
Forest Bond5449c682009-04-25 10:30:44 -0400870
Joe Perches915006c2013-03-18 10:44:47 -0700871 // Chain it all together
872 // SET_MODULE_OWNER(dev);
873 SET_NETDEV_DEV(dev, &pcid->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400874
Joe Perches915006c2013-03-18 10:44:47 -0700875 if (bFirst) {
876 printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
877 printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
878 bFirst = false;
879 }
Forest Bond5449c682009-04-25 10:30:44 -0400880
Joe Perches915006c2013-03-18 10:44:47 -0700881 vt6655_init_info(pcid, &pDevice, pChip_info);
882 pDevice->dev = dev;
883 pDevice->next_module = root_device_dev;
884 root_device_dev = dev;
Forest Bond5449c682009-04-25 10:30:44 -0400885
Joe Perches915006c2013-03-18 10:44:47 -0700886 if (pci_enable_device(pcid)) {
887 device_free_info(pDevice);
888 return -ENODEV;
889 }
890 dev->irq = pcid->irq;
Kulikov Vasiliy13b631a2010-08-03 19:44:20 +0400891
Forest Bond5449c682009-04-25 10:30:44 -0400892#ifdef DEBUG
Joe Perches915006c2013-03-18 10:44:47 -0700893 printk("Before get pci_info memaddr is %x\n", pDevice->memaddr);
Forest Bond5449c682009-04-25 10:30:44 -0400894#endif
Joe Perches915006c2013-03-18 10:44:47 -0700895 if (device_get_pci_info(pDevice, pcid) == false) {
896 printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n");
897 device_free_info(pDevice);
898 return -ENODEV;
899 }
Forest Bond5449c682009-04-25 10:30:44 -0400900
901#if 1
902
903#ifdef DEBUG
904
905 //pci_read_config_byte(pcid, PCI_BASE_ADDRESS_0, &pDevice->byRevId);
Joe Perches915006c2013-03-18 10:44:47 -0700906 printk("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 -0400907 {
908 int i;
Joe Perches915006c2013-03-18 10:44:47 -0700909 u32 bar, len;
Forest Bond5449c682009-04-25 10:30:44 -0400910 u32 address[] = {
Joe Perches915006c2013-03-18 10:44:47 -0700911 PCI_BASE_ADDRESS_0,
912 PCI_BASE_ADDRESS_1,
913 PCI_BASE_ADDRESS_2,
914 PCI_BASE_ADDRESS_3,
915 PCI_BASE_ADDRESS_4,
916 PCI_BASE_ADDRESS_5,
917 0};
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700918 for (i = 0; address[i]; i++) {
Forest Bond5449c682009-04-25 10:30:44 -0400919 //pci_write_config_dword(pcid,address[i], 0xFFFFFFFF);
920 pci_read_config_dword(pcid, address[i], &bar);
Joe Perches915006c2013-03-18 10:44:47 -0700921 printk("bar %d is %x\n", i, bar);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700922 if (!bar) {
Joe Perches915006c2013-03-18 10:44:47 -0700923 printk("bar %d not implemented\n", i);
Forest Bond5449c682009-04-25 10:30:44 -0400924 continue;
925 }
926 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
Joe Perches915006c2013-03-18 10:44:47 -0700927 /* This is IO */
Forest Bond5449c682009-04-25 10:30:44 -0400928
Joe Perches915006c2013-03-18 10:44:47 -0700929 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
930 len = len & ~(len - 1);
Forest Bond5449c682009-04-25 10:30:44 -0400931
Joe Perches915006c2013-03-18 10:44:47 -0700932 printk("IO space: len in IO %x, BAR %d\n", len, i);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700933 } else {
Forest Bond5449c682009-04-25 10:30:44 -0400934 len = bar & 0xFFFFFFF0;
935 len = ~len + 1;
936
937 printk("len in MEM %x, BAR %d\n", len, i);
938 }
939 }
940 }
941#endif
942
Forest Bond5449c682009-04-25 10:30:44 -0400943#endif
944
945#ifdef DEBUG
Joe Perches915006c2013-03-18 10:44:47 -0700946 //return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400947#endif
Joe Perches915006c2013-03-18 10:44:47 -0700948 pDevice->PortOffset = (unsigned long)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
Charles Clément0f4c60d2010-06-24 11:02:25 -0700949 //pDevice->PortOffset = (unsigned long)ioremap(pDevice->ioaddr & PCI_BASE_ADDRESS_IO_MASK, pDevice->io_size);
Forest Bond5449c682009-04-25 10:30:44 -0400950
Joe Perches915006c2013-03-18 10:44:47 -0700951 if (pDevice->PortOffset == 0) {
952 printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n");
953 device_free_info(pDevice);
954 return -ENODEV;
955 }
Forest Bond5449c682009-04-25 10:30:44 -0400956
Joe Perches915006c2013-03-18 10:44:47 -0700957 rc = pci_request_regions(pcid, DEVICE_NAME);
958 if (rc) {
959 printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n");
960 device_free_info(pDevice);
961 return -ENODEV;
962 }
Forest Bond5449c682009-04-25 10:30:44 -0400963
Joe Perches915006c2013-03-18 10:44:47 -0700964 dev->base_addr = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400965#ifdef PLICE_DEBUG
Joe Perches915006c2013-03-18 10:44:47 -0700966 unsigned char value;
Forest Bond5449c682009-04-25 10:30:44 -0400967
968 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Joe Perches915006c2013-03-18 10:44:47 -0700969 printk("Before write: value is %x\n", value);
Forest Bond5449c682009-04-25 10:30:44 -0400970 //VNSvInPortB(pDevice->PortOffset+0x3F, 0x00);
Joe Perches915006c2013-03-18 10:44:47 -0700971 VNSvOutPortB(pDevice->PortOffset, value);
Forest Bond5449c682009-04-25 10:30:44 -0400972 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Joe Perches915006c2013-03-18 10:44:47 -0700973 printk("After write: value is %x\n", value);
Forest Bond5449c682009-04-25 10:30:44 -0400974#endif
975
Forest Bond5449c682009-04-25 10:30:44 -0400976#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -0700977 pDevice->PortOffset = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400978#endif
Joe Perches915006c2013-03-18 10:44:47 -0700979 // do reset
980 if (!MACbSoftwareReset(pDevice->PortOffset)) {
981 printk(KERN_ERR DEVICE_NAME ": Failed to access MAC hardware..\n");
982 device_free_info(pDevice);
983 return -ENODEV;
984 }
985 // initial to reload eeprom
986 MACvInitialize(pDevice->PortOffset);
987 MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -0400988
Joe Perches915006c2013-03-18 10:44:47 -0700989 device_get_options(pDevice, device_nics-1, dev->name);
990 device_set_options(pDevice);
991 //Mask out the options cannot be set to the chip
992 pDevice->sOpts.flags &= pChip_info->flags;
Forest Bond5449c682009-04-25 10:30:44 -0400993
Joe Perches915006c2013-03-18 10:44:47 -0700994 //Enable the chip specified capabilities
995 pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL);
996 pDevice->tx_80211 = device_dma0_tx_80211;
997 pDevice->sMgmtObj.pAdapter = (void *)pDevice;
998 pDevice->pMgmt = &(pDevice->sMgmtObj);
Forest Bond5449c682009-04-25 10:30:44 -0400999
Joe Perches915006c2013-03-18 10:44:47 -07001000 dev->irq = pcid->irq;
1001 dev->netdev_ops = &device_netdev_ops;
Forest Bond5449c682009-04-25 10:30:44 -04001002
Forest Bond5449c682009-04-25 10:30:44 -04001003 dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
Forest Bond5449c682009-04-25 10:30:44 -04001004
Joe Perches915006c2013-03-18 10:44:47 -07001005 rc = register_netdev(dev);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001006 if (rc) {
Joe Perches915006c2013-03-18 10:44:47 -07001007 printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
1008 device_free_info(pDevice);
1009 return -ENODEV;
1010 }
1011 device_print_info(pDevice);
1012 pci_set_drvdata(pcid, pDevice);
1013 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001014}
1015
1016static void device_print_info(PSDevice pDevice)
1017{
Joe Perches915006c2013-03-18 10:44:47 -07001018 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001019
Joe Perches915006c2013-03-18 10:44:47 -07001020 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id));
1021 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -04001022#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -07001023 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx ", (unsigned long)pDevice->ioaddr);
1024 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -04001025#else
Joe Perches915006c2013-03-18 10:44:47 -07001026 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ",
1027 (unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset);
1028 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -04001029#endif
Forest Bond5449c682009-04-25 10:30:44 -04001030}
1031
Joe Perches915006c2013-03-18 10:44:47 -07001032static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice,
1033 PCHIP_INFO pChip_info) {
Joe Perches915006c2013-03-18 10:44:47 -07001034 PSDevice p;
Forest Bond5449c682009-04-25 10:30:44 -04001035
Joe Perches915006c2013-03-18 10:44:47 -07001036 memset(*ppDevice, 0, sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -04001037
Joe Perches915006c2013-03-18 10:44:47 -07001038 if (pDevice_Infos == NULL) {
1039 pDevice_Infos = *ppDevice;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001040 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001041 for (p = pDevice_Infos; p->next != NULL; p = p->next)
1042 do {} while (0);
1043 p->next = *ppDevice;
1044 (*ppDevice)->prev = p;
1045 }
Forest Bond5449c682009-04-25 10:30:44 -04001046
Joe Perches915006c2013-03-18 10:44:47 -07001047 (*ppDevice)->pcid = pcid;
1048 (*ppDevice)->chip_id = pChip_info->chip_id;
1049 (*ppDevice)->io_size = pChip_info->io_size;
1050 (*ppDevice)->nTxQueues = pChip_info->nTxQueue;
1051 (*ppDevice)->multicast_limit = 32;
Forest Bond5449c682009-04-25 10:30:44 -04001052
Joe Perches915006c2013-03-18 10:44:47 -07001053 spin_lock_init(&((*ppDevice)->lock));
Forest Bond5449c682009-04-25 10:30:44 -04001054}
1055
Joe Perches915006c2013-03-18 10:44:47 -07001056static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) {
Joe Perches915006c2013-03-18 10:44:47 -07001057 u16 pci_cmd;
1058 u8 b;
1059 unsigned int cis_addr;
Forest Bond5449c682009-04-25 10:30:44 -04001060#ifdef PLICE_DEBUG
Charles Clément3fc9b582010-06-24 11:02:27 -07001061 unsigned char pci_config[256];
Joe Perches915006c2013-03-18 10:44:47 -07001062 unsigned char value = 0x00;
1063 int ii, j;
1064 u16 max_lat = 0x0000;
1065 memset(pci_config, 0x00, 256);
Forest Bond5449c682009-04-25 10:30:44 -04001066#endif
1067
Joe Perches915006c2013-03-18 10:44:47 -07001068 pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId);
1069 pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pDevice->SubSystemID);
1070 pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID);
1071 pci_read_config_word(pcid, PCI_COMMAND, (u16 *)&(pci_cmd));
Forest Bond5449c682009-04-25 10:30:44 -04001072
Joe Perches915006c2013-03-18 10:44:47 -07001073 pci_set_master(pcid);
Forest Bond5449c682009-04-25 10:30:44 -04001074
Joe Perches915006c2013-03-18 10:44:47 -07001075 pDevice->memaddr = pci_resource_start(pcid, 0);
1076 pDevice->ioaddr = pci_resource_start(pcid, 1);
Forest Bond5449c682009-04-25 10:30:44 -04001077
1078#ifdef DEBUG
1079// pDevice->ioaddr = pci_resource_start(pcid, 0);
1080// pDevice->memaddr = pci_resource_start(pcid,1);
1081#endif
1082
Joe Perches915006c2013-03-18 10:44:47 -07001083 cis_addr = pci_resource_start(pcid, 2);
Forest Bond5449c682009-04-25 10:30:44 -04001084
Joe Perches915006c2013-03-18 10:44:47 -07001085 pDevice->pcid = pcid;
Forest Bond5449c682009-04-25 10:30:44 -04001086
Joe Perches915006c2013-03-18 10:44:47 -07001087 pci_read_config_byte(pcid, PCI_COMMAND, &b);
1088 pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER));
Forest Bond5449c682009-04-25 10:30:44 -04001089
1090#ifdef PLICE_DEBUG
Joe Perches915006c2013-03-18 10:44:47 -07001091 //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
Forest Bond5449c682009-04-25 10:30:44 -04001092 //for (ii=0;ii<0xFF;ii++)
Jim Lieb1e5743c2009-08-12 14:54:12 -07001093 //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
Forest Bond5449c682009-04-25 10:30:44 -04001094 //max_lat = 0x20;
Jim Lieb1e5743c2009-08-12 14:54:12 -07001095 //pci_write_config_word(pcid,PCI_MAX_LAT,max_lat);
1096 //pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
Forest Bond5449c682009-04-25 10:30:44 -04001097
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001098 for (ii = 0; ii < 0xFF; ii++) {
Joe Perches915006c2013-03-18 10:44:47 -07001099 pci_read_config_byte(pcid, ii, &value);
Forest Bond5449c682009-04-25 10:30:44 -04001100 pci_config[ii] = value;
1101 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001102 for (ii = 0, j = 1; ii < 0x100; ii++, j++) {
1103 if (j % 16 == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07001104 printk("%x:", pci_config[ii]);
Forest Bond5449c682009-04-25 10:30:44 -04001105 printk("\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001106 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001107 printk("%x:", pci_config[ii]);
Forest Bond5449c682009-04-25 10:30:44 -04001108 }
1109 }
1110#endif
Joe Perches915006c2013-03-18 10:44:47 -07001111 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001112}
1113
1114static void device_free_info(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001115 PSDevice ptr;
1116 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001117
Joe Perches915006c2013-03-18 10:44:47 -07001118 ASSERT(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001119//2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001120 device_release_WPADEV(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001121
1122//2008-07-21-01<Add>by MikeLiu
1123//unregister wpadev
Joe Perches915006c2013-03-18 10:44:47 -07001124 if (wpa_set_wpadev(pDevice, 0) != 0)
1125 printk("unregister wpadev fail?\n");
Forest Bond5449c682009-04-25 10:30:44 -04001126
Joe Perches915006c2013-03-18 10:44:47 -07001127 if (pDevice_Infos == NULL)
1128 return;
Forest Bond5449c682009-04-25 10:30:44 -04001129
Joe Perches915006c2013-03-18 10:44:47 -07001130 for (ptr = pDevice_Infos; ptr && (ptr != pDevice); ptr = ptr->next)
1131 do {} while (0);
Forest Bond5449c682009-04-25 10:30:44 -04001132
Joe Perches915006c2013-03-18 10:44:47 -07001133 if (ptr == pDevice) {
1134 if (ptr == pDevice_Infos)
1135 pDevice_Infos = ptr->next;
1136 else
1137 ptr->prev->next = ptr->next;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001138 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001139 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
1140 return;
1141 }
Forest Bond5449c682009-04-25 10:30:44 -04001142#ifdef HOSTAP
Joe Perches915006c2013-03-18 10:44:47 -07001143 if (dev)
1144 vt6655_hostap_set_hostapd(pDevice, 0, 0);
Forest Bond5449c682009-04-25 10:30:44 -04001145#endif
Joe Perches915006c2013-03-18 10:44:47 -07001146 if (dev)
1147 unregister_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001148
Joe Perches915006c2013-03-18 10:44:47 -07001149 if (pDevice->PortOffset)
1150 iounmap((void *)pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04001151
Joe Perches915006c2013-03-18 10:44:47 -07001152 if (pDevice->pcid)
1153 pci_release_regions(pDevice->pcid);
1154 if (dev)
1155 free_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001156
Joe Perches915006c2013-03-18 10:44:47 -07001157 if (pDevice->pcid) {
1158 pci_set_drvdata(pDevice->pcid, NULL);
1159 }
Forest Bond5449c682009-04-25 10:30:44 -04001160}
Forest Bond5449c682009-04-25 10:30:44 -04001161
Charles Clément7b6a0012010-08-01 17:15:50 +02001162static bool device_init_rings(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001163 void *vir_pool;
Forest Bond5449c682009-04-25 10:30:44 -04001164
Joe Perches915006c2013-03-18 10:44:47 -07001165 /*allocate all RD/TD rings a single pool*/
1166 vir_pool = pci_alloc_consistent(pDevice->pcid,
1167 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1168 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1169 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1170 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1171 &pDevice->pool_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001172
Joe Perches915006c2013-03-18 10:44:47 -07001173 if (vir_pool == NULL) {
1174 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
1175 return false;
1176 }
Forest Bond5449c682009-04-25 10:30:44 -04001177
Joe Perches915006c2013-03-18 10:44:47 -07001178 memset(vir_pool, 0,
1179 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1180 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1181 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1182 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1183 );
Forest Bond5449c682009-04-25 10:30:44 -04001184
Joe Perches915006c2013-03-18 10:44:47 -07001185 pDevice->aRD0Ring = vir_pool;
1186 pDevice->aRD1Ring = vir_pool +
1187 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001188
Joe Perches915006c2013-03-18 10:44:47 -07001189 pDevice->rd0_pool_dma = pDevice->pool_dma;
1190 pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
1191 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001192
Joe Perches915006c2013-03-18 10:44:47 -07001193 pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid,
1194 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1195 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1196 CB_BEACON_BUF_SIZE +
1197 CB_MAX_BUF_SIZE,
1198 &pDevice->tx_bufs_dma0);
Forest Bond5449c682009-04-25 10:30:44 -04001199
Joe Perches915006c2013-03-18 10:44:47 -07001200 if (pDevice->tx0_bufs == NULL) {
1201 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
1202 pci_free_consistent(pDevice->pcid,
1203 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1204 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1205 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1206 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1207 vir_pool, pDevice->pool_dma
1208 );
1209 return false;
1210 }
Forest Bond5449c682009-04-25 10:30:44 -04001211
Joe Perches915006c2013-03-18 10:44:47 -07001212 memset(pDevice->tx0_bufs, 0,
1213 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1214 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1215 CB_BEACON_BUF_SIZE +
1216 CB_MAX_BUF_SIZE
1217 );
Forest Bond5449c682009-04-25 10:30:44 -04001218
Joe Perches915006c2013-03-18 10:44:47 -07001219 pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
1220 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001221
Joe Perches915006c2013-03-18 10:44:47 -07001222 pDevice->td1_pool_dma = pDevice->td0_pool_dma +
1223 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001224
Joe Perches915006c2013-03-18 10:44:47 -07001225 // vir_pool: pvoid type
1226 pDevice->apTD0Rings = vir_pool
1227 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1228 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001229
Joe Perches915006c2013-03-18 10:44:47 -07001230 pDevice->apTD1Rings = vir_pool
1231 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1232 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
1233 + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001234
Joe Perches915006c2013-03-18 10:44:47 -07001235 pDevice->tx1_bufs = pDevice->tx0_bufs +
1236 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001237
Joe Perches915006c2013-03-18 10:44:47 -07001238 pDevice->tx_beacon_bufs = pDevice->tx1_bufs +
1239 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001240
Joe Perches915006c2013-03-18 10:44:47 -07001241 pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs +
1242 CB_BEACON_BUF_SIZE;
Forest Bond5449c682009-04-25 10:30:44 -04001243
Joe Perches915006c2013-03-18 10:44:47 -07001244 pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 +
1245 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001246
Joe Perches915006c2013-03-18 10:44:47 -07001247 pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 +
1248 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001249
Joe Perches915006c2013-03-18 10:44:47 -07001250 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001251}
1252
1253static void device_free_rings(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001254 pci_free_consistent(pDevice->pcid,
1255 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1256 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1257 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1258 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1259 ,
1260 pDevice->aRD0Ring, pDevice->pool_dma
1261 );
Forest Bond5449c682009-04-25 10:30:44 -04001262
Joe Perches915006c2013-03-18 10:44:47 -07001263 if (pDevice->tx0_bufs)
1264 pci_free_consistent(pDevice->pcid,
1265 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1266 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1267 CB_BEACON_BUF_SIZE +
1268 CB_MAX_BUF_SIZE,
1269 pDevice->tx0_bufs, pDevice->tx_bufs_dma0
1270 );
Forest Bond5449c682009-04-25 10:30:44 -04001271}
1272
1273static void device_init_rd0_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001274 int i;
1275 dma_addr_t curr = pDevice->rd0_pool_dma;
1276 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001277
Joe Perches915006c2013-03-18 10:44:47 -07001278 /* Init the RD0 ring entries */
1279 for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
1280 pDesc = &(pDevice->aRD0Ring[i]);
1281 pDesc->pRDInfo = alloc_rd_info();
1282 ASSERT(pDesc->pRDInfo);
1283 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1284 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1285 pDevice->dev->name);
1286 }
1287 pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
1288 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1289 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1290 }
Forest Bond5449c682009-04-25 10:30:44 -04001291
Joe Perches915006c2013-03-18 10:44:47 -07001292 if (i > 0)
1293 pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
1294 pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001295}
1296
Forest Bond5449c682009-04-25 10:30:44 -04001297static void device_init_rd1_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001298 int i;
1299 dma_addr_t curr = pDevice->rd1_pool_dma;
1300 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001301
Joe Perches915006c2013-03-18 10:44:47 -07001302 /* Init the RD1 ring entries */
1303 for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
1304 pDesc = &(pDevice->aRD1Ring[i]);
1305 pDesc->pRDInfo = alloc_rd_info();
1306 ASSERT(pDesc->pRDInfo);
1307 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1308 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1309 pDevice->dev->name);
1310 }
1311 pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
1312 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1313 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1314 }
Forest Bond5449c682009-04-25 10:30:44 -04001315
Joe Perches915006c2013-03-18 10:44:47 -07001316 if (i > 0)
1317 pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
1318 pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001319}
1320
Forest Bond5449c682009-04-25 10:30:44 -04001321static void device_init_defrag_cb(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001322 int i;
1323 PSDeFragControlBlock pDeF;
Forest Bond5449c682009-04-25 10:30:44 -04001324
Joe Perches915006c2013-03-18 10:44:47 -07001325 /* Init the fragment ctl entries */
1326 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1327 pDeF = &(pDevice->sRxDFCB[i]);
1328 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1329 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc frag bufs\n",
1330 pDevice->dev->name);
1331 }
1332 }
1333 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1334 pDevice->cbFreeDFCB = pDevice->cbDFCB;
Forest Bond5449c682009-04-25 10:30:44 -04001335}
1336
Forest Bond5449c682009-04-25 10:30:44 -04001337static void device_free_rd0_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001338 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001339
Joe Perches915006c2013-03-18 10:44:47 -07001340 for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
1341 PSRxDesc pDesc = &(pDevice->aRD0Ring[i]);
1342 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001343
Joe Perches915006c2013-03-18 10:44:47 -07001344 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1345 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001346
Joe Perches915006c2013-03-18 10:44:47 -07001347 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001348
Joe Perches915006c2013-03-18 10:44:47 -07001349 kfree((void *)pDesc->pRDInfo);
1350 }
Forest Bond5449c682009-04-25 10:30:44 -04001351}
1352
1353static void device_free_rd1_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001354 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001355
Joe Perches915006c2013-03-18 10:44:47 -07001356 for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
1357 PSRxDesc pDesc = &(pDevice->aRD1Ring[i]);
1358 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001359
Joe Perches915006c2013-03-18 10:44:47 -07001360 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1361 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001362
Joe Perches915006c2013-03-18 10:44:47 -07001363 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001364
Joe Perches915006c2013-03-18 10:44:47 -07001365 kfree((void *)pDesc->pRDInfo);
1366 }
Forest Bond5449c682009-04-25 10:30:44 -04001367}
1368
1369static void device_free_frag_buf(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001370 PSDeFragControlBlock pDeF;
1371 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001372
Joe Perches915006c2013-03-18 10:44:47 -07001373 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
Joe Perches915006c2013-03-18 10:44:47 -07001374 pDeF = &(pDevice->sRxDFCB[i]);
Forest Bond5449c682009-04-25 10:30:44 -04001375
Joe Perches915006c2013-03-18 10:44:47 -07001376 if (pDeF->skb)
1377 dev_kfree_skb(pDeF->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001378
Joe Perches915006c2013-03-18 10:44:47 -07001379 }
Forest Bond5449c682009-04-25 10:30:44 -04001380}
1381
1382static void device_init_td0_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001383 int i;
1384 dma_addr_t curr;
1385 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001386
Joe Perches915006c2013-03-18 10:44:47 -07001387 curr = pDevice->td0_pool_dma;
1388 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) {
1389 pDesc = &(pDevice->apTD0Rings[i]);
1390 pDesc->pTDInfo = alloc_td_info();
1391 ASSERT(pDesc->pTDInfo);
1392 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1393 pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ;
1394 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ;
1395 }
1396 pDesc->next = &(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]);
1397 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1398 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1399 }
Forest Bond5449c682009-04-25 10:30:44 -04001400
Joe Perches915006c2013-03-18 10:44:47 -07001401 if (i > 0)
1402 pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
1403 pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001404}
1405
1406static void device_init_td1_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001407 int i;
1408 dma_addr_t curr;
1409 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001410
Joe Perches915006c2013-03-18 10:44:47 -07001411 /* Init the TD ring entries */
1412 curr = pDevice->td1_pool_dma;
1413 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr += sizeof(STxDesc)) {
1414 pDesc = &(pDevice->apTD1Rings[i]);
1415 pDesc->pTDInfo = alloc_td_info();
1416 ASSERT(pDesc->pTDInfo);
1417 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1418 pDesc->pTDInfo->buf = pDevice->tx1_bufs + (i) * PKT_BUF_SZ;
1419 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma1 + (i) * PKT_BUF_SZ;
1420 }
1421 pDesc->next = &(pDevice->apTD1Rings[(i + 1) % pDevice->sOpts.nTxDescs[1]]);
1422 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1423 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1424 }
Forest Bond5449c682009-04-25 10:30:44 -04001425
Joe Perches915006c2013-03-18 10:44:47 -07001426 if (i > 0)
1427 pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
1428 pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001429}
1430
Forest Bond5449c682009-04-25 10:30:44 -04001431static void device_free_td0_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001432 int i;
1433 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
1434 PSTxDesc pDesc = &(pDevice->apTD0Rings[i]);
1435 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001436
Joe Perches915006c2013-03-18 10:44:47 -07001437 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1438 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1439 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001440
Joe Perches915006c2013-03-18 10:44:47 -07001441 if (pTDInfo->skb)
1442 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001443
Joe Perches915006c2013-03-18 10:44:47 -07001444 kfree((void *)pDesc->pTDInfo);
1445 }
Forest Bond5449c682009-04-25 10:30:44 -04001446}
1447
1448static void device_free_td1_ring(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -07001449 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001450
Joe Perches915006c2013-03-18 10:44:47 -07001451 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
1452 PSTxDesc pDesc = &(pDevice->apTD1Rings[i]);
1453 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001454
Joe Perches915006c2013-03-18 10:44:47 -07001455 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1456 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1457 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001458
Joe Perches915006c2013-03-18 10:44:47 -07001459 if (pTDInfo->skb)
1460 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001461
Joe Perches915006c2013-03-18 10:44:47 -07001462 kfree((void *)pDesc->pTDInfo);
1463 }
Forest Bond5449c682009-04-25 10:30:44 -04001464}
1465
Forest Bond5449c682009-04-25 10:30:44 -04001466/*-----------------------------------------------------------------*/
1467
Charles Clémentb6e95cd2010-06-02 09:52:01 -07001468static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) {
Joe Perches915006c2013-03-18 10:44:47 -07001469 PSRxDesc pRD;
1470 int works = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001471
Joe Perches915006c2013-03-18 10:44:47 -07001472 for (pRD = pDevice->pCurrRD[uIdx];
1473 pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
1474 pRD = pRD->next) {
Jim Lieb7e809a92009-07-30 10:27:21 -07001475// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->pCurrRD = %x, works = %d\n", pRD, works);
Joe Perches915006c2013-03-18 10:44:47 -07001476 if (works++ > 15)
1477 break;
1478 if (device_receive_frame(pDevice, pRD)) {
1479 if (!device_alloc_rx_buf(pDevice, pRD)) {
1480 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1481 "%s: can not allocate rx buf\n", pDevice->dev->name);
1482 break;
1483 }
1484 }
1485 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1486 pDevice->dev->last_rx = jiffies;
1487 }
Forest Bond5449c682009-04-25 10:30:44 -04001488
Joe Perches915006c2013-03-18 10:44:47 -07001489 pDevice->pCurrRD[uIdx] = pRD;
Forest Bond5449c682009-04-25 10:30:44 -04001490
Joe Perches915006c2013-03-18 10:44:47 -07001491 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001492}
1493
Charles Clément7b6a0012010-08-01 17:15:50 +02001494static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
Joe Perches915006c2013-03-18 10:44:47 -07001495 PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001496
Joe Perches915006c2013-03-18 10:44:47 -07001497 pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Joe Perches915006c2013-03-18 10:44:47 -07001498 if (pRDInfo->skb == NULL)
1499 return false;
1500 ASSERT(pRDInfo->skb);
1501 pRDInfo->skb->dev = pDevice->dev;
1502 pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
1503 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
1504 *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */
Forest Bond5449c682009-04-25 10:30:44 -04001505
Joe Perches915006c2013-03-18 10:44:47 -07001506 pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
1507 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1508 pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
1509 pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001510
Joe Perches915006c2013-03-18 10:44:47 -07001511 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001512}
1513
Charles Clément7b6a0012010-08-01 17:15:50 +02001514bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
Joe Perches915006c2013-03-18 10:44:47 -07001515 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1516 if (pDeF->skb == NULL)
1517 return false;
1518 ASSERT(pDeF->skb);
1519 pDeF->skb->dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001520
Joe Perches915006c2013-03-18 10:44:47 -07001521 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001522}
1523
Charles Clémentb6e95cd2010-06-02 09:52:01 -07001524static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
Joe Perches915006c2013-03-18 10:44:47 -07001525 PSTxDesc pTD;
1526 bool bFull = false;
1527 int works = 0;
1528 unsigned char byTsr0;
1529 unsigned char byTsr1;
1530 unsigned int uFrameSize, uFIFOHeaderSize;
1531 PSTxBufHead pTxBufHead;
1532 struct net_device_stats *pStats = &pDevice->stats;
1533 struct sk_buff *skb;
1534 unsigned int uNodeIndex;
1535 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04001536
Joe Perches915006c2013-03-18 10:44:47 -07001537 for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) {
Joe Perches915006c2013-03-18 10:44:47 -07001538 if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC)
1539 break;
1540 if (works++ > 15)
1541 break;
Forest Bond5449c682009-04-25 10:30:44 -04001542
Joe Perches915006c2013-03-18 10:44:47 -07001543 byTsr0 = pTD->m_td0TD0.byTSR0;
1544 byTsr1 = pTD->m_td0TD0.byTSR1;
Forest Bond5449c682009-04-25 10:30:44 -04001545
Joe Perches915006c2013-03-18 10:44:47 -07001546 //Only the status of first TD in the chain is correct
1547 if (pTD->m_td1TD1.byTCR & TCR_STP) {
Joe Perches915006c2013-03-18 10:44:47 -07001548 if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
1549 uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
1550 uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
1551 pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
1552 // Update the statistics based on the Transmit status
1553 // now, we DONT check TSR0_CDH
Forest Bond5449c682009-04-25 10:30:44 -04001554
Joe Perches915006c2013-03-18 10:44:47 -07001555 STAvUpdateTDStatCounter(&pDevice->scStatistic,
1556 byTsr0, byTsr1,
1557 (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize),
1558 uFrameSize, uIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001559
Joe Perches915006c2013-03-18 10:44:47 -07001560 BSSvUpdateNodeTxCounter(pDevice,
1561 byTsr0, byTsr1,
1562 (unsigned char *)(pTD->pTDInfo->buf),
1563 uFIFOHeaderSize
1564 );
Forest Bond5449c682009-04-25 10:30:44 -04001565
Joe Perches915006c2013-03-18 10:44:47 -07001566 if (!(byTsr1 & TSR1_TERR)) {
1567 if (byTsr0 != 0) {
1568 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
1569 (int)uIdx, byTsr1, byTsr0);
1570 }
1571 if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) {
1572 pDevice->s802_11Counter.TransmittedFragmentCount++;
1573 }
1574 pStats->tx_packets++;
1575 pStats->tx_bytes += pTD->pTDInfo->skb->len;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001576 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001577 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
1578 (int)uIdx, byTsr1, byTsr0);
1579 pStats->tx_errors++;
1580 pStats->tx_dropped++;
1581 }
1582 }
Forest Bond5449c682009-04-25 10:30:44 -04001583
Joe Perches915006c2013-03-18 10:44:47 -07001584 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1585 if (pDevice->bEnableHostapd) {
1586 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n");
1587 skb = pTD->pTDInfo->skb;
1588 skb->dev = pDevice->apdev;
1589 skb_reset_mac_header(skb);
1590 skb->pkt_type = PACKET_OTHERHOST;
1591 //skb->protocol = htons(ETH_P_802_2);
1592 memset(skb->cb, 0, sizeof(skb->cb));
1593 netif_rx(skb);
1594 }
1595 }
Forest Bond5449c682009-04-25 10:30:44 -04001596
Joe Perches915006c2013-03-18 10:44:47 -07001597 if (byTsr1 & TSR1_TERR) {
1598 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1599 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
1600 (int)uIdx, byTsr1, byTsr0);
1601 }
Forest Bond5449c682009-04-25 10:30:44 -04001602
Joe Perches915006c2013-03-18 10:44:47 -07001603// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
Charles Clément7ca30192010-06-01 12:38:56 -07001604// (int)uIdx, byTsr1, byTsr0);
Forest Bond5449c682009-04-25 10:30:44 -04001605
Joe Perches915006c2013-03-18 10:44:47 -07001606 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
1607 (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
1608 unsigned short wAID;
1609 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
Forest Bond5449c682009-04-25 10:30:44 -04001610
Joe Perches915006c2013-03-18 10:44:47 -07001611 skb = pTD->pTDInfo->skb;
1612 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1613 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1614 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1615 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1616 // set tx map
1617 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1618 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
1619 pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
1620 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
1621 , (int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
1622 pStats->tx_errors--;
1623 pStats->tx_dropped--;
1624 }
1625 }
1626 }
1627 }
1628 device_free_tx_buf(pDevice, pTD);
1629 pDevice->iTDUsed[uIdx]--;
1630 }
1631 }
Forest Bond5449c682009-04-25 10:30:44 -04001632
Joe Perches915006c2013-03-18 10:44:47 -07001633 if (uIdx == TYPE_AC0DMA) {
1634 // RESERV_AC0DMA reserved for relay
Forest Bond5449c682009-04-25 10:30:44 -04001635
Joe Perches915006c2013-03-18 10:44:47 -07001636 if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
1637 bFull = true;
1638 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
1639 }
1640 if (netif_queue_stopped(pDevice->dev) && (bFull == false)) {
1641 netif_wake_queue(pDevice->dev);
1642 }
1643 }
Forest Bond5449c682009-04-25 10:30:44 -04001644
Joe Perches915006c2013-03-18 10:44:47 -07001645 pDevice->apTailTD[uIdx] = pTD;
Forest Bond5449c682009-04-25 10:30:44 -04001646
Joe Perches915006c2013-03-18 10:44:47 -07001647 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001648}
1649
Charles Clément2986db52010-06-24 11:02:26 -07001650static void device_error(PSDevice pDevice, unsigned short status) {
Joe Perches915006c2013-03-18 10:44:47 -07001651 if (status & ISR_FETALERR) {
1652 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1653 "%s: Hardware fatal error.\n",
1654 pDevice->dev->name);
1655 netif_stop_queue(pDevice->dev);
1656 del_timer(&pDevice->sTimerCommand);
1657 del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
1658 pDevice->bCmdRunning = false;
1659 MACbShutdown(pDevice->PortOffset);
1660 return;
1661 }
Forest Bond5449c682009-04-25 10:30:44 -04001662}
1663
1664static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) {
Joe Perches915006c2013-03-18 10:44:47 -07001665 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
1666 struct sk_buff *skb = pTDInfo->skb;
Forest Bond5449c682009-04-25 10:30:44 -04001667
Joe Perches915006c2013-03-18 10:44:47 -07001668 // pre-allocated buf_dma can't be unmapped.
1669 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) {
1670 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len,
1671 PCI_DMA_TODEVICE);
1672 }
Forest Bond5449c682009-04-25 10:30:44 -04001673
Joe Perches915006c2013-03-18 10:44:47 -07001674 if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0)
1675 dev_kfree_skb_irq(skb);
Forest Bond5449c682009-04-25 10:30:44 -04001676
Joe Perches915006c2013-03-18 10:44:47 -07001677 pTDInfo->skb_dma = 0;
1678 pTDInfo->skb = 0;
1679 pTDInfo->byFlags = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001680}
1681
Forest Bond5449c682009-04-25 10:30:44 -04001682//PLICE_DEBUG ->
Charles Clément6b35b7b2010-05-07 12:30:19 -07001683void InitRxManagementQueue(PSDevice pDevice)
Forest Bond5449c682009-04-25 10:30:44 -04001684{
1685 pDevice->rxManeQueue.packet_num = 0;
1686 pDevice->rxManeQueue.head = pDevice->rxManeQueue.tail = 0;
1687}
1688//PLICE_DEBUG<-
1689
Forest Bond5449c682009-04-25 10:30:44 -04001690//PLICE_DEBUG ->
Charles Clément7ca30192010-06-01 12:38:56 -07001691int MlmeThread(
Joe Perches915006c2013-03-18 10:44:47 -07001692 void *Context)
Forest Bond5449c682009-04-25 10:30:44 -04001693{
1694 PSDevice pDevice = (PSDevice) Context;
1695 PSRxMgmtPacket pRxMgmtPacket;
Joe Perches915006c2013-03-18 10:44:47 -07001696 // int i;
Forest Bond5449c682009-04-25 10:30:44 -04001697 //complete(&pDevice->notify);
Forest Bond5449c682009-04-25 10:30:44 -04001698
Forest Bond5449c682009-04-25 10:30:44 -04001699 //i = 0;
1700#if 1
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001701 while (1) {
Joe Perches915006c2013-03-18 10:44:47 -07001702 //down(&pDevice->mlme_semaphore);
1703 // pRxMgmtPacket = DeQueue(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001704#if 1
1705 spin_lock_irq(&pDevice->lock);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001706 while (pDevice->rxManeQueue.packet_num != 0) {
Joe Perches915006c2013-03-18 10:44:47 -07001707 pRxMgmtPacket = DeQueue(pDevice);
1708 //pDevice;
1709 //DequeueManageObject(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
Forest Bond5449c682009-04-25 10:30:44 -04001710 vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
Joe Perches915006c2013-03-18 10:44:47 -07001711 }
Forest Bond5449c682009-04-25 10:30:44 -04001712 spin_unlock_irq(&pDevice->lock);
1713 if (mlme_kill == 0)
Joe Perches915006c2013-03-18 10:44:47 -07001714 break;
Forest Bond5449c682009-04-25 10:30:44 -04001715 //udelay(200);
1716#endif
Joe Perches915006c2013-03-18 10:44:47 -07001717 schedule();
Joe Perches915006c2013-03-18 10:44:47 -07001718 if (mlme_kill == 0)
1719 break;
Forest Bond5449c682009-04-25 10:30:44 -04001720 }
1721
1722#endif
1723 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001724}
1725
Forest Bond5449c682009-04-25 10:30:44 -04001726static int device_open(struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07001727 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1728 int i;
Jim Liebdb6cb902009-07-23 17:20:49 -07001729#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001730 extern SWPAResult wpa_Result;
Jim Liebdb6cb902009-07-23 17:20:49 -07001731#endif
1732
Joe Perches915006c2013-03-18 10:44:47 -07001733 pDevice->rx_buf_sz = PKT_BUF_SZ;
1734 if (!device_init_rings(pDevice)) {
1735 return -ENOMEM;
1736 }
Forest Bond5449c682009-04-25 10:30:44 -04001737//2008-5-13 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -07001738 i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
1739 if (i)
1740 return i;
Joe Perchesf2046f92013-03-18 20:55:36 -07001741
Forest Bond5449c682009-04-25 10:30:44 -04001742#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001743 memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
1744 wpa_Result.proto = 0;
1745 wpa_Result.key_mgmt = 0;
1746 wpa_Result.eap_type = 0;
1747 wpa_Result.authenticated = false;
1748 pDevice->fWPA_Authened = false;
Forest Bond5449c682009-04-25 10:30:44 -04001749#endif
Joe Perches915006c2013-03-18 10:44:47 -07001750 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
1751 device_init_rd0_ring(pDevice);
1752 device_init_rd1_ring(pDevice);
1753 device_init_defrag_cb(pDevice);
1754 device_init_td0_ring(pDevice);
1755 device_init_td1_ring(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001756// VNTWIFIvSet11h(pDevice->pMgmt, pDevice->b11hEnable);
1757
Joe Perches915006c2013-03-18 10:44:47 -07001758 if (pDevice->bDiversityRegCtlON) {
1759 device_init_diversity_timer(pDevice);
1760 }
1761 vMgrObjectInit(pDevice);
1762 vMgrTimerInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001763
1764//PLICE_DEBUG->
1765#ifdef TASK_LET
Joe Perches915006c2013-03-18 10:44:47 -07001766 tasklet_init(&pDevice->RxMngWorkItem, (void *)MngWorkItem, (unsigned long)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001767#endif
1768#ifdef THREAD
1769 InitRxManagementQueue(pDevice);
1770 mlme_kill = 0;
Joe Perches915006c2013-03-18 10:44:47 -07001771 mlme_task = kthread_run(MlmeThread, (void *)pDevice, "MLME");
Forest Bond5449c682009-04-25 10:30:44 -04001772 if (IS_ERR(mlme_task)) {
1773 printk("thread create fail\n");
1774 return -1;
1775 }
1776
1777 mlme_kill = 1;
1778#endif
1779
Forest Bond5449c682009-04-25 10:30:44 -04001780 //wait_for_completion(&pDevice->notify);
1781
Joe Perches915006c2013-03-18 10:44:47 -07001782 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
Forest Bond5449c682009-04-25 10:30:44 -04001783 device_init_registers(pDevice, DEVICE_INIT_COLD);
Joe Perches915006c2013-03-18 10:44:47 -07001784 MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
1785 memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1786 device_set_multi(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -04001787
Joe Perches915006c2013-03-18 10:44:47 -07001788 // Init for Key Management
1789 KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
1790 add_timer(&(pDevice->pMgmt->sTimerSecondCallback));
Forest Bond5449c682009-04-25 10:30:44 -04001791
Joe Perches915006c2013-03-18 10:44:47 -07001792#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond5449c682009-04-25 10:30:44 -04001793 /*
Joe Perches915006c2013-03-18 10:44:47 -07001794 pDevice->bwextstep0 = false;
1795 pDevice->bwextstep1 = false;
1796 pDevice->bwextstep2 = false;
1797 pDevice->bwextstep3 = false;
1798 */
1799 pDevice->bwextcount = 0;
1800 pDevice->bWPASuppWextEnabled = false;
Forest Bond5449c682009-04-25 10:30:44 -04001801#endif
Joe Perches915006c2013-03-18 10:44:47 -07001802 pDevice->byReAssocCount = 0;
1803 pDevice->bWPADEVUp = false;
1804 // Patch: if WEP key already set by iwconfig but device not yet open
1805 if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) {
1806 KeybSetDefaultKey(&(pDevice->sKey),
1807 (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
1808 pDevice->uKeyLength,
1809 NULL,
1810 pDevice->abyKey,
1811 KEY_CTL_WEP,
1812 pDevice->PortOffset,
1813 pDevice->byLocalID
1814 );
1815 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1816 }
Forest Bond5449c682009-04-25 10:30:44 -04001817
Joe Perches915006c2013-03-18 10:44:47 -07001818 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
Forest Bond5449c682009-04-25 10:30:44 -04001819 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
1820
Joe Perches915006c2013-03-18 10:44:47 -07001821 if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1822 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001823 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001824 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1825 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
1826 }
1827 pDevice->flags |= DEVICE_FLAGS_OPENED;
Forest Bond5449c682009-04-25 10:30:44 -04001828
Joe Perches915006c2013-03-18 10:44:47 -07001829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
1830 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001831}
1832
Forest Bond5449c682009-04-25 10:30:44 -04001833static int device_close(struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07001834 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1835 PSMgmtObject pMgmt = pDevice->pMgmt;
1836 //PLICE_DEBUG->
Forest Bond5449c682009-04-25 10:30:44 -04001837#ifdef THREAD
1838 mlme_kill = 0;
1839#endif
1840//PLICE_DEBUG<-
1841//2007-1121-02<Add>by EinsnLiu
Joe Perches915006c2013-03-18 10:44:47 -07001842 if (pDevice->bLinkPass) {
1843 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
1844 mdelay(30);
1845 }
Forest Bond5449c682009-04-25 10:30:44 -04001846#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07001847 del_timer(&pDevice->sTimerTxData);
Forest Bond5449c682009-04-25 10:30:44 -04001848#endif
Joe Perches915006c2013-03-18 10:44:47 -07001849 del_timer(&pDevice->sTimerCommand);
1850 del_timer(&pMgmt->sTimerSecondCallback);
1851 if (pDevice->bDiversityRegCtlON) {
1852 del_timer(&pDevice->TimerSQ3Tmax1);
1853 del_timer(&pDevice->TimerSQ3Tmax2);
1854 del_timer(&pDevice->TimerSQ3Tmax3);
1855 }
Forest Bond5449c682009-04-25 10:30:44 -04001856
1857#ifdef TASK_LET
1858 tasklet_kill(&pDevice->RxMngWorkItem);
1859#endif
Joe Perches915006c2013-03-18 10:44:47 -07001860 netif_stop_queue(dev);
1861 pDevice->bCmdRunning = false;
1862 MACbShutdown(pDevice->PortOffset);
1863 MACbSoftwareReset(pDevice->PortOffset);
1864 CARDbRadioPowerOff(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001865
Joe Perches915006c2013-03-18 10:44:47 -07001866 pDevice->bLinkPass = false;
1867 memset(pMgmt->abyCurrBSSID, 0, 6);
1868 pMgmt->eCurrState = WMAC_STATE_IDLE;
1869 device_free_td0_ring(pDevice);
1870 device_free_td1_ring(pDevice);
1871 device_free_rd0_ring(pDevice);
1872 device_free_rd1_ring(pDevice);
1873 device_free_frag_buf(pDevice);
1874 device_free_rings(pDevice);
1875 BSSvClearNodeDBTable(pDevice, 0);
1876 free_irq(dev->irq, dev);
1877 pDevice->flags &= (~DEVICE_FLAGS_OPENED);
Forest Bond5449c682009-04-25 10:30:44 -04001878 //2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001879 device_release_WPADEV(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001880//PLICE_DEBUG->
1881 //tasklet_kill(&pDevice->RxMngWorkItem);
1882//PLICE_DEBUG<-
Joe Perches915006c2013-03-18 10:44:47 -07001883 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n");
1884 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001885}
1886
Forest Bond5449c682009-04-25 10:30:44 -04001887static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07001888 PSDevice pDevice = netdev_priv(dev);
1889 unsigned char *pbMPDU;
1890 unsigned int cbMPDULen = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001891
Joe Perches915006c2013-03-18 10:44:47 -07001892 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
1893 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001894
Joe Perches915006c2013-03-18 10:44:47 -07001895 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1896 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
1897 dev_kfree_skb_irq(skb);
1898 spin_unlock_irq(&pDevice->lock);
1899 return 0;
1900 }
Forest Bond5449c682009-04-25 10:30:44 -04001901
Joe Perches915006c2013-03-18 10:44:47 -07001902 if (pDevice->bStopTx0Pkt == true) {
1903 dev_kfree_skb_irq(skb);
1904 spin_unlock_irq(&pDevice->lock);
1905 return 0;
1906 }
Forest Bond5449c682009-04-25 10:30:44 -04001907
Joe Perches915006c2013-03-18 10:44:47 -07001908 cbMPDULen = skb->len;
1909 pbMPDU = skb->data;
Forest Bond5449c682009-04-25 10:30:44 -04001910
Joe Perches915006c2013-03-18 10:44:47 -07001911 vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
Forest Bond5449c682009-04-25 10:30:44 -04001912
Joe Perches915006c2013-03-18 10:44:47 -07001913 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001914
Joe Perches915006c2013-03-18 10:44:47 -07001915 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001916}
1917
Charles Clément7b6a0012010-08-01 17:15:50 +02001918bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex) {
Joe Perches915006c2013-03-18 10:44:47 -07001919 PSMgmtObject pMgmt = pDevice->pMgmt;
1920 PSTxDesc pHeadTD, pLastTD;
1921 unsigned int cbFrameBodySize;
1922 unsigned int uMACfragNum;
1923 unsigned char byPktType;
1924 bool bNeedEncryption = false;
1925 PSKeyItem pTransmitKey = NULL;
1926 unsigned int cbHeaderSize;
1927 unsigned int ii;
1928 SKeyItem STempKey;
Charles Clément3fc9b582010-06-24 11:02:27 -07001929// unsigned char byKeyIndex = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001930
Joe Perches915006c2013-03-18 10:44:47 -07001931 if (pDevice->bStopTx0Pkt == true) {
1932 dev_kfree_skb_irq(skb);
1933 return false;
1934 }
Forest Bond5449c682009-04-25 10:30:44 -04001935
Joe Perches915006c2013-03-18 10:44:47 -07001936 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1937 dev_kfree_skb_irq(skb);
1938 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
1939 return false;
1940 }
Forest Bond5449c682009-04-25 10:30:44 -04001941
Joe Perches915006c2013-03-18 10:44:47 -07001942 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1943 if (pDevice->uAssocCount == 0) {
1944 dev_kfree_skb_irq(skb);
1945 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
1946 return false;
1947 }
1948 }
Forest Bond5449c682009-04-25 10:30:44 -04001949
Joe Perches915006c2013-03-18 10:44:47 -07001950 pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
Forest Bond5449c682009-04-25 10:30:44 -04001951
Joe Perches915006c2013-03-18 10:44:47 -07001952 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04001953
Joe Perches915006c2013-03-18 10:44:47 -07001954 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
1955 cbFrameBodySize = skb->len - ETH_HLEN;
Forest Bond5449c682009-04-25 10:30:44 -04001956
Joe Perches915006c2013-03-18 10:44:47 -07001957 // 802.1H
1958 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) {
1959 cbFrameBodySize += 8;
1960 }
1961 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04001962
Joe Perches915006c2013-03-18 10:44:47 -07001963 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
1964 dev_kfree_skb_irq(skb);
1965 return false;
1966 }
1967 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04001968
Joe Perches915006c2013-03-18 10:44:47 -07001969 if (pDevice->bFixRate) {
1970 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
1971 if (pDevice->uConnectionRate >= RATE_11M) {
1972 pDevice->wCurrentRate = RATE_11M;
1973 } else {
1974 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1975 }
1976 } else {
1977 if (pDevice->uConnectionRate >= RATE_54M)
1978 pDevice->wCurrentRate = RATE_54M;
1979 else
1980 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1981 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001982 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001983 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
1984 }
Forest Bond5449c682009-04-25 10:30:44 -04001985
Joe Perches915006c2013-03-18 10:44:47 -07001986 //preamble type
1987 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
1988 pDevice->byPreambleType = pDevice->byShortPreamble;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001989 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001990 pDevice->byPreambleType = PREAMBLE_LONG;
1991 }
Forest Bond5449c682009-04-25 10:30:44 -04001992
Joe Perches915006c2013-03-18 10:44:47 -07001993 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001994
Joe Perches915006c2013-03-18 10:44:47 -07001995 if (pDevice->wCurrentRate <= RATE_11M) {
1996 byPktType = PK_TYPE_11B;
1997 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1998 byPktType = PK_TYPE_11A;
1999 } else {
2000 if (pDevice->bProtectMode == true) {
2001 byPktType = PK_TYPE_11GB;
2002 } else {
2003 byPktType = PK_TYPE_11GA;
2004 }
2005 }
Forest Bond5449c682009-04-25 10:30:44 -04002006
Joe Perches915006c2013-03-18 10:44:47 -07002007 if (pDevice->bEncryptionEnable == true)
2008 bNeedEncryption = true;
Forest Bond5449c682009-04-25 10:30:44 -04002009
Joe Perches915006c2013-03-18 10:44:47 -07002010 if (pDevice->bEnableHostWEP) {
2011 pTransmitKey = &STempKey;
2012 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2013 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2014 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2015 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2016 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2017 memcpy(pTransmitKey->abyKey,
2018 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2019 pTransmitKey->uKeyLength
2020 );
2021 }
2022 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
2023 cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
2024 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
2025 &uMACfragNum,
2026 &cbHeaderSize
2027 );
Forest Bond5449c682009-04-25 10:30:44 -04002028
Joe Perches915006c2013-03-18 10:44:47 -07002029 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2030 // Disable PS
2031 MACbPSWakeup(pDevice->PortOffset);
2032 }
Forest Bond5449c682009-04-25 10:30:44 -04002033
Joe Perches915006c2013-03-18 10:44:47 -07002034 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002035
Joe Perches915006c2013-03-18 10:44:47 -07002036 pLastTD = pHeadTD;
2037 for (ii = 0; ii < uMACfragNum; ii++) {
2038 // Poll Transmit the adapter
2039 wmb();
2040 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2041 wmb();
2042 if (ii == (uMACfragNum - 1))
2043 pLastTD = pHeadTD;
2044 pHeadTD = pHeadTD->next;
2045 }
Forest Bond5449c682009-04-25 10:30:44 -04002046
Joe Perches915006c2013-03-18 10:44:47 -07002047 // Save the information needed by the tx interrupt handler
2048 // to complete the Send request
2049 pLastTD->pTDInfo->skb = skb;
2050 pLastTD->pTDInfo->byFlags = 0;
2051 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04002052
Joe Perches915006c2013-03-18 10:44:47 -07002053 pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04002054
Joe Perches915006c2013-03-18 10:44:47 -07002055 MACvTransmit0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002056
Joe Perches915006c2013-03-18 10:44:47 -07002057 return true;
Forest Bond5449c682009-04-25 10:30:44 -04002058}
2059
2060//TYPE_AC0DMA data tx
Forest Bond5449c682009-04-25 10:30:44 -04002061static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07002062 PSDevice pDevice = netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002063
Joe Perches915006c2013-03-18 10:44:47 -07002064 PSMgmtObject pMgmt = pDevice->pMgmt;
2065 PSTxDesc pHeadTD, pLastTD;
2066 unsigned int uNodeIndex = 0;
2067 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2068 unsigned short wAID;
2069 unsigned int uMACfragNum = 1;
2070 unsigned int cbFrameBodySize;
2071 unsigned char byPktType;
2072 unsigned int cbHeaderSize;
2073 bool bNeedEncryption = false;
2074 PSKeyItem pTransmitKey = NULL;
2075 SKeyItem STempKey;
2076 unsigned int ii;
2077 bool bTKIP_UseGTK = false;
2078 bool bNeedDeAuth = false;
2079 unsigned char *pbyBSSID;
2080 bool bNodeExist = false;
Forest Bond5449c682009-04-25 10:30:44 -04002081
Joe Perches915006c2013-03-18 10:44:47 -07002082 spin_lock_irq(&pDevice->lock);
2083 if (pDevice->bLinkPass == false) {
2084 dev_kfree_skb_irq(skb);
2085 spin_unlock_irq(&pDevice->lock);
2086 return 0;
2087 }
Forest Bond5449c682009-04-25 10:30:44 -04002088
Joe Perches915006c2013-03-18 10:44:47 -07002089 if (pDevice->bStopDataPkt) {
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 (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2096 if (pDevice->uAssocCount == 0) {
2097 dev_kfree_skb_irq(skb);
2098 spin_unlock_irq(&pDevice->lock);
2099 return 0;
2100 }
2101 if (is_multicast_ether_addr((unsigned char *)(skb->data))) {
2102 uNodeIndex = 0;
2103 bNodeExist = true;
2104 if (pMgmt->sNodeDBTable[0].bPSEnable) {
2105 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
2106 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
2107 // set tx map
2108 pMgmt->abyPSTxMap[0] |= byMask[0];
2109 spin_unlock_irq(&pDevice->lock);
2110 return 0;
2111 }
2112 } else {
2113 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
2114 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
2115 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
2116 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
2117 // set tx map
2118 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
2119 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
2120 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
2121 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
2122 spin_unlock_irq(&pDevice->lock);
2123 return 0;
2124 }
Forest Bond5449c682009-04-25 10:30:44 -04002125
Joe Perches915006c2013-03-18 10:44:47 -07002126 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
2127 pDevice->byPreambleType = pDevice->byShortPreamble;
Forest Bond5449c682009-04-25 10:30:44 -04002128
Joe Perches915006c2013-03-18 10:44:47 -07002129 } else {
2130 pDevice->byPreambleType = PREAMBLE_LONG;
2131 }
2132 bNodeExist = true;
Forest Bond5449c682009-04-25 10:30:44 -04002133
Joe Perches915006c2013-03-18 10:44:47 -07002134 }
2135 }
Forest Bond5449c682009-04-25 10:30:44 -04002136
Joe Perches915006c2013-03-18 10:44:47 -07002137 if (bNodeExist == false) {
2138 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB \n");
2139 dev_kfree_skb_irq(skb);
2140 spin_unlock_irq(&pDevice->lock);
2141 return 0;
2142 }
2143 }
Forest Bond5449c682009-04-25 10:30:44 -04002144
Joe Perches915006c2013-03-18 10:44:47 -07002145 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
Forest Bond5449c682009-04-25 10:30:44 -04002146
Joe Perches915006c2013-03-18 10:44:47 -07002147 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04002148
Joe Perches915006c2013-03-18 10:44:47 -07002149 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
2150 cbFrameBodySize = skb->len - ETH_HLEN;
2151 // 802.1H
2152 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) {
2153 cbFrameBodySize += 8;
2154 }
Forest Bond5449c682009-04-25 10:30:44 -04002155
Joe Perches915006c2013-03-18 10:44:47 -07002156 if (pDevice->bEncryptionEnable == true) {
2157 bNeedEncryption = true;
2158 // get Transmit key
2159 do {
2160 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2161 (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2162 pbyBSSID = pDevice->abyBSSID;
2163 // get pairwise key
2164 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
2165 // get group key
2166 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2167 bTKIP_UseGTK = true;
2168 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2169 break;
2170 }
2171 } else {
2172 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get PTK.\n");
2173 break;
2174 }
2175 } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Joe Perches915006c2013-03-18 10:44:47 -07002176 pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
2177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key: \n");
2178 for (ii = 0; ii < 6; ii++)
2179 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x \n", *(pbyBSSID+ii));
2180 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n");
Forest Bond5449c682009-04-25 10:30:44 -04002181
Joe Perches915006c2013-03-18 10:44:47 -07002182 // get pairwise key
2183 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
2184 break;
2185 }
2186 // get group key
2187 pbyBSSID = pDevice->abyBroadcastAddr;
2188 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
2189 pTransmitKey = NULL;
2190 if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2191 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002192 } else
Joe Perches915006c2013-03-18 10:44:47 -07002193 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
2194 } else {
2195 bTKIP_UseGTK = true;
2196 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2197 }
2198 } while (false);
2199 }
Forest Bond5449c682009-04-25 10:30:44 -04002200
Joe Perches915006c2013-03-18 10:44:47 -07002201 if (pDevice->bEnableHostWEP) {
2202 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex);
2203 if (pDevice->bEncryptionEnable == true) {
2204 pTransmitKey = &STempKey;
2205 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2206 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2207 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2208 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2209 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2210 memcpy(pTransmitKey->abyKey,
2211 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2212 pTransmitKey->uKeyLength
2213 );
2214 }
2215 }
Forest Bond5449c682009-04-25 10:30:44 -04002216
Joe Perches915006c2013-03-18 10:44:47 -07002217 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04002218
Joe Perches915006c2013-03-18 10:44:47 -07002219 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
2220 DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
2221 dev_kfree_skb_irq(skb);
2222 spin_unlock_irq(&pDevice->lock);
2223 return 0;
2224 }
Forest Bond5449c682009-04-25 10:30:44 -04002225
Joe Perches915006c2013-03-18 10:44:47 -07002226 if (pTransmitKey != NULL) {
2227 if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) &&
2228 (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) {
2229 uMACfragNum = 1; //WEP256 doesn't support fragment
2230 }
2231 }
Forest Bond5449c682009-04-25 10:30:44 -04002232
Joe Perches915006c2013-03-18 10:44:47 -07002233 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04002234
Joe Perches915006c2013-03-18 10:44:47 -07002235 if (pDevice->bFixRate) {
Forest Bond5449c682009-04-25 10:30:44 -04002236#ifdef PLICE_DEBUG
Joe Perches915006c2013-03-18 10:44:47 -07002237 printk("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate);
Forest Bond5449c682009-04-25 10:30:44 -04002238#endif
2239
Joe Perches915006c2013-03-18 10:44:47 -07002240 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
2241 if (pDevice->uConnectionRate >= RATE_11M) {
2242 pDevice->wCurrentRate = RATE_11M;
2243 } else {
2244 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
2245 }
2246 } else {
2247 if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
2248 (pDevice->uConnectionRate <= RATE_6M)) {
2249 pDevice->wCurrentRate = RATE_6M;
2250 } else {
2251 if (pDevice->uConnectionRate >= RATE_54M)
2252 pDevice->wCurrentRate = RATE_54M;
2253 else
2254 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Forest Bond5449c682009-04-25 10:30:44 -04002255
Joe Perches915006c2013-03-18 10:44:47 -07002256 }
2257 }
2258 pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate;
2259 pDevice->byTopCCKBasicRate = RATE_1M;
2260 pDevice->byTopOFDMBasicRate = RATE_6M;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002261 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002262 //auto rate
2263 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2264 if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
2265 pDevice->wCurrentRate = RATE_1M;
2266 pDevice->byACKRate = RATE_1M;
2267 pDevice->byTopCCKBasicRate = RATE_1M;
2268 pDevice->byTopOFDMBasicRate = RATE_6M;
2269 } else {
2270 pDevice->wCurrentRate = RATE_6M;
2271 pDevice->byACKRate = RATE_6M;
2272 pDevice->byTopCCKBasicRate = RATE_1M;
2273 pDevice->byTopOFDMBasicRate = RATE_6M;
2274 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002275 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002276 VNTWIFIvGetTxRate(pDevice->pMgmt,
2277 pDevice->sTxEthHeader.abyDstAddr,
2278 &(pDevice->wCurrentRate),
2279 &(pDevice->byACKRate),
2280 &(pDevice->byTopCCKBasicRate),
2281 &(pDevice->byTopOFDMBasicRate));
Forest Bond5449c682009-04-25 10:30:44 -04002282
Forest Bond5449c682009-04-25 10:30:44 -04002283 }
Joe Perches915006c2013-03-18 10:44:47 -07002284 }
Forest Bond5449c682009-04-25 10:30:44 -04002285
Jim Lieb7e809a92009-07-30 10:27:21 -07002286// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04002287
Joe Perches915006c2013-03-18 10:44:47 -07002288 if (pDevice->wCurrentRate <= RATE_11M) {
2289 byPktType = PK_TYPE_11B;
2290 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2291 byPktType = PK_TYPE_11A;
2292 } else {
2293 if (pDevice->bProtectMode == true) {
2294 byPktType = PK_TYPE_11GB;
2295 } else {
2296 byPktType = PK_TYPE_11GA;
2297 }
2298 }
Forest Bond5449c682009-04-25 10:30:44 -04002299
2300//#ifdef PLICE_DEBUG
2301// printk("FIX RATE:CurrentRate is %d");
2302//#endif
2303
Joe Perches915006c2013-03-18 10:44:47 -07002304 if (bNeedEncryption == true) {
2305 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
2306 if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
2307 bNeedEncryption = false;
2308 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
2309 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2310 if (pTransmitKey == NULL) {
2311 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002312 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002313 if (bTKIP_UseGTK == true) {
2314 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002315 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002316 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2317 bNeedEncryption = true;
2318 }
2319 }
2320 }
Forest Bond5449c682009-04-25 10:30:44 -04002321
Joe Perches915006c2013-03-18 10:44:47 -07002322 if (pDevice->byCntMeasure == 2) {
2323 bNeedDeAuth = true;
2324 pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
2325 }
Forest Bond5449c682009-04-25 10:30:44 -04002326
Joe Perches915006c2013-03-18 10:44:47 -07002327 if (pDevice->bEnableHostWEP) {
2328 if ((uNodeIndex != 0) &&
2329 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
2330 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2331 bNeedEncryption = true;
2332 }
2333 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002334 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002335 if (pTransmitKey == NULL) {
2336 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return no tx key\n");
2337 dev_kfree_skb_irq(skb);
2338 spin_unlock_irq(&pDevice->lock);
2339 return 0;
2340 }
2341 }
2342 }
Forest Bond5449c682009-04-25 10:30:44 -04002343
Joe Perches915006c2013-03-18 10:44:47 -07002344 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
2345 cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
2346 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
2347 &uMACfragNum,
2348 &cbHeaderSize
2349 );
Forest Bond5449c682009-04-25 10:30:44 -04002350
Joe Perches915006c2013-03-18 10:44:47 -07002351 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2352 // Disable PS
2353 MACbPSWakeup(pDevice->PortOffset);
2354 }
2355 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002356
Joe Perches915006c2013-03-18 10:44:47 -07002357 pLastTD = pHeadTD;
2358 for (ii = 0; ii < uMACfragNum; ii++) {
2359 // Poll Transmit the adapter
2360 wmb();
2361 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2362 wmb();
2363 if (ii == uMACfragNum - 1)
2364 pLastTD = pHeadTD;
2365 pHeadTD = pHeadTD->next;
2366 }
Forest Bond5449c682009-04-25 10:30:44 -04002367
Joe Perches915006c2013-03-18 10:44:47 -07002368 // Save the information needed by the tx interrupt handler
2369 // to complete the Send request
2370 pLastTD->pTDInfo->skb = skb;
2371 pLastTD->pTDInfo->byFlags = 0;
2372 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04002373#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07002374 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
2375#endif
2376 if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) {
2377 netif_stop_queue(dev);
2378 }
Forest Bond5449c682009-04-25 10:30:44 -04002379
Joe Perches915006c2013-03-18 10:44:47 -07002380 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04002381//#ifdef PLICE_DEBUG
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002382 if (pDevice->bFixRate) {
Joe Perches915006c2013-03-18 10:44:47 -07002383 printk("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002384 } else {
Forest Bond5449c682009-04-25 10:30:44 -04002385 }
2386//#endif
2387
Joe Perches915006c2013-03-18 10:44:47 -07002388 {
2389 unsigned char Protocol_Version; //802.1x Authentication
2390 unsigned char Packet_Type; //802.1x Authentication
2391 unsigned char Descriptor_type;
2392 unsigned short Key_info;
2393 bool bTxeapol_key = false;
2394 Protocol_Version = skb->data[ETH_HLEN];
2395 Packet_Type = skb->data[ETH_HLEN+1];
2396 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2397 Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
2398 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2399 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2400 (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer
2401 bTxeapol_key = true;
2402 if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN
2403 if (!(Key_info & BIT3) && //group-key challenge
2404 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2405 pDevice->fWPA_Authened = true;
2406 if (Descriptor_type == 254)
2407 printk("WPA ");
2408 else
2409 printk("WPA2 ");
2410 printk("Authentication completed!!\n");
2411 }
2412 }
2413 }
2414 }
2415 }
Forest Bond5449c682009-04-25 10:30:44 -04002416
Joe Perches915006c2013-03-18 10:44:47 -07002417 MACvTransmitAC0(pDevice->PortOffset);
Jim Lieb7e809a92009-07-30 10:27:21 -07002418// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD);
Forest Bond5449c682009-04-25 10:30:44 -04002419
Joe Perches915006c2013-03-18 10:44:47 -07002420 dev->trans_start = jiffies;
Forest Bond5449c682009-04-25 10:30:44 -04002421
Joe Perches915006c2013-03-18 10:44:47 -07002422 spin_unlock_irq(&pDevice->lock);
2423 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04002424}
2425
Forest Bond5449c682009-04-25 10:30:44 -04002426static irqreturn_t device_intr(int irq, void *dev_instance) {
Joe Perches915006c2013-03-18 10:44:47 -07002427 struct net_device *dev = dev_instance;
2428 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002429
Joe Perches915006c2013-03-18 10:44:47 -07002430 int max_count = 0;
2431 unsigned long dwMIBCounter = 0;
2432 PSMgmtObject pMgmt = pDevice->pMgmt;
2433 unsigned char byOrgPageSel = 0;
2434 int handled = 0;
2435 unsigned char byData = 0;
2436 int ii = 0;
Charles Clément3fc9b582010-06-24 11:02:27 -07002437// unsigned char byRSSI;
Forest Bond5449c682009-04-25 10:30:44 -04002438
Joe Perches915006c2013-03-18 10:44:47 -07002439 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002440
Joe Perches915006c2013-03-18 10:44:47 -07002441 if (pDevice->dwIsr == 0)
2442 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002443
Joe Perches915006c2013-03-18 10:44:47 -07002444 if (pDevice->dwIsr == 0xffffffff) {
2445 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
2446 return IRQ_RETVAL(handled);
2447 }
2448 /*
2449 // 2008-05-21 <mark> by Richardtai, we can't read RSSI here, because no packet bound with RSSI
Forest Bond5449c682009-04-25 10:30:44 -04002450
Joe Perches915006c2013-03-18 10:44:47 -07002451 if ((pDevice->dwIsr & ISR_RXDMA0) &&
2452 (pDevice->byLocalID != REV_ID_VT3253_B0) &&
2453 (pDevice->bBSSIDFilter == true)) {
2454 // update RSSI
2455 //BBbReadEmbedded(pDevice->PortOffset, 0x3E, &byRSSI);
2456 //pDevice->uCurrRSSI = byRSSI;
2457 }
2458 */
Forest Bond5449c682009-04-25 10:30:44 -04002459
Joe Perches915006c2013-03-18 10:44:47 -07002460 handled = 1;
2461 MACvIntDisable(pDevice->PortOffset);
2462 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04002463
Joe Perches915006c2013-03-18 10:44:47 -07002464 //Make sure current page is 0
2465 VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
2466 if (byOrgPageSel == 1) {
2467 MACvSelectPage0(pDevice->PortOffset);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002468 } else
Joe Perches915006c2013-03-18 10:44:47 -07002469 byOrgPageSel = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002470
Joe Perches915006c2013-03-18 10:44:47 -07002471 MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
2472 // TBD....
2473 // Must do this after doing rx/tx, cause ISR bit is slow
2474 // than RD/TD write back
2475 // update ISR counter
2476 STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
2477 while (pDevice->dwIsr != 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002478 STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
2479 MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002480
Joe Perches915006c2013-03-18 10:44:47 -07002481 if (pDevice->dwIsr & ISR_FETALERR) {
2482 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n");
2483 VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
2484 VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
2485 device_error(pDevice, pDevice->dwIsr);
2486 }
Forest Bond5449c682009-04-25 10:30:44 -04002487
Joe Perches915006c2013-03-18 10:44:47 -07002488 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
Joe Perches915006c2013-03-18 10:44:47 -07002489 if (pDevice->dwIsr & ISR_MEASURESTART) {
2490 // 802.11h measure start
2491 pDevice->byOrgChannel = pDevice->byCurrentCh;
2492 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
2493 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR));
2494 MACvSelectPage1(pDevice->PortOffset);
2495 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0));
2496 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
2497 MACvSelectPage0(pDevice->PortOffset);
2498 //xxxx
2499 // WCMDbFlushCommandQueue(pDevice->pMgmt, true);
2500 if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel) == true) {
2501 pDevice->bMeasureInProgress = true;
2502 MACvSelectPage1(pDevice->PortOffset);
2503 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
2504 MACvSelectPage0(pDevice->PortOffset);
2505 pDevice->byBasicMap = 0;
2506 pDevice->byCCAFraction = 0;
2507 for (ii = 0; ii < 8; ii++) {
2508 pDevice->dwRPIs[ii] = 0;
2509 }
2510 } else {
2511 // can not measure because set channel fail
2512 // WCMDbResetCommandQueue(pDevice->pMgmt);
2513 // clear measure control
2514 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2515 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE);
2516 MACvSelectPage1(pDevice->PortOffset);
2517 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2518 MACvSelectPage0(pDevice->PortOffset);
2519 }
2520 }
2521 if (pDevice->dwIsr & ISR_MEASUREEND) {
2522 // 802.11h measure end
2523 pDevice->bMeasureInProgress = false;
2524 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
2525 MACvSelectPage1(pDevice->PortOffset);
2526 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
2527 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
2528 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData);
2529 pDevice->byBasicMap |= (byData >> 4);
2530 VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction);
2531 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData);
2532 // clear measure control
2533 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2534 MACvSelectPage0(pDevice->PortOffset);
2535 set_channel(pDevice, pDevice->byOrgChannel);
2536 // WCMDbResetCommandQueue(pDevice->pMgmt);
2537 MACvSelectPage1(pDevice->PortOffset);
2538 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2539 MACvSelectPage0(pDevice->PortOffset);
2540 if (byData & MSRCTL_FINISH) {
2541 // measure success
2542 s_vCompleteCurrentMeasure(pDevice, 0);
2543 } else {
2544 // can not measure because not ready before end of measure time
2545 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
2546 }
2547 }
2548 if (pDevice->dwIsr & ISR_QUIETSTART) {
2549 do {
2550 ;
2551 } while (CARDbStartQuiet(pDevice) == false);
2552 }
2553 }
Forest Bond5449c682009-04-25 10:30:44 -04002554
Joe Perches915006c2013-03-18 10:44:47 -07002555 if (pDevice->dwIsr & ISR_TBTT) {
2556 if (pDevice->bEnableFirstQuiet == true) {
2557 pDevice->byQuietStartCount--;
2558 if (pDevice->byQuietStartCount == 0) {
2559 pDevice->bEnableFirstQuiet = false;
2560 MACvSelectPage1(pDevice->PortOffset);
2561 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
2562 MACvSelectPage0(pDevice->PortOffset);
2563 }
2564 }
2565 if ((pDevice->bChannelSwitch == true) &&
2566 (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
2567 pDevice->byChannelSwitchCount--;
2568 if (pDevice->byChannelSwitchCount == 0) {
2569 pDevice->bChannelSwitch = false;
2570 set_channel(pDevice, pDevice->byNewChannel);
2571 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2572 MACvSelectPage1(pDevice->PortOffset);
2573 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2574 MACvSelectPage0(pDevice->PortOffset);
2575 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
Forest Bond5449c682009-04-25 10:30:44 -04002576
Joe Perches915006c2013-03-18 10:44:47 -07002577 }
2578 }
2579 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2580 //pDevice->bBeaconSent = false;
2581 } else {
2582 if ((pDevice->bUpdateBBVGA) && (pDevice->bLinkPass == true) && (pDevice->uCurrRSSI != 0)) {
2583 long ldBm;
Forest Bond5449c682009-04-25 10:30:44 -04002584
Joe Perches915006c2013-03-18 10:44:47 -07002585 RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
2586 for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
2587 if (ldBm < pDevice->ldBmThreshold[ii]) {
2588 pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
2589 break;
2590 }
2591 }
2592 if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
2593 pDevice->uBBVGADiffCount++;
2594 if (pDevice->uBBVGADiffCount == 1) {
2595 // first VGA diff gain
2596 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2597 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2598 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2599 }
2600 if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
2601 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2602 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2603 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2604 }
2605 } else {
2606 pDevice->uBBVGADiffCount = 1;
2607 }
2608 }
2609 }
Forest Bond5449c682009-04-25 10:30:44 -04002610
Joe Perches915006c2013-03-18 10:44:47 -07002611 pDevice->bBeaconSent = false;
2612 if (pDevice->bEnablePSMode) {
2613 PSbIsNextTBTTWakeUp((void *)pDevice);
2614 }
Forest Bond5449c682009-04-25 10:30:44 -04002615
Joe Perches915006c2013-03-18 10:44:47 -07002616 if ((pDevice->eOPMode == OP_MODE_AP) ||
2617 (pDevice->eOPMode == OP_MODE_ADHOC)) {
Joe Perches915006c2013-03-18 10:44:47 -07002618 MACvOneShotTimer1MicroSec(pDevice->PortOffset,
2619 (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10);
2620 }
Forest Bond5449c682009-04-25 10:30:44 -04002621
Joe Perches915006c2013-03-18 10:44:47 -07002622 if (pDevice->eOPMode == OP_MODE_ADHOC && pDevice->pMgmt->wCurrATIMWindow > 0) {
2623 // todo adhoc PS mode
2624 }
Forest Bond5449c682009-04-25 10:30:44 -04002625
Joe Perches915006c2013-03-18 10:44:47 -07002626 }
Forest Bond5449c682009-04-25 10:30:44 -04002627
Joe Perches915006c2013-03-18 10:44:47 -07002628 if (pDevice->dwIsr & ISR_BNTX) {
Joe Perches915006c2013-03-18 10:44:47 -07002629 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2630 pDevice->bIsBeaconBufReadySet = false;
2631 pDevice->cbBeaconBufReadySetCnt = 0;
2632 }
Forest Bond5449c682009-04-25 10:30:44 -04002633
Joe Perches915006c2013-03-18 10:44:47 -07002634 if (pDevice->eOPMode == OP_MODE_AP) {
2635 if (pMgmt->byDTIMCount > 0) {
2636 pMgmt->byDTIMCount--;
2637 pMgmt->sNodeDBTable[0].bRxPSPoll = false;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002638 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002639 if (pMgmt->byDTIMCount == 0) {
2640 // check if mutltcast tx bufferring
2641 pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2642 pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2643 bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
2644 }
2645 }
2646 }
2647 pDevice->bBeaconSent = true;
Forest Bond5449c682009-04-25 10:30:44 -04002648
Joe Perches915006c2013-03-18 10:44:47 -07002649 if (pDevice->bChannelSwitch == true) {
2650 pDevice->byChannelSwitchCount--;
2651 if (pDevice->byChannelSwitchCount == 0) {
2652 pDevice->bChannelSwitch = false;
2653 set_channel(pDevice, pDevice->byNewChannel);
2654 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2655 MACvSelectPage1(pDevice->PortOffset);
2656 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2657 MACvSelectPage0(pDevice->PortOffset);
2658 //VNTWIFIbSendBeacon(pDevice->pMgmt);
2659 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
2660 }
2661 }
Forest Bond5449c682009-04-25 10:30:44 -04002662
Joe Perches915006c2013-03-18 10:44:47 -07002663 }
Forest Bond5449c682009-04-25 10:30:44 -04002664
Joe Perches915006c2013-03-18 10:44:47 -07002665 if (pDevice->dwIsr & ISR_RXDMA0) {
2666 max_count += device_rx_srv(pDevice, TYPE_RXDMA0);
2667 }
2668 if (pDevice->dwIsr & ISR_RXDMA1) {
2669 max_count += device_rx_srv(pDevice, TYPE_RXDMA1);
2670 }
2671 if (pDevice->dwIsr & ISR_TXDMA0) {
2672 max_count += device_tx_srv(pDevice, TYPE_TXDMA0);
2673 }
2674 if (pDevice->dwIsr & ISR_AC0DMA) {
2675 max_count += device_tx_srv(pDevice, TYPE_AC0DMA);
2676 }
2677 if (pDevice->dwIsr & ISR_SOFTTIMER) {
Joe Perches915006c2013-03-18 10:44:47 -07002678 }
2679 if (pDevice->dwIsr & ISR_SOFTTIMER1) {
2680 if (pDevice->eOPMode == OP_MODE_AP) {
2681 if (pDevice->bShortSlotTime)
2682 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
2683 else
2684 pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1));
2685 }
2686 bMgrPrepareBeaconToSend(pDevice, pMgmt);
2687 pDevice->byCntMeasure = 0;
2688 }
Forest Bond5449c682009-04-25 10:30:44 -04002689
Joe Perches915006c2013-03-18 10:44:47 -07002690 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002691
Joe Perches915006c2013-03-18 10:44:47 -07002692 MACvReceive0(pDevice->PortOffset);
2693 MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002694
Joe Perches915006c2013-03-18 10:44:47 -07002695 if (max_count > pDevice->sOpts.int_works)
2696 break;
2697 }
Forest Bond5449c682009-04-25 10:30:44 -04002698
Joe Perches915006c2013-03-18 10:44:47 -07002699 if (byOrgPageSel == 1) {
2700 MACvSelectPage1(pDevice->PortOffset);
2701 }
Forest Bond5449c682009-04-25 10:30:44 -04002702
Joe Perches915006c2013-03-18 10:44:47 -07002703 spin_unlock_irq(&pDevice->lock);
2704 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
Forest Bond5449c682009-04-25 10:30:44 -04002705
Joe Perches915006c2013-03-18 10:44:47 -07002706 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002707}
2708
Forest Bond5449c682009-04-25 10:30:44 -04002709static unsigned const ethernet_polynomial = 0x04c11db7U;
2710static inline u32 ether_crc(int length, unsigned char *data)
2711{
Joe Perches915006c2013-03-18 10:44:47 -07002712 int crc = -1;
Forest Bond5449c682009-04-25 10:30:44 -04002713
Joe Perches915006c2013-03-18 10:44:47 -07002714 while (--length >= 0) {
2715 unsigned char current_octet = *data++;
2716 int bit;
2717 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
2718 crc = (crc << 1) ^
2719 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
2720 }
2721 }
2722 return crc;
Forest Bond5449c682009-04-25 10:30:44 -04002723}
2724
2725//2008-8-4 <add> by chester
Charles Clément5c9824e2010-06-02 09:51:59 -07002726static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -07002727 unsigned char *dest, unsigned char *source)
Forest Bond5449c682009-04-25 10:30:44 -04002728{
Joe Perches915006c2013-03-18 10:44:47 -07002729 unsigned char buf1[100];
2730 int source_len = strlen(source);
Forest Bond5449c682009-04-25 10:30:44 -04002731
Joe Perches915006c2013-03-18 10:44:47 -07002732 memset(buf1, 0, 100);
2733 strcat(buf1, string);
2734 strcat(buf1, "=");
2735 source += strlen(buf1);
Forest Bond5449c682009-04-25 10:30:44 -04002736
Joe Perches915006c2013-03-18 10:44:47 -07002737 memcpy(dest, source, source_len - strlen(buf1));
2738 return true;
Forest Bond5449c682009-04-25 10:30:44 -04002739}
2740
Al Virof8054422013-04-06 18:11:22 -04002741int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter)
2742{
2743 unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
Joe Perches915006c2013-03-18 10:44:47 -07002744 unsigned char tmpbuffer[20];
Al Virof8054422013-04-06 18:11:22 -04002745 struct file *file;
2746 int result=0;
Forest Bond5449c682009-04-25 10:30:44 -04002747
Al Virof8054422013-04-06 18:11:22 -04002748 if (!buffer) {
Joe Perches915006c2013-03-18 10:44:47 -07002749 printk("allocate mem for file fail?\n");
Al Virof8054422013-04-06 18:11:22 -04002750 return -1;
2751 }
2752 file = filp_open(CONFIG_PATH, O_RDONLY, 0);
2753 if (IS_ERR(file)) {
2754 kfree(buffer);
2755 printk("Config_FileOperation:open file fail?\n");
2756 return -1;
Joe Perches915006c2013-03-18 10:44:47 -07002757 }
Forest Bond5449c682009-04-25 10:30:44 -04002758
Al Virof8054422013-04-06 18:11:22 -04002759 if (kernel_read(file, 0, buffer, 1024) < 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002760 printk("read file error?\n");
2761 result = -1;
2762 goto error1;
2763 }
Forest Bond5449c682009-04-25 10:30:44 -04002764
Al Virof8054422013-04-06 18:11:22 -04002765 if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
Joe Perches915006c2013-03-18 10:44:47 -07002766 printk("get parameter error?\n");
2767 result = -1;
2768 goto error1;
2769 }
Forest Bond5449c682009-04-25 10:30:44 -04002770
Al Virof8054422013-04-06 18:11:22 -04002771 if (memcmp(tmpbuffer,"USA",3)==0) {
Joe Perches915006c2013-03-18 10:44:47 -07002772 result = ZoneType_USA;
Al Virof8054422013-04-06 18:11:22 -04002773 } else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
Joe Perches915006c2013-03-18 10:44:47 -07002774 result = ZoneType_Japan;
Al Virof8054422013-04-06 18:11:22 -04002775 } else if(memcmp(tmpbuffer,"EUROPE",5)==0) {
Joe Perches915006c2013-03-18 10:44:47 -07002776 result = ZoneType_Europe;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002777 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002778 result = -1;
Al Virof8054422013-04-06 18:11:22 -04002779 printk("Unknown Zonetype[%s]?\n",tmpbuffer);
Joe Perches915006c2013-03-18 10:44:47 -07002780 }
Forest Bond5449c682009-04-25 10:30:44 -04002781
2782error1:
Joe Perches915006c2013-03-18 10:44:47 -07002783 kfree(buffer);
Al Virof8054422013-04-06 18:11:22 -04002784 fput(file);
Joe Perches915006c2013-03-18 10:44:47 -07002785 return result;
Forest Bond5449c682009-04-25 10:30:44 -04002786}
2787
Forest Bond5449c682009-04-25 10:30:44 -04002788static void device_set_multi(struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07002789 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002790
Joe Perches915006c2013-03-18 10:44:47 -07002791 PSMgmtObject pMgmt = pDevice->pMgmt;
2792 u32 mc_filter[2];
2793 struct netdev_hw_addr *ha;
Forest Bond5449c682009-04-25 10:30:44 -04002794
Joe Perches915006c2013-03-18 10:44:47 -07002795 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
Forest Bond5449c682009-04-25 10:30:44 -04002796
Joe Perches915006c2013-03-18 10:44:47 -07002797 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
2798 DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
2799 /* Unconditionally log net taps. */
2800 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002801 } else if ((netdev_mc_count(dev) > pDevice->multicast_limit)
Joe Perches915006c2013-03-18 10:44:47 -07002802 || (dev->flags & IFF_ALLMULTI)) {
2803 MACvSelectPage1(pDevice->PortOffset);
2804 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
2805 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
2806 MACvSelectPage0(pDevice->PortOffset);
2807 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002808 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002809 memset(mc_filter, 0, sizeof(mc_filter));
2810 netdev_for_each_mc_addr(ha, dev) {
2811 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
2812 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
2813 }
2814 MACvSelectPage1(pDevice->PortOffset);
2815 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]);
2816 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]);
2817 MACvSelectPage0(pDevice->PortOffset);
2818 pDevice->byRxMode &= ~(RCR_UNICAST);
2819 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2820 }
Forest Bond5449c682009-04-25 10:30:44 -04002821
Joe Perches915006c2013-03-18 10:44:47 -07002822 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2823 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
2824 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2825 pDevice->byRxMode &= ~(RCR_UNICAST);
2826 }
Forest Bond5449c682009-04-25 10:30:44 -04002827
Joe Perches915006c2013-03-18 10:44:47 -07002828 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
2829 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode);
Forest Bond5449c682009-04-25 10:30:44 -04002830}
2831
Forest Bond5449c682009-04-25 10:30:44 -04002832static struct net_device_stats *device_get_stats(struct net_device *dev) {
Joe Perches915006c2013-03-18 10:44:47 -07002833 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002834
Joe Perches915006c2013-03-18 10:44:47 -07002835 return &pDevice->stats;
Forest Bond5449c682009-04-25 10:30:44 -04002836}
2837
Forest Bond5449c682009-04-25 10:30:44 -04002838static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
Forest Bondc9d03522009-06-01 20:00:14 -04002839 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002840
Joe Perches915006c2013-03-18 10:44:47 -07002841 struct iwreq *wrq = (struct iwreq *)rq;
2842 int rc = 0;
2843 PSMgmtObject pMgmt = pDevice->pMgmt;
2844 PSCmdRequest pReq;
Forest Bond5449c682009-04-25 10:30:44 -04002845
Joe Perches915006c2013-03-18 10:44:47 -07002846 if (pMgmt == NULL) {
2847 rc = -EFAULT;
2848 return rc;
2849 }
Forest Bond5449c682009-04-25 10:30:44 -04002850
Joe Perches915006c2013-03-18 10:44:47 -07002851 switch (cmd) {
Forest Bond5449c682009-04-25 10:30:44 -04002852 case SIOCGIWNAME:
2853 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
2854 break;
2855
2856 case SIOCGIWNWID: //0x8b03 support
Marcos Paulo de Souza428c1fb2011-11-28 19:16:37 +00002857 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002858 break;
2859
2860 // Set frequency/channel
2861 case SIOCSIWFREQ:
Joe Perches915006c2013-03-18 10:44:47 -07002862 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002863 break;
2864
2865 // Get frequency/channel
2866 case SIOCGIWFREQ:
2867 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
2868 break;
2869
2870 // Set desired network name (ESSID)
2871 case SIOCSIWESSID:
2872
Joe Perches915006c2013-03-18 10:44:47 -07002873 {
2874 char essid[IW_ESSID_MAX_SIZE+1];
2875 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
2876 rc = -E2BIG;
2877 break;
Forest Bond5449c682009-04-25 10:30:44 -04002878 }
Joe Perches915006c2013-03-18 10:44:47 -07002879 if (copy_from_user(essid, wrq->u.essid.pointer,
2880 wrq->u.essid.length)) {
2881 rc = -EFAULT;
2882 break;
2883 }
2884 rc = iwctl_siwessid(dev, NULL,
2885 &(wrq->u.essid), essid);
2886 }
2887 break;
Forest Bond5449c682009-04-25 10:30:44 -04002888
Joe Perches915006c2013-03-18 10:44:47 -07002889 // Get current network name (ESSID)
Forest Bond5449c682009-04-25 10:30:44 -04002890 case SIOCGIWESSID:
2891
Joe Perches915006c2013-03-18 10:44:47 -07002892 {
2893 char essid[IW_ESSID_MAX_SIZE+1];
2894 if (wrq->u.essid.pointer)
2895 rc = iwctl_giwessid(dev, NULL,
2896 &(wrq->u.essid), essid);
2897 if (copy_to_user(wrq->u.essid.pointer,
2898 essid,
2899 wrq->u.essid.length))
2900 rc = -EFAULT;
2901 }
2902 break;
Forest Bond5449c682009-04-25 10:30:44 -04002903
2904 case SIOCSIWAP:
2905
2906 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2907 break;
2908
Forest Bond5449c682009-04-25 10:30:44 -04002909 // Get current Access Point (BSSID)
2910 case SIOCGIWAP:
2911 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2912 break;
2913
Forest Bond5449c682009-04-25 10:30:44 -04002914 // Set desired station name
2915 case SIOCSIWNICKN:
Joe Perches915006c2013-03-18 10:44:47 -07002916 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
2917 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002918 break;
2919
2920 // Get current station name
2921 case SIOCGIWNICKN:
Joe Perches915006c2013-03-18 10:44:47 -07002922 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
2923 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002924 break;
2925
2926 // Set the desired bit-rate
2927 case SIOCSIWRATE:
2928 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2929 break;
2930
Joe Perches915006c2013-03-18 10:44:47 -07002931 // Get the current bit-rate
Forest Bond5449c682009-04-25 10:30:44 -04002932 case SIOCGIWRATE:
2933
2934 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2935 break;
2936
Joe Perches915006c2013-03-18 10:44:47 -07002937 // Set the desired RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002938 case SIOCSIWRTS:
2939
2940 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
2941 break;
2942
Joe Perches915006c2013-03-18 10:44:47 -07002943 // Get the current RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002944 case SIOCGIWRTS:
2945
2946 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
2947 break;
2948
2949 // Set the desired fragmentation threshold
2950 case SIOCSIWFRAG:
2951
2952 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
Joe Perches915006c2013-03-18 10:44:47 -07002953 break;
Forest Bond5449c682009-04-25 10:30:44 -04002954
Joe Perches915006c2013-03-18 10:44:47 -07002955 // Get the current fragmentation threshold
Forest Bond5449c682009-04-25 10:30:44 -04002956 case SIOCGIWFRAG:
2957
2958 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
2959 break;
2960
2961 // Set mode of operation
2962 case SIOCSIWMODE:
Joe Perches915006c2013-03-18 10:44:47 -07002963 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002964 break;
2965
2966 // Get mode of operation
2967 case SIOCGIWMODE:
2968 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
2969 break;
2970
2971 // Set WEP keys and mode
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002972 case SIOCSIWENCODE: {
Joe Perches915006c2013-03-18 10:44:47 -07002973 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04002974
Joe Perches915006c2013-03-18 10:44:47 -07002975 if (wrq->u.encoding.pointer) {
Joe Perches915006c2013-03-18 10:44:47 -07002976 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
2977 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04002978 break;
2979 }
Joe Perches915006c2013-03-18 10:44:47 -07002980 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
2981 if (copy_from_user(abyKey,
2982 wrq->u.encoding.pointer,
2983 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_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
2992 }
2993 break;
Forest Bond5449c682009-04-25 10:30:44 -04002994
Joe Perches915006c2013-03-18 10:44:47 -07002995 // Get the WEP keys and mode
Forest Bond5449c682009-04-25 10:30:44 -04002996 case SIOCGIWENCODE:
2997
2998 if (!capable(CAP_NET_ADMIN)) {
2999 rc = -EPERM;
3000 break;
3001 }
3002 {
Joe Perches915006c2013-03-18 10:44:47 -07003003 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04003004
Joe Perches915006c2013-03-18 10:44:47 -07003005 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
3006 if (rc != 0) break;
Forest Bond5449c682009-04-25 10:30:44 -04003007 if (wrq->u.encoding.pointer) {
3008 if (copy_to_user(wrq->u.encoding.pointer,
Joe Perches915006c2013-03-18 10:44:47 -07003009 abyKey,
3010 wrq->u.encoding.length))
Forest Bond5449c682009-04-25 10:30:44 -04003011 rc = -EFAULT;
3012 }
3013 }
3014 break;
3015
Forest Bond5449c682009-04-25 10:30:44 -04003016 // Get the current Tx-Power
3017 case SIOCGIWTXPOW:
Joe Perches915006c2013-03-18 10:44:47 -07003018 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
3019 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04003020 break;
3021
3022 case SIOCSIWTXPOW:
Joe Perches915006c2013-03-18 10:44:47 -07003023 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW \n");
3024 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04003025 break;
3026
Forest Bond5449c682009-04-25 10:30:44 -04003027 case SIOCSIWRETRY:
3028
3029 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
3030 break;
3031
3032 case SIOCGIWRETRY:
3033
3034 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
3035 break;
3036
Forest Bond5449c682009-04-25 10:30:44 -04003037 // Get range of parameters
3038 case SIOCGIWRANGE:
3039
Joe Perches915006c2013-03-18 10:44:47 -07003040 {
3041 struct iw_range range;
Forest Bond5449c682009-04-25 10:30:44 -04003042
Joe Perches915006c2013-03-18 10:44:47 -07003043 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range);
3044 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
3045 rc = -EFAULT;
3046 }
Forest Bond5449c682009-04-25 10:30:44 -04003047
Joe Perches915006c2013-03-18 10:44:47 -07003048 break;
Forest Bond5449c682009-04-25 10:30:44 -04003049
3050 case SIOCGIWPOWER:
3051
3052 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
3053 break;
3054
Forest Bond5449c682009-04-25 10:30:44 -04003055 case SIOCSIWPOWER:
3056
3057 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
3058 break;
3059
Forest Bond5449c682009-04-25 10:30:44 -04003060 case SIOCGIWSENS:
3061
Joe Perches915006c2013-03-18 10:44:47 -07003062 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04003063 break;
3064
3065 case SIOCSIWSENS:
Joe Perches915006c2013-03-18 10:44:47 -07003066 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
Forest Bond5449c682009-04-25 10:30:44 -04003067 rc = -EOPNOTSUPP;
3068 break;
3069
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003070 case SIOCGIWAPLIST: {
Joe Perches915006c2013-03-18 10:44:47 -07003071 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
Forest Bond5449c682009-04-25 10:30:44 -04003072
Joe Perches915006c2013-03-18 10:44:47 -07003073 if (wrq->u.data.pointer) {
3074 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
3075 if (rc == 0) {
3076 if (copy_to_user(wrq->u.data.pointer,
3077 buffer,
3078 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
3079 ))
3080 rc = -EFAULT;
3081 }
3082 }
3083 }
3084 break;
Forest Bond5449c682009-04-25 10:30:44 -04003085
Forest Bond5449c682009-04-25 10:30:44 -04003086#ifdef WIRELESS_SPY
Joe Perches915006c2013-03-18 10:44:47 -07003087 // Set the spy list
Forest Bond5449c682009-04-25 10:30:44 -04003088 case SIOCSIWSPY:
3089
Joe Perches915006c2013-03-18 10:44:47 -07003090 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
Forest Bond5449c682009-04-25 10:30:44 -04003091 rc = -EOPNOTSUPP;
3092 break;
3093
3094 // Get the spy list
3095 case SIOCGIWSPY:
3096
Joe Perches915006c2013-03-18 10:44:47 -07003097 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY \n");
Forest Bond5449c682009-04-25 10:30:44 -04003098 rc = -EOPNOTSUPP;
3099 break;
3100
3101#endif // WIRELESS_SPY
3102
3103 case SIOCGIWPRIV:
Joe Perches915006c2013-03-18 10:44:47 -07003104 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
Forest Bond5449c682009-04-25 10:30:44 -04003105 rc = -EOPNOTSUPP;
3106/*
Joe Perches915006c2013-03-18 10:44:47 -07003107 if (wrq->u.data.pointer) {
3108 wrq->u.data.length = sizeof(iwctl_private_args) / sizeof(iwctl_private_args[0]);
Forest Bond5449c682009-04-25 10:30:44 -04003109
Joe Perches915006c2013-03-18 10:44:47 -07003110 if (copy_to_user(wrq->u.data.pointer,
3111 (u_char *) iwctl_private_args,
3112 sizeof(iwctl_private_args)))
3113 rc = -EFAULT;
3114 }
Forest Bond5449c682009-04-25 10:30:44 -04003115*/
3116 break;
3117
Forest Bond5449c682009-04-25 10:30:44 -04003118//2008-0409-07, <Add> by Einsn Liu
Joe Perches915006c2013-03-18 10:44:47 -07003119#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond5449c682009-04-25 10:30:44 -04003120 case SIOCSIWAUTH:
Jim Lieb7e809a92009-07-30 10:27:21 -07003121 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
Forest Bond5449c682009-04-25 10:30:44 -04003122 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
3123 break;
3124
3125 case SIOCGIWAUTH:
Jim Lieb7e809a92009-07-30 10:27:21 -07003126 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
Forest Bond5449c682009-04-25 10:30:44 -04003127 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
3128 break;
3129
3130 case SIOCSIWGENIE:
Jim Lieb7e809a92009-07-30 10:27:21 -07003131 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
Forest Bond5449c682009-04-25 10:30:44 -04003132 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
3133 break;
3134
3135 case SIOCGIWGENIE:
Jim Lieb7e809a92009-07-30 10:27:21 -07003136 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
Forest Bond5449c682009-04-25 10:30:44 -04003137 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
3138 break;
3139
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003140 case SIOCSIWENCODEEXT: {
Joe Perches915006c2013-03-18 10:44:47 -07003141 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
3142 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
3143 if (wrq->u.encoding.pointer) {
3144 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1);
3145 if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) {
3146 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04003147 break;
3148 }
Joe Perches915006c2013-03-18 10:44:47 -07003149 if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) {
3150 rc = -EFAULT;
3151 break;
3152 }
3153 } else if (wrq->u.encoding.length != 0) {
3154 rc = -EINVAL;
3155 break;
Forest Bond5449c682009-04-25 10:30:44 -04003156 }
Joe Perches915006c2013-03-18 10:44:47 -07003157 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
3158 }
3159 break;
Forest Bond5449c682009-04-25 10:30:44 -04003160
3161 case SIOCGIWENCODEEXT:
Jim Lieb7e809a92009-07-30 10:27:21 -07003162 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
Forest Bond5449c682009-04-25 10:30:44 -04003163 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
3164 break;
3165
3166 case SIOCSIWMLME:
Jim Lieb7e809a92009-07-30 10:27:21 -07003167 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
Forest Bond5449c682009-04-25 10:30:44 -04003168 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
3169 break;
3170
3171#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
3172//End Add -- //2008-0409-07, <Add> by Einsn Liu
3173
Joe Perches915006c2013-03-18 10:44:47 -07003174 case IOCTL_CMD_TEST:
Forest Bond5449c682009-04-25 10:30:44 -04003175
3176 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
Joe Perches915006c2013-03-18 10:44:47 -07003177 rc = -EFAULT;
3178 break;
Forest Bond5449c682009-04-25 10:30:44 -04003179 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003180 rc = 0;
Forest Bond5449c682009-04-25 10:30:44 -04003181 }
Joe Perches915006c2013-03-18 10:44:47 -07003182 pReq = (PSCmdRequest)rq;
3183 pReq->wResult = MAGIC_CODE;
3184 break;
Forest Bond5449c682009-04-25 10:30:44 -04003185
Joe Perches915006c2013-03-18 10:44:47 -07003186 case IOCTL_CMD_SET:
Forest Bond5449c682009-04-25 10:30:44 -04003187
Joe Perches915006c2013-03-18 10:44:47 -07003188#ifdef SndEvt_ToAPI
3189 if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) &&
3190 !(pDevice->flags & DEVICE_FLAGS_OPENED))
3191#else
3192 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
3193 (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA))
3194#endif
3195 {
3196 rc = -EFAULT;
3197 break;
3198 } else {
3199 rc = 0;
3200 }
3201
3202 if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy))) {
3203 return -EBUSY;
Forest Bond5449c682009-04-25 10:30:44 -04003204 }
Joe Perches915006c2013-03-18 10:44:47 -07003205 rc = private_ioctl(pDevice, rq);
3206 clear_bit(0, (void *)&(pMgmt->uCmdBusy));
3207 break;
Forest Bond5449c682009-04-25 10:30:44 -04003208
Joe Perches915006c2013-03-18 10:44:47 -07003209 case IOCTL_CMD_HOSTAPD:
Forest Bond5449c682009-04-25 10:30:44 -04003210
Joe Perches915006c2013-03-18 10:44:47 -07003211 rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data);
3212 break;
Forest Bond5449c682009-04-25 10:30:44 -04003213
Joe Perches915006c2013-03-18 10:44:47 -07003214 case IOCTL_CMD_WPA:
Forest Bond5449c682009-04-25 10:30:44 -04003215
Joe Perches915006c2013-03-18 10:44:47 -07003216 rc = wpa_ioctl(pDevice, &wrq->u.data);
3217 break;
Forest Bond5449c682009-04-25 10:30:44 -04003218
3219 case SIOCETHTOOL:
Joe Perches915006c2013-03-18 10:44:47 -07003220 return ethtool_ioctl(dev, (void *)rq->ifr_data);
3221 // All other calls are currently unsupported
Forest Bond5449c682009-04-25 10:30:44 -04003222
3223 default:
3224 rc = -EOPNOTSUPP;
Joe Perches915006c2013-03-18 10:44:47 -07003225 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
Forest Bond5449c682009-04-25 10:30:44 -04003226
Joe Perches915006c2013-03-18 10:44:47 -07003227 }
Forest Bond5449c682009-04-25 10:30:44 -04003228
Joe Perches915006c2013-03-18 10:44:47 -07003229 if (pDevice->bCommit) {
3230 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
3231 netif_stop_queue(pDevice->dev);
3232 spin_lock_irq(&pDevice->lock);
3233 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
3234 spin_unlock_irq(&pDevice->lock);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003235 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003236 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
3237 spin_lock_irq(&pDevice->lock);
3238 pDevice->bLinkPass = false;
3239 memset(pMgmt->abyCurrBSSID, 0, 6);
3240 pMgmt->eCurrState = WMAC_STATE_IDLE;
3241 netif_stop_queue(pDevice->dev);
3242#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
3243 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
3244 if (pDevice->bWPASuppWextEnabled != true)
3245#endif
3246 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
3247 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3248 spin_unlock_irq(&pDevice->lock);
3249 }
3250 pDevice->bCommit = false;
3251 }
Forest Bond5449c682009-04-25 10:30:44 -04003252
Joe Perches915006c2013-03-18 10:44:47 -07003253 return rc;
Forest Bond5449c682009-04-25 10:30:44 -04003254}
3255
Forest Bond5449c682009-04-25 10:30:44 -04003256static int ethtool_ioctl(struct net_device *dev, void *useraddr)
3257{
3258 u32 ethcmd;
3259
3260 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
3261 return -EFAULT;
3262
Joe Perches915006c2013-03-18 10:44:47 -07003263 switch (ethcmd) {
Forest Bond5449c682009-04-25 10:30:44 -04003264 case ETHTOOL_GDRVINFO: {
3265 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
3266 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
3267 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
3268 if (copy_to_user(useraddr, &info, sizeof(info)))
3269 return -EFAULT;
3270 return 0;
3271 }
3272
Joe Perches915006c2013-03-18 10:44:47 -07003273 }
Forest Bond5449c682009-04-25 10:30:44 -04003274
3275 return -EOPNOTSUPP;
3276}
3277
3278/*------------------------------------------------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -04003279
Charles Clément013a4682010-06-15 10:39:24 -07003280MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
Forest Bond5449c682009-04-25 10:30:44 -04003281
3282static struct pci_driver device_driver = {
Peter Huewe34381c22011-01-10 23:28:06 +01003283 .name = DEVICE_NAME,
3284 .id_table = vt6655_pci_id_table,
3285 .probe = vt6655_probe,
3286 .remove = vt6655_remove,
Forest Bond5449c682009-04-25 10:30:44 -04003287#ifdef CONFIG_PM
Peter Huewe34381c22011-01-10 23:28:06 +01003288 .suspend = viawget_suspend,
3289 .resume = viawget_resume,
Forest Bond5449c682009-04-25 10:30:44 -04003290#endif
Forest Bond5449c682009-04-25 10:30:44 -04003291};
3292
Charles Clément013a4682010-06-15 10:39:24 -07003293static int __init vt6655_init_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003294{
Joe Perches915006c2013-03-18 10:44:47 -07003295 int ret;
Forest Bond5449c682009-04-25 10:30:44 -04003296
Forest Bond5449c682009-04-25 10:30:44 -04003297// ret=pci_module_init(&device_driver);
3298 //ret = pcie_port_service_register(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003299 ret = pci_register_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003300#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003301 if (ret >= 0)
3302 register_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003303#endif
Forest Bond5449c682009-04-25 10:30:44 -04003304
Joe Perches915006c2013-03-18 10:44:47 -07003305 return ret;
Forest Bond5449c682009-04-25 10:30:44 -04003306}
3307
Charles Clément013a4682010-06-15 10:39:24 -07003308static void __exit vt6655_cleanup_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003309{
Forest Bond5449c682009-04-25 10:30:44 -04003310#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003311 unregister_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003312#endif
Joe Perches915006c2013-03-18 10:44:47 -07003313 pci_unregister_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003314}
3315
Charles Clément013a4682010-06-15 10:39:24 -07003316module_init(vt6655_init_module);
3317module_exit(vt6655_cleanup_module);
Forest Bond5449c682009-04-25 10:30:44 -04003318
Forest Bond5449c682009-04-25 10:30:44 -04003319#ifdef CONFIG_PM
3320static int
3321device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
3322{
Joe Perches915006c2013-03-18 10:44:47 -07003323 struct pci_dev *pdev = NULL;
3324 switch (event) {
3325 case SYS_DOWN:
3326 case SYS_HALT:
3327 case SYS_POWER_OFF:
3328 for_each_pci_dev(pdev) {
3329 if (pci_dev_driver(pdev) == &device_driver) {
3330 if (pci_get_drvdata(pdev))
3331 viawget_suspend(pdev, PMSG_HIBERNATE);
3332 }
3333 }
3334 }
3335 return NOTIFY_DONE;
Forest Bond5449c682009-04-25 10:30:44 -04003336}
3337
3338static int
Alan Coxf408ade2009-06-10 17:30:49 +01003339viawget_suspend(struct pci_dev *pcid, pm_message_t state)
Forest Bond5449c682009-04-25 10:30:44 -04003340{
Joe Perches915006c2013-03-18 10:44:47 -07003341 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003342
Joe Perches915006c2013-03-18 10:44:47 -07003343 PSDevice pDevice = pci_get_drvdata(pcid);
3344 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04003345
Joe Perches915006c2013-03-18 10:44:47 -07003346 netif_stop_queue(pDevice->dev);
3347 spin_lock_irq(&pDevice->lock);
3348 pci_save_state(pcid);
3349 del_timer(&pDevice->sTimerCommand);
3350 del_timer(&pMgmt->sTimerSecondCallback);
3351 pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
3352 pDevice->uCmdDequeueIdx = 0;
3353 pDevice->uCmdEnqueueIdx = 0;
3354 pDevice->bCmdRunning = false;
3355 MACbShutdown(pDevice->PortOffset);
3356 MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
3357 pDevice->bLinkPass = false;
3358 memset(pMgmt->abyCurrBSSID, 0, 6);
3359 pMgmt->eCurrState = WMAC_STATE_IDLE;
3360 pci_disable_device(pcid);
3361 power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state));
3362 spin_unlock_irq(&pDevice->lock);
3363 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003364}
3365
3366static int
3367viawget_resume(struct pci_dev *pcid)
3368{
Joe Perches915006c2013-03-18 10:44:47 -07003369 PSDevice pDevice = pci_get_drvdata(pcid);
3370 PSMgmtObject pMgmt = pDevice->pMgmt;
3371 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003372
Joe Perches915006c2013-03-18 10:44:47 -07003373 power_status = pci_set_power_state(pcid, 0);
3374 power_status = pci_enable_wake(pcid, 0, 0);
3375 pci_restore_state(pcid);
3376 if (netif_running(pDevice->dev)) {
3377 spin_lock_irq(&pDevice->lock);
3378 MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
3379 device_init_registers(pDevice, DEVICE_INIT_DXPL);
3380 if (pMgmt->sNodeDBTable[0].bActive == true) { // Assoc with BSS
3381 pMgmt->sNodeDBTable[0].bActive = false;
3382 pDevice->bLinkPass = false;
3383 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3384 // In Adhoc, BSS state set back to started.
3385 pMgmt->eCurrState = WMAC_STATE_STARTED;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003386 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003387 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
3388 pMgmt->eCurrState = WMAC_STATE_IDLE;
3389 }
3390 }
3391 init_timer(&pMgmt->sTimerSecondCallback);
3392 init_timer(&pDevice->sTimerCommand);
3393 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
3394 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
3395 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
3396 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3397 spin_unlock_irq(&pDevice->lock);
3398 }
3399 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003400}
3401
3402#endif