blob: e8584fd565c5495d9bf6bee2b3528f01572c21a7 [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: device_main.c
20 *
21 * Purpose: driver entry for initial, open, close, tx and rx.
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: Jan 8, 2003
26 *
27 * Functions:
28 *
Charles Clément013a4682010-06-15 10:39:24 -070029 * vt6655_probe - module initial (insmod) driver entry
30 * vt6655_remove - module remove entry
31 * vt6655_init_info - device structure resource allocation function
Forest Bond5449c682009-04-25 10:30:44 -040032 * device_free_info - device structure resource free function
33 * device_get_pci_info - get allocated pci io/mem resource
34 * device_print_info - print out resource
35 * device_open - allocate dma/descripter resource & initial mac/bbp function
36 * device_xmit - asynchrous data tx function
37 * device_intr - interrupt handle function
38 * device_set_multi - set mac filter
39 * device_ioctl - ioctl entry
40 * device_close - shutdown mac/bbp & free dma/descripter resource
41 * device_rx_srv - rx service function
42 * device_receive_frame - rx data function
43 * device_alloc_rx_buf - rx buffer pre-allocated function
44 * device_alloc_frag_buf - rx fragement pre-allocated function
45 * device_free_tx_buf - free tx buffer function
46 * device_free_frag_buf- free de-fragement buffer
47 * device_dma0_tx_80211- tx 802.11 frame via dma0
48 * device_dma0_xmit- tx PS bufferred frame via dma0
49 * device_init_rd0_ring- initial rd dma0 ring
50 * device_init_rd1_ring- initial rd dma1 ring
51 * device_init_td0_ring- initial tx dma0 ring buffer
52 * device_init_td1_ring- initial tx dma1 ring buffer
53 * device_init_registers- initial MAC & BBP & RF internal registers.
54 * device_init_rings- initial tx/rx ring buffer
55 * device_init_defrag_cb- initial & allocate de-fragement buffer.
56 * device_free_rings- free all allocated ring buffer
57 * device_tx_srv- tx interrupt service function
58 *
59 * Revision History:
60 */
61#undef __NO_VERSION__
62
Al Virof8054422013-04-06 18:11:22 -040063#include <linux/file.h>
Forest Bond5449c682009-04-25 10:30:44 -040064#include "device.h"
Forest Bond5449c682009-04-25 10:30:44 -040065#include "card.h"
Charles Clément79566eb2010-06-21 10:39:51 -070066#include "channel.h"
Forest Bond5449c682009-04-25 10:30:44 -040067#include "baseband.h"
Forest Bond5449c682009-04-25 10:30:44 -040068#include "mac.h"
Forest Bond5449c682009-04-25 10:30:44 -040069#include "tether.h"
Forest Bond5449c682009-04-25 10:30:44 -040070#include "wmgr.h"
Forest Bond5449c682009-04-25 10:30:44 -040071#include "wctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040072#include "power.h"
Forest Bond5449c682009-04-25 10:30:44 -040073#include "wcmd.h"
Forest Bond5449c682009-04-25 10:30:44 -040074#include "iocmd.h"
Forest Bond5449c682009-04-25 10:30:44 -040075#include "tcrc.h"
Forest Bond5449c682009-04-25 10:30:44 -040076#include "rxtx.h"
Forest Bond5449c682009-04-25 10:30:44 -040077#include "wroute.h"
Forest Bond5449c682009-04-25 10:30:44 -040078#include "bssdb.h"
Forest Bond5449c682009-04-25 10:30:44 -040079#include "hostap.h"
Forest Bond5449c682009-04-25 10:30:44 -040080#include "wpactl.h"
Forest Bond5449c682009-04-25 10:30:44 -040081#include "ioctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040082#include "iwctl.h"
Forest Bond5449c682009-04-25 10:30:44 -040083#include "dpc.h"
Forest Bond5449c682009-04-25 10:30:44 -040084#include "datarate.h"
Forest Bond5449c682009-04-25 10:30:44 -040085#include "rf.h"
Forest Bond5449c682009-04-25 10:30:44 -040086#include "iowpa.h"
Forest Bond5449c682009-04-25 10:30:44 -040087#include <linux/delay.h>
88#include <linux/kthread.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090089#include <linux/slab.h>
Forest Bond5449c682009-04-25 10:30:44 -040090
Forest Bond5449c682009-04-25 10:30:44 -040091/*--------------------- Static Definitions -------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -040092static int msglevel = MSG_LEVEL_INFO;
93
Forest Bond5449c682009-04-25 10:30:44 -040094//
95// Define module options
96//
Forest Bond5449c682009-04-25 10:30:44 -040097MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
98MODULE_LICENSE("GPL");
99MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
Forest Bond5449c682009-04-25 10:30:44 -0400100
Joe Perches915006c2013-03-18 10:44:47 -0700101#define DEVICE_PARAM(N, D)
Forest Bond5449c682009-04-25 10:30:44 -0400102
103#define RX_DESC_MIN0 16
104#define RX_DESC_MAX0 128
105#define RX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700106DEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400107
108#define RX_DESC_MIN1 16
109#define RX_DESC_MAX1 128
110#define RX_DESC_DEF1 32
Joe Perches915006c2013-03-18 10:44:47 -0700111DEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400112
113#define TX_DESC_MIN0 16
114#define TX_DESC_MAX0 128
115#define TX_DESC_DEF0 32
Joe Perches915006c2013-03-18 10:44:47 -0700116DEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0");
Forest Bond5449c682009-04-25 10:30:44 -0400117
118#define TX_DESC_MIN1 16
119#define TX_DESC_MAX1 128
120#define TX_DESC_DEF1 64
Joe Perches915006c2013-03-18 10:44:47 -0700121DEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1");
Forest Bond5449c682009-04-25 10:30:44 -0400122
Forest Bond5449c682009-04-25 10:30:44 -0400123#define IP_ALIG_DEF 0
Charles Clément0f4c60d2010-06-24 11:02:25 -0700124/* IP_byte_align[] is used for IP header unsigned long byte aligned
125 0: indicate the IP header won't be unsigned long byte aligned.(Default) .
126 1: indicate the IP header will be unsigned long byte aligned.
Joe Perches915006c2013-03-18 10:44:47 -0700127 In some environment, the IP header should be unsigned long byte aligned,
128 or the packet will be droped when we receive it. (eg: IPVS)
Forest Bond5449c682009-04-25 10:30:44 -0400129*/
Joe Perches915006c2013-03-18 10:44:47 -0700130DEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned");
Forest Bond5449c682009-04-25 10:30:44 -0400131
Forest Bond5449c682009-04-25 10:30:44 -0400132#define INT_WORKS_DEF 20
133#define INT_WORKS_MIN 10
134#define INT_WORKS_MAX 64
135
Joe Perches915006c2013-03-18 10:44:47 -0700136DEVICE_PARAM(int_works, "Number of packets per interrupt services");
Forest Bond5449c682009-04-25 10:30:44 -0400137
138#define CHANNEL_MIN 1
139#define CHANNEL_MAX 14
140#define CHANNEL_DEF 6
141
142DEVICE_PARAM(Channel, "Channel number");
143
Forest Bond5449c682009-04-25 10:30:44 -0400144/* PreambleType[] is the preamble length used for transmit.
145 0: indicate allows long preamble type
146 1: indicate allows short preamble type
147*/
148
149#define PREAMBLE_TYPE_DEF 1
150
151DEVICE_PARAM(PreambleType, "Preamble Type");
152
Forest Bond5449c682009-04-25 10:30:44 -0400153#define RTS_THRESH_MIN 512
154#define RTS_THRESH_MAX 2347
155#define RTS_THRESH_DEF 2347
156
157DEVICE_PARAM(RTSThreshold, "RTS threshold");
158
Forest Bond5449c682009-04-25 10:30:44 -0400159#define FRAG_THRESH_MIN 256
160#define FRAG_THRESH_MAX 2346
161#define FRAG_THRESH_DEF 2346
162
163DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
164
Forest Bond5449c682009-04-25 10:30:44 -0400165#define DATA_RATE_MIN 0
166#define DATA_RATE_MAX 13
167#define DATA_RATE_DEF 13
168/* datarate[] index
169 0: indicate 1 Mbps 0x02
170 1: indicate 2 Mbps 0x04
171 2: indicate 5.5 Mbps 0x0B
172 3: indicate 11 Mbps 0x16
173 4: indicate 6 Mbps 0x0c
174 5: indicate 9 Mbps 0x12
175 6: indicate 12 Mbps 0x18
176 7: indicate 18 Mbps 0x24
177 8: indicate 24 Mbps 0x30
178 9: indicate 36 Mbps 0x48
Joe Perches915006c2013-03-18 10:44:47 -0700179 10: indicate 48 Mbps 0x60
180 11: indicate 54 Mbps 0x6c
181 12: indicate 72 Mbps 0x90
182 13: indicate auto rate
Forest Bond5449c682009-04-25 10:30:44 -0400183*/
184
185DEVICE_PARAM(ConnectionRate, "Connection data rate");
186
187#define OP_MODE_DEF 0
188
189DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
190
191/* OpMode[] is used for transmit.
192 0: indicate infrastruct mode used
193 1: indicate adhoc mode used
194 2: indicate AP mode used
195*/
196
Forest Bond5449c682009-04-25 10:30:44 -0400197/* PSMode[]
198 0: indicate disable power saving mode
199 1: indicate enable power saving mode
200*/
201
202#define PS_MODE_DEF 0
203
204DEVICE_PARAM(PSMode, "Power saving mode");
205
Forest Bond5449c682009-04-25 10:30:44 -0400206#define SHORT_RETRY_MIN 0
207#define SHORT_RETRY_MAX 31
208#define SHORT_RETRY_DEF 8
209
Forest Bond5449c682009-04-25 10:30:44 -0400210DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
211
212#define LONG_RETRY_MIN 0
213#define LONG_RETRY_MAX 15
214#define LONG_RETRY_DEF 4
215
Forest Bond5449c682009-04-25 10:30:44 -0400216DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
217
Forest Bond5449c682009-04-25 10:30:44 -0400218/* BasebandType[] baseband type selected
219 0: indicate 802.11a type
220 1: indicate 802.11b type
221 2: indicate 802.11g type
222*/
223#define BBP_TYPE_MIN 0
224#define BBP_TYPE_MAX 2
225#define BBP_TYPE_DEF 2
226
227DEVICE_PARAM(BasebandType, "baseband type");
228
Forest Bond5449c682009-04-25 10:30:44 -0400229/* 80211hEnable[]
230 0: indicate disable 802.11h
231 1: indicate enable 802.11h
232*/
233
234#define X80211h_MODE_DEF 0
235
236DEVICE_PARAM(b80211hEnable, "802.11h mode");
237
238/* 80211hEnable[]
239 0: indicate disable 802.11h
240 1: indicate enable 802.11h
241*/
242
243#define DIVERSITY_ANT_DEF 0
244
245DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
246
Forest Bond5449c682009-04-25 10:30:44 -0400247//
248// Static vars definitions
249//
250
Joe Perches915006c2013-03-18 10:44:47 -0700251static int device_nics = 0;
252static PSDevice pDevice_Infos = NULL;
Forest Bond5449c682009-04-25 10:30:44 -0400253static struct net_device *root_device_dev = NULL;
254
Joe Perches915006c2013-03-18 10:44:47 -0700255static CHIP_INFO chip_info_table[] = {
256 { VT3253, "VIA Networking Solomon-A/B/G Wireless LAN Adapter ",
257 256, 1, DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN },
258 {0, NULL}
Forest Bond5449c682009-04-25 10:30:44 -0400259};
260
Guillaume Clement9e4c5c22014-07-22 22:08:28 +0200261static const struct pci_device_id vt6655_pci_id_table[] = {
Jim Liebdb6cb902009-07-23 17:20:49 -0700262 { PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
263 { 0, }
Forest Bond5449c682009-04-25 10:30:44 -0400264};
Forest Bond5449c682009-04-25 10:30:44 -0400265
266/*--------------------- Static Functions --------------------------*/
267
Charles Clément013a4682010-06-15 10:39:24 -0700268static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
Joe Perches915006c2013-03-18 10:44:47 -0700269static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, PCHIP_INFO);
Forest Bond5449c682009-04-25 10:30:44 -0400270static void device_free_info(PSDevice pDevice);
Joe Perches915006c2013-03-18 10:44:47 -0700271static bool device_get_pci_info(PSDevice, struct pci_dev *pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400272static void device_print_info(PSDevice pDevice);
273static struct net_device_stats *device_get_stats(struct net_device *dev);
274static void device_init_diversity_timer(PSDevice pDevice);
275static int device_open(struct net_device *dev);
276static int device_xmit(struct sk_buff *skb, struct net_device *dev);
Joe Perches915006c2013-03-18 10:44:47 -0700277static irqreturn_t device_intr(int irq, void *dev_instance);
Forest Bond5449c682009-04-25 10:30:44 -0400278static void device_set_multi(struct net_device *dev);
279static int device_close(struct net_device *dev);
280static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
281
Forest Bond5449c682009-04-25 10:30:44 -0400282#ifdef CONFIG_PM
283static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
Alan Coxf408ade2009-06-10 17:30:49 +0100284static int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
Forest Bond5449c682009-04-25 10:30:44 -0400285static int viawget_resume(struct pci_dev *pcid);
Guillaume Clement9e4c5c22014-07-22 22:08:28 +0200286static struct notifier_block device_notifier = {
Peter Huewe34381c22011-01-10 23:28:06 +0100287 .notifier_call = device_notify_reboot,
288 .next = NULL,
289 .priority = 0,
Forest Bond5449c682009-04-25 10:30:44 -0400290};
291#endif
Forest Bond5449c682009-04-25 10:30:44 -0400292
Forest Bond5449c682009-04-25 10:30:44 -0400293static void device_init_rd0_ring(PSDevice pDevice);
294static void device_init_rd1_ring(PSDevice pDevice);
295static void device_init_defrag_cb(PSDevice pDevice);
296static void device_init_td0_ring(PSDevice pDevice);
297static void device_init_td1_ring(PSDevice pDevice);
298
Forest Bond5449c682009-04-25 10:30:44 -0400299static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
Forest Bond5449c682009-04-25 10:30:44 -0400300//2008-0714<Add>by Mike Liu
Charles Clément7b6a0012010-08-01 17:15:50 +0200301static bool device_release_WPADEV(PSDevice pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400302
James A Shacklefordebc43d02014-05-31 20:09:05 -0400303static int ethtool_ioctl(struct net_device *dev, void __user *useraddr);
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700304static int device_rx_srv(PSDevice pDevice, unsigned int uIdx);
305static int device_tx_srv(PSDevice pDevice, unsigned int uIdx);
Charles Clément7b6a0012010-08-01 17:15:50 +0200306static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
Forest Bond5449c682009-04-25 10:30:44 -0400307static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
308static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
309static void device_free_td0_ring(PSDevice pDevice);
310static void device_free_td1_ring(PSDevice pDevice);
311static void device_free_rd0_ring(PSDevice pDevice);
312static void device_free_rd1_ring(PSDevice pDevice);
313static void device_free_rings(PSDevice pDevice);
314static void device_free_frag_buf(PSDevice pDevice);
Charles Clément5c9824e2010-06-02 09:51:59 -0700315static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -0700316 unsigned char *dest, unsigned char *source);
Forest Bond5449c682009-04-25 10:30:44 -0400317
Forest Bond5449c682009-04-25 10:30:44 -0400318/*--------------------- Export Variables --------------------------*/
319
320/*--------------------- Export Functions --------------------------*/
321
Joe Perches915006c2013-03-18 10:44:47 -0700322static char *get_chip_name(int chip_id)
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530323{
324 int i;
Guillaume Clement6b711272014-07-25 01:06:16 +0200325
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530326 for (i = 0; chip_info_table[i].name != NULL; i++)
327 if (chip_info_table[i].chip_id == chip_id)
328 break;
329 return chip_info_table[i].name;
Forest Bond5449c682009-04-25 10:30:44 -0400330}
331
Bill Pembertonf4e1b7c2012-11-19 13:26:53 -0500332static void vt6655_remove(struct pci_dev *pcid)
Forest Bond5449c682009-04-25 10:30:44 -0400333{
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530334 PSDevice pDevice = pci_get_drvdata(pcid);
Forest Bond5449c682009-04-25 10:30:44 -0400335
Devendra Naga3ac9e0f2012-09-07 00:08:02 +0530336 if (pDevice == NULL)
337 return;
338 device_free_info(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400339}
340
Joe Perches915006c2013-03-18 10:44:47 -0700341static void device_get_options(PSDevice pDevice, int index, char *devname)
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530342{
343 POPTIONS pOpts = &(pDevice->sOpts);
Forest Bond5449c682009-04-25 10:30:44 -0400344
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530345 pOpts->nRxDescs0 = RX_DESC_DEF0;
346 pOpts->nRxDescs1 = RX_DESC_DEF1;
347 pOpts->nTxDescs[0] = TX_DESC_DEF0;
348 pOpts->nTxDescs[1] = TX_DESC_DEF1;
349 pOpts->flags |= DEVICE_FLAGS_IP_ALIGN;
350 pOpts->int_works = INT_WORKS_DEF;
351 pOpts->rts_thresh = RTS_THRESH_DEF;
352 pOpts->frag_thresh = FRAG_THRESH_DEF;
353 pOpts->data_rate = DATA_RATE_DEF;
354 pOpts->channel_num = CHANNEL_DEF;
Forest Bond5449c682009-04-25 10:30:44 -0400355
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530356 pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE;
357 pOpts->flags |= DEVICE_FLAGS_OP_MODE;
Devendra Nagabf76ebd2012-09-07 00:08:03 +0530358 pOpts->short_retry = SHORT_RETRY_DEF;
359 pOpts->long_retry = LONG_RETRY_DEF;
360 pOpts->bbp_type = BBP_TYPE_DEF;
361 pOpts->flags |= DEVICE_FLAGS_80211h_MODE;
362 pOpts->flags |= DEVICE_FLAGS_DiversityANT;
Forest Bond5449c682009-04-25 10:30:44 -0400363}
364
365static void
366device_set_options(PSDevice pDevice) {
Joe Perches915006c2013-03-18 10:44:47 -0700367 unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
368 unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
369 unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
Forest Bond5449c682009-04-25 10:30:44 -0400370
Joe Perches915006c2013-03-18 10:44:47 -0700371 memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
372 memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
373 memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
Forest Bond5449c682009-04-25 10:30:44 -0400374
Joe Perches915006c2013-03-18 10:44:47 -0700375 pDevice->uChannel = pDevice->sOpts.channel_num;
376 pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh;
377 pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh;
378 pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
379 pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
380 pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
381 pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0;
382 pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0;
383 pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0;
384 pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
385 pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
386 pDevice->uConnectionRate = pDevice->sOpts.data_rate;
Guillaume Clementa1613422014-07-25 01:06:22 +0200387 if (pDevice->uConnectionRate < RATE_AUTO)
388 pDevice->bFixRate = true;
Joe Perches915006c2013-03-18 10:44:47 -0700389 pDevice->byBBType = pDevice->sOpts.bbp_type;
390 pDevice->byPacketType = pDevice->byBBType;
Forest Bond5449c682009-04-25 10:30:44 -0400391
392//PLICE_DEBUG->
393 pDevice->byAutoFBCtrl = AUTO_FB_0;
Forest Bond5449c682009-04-25 10:30:44 -0400394//PLICE_DEBUG<-
Joe Perches915006c2013-03-18 10:44:47 -0700395 pDevice->bUpdateBBVGA = true;
396 pDevice->byFOETuning = 0;
397 pDevice->wCTSDuration = 0;
398 pDevice->byPreambleType = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400399
Joe Perches915006c2013-03-18 10:44:47 -0700400 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uChannel= %d\n", (int)pDevice->uChannel);
401 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byOpMode= %d\n", (int)pDevice->byOpMode);
402 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ePSMode= %d\n", (int)pDevice->ePSMode);
403 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold);
404 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit);
405 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit);
406 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byPreambleType= %d\n", (int)pDevice->byPreambleType);
407 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
408 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uConnectionRate= %d\n", (int)pDevice->uConnectionRate);
409 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byBBType= %d\n", (int)pDevice->byBBType);
410 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable);
411 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON);
Forest Bond5449c682009-04-25 10:30:44 -0400412}
413
Joe Perches915006c2013-03-18 10:44:47 -0700414static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult)
Forest Bond5449c682009-04-25 10:30:44 -0400415{
Joe Perches915006c2013-03-18 10:44:47 -0700416 unsigned int ii;
417 unsigned long dwDuration = 0;
418 unsigned char byRPI0 = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400419
Joe Perches915006c2013-03-18 10:44:47 -0700420 for (ii = 1; ii < 8; ii++) {
421 pDevice->dwRPIs[ii] *= 255;
422 dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration));
423 dwDuration <<= 10;
424 pDevice->dwRPIs[ii] /= dwDuration;
425 pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii];
426 byRPI0 += pDevice->abyRPIs[ii];
427 }
428 pDevice->abyRPIs[0] = (0xFF - byRPI0);
Forest Bond5449c682009-04-25 10:30:44 -0400429
Joe Perches915006c2013-03-18 10:44:47 -0700430 if (pDevice->uNumOfMeasureEIDs == 0) {
431 VNTWIFIbMeasureReport(pDevice->pMgmt,
432 true,
433 pDevice->pCurrMeasureEID,
434 byResult,
435 pDevice->byBasicMap,
436 pDevice->byCCAFraction,
437 pDevice->abyRPIs
438 );
439 } else {
440 VNTWIFIbMeasureReport(pDevice->pMgmt,
441 false,
442 pDevice->pCurrMeasureEID,
443 byResult,
444 pDevice->byBasicMap,
445 pDevice->byCCAFraction,
446 pDevice->abyRPIs
447 );
448 CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs);
449 }
Forest Bond5449c682009-04-25 10:30:44 -0400450}
451
Forest Bond5449c682009-04-25 10:30:44 -0400452//
Justin P. Mattock789d1ae2012-08-20 08:43:13 -0700453// Initialisation of MAC & BBP registers
Forest Bond5449c682009-04-25 10:30:44 -0400454//
455
456static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
457{
Joe Perches915006c2013-03-18 10:44:47 -0700458 unsigned int ii;
459 unsigned char byValue;
460 unsigned char byValue1;
461 unsigned char byCCKPwrdBm = 0;
462 unsigned char byOFDMPwrdBm = 0;
463 int zonetype = 0;
464 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
Guillaume Clement6b711272014-07-25 01:06:16 +0200465
Joe Perches915006c2013-03-18 10:44:47 -0700466 MACbShutdown(pDevice->PortOffset);
467 BBvSoftwareReset(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400468
Joe Perches915006c2013-03-18 10:44:47 -0700469 if ((InitType == DEVICE_INIT_COLD) ||
470 (InitType == DEVICE_INIT_DXPL)) {
471 // Do MACbSoftwareReset in MACvInitialize
472 MACbSoftwareReset(pDevice->PortOffset);
473 // force CCK
474 pDevice->bCCK = true;
475 pDevice->bAES = false;
476 pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE
477 pDevice->bNonERPPresent = false;
478 pDevice->bBarkerPreambleMd = false;
479 pDevice->wCurrentRate = RATE_1M;
480 pDevice->byTopOFDMBasicRate = RATE_24M;
481 pDevice->byTopCCKBasicRate = RATE_1M;
Forest Bond5449c682009-04-25 10:30:44 -0400482
Joe Perches915006c2013-03-18 10:44:47 -0700483 pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
Forest Bond5449c682009-04-25 10:30:44 -0400484
Joe Perches915006c2013-03-18 10:44:47 -0700485 // init MAC
486 MACvInitialize(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400487
Joe Perches915006c2013-03-18 10:44:47 -0700488 // Get Local ID
489 VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID));
Forest Bond5449c682009-04-25 10:30:44 -0400490
Joe Perches915006c2013-03-18 10:44:47 -0700491 spin_lock_irq(&pDevice->lock);
492 SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
Forest Bond5449c682009-04-25 10:30:44 -0400493
Joe Perches915006c2013-03-18 10:44:47 -0700494 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -0400495
Joe Perches915006c2013-03-18 10:44:47 -0700496 // Get Channel range
Forest Bond5449c682009-04-25 10:30:44 -0400497
Joe Perches915006c2013-03-18 10:44:47 -0700498 pDevice->byMinChannel = 1;
499 pDevice->byMaxChannel = CB_MAX_CHANNEL;
Forest Bond5449c682009-04-25 10:30:44 -0400500
Joe Perches915006c2013-03-18 10:44:47 -0700501 // Get Antena
502 byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
503 if (byValue & EEP_ANTINV)
504 pDevice->bTxRxAntInv = true;
505 else
506 pDevice->bTxRxAntInv = false;
Forest Bond5449c682009-04-25 10:30:44 -0400507
Joe Perches915006c2013-03-18 10:44:47 -0700508 byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
509 if (byValue == 0) // if not set default is All
510 byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
Joe Perchesf2046f92013-03-18 20:55:36 -0700511
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300512 pDevice->ulDiversityNValue = 100*260;
513 pDevice->ulDiversityMValue = 100*16;
514 pDevice->byTMax = 1;
515 pDevice->byTMax2 = 4;
516 pDevice->ulSQ3TH = 0;
517 pDevice->byTMax3 = 64;
Forest Bond5449c682009-04-25 10:30:44 -0400518
Joe Perches915006c2013-03-18 10:44:47 -0700519 if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
520 pDevice->byAntennaCount = 2;
521 pDevice->byTxAntennaMode = ANT_B;
522 pDevice->dwTxAntennaSel = 1;
523 pDevice->dwRxAntennaSel = 1;
Teodora Baluta1208f142013-11-10 17:12:42 +0200524 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700525 pDevice->byRxAntennaMode = ANT_A;
526 else
527 pDevice->byRxAntennaMode = ANT_B;
528 // chester for antenna
529 byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
Joe Perches915006c2013-03-18 10:44:47 -0700530 if ((byValue1 & 0x08) == 0)
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300531 pDevice->bDiversityEnable = false;
Joe Perches915006c2013-03-18 10:44:47 -0700532 else
533 pDevice->bDiversityEnable = true;
Joe Perches915006c2013-03-18 10:44:47 -0700534 } else {
535 pDevice->bDiversityEnable = false;
536 pDevice->byAntennaCount = 1;
537 pDevice->dwTxAntennaSel = 0;
538 pDevice->dwRxAntennaSel = 0;
539 if (byValue & EEP_ANTENNA_AUX) {
540 pDevice->byTxAntennaMode = ANT_A;
Teodora Baluta1208f142013-11-10 17:12:42 +0200541 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700542 pDevice->byRxAntennaMode = ANT_B;
543 else
544 pDevice->byRxAntennaMode = ANT_A;
545 } else {
546 pDevice->byTxAntennaMode = ANT_B;
Teodora Baluta1208f142013-11-10 17:12:42 +0200547 if (pDevice->bTxRxAntInv)
Joe Perches915006c2013-03-18 10:44:47 -0700548 pDevice->byRxAntennaMode = ANT_A;
549 else
550 pDevice->byRxAntennaMode = ANT_B;
551 }
552 }
Joe Perches915006c2013-03-18 10:44:47 -0700553 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
554 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2);
Forest Bond5449c682009-04-25 10:30:44 -0400555
Forest Bond5449c682009-04-25 10:30:44 -0400556//2008-8-4 <add> by chester
557//zonetype initial
Joe Perches915006c2013-03-18 10:44:47 -0700558 pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
559 zonetype = Config_FileOperation(pDevice, false, NULL);
560 if (zonetype >= 0) { //read zonetype file ok!
561 if ((zonetype == 0) &&
562 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { //for USA
563 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
564 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
565 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700566 } else if ((zonetype == 1) &&
Joe Perches915006c2013-03-18 10:44:47 -0700567 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { //for Japan
568 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
569 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700570 } else if ((zonetype == 2) &&
Joe Perches915006c2013-03-18 10:44:47 -0700571 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { //for Europe
572 pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
573 pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
574 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n");
575 }
Forest Bond5449c682009-04-25 10:30:44 -0400576
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700577 else {
Joe Perches915006c2013-03-18 10:44:47 -0700578 if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
Guillaume Clement941ead92014-07-25 01:06:21 +0200579 pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", zonetype, pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
Joe Perches915006c2013-03-18 10:44:47 -0700580 else
Guillaume Clement941ead92014-07-25 01:06:21 +0200581 pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n", zonetype);
Joe Perches915006c2013-03-18 10:44:47 -0700582 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700583 } else
Guillaume Clement941ead92014-07-25 01:06:21 +0200584 pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n", SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
Forest Bond5449c682009-04-25 10:30:44 -0400585
Joe Perches915006c2013-03-18 10:44:47 -0700586 // Get RFType
587 pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
Forest Bond5449c682009-04-25 10:30:44 -0400588
Joe Perches915006c2013-03-18 10:44:47 -0700589 if ((pDevice->byRFType & RF_EMU) != 0) {
590 // force change RevID for VT3253 emu
591 pDevice->byRevId = 0x80;
592 }
Forest Bond5449c682009-04-25 10:30:44 -0400593
Joe Perches915006c2013-03-18 10:44:47 -0700594 pDevice->byRFType &= RF_MASK;
595 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
Forest Bond5449c682009-04-25 10:30:44 -0400596
Guido Martínezbc5cf652014-04-19 16:45:00 -0300597 if (!pDevice->bZoneRegExist)
Joe Perches915006c2013-03-18 10:44:47 -0700598 pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
Guido Martínezbc5cf652014-04-19 16:45:00 -0300599
Joe Perches915006c2013-03-18 10:44:47 -0700600 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
Forest Bond5449c682009-04-25 10:30:44 -0400601
Joe Perches915006c2013-03-18 10:44:47 -0700602 //Init RF module
603 RFbInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400604
Joe Perches915006c2013-03-18 10:44:47 -0700605 //Get Desire Power Value
606 pDevice->byCurPwr = 0xFF;
607 pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
608 pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
Joe Perchesf2046f92013-03-18 20:55:36 -0700609
Forest Bond5449c682009-04-25 10:30:44 -0400610 // Load power Table
611
Joe Perches915006c2013-03-18 10:44:47 -0700612 for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
613 pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
Guido Martínezbc5cf652014-04-19 16:45:00 -0300614 if (pDevice->abyCCKPwrTbl[ii + 1] == 0)
Joe Perches915006c2013-03-18 10:44:47 -0700615 pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300616
Joe Perches915006c2013-03-18 10:44:47 -0700617 pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
Guido Martínezbc5cf652014-04-19 16:45:00 -0300618 if (pDevice->abyOFDMPwrTbl[ii + 1] == 0)
Joe Perches915006c2013-03-18 10:44:47 -0700619 pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300620
Joe Perches915006c2013-03-18 10:44:47 -0700621 pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
622 pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
623 }
Forest Bond5449c682009-04-25 10:30:44 -0400624 //2008-8-4 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -0700625 //recover 12,13 ,14channel for EUROPE by 11 channel
626 if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
627 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
628 (pDevice->byOriginalZonetype == ZoneType_USA)) {
629 for (ii = 11; ii < 14; ii++) {
630 pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
631 pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
Forest Bond5449c682009-04-25 10:30:44 -0400632
Joe Perches915006c2013-03-18 10:44:47 -0700633 }
634 }
Forest Bond5449c682009-04-25 10:30:44 -0400635
Joe Perches915006c2013-03-18 10:44:47 -0700636 // Load OFDM A Power Table
637 for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
638 pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
639 pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
640 }
641 init_channel_table((void *)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400642
Joe Perches915006c2013-03-18 10:44:47 -0700643 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
644 MACvSelectPage1(pDevice->PortOffset);
645 VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
646 MACvSelectPage0(pDevice->PortOffset);
647 }
Forest Bond5449c682009-04-25 10:30:44 -0400648
Joe Perches915006c2013-03-18 10:44:47 -0700649 // use relative tx timeout and 802.11i D4
650 MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
Forest Bond5449c682009-04-25 10:30:44 -0400651
Joe Perches915006c2013-03-18 10:44:47 -0700652 // set performance parameter by registry
653 MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
654 MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
Forest Bond5449c682009-04-25 10:30:44 -0400655
Joe Perches915006c2013-03-18 10:44:47 -0700656 // reset TSF counter
657 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
658 // enable TSF counter
659 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
Forest Bond5449c682009-04-25 10:30:44 -0400660
Joe Perches915006c2013-03-18 10:44:47 -0700661 // initialize BBP registers
662 BBbVT3253Init(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400663
Joe Perches915006c2013-03-18 10:44:47 -0700664 if (pDevice->bUpdateBBVGA) {
665 pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
666 pDevice->byBBVGANew = pDevice->byBBVGACurrent;
667 BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
668 }
Joe Perches915006c2013-03-18 10:44:47 -0700669 BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
670 BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
Forest Bond5449c682009-04-25 10:30:44 -0400671
Joe Perches915006c2013-03-18 10:44:47 -0700672 pDevice->byCurrentCh = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400673
Joe Perches915006c2013-03-18 10:44:47 -0700674 // Set BB and packet type at the same time.
675 // Set Short Slot Time, xIFS, and RSPINF.
Guido Martínezbc5cf652014-04-19 16:45:00 -0300676 if (pDevice->uConnectionRate == RATE_AUTO)
Joe Perches915006c2013-03-18 10:44:47 -0700677 pDevice->wCurrentRate = RATE_54M;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300678 else
Joe Perches915006c2013-03-18 10:44:47 -0700679 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Forest Bond5449c682009-04-25 10:30:44 -0400680
Joe Perches915006c2013-03-18 10:44:47 -0700681 // default G Mode
682 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
683 VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
Forest Bond5449c682009-04-25 10:30:44 -0400684
Joe Perches915006c2013-03-18 10:44:47 -0700685 pDevice->bRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400686
Joe Perches915006c2013-03-18 10:44:47 -0700687 pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
688 pDevice->bHWRadioOff = false;
Forest Bond5449c682009-04-25 10:30:44 -0400689
Joe Perches915006c2013-03-18 10:44:47 -0700690 if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
691 // Get GPIO
692 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
Forest Bond5449c682009-04-25 10:30:44 -0400693//2008-4-14 <add> by chester for led issue
Joe Perches915006c2013-03-18 10:44:47 -0700694 if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
695 (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
696 pDevice->bHWRadioOff = true;
697 }
698 }
Guido Martínezbc5cf652014-04-19 16:45:00 -0300699 if (pDevice->bHWRadioOff || pDevice->bRadioControlOff)
Joe Perches915006c2013-03-18 10:44:47 -0700700 CARDbRadioPowerOff(pDevice);
Joe Perches915006c2013-03-18 10:44:47 -0700701}
702pMgmt->eScanType = WMAC_SCAN_PASSIVE;
703// get Permanent network address
704SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
705DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n",
706 pDevice->abyCurrentNetAddr);
Forest Bond5449c682009-04-25 10:30:44 -0400707
Joe Perches915006c2013-03-18 10:44:47 -0700708// reset Tx pointer
709CARDvSafeResetRx(pDevice);
710// reset Rx pointer
711CARDvSafeResetTx(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -0400712
Guido Martínezbc5cf652014-04-19 16:45:00 -0300713if (pDevice->byLocalID <= REV_ID_VT3253_A1)
Joe Perches915006c2013-03-18 10:44:47 -0700714 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
Forest Bond5449c682009-04-25 10:30:44 -0400715
Joe Perches915006c2013-03-18 10:44:47 -0700716pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
Forest Bond5449c682009-04-25 10:30:44 -0400717
Joe Perches915006c2013-03-18 10:44:47 -0700718// Turn On Rx DMA
719MACvReceive0(pDevice->PortOffset);
720MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400721
Joe Perches915006c2013-03-18 10:44:47 -0700722// start the adapter
723MACvStart(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -0400724
Joe Perches915006c2013-03-18 10:44:47 -0700725netif_stop_queue(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400726}
727
Guillaume Clement84b50762014-07-25 01:06:18 +0200728static void device_init_diversity_timer(PSDevice pDevice)
729{
Joe Perches915006c2013-03-18 10:44:47 -0700730 init_timer(&pDevice->TimerSQ3Tmax1);
731 pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
732 pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
733 pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400734
Joe Perches915006c2013-03-18 10:44:47 -0700735 init_timer(&pDevice->TimerSQ3Tmax2);
736 pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
737 pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
738 pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400739
Joe Perches915006c2013-03-18 10:44:47 -0700740 init_timer(&pDevice->TimerSQ3Tmax3);
741 pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
742 pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
743 pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
Forest Bond5449c682009-04-25 10:30:44 -0400744}
745
Charles Clément7b6a0012010-08-01 17:15:50 +0200746static bool device_release_WPADEV(PSDevice pDevice)
Forest Bond5449c682009-04-25 10:30:44 -0400747{
Joe Perches915006c2013-03-18 10:44:47 -0700748 viawget_wpa_header *wpahdr;
749 int ii = 0;
Guido Martínez4e8a7e52014-04-19 16:44:59 -0300750
Joe Perches915006c2013-03-18 10:44:47 -0700751 //send device close to wpa_supplicnat layer
Teodora Baluta1208f142013-11-10 17:12:42 +0200752 if (pDevice->bWPADEVUp) {
Joe Perches915006c2013-03-18 10:44:47 -0700753 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
754 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
755 wpahdr->resp_ie_len = 0;
756 wpahdr->req_ie_len = 0;
757 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
758 pDevice->skb->dev = pDevice->wpadev;
759 skb_reset_mac_header(pDevice->skb);
760 pDevice->skb->pkt_type = PACKET_HOST;
761 pDevice->skb->protocol = htons(ETH_P_802_2);
762 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
763 netif_rx(pDevice->skb);
764 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Forest Bond5449c682009-04-25 10:30:44 -0400765
Teodora Baluta1208f142013-11-10 17:12:42 +0200766 while (pDevice->bWPADEVUp) {
Joe Perches915006c2013-03-18 10:44:47 -0700767 set_current_state(TASK_UNINTERRUPTIBLE);
768 schedule_timeout(HZ / 20); //wait 50ms
769 ii++;
770 if (ii > 20)
771 break;
772 }
773 }
774 return true;
Forest Bond5449c682009-04-25 10:30:44 -0400775}
776
Forest Bond57211352009-06-02 14:44:33 -0400777static const struct net_device_ops device_netdev_ops = {
Devendra Naga502eb532012-09-07 00:08:04 +0530778 .ndo_open = device_open,
779 .ndo_stop = device_close,
780 .ndo_do_ioctl = device_ioctl,
781 .ndo_get_stats = device_get_stats,
782 .ndo_start_xmit = device_xmit,
783 .ndo_set_rx_mode = device_set_multi,
Forest Bond57211352009-06-02 14:44:33 -0400784};
785
Bill Pembertona1179b22012-11-19 13:21:54 -0500786static int
Charles Clément013a4682010-06-15 10:39:24 -0700787vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
Forest Bond5449c682009-04-25 10:30:44 -0400788{
Joe Perches915006c2013-03-18 10:44:47 -0700789 static bool bFirst = true;
790 struct net_device *dev = NULL;
791 PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data;
792 PSDevice pDevice;
793 int rc;
Guillaume Clement941ead92014-07-25 01:06:21 +0200794
Joe Perches915006c2013-03-18 10:44:47 -0700795 if (device_nics++ >= MAX_UINTS) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200796 pr_notice(DEVICE_NAME ": already found %d NICs\n", device_nics);
Joe Perches915006c2013-03-18 10:44:47 -0700797 return -ENODEV;
798 }
Forest Bond5449c682009-04-25 10:30:44 -0400799
Joe Perches915006c2013-03-18 10:44:47 -0700800 dev = alloc_etherdev(sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -0400801
Joe Perches915006c2013-03-18 10:44:47 -0700802 pDevice = (PSDevice) netdev_priv(dev);
Forest Bondc9d03522009-06-01 20:00:14 -0400803
Joe Perches915006c2013-03-18 10:44:47 -0700804 if (dev == NULL) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200805 pr_err(DEVICE_NAME ": allocate net device failed\n");
Joe Perches915006c2013-03-18 10:44:47 -0700806 return -ENOMEM;
807 }
Forest Bond5449c682009-04-25 10:30:44 -0400808
Joe Perches915006c2013-03-18 10:44:47 -0700809 // Chain it all together
Joe Perches915006c2013-03-18 10:44:47 -0700810 SET_NETDEV_DEV(dev, &pcid->dev);
Forest Bond5449c682009-04-25 10:30:44 -0400811
Joe Perches915006c2013-03-18 10:44:47 -0700812 if (bFirst) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200813 pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
814 pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
Joe Perches915006c2013-03-18 10:44:47 -0700815 bFirst = false;
816 }
Forest Bond5449c682009-04-25 10:30:44 -0400817
Joe Perches915006c2013-03-18 10:44:47 -0700818 vt6655_init_info(pcid, &pDevice, pChip_info);
819 pDevice->dev = dev;
820 pDevice->next_module = root_device_dev;
821 root_device_dev = dev;
Forest Bond5449c682009-04-25 10:30:44 -0400822
Joe Perches915006c2013-03-18 10:44:47 -0700823 if (pci_enable_device(pcid)) {
824 device_free_info(pDevice);
825 return -ENODEV;
826 }
827 dev->irq = pcid->irq;
Kulikov Vasiliy13b631a2010-08-03 19:44:20 +0400828
Forest Bond5449c682009-04-25 10:30:44 -0400829#ifdef DEBUG
Guillaume Clement941ead92014-07-25 01:06:21 +0200830 pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr);
Forest Bond5449c682009-04-25 10:30:44 -0400831#endif
Teodora Baluta1208f142013-11-10 17:12:42 +0200832 if (!device_get_pci_info(pDevice, pcid)) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200833 pr_err(DEVICE_NAME ": Failed to find PCI device.\n");
Joe Perches915006c2013-03-18 10:44:47 -0700834 device_free_info(pDevice);
835 return -ENODEV;
836 }
Forest Bond5449c682009-04-25 10:30:44 -0400837
838#if 1
839
840#ifdef DEBUG
841
Guillaume Clement941ead92014-07-25 01:06:21 +0200842 pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size);
Forest Bond5449c682009-04-25 10:30:44 -0400843 {
844 int i;
Joe Perches915006c2013-03-18 10:44:47 -0700845 u32 bar, len;
Forest Bond5449c682009-04-25 10:30:44 -0400846 u32 address[] = {
Joe Perches915006c2013-03-18 10:44:47 -0700847 PCI_BASE_ADDRESS_0,
848 PCI_BASE_ADDRESS_1,
849 PCI_BASE_ADDRESS_2,
850 PCI_BASE_ADDRESS_3,
851 PCI_BASE_ADDRESS_4,
852 PCI_BASE_ADDRESS_5,
853 0};
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700854 for (i = 0; address[i]; i++) {
Forest Bond5449c682009-04-25 10:30:44 -0400855 pci_read_config_dword(pcid, address[i], &bar);
Guillaume Clement941ead92014-07-25 01:06:21 +0200856 pr_debug("bar %d is %x\n", i, bar);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700857 if (!bar) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200858 pr_debug("bar %d not implemented\n", i);
Forest Bond5449c682009-04-25 10:30:44 -0400859 continue;
860 }
861 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
Joe Perches915006c2013-03-18 10:44:47 -0700862 /* This is IO */
Forest Bond5449c682009-04-25 10:30:44 -0400863
Joe Perches915006c2013-03-18 10:44:47 -0700864 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
865 len = len & ~(len - 1);
Forest Bond5449c682009-04-25 10:30:44 -0400866
Guillaume Clement941ead92014-07-25 01:06:21 +0200867 pr_debug("IO space: len in IO %x, BAR %d\n", len, i);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700868 } else {
Forest Bond5449c682009-04-25 10:30:44 -0400869 len = bar & 0xFFFFFFF0;
870 len = ~len + 1;
871
Guillaume Clement941ead92014-07-25 01:06:21 +0200872 pr_debug("len in MEM %x, BAR %d\n", len, i);
Forest Bond5449c682009-04-25 10:30:44 -0400873 }
874 }
875 }
876#endif
877
Forest Bond5449c682009-04-25 10:30:44 -0400878#endif
879
Guillaume Clement16834402014-07-22 22:08:26 +0200880 pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
Forest Bond5449c682009-04-25 10:30:44 -0400881
Guillaume Clement16834402014-07-22 22:08:26 +0200882 if (pDevice->PortOffset == NULL) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200883 pr_err(DEVICE_NAME ": Failed to IO remapping ..\n");
Joe Perches915006c2013-03-18 10:44:47 -0700884 device_free_info(pDevice);
885 return -ENODEV;
886 }
Forest Bond5449c682009-04-25 10:30:44 -0400887
Joe Perches915006c2013-03-18 10:44:47 -0700888 rc = pci_request_regions(pcid, DEVICE_NAME);
889 if (rc) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200890 pr_err(DEVICE_NAME ": Failed to find PCI device\n");
Joe Perches915006c2013-03-18 10:44:47 -0700891 device_free_info(pDevice);
892 return -ENODEV;
893 }
Forest Bond5449c682009-04-25 10:30:44 -0400894
Joe Perches915006c2013-03-18 10:44:47 -0700895 dev->base_addr = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400896#ifdef PLICE_DEBUG
Joe Perches915006c2013-03-18 10:44:47 -0700897 unsigned char value;
Forest Bond5449c682009-04-25 10:30:44 -0400898
899 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Guillaume Clement941ead92014-07-25 01:06:21 +0200900 pr_debug("Before write: value is %x\n", value);
Joe Perches915006c2013-03-18 10:44:47 -0700901 VNSvOutPortB(pDevice->PortOffset, value);
Forest Bond5449c682009-04-25 10:30:44 -0400902 VNSvInPortB(pDevice->PortOffset+0x4F, &value);
Guillaume Clement941ead92014-07-25 01:06:21 +0200903 pr_debug("After write: value is %x\n", value);
Forest Bond5449c682009-04-25 10:30:44 -0400904#endif
905
Forest Bond5449c682009-04-25 10:30:44 -0400906#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -0700907 pDevice->PortOffset = pDevice->ioaddr;
Forest Bond5449c682009-04-25 10:30:44 -0400908#endif
Joe Perches915006c2013-03-18 10:44:47 -0700909 // do reset
910 if (!MACbSoftwareReset(pDevice->PortOffset)) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200911 pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n");
Joe Perches915006c2013-03-18 10:44:47 -0700912 device_free_info(pDevice);
913 return -ENODEV;
914 }
915 // initial to reload eeprom
916 MACvInitialize(pDevice->PortOffset);
917 MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -0400918
Joe Perches915006c2013-03-18 10:44:47 -0700919 device_get_options(pDevice, device_nics-1, dev->name);
920 device_set_options(pDevice);
921 //Mask out the options cannot be set to the chip
922 pDevice->sOpts.flags &= pChip_info->flags;
Forest Bond5449c682009-04-25 10:30:44 -0400923
Joe Perches915006c2013-03-18 10:44:47 -0700924 //Enable the chip specified capabilities
925 pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL);
926 pDevice->tx_80211 = device_dma0_tx_80211;
927 pDevice->sMgmtObj.pAdapter = (void *)pDevice;
928 pDevice->pMgmt = &(pDevice->sMgmtObj);
Forest Bond5449c682009-04-25 10:30:44 -0400929
Joe Perches915006c2013-03-18 10:44:47 -0700930 dev->irq = pcid->irq;
931 dev->netdev_ops = &device_netdev_ops;
Forest Bond5449c682009-04-25 10:30:44 -0400932
Forest Bond5449c682009-04-25 10:30:44 -0400933 dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
Forest Bond5449c682009-04-25 10:30:44 -0400934
Joe Perches915006c2013-03-18 10:44:47 -0700935 rc = register_netdev(dev);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700936 if (rc) {
Guillaume Clement941ead92014-07-25 01:06:21 +0200937 pr_err(DEVICE_NAME " Failed to register netdev\n");
Joe Perches915006c2013-03-18 10:44:47 -0700938 device_free_info(pDevice);
939 return -ENODEV;
940 }
941 device_print_info(pDevice);
942 pci_set_drvdata(pcid, pDevice);
943 return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400944}
945
946static void device_print_info(PSDevice pDevice)
947{
Joe Perches915006c2013-03-18 10:44:47 -0700948 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -0400949
Joe Perches915006c2013-03-18 10:44:47 -0700950 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id));
951 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
Forest Bond5449c682009-04-25 10:30:44 -0400952#ifdef IO_MAP
Joe Perches915006c2013-03-18 10:44:47 -0700953 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx ", (unsigned long)pDevice->ioaddr);
Guillaume Clementbfd7a282014-07-25 01:06:17 +0200954 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -0400955#else
Joe Perches915006c2013-03-18 10:44:47 -0700956 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ",
957 (unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset);
Guillaume Clementbfd7a282014-07-25 01:06:17 +0200958 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq);
Forest Bond5449c682009-04-25 10:30:44 -0400959#endif
Forest Bond5449c682009-04-25 10:30:44 -0400960}
961
Joe Perches915006c2013-03-18 10:44:47 -0700962static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice,
963 PCHIP_INFO pChip_info) {
Joe Perches915006c2013-03-18 10:44:47 -0700964 PSDevice p;
Forest Bond5449c682009-04-25 10:30:44 -0400965
Joe Perches915006c2013-03-18 10:44:47 -0700966 memset(*ppDevice, 0, sizeof(DEVICE_INFO));
Forest Bond5449c682009-04-25 10:30:44 -0400967
Joe Perches915006c2013-03-18 10:44:47 -0700968 if (pDevice_Infos == NULL) {
969 pDevice_Infos = *ppDevice;
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700970 } else {
Joe Perches915006c2013-03-18 10:44:47 -0700971 for (p = pDevice_Infos; p->next != NULL; p = p->next)
972 do {} while (0);
973 p->next = *ppDevice;
974 (*ppDevice)->prev = p;
975 }
Forest Bond5449c682009-04-25 10:30:44 -0400976
Joe Perches915006c2013-03-18 10:44:47 -0700977 (*ppDevice)->pcid = pcid;
978 (*ppDevice)->chip_id = pChip_info->chip_id;
979 (*ppDevice)->io_size = pChip_info->io_size;
980 (*ppDevice)->nTxQueues = pChip_info->nTxQueue;
981 (*ppDevice)->multicast_limit = 32;
Forest Bond5449c682009-04-25 10:30:44 -0400982
Joe Perches915006c2013-03-18 10:44:47 -0700983 spin_lock_init(&((*ppDevice)->lock));
Forest Bond5449c682009-04-25 10:30:44 -0400984}
985
Guillaume Clement84b50762014-07-25 01:06:18 +0200986static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid)
987{
Joe Perches915006c2013-03-18 10:44:47 -0700988 u16 pci_cmd;
989 u8 b;
990 unsigned int cis_addr;
Forest Bond5449c682009-04-25 10:30:44 -0400991#ifdef PLICE_DEBUG
Charles Clément3fc9b582010-06-24 11:02:27 -0700992 unsigned char pci_config[256];
Joe Perches915006c2013-03-18 10:44:47 -0700993 unsigned char value = 0x00;
994 int ii, j;
995 u16 max_lat = 0x0000;
Guillaume Clement6b711272014-07-25 01:06:16 +0200996
Joe Perches915006c2013-03-18 10:44:47 -0700997 memset(pci_config, 0x00, 256);
Forest Bond5449c682009-04-25 10:30:44 -0400998#endif
999
Joe Perches915006c2013-03-18 10:44:47 -07001000 pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId);
1001 pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pDevice->SubSystemID);
1002 pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID);
1003 pci_read_config_word(pcid, PCI_COMMAND, (u16 *)&(pci_cmd));
Forest Bond5449c682009-04-25 10:30:44 -04001004
Joe Perches915006c2013-03-18 10:44:47 -07001005 pci_set_master(pcid);
Forest Bond5449c682009-04-25 10:30:44 -04001006
Joe Perches915006c2013-03-18 10:44:47 -07001007 pDevice->memaddr = pci_resource_start(pcid, 0);
1008 pDevice->ioaddr = pci_resource_start(pcid, 1);
Forest Bond5449c682009-04-25 10:30:44 -04001009
Joe Perches915006c2013-03-18 10:44:47 -07001010 cis_addr = pci_resource_start(pcid, 2);
Forest Bond5449c682009-04-25 10:30:44 -04001011
Joe Perches915006c2013-03-18 10:44:47 -07001012 pDevice->pcid = pcid;
Forest Bond5449c682009-04-25 10:30:44 -04001013
Joe Perches915006c2013-03-18 10:44:47 -07001014 pci_read_config_byte(pcid, PCI_COMMAND, &b);
1015 pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER));
Forest Bond5449c682009-04-25 10:30:44 -04001016
1017#ifdef PLICE_DEBUG
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001018 for (ii = 0; ii < 0xFF; ii++) {
Joe Perches915006c2013-03-18 10:44:47 -07001019 pci_read_config_byte(pcid, ii, &value);
Forest Bond5449c682009-04-25 10:30:44 -04001020 pci_config[ii] = value;
1021 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001022 for (ii = 0, j = 1; ii < 0x100; ii++, j++) {
1023 if (j % 16 == 0) {
Guillaume Clement941ead92014-07-25 01:06:21 +02001024 pr_debug("%x:", pci_config[ii]);
1025 pr_debug("\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001026 } else {
Guillaume Clement941ead92014-07-25 01:06:21 +02001027 pr_debug("%x:", pci_config[ii]);
Forest Bond5449c682009-04-25 10:30:44 -04001028 }
1029 }
1030#endif
Joe Perches915006c2013-03-18 10:44:47 -07001031 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001032}
1033
Guillaume Clement84b50762014-07-25 01:06:18 +02001034static void device_free_info(PSDevice pDevice)
1035{
Joe Perches915006c2013-03-18 10:44:47 -07001036 PSDevice ptr;
1037 struct net_device *dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001038
Joe Perches915006c2013-03-18 10:44:47 -07001039 ASSERT(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001040//2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001041 device_release_WPADEV(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001042
1043//2008-07-21-01<Add>by MikeLiu
1044//unregister wpadev
Joe Perches915006c2013-03-18 10:44:47 -07001045 if (wpa_set_wpadev(pDevice, 0) != 0)
Guillaume Clement941ead92014-07-25 01:06:21 +02001046 pr_err("unregister wpadev fail?\n");
Forest Bond5449c682009-04-25 10:30:44 -04001047
Joe Perches915006c2013-03-18 10:44:47 -07001048 if (pDevice_Infos == NULL)
1049 return;
Forest Bond5449c682009-04-25 10:30:44 -04001050
Joe Perches915006c2013-03-18 10:44:47 -07001051 for (ptr = pDevice_Infos; ptr && (ptr != pDevice); ptr = ptr->next)
1052 do {} while (0);
Forest Bond5449c682009-04-25 10:30:44 -04001053
Joe Perches915006c2013-03-18 10:44:47 -07001054 if (ptr == pDevice) {
1055 if (ptr == pDevice_Infos)
1056 pDevice_Infos = ptr->next;
1057 else
1058 ptr->prev->next = ptr->next;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001059 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001060 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
1061 return;
1062 }
Forest Bond5449c682009-04-25 10:30:44 -04001063#ifdef HOSTAP
Joe Perches915006c2013-03-18 10:44:47 -07001064 if (dev)
1065 vt6655_hostap_set_hostapd(pDevice, 0, 0);
Forest Bond5449c682009-04-25 10:30:44 -04001066#endif
Joe Perches915006c2013-03-18 10:44:47 -07001067 if (dev)
1068 unregister_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001069
Joe Perches915006c2013-03-18 10:44:47 -07001070 if (pDevice->PortOffset)
Guillaume Clement16834402014-07-22 22:08:26 +02001071 iounmap(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04001072
Joe Perches915006c2013-03-18 10:44:47 -07001073 if (pDevice->pcid)
1074 pci_release_regions(pDevice->pcid);
1075 if (dev)
1076 free_netdev(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001077}
Forest Bond5449c682009-04-25 10:30:44 -04001078
Guillaume Clement84b50762014-07-25 01:06:18 +02001079static bool device_init_rings(PSDevice pDevice)
1080{
Joe Perches915006c2013-03-18 10:44:47 -07001081 void *vir_pool;
Forest Bond5449c682009-04-25 10:30:44 -04001082
Joe Perches915006c2013-03-18 10:44:47 -07001083 /*allocate all RD/TD rings a single pool*/
1084 vir_pool = pci_alloc_consistent(pDevice->pcid,
1085 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1086 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1087 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1088 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1089 &pDevice->pool_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001090
Joe Perches915006c2013-03-18 10:44:47 -07001091 if (vir_pool == NULL) {
1092 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
1093 return false;
1094 }
Forest Bond5449c682009-04-25 10:30:44 -04001095
Joe Perches915006c2013-03-18 10:44:47 -07001096 memset(vir_pool, 0,
1097 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1098 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1099 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1100 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1101 );
Forest Bond5449c682009-04-25 10:30:44 -04001102
Joe Perches915006c2013-03-18 10:44:47 -07001103 pDevice->aRD0Ring = vir_pool;
1104 pDevice->aRD1Ring = vir_pool +
1105 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001106
Joe Perches915006c2013-03-18 10:44:47 -07001107 pDevice->rd0_pool_dma = pDevice->pool_dma;
1108 pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
1109 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001110
Joe Perches915006c2013-03-18 10:44:47 -07001111 pDevice->tx0_bufs = pci_alloc_consistent(pDevice->pcid,
1112 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1113 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1114 CB_BEACON_BUF_SIZE +
1115 CB_MAX_BUF_SIZE,
1116 &pDevice->tx_bufs_dma0);
Forest Bond5449c682009-04-25 10:30:44 -04001117
Joe Perches915006c2013-03-18 10:44:47 -07001118 if (pDevice->tx0_bufs == NULL) {
1119 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
1120 pci_free_consistent(pDevice->pcid,
1121 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1122 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1123 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1124 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1125 vir_pool, pDevice->pool_dma
1126 );
1127 return false;
1128 }
Forest Bond5449c682009-04-25 10:30:44 -04001129
Joe Perches915006c2013-03-18 10:44:47 -07001130 memset(pDevice->tx0_bufs, 0,
1131 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1132 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1133 CB_BEACON_BUF_SIZE +
1134 CB_MAX_BUF_SIZE
1135 );
Forest Bond5449c682009-04-25 10:30:44 -04001136
Joe Perches915006c2013-03-18 10:44:47 -07001137 pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
1138 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001139
Joe Perches915006c2013-03-18 10:44:47 -07001140 pDevice->td1_pool_dma = pDevice->td0_pool_dma +
1141 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001142
Joe Perches915006c2013-03-18 10:44:47 -07001143 // vir_pool: pvoid type
1144 pDevice->apTD0Rings = vir_pool
1145 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1146 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001147
Joe Perches915006c2013-03-18 10:44:47 -07001148 pDevice->apTD1Rings = vir_pool
1149 + pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1150 + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
1151 + pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
Forest Bond5449c682009-04-25 10:30:44 -04001152
Joe Perches915006c2013-03-18 10:44:47 -07001153 pDevice->tx1_bufs = pDevice->tx0_bufs +
1154 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001155
Joe Perches915006c2013-03-18 10:44:47 -07001156 pDevice->tx_beacon_bufs = pDevice->tx1_bufs +
1157 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001158
Joe Perches915006c2013-03-18 10:44:47 -07001159 pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs +
1160 CB_BEACON_BUF_SIZE;
Forest Bond5449c682009-04-25 10:30:44 -04001161
Joe Perches915006c2013-03-18 10:44:47 -07001162 pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 +
1163 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001164
Joe Perches915006c2013-03-18 10:44:47 -07001165 pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 +
1166 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
Forest Bond5449c682009-04-25 10:30:44 -04001167
Joe Perches915006c2013-03-18 10:44:47 -07001168 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001169}
1170
Guillaume Clement84b50762014-07-25 01:06:18 +02001171static void device_free_rings(PSDevice pDevice)
1172{
Joe Perches915006c2013-03-18 10:44:47 -07001173 pci_free_consistent(pDevice->pcid,
1174 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1175 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1176 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1177 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1178 ,
1179 pDevice->aRD0Ring, pDevice->pool_dma
1180 );
Forest Bond5449c682009-04-25 10:30:44 -04001181
Joe Perches915006c2013-03-18 10:44:47 -07001182 if (pDevice->tx0_bufs)
1183 pci_free_consistent(pDevice->pcid,
1184 pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1185 pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1186 CB_BEACON_BUF_SIZE +
1187 CB_MAX_BUF_SIZE,
1188 pDevice->tx0_bufs, pDevice->tx_bufs_dma0
1189 );
Forest Bond5449c682009-04-25 10:30:44 -04001190}
1191
Guillaume Clement84b50762014-07-25 01:06:18 +02001192static void device_init_rd0_ring(PSDevice pDevice)
1193{
Joe Perches915006c2013-03-18 10:44:47 -07001194 int i;
1195 dma_addr_t curr = pDevice->rd0_pool_dma;
1196 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001197
Joe Perches915006c2013-03-18 10:44:47 -07001198 /* Init the RD0 ring entries */
1199 for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
1200 pDesc = &(pDevice->aRD0Ring[i]);
1201 pDesc->pRDInfo = alloc_rd_info();
1202 ASSERT(pDesc->pRDInfo);
1203 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1204 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1205 pDevice->dev->name);
1206 }
1207 pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
1208 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1209 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1210 }
Forest Bond5449c682009-04-25 10:30:44 -04001211
Joe Perches915006c2013-03-18 10:44:47 -07001212 if (i > 0)
1213 pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
1214 pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001215}
1216
Guillaume Clement84b50762014-07-25 01:06:18 +02001217static void device_init_rd1_ring(PSDevice pDevice)
1218{
Joe Perches915006c2013-03-18 10:44:47 -07001219 int i;
1220 dma_addr_t curr = pDevice->rd1_pool_dma;
1221 PSRxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001222
Joe Perches915006c2013-03-18 10:44:47 -07001223 /* Init the RD1 ring entries */
1224 for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
1225 pDesc = &(pDevice->aRD1Ring[i]);
1226 pDesc->pRDInfo = alloc_rd_info();
1227 ASSERT(pDesc->pRDInfo);
1228 if (!device_alloc_rx_buf(pDevice, pDesc)) {
1229 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n",
1230 pDevice->dev->name);
1231 }
1232 pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
1233 pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1234 pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1235 }
Forest Bond5449c682009-04-25 10:30:44 -04001236
Joe Perches915006c2013-03-18 10:44:47 -07001237 if (i > 0)
1238 pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
1239 pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001240}
1241
Guillaume Clement84b50762014-07-25 01:06:18 +02001242static void device_init_defrag_cb(PSDevice pDevice)
1243{
Joe Perches915006c2013-03-18 10:44:47 -07001244 int i;
1245 PSDeFragControlBlock pDeF;
Forest Bond5449c682009-04-25 10:30:44 -04001246
Joe Perches915006c2013-03-18 10:44:47 -07001247 /* Init the fragment ctl entries */
1248 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1249 pDeF = &(pDevice->sRxDFCB[i]);
1250 if (!device_alloc_frag_buf(pDevice, pDeF)) {
1251 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc frag bufs\n",
1252 pDevice->dev->name);
1253 }
1254 }
1255 pDevice->cbDFCB = CB_MAX_RX_FRAG;
1256 pDevice->cbFreeDFCB = pDevice->cbDFCB;
Forest Bond5449c682009-04-25 10:30:44 -04001257}
1258
Guillaume Clement84b50762014-07-25 01:06:18 +02001259static void device_free_rd0_ring(PSDevice pDevice)
1260{
Joe Perches915006c2013-03-18 10:44:47 -07001261 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001262
Joe Perches915006c2013-03-18 10:44:47 -07001263 for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
1264 PSRxDesc pDesc = &(pDevice->aRD0Ring[i]);
1265 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001266
Joe Perches915006c2013-03-18 10:44:47 -07001267 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1268 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001269
Joe Perches915006c2013-03-18 10:44:47 -07001270 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001271
Joe Perches915006c2013-03-18 10:44:47 -07001272 kfree((void *)pDesc->pRDInfo);
1273 }
Forest Bond5449c682009-04-25 10:30:44 -04001274}
1275
Guillaume Clement84b50762014-07-25 01:06:18 +02001276static void device_free_rd1_ring(PSDevice pDevice)
1277{
Joe Perches915006c2013-03-18 10:44:47 -07001278 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001279
Joe Perches915006c2013-03-18 10:44:47 -07001280 for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
1281 PSRxDesc pDesc = &(pDevice->aRD1Ring[i]);
1282 PDEVICE_RD_INFO pRDInfo = pDesc->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001283
Joe Perches915006c2013-03-18 10:44:47 -07001284 pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1285 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001286
Joe Perches915006c2013-03-18 10:44:47 -07001287 dev_kfree_skb(pRDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001288
Joe Perches915006c2013-03-18 10:44:47 -07001289 kfree((void *)pDesc->pRDInfo);
1290 }
Forest Bond5449c682009-04-25 10:30:44 -04001291}
1292
Guillaume Clement84b50762014-07-25 01:06:18 +02001293static void device_free_frag_buf(PSDevice pDevice)
1294{
Joe Perches915006c2013-03-18 10:44:47 -07001295 PSDeFragControlBlock pDeF;
1296 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001297
Joe Perches915006c2013-03-18 10:44:47 -07001298 for (i = 0; i < CB_MAX_RX_FRAG; i++) {
Joe Perches915006c2013-03-18 10:44:47 -07001299 pDeF = &(pDevice->sRxDFCB[i]);
Forest Bond5449c682009-04-25 10:30:44 -04001300
Joe Perches915006c2013-03-18 10:44:47 -07001301 if (pDeF->skb)
1302 dev_kfree_skb(pDeF->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001303
Joe Perches915006c2013-03-18 10:44:47 -07001304 }
Forest Bond5449c682009-04-25 10:30:44 -04001305}
1306
Guillaume Clement84b50762014-07-25 01:06:18 +02001307static void device_init_td0_ring(PSDevice pDevice)
1308{
Joe Perches915006c2013-03-18 10:44:47 -07001309 int i;
1310 dma_addr_t curr;
1311 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001312
Joe Perches915006c2013-03-18 10:44:47 -07001313 curr = pDevice->td0_pool_dma;
1314 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) {
1315 pDesc = &(pDevice->apTD0Rings[i]);
1316 pDesc->pTDInfo = alloc_td_info();
1317 ASSERT(pDesc->pTDInfo);
1318 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1319 pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ;
1320 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ;
1321 }
1322 pDesc->next = &(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]);
1323 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1324 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1325 }
Forest Bond5449c682009-04-25 10:30:44 -04001326
Joe Perches915006c2013-03-18 10:44:47 -07001327 if (i > 0)
1328 pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
1329 pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001330}
1331
Guillaume Clement84b50762014-07-25 01:06:18 +02001332static void device_init_td1_ring(PSDevice pDevice)
1333{
Joe Perches915006c2013-03-18 10:44:47 -07001334 int i;
1335 dma_addr_t curr;
1336 PSTxDesc pDesc;
Forest Bond5449c682009-04-25 10:30:44 -04001337
Joe Perches915006c2013-03-18 10:44:47 -07001338 /* Init the TD ring entries */
1339 curr = pDevice->td1_pool_dma;
1340 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr += sizeof(STxDesc)) {
1341 pDesc = &(pDevice->apTD1Rings[i]);
1342 pDesc->pTDInfo = alloc_td_info();
1343 ASSERT(pDesc->pTDInfo);
1344 if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1345 pDesc->pTDInfo->buf = pDevice->tx1_bufs + (i) * PKT_BUF_SZ;
1346 pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma1 + (i) * PKT_BUF_SZ;
1347 }
1348 pDesc->next = &(pDevice->apTD1Rings[(i + 1) % pDevice->sOpts.nTxDescs[1]]);
1349 pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1350 pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1351 }
Forest Bond5449c682009-04-25 10:30:44 -04001352
Joe Perches915006c2013-03-18 10:44:47 -07001353 if (i > 0)
1354 pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
1355 pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
Forest Bond5449c682009-04-25 10:30:44 -04001356}
1357
Guillaume Clement84b50762014-07-25 01:06:18 +02001358static void device_free_td0_ring(PSDevice pDevice)
1359{
Joe Perches915006c2013-03-18 10:44:47 -07001360 int i;
Guillaume Clement6b711272014-07-25 01:06:16 +02001361
Joe Perches915006c2013-03-18 10:44:47 -07001362 for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
1363 PSTxDesc pDesc = &(pDevice->apTD0Rings[i]);
1364 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001365
Joe Perches915006c2013-03-18 10:44:47 -07001366 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1367 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1368 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001369
Joe Perches915006c2013-03-18 10:44:47 -07001370 if (pTDInfo->skb)
1371 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001372
Joe Perches915006c2013-03-18 10:44:47 -07001373 kfree((void *)pDesc->pTDInfo);
1374 }
Forest Bond5449c682009-04-25 10:30:44 -04001375}
1376
Guillaume Clement84b50762014-07-25 01:06:18 +02001377static void device_free_td1_ring(PSDevice pDevice)
1378{
Joe Perches915006c2013-03-18 10:44:47 -07001379 int i;
Forest Bond5449c682009-04-25 10:30:44 -04001380
Joe Perches915006c2013-03-18 10:44:47 -07001381 for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
1382 PSTxDesc pDesc = &(pDevice->apTD1Rings[i]);
1383 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001384
Joe Perches915006c2013-03-18 10:44:47 -07001385 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1386 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1387 pTDInfo->skb->len, PCI_DMA_TODEVICE);
Forest Bond5449c682009-04-25 10:30:44 -04001388
Joe Perches915006c2013-03-18 10:44:47 -07001389 if (pTDInfo->skb)
1390 dev_kfree_skb(pTDInfo->skb);
Forest Bond5449c682009-04-25 10:30:44 -04001391
Joe Perches915006c2013-03-18 10:44:47 -07001392 kfree((void *)pDesc->pTDInfo);
1393 }
Forest Bond5449c682009-04-25 10:30:44 -04001394}
1395
Forest Bond5449c682009-04-25 10:30:44 -04001396/*-----------------------------------------------------------------*/
1397
Guillaume Clement84b50762014-07-25 01:06:18 +02001398static int device_rx_srv(PSDevice pDevice, unsigned int uIdx)
1399{
Joe Perches915006c2013-03-18 10:44:47 -07001400 PSRxDesc pRD;
1401 int works = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001402
Joe Perches915006c2013-03-18 10:44:47 -07001403 for (pRD = pDevice->pCurrRD[uIdx];
1404 pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
1405 pRD = pRD->next) {
Joe Perches915006c2013-03-18 10:44:47 -07001406 if (works++ > 15)
1407 break;
1408 if (device_receive_frame(pDevice, pRD)) {
1409 if (!device_alloc_rx_buf(pDevice, pRD)) {
1410 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1411 "%s: can not allocate rx buf\n", pDevice->dev->name);
1412 break;
1413 }
1414 }
1415 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1416 pDevice->dev->last_rx = jiffies;
1417 }
Forest Bond5449c682009-04-25 10:30:44 -04001418
Joe Perches915006c2013-03-18 10:44:47 -07001419 pDevice->pCurrRD[uIdx] = pRD;
Forest Bond5449c682009-04-25 10:30:44 -04001420
Joe Perches915006c2013-03-18 10:44:47 -07001421 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001422}
1423
Guillaume Clement84b50762014-07-25 01:06:18 +02001424static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD)
1425{
Joe Perches915006c2013-03-18 10:44:47 -07001426 PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
Forest Bond5449c682009-04-25 10:30:44 -04001427
Joe Perches915006c2013-03-18 10:44:47 -07001428 pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
Joe Perches915006c2013-03-18 10:44:47 -07001429 if (pRDInfo->skb == NULL)
1430 return false;
1431 ASSERT(pRDInfo->skb);
1432 pRDInfo->skb->dev = pDevice->dev;
1433 pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
1434 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
1435 *((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */
Forest Bond5449c682009-04-25 10:30:44 -04001436
Joe Perches915006c2013-03-18 10:44:47 -07001437 pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
1438 pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1439 pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
1440 pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
Forest Bond5449c682009-04-25 10:30:44 -04001441
Joe Perches915006c2013-03-18 10:44:47 -07001442 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001443}
1444
Guillaume Clement84b50762014-07-25 01:06:18 +02001445bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF)
1446{
Joe Perches915006c2013-03-18 10:44:47 -07001447 pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1448 if (pDeF->skb == NULL)
1449 return false;
1450 ASSERT(pDeF->skb);
1451 pDeF->skb->dev = pDevice->dev;
Forest Bond5449c682009-04-25 10:30:44 -04001452
Joe Perches915006c2013-03-18 10:44:47 -07001453 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001454}
1455
Guillaume Clement84b50762014-07-25 01:06:18 +02001456static int device_tx_srv(PSDevice pDevice, unsigned int uIdx)
1457{
Joe Perches915006c2013-03-18 10:44:47 -07001458 PSTxDesc pTD;
1459 bool bFull = false;
1460 int works = 0;
1461 unsigned char byTsr0;
1462 unsigned char byTsr1;
1463 unsigned int uFrameSize, uFIFOHeaderSize;
1464 PSTxBufHead pTxBufHead;
1465 struct net_device_stats *pStats = &pDevice->stats;
1466 struct sk_buff *skb;
1467 unsigned int uNodeIndex;
1468 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04001469
Joe Perches915006c2013-03-18 10:44:47 -07001470 for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) {
Joe Perches915006c2013-03-18 10:44:47 -07001471 if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC)
1472 break;
1473 if (works++ > 15)
1474 break;
Forest Bond5449c682009-04-25 10:30:44 -04001475
Joe Perches915006c2013-03-18 10:44:47 -07001476 byTsr0 = pTD->m_td0TD0.byTSR0;
1477 byTsr1 = pTD->m_td0TD0.byTSR1;
Forest Bond5449c682009-04-25 10:30:44 -04001478
Joe Perches915006c2013-03-18 10:44:47 -07001479 //Only the status of first TD in the chain is correct
1480 if (pTD->m_td1TD1.byTCR & TCR_STP) {
Joe Perches915006c2013-03-18 10:44:47 -07001481 if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
1482 uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
1483 uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
1484 pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
1485 // Update the statistics based on the Transmit status
1486 // now, we DONT check TSR0_CDH
Forest Bond5449c682009-04-25 10:30:44 -04001487
Joe Perches915006c2013-03-18 10:44:47 -07001488 STAvUpdateTDStatCounter(&pDevice->scStatistic,
1489 byTsr0, byTsr1,
1490 (unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize),
1491 uFrameSize, uIdx);
Forest Bond5449c682009-04-25 10:30:44 -04001492
Joe Perches915006c2013-03-18 10:44:47 -07001493 BSSvUpdateNodeTxCounter(pDevice,
1494 byTsr0, byTsr1,
1495 (unsigned char *)(pTD->pTDInfo->buf),
1496 uFIFOHeaderSize
1497 );
Forest Bond5449c682009-04-25 10:30:44 -04001498
Joe Perches915006c2013-03-18 10:44:47 -07001499 if (!(byTsr1 & TSR1_TERR)) {
1500 if (byTsr0 != 0) {
1501 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
1502 (int)uIdx, byTsr1, byTsr0);
1503 }
Guido Martínezbc5cf652014-04-19 16:45:00 -03001504 if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG)
Joe Perches915006c2013-03-18 10:44:47 -07001505 pDevice->s802_11Counter.TransmittedFragmentCount++;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001506
Joe Perches915006c2013-03-18 10:44:47 -07001507 pStats->tx_packets++;
1508 pStats->tx_bytes += pTD->pTDInfo->skb->len;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001509 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001510 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
1511 (int)uIdx, byTsr1, byTsr0);
1512 pStats->tx_errors++;
1513 pStats->tx_dropped++;
1514 }
1515 }
Forest Bond5449c682009-04-25 10:30:44 -04001516
Joe Perches915006c2013-03-18 10:44:47 -07001517 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1518 if (pDevice->bEnableHostapd) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001519 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001520 skb = pTD->pTDInfo->skb;
1521 skb->dev = pDevice->apdev;
1522 skb_reset_mac_header(skb);
1523 skb->pkt_type = PACKET_OTHERHOST;
Joe Perches915006c2013-03-18 10:44:47 -07001524 memset(skb->cb, 0, sizeof(skb->cb));
1525 netif_rx(skb);
1526 }
1527 }
Forest Bond5449c682009-04-25 10:30:44 -04001528
Joe Perches915006c2013-03-18 10:44:47 -07001529 if (byTsr1 & TSR1_TERR) {
1530 if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1531 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
1532 (int)uIdx, byTsr1, byTsr0);
1533 }
Forest Bond5449c682009-04-25 10:30:44 -04001534
Forest Bond5449c682009-04-25 10:30:44 -04001535
Joe Perches915006c2013-03-18 10:44:47 -07001536 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
1537 (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
1538 unsigned short wAID;
1539 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
Forest Bond5449c682009-04-25 10:30:44 -04001540
Joe Perches915006c2013-03-18 10:44:47 -07001541 skb = pTD->pTDInfo->skb;
1542 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1543 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1544 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1545 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1546 // set tx map
1547 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1548 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
1549 pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
1550 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
1551 , (int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
1552 pStats->tx_errors--;
1553 pStats->tx_dropped--;
1554 }
1555 }
1556 }
1557 }
1558 device_free_tx_buf(pDevice, pTD);
1559 pDevice->iTDUsed[uIdx]--;
1560 }
1561 }
Forest Bond5449c682009-04-25 10:30:44 -04001562
Joe Perches915006c2013-03-18 10:44:47 -07001563 if (uIdx == TYPE_AC0DMA) {
1564 // RESERV_AC0DMA reserved for relay
Forest Bond5449c682009-04-25 10:30:44 -04001565
Joe Perches915006c2013-03-18 10:44:47 -07001566 if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
1567 bFull = true;
1568 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
1569 }
Guido Martínezbc5cf652014-04-19 16:45:00 -03001570 if (netif_queue_stopped(pDevice->dev) && !bFull)
Joe Perches915006c2013-03-18 10:44:47 -07001571 netif_wake_queue(pDevice->dev);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001572
Joe Perches915006c2013-03-18 10:44:47 -07001573 }
Forest Bond5449c682009-04-25 10:30:44 -04001574
Joe Perches915006c2013-03-18 10:44:47 -07001575 pDevice->apTailTD[uIdx] = pTD;
Forest Bond5449c682009-04-25 10:30:44 -04001576
Joe Perches915006c2013-03-18 10:44:47 -07001577 return works;
Forest Bond5449c682009-04-25 10:30:44 -04001578}
1579
Guillaume Clement84b50762014-07-25 01:06:18 +02001580static void device_error(PSDevice pDevice, unsigned short status)
1581{
Joe Perches915006c2013-03-18 10:44:47 -07001582 if (status & ISR_FETALERR) {
1583 DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
1584 "%s: Hardware fatal error.\n",
1585 pDevice->dev->name);
1586 netif_stop_queue(pDevice->dev);
1587 del_timer(&pDevice->sTimerCommand);
1588 del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
1589 pDevice->bCmdRunning = false;
1590 MACbShutdown(pDevice->PortOffset);
1591 return;
1592 }
Forest Bond5449c682009-04-25 10:30:44 -04001593}
1594
Guillaume Clement84b50762014-07-25 01:06:18 +02001595static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc)
1596{
Joe Perches915006c2013-03-18 10:44:47 -07001597 PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
1598 struct sk_buff *skb = pTDInfo->skb;
Forest Bond5449c682009-04-25 10:30:44 -04001599
Joe Perches915006c2013-03-18 10:44:47 -07001600 // pre-allocated buf_dma can't be unmapped.
1601 if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) {
1602 pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len,
1603 PCI_DMA_TODEVICE);
1604 }
Forest Bond5449c682009-04-25 10:30:44 -04001605
Joe Perches915006c2013-03-18 10:44:47 -07001606 if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0)
1607 dev_kfree_skb_irq(skb);
Forest Bond5449c682009-04-25 10:30:44 -04001608
Joe Perches915006c2013-03-18 10:44:47 -07001609 pTDInfo->skb_dma = 0;
Guillaume Clement70ae5432014-07-25 01:06:28 +02001610 pTDInfo->skb = NULL;
Joe Perches915006c2013-03-18 10:44:47 -07001611 pTDInfo->byFlags = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001612}
1613
Guillaume Clement84b50762014-07-25 01:06:18 +02001614static int device_open(struct net_device *dev)
1615{
Joe Perches915006c2013-03-18 10:44:47 -07001616 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1617 int i;
Jim Liebdb6cb902009-07-23 17:20:49 -07001618#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001619 extern SWPAResult wpa_Result;
Jim Liebdb6cb902009-07-23 17:20:49 -07001620#endif
1621
Joe Perches915006c2013-03-18 10:44:47 -07001622 pDevice->rx_buf_sz = PKT_BUF_SZ;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001623 if (!device_init_rings(pDevice))
Joe Perches915006c2013-03-18 10:44:47 -07001624 return -ENOMEM;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001625
Forest Bond5449c682009-04-25 10:30:44 -04001626//2008-5-13 <add> by chester
Joe Perches915006c2013-03-18 10:44:47 -07001627 i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
1628 if (i)
1629 return i;
Joe Perchesf2046f92013-03-18 20:55:36 -07001630
Forest Bond5449c682009-04-25 10:30:44 -04001631#ifdef WPA_SM_Transtatus
Joe Perches915006c2013-03-18 10:44:47 -07001632 memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
1633 wpa_Result.proto = 0;
1634 wpa_Result.key_mgmt = 0;
1635 wpa_Result.eap_type = 0;
1636 wpa_Result.authenticated = false;
1637 pDevice->fWPA_Authened = false;
Forest Bond5449c682009-04-25 10:30:44 -04001638#endif
Joe Perches915006c2013-03-18 10:44:47 -07001639 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
1640 device_init_rd0_ring(pDevice);
1641 device_init_rd1_ring(pDevice);
1642 device_init_defrag_cb(pDevice);
1643 device_init_td0_ring(pDevice);
1644 device_init_td1_ring(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001645
Guido Martínezbc5cf652014-04-19 16:45:00 -03001646 if (pDevice->bDiversityRegCtlON)
Joe Perches915006c2013-03-18 10:44:47 -07001647 device_init_diversity_timer(pDevice);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001648
Joe Perches915006c2013-03-18 10:44:47 -07001649 vMgrObjectInit(pDevice);
1650 vMgrTimerInit(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001651
Joe Perches915006c2013-03-18 10:44:47 -07001652 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
Forest Bond5449c682009-04-25 10:30:44 -04001653 device_init_registers(pDevice, DEVICE_INIT_COLD);
Joe Perches915006c2013-03-18 10:44:47 -07001654 MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
1655 memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1656 device_set_multi(pDevice->dev);
Forest Bond5449c682009-04-25 10:30:44 -04001657
Joe Perches915006c2013-03-18 10:44:47 -07001658 // Init for Key Management
1659 KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
1660 add_timer(&(pDevice->pMgmt->sTimerSecondCallback));
Forest Bond5449c682009-04-25 10:30:44 -04001661
Joe Perches915006c2013-03-18 10:44:47 -07001662#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Joe Perches915006c2013-03-18 10:44:47 -07001663 pDevice->bwextcount = 0;
1664 pDevice->bWPASuppWextEnabled = false;
Forest Bond5449c682009-04-25 10:30:44 -04001665#endif
Joe Perches915006c2013-03-18 10:44:47 -07001666 pDevice->byReAssocCount = 0;
1667 pDevice->bWPADEVUp = false;
1668 // Patch: if WEP key already set by iwconfig but device not yet open
Teodora Baluta1208f142013-11-10 17:12:42 +02001669 if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) {
Joe Perches915006c2013-03-18 10:44:47 -07001670 KeybSetDefaultKey(&(pDevice->sKey),
1671 (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
1672 pDevice->uKeyLength,
1673 NULL,
1674 pDevice->abyKey,
1675 KEY_CTL_WEP,
1676 pDevice->PortOffset,
1677 pDevice->byLocalID
1678 );
1679 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1680 }
Forest Bond5449c682009-04-25 10:30:44 -04001681
Joe Perches915006c2013-03-18 10:44:47 -07001682 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
Forest Bond5449c682009-04-25 10:30:44 -04001683 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
1684
Joe Perches915006c2013-03-18 10:44:47 -07001685 if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1686 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001687 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001688 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1689 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
1690 }
1691 pDevice->flags |= DEVICE_FLAGS_OPENED;
Forest Bond5449c682009-04-25 10:30:44 -04001692
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001693 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001694 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001695}
1696
Guillaume Clement84b50762014-07-25 01:06:18 +02001697static int device_close(struct net_device *dev)
1698{
Joe Perches915006c2013-03-18 10:44:47 -07001699 PSDevice pDevice = (PSDevice)netdev_priv(dev);
1700 PSMgmtObject pMgmt = pDevice->pMgmt;
1701 //PLICE_DEBUG->
Forest Bond5449c682009-04-25 10:30:44 -04001702//PLICE_DEBUG<-
1703//2007-1121-02<Add>by EinsnLiu
Joe Perches915006c2013-03-18 10:44:47 -07001704 if (pDevice->bLinkPass) {
1705 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
1706 mdelay(30);
1707 }
Forest Bond5449c682009-04-25 10:30:44 -04001708#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07001709 del_timer(&pDevice->sTimerTxData);
Forest Bond5449c682009-04-25 10:30:44 -04001710#endif
Joe Perches915006c2013-03-18 10:44:47 -07001711 del_timer(&pDevice->sTimerCommand);
1712 del_timer(&pMgmt->sTimerSecondCallback);
1713 if (pDevice->bDiversityRegCtlON) {
1714 del_timer(&pDevice->TimerSQ3Tmax1);
1715 del_timer(&pDevice->TimerSQ3Tmax2);
1716 del_timer(&pDevice->TimerSQ3Tmax3);
1717 }
Forest Bond5449c682009-04-25 10:30:44 -04001718
Joe Perches915006c2013-03-18 10:44:47 -07001719 netif_stop_queue(dev);
1720 pDevice->bCmdRunning = false;
1721 MACbShutdown(pDevice->PortOffset);
1722 MACbSoftwareReset(pDevice->PortOffset);
1723 CARDbRadioPowerOff(pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04001724
Joe Perches915006c2013-03-18 10:44:47 -07001725 pDevice->bLinkPass = false;
1726 memset(pMgmt->abyCurrBSSID, 0, 6);
1727 pMgmt->eCurrState = WMAC_STATE_IDLE;
1728 device_free_td0_ring(pDevice);
1729 device_free_td1_ring(pDevice);
1730 device_free_rd0_ring(pDevice);
1731 device_free_rd1_ring(pDevice);
1732 device_free_frag_buf(pDevice);
1733 device_free_rings(pDevice);
1734 BSSvClearNodeDBTable(pDevice, 0);
1735 free_irq(dev->irq, dev);
1736 pDevice->flags &= (~DEVICE_FLAGS_OPENED);
Forest Bond5449c682009-04-25 10:30:44 -04001737 //2008-0714-01<Add>by chester
Joe Perches915006c2013-03-18 10:44:47 -07001738 device_release_WPADEV(pDevice);
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001739
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001740 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close..\n");
Joe Perches915006c2013-03-18 10:44:47 -07001741 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001742}
1743
Guillaume Clement84b50762014-07-25 01:06:18 +02001744static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
1745{
Joe Perches915006c2013-03-18 10:44:47 -07001746 PSDevice pDevice = netdev_priv(dev);
1747 unsigned char *pbMPDU;
1748 unsigned int cbMPDULen = 0;
Forest Bond5449c682009-04-25 10:30:44 -04001749
Joe Perches915006c2013-03-18 10:44:47 -07001750 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
1751 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001752
Joe Perches915006c2013-03-18 10:44:47 -07001753 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1754 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
1755 dev_kfree_skb_irq(skb);
1756 spin_unlock_irq(&pDevice->lock);
1757 return 0;
1758 }
Forest Bond5449c682009-04-25 10:30:44 -04001759
Teodora Baluta1208f142013-11-10 17:12:42 +02001760 if (pDevice->bStopTx0Pkt) {
Joe Perches915006c2013-03-18 10:44:47 -07001761 dev_kfree_skb_irq(skb);
1762 spin_unlock_irq(&pDevice->lock);
1763 return 0;
1764 }
Forest Bond5449c682009-04-25 10:30:44 -04001765
Joe Perches915006c2013-03-18 10:44:47 -07001766 cbMPDULen = skb->len;
1767 pbMPDU = skb->data;
Forest Bond5449c682009-04-25 10:30:44 -04001768
Joe Perches915006c2013-03-18 10:44:47 -07001769 vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
Forest Bond5449c682009-04-25 10:30:44 -04001770
Joe Perches915006c2013-03-18 10:44:47 -07001771 spin_unlock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04001772
Joe Perches915006c2013-03-18 10:44:47 -07001773 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04001774}
1775
Guillaume Clement84b50762014-07-25 01:06:18 +02001776bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex)
1777{
Joe Perches915006c2013-03-18 10:44:47 -07001778 PSMgmtObject pMgmt = pDevice->pMgmt;
1779 PSTxDesc pHeadTD, pLastTD;
1780 unsigned int cbFrameBodySize;
1781 unsigned int uMACfragNum;
1782 unsigned char byPktType;
1783 bool bNeedEncryption = false;
1784 PSKeyItem pTransmitKey = NULL;
1785 unsigned int cbHeaderSize;
1786 unsigned int ii;
1787 SKeyItem STempKey;
Forest Bond5449c682009-04-25 10:30:44 -04001788
Teodora Baluta1208f142013-11-10 17:12:42 +02001789 if (pDevice->bStopTx0Pkt) {
Joe Perches915006c2013-03-18 10:44:47 -07001790 dev_kfree_skb_irq(skb);
1791 return false;
1792 }
Forest Bond5449c682009-04-25 10:30:44 -04001793
Joe Perches915006c2013-03-18 10:44:47 -07001794 if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1795 dev_kfree_skb_irq(skb);
1796 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
1797 return false;
1798 }
Forest Bond5449c682009-04-25 10:30:44 -04001799
Joe Perches915006c2013-03-18 10:44:47 -07001800 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1801 if (pDevice->uAssocCount == 0) {
1802 dev_kfree_skb_irq(skb);
1803 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
1804 return false;
1805 }
1806 }
Forest Bond5449c682009-04-25 10:30:44 -04001807
Joe Perches915006c2013-03-18 10:44:47 -07001808 pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
Forest Bond5449c682009-04-25 10:30:44 -04001809
Joe Perches915006c2013-03-18 10:44:47 -07001810 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04001811
Joe Perches915006c2013-03-18 10:44:47 -07001812 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
1813 cbFrameBodySize = skb->len - ETH_HLEN;
Forest Bond5449c682009-04-25 10:30:44 -04001814
Joe Perches915006c2013-03-18 10:44:47 -07001815 // 802.1H
Guido Martínezbc5cf652014-04-19 16:45:00 -03001816 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
Joe Perches915006c2013-03-18 10:44:47 -07001817 cbFrameBodySize += 8;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001818
Joe Perches915006c2013-03-18 10:44:47 -07001819 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04001820
Joe Perches915006c2013-03-18 10:44:47 -07001821 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
1822 dev_kfree_skb_irq(skb);
1823 return false;
1824 }
1825 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04001826
Joe Perches915006c2013-03-18 10:44:47 -07001827 if (pDevice->bFixRate) {
1828 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03001829 if (pDevice->uConnectionRate >= RATE_11M)
Joe Perches915006c2013-03-18 10:44:47 -07001830 pDevice->wCurrentRate = RATE_11M;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001831 else
Joe Perches915006c2013-03-18 10:44:47 -07001832 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Joe Perches915006c2013-03-18 10:44:47 -07001833 } else {
1834 if (pDevice->uConnectionRate >= RATE_54M)
1835 pDevice->wCurrentRate = RATE_54M;
1836 else
1837 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1838 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001839 } else {
Joe Perches915006c2013-03-18 10:44:47 -07001840 pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
1841 }
Forest Bond5449c682009-04-25 10:30:44 -04001842
Joe Perches915006c2013-03-18 10:44:47 -07001843 //preamble type
Guido Martínezbc5cf652014-04-19 16:45:00 -03001844 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
Joe Perches915006c2013-03-18 10:44:47 -07001845 pDevice->byPreambleType = pDevice->byShortPreamble;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001846 else
Joe Perches915006c2013-03-18 10:44:47 -07001847 pDevice->byPreambleType = PREAMBLE_LONG;
Forest Bond5449c682009-04-25 10:30:44 -04001848
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001849 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -04001850
Joe Perches915006c2013-03-18 10:44:47 -07001851 if (pDevice->wCurrentRate <= RATE_11M) {
1852 byPktType = PK_TYPE_11B;
1853 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1854 byPktType = PK_TYPE_11A;
1855 } else {
Guido Martínezbc5cf652014-04-19 16:45:00 -03001856 if (pDevice->bProtectMode)
Joe Perches915006c2013-03-18 10:44:47 -07001857 byPktType = PK_TYPE_11GB;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001858 else
Joe Perches915006c2013-03-18 10:44:47 -07001859 byPktType = PK_TYPE_11GA;
Joe Perches915006c2013-03-18 10:44:47 -07001860 }
Forest Bond5449c682009-04-25 10:30:44 -04001861
Teodora Baluta1208f142013-11-10 17:12:42 +02001862 if (pDevice->bEncryptionEnable)
Joe Perches915006c2013-03-18 10:44:47 -07001863 bNeedEncryption = true;
Forest Bond5449c682009-04-25 10:30:44 -04001864
Joe Perches915006c2013-03-18 10:44:47 -07001865 if (pDevice->bEnableHostWEP) {
1866 pTransmitKey = &STempKey;
1867 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
1868 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
1869 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
1870 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
1871 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
1872 memcpy(pTransmitKey->abyKey,
1873 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
1874 pTransmitKey->uKeyLength
1875 );
1876 }
1877 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
1878 cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
1879 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
1880 &uMACfragNum,
1881 &cbHeaderSize
1882 );
Forest Bond5449c682009-04-25 10:30:44 -04001883
Joe Perches915006c2013-03-18 10:44:47 -07001884 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
1885 // Disable PS
1886 MACbPSWakeup(pDevice->PortOffset);
1887 }
Forest Bond5449c682009-04-25 10:30:44 -04001888
Joe Perches915006c2013-03-18 10:44:47 -07001889 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04001890
Joe Perches915006c2013-03-18 10:44:47 -07001891 pLastTD = pHeadTD;
1892 for (ii = 0; ii < uMACfragNum; ii++) {
1893 // Poll Transmit the adapter
1894 wmb();
1895 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
1896 wmb();
1897 if (ii == (uMACfragNum - 1))
1898 pLastTD = pHeadTD;
1899 pHeadTD = pHeadTD->next;
1900 }
Forest Bond5449c682009-04-25 10:30:44 -04001901
Joe Perches915006c2013-03-18 10:44:47 -07001902 // Save the information needed by the tx interrupt handler
1903 // to complete the Send request
1904 pLastTD->pTDInfo->skb = skb;
1905 pLastTD->pTDInfo->byFlags = 0;
1906 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04001907
Joe Perches915006c2013-03-18 10:44:47 -07001908 pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001909
Joe Perches915006c2013-03-18 10:44:47 -07001910 MACvTransmit0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04001911
Joe Perches915006c2013-03-18 10:44:47 -07001912 return true;
Forest Bond5449c682009-04-25 10:30:44 -04001913}
1914
1915//TYPE_AC0DMA data tx
Guillaume Clement84b50762014-07-25 01:06:18 +02001916static int device_xmit(struct sk_buff *skb, struct net_device *dev)
1917{
Joe Perches915006c2013-03-18 10:44:47 -07001918 PSDevice pDevice = netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04001919
Joe Perches915006c2013-03-18 10:44:47 -07001920 PSMgmtObject pMgmt = pDevice->pMgmt;
1921 PSTxDesc pHeadTD, pLastTD;
1922 unsigned int uNodeIndex = 0;
1923 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
1924 unsigned short wAID;
1925 unsigned int uMACfragNum = 1;
1926 unsigned int cbFrameBodySize;
1927 unsigned char byPktType;
1928 unsigned int cbHeaderSize;
1929 bool bNeedEncryption = false;
1930 PSKeyItem pTransmitKey = NULL;
1931 SKeyItem STempKey;
1932 unsigned int ii;
1933 bool bTKIP_UseGTK = false;
1934 bool bNeedDeAuth = false;
1935 unsigned char *pbyBSSID;
1936 bool bNodeExist = false;
Forest Bond5449c682009-04-25 10:30:44 -04001937
Joe Perches915006c2013-03-18 10:44:47 -07001938 spin_lock_irq(&pDevice->lock);
Teodora Baluta1208f142013-11-10 17:12:42 +02001939 if (!pDevice->bLinkPass) {
Joe Perches915006c2013-03-18 10:44:47 -07001940 dev_kfree_skb_irq(skb);
1941 spin_unlock_irq(&pDevice->lock);
1942 return 0;
1943 }
Forest Bond5449c682009-04-25 10:30:44 -04001944
Joe Perches915006c2013-03-18 10:44:47 -07001945 if (pDevice->bStopDataPkt) {
1946 dev_kfree_skb_irq(skb);
1947 spin_unlock_irq(&pDevice->lock);
1948 return 0;
1949 }
Forest Bond5449c682009-04-25 10:30:44 -04001950
Joe Perches915006c2013-03-18 10:44:47 -07001951 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1952 if (pDevice->uAssocCount == 0) {
1953 dev_kfree_skb_irq(skb);
1954 spin_unlock_irq(&pDevice->lock);
1955 return 0;
1956 }
1957 if (is_multicast_ether_addr((unsigned char *)(skb->data))) {
1958 uNodeIndex = 0;
1959 bNodeExist = true;
1960 if (pMgmt->sNodeDBTable[0].bPSEnable) {
1961 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
1962 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
1963 // set tx map
1964 pMgmt->abyPSTxMap[0] |= byMask[0];
1965 spin_unlock_irq(&pDevice->lock);
1966 return 0;
1967 }
1968 } else {
1969 if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1970 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1971 skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1972 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1973 // set tx map
1974 wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1975 pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
1976 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
1977 (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
1978 spin_unlock_irq(&pDevice->lock);
1979 return 0;
1980 }
Forest Bond5449c682009-04-25 10:30:44 -04001981
Guido Martínezbc5cf652014-04-19 16:45:00 -03001982 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
Joe Perches915006c2013-03-18 10:44:47 -07001983 pDevice->byPreambleType = pDevice->byShortPreamble;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001984 else
Joe Perches915006c2013-03-18 10:44:47 -07001985 pDevice->byPreambleType = PREAMBLE_LONG;
Guido Martínezbc5cf652014-04-19 16:45:00 -03001986
Joe Perches915006c2013-03-18 10:44:47 -07001987 bNodeExist = true;
Forest Bond5449c682009-04-25 10:30:44 -04001988
Joe Perches915006c2013-03-18 10:44:47 -07001989 }
1990 }
Forest Bond5449c682009-04-25 10:30:44 -04001991
Teodora Baluta1208f142013-11-10 17:12:42 +02001992 if (!bNodeExist) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02001993 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB\n");
Joe Perches915006c2013-03-18 10:44:47 -07001994 dev_kfree_skb_irq(skb);
1995 spin_unlock_irq(&pDevice->lock);
1996 return 0;
1997 }
1998 }
Forest Bond5449c682009-04-25 10:30:44 -04001999
Joe Perches915006c2013-03-18 10:44:47 -07002000 pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
Forest Bond5449c682009-04-25 10:30:44 -04002001
Joe Perches915006c2013-03-18 10:44:47 -07002002 pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
Forest Bond5449c682009-04-25 10:30:44 -04002003
Joe Perches915006c2013-03-18 10:44:47 -07002004 memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
2005 cbFrameBodySize = skb->len - ETH_HLEN;
2006 // 802.1H
Guido Martínezbc5cf652014-04-19 16:45:00 -03002007 if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
Joe Perches915006c2013-03-18 10:44:47 -07002008 cbFrameBodySize += 8;
Forest Bond5449c682009-04-25 10:30:44 -04002009
Teodora Baluta1208f142013-11-10 17:12:42 +02002010 if (pDevice->bEncryptionEnable) {
Joe Perches915006c2013-03-18 10:44:47 -07002011 bNeedEncryption = true;
2012 // get Transmit key
2013 do {
2014 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2015 (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2016 pbyBSSID = pDevice->abyBSSID;
2017 // get pairwise key
2018 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
2019 // get group key
2020 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
2021 bTKIP_UseGTK = true;
2022 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2023 break;
2024 }
2025 } else {
2026 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get PTK.\n");
2027 break;
2028 }
2029 } else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
Joe Perches915006c2013-03-18 10:44:47 -07002030 pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002031 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key:\n");
Joe Perches915006c2013-03-18 10:44:47 -07002032 for (ii = 0; ii < 6; ii++)
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002033 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x\n", *(pbyBSSID+ii));
Joe Perches915006c2013-03-18 10:44:47 -07002034 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n");
Forest Bond5449c682009-04-25 10:30:44 -04002035
Joe Perches915006c2013-03-18 10:44:47 -07002036 // get pairwise key
2037 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
2038 break;
2039 }
2040 // get group key
2041 pbyBSSID = pDevice->abyBroadcastAddr;
2042 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
2043 pTransmitKey = NULL;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002044 if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
Joe Perches915006c2013-03-18 10:44:47 -07002045 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002046 else
Joe Perches915006c2013-03-18 10:44:47 -07002047 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
2048 } else {
2049 bTKIP_UseGTK = true;
2050 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n");
2051 }
2052 } while (false);
2053 }
Forest Bond5449c682009-04-25 10:30:44 -04002054
Joe Perches915006c2013-03-18 10:44:47 -07002055 if (pDevice->bEnableHostWEP) {
2056 DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex);
Teodora Baluta1208f142013-11-10 17:12:42 +02002057 if (pDevice->bEncryptionEnable) {
Joe Perches915006c2013-03-18 10:44:47 -07002058 pTransmitKey = &STempKey;
2059 pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
2060 pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
2061 pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2062 pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2063 pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2064 memcpy(pTransmitKey->abyKey,
2065 &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2066 pTransmitKey->uKeyLength
2067 );
2068 }
2069 }
Forest Bond5449c682009-04-25 10:30:44 -04002070
Joe Perches915006c2013-03-18 10:44:47 -07002071 uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
Forest Bond5449c682009-04-25 10:30:44 -04002072
Joe Perches915006c2013-03-18 10:44:47 -07002073 if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
2074 DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
2075 dev_kfree_skb_irq(skb);
2076 spin_unlock_irq(&pDevice->lock);
2077 return 0;
2078 }
Forest Bond5449c682009-04-25 10:30:44 -04002079
Joe Perches915006c2013-03-18 10:44:47 -07002080 if (pTransmitKey != NULL) {
2081 if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) &&
2082 (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) {
2083 uMACfragNum = 1; //WEP256 doesn't support fragment
2084 }
2085 }
Forest Bond5449c682009-04-25 10:30:44 -04002086
Joe Perches915006c2013-03-18 10:44:47 -07002087 byPktType = (unsigned char)pDevice->byPacketType;
Forest Bond5449c682009-04-25 10:30:44 -04002088
Joe Perches915006c2013-03-18 10:44:47 -07002089 if (pDevice->bFixRate) {
Forest Bond5449c682009-04-25 10:30:44 -04002090#ifdef PLICE_DEBUG
Guillaume Clement941ead92014-07-25 01:06:21 +02002091 pr_debug("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate);
Forest Bond5449c682009-04-25 10:30:44 -04002092#endif
2093
Joe Perches915006c2013-03-18 10:44:47 -07002094 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002095 if (pDevice->uConnectionRate >= RATE_11M)
Joe Perches915006c2013-03-18 10:44:47 -07002096 pDevice->wCurrentRate = RATE_11M;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002097 else
Joe Perches915006c2013-03-18 10:44:47 -07002098 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Joe Perches915006c2013-03-18 10:44:47 -07002099 } else {
2100 if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
2101 (pDevice->uConnectionRate <= RATE_6M)) {
2102 pDevice->wCurrentRate = RATE_6M;
2103 } else {
2104 if (pDevice->uConnectionRate >= RATE_54M)
2105 pDevice->wCurrentRate = RATE_54M;
2106 else
2107 pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
Forest Bond5449c682009-04-25 10:30:44 -04002108
Joe Perches915006c2013-03-18 10:44:47 -07002109 }
2110 }
2111 pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate;
2112 pDevice->byTopCCKBasicRate = RATE_1M;
2113 pDevice->byTopOFDMBasicRate = RATE_6M;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002114 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002115 //auto rate
2116 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2117 if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
2118 pDevice->wCurrentRate = RATE_1M;
2119 pDevice->byACKRate = RATE_1M;
2120 pDevice->byTopCCKBasicRate = RATE_1M;
2121 pDevice->byTopOFDMBasicRate = RATE_6M;
2122 } else {
2123 pDevice->wCurrentRate = RATE_6M;
2124 pDevice->byACKRate = RATE_6M;
2125 pDevice->byTopCCKBasicRate = RATE_1M;
2126 pDevice->byTopOFDMBasicRate = RATE_6M;
2127 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002128 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002129 VNTWIFIvGetTxRate(pDevice->pMgmt,
2130 pDevice->sTxEthHeader.abyDstAddr,
2131 &(pDevice->wCurrentRate),
2132 &(pDevice->byACKRate),
2133 &(pDevice->byTopCCKBasicRate),
2134 &(pDevice->byTopOFDMBasicRate));
Forest Bond5449c682009-04-25 10:30:44 -04002135
Forest Bond5449c682009-04-25 10:30:44 -04002136 }
Joe Perches915006c2013-03-18 10:44:47 -07002137 }
Forest Bond5449c682009-04-25 10:30:44 -04002138
Forest Bond5449c682009-04-25 10:30:44 -04002139
Joe Perches915006c2013-03-18 10:44:47 -07002140 if (pDevice->wCurrentRate <= RATE_11M) {
2141 byPktType = PK_TYPE_11B;
2142 } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2143 byPktType = PK_TYPE_11A;
2144 } else {
Guido Martínezbc5cf652014-04-19 16:45:00 -03002145 if (pDevice->bProtectMode)
Joe Perches915006c2013-03-18 10:44:47 -07002146 byPktType = PK_TYPE_11GB;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002147 else
Joe Perches915006c2013-03-18 10:44:47 -07002148 byPktType = PK_TYPE_11GA;
Joe Perches915006c2013-03-18 10:44:47 -07002149 }
Forest Bond5449c682009-04-25 10:30:44 -04002150
Teodora Baluta1208f142013-11-10 17:12:42 +02002151 if (bNeedEncryption) {
Joe Perches915006c2013-03-18 10:44:47 -07002152 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
2153 if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
2154 bNeedEncryption = false;
2155 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
2156 if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2157 if (pTransmitKey == NULL) {
2158 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002159 } else {
Teodora Baluta1208f142013-11-10 17:12:42 +02002160 if (bTKIP_UseGTK) {
Joe Perches915006c2013-03-18 10:44:47 -07002161 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n");
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002162 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002163 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2164 bNeedEncryption = true;
2165 }
2166 }
2167 }
Forest Bond5449c682009-04-25 10:30:44 -04002168
Joe Perches915006c2013-03-18 10:44:47 -07002169 if (pDevice->byCntMeasure == 2) {
2170 bNeedDeAuth = true;
2171 pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
2172 }
Forest Bond5449c682009-04-25 10:30:44 -04002173
Joe Perches915006c2013-03-18 10:44:47 -07002174 if (pDevice->bEnableHostWEP) {
2175 if ((uNodeIndex != 0) &&
2176 (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
2177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
2178 bNeedEncryption = true;
2179 }
2180 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002181 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002182 if (pTransmitKey == NULL) {
2183 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return no tx key\n");
2184 dev_kfree_skb_irq(skb);
2185 spin_unlock_irq(&pDevice->lock);
2186 return 0;
2187 }
2188 }
2189 }
Forest Bond5449c682009-04-25 10:30:44 -04002190
Joe Perches915006c2013-03-18 10:44:47 -07002191 vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
2192 cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
2193 &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
2194 &uMACfragNum,
2195 &cbHeaderSize
2196 );
Forest Bond5449c682009-04-25 10:30:44 -04002197
Joe Perches915006c2013-03-18 10:44:47 -07002198 if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2199 // Disable PS
2200 MACbPSWakeup(pDevice->PortOffset);
2201 }
2202 pDevice->bPWBitOn = false;
Forest Bond5449c682009-04-25 10:30:44 -04002203
Joe Perches915006c2013-03-18 10:44:47 -07002204 pLastTD = pHeadTD;
2205 for (ii = 0; ii < uMACfragNum; ii++) {
2206 // Poll Transmit the adapter
2207 wmb();
2208 pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2209 wmb();
2210 if (ii == uMACfragNum - 1)
2211 pLastTD = pHeadTD;
2212 pHeadTD = pHeadTD->next;
2213 }
Forest Bond5449c682009-04-25 10:30:44 -04002214
Joe Perches915006c2013-03-18 10:44:47 -07002215 // Save the information needed by the tx interrupt handler
2216 // to complete the Send request
2217 pLastTD->pTDInfo->skb = skb;
2218 pLastTD->pTDInfo->byFlags = 0;
2219 pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
Forest Bond5449c682009-04-25 10:30:44 -04002220#ifdef TxInSleep
Joe Perches915006c2013-03-18 10:44:47 -07002221 pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
2222#endif
Guido Martínezbc5cf652014-04-19 16:45:00 -03002223 if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1)
Joe Perches915006c2013-03-18 10:44:47 -07002224 netif_stop_queue(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002225
Joe Perches915006c2013-03-18 10:44:47 -07002226 pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002227
Guido Martínezbc5cf652014-04-19 16:45:00 -03002228 if (pDevice->bFixRate)
Guillaume Clement941ead92014-07-25 01:06:21 +02002229 pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
Forest Bond5449c682009-04-25 10:30:44 -04002230
Joe Perches915006c2013-03-18 10:44:47 -07002231 {
2232 unsigned char Protocol_Version; //802.1x Authentication
2233 unsigned char Packet_Type; //802.1x Authentication
2234 unsigned char Descriptor_type;
2235 unsigned short Key_info;
2236 bool bTxeapol_key = false;
Guillaume Clement6b711272014-07-25 01:06:16 +02002237
Joe Perches915006c2013-03-18 10:44:47 -07002238 Protocol_Version = skb->data[ETH_HLEN];
2239 Packet_Type = skb->data[ETH_HLEN+1];
2240 Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2241 Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
2242 if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2243 if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2244 (Packet_Type == 3)) { //802.1x OR eapol-key challenge frame transfer
2245 bTxeapol_key = true;
2246 if ((Descriptor_type == 254) || (Descriptor_type == 2)) { //WPA or RSN
2247 if (!(Key_info & BIT3) && //group-key challenge
2248 (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
2249 pDevice->fWPA_Authened = true;
2250 if (Descriptor_type == 254)
Guillaume Clement941ead92014-07-25 01:06:21 +02002251 pr_debug("WPA ");
Joe Perches915006c2013-03-18 10:44:47 -07002252 else
Guillaume Clement941ead92014-07-25 01:06:21 +02002253 pr_debug("WPA2 ");
2254 pr_debug("Authentication completed!!\n");
Joe Perches915006c2013-03-18 10:44:47 -07002255 }
2256 }
2257 }
2258 }
2259 }
Forest Bond5449c682009-04-25 10:30:44 -04002260
Joe Perches915006c2013-03-18 10:44:47 -07002261 MACvTransmitAC0(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002262
Joe Perches915006c2013-03-18 10:44:47 -07002263 dev->trans_start = jiffies;
Forest Bond5449c682009-04-25 10:30:44 -04002264
Joe Perches915006c2013-03-18 10:44:47 -07002265 spin_unlock_irq(&pDevice->lock);
2266 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04002267}
2268
Guillaume Clement84b50762014-07-25 01:06:18 +02002269static irqreturn_t device_intr(int irq, void *dev_instance)
2270{
Joe Perches915006c2013-03-18 10:44:47 -07002271 struct net_device *dev = dev_instance;
2272 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002273
Joe Perches915006c2013-03-18 10:44:47 -07002274 int max_count = 0;
2275 unsigned long dwMIBCounter = 0;
2276 PSMgmtObject pMgmt = pDevice->pMgmt;
2277 unsigned char byOrgPageSel = 0;
2278 int handled = 0;
2279 unsigned char byData = 0;
2280 int ii = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002281
Joe Perches915006c2013-03-18 10:44:47 -07002282 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002283
Joe Perches915006c2013-03-18 10:44:47 -07002284 if (pDevice->dwIsr == 0)
2285 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002286
Joe Perches915006c2013-03-18 10:44:47 -07002287 if (pDevice->dwIsr == 0xffffffff) {
2288 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
2289 return IRQ_RETVAL(handled);
2290 }
Forest Bond5449c682009-04-25 10:30:44 -04002291
Joe Perches915006c2013-03-18 10:44:47 -07002292 handled = 1;
2293 MACvIntDisable(pDevice->PortOffset);
2294 spin_lock_irq(&pDevice->lock);
Forest Bond5449c682009-04-25 10:30:44 -04002295
Joe Perches915006c2013-03-18 10:44:47 -07002296 //Make sure current page is 0
2297 VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002298 if (byOrgPageSel == 1)
Joe Perches915006c2013-03-18 10:44:47 -07002299 MACvSelectPage0(pDevice->PortOffset);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002300 else
Joe Perches915006c2013-03-18 10:44:47 -07002301 byOrgPageSel = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002302
Joe Perches915006c2013-03-18 10:44:47 -07002303 MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
2304 // TBD....
2305 // Must do this after doing rx/tx, cause ISR bit is slow
2306 // than RD/TD write back
2307 // update ISR counter
2308 STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
2309 while (pDevice->dwIsr != 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002310 STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
2311 MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002312
Joe Perches915006c2013-03-18 10:44:47 -07002313 if (pDevice->dwIsr & ISR_FETALERR) {
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002314 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR\n");
Joe Perches915006c2013-03-18 10:44:47 -07002315 VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
2316 VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
2317 device_error(pDevice, pDevice->dwIsr);
2318 }
Forest Bond5449c682009-04-25 10:30:44 -04002319
Joe Perches915006c2013-03-18 10:44:47 -07002320 if (pDevice->byLocalID > REV_ID_VT3253_B1) {
Joe Perches915006c2013-03-18 10:44:47 -07002321 if (pDevice->dwIsr & ISR_MEASURESTART) {
2322 // 802.11h measure start
2323 pDevice->byOrgChannel = pDevice->byCurrentCh;
2324 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
2325 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR));
2326 MACvSelectPage1(pDevice->PortOffset);
2327 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0));
2328 VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
2329 MACvSelectPage0(pDevice->PortOffset);
2330 //xxxx
Teodora Baluta1208f142013-11-10 17:12:42 +02002331 if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) {
Joe Perches915006c2013-03-18 10:44:47 -07002332 pDevice->bMeasureInProgress = true;
2333 MACvSelectPage1(pDevice->PortOffset);
2334 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
2335 MACvSelectPage0(pDevice->PortOffset);
2336 pDevice->byBasicMap = 0;
2337 pDevice->byCCAFraction = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002338 for (ii = 0; ii < 8; ii++)
Joe Perches915006c2013-03-18 10:44:47 -07002339 pDevice->dwRPIs[ii] = 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002340
Joe Perches915006c2013-03-18 10:44:47 -07002341 } else {
2342 // can not measure because set channel fail
Joe Perches915006c2013-03-18 10:44:47 -07002343 // clear measure control
2344 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2345 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE);
2346 MACvSelectPage1(pDevice->PortOffset);
2347 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2348 MACvSelectPage0(pDevice->PortOffset);
2349 }
2350 }
2351 if (pDevice->dwIsr & ISR_MEASUREEND) {
2352 // 802.11h measure end
2353 pDevice->bMeasureInProgress = false;
2354 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
2355 MACvSelectPage1(pDevice->PortOffset);
2356 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
2357 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
2358 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData);
2359 pDevice->byBasicMap |= (byData >> 4);
2360 VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction);
2361 VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData);
2362 // clear measure control
2363 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2364 MACvSelectPage0(pDevice->PortOffset);
2365 set_channel(pDevice, pDevice->byOrgChannel);
Joe Perches915006c2013-03-18 10:44:47 -07002366 MACvSelectPage1(pDevice->PortOffset);
2367 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2368 MACvSelectPage0(pDevice->PortOffset);
2369 if (byData & MSRCTL_FINISH) {
2370 // measure success
2371 s_vCompleteCurrentMeasure(pDevice, 0);
2372 } else {
2373 // can not measure because not ready before end of measure time
2374 s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
2375 }
2376 }
2377 if (pDevice->dwIsr & ISR_QUIETSTART) {
2378 do {
2379 ;
Teodora Baluta1208f142013-11-10 17:12:42 +02002380 } while (!CARDbStartQuiet(pDevice));
Joe Perches915006c2013-03-18 10:44:47 -07002381 }
2382 }
Forest Bond5449c682009-04-25 10:30:44 -04002383
Joe Perches915006c2013-03-18 10:44:47 -07002384 if (pDevice->dwIsr & ISR_TBTT) {
Teodora Baluta1208f142013-11-10 17:12:42 +02002385 if (pDevice->bEnableFirstQuiet) {
Joe Perches915006c2013-03-18 10:44:47 -07002386 pDevice->byQuietStartCount--;
2387 if (pDevice->byQuietStartCount == 0) {
2388 pDevice->bEnableFirstQuiet = false;
2389 MACvSelectPage1(pDevice->PortOffset);
2390 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
2391 MACvSelectPage0(pDevice->PortOffset);
2392 }
2393 }
Teodora Baluta1208f142013-11-10 17:12:42 +02002394 if (pDevice->bChannelSwitch &&
Joe Perches915006c2013-03-18 10:44:47 -07002395 (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE)) {
2396 pDevice->byChannelSwitchCount--;
2397 if (pDevice->byChannelSwitchCount == 0) {
2398 pDevice->bChannelSwitch = false;
2399 set_channel(pDevice, pDevice->byNewChannel);
2400 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2401 MACvSelectPage1(pDevice->PortOffset);
2402 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2403 MACvSelectPage0(pDevice->PortOffset);
2404 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
Forest Bond5449c682009-04-25 10:30:44 -04002405
Joe Perches915006c2013-03-18 10:44:47 -07002406 }
2407 }
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002408 if (pDevice->eOPMode != OP_MODE_ADHOC) {
Teodora Baluta1208f142013-11-10 17:12:42 +02002409 if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) {
Joe Perches915006c2013-03-18 10:44:47 -07002410 long ldBm;
Forest Bond5449c682009-04-25 10:30:44 -04002411
Joe Perches915006c2013-03-18 10:44:47 -07002412 RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
2413 for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
2414 if (ldBm < pDevice->ldBmThreshold[ii]) {
2415 pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
2416 break;
2417 }
2418 }
2419 if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
2420 pDevice->uBBVGADiffCount++;
2421 if (pDevice->uBBVGADiffCount == 1) {
2422 // first VGA diff gain
2423 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2424 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2425 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2426 }
2427 if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
2428 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
2429 (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
2430 BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2431 }
2432 } else {
2433 pDevice->uBBVGADiffCount = 1;
2434 }
2435 }
2436 }
Forest Bond5449c682009-04-25 10:30:44 -04002437
Joe Perches915006c2013-03-18 10:44:47 -07002438 pDevice->bBeaconSent = false;
Guido Martínezbc5cf652014-04-19 16:45:00 -03002439 if (pDevice->bEnablePSMode)
Joe Perches915006c2013-03-18 10:44:47 -07002440 PSbIsNextTBTTWakeUp((void *)pDevice);
Forest Bond5449c682009-04-25 10:30:44 -04002441
Joe Perches915006c2013-03-18 10:44:47 -07002442 if ((pDevice->eOPMode == OP_MODE_AP) ||
2443 (pDevice->eOPMode == OP_MODE_ADHOC)) {
Joe Perches915006c2013-03-18 10:44:47 -07002444 MACvOneShotTimer1MicroSec(pDevice->PortOffset,
2445 (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10);
2446 }
Forest Bond5449c682009-04-25 10:30:44 -04002447
Guido Martínez4e8a7e52014-04-19 16:44:59 -03002448 /* TODO: adhoc PS mode */
Forest Bond5449c682009-04-25 10:30:44 -04002449
Joe Perches915006c2013-03-18 10:44:47 -07002450 }
Forest Bond5449c682009-04-25 10:30:44 -04002451
Joe Perches915006c2013-03-18 10:44:47 -07002452 if (pDevice->dwIsr & ISR_BNTX) {
Joe Perches915006c2013-03-18 10:44:47 -07002453 if (pDevice->eOPMode == OP_MODE_ADHOC) {
2454 pDevice->bIsBeaconBufReadySet = false;
2455 pDevice->cbBeaconBufReadySetCnt = 0;
2456 }
Forest Bond5449c682009-04-25 10:30:44 -04002457
Joe Perches915006c2013-03-18 10:44:47 -07002458 if (pDevice->eOPMode == OP_MODE_AP) {
2459 if (pMgmt->byDTIMCount > 0) {
2460 pMgmt->byDTIMCount--;
2461 pMgmt->sNodeDBTable[0].bRxPSPoll = false;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002462 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002463 if (pMgmt->byDTIMCount == 0) {
2464 // check if mutltcast tx bufferring
2465 pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2466 pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2467 bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
2468 }
2469 }
2470 }
2471 pDevice->bBeaconSent = true;
Forest Bond5449c682009-04-25 10:30:44 -04002472
Teodora Baluta1208f142013-11-10 17:12:42 +02002473 if (pDevice->bChannelSwitch) {
Joe Perches915006c2013-03-18 10:44:47 -07002474 pDevice->byChannelSwitchCount--;
2475 if (pDevice->byChannelSwitchCount == 0) {
2476 pDevice->bChannelSwitch = false;
2477 set_channel(pDevice, pDevice->byNewChannel);
2478 VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2479 MACvSelectPage1(pDevice->PortOffset);
2480 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2481 MACvSelectPage0(pDevice->PortOffset);
Joe Perches915006c2013-03-18 10:44:47 -07002482 CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
2483 }
2484 }
Forest Bond5449c682009-04-25 10:30:44 -04002485
Joe Perches915006c2013-03-18 10:44:47 -07002486 }
Forest Bond5449c682009-04-25 10:30:44 -04002487
Guido Martínezbc5cf652014-04-19 16:45:00 -03002488 if (pDevice->dwIsr & ISR_RXDMA0)
Joe Perches915006c2013-03-18 10:44:47 -07002489 max_count += device_rx_srv(pDevice, TYPE_RXDMA0);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002490
2491 if (pDevice->dwIsr & ISR_RXDMA1)
Joe Perches915006c2013-03-18 10:44:47 -07002492 max_count += device_rx_srv(pDevice, TYPE_RXDMA1);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002493
2494 if (pDevice->dwIsr & ISR_TXDMA0)
Joe Perches915006c2013-03-18 10:44:47 -07002495 max_count += device_tx_srv(pDevice, TYPE_TXDMA0);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002496
2497 if (pDevice->dwIsr & ISR_AC0DMA)
Joe Perches915006c2013-03-18 10:44:47 -07002498 max_count += device_tx_srv(pDevice, TYPE_AC0DMA);
Guido Martínezbc5cf652014-04-19 16:45:00 -03002499
Joe Perches915006c2013-03-18 10:44:47 -07002500 if (pDevice->dwIsr & ISR_SOFTTIMER1) {
2501 if (pDevice->eOPMode == OP_MODE_AP) {
2502 if (pDevice->bShortSlotTime)
2503 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
2504 else
2505 pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1));
2506 }
2507 bMgrPrepareBeaconToSend(pDevice, pMgmt);
2508 pDevice->byCntMeasure = 0;
2509 }
Forest Bond5449c682009-04-25 10:30:44 -04002510
Joe Perches915006c2013-03-18 10:44:47 -07002511 MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
Forest Bond5449c682009-04-25 10:30:44 -04002512
Joe Perches915006c2013-03-18 10:44:47 -07002513 MACvReceive0(pDevice->PortOffset);
2514 MACvReceive1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002515
Joe Perches915006c2013-03-18 10:44:47 -07002516 if (max_count > pDevice->sOpts.int_works)
2517 break;
2518 }
Forest Bond5449c682009-04-25 10:30:44 -04002519
Guido Martínezbc5cf652014-04-19 16:45:00 -03002520 if (byOrgPageSel == 1)
Joe Perches915006c2013-03-18 10:44:47 -07002521 MACvSelectPage1(pDevice->PortOffset);
Forest Bond5449c682009-04-25 10:30:44 -04002522
Joe Perches915006c2013-03-18 10:44:47 -07002523 spin_unlock_irq(&pDevice->lock);
2524 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
Forest Bond5449c682009-04-25 10:30:44 -04002525
Joe Perches915006c2013-03-18 10:44:47 -07002526 return IRQ_RETVAL(handled);
Forest Bond5449c682009-04-25 10:30:44 -04002527}
2528
Forest Bond5449c682009-04-25 10:30:44 -04002529static unsigned const ethernet_polynomial = 0x04c11db7U;
2530static inline u32 ether_crc(int length, unsigned char *data)
2531{
Joe Perches915006c2013-03-18 10:44:47 -07002532 int crc = -1;
Forest Bond5449c682009-04-25 10:30:44 -04002533
Joe Perches915006c2013-03-18 10:44:47 -07002534 while (--length >= 0) {
2535 unsigned char current_octet = *data++;
2536 int bit;
Guillaume Clement6b711272014-07-25 01:06:16 +02002537
Joe Perches915006c2013-03-18 10:44:47 -07002538 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
2539 crc = (crc << 1) ^
2540 ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
2541 }
2542 }
2543 return crc;
Forest Bond5449c682009-04-25 10:30:44 -04002544}
2545
2546//2008-8-4 <add> by chester
Charles Clément5c9824e2010-06-02 09:51:59 -07002547static int Config_FileGetParameter(unsigned char *string,
Joe Perches915006c2013-03-18 10:44:47 -07002548 unsigned char *dest, unsigned char *source)
Forest Bond5449c682009-04-25 10:30:44 -04002549{
Joe Perches915006c2013-03-18 10:44:47 -07002550 unsigned char buf1[100];
2551 int source_len = strlen(source);
Forest Bond5449c682009-04-25 10:30:44 -04002552
Joe Perches915006c2013-03-18 10:44:47 -07002553 memset(buf1, 0, 100);
2554 strcat(buf1, string);
2555 strcat(buf1, "=");
2556 source += strlen(buf1);
Forest Bond5449c682009-04-25 10:30:44 -04002557
Joe Perches915006c2013-03-18 10:44:47 -07002558 memcpy(dest, source, source_len - strlen(buf1));
2559 return true;
Forest Bond5449c682009-04-25 10:30:44 -04002560}
2561
Guillaume Clementfa138492014-07-25 01:06:24 +02002562int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter)
Al Virof8054422013-04-06 18:11:22 -04002563{
2564 unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
Joe Perches915006c2013-03-18 10:44:47 -07002565 unsigned char tmpbuffer[20];
Al Virof8054422013-04-06 18:11:22 -04002566 struct file *file;
Guillaume Clementfa138492014-07-25 01:06:24 +02002567 int result = 0;
Forest Bond5449c682009-04-25 10:30:44 -04002568
Al Virof8054422013-04-06 18:11:22 -04002569 if (!buffer) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002570 pr_err("allocate mem for file fail?\n");
Al Virof8054422013-04-06 18:11:22 -04002571 return -1;
2572 }
2573 file = filp_open(CONFIG_PATH, O_RDONLY, 0);
2574 if (IS_ERR(file)) {
2575 kfree(buffer);
Guillaume Clement941ead92014-07-25 01:06:21 +02002576 pr_err("Config_FileOperation:open file fail?\n");
Al Virof8054422013-04-06 18:11:22 -04002577 return -1;
Joe Perches915006c2013-03-18 10:44:47 -07002578 }
Forest Bond5449c682009-04-25 10:30:44 -04002579
Al Virof8054422013-04-06 18:11:22 -04002580 if (kernel_read(file, 0, buffer, 1024) < 0) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002581 pr_err("read file error?\n");
Joe Perches915006c2013-03-18 10:44:47 -07002582 result = -1;
2583 goto error1;
2584 }
Forest Bond5449c682009-04-25 10:30:44 -04002585
Al Virof8054422013-04-06 18:11:22 -04002586 if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
Guillaume Clement941ead92014-07-25 01:06:21 +02002587 pr_err("get parameter error?\n");
Joe Perches915006c2013-03-18 10:44:47 -07002588 result = -1;
2589 goto error1;
2590 }
Forest Bond5449c682009-04-25 10:30:44 -04002591
Guillaume Clementfa138492014-07-25 01:06:24 +02002592 if (memcmp(tmpbuffer, "USA", 3) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002593 result = ZoneType_USA;
Guillaume Clementfa138492014-07-25 01:06:24 +02002594 } else if(memcmp(tmpbuffer, "JAPAN", 5) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002595 result = ZoneType_Japan;
Guillaume Clementfa138492014-07-25 01:06:24 +02002596 } else if(memcmp(tmpbuffer, "EUROPE", 5) == 0) {
Joe Perches915006c2013-03-18 10:44:47 -07002597 result = ZoneType_Europe;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002598 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002599 result = -1;
Guillaume Clement941ead92014-07-25 01:06:21 +02002600 pr_err("Unknown Zonetype[%s]?\n", tmpbuffer);
Joe Perches915006c2013-03-18 10:44:47 -07002601 }
Forest Bond5449c682009-04-25 10:30:44 -04002602
2603error1:
Joe Perches915006c2013-03-18 10:44:47 -07002604 kfree(buffer);
Al Virof8054422013-04-06 18:11:22 -04002605 fput(file);
Joe Perches915006c2013-03-18 10:44:47 -07002606 return result;
Forest Bond5449c682009-04-25 10:30:44 -04002607}
2608
Guillaume Clement84b50762014-07-25 01:06:18 +02002609static void device_set_multi(struct net_device *dev)
2610{
Joe Perches915006c2013-03-18 10:44:47 -07002611 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002612
Joe Perches915006c2013-03-18 10:44:47 -07002613 PSMgmtObject pMgmt = pDevice->pMgmt;
2614 u32 mc_filter[2];
2615 struct netdev_hw_addr *ha;
Forest Bond5449c682009-04-25 10:30:44 -04002616
Joe Perches915006c2013-03-18 10:44:47 -07002617 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
Forest Bond5449c682009-04-25 10:30:44 -04002618
Joe Perches915006c2013-03-18 10:44:47 -07002619 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
2620 DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
2621 /* Unconditionally log net taps. */
2622 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002623 } else if ((netdev_mc_count(dev) > pDevice->multicast_limit)
Joe Perches915006c2013-03-18 10:44:47 -07002624 || (dev->flags & IFF_ALLMULTI)) {
2625 MACvSelectPage1(pDevice->PortOffset);
2626 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
2627 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
2628 MACvSelectPage0(pDevice->PortOffset);
2629 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002630 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002631 memset(mc_filter, 0, sizeof(mc_filter));
2632 netdev_for_each_mc_addr(ha, dev) {
2633 int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
Guillaume Clement6b711272014-07-25 01:06:16 +02002634
Joe Perches915006c2013-03-18 10:44:47 -07002635 mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
2636 }
2637 MACvSelectPage1(pDevice->PortOffset);
2638 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]);
2639 VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]);
2640 MACvSelectPage0(pDevice->PortOffset);
2641 pDevice->byRxMode &= ~(RCR_UNICAST);
2642 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2643 }
Forest Bond5449c682009-04-25 10:30:44 -04002644
Joe Perches915006c2013-03-18 10:44:47 -07002645 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2646 // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
2647 pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2648 pDevice->byRxMode &= ~(RCR_UNICAST);
2649 }
Forest Bond5449c682009-04-25 10:30:44 -04002650
Joe Perches915006c2013-03-18 10:44:47 -07002651 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
2652 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode);
Forest Bond5449c682009-04-25 10:30:44 -04002653}
2654
Guillaume Clement84b50762014-07-25 01:06:18 +02002655static struct net_device_stats *device_get_stats(struct net_device *dev)
2656{
Joe Perches915006c2013-03-18 10:44:47 -07002657 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002658
Joe Perches915006c2013-03-18 10:44:47 -07002659 return &pDevice->stats;
Forest Bond5449c682009-04-25 10:30:44 -04002660}
2661
Guillaume Clement84b50762014-07-25 01:06:18 +02002662static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2663{
Forest Bondc9d03522009-06-01 20:00:14 -04002664 PSDevice pDevice = (PSDevice)netdev_priv(dev);
Forest Bond5449c682009-04-25 10:30:44 -04002665
Joe Perches915006c2013-03-18 10:44:47 -07002666 struct iwreq *wrq = (struct iwreq *)rq;
2667 int rc = 0;
2668 PSMgmtObject pMgmt = pDevice->pMgmt;
2669 PSCmdRequest pReq;
Forest Bond5449c682009-04-25 10:30:44 -04002670
Joe Perches915006c2013-03-18 10:44:47 -07002671 if (pMgmt == NULL) {
2672 rc = -EFAULT;
2673 return rc;
2674 }
Forest Bond5449c682009-04-25 10:30:44 -04002675
Joe Perches915006c2013-03-18 10:44:47 -07002676 switch (cmd) {
Forest Bond5449c682009-04-25 10:30:44 -04002677 case SIOCGIWNAME:
2678 rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
2679 break;
2680
2681 case SIOCGIWNWID: //0x8b03 support
Marcos Paulo de Souza428c1fb2011-11-28 19:16:37 +00002682 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002683 break;
2684
2685 // Set frequency/channel
2686 case SIOCSIWFREQ:
Joe Perches915006c2013-03-18 10:44:47 -07002687 rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002688 break;
2689
2690 // Get frequency/channel
2691 case SIOCGIWFREQ:
2692 rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
2693 break;
2694
2695 // Set desired network name (ESSID)
2696 case SIOCSIWESSID:
2697
Joe Perches915006c2013-03-18 10:44:47 -07002698 {
2699 char essid[IW_ESSID_MAX_SIZE+1];
Guillaume Clement6b711272014-07-25 01:06:16 +02002700
Joe Perches915006c2013-03-18 10:44:47 -07002701 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
2702 rc = -E2BIG;
2703 break;
Forest Bond5449c682009-04-25 10:30:44 -04002704 }
Joe Perches915006c2013-03-18 10:44:47 -07002705 if (copy_from_user(essid, wrq->u.essid.pointer,
2706 wrq->u.essid.length)) {
2707 rc = -EFAULT;
2708 break;
2709 }
2710 rc = iwctl_siwessid(dev, NULL,
2711 &(wrq->u.essid), essid);
2712 }
2713 break;
Forest Bond5449c682009-04-25 10:30:44 -04002714
Joe Perches915006c2013-03-18 10:44:47 -07002715 // Get current network name (ESSID)
Forest Bond5449c682009-04-25 10:30:44 -04002716 case SIOCGIWESSID:
2717
Joe Perches915006c2013-03-18 10:44:47 -07002718 {
2719 char essid[IW_ESSID_MAX_SIZE+1];
Guillaume Clement6b711272014-07-25 01:06:16 +02002720
Joe Perches915006c2013-03-18 10:44:47 -07002721 if (wrq->u.essid.pointer)
2722 rc = iwctl_giwessid(dev, NULL,
2723 &(wrq->u.essid), essid);
2724 if (copy_to_user(wrq->u.essid.pointer,
2725 essid,
2726 wrq->u.essid.length))
2727 rc = -EFAULT;
2728 }
2729 break;
Forest Bond5449c682009-04-25 10:30:44 -04002730
2731 case SIOCSIWAP:
2732
2733 rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2734 break;
2735
Forest Bond5449c682009-04-25 10:30:44 -04002736 // Get current Access Point (BSSID)
2737 case SIOCGIWAP:
2738 rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
2739 break;
2740
Forest Bond5449c682009-04-25 10:30:44 -04002741 // Set desired station name
2742 case SIOCSIWNICKN:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002743 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN\n");
Joe Perches915006c2013-03-18 10:44:47 -07002744 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002745 break;
2746
2747 // Get current station name
2748 case SIOCGIWNICKN:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002749 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN\n");
Joe Perches915006c2013-03-18 10:44:47 -07002750 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002751 break;
2752
2753 // Set the desired bit-rate
2754 case SIOCSIWRATE:
2755 rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2756 break;
2757
Joe Perches915006c2013-03-18 10:44:47 -07002758 // Get the current bit-rate
Forest Bond5449c682009-04-25 10:30:44 -04002759 case SIOCGIWRATE:
2760
2761 rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
2762 break;
2763
Joe Perches915006c2013-03-18 10:44:47 -07002764 // Set the desired RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002765 case SIOCSIWRTS:
2766
2767 rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
2768 break;
2769
Joe Perches915006c2013-03-18 10:44:47 -07002770 // Get the current RTS threshold
Forest Bond5449c682009-04-25 10:30:44 -04002771 case SIOCGIWRTS:
2772
2773 rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
2774 break;
2775
2776 // Set the desired fragmentation threshold
2777 case SIOCSIWFRAG:
2778
2779 rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
Joe Perches915006c2013-03-18 10:44:47 -07002780 break;
Forest Bond5449c682009-04-25 10:30:44 -04002781
Joe Perches915006c2013-03-18 10:44:47 -07002782 // Get the current fragmentation threshold
Forest Bond5449c682009-04-25 10:30:44 -04002783 case SIOCGIWFRAG:
2784
2785 rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
2786 break;
2787
2788 // Set mode of operation
2789 case SIOCSIWMODE:
Joe Perches915006c2013-03-18 10:44:47 -07002790 rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002791 break;
2792
2793 // Get mode of operation
2794 case SIOCGIWMODE:
2795 rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
2796 break;
2797
2798 // Set WEP keys and mode
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002799 case SIOCSIWENCODE: {
Joe Perches915006c2013-03-18 10:44:47 -07002800 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04002801
Joe Perches915006c2013-03-18 10:44:47 -07002802 if (wrq->u.encoding.pointer) {
Joe Perches915006c2013-03-18 10:44:47 -07002803 if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
2804 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04002805 break;
2806 }
Joe Perches915006c2013-03-18 10:44:47 -07002807 memset(abyKey, 0, WLAN_WEP232_KEYLEN);
2808 if (copy_from_user(abyKey,
2809 wrq->u.encoding.pointer,
2810 wrq->u.encoding.length)) {
2811 rc = -EFAULT;
2812 break;
2813 }
2814 } else if (wrq->u.encoding.length != 0) {
2815 rc = -EINVAL;
2816 break;
Forest Bond5449c682009-04-25 10:30:44 -04002817 }
Joe Perches915006c2013-03-18 10:44:47 -07002818 rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
2819 }
2820 break;
Forest Bond5449c682009-04-25 10:30:44 -04002821
Joe Perches915006c2013-03-18 10:44:47 -07002822 // Get the WEP keys and mode
Forest Bond5449c682009-04-25 10:30:44 -04002823 case SIOCGIWENCODE:
2824
2825 if (!capable(CAP_NET_ADMIN)) {
2826 rc = -EPERM;
2827 break;
2828 }
2829 {
Joe Perches915006c2013-03-18 10:44:47 -07002830 char abyKey[WLAN_WEP232_KEYLEN];
Forest Bond5449c682009-04-25 10:30:44 -04002831
Joe Perches915006c2013-03-18 10:44:47 -07002832 rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
Guillaume Clementa1613422014-07-25 01:06:22 +02002833 if (rc != 0)
2834 break;
Forest Bond5449c682009-04-25 10:30:44 -04002835 if (wrq->u.encoding.pointer) {
2836 if (copy_to_user(wrq->u.encoding.pointer,
Joe Perches915006c2013-03-18 10:44:47 -07002837 abyKey,
2838 wrq->u.encoding.length))
Forest Bond5449c682009-04-25 10:30:44 -04002839 rc = -EFAULT;
2840 }
2841 }
2842 break;
2843
Forest Bond5449c682009-04-25 10:30:44 -04002844 // Get the current Tx-Power
2845 case SIOCGIWTXPOW:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002846 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW\n");
Joe Perches915006c2013-03-18 10:44:47 -07002847 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002848 break;
2849
2850 case SIOCSIWTXPOW:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002851 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW\n");
Joe Perches915006c2013-03-18 10:44:47 -07002852 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002853 break;
2854
Forest Bond5449c682009-04-25 10:30:44 -04002855 case SIOCSIWRETRY:
2856
2857 rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
2858 break;
2859
2860 case SIOCGIWRETRY:
2861
2862 rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
2863 break;
2864
Forest Bond5449c682009-04-25 10:30:44 -04002865 // Get range of parameters
2866 case SIOCGIWRANGE:
2867
Joe Perches915006c2013-03-18 10:44:47 -07002868 {
2869 struct iw_range range;
Forest Bond5449c682009-04-25 10:30:44 -04002870
Joe Perches915006c2013-03-18 10:44:47 -07002871 rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range);
2872 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
2873 rc = -EFAULT;
2874 }
Forest Bond5449c682009-04-25 10:30:44 -04002875
Joe Perches915006c2013-03-18 10:44:47 -07002876 break;
Forest Bond5449c682009-04-25 10:30:44 -04002877
2878 case SIOCGIWPOWER:
2879
2880 rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
2881 break;
2882
Forest Bond5449c682009-04-25 10:30:44 -04002883 case SIOCSIWPOWER:
2884
2885 rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
2886 break;
2887
Forest Bond5449c682009-04-25 10:30:44 -04002888 case SIOCGIWSENS:
2889
Joe Perches915006c2013-03-18 10:44:47 -07002890 rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
Forest Bond5449c682009-04-25 10:30:44 -04002891 break;
2892
2893 case SIOCSIWSENS:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002894 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS\n");
Forest Bond5449c682009-04-25 10:30:44 -04002895 rc = -EOPNOTSUPP;
2896 break;
2897
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002898 case SIOCGIWAPLIST: {
Joe Perches915006c2013-03-18 10:44:47 -07002899 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
Forest Bond5449c682009-04-25 10:30:44 -04002900
Joe Perches915006c2013-03-18 10:44:47 -07002901 if (wrq->u.data.pointer) {
2902 rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
2903 if (rc == 0) {
2904 if (copy_to_user(wrq->u.data.pointer,
2905 buffer,
2906 (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality)))
2907 ))
2908 rc = -EFAULT;
2909 }
2910 }
2911 }
2912 break;
Forest Bond5449c682009-04-25 10:30:44 -04002913
Forest Bond5449c682009-04-25 10:30:44 -04002914#ifdef WIRELESS_SPY
Joe Perches915006c2013-03-18 10:44:47 -07002915 // Set the spy list
Forest Bond5449c682009-04-25 10:30:44 -04002916 case SIOCSIWSPY:
2917
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002918 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY\n");
Forest Bond5449c682009-04-25 10:30:44 -04002919 rc = -EOPNOTSUPP;
2920 break;
2921
2922 // Get the spy list
2923 case SIOCGIWSPY:
2924
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002925 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY\n");
Forest Bond5449c682009-04-25 10:30:44 -04002926 rc = -EOPNOTSUPP;
2927 break;
2928
2929#endif // WIRELESS_SPY
2930
2931 case SIOCGIWPRIV:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002932 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV\n");
Forest Bond5449c682009-04-25 10:30:44 -04002933 rc = -EOPNOTSUPP;
Forest Bond5449c682009-04-25 10:30:44 -04002934 break;
2935
Forest Bond5449c682009-04-25 10:30:44 -04002936//2008-0409-07, <Add> by Einsn Liu
Joe Perches915006c2013-03-18 10:44:47 -07002937#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
Forest Bond5449c682009-04-25 10:30:44 -04002938 case SIOCSIWAUTH:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002939 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
Forest Bond5449c682009-04-25 10:30:44 -04002940 rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
2941 break;
2942
2943 case SIOCGIWAUTH:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002944 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH\n");
Forest Bond5449c682009-04-25 10:30:44 -04002945 rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
2946 break;
2947
2948 case SIOCSIWGENIE:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002949 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE\n");
Forest Bond5449c682009-04-25 10:30:44 -04002950 rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2951 break;
2952
2953 case SIOCGIWGENIE:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002954 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE\n");
Forest Bond5449c682009-04-25 10:30:44 -04002955 rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2956 break;
2957
Joe Perches5e0cc8a2013-03-18 20:55:37 -07002958 case SIOCSIWENCODEEXT: {
Joe Perches915006c2013-03-18 10:44:47 -07002959 char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002960
2961 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT\n");
Joe Perches915006c2013-03-18 10:44:47 -07002962 if (wrq->u.encoding.pointer) {
2963 memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1);
2964 if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) {
2965 rc = -E2BIG;
Forest Bond5449c682009-04-25 10:30:44 -04002966 break;
2967 }
Joe Perches915006c2013-03-18 10:44:47 -07002968 if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) {
2969 rc = -EFAULT;
2970 break;
2971 }
2972 } else if (wrq->u.encoding.length != 0) {
2973 rc = -EINVAL;
2974 break;
Forest Bond5449c682009-04-25 10:30:44 -04002975 }
Joe Perches915006c2013-03-18 10:44:47 -07002976 rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
2977 }
2978 break;
Forest Bond5449c682009-04-25 10:30:44 -04002979
2980 case SIOCGIWENCODEEXT:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002981 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT\n");
Forest Bond5449c682009-04-25 10:30:44 -04002982 rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
2983 break;
2984
2985 case SIOCSIWMLME:
Guillaume Clementbfd7a282014-07-25 01:06:17 +02002986 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
Forest Bond5449c682009-04-25 10:30:44 -04002987 rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
2988 break;
2989
2990#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2991//End Add -- //2008-0409-07, <Add> by Einsn Liu
2992
Joe Perches915006c2013-03-18 10:44:47 -07002993 case IOCTL_CMD_TEST:
Forest Bond5449c682009-04-25 10:30:44 -04002994
2995 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
Joe Perches915006c2013-03-18 10:44:47 -07002996 rc = -EFAULT;
2997 break;
Forest Bond5449c682009-04-25 10:30:44 -04002998 } else {
Joe Perches915006c2013-03-18 10:44:47 -07002999 rc = 0;
Forest Bond5449c682009-04-25 10:30:44 -04003000 }
Joe Perches915006c2013-03-18 10:44:47 -07003001 pReq = (PSCmdRequest)rq;
3002 pReq->wResult = MAGIC_CODE;
3003 break;
Forest Bond5449c682009-04-25 10:30:44 -04003004
Joe Perches915006c2013-03-18 10:44:47 -07003005 case IOCTL_CMD_SET:
Forest Bond5449c682009-04-25 10:30:44 -04003006
Joe Perches915006c2013-03-18 10:44:47 -07003007#ifdef SndEvt_ToAPI
3008 if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) &&
3009 !(pDevice->flags & DEVICE_FLAGS_OPENED))
3010#else
3011 if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
3012 (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA))
3013#endif
3014 {
3015 rc = -EFAULT;
3016 break;
3017 } else {
3018 rc = 0;
3019 }
3020
Guido Martínezbc5cf652014-04-19 16:45:00 -03003021 if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy)))
Joe Perches915006c2013-03-18 10:44:47 -07003022 return -EBUSY;
Guido Martínezbc5cf652014-04-19 16:45:00 -03003023
Joe Perches915006c2013-03-18 10:44:47 -07003024 rc = private_ioctl(pDevice, rq);
3025 clear_bit(0, (void *)&(pMgmt->uCmdBusy));
3026 break;
Forest Bond5449c682009-04-25 10:30:44 -04003027
Joe Perches915006c2013-03-18 10:44:47 -07003028 case IOCTL_CMD_HOSTAPD:
Forest Bond5449c682009-04-25 10:30:44 -04003029
Joe Perches915006c2013-03-18 10:44:47 -07003030 rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data);
3031 break;
Forest Bond5449c682009-04-25 10:30:44 -04003032
Joe Perches915006c2013-03-18 10:44:47 -07003033 case IOCTL_CMD_WPA:
Forest Bond5449c682009-04-25 10:30:44 -04003034
Joe Perches915006c2013-03-18 10:44:47 -07003035 rc = wpa_ioctl(pDevice, &wrq->u.data);
3036 break;
Forest Bond5449c682009-04-25 10:30:44 -04003037
3038 case SIOCETHTOOL:
James A Shacklefordebc43d02014-05-31 20:09:05 -04003039 return ethtool_ioctl(dev, rq->ifr_data);
Joe Perches915006c2013-03-18 10:44:47 -07003040 // All other calls are currently unsupported
Forest Bond5449c682009-04-25 10:30:44 -04003041
3042 default:
3043 rc = -EOPNOTSUPP;
Joe Perches915006c2013-03-18 10:44:47 -07003044 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
Forest Bond5449c682009-04-25 10:30:44 -04003045
Joe Perches915006c2013-03-18 10:44:47 -07003046 }
Forest Bond5449c682009-04-25 10:30:44 -04003047
Joe Perches915006c2013-03-18 10:44:47 -07003048 if (pDevice->bCommit) {
3049 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
3050 netif_stop_queue(pDevice->dev);
3051 spin_lock_irq(&pDevice->lock);
3052 bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
3053 spin_unlock_irq(&pDevice->lock);
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003054 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003055 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
3056 spin_lock_irq(&pDevice->lock);
3057 pDevice->bLinkPass = false;
3058 memset(pMgmt->abyCurrBSSID, 0, 6);
3059 pMgmt->eCurrState = WMAC_STATE_IDLE;
3060 netif_stop_queue(pDevice->dev);
3061#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
3062 pMgmt->eScanType = WMAC_SCAN_ACTIVE;
Teodora Baluta1208f142013-11-10 17:12:42 +02003063 if (!pDevice->bWPASuppWextEnabled)
Joe Perches915006c2013-03-18 10:44:47 -07003064#endif
3065 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
3066 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3067 spin_unlock_irq(&pDevice->lock);
3068 }
3069 pDevice->bCommit = false;
3070 }
Forest Bond5449c682009-04-25 10:30:44 -04003071
Joe Perches915006c2013-03-18 10:44:47 -07003072 return rc;
Forest Bond5449c682009-04-25 10:30:44 -04003073}
3074
James A Shacklefordebc43d02014-05-31 20:09:05 -04003075static int ethtool_ioctl(struct net_device *dev, void __user *useraddr)
Forest Bond5449c682009-04-25 10:30:44 -04003076{
3077 u32 ethcmd;
3078
3079 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
3080 return -EFAULT;
3081
Joe Perches915006c2013-03-18 10:44:47 -07003082 switch (ethcmd) {
Forest Bond5449c682009-04-25 10:30:44 -04003083 case ETHTOOL_GDRVINFO: {
3084 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
Guillaume Clement6b711272014-07-25 01:06:16 +02003085
Forest Bond5449c682009-04-25 10:30:44 -04003086 strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
3087 strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
3088 if (copy_to_user(useraddr, &info, sizeof(info)))
3089 return -EFAULT;
3090 return 0;
3091 }
3092
Joe Perches915006c2013-03-18 10:44:47 -07003093 }
Forest Bond5449c682009-04-25 10:30:44 -04003094
3095 return -EOPNOTSUPP;
3096}
3097
3098/*------------------------------------------------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -04003099
Charles Clément013a4682010-06-15 10:39:24 -07003100MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
Forest Bond5449c682009-04-25 10:30:44 -04003101
3102static struct pci_driver device_driver = {
Peter Huewe34381c22011-01-10 23:28:06 +01003103 .name = DEVICE_NAME,
3104 .id_table = vt6655_pci_id_table,
3105 .probe = vt6655_probe,
3106 .remove = vt6655_remove,
Forest Bond5449c682009-04-25 10:30:44 -04003107#ifdef CONFIG_PM
Peter Huewe34381c22011-01-10 23:28:06 +01003108 .suspend = viawget_suspend,
3109 .resume = viawget_resume,
Forest Bond5449c682009-04-25 10:30:44 -04003110#endif
Forest Bond5449c682009-04-25 10:30:44 -04003111};
3112
Charles Clément013a4682010-06-15 10:39:24 -07003113static int __init vt6655_init_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003114{
Joe Perches915006c2013-03-18 10:44:47 -07003115 int ret;
Forest Bond5449c682009-04-25 10:30:44 -04003116
Forest Bond5449c682009-04-25 10:30:44 -04003117 ret = pci_register_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003118#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003119 if (ret >= 0)
3120 register_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003121#endif
Forest Bond5449c682009-04-25 10:30:44 -04003122
Joe Perches915006c2013-03-18 10:44:47 -07003123 return ret;
Forest Bond5449c682009-04-25 10:30:44 -04003124}
3125
Charles Clément013a4682010-06-15 10:39:24 -07003126static void __exit vt6655_cleanup_module(void)
Forest Bond5449c682009-04-25 10:30:44 -04003127{
Forest Bond5449c682009-04-25 10:30:44 -04003128#ifdef CONFIG_PM
Joe Perches915006c2013-03-18 10:44:47 -07003129 unregister_reboot_notifier(&device_notifier);
Forest Bond5449c682009-04-25 10:30:44 -04003130#endif
Joe Perches915006c2013-03-18 10:44:47 -07003131 pci_unregister_driver(&device_driver);
Forest Bond5449c682009-04-25 10:30:44 -04003132}
3133
Charles Clément013a4682010-06-15 10:39:24 -07003134module_init(vt6655_init_module);
3135module_exit(vt6655_cleanup_module);
Forest Bond5449c682009-04-25 10:30:44 -04003136
Forest Bond5449c682009-04-25 10:30:44 -04003137#ifdef CONFIG_PM
3138static int
3139device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
3140{
Joe Perches915006c2013-03-18 10:44:47 -07003141 struct pci_dev *pdev = NULL;
Guillaume Clement6b711272014-07-25 01:06:16 +02003142
Joe Perches915006c2013-03-18 10:44:47 -07003143 switch (event) {
3144 case SYS_DOWN:
3145 case SYS_HALT:
3146 case SYS_POWER_OFF:
3147 for_each_pci_dev(pdev) {
3148 if (pci_dev_driver(pdev) == &device_driver) {
3149 if (pci_get_drvdata(pdev))
3150 viawget_suspend(pdev, PMSG_HIBERNATE);
3151 }
3152 }
3153 }
3154 return NOTIFY_DONE;
Forest Bond5449c682009-04-25 10:30:44 -04003155}
3156
3157static int
Alan Coxf408ade2009-06-10 17:30:49 +01003158viawget_suspend(struct pci_dev *pcid, pm_message_t state)
Forest Bond5449c682009-04-25 10:30:44 -04003159{
Joe Perches915006c2013-03-18 10:44:47 -07003160 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003161
Joe Perches915006c2013-03-18 10:44:47 -07003162 PSDevice pDevice = pci_get_drvdata(pcid);
3163 PSMgmtObject pMgmt = pDevice->pMgmt;
Forest Bond5449c682009-04-25 10:30:44 -04003164
Joe Perches915006c2013-03-18 10:44:47 -07003165 netif_stop_queue(pDevice->dev);
3166 spin_lock_irq(&pDevice->lock);
3167 pci_save_state(pcid);
3168 del_timer(&pDevice->sTimerCommand);
3169 del_timer(&pMgmt->sTimerSecondCallback);
3170 pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
3171 pDevice->uCmdDequeueIdx = 0;
3172 pDevice->uCmdEnqueueIdx = 0;
3173 pDevice->bCmdRunning = false;
3174 MACbShutdown(pDevice->PortOffset);
3175 MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
3176 pDevice->bLinkPass = false;
3177 memset(pMgmt->abyCurrBSSID, 0, 6);
3178 pMgmt->eCurrState = WMAC_STATE_IDLE;
3179 pci_disable_device(pcid);
3180 power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state));
3181 spin_unlock_irq(&pDevice->lock);
3182 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003183}
3184
3185static int
3186viawget_resume(struct pci_dev *pcid)
3187{
Joe Perches915006c2013-03-18 10:44:47 -07003188 PSDevice pDevice = pci_get_drvdata(pcid);
3189 PSMgmtObject pMgmt = pDevice->pMgmt;
3190 int power_status; // to silence the compiler
Forest Bond5449c682009-04-25 10:30:44 -04003191
Yijing Wang6496c042013-06-27 20:57:23 +08003192 power_status = pci_set_power_state(pcid, PCI_D0);
3193 power_status = pci_enable_wake(pcid, PCI_D0, 0);
Joe Perches915006c2013-03-18 10:44:47 -07003194 pci_restore_state(pcid);
3195 if (netif_running(pDevice->dev)) {
3196 spin_lock_irq(&pDevice->lock);
3197 MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
3198 device_init_registers(pDevice, DEVICE_INIT_DXPL);
Teodora Baluta1208f142013-11-10 17:12:42 +02003199 if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
Joe Perches915006c2013-03-18 10:44:47 -07003200 pMgmt->sNodeDBTable[0].bActive = false;
3201 pDevice->bLinkPass = false;
3202 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3203 // In Adhoc, BSS state set back to started.
3204 pMgmt->eCurrState = WMAC_STATE_STARTED;
Joe Perches5e0cc8a2013-03-18 20:55:37 -07003205 } else {
Joe Perches915006c2013-03-18 10:44:47 -07003206 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
3207 pMgmt->eCurrState = WMAC_STATE_IDLE;
3208 }
3209 }
3210 init_timer(&pMgmt->sTimerSecondCallback);
3211 init_timer(&pDevice->sTimerCommand);
3212 MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
3213 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
3214 bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
3215 bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3216 spin_unlock_irq(&pDevice->lock);
3217 }
3218 return 0;
Forest Bond5449c682009-04-25 10:30:44 -04003219}
3220
3221#endif