15449c685a4b39534f18869a93896370224463715Forest Bond/*
25449c685a4b39534f18869a93896370224463715Forest Bond * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
35449c685a4b39534f18869a93896370224463715Forest Bond * All rights reserved.
45449c685a4b39534f18869a93896370224463715Forest Bond *
55449c685a4b39534f18869a93896370224463715Forest Bond * This program is free software; you can redistribute it and/or modify
65449c685a4b39534f18869a93896370224463715Forest Bond * it under the terms of the GNU General Public License as published by
75449c685a4b39534f18869a93896370224463715Forest Bond * the Free Software Foundation; either version 2 of the License, or
85449c685a4b39534f18869a93896370224463715Forest Bond * (at your option) any later version.
95449c685a4b39534f18869a93896370224463715Forest Bond *
105449c685a4b39534f18869a93896370224463715Forest Bond * This program is distributed in the hope that it will be useful,
115449c685a4b39534f18869a93896370224463715Forest Bond * but WITHOUT ANY WARRANTY; without even the implied warranty of
125449c685a4b39534f18869a93896370224463715Forest Bond * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
135449c685a4b39534f18869a93896370224463715Forest Bond * GNU General Public License for more details.
145449c685a4b39534f18869a93896370224463715Forest Bond *
155449c685a4b39534f18869a93896370224463715Forest Bond * You should have received a copy of the GNU General Public License along
165449c685a4b39534f18869a93896370224463715Forest Bond * with this program; if not, write to the Free Software Foundation, Inc.,
175449c685a4b39534f18869a93896370224463715Forest Bond * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
185449c685a4b39534f18869a93896370224463715Forest Bond *
195449c685a4b39534f18869a93896370224463715Forest Bond * File: device_main.c
205449c685a4b39534f18869a93896370224463715Forest Bond *
215449c685a4b39534f18869a93896370224463715Forest Bond * Purpose: driver entry for initial, open, close, tx and rx.
225449c685a4b39534f18869a93896370224463715Forest Bond *
235449c685a4b39534f18869a93896370224463715Forest Bond * Author: Lyndon Chen
245449c685a4b39534f18869a93896370224463715Forest Bond *
255449c685a4b39534f18869a93896370224463715Forest Bond * Date: Jan 8, 2003
265449c685a4b39534f18869a93896370224463715Forest Bond *
275449c685a4b39534f18869a93896370224463715Forest Bond * Functions:
285449c685a4b39534f18869a93896370224463715Forest Bond *
29013a468c4504738856d67118492ce7b7fff53a48Charles Clément *   vt6655_probe - module initial (insmod) driver entry
30013a468c4504738856d67118492ce7b7fff53a48Charles Clément *   vt6655_remove - module remove entry
31013a468c4504738856d67118492ce7b7fff53a48Charles Clément *   vt6655_init_info - device structure resource allocation function
325449c685a4b39534f18869a93896370224463715Forest Bond *   device_free_info - device structure resource free function
335449c685a4b39534f18869a93896370224463715Forest Bond *   device_get_pci_info - get allocated pci io/mem resource
345449c685a4b39534f18869a93896370224463715Forest Bond *   device_print_info - print out resource
355449c685a4b39534f18869a93896370224463715Forest Bond *   device_open - allocate dma/descripter resource & initial mac/bbp function
365449c685a4b39534f18869a93896370224463715Forest Bond *   device_xmit - asynchrous data tx function
375449c685a4b39534f18869a93896370224463715Forest Bond *   device_intr - interrupt handle function
385449c685a4b39534f18869a93896370224463715Forest Bond *   device_set_multi - set mac filter
395449c685a4b39534f18869a93896370224463715Forest Bond *   device_ioctl - ioctl entry
405449c685a4b39534f18869a93896370224463715Forest Bond *   device_close - shutdown mac/bbp & free dma/descripter resource
415449c685a4b39534f18869a93896370224463715Forest Bond *   device_rx_srv - rx service function
425449c685a4b39534f18869a93896370224463715Forest Bond *   device_receive_frame - rx data function
435449c685a4b39534f18869a93896370224463715Forest Bond *   device_alloc_rx_buf - rx buffer pre-allocated function
445449c685a4b39534f18869a93896370224463715Forest Bond *   device_alloc_frag_buf - rx fragement pre-allocated function
455449c685a4b39534f18869a93896370224463715Forest Bond *   device_free_tx_buf - free tx buffer function
465449c685a4b39534f18869a93896370224463715Forest Bond *   device_free_frag_buf- free de-fragement buffer
475449c685a4b39534f18869a93896370224463715Forest Bond *   device_dma0_tx_80211- tx 802.11 frame via dma0
485449c685a4b39534f18869a93896370224463715Forest Bond *   device_dma0_xmit- tx PS bufferred frame via dma0
495449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_rd0_ring- initial rd dma0 ring
505449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_rd1_ring- initial rd dma1 ring
515449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_td0_ring- initial tx dma0 ring buffer
525449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_td1_ring- initial tx dma1 ring buffer
535449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_registers- initial MAC & BBP & RF internal registers.
545449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_rings- initial tx/rx ring buffer
555449c685a4b39534f18869a93896370224463715Forest Bond *   device_init_defrag_cb- initial & allocate de-fragement buffer.
565449c685a4b39534f18869a93896370224463715Forest Bond *   device_free_rings- free all allocated ring buffer
575449c685a4b39534f18869a93896370224463715Forest Bond *   device_tx_srv- tx interrupt service function
585449c685a4b39534f18869a93896370224463715Forest Bond *
595449c685a4b39534f18869a93896370224463715Forest Bond * Revision History:
605449c685a4b39534f18869a93896370224463715Forest Bond */
615449c685a4b39534f18869a93896370224463715Forest Bond#undef __NO_VERSION__
625449c685a4b39534f18869a93896370224463715Forest Bond
63f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro#include <linux/file.h>
645449c685a4b39534f18869a93896370224463715Forest Bond#include "device.h"
655449c685a4b39534f18869a93896370224463715Forest Bond#include "card.h"
6679566eb2df013f0ed20e548f4be0f8afbe78f9a3Charles Clément#include "channel.h"
675449c685a4b39534f18869a93896370224463715Forest Bond#include "baseband.h"
685449c685a4b39534f18869a93896370224463715Forest Bond#include "mac.h"
695449c685a4b39534f18869a93896370224463715Forest Bond#include "tether.h"
705449c685a4b39534f18869a93896370224463715Forest Bond#include "wmgr.h"
715449c685a4b39534f18869a93896370224463715Forest Bond#include "wctl.h"
725449c685a4b39534f18869a93896370224463715Forest Bond#include "power.h"
735449c685a4b39534f18869a93896370224463715Forest Bond#include "wcmd.h"
745449c685a4b39534f18869a93896370224463715Forest Bond#include "iocmd.h"
755449c685a4b39534f18869a93896370224463715Forest Bond#include "tcrc.h"
765449c685a4b39534f18869a93896370224463715Forest Bond#include "rxtx.h"
775449c685a4b39534f18869a93896370224463715Forest Bond#include "wroute.h"
785449c685a4b39534f18869a93896370224463715Forest Bond#include "bssdb.h"
795449c685a4b39534f18869a93896370224463715Forest Bond#include "hostap.h"
805449c685a4b39534f18869a93896370224463715Forest Bond#include "wpactl.h"
815449c685a4b39534f18869a93896370224463715Forest Bond#include "ioctl.h"
825449c685a4b39534f18869a93896370224463715Forest Bond#include "iwctl.h"
835449c685a4b39534f18869a93896370224463715Forest Bond#include "dpc.h"
845449c685a4b39534f18869a93896370224463715Forest Bond#include "datarate.h"
855449c685a4b39534f18869a93896370224463715Forest Bond#include "rf.h"
865449c685a4b39534f18869a93896370224463715Forest Bond#include "iowpa.h"
875449c685a4b39534f18869a93896370224463715Forest Bond#include <linux/delay.h>
885449c685a4b39534f18869a93896370224463715Forest Bond#include <linux/kthread.h>
895a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
905449c685a4b39534f18869a93896370224463715Forest Bond
915449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Definitions -------------------------*/
925449c685a4b39534f18869a93896370224463715Forest Bond//
935449c685a4b39534f18869a93896370224463715Forest Bond// Define module options
945449c685a4b39534f18869a93896370224463715Forest Bond//
955449c685a4b39534f18869a93896370224463715Forest BondMODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
965449c685a4b39534f18869a93896370224463715Forest BondMODULE_LICENSE("GPL");
975449c685a4b39534f18869a93896370224463715Forest BondMODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
985449c685a4b39534f18869a93896370224463715Forest Bond
99915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#define DEVICE_PARAM(N, D)
1005449c685a4b39534f18869a93896370224463715Forest Bond
1015449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_MIN0     16
1025449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_MAX0     128
1035449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_DEF0     32
104915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(RxDescriptors0, "Number of receive descriptors0");
1055449c685a4b39534f18869a93896370224463715Forest Bond
1065449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_MIN1     16
1075449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_MAX1     128
1085449c685a4b39534f18869a93896370224463715Forest Bond#define RX_DESC_DEF1     32
109915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(RxDescriptors1, "Number of receive descriptors1");
1105449c685a4b39534f18869a93896370224463715Forest Bond
1115449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_MIN0     16
1125449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_MAX0     128
1135449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_DEF0     32
114915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(TxDescriptors0, "Number of transmit descriptors0");
1155449c685a4b39534f18869a93896370224463715Forest Bond
1165449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_MIN1     16
1175449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_MAX1     128
1185449c685a4b39534f18869a93896370224463715Forest Bond#define TX_DESC_DEF1     64
119915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(TxDescriptors1, "Number of transmit descriptors1");
1205449c685a4b39534f18869a93896370224463715Forest Bond
1215449c685a4b39534f18869a93896370224463715Forest Bond#define IP_ALIG_DEF     0
1220f4c60d61e9c10a0733eacd650c101189bdf75cdCharles Clément/* IP_byte_align[] is used for IP header unsigned long byte aligned
1230f4c60d61e9c10a0733eacd650c101189bdf75cdCharles Clément   0: indicate the IP header won't be unsigned long byte aligned.(Default) .
1240f4c60d61e9c10a0733eacd650c101189bdf75cdCharles Clément   1: indicate the IP header will be unsigned long byte aligned.
125915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   In some environment, the IP header should be unsigned long byte aligned,
126915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   or the packet will be droped when we receive it. (eg: IPVS)
1275449c685a4b39534f18869a93896370224463715Forest Bond*/
128915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(IP_byte_align, "Enable IP header dword aligned");
1295449c685a4b39534f18869a93896370224463715Forest Bond
1305449c685a4b39534f18869a93896370224463715Forest Bond#define INT_WORKS_DEF   20
1315449c685a4b39534f18869a93896370224463715Forest Bond#define INT_WORKS_MIN   10
1325449c685a4b39534f18869a93896370224463715Forest Bond#define INT_WORKS_MAX   64
1335449c685a4b39534f18869a93896370224463715Forest Bond
134915006cddc7979263a0fe1c6cb1369962bfe68f5Joe PerchesDEVICE_PARAM(int_works, "Number of packets per interrupt services");
1355449c685a4b39534f18869a93896370224463715Forest Bond
1365449c685a4b39534f18869a93896370224463715Forest Bond#define CHANNEL_MIN     1
1375449c685a4b39534f18869a93896370224463715Forest Bond#define CHANNEL_MAX     14
1385449c685a4b39534f18869a93896370224463715Forest Bond#define CHANNEL_DEF     6
1395449c685a4b39534f18869a93896370224463715Forest Bond
1405449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(Channel, "Channel number");
1415449c685a4b39534f18869a93896370224463715Forest Bond
1425449c685a4b39534f18869a93896370224463715Forest Bond/* PreambleType[] is the preamble length used for transmit.
1435449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate allows long preamble type
1445449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate allows short preamble type
1455449c685a4b39534f18869a93896370224463715Forest Bond*/
1465449c685a4b39534f18869a93896370224463715Forest Bond
1475449c685a4b39534f18869a93896370224463715Forest Bond#define PREAMBLE_TYPE_DEF     1
1485449c685a4b39534f18869a93896370224463715Forest Bond
1495449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(PreambleType, "Preamble Type");
1505449c685a4b39534f18869a93896370224463715Forest Bond
1515449c685a4b39534f18869a93896370224463715Forest Bond#define RTS_THRESH_MIN     512
1525449c685a4b39534f18869a93896370224463715Forest Bond#define RTS_THRESH_MAX     2347
1535449c685a4b39534f18869a93896370224463715Forest Bond#define RTS_THRESH_DEF     2347
1545449c685a4b39534f18869a93896370224463715Forest Bond
1555449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(RTSThreshold, "RTS threshold");
1565449c685a4b39534f18869a93896370224463715Forest Bond
1575449c685a4b39534f18869a93896370224463715Forest Bond#define FRAG_THRESH_MIN     256
1585449c685a4b39534f18869a93896370224463715Forest Bond#define FRAG_THRESH_MAX     2346
1595449c685a4b39534f18869a93896370224463715Forest Bond#define FRAG_THRESH_DEF     2346
1605449c685a4b39534f18869a93896370224463715Forest Bond
1615449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(FragThreshold, "Fragmentation threshold");
1625449c685a4b39534f18869a93896370224463715Forest Bond
1635449c685a4b39534f18869a93896370224463715Forest Bond#define DATA_RATE_MIN     0
1645449c685a4b39534f18869a93896370224463715Forest Bond#define DATA_RATE_MAX     13
1655449c685a4b39534f18869a93896370224463715Forest Bond#define DATA_RATE_DEF     13
1665449c685a4b39534f18869a93896370224463715Forest Bond/* datarate[] index
1675449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate 1 Mbps   0x02
1685449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate 2 Mbps   0x04
1695449c685a4b39534f18869a93896370224463715Forest Bond   2: indicate 5.5 Mbps 0x0B
1705449c685a4b39534f18869a93896370224463715Forest Bond   3: indicate 11 Mbps  0x16
1715449c685a4b39534f18869a93896370224463715Forest Bond   4: indicate 6 Mbps   0x0c
1725449c685a4b39534f18869a93896370224463715Forest Bond   5: indicate 9 Mbps   0x12
1735449c685a4b39534f18869a93896370224463715Forest Bond   6: indicate 12 Mbps  0x18
1745449c685a4b39534f18869a93896370224463715Forest Bond   7: indicate 18 Mbps  0x24
1755449c685a4b39534f18869a93896370224463715Forest Bond   8: indicate 24 Mbps  0x30
1765449c685a4b39534f18869a93896370224463715Forest Bond   9: indicate 36 Mbps  0x48
177915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   10: indicate 48 Mbps  0x60
178915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   11: indicate 54 Mbps  0x6c
179915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   12: indicate 72 Mbps  0x90
180915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches   13: indicate auto rate
1815449c685a4b39534f18869a93896370224463715Forest Bond*/
1825449c685a4b39534f18869a93896370224463715Forest Bond
1835449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(ConnectionRate, "Connection data rate");
1845449c685a4b39534f18869a93896370224463715Forest Bond
1855449c685a4b39534f18869a93896370224463715Forest Bond#define OP_MODE_DEF     0
1865449c685a4b39534f18869a93896370224463715Forest Bond
1875449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
1885449c685a4b39534f18869a93896370224463715Forest Bond
1895449c685a4b39534f18869a93896370224463715Forest Bond/* OpMode[] is used for transmit.
1905449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate infrastruct mode used
1915449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate adhoc mode used
1925449c685a4b39534f18869a93896370224463715Forest Bond   2: indicate AP mode used
1935449c685a4b39534f18869a93896370224463715Forest Bond*/
1945449c685a4b39534f18869a93896370224463715Forest Bond
1955449c685a4b39534f18869a93896370224463715Forest Bond/* PSMode[]
1965449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate disable power saving mode
1975449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate enable power saving mode
1985449c685a4b39534f18869a93896370224463715Forest Bond*/
1995449c685a4b39534f18869a93896370224463715Forest Bond
2005449c685a4b39534f18869a93896370224463715Forest Bond#define PS_MODE_DEF     0
2015449c685a4b39534f18869a93896370224463715Forest Bond
2025449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(PSMode, "Power saving mode");
2035449c685a4b39534f18869a93896370224463715Forest Bond
2045449c685a4b39534f18869a93896370224463715Forest Bond#define SHORT_RETRY_MIN     0
2055449c685a4b39534f18869a93896370224463715Forest Bond#define SHORT_RETRY_MAX     31
2065449c685a4b39534f18869a93896370224463715Forest Bond#define SHORT_RETRY_DEF     8
2075449c685a4b39534f18869a93896370224463715Forest Bond
2085449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
2095449c685a4b39534f18869a93896370224463715Forest Bond
2105449c685a4b39534f18869a93896370224463715Forest Bond#define LONG_RETRY_MIN     0
2115449c685a4b39534f18869a93896370224463715Forest Bond#define LONG_RETRY_MAX     15
2125449c685a4b39534f18869a93896370224463715Forest Bond#define LONG_RETRY_DEF     4
2135449c685a4b39534f18869a93896370224463715Forest Bond
2145449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(LongRetryLimit, "long frame retry limits");
2155449c685a4b39534f18869a93896370224463715Forest Bond
2165449c685a4b39534f18869a93896370224463715Forest Bond/* BasebandType[] baseband type selected
2175449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate 802.11a type
2185449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate 802.11b type
2195449c685a4b39534f18869a93896370224463715Forest Bond   2: indicate 802.11g type
2205449c685a4b39534f18869a93896370224463715Forest Bond*/
2215449c685a4b39534f18869a93896370224463715Forest Bond#define BBP_TYPE_MIN     0
2225449c685a4b39534f18869a93896370224463715Forest Bond#define BBP_TYPE_MAX     2
2235449c685a4b39534f18869a93896370224463715Forest Bond#define BBP_TYPE_DEF     2
2245449c685a4b39534f18869a93896370224463715Forest Bond
2255449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(BasebandType, "baseband type");
2265449c685a4b39534f18869a93896370224463715Forest Bond
2275449c685a4b39534f18869a93896370224463715Forest Bond/* 80211hEnable[]
2285449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate disable 802.11h
2295449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate enable 802.11h
2305449c685a4b39534f18869a93896370224463715Forest Bond*/
2315449c685a4b39534f18869a93896370224463715Forest Bond
2325449c685a4b39534f18869a93896370224463715Forest Bond#define X80211h_MODE_DEF     0
2335449c685a4b39534f18869a93896370224463715Forest Bond
2345449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(b80211hEnable, "802.11h mode");
2355449c685a4b39534f18869a93896370224463715Forest Bond
2365449c685a4b39534f18869a93896370224463715Forest Bond/* 80211hEnable[]
2375449c685a4b39534f18869a93896370224463715Forest Bond   0: indicate disable 802.11h
2385449c685a4b39534f18869a93896370224463715Forest Bond   1: indicate enable 802.11h
2395449c685a4b39534f18869a93896370224463715Forest Bond*/
2405449c685a4b39534f18869a93896370224463715Forest Bond
2415449c685a4b39534f18869a93896370224463715Forest Bond#define DIVERSITY_ANT_DEF     0
2425449c685a4b39534f18869a93896370224463715Forest Bond
2435449c685a4b39534f18869a93896370224463715Forest BondDEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
2445449c685a4b39534f18869a93896370224463715Forest Bond
2455449c685a4b39534f18869a93896370224463715Forest Bond//
2465449c685a4b39534f18869a93896370224463715Forest Bond// Static vars definitions
2475449c685a4b39534f18869a93896370224463715Forest Bond//
248915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perchesstatic CHIP_INFO chip_info_table[] = {
249915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{ VT3253,       "VIA Networking Solomon-A/B/G Wireless LAN Adapter ",
250915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	  256, 1,     DEVICE_FLAGS_IP_ALIGN|DEVICE_FLAGS_TX_ALIGN },
251915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{0, NULL}
2525449c685a4b39534f18869a93896370224463715Forest Bond};
2535449c685a4b39534f18869a93896370224463715Forest Bond
2549e4c5c2837a4bf059590ad75fa3fe0c2af93e65aGuillaume Clementstatic const struct pci_device_id vt6655_pci_id_table[] = {
255db6cb9036b2756c50efc43127c476786ea92eae2Jim Lieb	{ PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
256db6cb9036b2756c50efc43127c476786ea92eae2Jim Lieb	{ 0, }
2575449c685a4b39534f18869a93896370224463715Forest Bond};
2585449c685a4b39534f18869a93896370224463715Forest Bond
2595449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Static Functions  --------------------------*/
2605449c685a4b39534f18869a93896370224463715Forest Bond
261013a468c4504738856d67118492ce7b7fff53a48Charles Clémentstatic int  vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
2623f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void vt6655_init_info(struct pci_dev *pcid,
2633f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley			     struct vnt_private **ppDevice, PCHIP_INFO);
2643f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_info(struct vnt_private *pDevice);
2653f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid);
2663f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_print_info(struct vnt_private *pDevice);
2673f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_diversity_timer(struct vnt_private *pDevice);
2685449c685a4b39534f18869a93896370224463715Forest Bondstatic int  device_open(struct net_device *dev);
2695449c685a4b39534f18869a93896370224463715Forest Bondstatic int  device_xmit(struct sk_buff *skb, struct net_device *dev);
270915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perchesstatic  irqreturn_t  device_intr(int irq,  void *dev_instance);
2715449c685a4b39534f18869a93896370224463715Forest Bondstatic void device_set_multi(struct net_device *dev);
2725449c685a4b39534f18869a93896370224463715Forest Bondstatic int  device_close(struct net_device *dev);
2735449c685a4b39534f18869a93896370224463715Forest Bondstatic int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
2745449c685a4b39534f18869a93896370224463715Forest Bond
2755449c685a4b39534f18869a93896370224463715Forest Bond#ifdef CONFIG_PM
2765449c685a4b39534f18869a93896370224463715Forest Bondstatic int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
277f408adeb517e1b17102acd889251d5ab60c1fb88Alan Coxstatic int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
2785449c685a4b39534f18869a93896370224463715Forest Bondstatic int viawget_resume(struct pci_dev *pcid);
2799e4c5c2837a4bf059590ad75fa3fe0c2af93e65aGuillaume Clementstatic struct notifier_block device_notifier = {
28034381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.notifier_call = device_notify_reboot,
28134381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.next = NULL,
28234381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.priority = 0,
2835449c685a4b39534f18869a93896370224463715Forest Bond};
2845449c685a4b39534f18869a93896370224463715Forest Bond#endif
2855449c685a4b39534f18869a93896370224463715Forest Bond
2863f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_rd0_ring(struct vnt_private *pDevice);
2873f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_rd1_ring(struct vnt_private *pDevice);
2883f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_defrag_cb(struct vnt_private *pDevice);
2893f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_td0_ring(struct vnt_private *pDevice);
2903f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_td1_ring(struct vnt_private *pDevice);
2915449c685a4b39534f18869a93896370224463715Forest Bond
2925449c685a4b39534f18869a93896370224463715Forest Bondstatic int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
2935449c685a4b39534f18869a93896370224463715Forest Bond//2008-0714<Add>by Mike Liu
2943f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_release_WPADEV(struct vnt_private *pDevice);
2955449c685a4b39534f18869a93896370224463715Forest Bond
296ebc43d093b38262f1fc51018a50892ce3a144852James A Shacklefordstatic int  ethtool_ioctl(struct net_device *dev, void __user *useraddr);
2973f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic int  device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx);
2983f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic int  device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx);
2993f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pDesc);
3003f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_registers(struct vnt_private *pDevice);
3013f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc);
3023f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_td0_ring(struct vnt_private *pDevice);
3033f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_td1_ring(struct vnt_private *pDevice);
3043f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rd0_ring(struct vnt_private *pDevice);
3053f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rd1_ring(struct vnt_private *pDevice);
3063f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rings(struct vnt_private *pDevice);
3073f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_frag_buf(struct vnt_private *pDevice);
3085c9824e124f67c2590e1dbd33045603c36168609Charles Clémentstatic int Config_FileGetParameter(unsigned char *string,
309915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				   unsigned char *dest, unsigned char *source);
3105449c685a4b39534f18869a93896370224463715Forest Bond
3115449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Export Variables  --------------------------*/
3125449c685a4b39534f18869a93896370224463715Forest Bond
3135449c685a4b39534f18869a93896370224463715Forest Bond/*---------------------  Export Functions  --------------------------*/
3145449c685a4b39534f18869a93896370224463715Forest Bond
315915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perchesstatic char *get_chip_name(int chip_id)
3163ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga{
3173ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga	int i;
3186b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
3193ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga	for (i = 0; chip_info_table[i].name != NULL; i++)
3203ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga		if (chip_info_table[i].chip_id == chip_id)
3213ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga			break;
3223ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga	return chip_info_table[i].name;
3235449c685a4b39534f18869a93896370224463715Forest Bond}
3245449c685a4b39534f18869a93896370224463715Forest Bond
325f4e1b7c830f813884679dc63bed3a708d0f5653eBill Pembertonstatic void vt6655_remove(struct pci_dev *pcid)
3265449c685a4b39534f18869a93896370224463715Forest Bond{
3273f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = pci_get_drvdata(pcid);
3285449c685a4b39534f18869a93896370224463715Forest Bond
3293ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga	if (pDevice == NULL)
3303ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga		return;
3313ac9e0fd2a7fcd4eccbb79909b421b4284ed9520Devendra Naga	device_free_info(pDevice);
3325449c685a4b39534f18869a93896370224463715Forest Bond}
3335449c685a4b39534f18869a93896370224463715Forest Bond
33446fa0ec0fa4d396e94ac9a8d3e01e6da1f35efddMalcolm Priestleystatic void device_get_options(struct vnt_private *pDevice)
335bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga{
336bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	POPTIONS pOpts = &(pDevice->sOpts);
337bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga
338bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->nRxDescs0 = RX_DESC_DEF0;
339bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->nRxDescs1 = RX_DESC_DEF1;
340bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->nTxDescs[0] = TX_DESC_DEF0;
341bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->nTxDescs[1] = TX_DESC_DEF1;
342bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->flags |= DEVICE_FLAGS_IP_ALIGN;
343bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->int_works = INT_WORKS_DEF;
344bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->rts_thresh = RTS_THRESH_DEF;
345bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->frag_thresh = FRAG_THRESH_DEF;
346bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->data_rate = DATA_RATE_DEF;
347bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->channel_num = CHANNEL_DEF;
348bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga
349bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->flags |= DEVICE_FLAGS_PREAMBLE_TYPE;
350bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->flags |= DEVICE_FLAGS_OP_MODE;
351bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->short_retry = SHORT_RETRY_DEF;
352bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->long_retry = LONG_RETRY_DEF;
353bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->bbp_type = BBP_TYPE_DEF;
354bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->flags |= DEVICE_FLAGS_80211h_MODE;
355bf76ebd9cfd0018be820657da781201e2f74cf5dDevendra Naga	pOpts->flags |= DEVICE_FLAGS_DiversityANT;
3565449c685a4b39534f18869a93896370224463715Forest Bond}
3575449c685a4b39534f18869a93896370224463715Forest Bond
3585449c685a4b39534f18869a93896370224463715Forest Bondstatic void
3593f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleydevice_set_options(struct vnt_private *pDevice)
3603f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley{
361915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
362915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
363915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
364915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
365915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
366915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
367915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
368915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
369915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->uChannel = pDevice->sOpts.channel_num;
370915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh;
371915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->wFragmentationThreshold = pDevice->sOpts.frag_thresh;
372915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
373915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
374915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
375915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byShortPreamble = (pDevice->sOpts.flags & DEVICE_FLAGS_PREAMBLE_TYPE) ? 1 : 0;
376915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byOpMode = (pDevice->sOpts.flags & DEVICE_FLAGS_OP_MODE) ? 1 : 0;
377915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->ePSMode = (pDevice->sOpts.flags & DEVICE_FLAGS_PS_MODE) ? 1 : 0;
378915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
379915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
380915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->uConnectionRate = pDevice->sOpts.data_rate;
381a1613423cd1da7f5f6fc0e45da5411a0adcac3c5Guillaume Clement	if (pDevice->uConnectionRate < RATE_AUTO)
382a1613423cd1da7f5f6fc0e45da5411a0adcac3c5Guillaume Clement		pDevice->bFixRate = true;
383915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byBBType = pDevice->sOpts.bbp_type;
384a793b2d817dffce9f16af694fcce327bdefedbedGulsah Kose	pDevice->byPacketType = (VIA_PKT_TYPE)pDevice->byBBType;
3855449c685a4b39534f18869a93896370224463715Forest Bond	pDevice->byAutoFBCtrl = AUTO_FB_0;
386915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bUpdateBBVGA = true;
387915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byFOETuning = 0;
388915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byPreambleType = 0;
389915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
39048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" uChannel= %d\n", (int)pDevice->uChannel);
39148caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byOpMode= %d\n", (int)pDevice->byOpMode);
39248caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" ePSMode= %d\n", (int)pDevice->ePSMode);
39348caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold);
39448caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit);
39548caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit);
39648caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType);
39748caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
39848caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" uConnectionRate= %d\n", (int)pDevice->uConnectionRate);
39948caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" byBBType= %d\n", (int)pDevice->byBBType);
40048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable);
40148caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug(" pDevice->bDiversityRegCtlON= %d\n",
40248caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 (int)pDevice->bDiversityRegCtlON);
4035449c685a4b39534f18869a93896370224463715Forest Bond}
4045449c685a4b39534f18869a93896370224463715Forest Bond
4053f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void s_vCompleteCurrentMeasure(struct vnt_private *pDevice,
4063f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley				      unsigned char byResult)
4075449c685a4b39534f18869a93896370224463715Forest Bond{
408915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int ii;
409915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned long dwDuration = 0;
410915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byRPI0 = 0;
411915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
412915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (ii = 1; ii < 8; ii++) {
413915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->dwRPIs[ii] *= 255;
414915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dwDuration |= *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration));
415915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dwDuration <<= 10;
416915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->dwRPIs[ii] /= dwDuration;
417915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->abyRPIs[ii] = (unsigned char)pDevice->dwRPIs[ii];
418915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byRPI0 += pDevice->abyRPIs[ii];
419915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
420915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->abyRPIs[0] = (0xFF - byRPI0);
421915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
422915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->uNumOfMeasureEIDs == 0) {
423915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNTWIFIbMeasureReport(pDevice->pMgmt,
424915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      true,
425915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->pCurrMeasureEID,
426915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      byResult,
427915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->byBasicMap,
428915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->byCCAFraction,
429915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->abyRPIs
430915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
431915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	} else {
432915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNTWIFIbMeasureReport(pDevice->pMgmt,
433915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      false,
434915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->pCurrMeasureEID,
435915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      byResult,
436915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->byBasicMap,
437915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->byCCAFraction,
438915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				      pDevice->abyRPIs
439915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
440915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		CARDbStartMeasure(pDevice, pDevice->pCurrMeasureEID++, pDevice->uNumOfMeasureEIDs);
441915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
4425449c685a4b39534f18869a93896370224463715Forest Bond}
4435449c685a4b39534f18869a93896370224463715Forest Bond
4445449c685a4b39534f18869a93896370224463715Forest Bond//
445789d1aef176e720fce4a8a5a9ab07f093ddb9086Justin P. Mattock// Initialisation of MAC & BBP registers
4465449c685a4b39534f18869a93896370224463715Forest Bond//
4475449c685a4b39534f18869a93896370224463715Forest Bond
4483f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_registers(struct vnt_private *pDevice)
4495449c685a4b39534f18869a93896370224463715Forest Bond{
450915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int ii;
451915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byValue;
452915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byValue1;
453915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byCCKPwrdBm = 0;
454915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byOFDMPwrdBm = 0;
455915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int zonetype = 0;
456915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
4576b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
458915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACbShutdown(pDevice->PortOffset);
459915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	BBvSoftwareReset(pDevice->PortOffset);
460915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4619f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Do MACbSoftwareReset in MACvInitialize */
4629f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	MACbSoftwareReset(pDevice->PortOffset);
463915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4649f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bAES = false;
465915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4669f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Only used in 11g type, sync with ERP IE */
4679f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bProtectMode = false;
468915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4699f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bNonERPPresent = false;
4709f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bBarkerPreambleMd = false;
4719f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->wCurrentRate = RATE_1M;
4729f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byTopOFDMBasicRate = RATE_24M;
4739f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byTopCCKBasicRate = RATE_1M;
474915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4759f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Target to IF pin while programming to RF chip. */
4769f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byRevId = 0;
477915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4789f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* init MAC */
4799f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	MACvInitialize(pDevice->PortOffset);
4809f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
4819f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Get Local ID */
4829f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &pDevice->byLocalID);
483915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4849f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	spin_lock_irq(&pDevice->lock);
485915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4869f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
487915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4889f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	spin_unlock_irq(&pDevice->lock);
489915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4909f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Get Channel range */
4919f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byMinChannel = 1;
4929f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byMaxChannel = CB_MAX_CHANNEL;
493915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
4949f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Get Antena */
4959f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
4969f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (byValue & EEP_ANTINV)
4979f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->bTxRxAntInv = true;
4989f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	else
4999f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->bTxRxAntInv = false;
5009f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5019f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
5029f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* if not set default is All */
5039f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (byValue == 0)
5049f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
5059f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5069f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->ulDiversityNValue = 100*260;
5079f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->ulDiversityMValue = 100*16;
5089f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byTMax = 1;
5099f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byTMax2 = 4;
5109f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->ulSQ3TH = 0;
5119f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byTMax3 = 64;
5129f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5139f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
5149f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byAntennaCount = 2;
5159f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byTxAntennaMode = ANT_B;
5169f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->dwTxAntennaSel = 1;
5179f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->dwRxAntennaSel = 1;
5189f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5199f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if (pDevice->bTxRxAntInv)
5209f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->byRxAntennaMode = ANT_A;
521915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		else
5229f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->byRxAntennaMode = ANT_B;
5235449c685a4b39534f18869a93896370224463715Forest Bond
5249f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		byValue1 = SROMbyReadEmbedded(pDevice->PortOffset,
5259f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					      EEP_OFS_ANTENNA);
526f2046f93db0918f99875853772142143590ba0c6Joe Perches
5279f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if ((byValue1 & 0x08) == 0)
5289f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->bDiversityEnable = false;
5299f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		else
5309f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->bDiversityEnable = true;
5319f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	} else  {
5329f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->bDiversityEnable = false;
5339f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byAntennaCount = 1;
5349f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->dwTxAntennaSel = 0;
5359f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->dwRxAntennaSel = 0;
536915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
5379f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if (byValue & EEP_ANTENNA_AUX) {
5389f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->byTxAntennaMode = ANT_A;
539915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
5409f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			if (pDevice->bTxRxAntInv)
5419f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley				pDevice->byRxAntennaMode = ANT_B;
5429f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			else
5439f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley				pDevice->byRxAntennaMode = ANT_A;
5449f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		} else {
545915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->byTxAntennaMode = ANT_B;
5469f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5471208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (pDevice->bTxRxAntInv)
548915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byRxAntennaMode = ANT_A;
549915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			else
550915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byRxAntennaMode = ANT_B;
551915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
5529f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
5535449c685a4b39534f18869a93896370224463715Forest Bond
55448caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
55548caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue,
55648caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 (int)pDevice->ulDiversityMValue, pDevice->byTMax,
55748caf5a060491edb2e1793539dad72e70c54c869Joe Perches		 pDevice->byTMax2);
5589f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5599f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* zonetype initial */
5609f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
5619f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	zonetype = Config_FileOperation(pDevice, false, NULL);
5629f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
5639f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (zonetype >= 0) {
5649f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if ((zonetype == 0) &&
5659f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		    (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) {
5669f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			/* for USA */
5679f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
5689f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
5699f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
57048caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("Init Zone Type :USA\n");
5719f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		} else if ((zonetype == 1) &&
5729f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			 (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) {
5739f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			/* for Japan */
5749f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
5759f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
5769f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		} else if ((zonetype == 2) &&
5779f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			  (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) {
5789f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			/* for Europe */
5799f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
5809f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
5819f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
58248caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("Init Zone Type :Europe\n");
5839f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		} else {
5849f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
5859f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley				pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",
5869f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					 zonetype,
5879f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					 pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
5889f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			else
5899f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley				pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n",
5909f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					 zonetype);
5919f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		}
5929f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	} else {
5939f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n",
5949f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			 SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
5959f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
596915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
5979f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Get RFType */
5989f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
599915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6009f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* force change RevID for VT3253 emu */
6019f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if ((pDevice->byRFType & RF_EMU) != 0)
602915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->byRevId = 0x80;
603915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6049f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byRFType &= RF_MASK;
60548caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType);
606915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6079f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (!pDevice->bZoneRegExist)
6089f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
609bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
61048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("pDevice->byZoneType = %x\n", pDevice->byZoneType);
611915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6129f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Init RF module */
6139f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	RFbInit(pDevice);
614915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6159f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Get Desire Power Value */
6169f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byCurPwr = 0xFF;
6179f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
6189f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
619f2046f93db0918f99875853772142143590ba0c6Joe Perches
6209f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Load power Table */
6219f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
6229f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyCCKPwrTbl[ii + 1] =
6239f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			SROMbyReadEmbedded(pDevice->PortOffset,
6249f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					   (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
6259f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if (pDevice->abyCCKPwrTbl[ii + 1] == 0)
6269f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
6275449c685a4b39534f18869a93896370224463715Forest Bond
6289f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyOFDMPwrTbl[ii + 1] =
6299f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			SROMbyReadEmbedded(pDevice->PortOffset,
6309f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					   (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
6319f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if (pDevice->abyOFDMPwrTbl[ii + 1] == 0)
6329f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
633bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
6349f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
6359f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
6369f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
637bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
6389f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* recover 12,13 ,14channel for EUROPE by 11 channel */
6399f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
6409f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
6419f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	    (pDevice->byOriginalZonetype == ZoneType_USA)) {
6429f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		for (ii = 11; ii < 14; ii++) {
6439f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
6449f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
6455449c685a4b39534f18869a93896370224463715Forest Bond
646915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
6479f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
6485449c685a4b39534f18869a93896370224463715Forest Bond
6499f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Load OFDM A Power Table */
6509f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
6519f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] =
6529f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			SROMbyReadEmbedded(pDevice->PortOffset,
6539f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					   (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
6545449c685a4b39534f18869a93896370224463715Forest Bond
6559f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] =
6569f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			SROMbyReadEmbedded(pDevice->PortOffset,
6579f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley					   (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
6589f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
6595449c685a4b39534f18869a93896370224463715Forest Bond
6609f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	init_channel_table((void *)pDevice);
6615449c685a4b39534f18869a93896370224463715Forest Bond
6629f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (pDevice->byLocalID > REV_ID_VT3253_B1) {
6639f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		MACvSelectPage1(pDevice->PortOffset);
6645449c685a4b39534f18869a93896370224463715Forest Bond
6659f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1,
6669f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			     (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
6675449c685a4b39534f18869a93896370224463715Forest Bond
6689f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		MACvSelectPage0(pDevice->PortOffset);
6699f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
6705449c685a4b39534f18869a93896370224463715Forest Bond
6719f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* use relative tx timeout and 802.11i D4 */
6729f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	MACvWordRegBitsOn(pDevice->PortOffset,
6739f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley			  MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
6745449c685a4b39534f18869a93896370224463715Forest Bond
6759f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* set performance parameter by registry */
6769f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
6779f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
6785449c685a4b39534f18869a93896370224463715Forest Bond
6799f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* reset TSF counter */
6809f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
6819f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* enable TSF counter */
6829f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
6835449c685a4b39534f18869a93896370224463715Forest Bond
6849f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* initialize BBP registers */
6859f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	BBbVT3253Init(pDevice);
6865449c685a4b39534f18869a93896370224463715Forest Bond
6879f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (pDevice->bUpdateBBVGA) {
6889f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
6899f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->byBBVGANew = pDevice->byBBVGACurrent;
6909f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
6919f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	}
6925449c685a4b39534f18869a93896370224463715Forest Bond
6939f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
6949f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
6955449c685a4b39534f18869a93896370224463715Forest Bond
6969f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byCurrentCh = 0;
697915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
6989f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Set BB and packet type at the same time. */
6999f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* Set Short Slot Time, xIFS, and RSPINF. */
7009f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (pDevice->uConnectionRate == RATE_AUTO)
7019f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->wCurrentRate = RATE_54M;
7029f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	else
7039f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
704bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
7059f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	/* default G Mode */
7069f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
7079f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
7085449c685a4b39534f18869a93896370224463715Forest Bond
7099f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bRadioOff = false;
7105449c685a4b39534f18869a93896370224463715Forest Bond
7119f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset,
7129f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley						 EEP_OFS_RADIOCTL);
7139f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	pDevice->bHWRadioOff = false;
7145449c685a4b39534f18869a93896370224463715Forest Bond
7159f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
7169f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		/* Get GPIO */
7179f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
7189f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
7199f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		if (((pDevice->byGPIO & GPIO0_DATA) &&
7209f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		     !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
7219f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		     (!(pDevice->byGPIO & GPIO0_DATA) &&
7229f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		     (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
723915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->bHWRadioOff = true;
724915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
7259f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
726bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (pDevice->bHWRadioOff || pDevice->bRadioControlOff)
727915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		CARDbRadioPowerOff(pDevice);
7285449c685a4b39534f18869a93896370224463715Forest Bond
7293500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	pMgmt->eScanType = WMAC_SCAN_PASSIVE;
730915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
7313500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	/* get Permanent network address */
7323500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
73348caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("Network address = %pM\n", pDevice->abyCurrentNetAddr);
734915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
7353500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	/* reset Tx pointer */
7363500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	CARDvSafeResetRx(pDevice);
7373500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	/* reset Rx pointer */
7383500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	CARDvSafeResetTx(pDevice);
7395449c685a4b39534f18869a93896370224463715Forest Bond
7403500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	if (pDevice->byLocalID <= REV_ID_VT3253_A1)
7413500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
7425449c685a4b39534f18869a93896370224463715Forest Bond
7433500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
7445449c685a4b39534f18869a93896370224463715Forest Bond
7453500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	/* Turn On Rx DMA */
7463500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	MACvReceive0(pDevice->PortOffset);
7473500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	MACvReceive1(pDevice->PortOffset);
7485449c685a4b39534f18869a93896370224463715Forest Bond
7493500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	/* start the adapter */
7503500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	MACvStart(pDevice->PortOffset);
7513500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley
7523500a1da81c25f03e4eed159a38e96d280eba6e9Malcolm Priestley	netif_stop_queue(pDevice->dev);
7535449c685a4b39534f18869a93896370224463715Forest Bond}
7545449c685a4b39534f18869a93896370224463715Forest Bond
7553f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_diversity_timer(struct vnt_private *pDevice)
75684b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
757915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	init_timer(&pDevice->TimerSQ3Tmax1);
758915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
759915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
760915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
7615449c685a4b39534f18869a93896370224463715Forest Bond
762915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	init_timer(&pDevice->TimerSQ3Tmax2);
763915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
764915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
765915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
7665449c685a4b39534f18869a93896370224463715Forest Bond
767915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	init_timer(&pDevice->TimerSQ3Tmax3);
768915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
769915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
770915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
7715449c685a4b39534f18869a93896370224463715Forest Bond}
7725449c685a4b39534f18869a93896370224463715Forest Bond
7733f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_release_WPADEV(struct vnt_private *pDevice)
7745449c685a4b39534f18869a93896370224463715Forest Bond{
775915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	viawget_wpa_header *wpahdr;
776915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int ii = 0;
7774e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
778915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	//send device close to wpa_supplicnat layer
7791208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bWPADEVUp) {
780915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wpahdr = (viawget_wpa_header *)pDevice->skb->data;
781915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
782915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wpahdr->resp_ie_len = 0;
783915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wpahdr->req_ie_len = 0;
784915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		skb_put(pDevice->skb, sizeof(viawget_wpa_header));
785915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->skb->dev = pDevice->wpadev;
786915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		skb_reset_mac_header(pDevice->skb);
787915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->skb->pkt_type = PACKET_HOST;
788915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->skb->protocol = htons(ETH_P_802_2);
789915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
790915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		netif_rx(pDevice->skb);
791915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
792915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
7931208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		while (pDevice->bWPADEVUp) {
794915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			set_current_state(TASK_UNINTERRUPTIBLE);
795915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			schedule_timeout(HZ / 20);          //wait 50ms
796915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			ii++;
797915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (ii > 20)
798915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				break;
799915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
800915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
801915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
8025449c685a4b39534f18869a93896370224463715Forest Bond}
8035449c685a4b39534f18869a93896370224463715Forest Bond
804572113540886faf393fd04408c394899df98ada3Forest Bondstatic const struct net_device_ops device_netdev_ops = {
805502eb5369f51539aaee6ec173165be28d916a3caDevendra Naga	.ndo_open               = device_open,
806502eb5369f51539aaee6ec173165be28d916a3caDevendra Naga	.ndo_stop               = device_close,
807502eb5369f51539aaee6ec173165be28d916a3caDevendra Naga	.ndo_do_ioctl           = device_ioctl,
808502eb5369f51539aaee6ec173165be28d916a3caDevendra Naga	.ndo_start_xmit         = device_xmit,
809502eb5369f51539aaee6ec173165be28d916a3caDevendra Naga	.ndo_set_rx_mode	= device_set_multi,
810572113540886faf393fd04408c394899df98ada3Forest Bond};
811572113540886faf393fd04408c394899df98ada3Forest Bond
812a1179b20ed939792635aacefcbc676d089a9ae2dBill Pembertonstatic int
813013a468c4504738856d67118492ce7b7fff53a48Charles Clémentvt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
8145449c685a4b39534f18869a93896370224463715Forest Bond{
815915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	static bool bFirst = true;
816915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct net_device *dev = NULL;
817915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PCHIP_INFO  pChip_info = (PCHIP_INFO)ent->driver_data;
8183f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice;
819915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int         rc;
820941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement
8211bd6375760ef13baeee404276b95034c691f2ed8Malcolm Priestley	dev = alloc_etherdev(sizeof(*pDevice));
822915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
8233f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	pDevice = netdev_priv(dev);
824915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
825915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (dev == NULL) {
826941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME ": allocate net device failed\n");
827915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENOMEM;
828915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
829915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
830915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Chain it all together
831915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	SET_NETDEV_DEV(dev, &pcid->dev);
832915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
833915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (bFirst) {
834941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
835941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
836915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bFirst = false;
837915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
838915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
839915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vt6655_init_info(pcid, &pDevice, pChip_info);
840915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->dev = dev;
841915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
842915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pci_enable_device(pcid)) {
843915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
844915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
845915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
846915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dev->irq = pcid->irq;
84713b631a599cddabc1cbb3a2fb862aee5ceb6e427Kulikov Vasiliy
8485449c685a4b39534f18869a93896370224463715Forest Bond#ifdef	DEBUG
849941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement	pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr);
8505449c685a4b39534f18869a93896370224463715Forest Bond#endif
8511208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (!device_get_pci_info(pDevice, pcid)) {
852941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME ": Failed to find PCI device.\n");
853915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
854915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
855915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
8565449c685a4b39534f18869a93896370224463715Forest Bond
8575449c685a4b39534f18869a93896370224463715Forest Bond#if 1
8585449c685a4b39534f18869a93896370224463715Forest Bond
8595449c685a4b39534f18869a93896370224463715Forest Bond#ifdef	DEBUG
8605449c685a4b39534f18869a93896370224463715Forest Bond
861941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement	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);
8625449c685a4b39534f18869a93896370224463715Forest Bond	{
8635449c685a4b39534f18869a93896370224463715Forest Bond		int i;
864915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		u32 bar, len;
8655449c685a4b39534f18869a93896370224463715Forest Bond		u32 address[] = {
866915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_0,
867915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_1,
868915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_2,
869915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_3,
870915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_4,
871915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			PCI_BASE_ADDRESS_5,
872915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			0};
8735e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		for (i = 0; address[i]; i++) {
8745449c685a4b39534f18869a93896370224463715Forest Bond			pci_read_config_dword(pcid, address[i], &bar);
875941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement			pr_debug("bar %d is %x\n", i, bar);
8765e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			if (!bar) {
877941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement				pr_debug("bar %d not implemented\n", i);
8785449c685a4b39534f18869a93896370224463715Forest Bond				continue;
8795449c685a4b39534f18869a93896370224463715Forest Bond			}
8805449c685a4b39534f18869a93896370224463715Forest Bond			if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
881915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				/* This is IO */
8825449c685a4b39534f18869a93896370224463715Forest Bond
883915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
884915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				len = len & ~(len - 1);
8855449c685a4b39534f18869a93896370224463715Forest Bond
886941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement				pr_debug("IO space:  len in IO %x, BAR %d\n", len, i);
8875e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
8885449c685a4b39534f18869a93896370224463715Forest Bond				len = bar & 0xFFFFFFF0;
8895449c685a4b39534f18869a93896370224463715Forest Bond				len = ~len + 1;
8905449c685a4b39534f18869a93896370224463715Forest Bond
891941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement				pr_debug("len in MEM %x, BAR %d\n", len, i);
8925449c685a4b39534f18869a93896370224463715Forest Bond			}
8935449c685a4b39534f18869a93896370224463715Forest Bond		}
8945449c685a4b39534f18869a93896370224463715Forest Bond	}
8955449c685a4b39534f18869a93896370224463715Forest Bond#endif
8965449c685a4b39534f18869a93896370224463715Forest Bond
8975449c685a4b39534f18869a93896370224463715Forest Bond#endif
8985449c685a4b39534f18869a93896370224463715Forest Bond
8991683440595ea33cc019fb8524b04319cf82bc6acGuillaume Clement	pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
9005449c685a4b39534f18869a93896370224463715Forest Bond
9011683440595ea33cc019fb8524b04319cf82bc6acGuillaume Clement	if (pDevice->PortOffset == NULL) {
902941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME ": Failed to IO remapping ..\n");
903915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
904915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
905915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
9065449c685a4b39534f18869a93896370224463715Forest Bond
907915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	rc = pci_request_regions(pcid, DEVICE_NAME);
908915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (rc) {
909941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME ": Failed to find PCI device\n");
910915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
911915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
912915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
9135449c685a4b39534f18869a93896370224463715Forest Bond
914915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dev->base_addr = pDevice->ioaddr;
915915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// do reset
916915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (!MACbSoftwareReset(pDevice->PortOffset)) {
917941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n");
918915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
919915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
920915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
921915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// initial to reload eeprom
922915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvInitialize(pDevice->PortOffset);
923915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvReadEtherAddress(pDevice->PortOffset, dev->dev_addr);
924915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
92546fa0ec0fa4d396e94ac9a8d3e01e6da1f35efddMalcolm Priestley	device_get_options(pDevice);
926915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_set_options(pDevice);
927915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	//Mask out the options cannot be set to the chip
928915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->sOpts.flags &= pChip_info->flags;
929915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
930915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	//Enable the chip specified capabilities
931915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL);
932915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->tx_80211 = device_dma0_tx_80211;
933915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->sMgmtObj.pAdapter = (void *)pDevice;
934915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pMgmt = &(pDevice->sMgmtObj);
935915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
936915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dev->irq                = pcid->irq;
937915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dev->netdev_ops         = &device_netdev_ops;
9385449c685a4b39534f18869a93896370224463715Forest Bond
9395449c685a4b39534f18869a93896370224463715Forest Bond	dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
9405449c685a4b39534f18869a93896370224463715Forest Bond
941915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	rc = register_netdev(dev);
9425e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	if (rc) {
943941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err(DEVICE_NAME " Failed to register netdev\n");
944915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_free_info(pDevice);
945915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENODEV;
946915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
947915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_print_info(pDevice);
948915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_set_drvdata(pcid, pDevice);
949915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
9505449c685a4b39534f18869a93896370224463715Forest Bond}
9515449c685a4b39534f18869a93896370224463715Forest Bond
9523f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_print_info(struct vnt_private *pDevice)
9535449c685a4b39534f18869a93896370224463715Forest Bond{
954915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct net_device *dev = pDevice->dev;
9555449c685a4b39534f18869a93896370224463715Forest Bond
95648caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_info("%s: %s\n", dev->name, get_chip_name(pDevice->chip_id));
95748caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_info("%s: MAC=%pM IO=0x%lx Mem=0x%lx IRQ=%d\n",
95848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		dev->name, dev->dev_addr, (unsigned long)pDevice->ioaddr,
95948caf5a060491edb2e1793539dad72e70c54c869Joe Perches		(unsigned long)pDevice->PortOffset, pDevice->dev->irq);
9605449c685a4b39534f18869a93896370224463715Forest Bond}
9615449c685a4b39534f18869a93896370224463715Forest Bond
9623f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void vt6655_init_info(struct pci_dev *pcid,
9633f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley			     struct vnt_private **ppDevice,
9643f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley			     PCHIP_INFO pChip_info)
9653f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley{
9661bd6375760ef13baeee404276b95034c691f2ed8Malcolm Priestley	memset(*ppDevice, 0, sizeof(**ppDevice));
9675449c685a4b39534f18869a93896370224463715Forest Bond
968915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	(*ppDevice)->pcid = pcid;
969915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	(*ppDevice)->chip_id = pChip_info->chip_id;
970915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	(*ppDevice)->io_size = pChip_info->io_size;
971915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	(*ppDevice)->nTxQueues = pChip_info->nTxQueue;
972915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	(*ppDevice)->multicast_limit = 32;
9735449c685a4b39534f18869a93896370224463715Forest Bond
974915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_lock_init(&((*ppDevice)->lock));
9755449c685a4b39534f18869a93896370224463715Forest Bond}
9765449c685a4b39534f18869a93896370224463715Forest Bond
9773f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_get_pci_info(struct vnt_private *pDevice,
9783f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley				struct pci_dev *pcid)
97984b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
980915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	u16 pci_cmd;
981915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	u8  b;
982915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cis_addr;
9835449c685a4b39534f18869a93896370224463715Forest Bond
984915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_read_config_byte(pcid, PCI_REVISION_ID, &pDevice->byRevId);
985915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_read_config_word(pcid, PCI_SUBSYSTEM_ID, &pDevice->SubSystemID);
986915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_read_config_word(pcid, PCI_SUBSYSTEM_VENDOR_ID, &pDevice->SubVendorID);
987915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_read_config_word(pcid, PCI_COMMAND, (u16 *)&(pci_cmd));
9885449c685a4b39534f18869a93896370224463715Forest Bond
989915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_set_master(pcid);
9905449c685a4b39534f18869a93896370224463715Forest Bond
991915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->memaddr = pci_resource_start(pcid, 0);
992915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->ioaddr = pci_resource_start(pcid, 1);
9935449c685a4b39534f18869a93896370224463715Forest Bond
994915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	cis_addr = pci_resource_start(pcid, 2);
9955449c685a4b39534f18869a93896370224463715Forest Bond
996915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pcid = pcid;
9975449c685a4b39534f18869a93896370224463715Forest Bond
998915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_read_config_byte(pcid, PCI_COMMAND, &b);
999915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER));
10005449c685a4b39534f18869a93896370224463715Forest Bond
1001915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
10025449c685a4b39534f18869a93896370224463715Forest Bond}
10035449c685a4b39534f18869a93896370224463715Forest Bond
10043f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_info(struct vnt_private *pDevice)
100584b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1006915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct net_device *dev = pDevice->dev;
10075449c685a4b39534f18869a93896370224463715Forest Bond
1008915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	ASSERT(pDevice);
10095449c685a4b39534f18869a93896370224463715Forest Bond//2008-0714-01<Add>by chester
1010915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_release_WPADEV(pDevice);
10115449c685a4b39534f18869a93896370224463715Forest Bond
10125449c685a4b39534f18869a93896370224463715Forest Bond//2008-07-21-01<Add>by MikeLiu
10135449c685a4b39534f18869a93896370224463715Forest Bond//unregister wpadev
1014915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (wpa_set_wpadev(pDevice, 0) != 0)
1015941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("unregister wpadev fail?\n");
1016915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
10175449c685a4b39534f18869a93896370224463715Forest Bond#ifdef HOSTAP
1018915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (dev)
1019915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		vt6655_hostap_set_hostapd(pDevice, 0, 0);
10205449c685a4b39534f18869a93896370224463715Forest Bond#endif
1021915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (dev)
1022915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		unregister_netdev(dev);
10235449c685a4b39534f18869a93896370224463715Forest Bond
1024915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->PortOffset)
10251683440595ea33cc019fb8524b04319cf82bc6acGuillaume Clement		iounmap(pDevice->PortOffset);
10265449c685a4b39534f18869a93896370224463715Forest Bond
1027915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->pcid)
1028915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_release_regions(pDevice->pcid);
1029915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (dev)
1030915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		free_netdev(dev);
10315449c685a4b39534f18869a93896370224463715Forest Bond}
10325449c685a4b39534f18869a93896370224463715Forest Bond
10333f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_init_rings(struct vnt_private *pDevice)
103484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1035915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	void *vir_pool;
10365449c685a4b39534f18869a93896370224463715Forest Bond
1037915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	/*allocate all RD/TD rings a single pool*/
10388b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches	vir_pool = pci_zalloc_consistent(pDevice->pcid,
10398b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches					 pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
10408b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches					 pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
10418b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches					 pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
10428b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches					 pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
10438b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches					 &pDevice->pool_dma);
1044915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (vir_pool == NULL) {
104542f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		dev_err(&pDevice->pcid->dev, "allocate desc dma memory failed\n");
1046915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1047915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
10485449c685a4b39534f18869a93896370224463715Forest Bond
1049915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->aRD0Ring = vir_pool;
1050915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->aRD1Ring = vir_pool +
1051915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
1052915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1053915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->rd0_pool_dma = pDevice->pool_dma;
1054915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->rd1_pool_dma = pDevice->rd0_pool_dma +
1055915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc);
1056915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
10578b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches	pDevice->tx0_bufs = pci_zalloc_consistent(pDevice->pcid,
10588b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches						  pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
10598b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches						  pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
10608b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches						  CB_BEACON_BUF_SIZE +
10618b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches						  CB_MAX_BUF_SIZE,
10628b983be54bb5c4ff133e3aa45fe50669089d0a68Joe Perches						  &pDevice->tx_bufs_dma0);
1063915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->tx0_bufs == NULL) {
106442f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		dev_err(&pDevice->pcid->dev, "allocate buf dma memory failed\n");
106542f709eff132e82f5375b4daae208953035768b2Malcolm Priestley
1066915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_free_consistent(pDevice->pcid,
1067915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1068915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1069915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1070915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc),
1071915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    vir_pool, pDevice->pool_dma
1072915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
1073915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1074915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
10755449c685a4b39534f18869a93896370224463715Forest Bond
1076915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->td0_pool_dma = pDevice->rd1_pool_dma +
1077915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
10785449c685a4b39534f18869a93896370224463715Forest Bond
1079915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->td1_pool_dma = pDevice->td0_pool_dma +
1080915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
10815449c685a4b39534f18869a93896370224463715Forest Bond
1082915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// vir_pool: pvoid type
1083915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apTD0Rings = vir_pool
1084915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		+ pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1085915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		+ pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc);
10865449c685a4b39534f18869a93896370224463715Forest Bond
1087915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apTD1Rings = vir_pool
1088915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		+ pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc)
1089915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		+ pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc)
1090915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		+ pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc);
10915449c685a4b39534f18869a93896370224463715Forest Bond
1092915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->tx1_bufs = pDevice->tx0_bufs +
1093915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
10945449c685a4b39534f18869a93896370224463715Forest Bond
1095915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->tx_beacon_bufs = pDevice->tx1_bufs +
1096915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
10975449c685a4b39534f18869a93896370224463715Forest Bond
1098915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pbyTmpBuff = pDevice->tx_beacon_bufs +
1099915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		CB_BEACON_BUF_SIZE;
11005449c685a4b39534f18869a93896370224463715Forest Bond
1101915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->tx_bufs_dma1 = pDevice->tx_bufs_dma0 +
1102915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ;
11035449c685a4b39534f18869a93896370224463715Forest Bond
1104915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->tx_beacon_dma = pDevice->tx_bufs_dma1 +
1105915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ;
11065449c685a4b39534f18869a93896370224463715Forest Bond
1107915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
11085449c685a4b39534f18869a93896370224463715Forest Bond}
11095449c685a4b39534f18869a93896370224463715Forest Bond
11103f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rings(struct vnt_private *pDevice)
111184b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1112915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_free_consistent(pDevice->pcid,
1113915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
1114915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
1115915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    pDevice->sOpts.nTxDescs[0] * sizeof(STxDesc) +
1116915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc)
1117915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    ,
1118915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    pDevice->aRD0Ring, pDevice->pool_dma
1119915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		);
1120915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1121915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->tx0_bufs)
1122915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_free_consistent(pDevice->pcid,
1123915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nTxDescs[0] * PKT_BUF_SZ +
1124915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->sOpts.nTxDescs[1] * PKT_BUF_SZ +
1125915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    CB_BEACON_BUF_SIZE +
1126915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    CB_MAX_BUF_SIZE,
1127915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    pDevice->tx0_bufs, pDevice->tx_bufs_dma0
1128915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
11295449c685a4b39534f18869a93896370224463715Forest Bond}
11305449c685a4b39534f18869a93896370224463715Forest Bond
11313f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_rd0_ring(struct vnt_private *pDevice)
113284b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1133915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1134915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dma_addr_t      curr = pDevice->rd0_pool_dma;
1135915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSRxDesc        pDesc;
1136915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1137915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	/* Init the RD0 ring entries */
1138915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nRxDescs0; i ++, curr += sizeof(SRxDesc)) {
1139915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc = &(pDevice->aRD0Ring[i]);
1140915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pRDInfo = alloc_rd_info();
1141915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		ASSERT(pDesc->pRDInfo);
114242f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		if (!device_alloc_rx_buf(pDevice, pDesc))
114342f709eff132e82f5375b4daae208953035768b2Malcolm Priestley			dev_err(&pDevice->pcid->dev, "can not alloc rx bufs\n");
114442f709eff132e82f5375b4daae208953035768b2Malcolm Priestley
1145915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
1146915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1147915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1148915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1149915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1150915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (i > 0)
1151915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
1152915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
11535449c685a4b39534f18869a93896370224463715Forest Bond}
11545449c685a4b39534f18869a93896370224463715Forest Bond
11553f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_rd1_ring(struct vnt_private *pDevice)
115684b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1157915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1158915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dma_addr_t      curr = pDevice->rd1_pool_dma;
1159915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSRxDesc        pDesc;
1160915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1161915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	/* Init the RD1 ring entries */
1162915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nRxDescs1; i ++, curr += sizeof(SRxDesc)) {
1163915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc = &(pDevice->aRD1Ring[i]);
1164915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pRDInfo = alloc_rd_info();
1165915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		ASSERT(pDesc->pRDInfo);
116642f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		if (!device_alloc_rx_buf(pDevice, pDesc))
116742f709eff132e82f5375b4daae208953035768b2Malcolm Priestley			dev_err(&pDevice->pcid->dev, "can not alloc rx bufs\n");
116842f709eff132e82f5375b4daae208953035768b2Malcolm Priestley
1169915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
1170915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pRDInfo->curr_desc = cpu_to_le32(curr);
1171915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
1172915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1173915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1174915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (i > 0)
1175915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
1176915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
11775449c685a4b39534f18869a93896370224463715Forest Bond}
11785449c685a4b39534f18869a93896370224463715Forest Bond
11793f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_defrag_cb(struct vnt_private *pDevice)
118084b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1181915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1182915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSDeFragControlBlock pDeF;
1183915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1184915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	/* Init the fragment ctl entries */
1185915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1186915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDeF = &(pDevice->sRxDFCB[i]);
118742f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		if (!device_alloc_frag_buf(pDevice, pDeF))
118842f709eff132e82f5375b4daae208953035768b2Malcolm Priestley			dev_err(&pDevice->pcid->dev, "can not alloc frag bufs\n");
1189915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1190915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->cbDFCB = CB_MAX_RX_FRAG;
1191915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->cbFreeDFCB = pDevice->cbDFCB;
11925449c685a4b39534f18869a93896370224463715Forest Bond}
11935449c685a4b39534f18869a93896370224463715Forest Bond
11943f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rd0_ring(struct vnt_private *pDevice)
119584b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1196915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
11975449c685a4b39534f18869a93896370224463715Forest Bond
1198915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
1199915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PSRxDesc        pDesc = &(pDevice->aRD0Ring[i]);
1200915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PDEVICE_RD_INFO  pRDInfo = pDesc->pRDInfo;
12015449c685a4b39534f18869a93896370224463715Forest Bond
1202915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1203915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
12045449c685a4b39534f18869a93896370224463715Forest Bond
1205915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb(pRDInfo->skb);
12065449c685a4b39534f18869a93896370224463715Forest Bond
1207915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		kfree((void *)pDesc->pRDInfo);
1208915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
12095449c685a4b39534f18869a93896370224463715Forest Bond}
12105449c685a4b39534f18869a93896370224463715Forest Bond
12113f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_rd1_ring(struct vnt_private *pDevice)
121284b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1213915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
12145449c685a4b39534f18869a93896370224463715Forest Bond
1215915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
1216915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PSRxDesc        pDesc = &(pDevice->aRD1Ring[i]);
1217915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PDEVICE_RD_INFO  pRDInfo = pDesc->pRDInfo;
12185449c685a4b39534f18869a93896370224463715Forest Bond
1219915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma,
1220915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				 pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
12215449c685a4b39534f18869a93896370224463715Forest Bond
1222915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb(pRDInfo->skb);
12235449c685a4b39534f18869a93896370224463715Forest Bond
1224915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		kfree((void *)pDesc->pRDInfo);
1225915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
12265449c685a4b39534f18869a93896370224463715Forest Bond}
12275449c685a4b39534f18869a93896370224463715Forest Bond
12283f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_frag_buf(struct vnt_private *pDevice)
122984b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1230915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSDeFragControlBlock pDeF;
1231915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
12325449c685a4b39534f18869a93896370224463715Forest Bond
1233915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < CB_MAX_RX_FRAG; i++) {
1234915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDeF = &(pDevice->sRxDFCB[i]);
12355449c685a4b39534f18869a93896370224463715Forest Bond
1236915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDeF->skb)
1237915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb(pDeF->skb);
12385449c685a4b39534f18869a93896370224463715Forest Bond
1239915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
12405449c685a4b39534f18869a93896370224463715Forest Bond}
12415449c685a4b39534f18869a93896370224463715Forest Bond
12423f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_td0_ring(struct vnt_private *pDevice)
124384b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1244915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1245915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dma_addr_t  curr;
1246915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxDesc        pDesc;
1247915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1248915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	curr = pDevice->td0_pool_dma;
1249915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++, curr += sizeof(STxDesc)) {
1250915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc = &(pDevice->apTD0Rings[i]);
1251915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pTDInfo = alloc_td_info();
1252915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		ASSERT(pDesc->pTDInfo);
1253915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1254915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDesc->pTDInfo->buf = pDevice->tx0_bufs + (i)*PKT_BUF_SZ;
1255915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma0 + (i)*PKT_BUF_SZ;
1256915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1257915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next = &(pDevice->apTD0Rings[(i+1) % pDevice->sOpts.nTxDescs[0]]);
1258915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1259915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1260915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1261915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1262915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (i > 0)
1263915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
1264915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
12655449c685a4b39534f18869a93896370224463715Forest Bond}
12665449c685a4b39534f18869a93896370224463715Forest Bond
12673f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_init_td1_ring(struct vnt_private *pDevice)
126884b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1269915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1270915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dma_addr_t  curr;
1271915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxDesc    pDesc;
1272915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1273915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	/* Init the TD ring entries */
1274915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	curr = pDevice->td1_pool_dma;
1275915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++, curr += sizeof(STxDesc)) {
1276915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc = &(pDevice->apTD1Rings[i]);
1277915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pTDInfo = alloc_td_info();
1278915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		ASSERT(pDesc->pTDInfo);
1279915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->flags & DEVICE_FLAGS_TX_ALIGN) {
1280915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDesc->pTDInfo->buf = pDevice->tx1_bufs + (i) * PKT_BUF_SZ;
1281915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDesc->pTDInfo->buf_dma = pDevice->tx_bufs_dma1 + (i) * PKT_BUF_SZ;
1282915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1283915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next = &(pDevice->apTD1Rings[(i + 1) % pDevice->sOpts.nTxDescs[1]]);
1284915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->pTDInfo->curr_desc = cpu_to_le32(curr);
1285915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
1286915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1287915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1288915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (i > 0)
1289915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
1290915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
12915449c685a4b39534f18869a93896370224463715Forest Bond}
12925449c685a4b39534f18869a93896370224463715Forest Bond
12933f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_td0_ring(struct vnt_private *pDevice)
129484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1295915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
12966b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
1297915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
1298915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PSTxDesc        pDesc = &(pDevice->apTD0Rings[i]);
1299915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PDEVICE_TD_INFO  pTDInfo = pDesc->pTDInfo;
13005449c685a4b39534f18869a93896370224463715Forest Bond
1301915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1302915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1303915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					 pTDInfo->skb->len, PCI_DMA_TODEVICE);
13045449c685a4b39534f18869a93896370224463715Forest Bond
1305915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTDInfo->skb)
1306915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb(pTDInfo->skb);
13075449c685a4b39534f18869a93896370224463715Forest Bond
1308915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		kfree((void *)pDesc->pTDInfo);
1309915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
13105449c685a4b39534f18869a93896370224463715Forest Bond}
13115449c685a4b39534f18869a93896370224463715Forest Bond
13123f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_td1_ring(struct vnt_private *pDevice)
131384b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1314915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
13155449c685a4b39534f18869a93896370224463715Forest Bond
1316915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
1317915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PSTxDesc        pDesc = &(pDevice->apTD1Rings[i]);
1318915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		PDEVICE_TD_INFO  pTDInfo = pDesc->pTDInfo;
13195449c685a4b39534f18869a93896370224463715Forest Bond
1320915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma))
1321915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma,
1322915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					 pTDInfo->skb->len, PCI_DMA_TODEVICE);
13235449c685a4b39534f18869a93896370224463715Forest Bond
1324915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTDInfo->skb)
1325915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb(pTDInfo->skb);
13265449c685a4b39534f18869a93896370224463715Forest Bond
1327915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		kfree((void *)pDesc->pTDInfo);
1328915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
13295449c685a4b39534f18869a93896370224463715Forest Bond}
13305449c685a4b39534f18869a93896370224463715Forest Bond
13315449c685a4b39534f18869a93896370224463715Forest Bond/*-----------------------------------------------------------------*/
13325449c685a4b39534f18869a93896370224463715Forest Bond
13333f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx)
133484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1335915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSRxDesc    pRD;
1336915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int works = 0;
13375449c685a4b39534f18869a93896370224463715Forest Bond
1338915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (pRD = pDevice->pCurrRD[uIdx];
1339915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	     pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
1340915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	     pRD = pRD->next) {
1341915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (works++ > 15)
1342915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
1343915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (device_receive_frame(pDevice, pRD)) {
1344915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (!device_alloc_rx_buf(pDevice, pRD)) {
134542f709eff132e82f5375b4daae208953035768b2Malcolm Priestley				dev_err(&pDevice->pcid->dev,
134642f709eff132e82f5375b4daae208953035768b2Malcolm Priestley					"can not allocate rx buf\n");
1347915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				break;
1348915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1349915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1350915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1351915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->dev->last_rx = jiffies;
1352915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1353915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1354915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->pCurrRD[uIdx] = pRD;
1355915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1356915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return works;
13575449c685a4b39534f18869a93896370224463715Forest Bond}
13585449c685a4b39534f18869a93896370224463715Forest Bond
13593f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD)
136084b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1361915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
13625449c685a4b39534f18869a93896370224463715Forest Bond
1363915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1364915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pRDInfo->skb == NULL)
1365915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1366915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	ASSERT(pRDInfo->skb);
1367915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRDInfo->skb->dev = pDevice->dev;
1368915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
1369915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
1370915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	*((unsigned int *)&(pRD->m_rd0RD0)) = 0; /* FIX cast */
1371915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1372915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
1373915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
1374915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRD->m_rd1RD1.wReqCount = cpu_to_le16(pDevice->rx_buf_sz);
1375915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pRD->buff_addr = cpu_to_le32(pRDInfo->skb_dma);
1376915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1377915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
13785449c685a4b39534f18869a93896370224463715Forest Bond}
13795449c685a4b39534f18869a93896370224463715Forest Bond
13803f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleybool device_alloc_frag_buf(struct vnt_private *pDevice,
13813f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley			   PSDeFragControlBlock pDeF)
138284b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1383915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1384915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDeF->skb == NULL)
1385915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1386915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	ASSERT(pDeF->skb);
1387915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDeF->skb->dev = pDevice->dev;
13885449c685a4b39534f18869a93896370224463715Forest Bond
1389915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
13905449c685a4b39534f18869a93896370224463715Forest Bond}
13915449c685a4b39534f18869a93896370224463715Forest Bond
13923f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx)
139384b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1394915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxDesc                 pTD;
1395915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bFull = false;
1396915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int                      works = 0;
1397915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byTsr0;
1398915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byTsr1;
1399915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int	uFrameSize, uFIFOHeaderSize;
1400915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxBufHead              pTxBufHead;
140122981e0e5ab3aedfb46698ed7c12c7b944781bd3Tobias Klauser	struct net_device_stats *pStats = &pDevice->dev->stats;
1402915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct sk_buff *skb;
1403915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int	uNodeIndex;
1404915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject             pMgmt = pDevice->pMgmt;
1405915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1406915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] > 0; pTD = pTD->next) {
1407915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTD->m_td0TD0.f1Owner == OWNED_BY_NIC)
1408915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
1409915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (works++ > 15)
1410915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
1411915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1412915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byTsr0 = pTD->m_td0TD0.byTSR0;
1413915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byTsr1 = pTD->m_td0TD0.byTSR1;
1414915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1415915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		//Only the status of first TD in the chain is correct
1416915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pTD->m_td1TD1.byTCR & TCR_STP) {
1417915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
1418915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
1419915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
1420915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
1421915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// Update the statistics based on the Transmit status
1422915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// now, we DONT check TSR0_CDH
1423915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1424915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				STAvUpdateTDStatCounter(&pDevice->scStatistic,
1425915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							byTsr0, byTsr1,
1426915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							(unsigned char *)(pTD->pTDInfo->buf + uFIFOHeaderSize),
1427915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							uFrameSize, uIdx);
1428915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1429915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				BSSvUpdateNodeTxCounter(pDevice,
1430915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							byTsr0, byTsr1,
1431915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							(unsigned char *)(pTD->pTDInfo->buf),
1432915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							uFIFOHeaderSize
1433915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					);
1434915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1435915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (!(byTsr1 & TSR1_TERR)) {
1436915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (byTsr0 != 0) {
143748caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n",
143848caf5a060491edb2e1793539dad72e70c54c869Joe Perches							 (int)uIdx, byTsr1,
143948caf5a060491edb2e1793539dad72e70c54c869Joe Perches							 byTsr0);
1440915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
1441bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez					if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG)
1442915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pDevice->s802_11Counter.TransmittedFragmentCount++;
1443bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1444915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pStats->tx_packets++;
1445915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pStats->tx_bytes += pTD->pTDInfo->skb->len;
14465e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches				} else {
144748caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n",
144848caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 (int)uIdx, byTsr1, byTsr0);
1449915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pStats->tx_errors++;
1450915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pStats->tx_dropped++;
1451915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1452915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1453915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1454915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
1455915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->bEnableHostapd) {
145648caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("tx call back netif..\n");
1457915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb = pTD->pTDInfo->skb;
1458915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb->dev = pDevice->apdev;
1459915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb_reset_mac_header(skb);
1460915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb->pkt_type = PACKET_OTHERHOST;
1461915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					memset(skb->cb, 0, sizeof(skb->cb));
1462915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					netif_rx(skb);
1463915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1464915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1465915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1466915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (byTsr1 & TSR1_TERR) {
1467915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
146848caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n",
146948caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 (int)uIdx, byTsr1, byTsr0);
1470915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1471915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
14725449c685a4b39534f18869a93896370224463715Forest Bond
1473915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
1474915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    (pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)) {
1475915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					unsigned short wAID;
1476915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
1477915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1478915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb = pTD->pTDInfo->skb;
1479915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1480915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1481915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1482915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1483915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							// set tx map
1484915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1485915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
1486915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
148748caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_debug("tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n",
148848caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 (int)uNodeIndex,
148948caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
1490915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pStats->tx_errors--;
1491915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pStats->tx_dropped--;
1492915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						}
1493915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
1494915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1495915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1496915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			device_free_tx_buf(pDevice, pTD);
1497915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->iTDUsed[uIdx]--;
1498915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1499915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1500915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1501915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (uIdx == TYPE_AC0DMA) {
1502915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// RESERV_AC0DMA reserved for relay
1503915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1504915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
1505915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bFull = true;
150648caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug(" AC0DMA is Full = %d\n",
150748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				 pDevice->iTDUsed[uIdx]);
1508915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1509bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (netif_queue_stopped(pDevice->dev) && !bFull)
1510915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			netif_wake_queue(pDevice->dev);
1511bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1512915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1513915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1514915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apTailTD[uIdx] = pTD;
1515915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1516915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return works;
15175449c685a4b39534f18869a93896370224463715Forest Bond}
15185449c685a4b39534f18869a93896370224463715Forest Bond
15193f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_error(struct vnt_private *pDevice, unsigned short status)
152084b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1521915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (status & ISR_FETALERR) {
152242f709eff132e82f5375b4daae208953035768b2Malcolm Priestley		dev_err(&pDevice->pcid->dev, "Hardware fatal error\n");
152342f709eff132e82f5375b4daae208953035768b2Malcolm Priestley
1524915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		netif_stop_queue(pDevice->dev);
1525915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		del_timer(&pDevice->sTimerCommand);
1526915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		del_timer(&(pDevice->pMgmt->sTimerSecondCallback));
1527915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->bCmdRunning = false;
1528915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACbShutdown(pDevice->PortOffset);
1529915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return;
1530915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
15315449c685a4b39534f18869a93896370224463715Forest Bond}
15325449c685a4b39534f18869a93896370224463715Forest Bond
15333f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc)
153484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1535915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PDEVICE_TD_INFO  pTDInfo = pDesc->pTDInfo;
1536915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct sk_buff *skb = pTDInfo->skb;
15375449c685a4b39534f18869a93896370224463715Forest Bond
1538915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// pre-allocated buf_dma can't be unmapped.
1539915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pTDInfo->skb_dma && (pTDInfo->skb_dma != pTDInfo->buf_dma)) {
1540915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pci_unmap_single(pDevice->pcid, pTDInfo->skb_dma, skb->len,
1541915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				 PCI_DMA_TODEVICE);
1542915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
15435449c685a4b39534f18869a93896370224463715Forest Bond
1544915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if ((pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0)
1545915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
15465449c685a4b39534f18869a93896370224463715Forest Bond
1547915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pTDInfo->skb_dma = 0;
154870ae543b3260a1cb53b30320d650effa575fa174Guillaume Clement	pTDInfo->skb = NULL;
1549915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pTDInfo->byFlags = 0;
15505449c685a4b39534f18869a93896370224463715Forest Bond}
15515449c685a4b39534f18869a93896370224463715Forest Bond
155284b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clementstatic int  device_open(struct net_device *dev)
15535449c685a4b39534f18869a93896370224463715Forest Bond{
15543f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
1555915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int i;
1556db6cb9036b2756c50efc43127c476786ea92eae2Jim Lieb#ifdef WPA_SM_Transtatus
1557915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	extern SWPAResult wpa_Result;
1558db6cb9036b2756c50efc43127c476786ea92eae2Jim Lieb#endif
1559db6cb9036b2756c50efc43127c476786ea92eae2Jim Lieb
1560915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->rx_buf_sz = PKT_BUF_SZ;
1561bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (!device_init_rings(pDevice))
1562915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return -ENOMEM;
1563bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
15645449c685a4b39534f18869a93896370224463715Forest Bond//2008-5-13 <add> by chester
1565915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	i = request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
1566915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (i)
1567915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return i;
1568f2046f93db0918f99875853772142143590ba0c6Joe Perches
15695449c685a4b39534f18869a93896370224463715Forest Bond#ifdef WPA_SM_Transtatus
1570915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memset(wpa_Result.ifname, 0, sizeof(wpa_Result.ifname));
1571915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	wpa_Result.proto = 0;
1572915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	wpa_Result.key_mgmt = 0;
1573915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	wpa_Result.eap_type = 0;
1574915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	wpa_Result.authenticated = false;
1575915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->fWPA_Authened = false;
15765449c685a4b39534f18869a93896370224463715Forest Bond#endif
157748caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("call device init rd0 ring\n");
1578915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_init_rd0_ring(pDevice);
1579915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_init_rd1_ring(pDevice);
1580915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_init_defrag_cb(pDevice);
1581915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_init_td0_ring(pDevice);
1582915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_init_td1_ring(pDevice);
15835449c685a4b39534f18869a93896370224463715Forest Bond
1584bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (pDevice->bDiversityRegCtlON)
1585915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		device_init_diversity_timer(pDevice);
1586bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1587915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vMgrObjectInit(pDevice);
1588915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vMgrTimerInit(pDevice);
15895449c685a4b39534f18869a93896370224463715Forest Bond
159048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("call device_init_registers\n");
15919f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley	device_init_registers(pDevice);
15929f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley
1593915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
1594915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
1595915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_set_multi(pDevice->dev);
15965449c685a4b39534f18869a93896370224463715Forest Bond
1597915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Init for Key Management
1598915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
1599915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	add_timer(&(pDevice->pMgmt->sTimerSecondCallback));
16005449c685a4b39534f18869a93896370224463715Forest Bond
1601915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1602915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bwextcount = 0;
1603915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bWPASuppWextEnabled = false;
16045449c685a4b39534f18869a93896370224463715Forest Bond#endif
1605915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->byReAssocCount = 0;
1606915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bWPADEVUp = false;
1607915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Patch: if WEP key already set by iwconfig but device not yet open
16081208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bEncryptionEnable && pDevice->bTransmitKey) {
1609915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		KeybSetDefaultKey(&(pDevice->sKey),
1610915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  (unsigned long)(pDevice->byKeyIndex | (1 << 31)),
1611915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  pDevice->uKeyLength,
1612915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  NULL,
1613915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  pDevice->abyKey,
1614915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  KEY_CTL_WEP,
1615915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  pDevice->PortOffset,
1616915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				  pDevice->byLocalID
1617915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
1618915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
1619915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
16205449c685a4b39534f18869a93896370224463715Forest Bond
162148caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("call MACvIntEnable\n");
16225449c685a4b39534f18869a93896370224463715Forest Bond	MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
16235449c685a4b39534f18869a93896370224463715Forest Bond
1624915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
1625915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
16265e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
1627915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
1628915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
1629915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1630915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->flags |= DEVICE_FLAGS_OPENED;
16315449c685a4b39534f18869a93896370224463715Forest Bond
163248caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("device_open success..\n");
1633915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
16345449c685a4b39534f18869a93896370224463715Forest Bond}
16355449c685a4b39534f18869a93896370224463715Forest Bond
163684b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clementstatic int  device_close(struct net_device *dev)
163784b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
16383f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
1639915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject     pMgmt = pDevice->pMgmt;
16405449c685a4b39534f18869a93896370224463715Forest Bond//2007-1121-02<Add>by EinsnLiu
1641915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bLinkPass) {
1642915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
1643915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		mdelay(30);
1644915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1645f2af99ee5bca2eccc2d61bfee0ad82c84af18f8fMalcolm Priestley
1646915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	del_timer(&pDevice->sTimerTxData);
1647915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	del_timer(&pDevice->sTimerCommand);
1648915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	del_timer(&pMgmt->sTimerSecondCallback);
1649915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bDiversityRegCtlON) {
1650915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		del_timer(&pDevice->TimerSQ3Tmax1);
1651915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		del_timer(&pDevice->TimerSQ3Tmax2);
1652915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		del_timer(&pDevice->TimerSQ3Tmax3);
1653915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
16545449c685a4b39534f18869a93896370224463715Forest Bond
1655915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	netif_stop_queue(dev);
1656915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bCmdRunning = false;
1657915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACbShutdown(pDevice->PortOffset);
1658915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACbSoftwareReset(pDevice->PortOffset);
1659915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	CARDbRadioPowerOff(pDevice);
1660915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1661915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bLinkPass = false;
1662915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memset(pMgmt->abyCurrBSSID, 0, 6);
1663915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pMgmt->eCurrState = WMAC_STATE_IDLE;
1664915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_td0_ring(pDevice);
1665915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_td1_ring(pDevice);
1666915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_rd0_ring(pDevice);
1667915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_rd1_ring(pDevice);
1668915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_frag_buf(pDevice);
1669915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_free_rings(pDevice);
1670915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	BSSvClearNodeDBTable(pDevice, 0);
1671915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	free_irq(dev->irq, dev);
1672915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->flags &= (~DEVICE_FLAGS_OPENED);
16735449c685a4b39534f18869a93896370224463715Forest Bond	//2008-0714-01<Add>by chester
1674915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	device_release_WPADEV(pDevice);
16754e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
167648caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("device_close..\n");
1677915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
16785449c685a4b39534f18869a93896370224463715Forest Bond}
16795449c685a4b39534f18869a93896370224463715Forest Bond
168084b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clementstatic int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
168184b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
16823f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
1683915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char *pbMPDU;
1684915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cbMPDULen = 0;
16855449c685a4b39534f18869a93896370224463715Forest Bond
168648caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("device_dma0_tx_80211\n");
1687915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_lock_irq(&pDevice->lock);
16885449c685a4b39534f18869a93896370224463715Forest Bond
1689915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
169048caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("device_dma0_tx_80211, td0 <=0\n");
1691915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1692915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
1693915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return 0;
1694915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
16955449c685a4b39534f18869a93896370224463715Forest Bond
16961208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bStopTx0Pkt) {
1697915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1698915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
1699915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return 0;
1700915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
17015449c685a4b39534f18869a93896370224463715Forest Bond
1702915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	cbMPDULen = skb->len;
1703915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pbMPDU = skb->data;
17045449c685a4b39534f18869a93896370224463715Forest Bond
1705915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
17065449c685a4b39534f18869a93896370224463715Forest Bond
1707915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_unlock_irq(&pDevice->lock);
17085449c685a4b39534f18869a93896370224463715Forest Bond
1709915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
17105449c685a4b39534f18869a93896370224463715Forest Bond}
17115449c685a4b39534f18869a93896370224463715Forest Bond
17123f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleybool device_dma0_xmit(struct vnt_private *pDevice,
17133f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley		      struct sk_buff *skb, unsigned int uNodeIndex)
171484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
1715915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
1716915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxDesc        pHeadTD, pLastTD;
1717915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cbFrameBodySize;
1718915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int uMACfragNum;
1719915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byPktType;
1720915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bNeedEncryption = false;
1721915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSKeyItem       pTransmitKey = NULL;
1722915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cbHeaderSize;
1723915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int ii;
1724915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	SKeyItem        STempKey;
17255449c685a4b39534f18869a93896370224463715Forest Bond
17261208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bStopTx0Pkt) {
1727915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1728915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1729915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
17305449c685a4b39534f18869a93896370224463715Forest Bond
1731915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
1732915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
173348caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("device_dma0_xmit, td0 <=0\n");
1734915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1735915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
17365449c685a4b39534f18869a93896370224463715Forest Bond
1737915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1738915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->uAssocCount == 0) {
1739915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb_irq(skb);
174048caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("device_dma0_xmit, assocCount = 0\n");
1741915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			return false;
1742915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1743915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
17445449c685a4b39534f18869a93896370224463715Forest Bond
1745915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
17465449c685a4b39534f18869a93896370224463715Forest Bond
1747915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
17485449c685a4b39534f18869a93896370224463715Forest Bond
1749915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
1750915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	cbFrameBodySize = skb->len - ETH_HLEN;
17515449c685a4b39534f18869a93896370224463715Forest Bond
1752915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// 802.1H
1753bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
1754915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		cbFrameBodySize += 8;
1755bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1756915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
17575449c685a4b39534f18869a93896370224463715Forest Bond
1758915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (uMACfragNum > AVAIL_TD(pDevice, TYPE_TXDMA0)) {
1759915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1760915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return false;
1761915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1762915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	byPktType = (unsigned char)pDevice->byPacketType;
17635449c685a4b39534f18869a93896370224463715Forest Bond
1764915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bFixRate) {
1765915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
1766bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (pDevice->uConnectionRate >= RATE_11M)
1767915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_11M;
1768bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			else
1769915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1770915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} else {
1771915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->uConnectionRate >= RATE_54M)
1772915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_54M;
1773915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			else
1774915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
1775915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
17765e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
1777915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->wCurrentRate = pDevice->pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
17785449c685a4b39534f18869a93896370224463715Forest Bond	}
17795449c685a4b39534f18869a93896370224463715Forest Bond
1780915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	//preamble type
1781bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
1782915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byPreambleType = pDevice->byShortPreamble;
1783bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	else
1784915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byPreambleType = PREAMBLE_LONG;
17855449c685a4b39534f18869a93896370224463715Forest Bond
178648caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate);
17875449c685a4b39534f18869a93896370224463715Forest Bond
1788915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->wCurrentRate <= RATE_11M) {
1789915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byPktType = PK_TYPE_11B;
1790915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	} else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
1791915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byPktType = PK_TYPE_11A;
1792915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	} else {
1793bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->bProtectMode)
1794915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			byPktType = PK_TYPE_11GB;
1795bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		else
1796915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			byPktType = PK_TYPE_11GA;
1797915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
17985449c685a4b39534f18869a93896370224463715Forest Bond
17991208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bEncryptionEnable)
1800915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bNeedEncryption = true;
1801915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1802915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bEnableHostWEP) {
1803915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey = &STempKey;
1804915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
1805915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
1806915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
1807915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
1808915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
1809915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		memcpy(pTransmitKey->abyKey,
1810915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		       &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
1811915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		       pTransmitKey->uKeyLength
1812915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			);
1813915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1814915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
1815915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
1816915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
1817915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &uMACfragNum,
1818915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &cbHeaderSize
1819915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		);
1820915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1821915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
1822915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Disable PS
1823915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACbPSWakeup(pDevice->PortOffset);
1824915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
18255449c685a4b39534f18869a93896370224463715Forest Bond
1826915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bPWBitOn = false;
1827915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1828915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD = pHeadTD;
1829915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (ii = 0; ii < uMACfragNum; ii++) {
1830915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Poll Transmit the adapter
1831915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wmb();
1832915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
1833915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wmb();
1834915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (ii == (uMACfragNum - 1))
1835915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pLastTD = pHeadTD;
1836915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pHeadTD = pHeadTD->next;
1837915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
18385449c685a4b39534f18869a93896370224463715Forest Bond
1839915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Save the information needed by the tx interrupt handler
1840915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// to complete the Send request
1841915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->skb = skb;
1842915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->byFlags = 0;
1843915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
18445449c685a4b39534f18869a93896370224463715Forest Bond
1845915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apCurrTD[TYPE_TXDMA0] = pHeadTD;
18465449c685a4b39534f18869a93896370224463715Forest Bond
1847915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvTransmit0(pDevice->PortOffset);
18485449c685a4b39534f18869a93896370224463715Forest Bond
1849915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
18505449c685a4b39534f18869a93896370224463715Forest Bond}
18515449c685a4b39534f18869a93896370224463715Forest Bond
1852915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches//TYPE_AC0DMA data tx
18533f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
18543f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
1855915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
1856915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSTxDesc        pHeadTD, pLastTD;
1857915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int uNodeIndex = 0;
1858915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
1859915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned short wAID;
1860915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int uMACfragNum = 1;
1861915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cbFrameBodySize;
1862915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byPktType;
1863915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int cbHeaderSize;
1864915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bNeedEncryption = false;
1865915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSKeyItem       pTransmitKey = NULL;
1866915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	SKeyItem        STempKey;
1867915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned int ii;
1868915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bTKIP_UseGTK = false;
1869915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bNeedDeAuth = false;
1870915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char *pbyBSSID;
1871915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	bool bNodeExist = false;
1872915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1873915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_lock_irq(&pDevice->lock);
18741208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (!pDevice->bLinkPass) {
1875915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1876915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
1877915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return 0;
1878915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
18795449c685a4b39534f18869a93896370224463715Forest Bond
1880915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bStopDataPkt) {
1881915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
1882915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
1883915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return 0;
1884915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
18855449c685a4b39534f18869a93896370224463715Forest Bond
1886915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1887915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->uAssocCount == 0) {
1888915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb_irq(skb);
1889915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_unlock_irq(&pDevice->lock);
1890915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			return 0;
1891915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1892915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (is_multicast_ether_addr((unsigned char *)(skb->data))) {
1893915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			uNodeIndex = 0;
1894915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bNodeExist = true;
1895915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pMgmt->sNodeDBTable[0].bPSEnable) {
1896915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
1897915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pMgmt->sNodeDBTable[0].wEnQueueCnt++;
1898915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// set tx map
1899915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pMgmt->abyPSTxMap[0] |= byMask[0];
1900915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				spin_unlock_irq(&pDevice->lock);
1901915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				return 0;
1902915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1903915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} else {
1904915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(skb->data), &uNodeIndex)) {
1905915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
1906915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
1907915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
1908915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// set tx map
1909915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
1910915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
191148caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("Set:pMgmt->abyPSTxMap[%d]= %d\n",
191248caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 (wAID >> 3),
191348caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 pMgmt->abyPSTxMap[wAID >> 3]);
1914915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					spin_unlock_irq(&pDevice->lock);
1915915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					return 0;
1916915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1917915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1918bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
1919915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->byPreambleType = pDevice->byShortPreamble;
1920bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				else
1921915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->byPreambleType = PREAMBLE_LONG;
1922bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
1923915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				bNodeExist = true;
1924915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1925915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1926915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1927915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
19281208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		if (!bNodeExist) {
192948caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("Unknown STA not found in node DB\n");
1930915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			dev_kfree_skb_irq(skb);
1931915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_unlock_irq(&pDevice->lock);
1932915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			return 0;
1933915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
1934915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1935915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1936915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pHeadTD = pDevice->apCurrTD[TYPE_AC0DMA];
1937915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1938915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
1939915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1940915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(pDevice->sTxEthHeader.abyDstAddr, (unsigned char *)(skb->data), ETH_HLEN);
1941915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	cbFrameBodySize = skb->len - ETH_HLEN;
1942915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// 802.1H
1943bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN)
1944915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		cbFrameBodySize += 8;
1945915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
19461208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (pDevice->bEncryptionEnable) {
1947915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bNeedEncryption = true;
1948915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// get Transmit key
1949915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		do {
1950915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
1951915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
1952915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pbyBSSID = pDevice->abyBSSID;
1953915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// get pairwise key
1954915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
1955915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// get group key
1956915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
1957915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						bTKIP_UseGTK = true;
195848caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_debug("Get GTK\n");
1959915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						break;
1960915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
1961915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				} else {
196248caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("Get PTK\n");
1963915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					break;
1964915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
1965915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			} else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
1966915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pbyBSSID = pDevice->sTxEthHeader.abyDstAddr;  //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
196748caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("IBSS Serach Key:\n");
1968915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				for (ii = 0; ii < 6; ii++)
196948caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("%x\n", *(pbyBSSID+ii));
197048caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("\n");
1971915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1972915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// get pairwise key
1973915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
1974915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					break;
1975915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1976915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			// get group key
1977915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pbyBSSID = pDevice->abyBroadcastAddr;
1978915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
1979915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pTransmitKey = NULL;
1980bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
198148caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("IBSS and KEY is NULL. [%d]\n",
198248caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 pDevice->pMgmt->eCurrMode);
1983bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez				else
198448caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("NOT IBSS and KEY is NULL. [%d]\n",
198548caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 pDevice->pMgmt->eCurrMode);
1986915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			} else {
1987915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				bTKIP_UseGTK = true;
198848caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("Get GTK\n");
1989915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
1990915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} while (false);
1991915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
1992915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
1993915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bEnableHostWEP) {
199448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("acdma0: STA index %d\n", uNodeIndex);
19951208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		if (pDevice->bEncryptionEnable) {
1996915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey = &STempKey;
1997915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
1998915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
1999915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
2000915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
2001915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
2002915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			memcpy(pTransmitKey->abyKey,
2003915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			       &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
2004915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			       pTransmitKey->uKeyLength
2005915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				);
2006915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2007915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2008915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2009915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
2010915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2011915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
201248caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n",
201348caf5a060491edb2e1793539dad72e70c54c869Joe Perches			 uMACfragNum);
2014915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		dev_kfree_skb_irq(skb);
2015915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
2016915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return 0;
2017915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2018915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2019915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pTransmitKey != NULL) {
2020915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if ((pTransmitKey->byCipherSuite == KEY_CTL_WEP) &&
2021915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		    (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN)) {
2022915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			uMACfragNum = 1; //WEP256 doesn't support fragment
2023915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2024915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2025915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2026915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	byPktType = (unsigned char)pDevice->byPacketType;
2027915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2028915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bFixRate) {
2029915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
2030bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (pDevice->uConnectionRate >= RATE_11M)
2031915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_11M;
2032bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			else
2033915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
2034915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} else {
2035915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if ((pDevice->eCurrentPHYType == PHY_TYPE_11A) &&
2036915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    (pDevice->uConnectionRate <= RATE_6M)) {
2037915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_6M;
2038915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			} else {
2039915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->uConnectionRate >= RATE_54M)
2040915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->wCurrentRate = RATE_54M;
2041915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				else
2042915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
2043915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2044915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2045915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2046915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byACKRate = (unsigned char) pDevice->wCurrentRate;
2047915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byTopCCKBasicRate = RATE_1M;
2048915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byTopOFDMBasicRate = RATE_6M;
20495e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
2050915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		//auto rate
2051915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2052915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
2053915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_1M;
2054915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byACKRate = RATE_1M;
2055915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byTopCCKBasicRate = RATE_1M;
2056915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byTopOFDMBasicRate = RATE_6M;
2057915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			} else {
2058915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->wCurrentRate = RATE_6M;
2059915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byACKRate = RATE_6M;
2060915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byTopCCKBasicRate = RATE_1M;
2061915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byTopOFDMBasicRate = RATE_6M;
2062915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
20635e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
2064915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			VNTWIFIvGetTxRate(pDevice->pMgmt,
2065915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  pDevice->sTxEthHeader.abyDstAddr,
2066915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  &(pDevice->wCurrentRate),
2067915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  &(pDevice->byACKRate),
2068915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  &(pDevice->byTopCCKBasicRate),
2069915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					  &(pDevice->byTopOFDMBasicRate));
2070915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2071915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2072915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2073915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2074915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2075915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->wCurrentRate <= RATE_11M) {
2076915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byPktType = PK_TYPE_11B;
2077915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	} else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
2078915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byPktType = PK_TYPE_11A;
2079915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	} else {
2080bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->bProtectMode)
2081915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			byPktType = PK_TYPE_11GB;
2082bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		else
2083915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			byPktType = PK_TYPE_11GA;
2084915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2085915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
20861208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta	if (bNeedEncryption) {
208748caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("ntohs Pkt Type=%04x\n",
208848caf5a060491edb2e1793539dad72e70c54c869Joe Perches			 ntohs(pDevice->sTxEthHeader.wType));
2089915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
2090915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bNeedEncryption = false;
209148caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("Pkt Type=%04x\n",
209248caf5a060491edb2e1793539dad72e70c54c869Joe Perches				 (pDevice->sTxEthHeader.wType));
2093915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2094915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pTransmitKey == NULL) {
209548caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("Don't Find TX KEY\n");
20965e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches				} else {
20971208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta					if (bTKIP_UseGTK) {
209848caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_debug("error: KEY is GTK!!~~\n");
20995e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches					} else {
210048caf5a060491edb2e1793539dad72e70c54c869Joe Perches						pr_debug("Find PTK [%lX]\n",
210148caf5a060491edb2e1793539dad72e70c54c869Joe Perches							 pTransmitKey->dwKeyIndex);
2102915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						bNeedEncryption = true;
2103915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
2104915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2105915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2106915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2107915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->byCntMeasure == 2) {
2108915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				bNeedDeAuth = true;
2109915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
2110915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2111915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2112915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->bEnableHostWEP) {
2113915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if ((uNodeIndex != 0) &&
2114915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
211548caf5a060491edb2e1793539dad72e70c54c869Joe Perches					pr_debug("Find PTK [%lX]\n",
211648caf5a060491edb2e1793539dad72e70c54c869Joe Perches						 pTransmitKey->dwKeyIndex);
2117915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					bNeedEncryption = true;
2118915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2119915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
21205e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
2121915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pTransmitKey == NULL) {
212248caf5a060491edb2e1793539dad72e70c54c869Joe Perches				pr_debug("return no tx key\n");
2123915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				dev_kfree_skb_irq(skb);
2124915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				spin_unlock_irq(&pDevice->lock);
2125915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				return 0;
2126915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2127915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2128915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2129915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2130915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
2131915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
2132915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &pDevice->sTxEthHeader, (unsigned char *)skb->data, pTransmitKey, uNodeIndex,
2133915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &uMACfragNum,
2134915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    &cbHeaderSize
2135915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		);
2136915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2137915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
2138915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Disable PS
2139915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACbPSWakeup(pDevice->PortOffset);
2140915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2141915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bPWBitOn = false;
2142915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2143915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD = pHeadTD;
2144915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	for (ii = 0; ii < uMACfragNum; ii++) {
2145915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Poll Transmit the adapter
2146915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wmb();
2147915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pHeadTD->m_td0TD0.f1Owner = OWNED_BY_NIC;
2148915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		wmb();
2149915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (ii == uMACfragNum - 1)
2150915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pLastTD = pHeadTD;
2151915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pHeadTD = pHeadTD->next;
2152915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2153915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2154915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Save the information needed by the tx interrupt handler
2155915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// to complete the Send request
2156915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->skb = skb;
2157915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->byFlags = 0;
2158915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
2159915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->nTxDataTimeCout = 0; //2008-8-21 chester <add> for send null packet
2160f2af99ee5bca2eccc2d61bfee0ad82c84af18f8fMalcolm Priestley
2161bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1)
2162915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		netif_stop_queue(dev);
2163915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2164915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
21654e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez
2166bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (pDevice->bFixRate)
2167941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
2168915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2169915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{
2170915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		unsigned char Protocol_Version;    //802.1x Authentication
2171915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		unsigned char Packet_Type;           //802.1x Authentication
2172915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		unsigned char Descriptor_type;
2173915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		unsigned short Key_info;
2174915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bool bTxeapol_key = false;
21756b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
2176915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		Protocol_Version = skb->data[ETH_HLEN];
2177915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		Packet_Type = skb->data[ETH_HLEN+1];
2178915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		Descriptor_type = skb->data[ETH_HLEN+1+1+2];
2179915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
2180915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
2181915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
2182915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    (Packet_Type == 3)) {  //802.1x OR eapol-key challenge frame transfer
2183915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				bTxeapol_key = true;
2184915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if ((Descriptor_type == 254) || (Descriptor_type == 2)) {       //WPA or RSN
2185915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (!(Key_info & BIT3) &&   //group-key challenge
2186915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					    (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key
2187915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pDevice->fWPA_Authened = true;
2188915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						if (Descriptor_type == 254)
2189941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement							pr_debug("WPA ");
2190915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						else
2191941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement							pr_debug("WPA2 ");
2192941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement						pr_debug("Authentication completed!!\n");
2193915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
2194915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2195915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2196915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2197915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2198915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2199915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvTransmitAC0(pDevice->PortOffset);
2200915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2201915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	dev->trans_start = jiffies;
2202915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2203915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_unlock_irq(&pDevice->lock);
2204915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
22055449c685a4b39534f18869a93896370224463715Forest Bond}
2206915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
220784b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clementstatic  irqreturn_t  device_intr(int irq,  void *dev_instance)
220884b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
2209915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct net_device *dev = dev_instance;
22103f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
2211915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int             max_count = 0;
2212915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned long dwMIBCounter = 0;
2213915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject    pMgmt = pDevice->pMgmt;
2214915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byOrgPageSel = 0;
2215915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int             handled = 0;
2216915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char byData = 0;
2217915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int             ii = 0;
22186cff1f6ad4c615319c1a146b2aa0af1043c5e9f5Malcolm Priestley	unsigned long flags;
2219915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2220915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
2221915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2222915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->dwIsr == 0)
2223915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return IRQ_RETVAL(handled);
2224915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2225915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->dwIsr == 0xffffffff) {
222648caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("dwIsr = 0xffff\n");
2227915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return IRQ_RETVAL(handled);
2228915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2229915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2230915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	handled = 1;
2231915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvIntDisable(pDevice->PortOffset);
22326cff1f6ad4c615319c1a146b2aa0af1043c5e9f5Malcolm Priestley
22336cff1f6ad4c615319c1a146b2aa0af1043c5e9f5Malcolm Priestley	spin_lock_irqsave(&pDevice->lock, flags);
2234915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2235915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	//Make sure current page is 0
2236915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
2237bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (byOrgPageSel == 1)
2238915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage0(pDevice->PortOffset);
2239bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	else
2240915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		byOrgPageSel = 0;
2241915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2242915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter);
2243915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// TBD....
2244915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Must do this after doing rx/tx, cause ISR bit is slow
2245915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// than RD/TD write back
2246915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// update ISR counter
2247915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
2248915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	while (pDevice->dwIsr != 0) {
2249915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
2250915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
2251915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2252915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->dwIsr & ISR_FETALERR) {
225348caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug(" ISR_FETALERR\n");
2254915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
2255915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
2256915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			device_error(pDevice, pDevice->dwIsr);
2257915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2258915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2259915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->byLocalID > REV_ID_VT3253_B1) {
2260915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->dwIsr & ISR_MEASURESTART) {
2261915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// 802.11h measure start
2262915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byOrgChannel = pDevice->byCurrentCh;
2263915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
2264915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, (RCR_RXALLTYPE | RCR_UNICAST | RCR_BROADCAST | RCR_MULTICAST | RCR_WPAERR));
2265915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage1(pDevice->PortOffset);
2266915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR0, &(pDevice->dwOrgMAR0));
2267915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortD(pDevice->PortOffset + MAC_REG_MAR4, &(pDevice->dwOrgMAR4));
2268915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage0(pDevice->PortOffset);
2269915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				//xxxx
22701208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta				if (set_channel(pDevice, pDevice->pCurrMeasureEID->sReq.byChannel)) {
2271915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->bMeasureInProgress = true;
2272915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage1(pDevice->PortOffset);
2273915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_READY);
2274915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage0(pDevice->PortOffset);
2275915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->byBasicMap = 0;
2276915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->byCCAFraction = 0;
2277bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez					for (ii = 0; ii < 8; ii++)
2278915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pDevice->dwRPIs[ii] = 0;
2279bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2280915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				} else {
2281915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// can not measure because set channel fail
2282915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// clear measure control
2283915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2284915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_INCAPABLE);
2285915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage1(pDevice->PortOffset);
2286915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2287915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage0(pDevice->PortOffset);
2288915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2289915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2290915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->dwIsr & ISR_MEASUREEND) {
2291915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// 802.11h measure end
2292915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->bMeasureInProgress = false;
2293915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
2294915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage1(pDevice->PortOffset);
2295915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
2296915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
2297915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRBBSTS, &byData);
2298915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byBasicMap |= (byData >> 4);
2299915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_CCAFRACTION, &pDevice->byCCAFraction);
2300915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				VNSvInPortB(pDevice->PortOffset + MAC_REG_MSRCTL, &byData);
2301915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// clear measure control
2302915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
2303915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage0(pDevice->PortOffset);
2304915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				set_channel(pDevice, pDevice->byOrgChannel);
2305915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage1(pDevice->PortOffset);
2306915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2307915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvSelectPage0(pDevice->PortOffset);
2308915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (byData & MSRCTL_FINISH) {
2309915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// measure success
2310915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					s_vCompleteCurrentMeasure(pDevice, 0);
2311915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				} else {
2312915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					// can not measure because not ready before end of measure time
2313915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
2314915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2315915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2316915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pDevice->dwIsr & ISR_QUIETSTART) {
2317915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				do {
2318915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					;
23191208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta				} while (!CARDbStartQuiet(pDevice));
2320915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2321915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2322915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2323915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->dwIsr & ISR_TBTT) {
23241208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (pDevice->bEnableFirstQuiet) {
2325915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byQuietStartCount--;
2326915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->byQuietStartCount == 0) {
2327915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->bEnableFirstQuiet = false;
2328915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage1(pDevice->PortOffset);
2329915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
2330915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage0(pDevice->PortOffset);
2331915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2332915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
23331208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (pDevice->bChannelSwitch &&
2334a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			    (pDevice->op_mode == NL80211_IFTYPE_STATION)) {
2335915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byChannelSwitchCount--;
2336915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->byChannelSwitchCount == 0) {
2337915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->bChannelSwitch = false;
2338915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					set_channel(pDevice, pDevice->byNewChannel);
2339915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2340915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage1(pDevice->PortOffset);
2341915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2342915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage0(pDevice->PortOffset);
2343915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
2344915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2345915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2346915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2347a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) {
23481208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta				if ((pDevice->bUpdateBBVGA) && pDevice->bLinkPass && (pDevice->uCurrRSSI != 0)) {
2349915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					long            ldBm;
2350915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2351915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
2352915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
2353915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						if (ldBm < pDevice->ldBmThreshold[ii]) {
2354915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
2355915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							break;
2356915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						}
2357915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
2358915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
2359915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pDevice->uBBVGADiffCount++;
2360915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						if (pDevice->uBBVGADiffCount == 1) {
2361915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							// first VGA diff gain
2362915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
236348caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_debug("First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
236448caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 (int)ldBm,
236548caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 pDevice->byBBVGANew,
236648caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 pDevice->byBBVGACurrent,
236748caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 (int)pDevice->uBBVGADiffCount);
2368915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						}
2369915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
237048caf5a060491edb2e1793539dad72e70c54c869Joe Perches							pr_debug("RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
237148caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 (int)ldBm,
237248caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 pDevice->byBBVGANew,
237348caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 pDevice->byBBVGACurrent,
237448caf5a060491edb2e1793539dad72e70c54c869Joe Perches								 (int)pDevice->uBBVGADiffCount);
2375915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
2376915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						}
2377915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					} else {
2378915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pDevice->uBBVGADiffCount = 1;
2379915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
2380915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2381915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2382915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2383915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->bBeaconSent = false;
2384bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez			if (pDevice->bEnablePSMode)
2385915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				PSbIsNextTBTTWakeUp((void *)pDevice);
2386915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2387a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			if ((pDevice->op_mode == NL80211_IFTYPE_AP) ||
2388a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			    (pDevice->op_mode == NL80211_IFTYPE_ADHOC)) {
2389915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				MACvOneShotTimer1MicroSec(pDevice->PortOffset,
2390915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches							  (pMgmt->wIBSSBeaconPeriod - MAKE_BEACON_RESERVED) << 10);
2391915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2392915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
23934e8a7e5fc29697f881f5c358f84df52914908703Guido Martínez			/* TODO: adhoc PS mode */
2394915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2395915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2396915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2397915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->dwIsr & ISR_BNTX) {
2398a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
2399915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->bIsBeaconBufReadySet = false;
2400915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->cbBeaconBufReadySetCnt = 0;
2401915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2402915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2403a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			if (pDevice->op_mode == NL80211_IFTYPE_AP) {
2404915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pMgmt->byDTIMCount > 0) {
2405915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->byDTIMCount--;
2406915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->sNodeDBTable[0].bRxPSPoll = false;
24075e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches				} else {
2408915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					if (pMgmt->byDTIMCount == 0) {
2409915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						// check if mutltcast tx bufferring
2410915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2411915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2412915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
2413915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					}
2414915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2415915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2416915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->bBeaconSent = true;
2417915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
24181208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (pDevice->bChannelSwitch) {
2419915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pDevice->byChannelSwitchCount--;
2420915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->byChannelSwitchCount == 0) {
2421915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pDevice->bChannelSwitch = false;
2422915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					set_channel(pDevice, pDevice->byNewChannel);
2423915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					VNTWIFIbChannelSwitch(pDevice->pMgmt, pDevice->byNewChannel);
2424915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage1(pDevice->PortOffset);
2425915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
2426915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					MACvSelectPage0(pDevice->PortOffset);
2427915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					CARDbStartTxPacket(pDevice, PKT_TYPE_802_11_ALL);
2428915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				}
2429915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2430915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2431915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2432915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2433bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->dwIsr & ISR_RXDMA0)
2434915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			max_count += device_rx_srv(pDevice, TYPE_RXDMA0);
2435bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2436bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->dwIsr & ISR_RXDMA1)
2437915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			max_count += device_rx_srv(pDevice, TYPE_RXDMA1);
2438bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2439bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->dwIsr & ISR_TXDMA0)
2440915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			max_count += device_tx_srv(pDevice, TYPE_TXDMA0);
2441bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2442bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (pDevice->dwIsr & ISR_AC0DMA)
2443915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			max_count += device_tx_srv(pDevice, TYPE_AC0DMA);
2444bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2445915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pDevice->dwIsr & ISR_SOFTTIMER1) {
2446a9873673484b5aa4346111d021c83a2f11d62eb5Malcolm Priestley			if (pDevice->op_mode == NL80211_IFTYPE_AP) {
2447915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pDevice->bShortSlotTime)
2448915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
2449915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				else
2450915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					pMgmt->wCurrCapInfo &= ~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1));
2451915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2452915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bMgrPrepareBeaconToSend(pDevice, pMgmt);
2453915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->byCntMeasure = 0;
2454915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2455915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2456915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
2457915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2458915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvReceive0(pDevice->PortOffset);
2459915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvReceive1(pDevice->PortOffset);
2460915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2461915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (max_count > pDevice->sOpts.int_works)
2462915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
2463915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2464915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2465bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez	if (byOrgPageSel == 1)
2466915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage1(pDevice->PortOffset);
2467915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
24686cff1f6ad4c615319c1a146b2aa0af1043c5e9f5Malcolm Priestley	spin_unlock_irqrestore(&pDevice->lock, flags);
24696cff1f6ad4c615319c1a146b2aa0af1043c5e9f5Malcolm Priestley
2470915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
2471915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2472915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return IRQ_RETVAL(handled);
24735449c685a4b39534f18869a93896370224463715Forest Bond}
2474915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2475915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches//2008-8-4 <add> by chester
2476915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perchesstatic int Config_FileGetParameter(unsigned char *string,
2477915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				   unsigned char *dest, unsigned char *source)
2478915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches{
2479915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char buf1[100];
2480915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int source_len = strlen(source);
2481915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2482915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memset(buf1, 0, 100);
2483915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	strcat(buf1, string);
2484915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	strcat(buf1, "=");
2485915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	source += strlen(buf1);
2486915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2487915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memcpy(dest, source, source_len - strlen(buf1));
2488915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return true;
24895449c685a4b39534f18869a93896370224463715Forest Bond}
24905449c685a4b39534f18869a93896370224463715Forest Bond
24913f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleyint Config_FileOperation(struct vnt_private *pDevice,
24923f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley			 bool fwrite, unsigned char *Parameter)
2493f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro{
2494f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
2495915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unsigned char tmpbuffer[20];
2496f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	struct file *file;
2497fa13849f58dcecbb14ce9f40a15b8c9b26df004dGuillaume Clement	int result = 0;
2498915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2499f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	if (!buffer) {
2500941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("allocate mem for file fail?\n");
2501f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro		return -1;
2502f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	}
2503f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	file = filp_open(CONFIG_PATH, O_RDONLY, 0);
2504f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	if (IS_ERR(file)) {
2505f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro		kfree(buffer);
2506941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("Config_FileOperation:open file fail?\n");
2507f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro		return -1;
2508915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2509915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2510f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	if (kernel_read(file, 0, buffer, 1024) < 0) {
2511941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("read file error?\n");
2512915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = -1;
2513915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		goto error1;
2514915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2515915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
25166e61b441ceb5462d7fe14eb1697a61cb645dc871Aybuke Ozdemir	if (Config_FileGetParameter("ZONETYPE", tmpbuffer, buffer) != true) {
2517941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("get parameter error?\n");
2518915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = -1;
2519915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		goto error1;
2520915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2521915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2522fa13849f58dcecbb14ce9f40a15b8c9b26df004dGuillaume Clement	if (memcmp(tmpbuffer, "USA", 3) == 0) {
2523915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = ZoneType_USA;
25249e23c1b8c3cab8fa69fa05a9c14113d74026eaf0Aybuke Ozdemir	} else if (memcmp(tmpbuffer, "JAPAN", 5) == 0) {
2525915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = ZoneType_Japan;
25269e23c1b8c3cab8fa69fa05a9c14113d74026eaf0Aybuke Ozdemir	} else if (memcmp(tmpbuffer, "EUROPE", 5) == 0) {
2527915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = ZoneType_Europe;
25285e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
2529915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		result = -1;
2530941ead9adf195395d75eabb0cec15311bf5c5959Guillaume Clement		pr_err("Unknown Zonetype[%s]?\n", tmpbuffer);
2531915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2532915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
25335449c685a4b39534f18869a93896370224463715Forest Bonderror1:
2534915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	kfree(buffer);
2535f805442e130c6eeb6c25bc5c3b3cefc27ab6dcecAl Viro	fput(file);
2536915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return result;
25375449c685a4b39534f18869a93896370224463715Forest Bond}
25385449c685a4b39534f18869a93896370224463715Forest Bond
25393f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestleystatic void device_set_multi(struct net_device *dev) {
25403f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
2541915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject     pMgmt = pDevice->pMgmt;
2542915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	u32              mc_filter[2];
2543915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct netdev_hw_addr *ha;
2544915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2545915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
2546915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2547915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (dev->flags & IFF_PROMISC) {         /* Set promiscuous. */
254848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_notice("%s: Promiscuous mode enabled\n", dev->name);
2549915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		/* Unconditionally log net taps. */
2550915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
25515e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else if ((netdev_mc_count(dev) > pDevice->multicast_limit)
2552915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		 ||  (dev->flags & IFF_ALLMULTI)) {
2553915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage1(pDevice->PortOffset);
2554915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
2555915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
2556915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage0(pDevice->PortOffset);
2557915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
25585e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	} else {
2559915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		memset(mc_filter, 0, sizeof(mc_filter));
2560915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		netdev_for_each_mc_addr(ha, dev) {
2561915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
25626b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
2563915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
2564915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2565915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage1(pDevice->PortOffset);
2566915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, mc_filter[0]);
2567915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, mc_filter[1]);
2568915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvSelectPage0(pDevice->PortOffset);
2569915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode &= ~(RCR_UNICAST);
2570915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2571915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2572915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2573915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2574915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
2575915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
2576915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->byRxMode &= ~(RCR_UNICAST);
2577915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2578915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2579915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
258048caf5a060491edb2e1793539dad72e70c54c869Joe Perches	pr_debug("pDevice->byRxMode = %x\n", pDevice->byRxMode);
25815449c685a4b39534f18869a93896370224463715Forest Bond}
25825449c685a4b39534f18869a93896370224463715Forest Bond
258384b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clementstatic int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
258484b50762077e914348cc830d7b72bd2ee1030cedGuillaume Clement{
25853f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = netdev_priv(dev);
2586915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct iwreq *wrq = (struct iwreq *)rq;
2587915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int rc = 0;
2588915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject pMgmt = pDevice->pMgmt;
2589915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSCmdRequest pReq;
25905449c685a4b39534f18869a93896370224463715Forest Bond
2591915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pMgmt == NULL) {
2592915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = -EFAULT;
2593915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		return rc;
2594915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
25955449c685a4b39534f18869a93896370224463715Forest Bond
2596915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	switch (cmd) {
25975449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWNAME:
25985449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
25995449c685a4b39534f18869a93896370224463715Forest Bond		break;
26005449c685a4b39534f18869a93896370224463715Forest Bond
26015449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWNWID:     //0x8b03  support
2602428c1fb50ec57587eb9d7e48439059cbfeb9330aMarcos Paulo de Souza		rc = -EOPNOTSUPP;
26035449c685a4b39534f18869a93896370224463715Forest Bond		break;
26045449c685a4b39534f18869a93896370224463715Forest Bond
26055449c685a4b39534f18869a93896370224463715Forest Bond		// Set frequency/channel
26065449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWFREQ:
2607915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
26085449c685a4b39534f18869a93896370224463715Forest Bond		break;
26095449c685a4b39534f18869a93896370224463715Forest Bond
26105449c685a4b39534f18869a93896370224463715Forest Bond		// Get frequency/channel
26115449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWFREQ:
26125449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
26135449c685a4b39534f18869a93896370224463715Forest Bond		break;
26145449c685a4b39534f18869a93896370224463715Forest Bond
26155449c685a4b39534f18869a93896370224463715Forest Bond		// Set desired network name (ESSID)
26165449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWESSID:
26175449c685a4b39534f18869a93896370224463715Forest Bond
2618915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{
2619915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		char essid[IW_ESSID_MAX_SIZE+1];
26206b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
2621915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
2622915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -E2BIG;
2623915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
26245449c685a4b39534f18869a93896370224463715Forest Bond		}
2625915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (copy_from_user(essid, wrq->u.essid.pointer,
2626915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				   wrq->u.essid.length)) {
2627915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EFAULT;
2628915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
2629915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2630915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_siwessid(dev, NULL,
2631915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				    &(wrq->u.essid), essid);
2632915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2633915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
26345449c685a4b39534f18869a93896370224463715Forest Bond
2635915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Get current network name (ESSID)
26365449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWESSID:
26375449c685a4b39534f18869a93896370224463715Forest Bond
2638915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{
2639915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		char essid[IW_ESSID_MAX_SIZE+1];
26406b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
2641915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (wrq->u.essid.pointer)
2642915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = iwctl_giwessid(dev, NULL,
2643915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					    &(wrq->u.essid), essid);
2644915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (copy_to_user(wrq->u.essid.pointer,
2645915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				 essid,
2646915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				 wrq->u.essid.length))
2647915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EFAULT;
2648915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2649915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
26505449c685a4b39534f18869a93896370224463715Forest Bond
26515449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWAP:
26525449c685a4b39534f18869a93896370224463715Forest Bond
26535449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
26545449c685a4b39534f18869a93896370224463715Forest Bond		break;
26555449c685a4b39534f18869a93896370224463715Forest Bond
26565449c685a4b39534f18869a93896370224463715Forest Bond		// Get current Access Point (BSSID)
26575449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWAP:
26585449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
26595449c685a4b39534f18869a93896370224463715Forest Bond		break;
26605449c685a4b39534f18869a93896370224463715Forest Bond
26615449c685a4b39534f18869a93896370224463715Forest Bond		// Set desired station name
26625449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWNICKN:
266348caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWNICKN\n");
2664915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = -EOPNOTSUPP;
26655449c685a4b39534f18869a93896370224463715Forest Bond		break;
26665449c685a4b39534f18869a93896370224463715Forest Bond
26675449c685a4b39534f18869a93896370224463715Forest Bond		// Get current station name
26685449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWNICKN:
266948caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWNICKN\n");
2670915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = -EOPNOTSUPP;
26715449c685a4b39534f18869a93896370224463715Forest Bond		break;
26725449c685a4b39534f18869a93896370224463715Forest Bond
26735449c685a4b39534f18869a93896370224463715Forest Bond		// Set the desired bit-rate
26745449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWRATE:
26755449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
26765449c685a4b39534f18869a93896370224463715Forest Bond		break;
26775449c685a4b39534f18869a93896370224463715Forest Bond
2678915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Get the current bit-rate
26795449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWRATE:
26805449c685a4b39534f18869a93896370224463715Forest Bond
26815449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
26825449c685a4b39534f18869a93896370224463715Forest Bond		break;
26835449c685a4b39534f18869a93896370224463715Forest Bond
2684915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Set the desired RTS threshold
26855449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWRTS:
26865449c685a4b39534f18869a93896370224463715Forest Bond
26875449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
26885449c685a4b39534f18869a93896370224463715Forest Bond		break;
26895449c685a4b39534f18869a93896370224463715Forest Bond
2690915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Get the current RTS threshold
26915449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWRTS:
26925449c685a4b39534f18869a93896370224463715Forest Bond
26935449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
26945449c685a4b39534f18869a93896370224463715Forest Bond		break;
26955449c685a4b39534f18869a93896370224463715Forest Bond
26965449c685a4b39534f18869a93896370224463715Forest Bond		// Set the desired fragmentation threshold
26975449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWFRAG:
26985449c685a4b39534f18869a93896370224463715Forest Bond
26995449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
2700915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		break;
27015449c685a4b39534f18869a93896370224463715Forest Bond
2702915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// Get the current fragmentation threshold
27035449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWFRAG:
27045449c685a4b39534f18869a93896370224463715Forest Bond
27055449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
27065449c685a4b39534f18869a93896370224463715Forest Bond		break;
27075449c685a4b39534f18869a93896370224463715Forest Bond
27085449c685a4b39534f18869a93896370224463715Forest Bond		// Set mode of operation
27095449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWMODE:
2710915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
27115449c685a4b39534f18869a93896370224463715Forest Bond		break;
27125449c685a4b39534f18869a93896370224463715Forest Bond
27135449c685a4b39534f18869a93896370224463715Forest Bond		// Get mode of operation
27145449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWMODE:
27155449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
27165449c685a4b39534f18869a93896370224463715Forest Bond		break;
27175449c685a4b39534f18869a93896370224463715Forest Bond
27185449c685a4b39534f18869a93896370224463715Forest Bond		// Set WEP keys and mode
27195e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	case SIOCSIWENCODE: {
2720915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		char abyKey[WLAN_WEP232_KEYLEN];
27215449c685a4b39534f18869a93896370224463715Forest Bond
2722915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (wrq->u.encoding.pointer) {
2723915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
2724915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = -E2BIG;
2725915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				break;
2726915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2727915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			memset(abyKey, 0, WLAN_WEP232_KEYLEN);
2728915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (copy_from_user(abyKey,
2729915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					   wrq->u.encoding.pointer,
2730915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					   wrq->u.encoding.length)) {
2731915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = -EFAULT;
27325449c685a4b39534f18869a93896370224463715Forest Bond				break;
27335449c685a4b39534f18869a93896370224463715Forest Bond			}
2734915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} else if (wrq->u.encoding.length != 0) {
2735915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EINVAL;
2736915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
27375449c685a4b39534f18869a93896370224463715Forest Bond		}
2738915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
2739915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2740915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
27415449c685a4b39534f18869a93896370224463715Forest Bond
2742915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Get the WEP keys and mode
27435449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWENCODE:
27445449c685a4b39534f18869a93896370224463715Forest Bond
27455449c685a4b39534f18869a93896370224463715Forest Bond		if (!capable(CAP_NET_ADMIN)) {
27465449c685a4b39534f18869a93896370224463715Forest Bond			rc = -EPERM;
27475449c685a4b39534f18869a93896370224463715Forest Bond			break;
27485449c685a4b39534f18869a93896370224463715Forest Bond		}
27495449c685a4b39534f18869a93896370224463715Forest Bond		{
2750915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			char abyKey[WLAN_WEP232_KEYLEN];
27515449c685a4b39534f18869a93896370224463715Forest Bond
2752915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
2753a1613423cd1da7f5f6fc0e45da5411a0adcac3c5Guillaume Clement			if (rc != 0)
2754a1613423cd1da7f5f6fc0e45da5411a0adcac3c5Guillaume Clement				break;
27555449c685a4b39534f18869a93896370224463715Forest Bond			if (wrq->u.encoding.pointer) {
27565449c685a4b39534f18869a93896370224463715Forest Bond				if (copy_to_user(wrq->u.encoding.pointer,
2757915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						 abyKey,
2758915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						 wrq->u.encoding.length))
27595449c685a4b39534f18869a93896370224463715Forest Bond					rc = -EFAULT;
27605449c685a4b39534f18869a93896370224463715Forest Bond			}
27615449c685a4b39534f18869a93896370224463715Forest Bond		}
27625449c685a4b39534f18869a93896370224463715Forest Bond		break;
27635449c685a4b39534f18869a93896370224463715Forest Bond
27645449c685a4b39534f18869a93896370224463715Forest Bond		// Get the current Tx-Power
27655449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWTXPOW:
276648caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWTXPOW\n");
2767915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = -EOPNOTSUPP;
27685449c685a4b39534f18869a93896370224463715Forest Bond		break;
27695449c685a4b39534f18869a93896370224463715Forest Bond
27705449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWTXPOW:
277148caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWTXPOW\n");
2772915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = -EOPNOTSUPP;
27735449c685a4b39534f18869a93896370224463715Forest Bond		break;
27745449c685a4b39534f18869a93896370224463715Forest Bond
27755449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWRETRY:
27765449c685a4b39534f18869a93896370224463715Forest Bond
27775449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
27785449c685a4b39534f18869a93896370224463715Forest Bond		break;
27795449c685a4b39534f18869a93896370224463715Forest Bond
27805449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWRETRY:
27815449c685a4b39534f18869a93896370224463715Forest Bond
27825449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
27835449c685a4b39534f18869a93896370224463715Forest Bond		break;
27845449c685a4b39534f18869a93896370224463715Forest Bond
27855449c685a4b39534f18869a93896370224463715Forest Bond		// Get range of parameters
27865449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWRANGE:
27875449c685a4b39534f18869a93896370224463715Forest Bond
2788915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	{
2789915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		struct iw_range range;
27905449c685a4b39534f18869a93896370224463715Forest Bond
2791915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *)&range);
2792915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
2793915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EFAULT;
2794915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
27955449c685a4b39534f18869a93896370224463715Forest Bond
2796915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
27975449c685a4b39534f18869a93896370224463715Forest Bond
27985449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWPOWER:
27995449c685a4b39534f18869a93896370224463715Forest Bond
28005449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
28015449c685a4b39534f18869a93896370224463715Forest Bond		break;
28025449c685a4b39534f18869a93896370224463715Forest Bond
28035449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWPOWER:
28045449c685a4b39534f18869a93896370224463715Forest Bond
28055449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
28065449c685a4b39534f18869a93896370224463715Forest Bond		break;
28075449c685a4b39534f18869a93896370224463715Forest Bond
28085449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWSENS:
28095449c685a4b39534f18869a93896370224463715Forest Bond
2810915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
28115449c685a4b39534f18869a93896370224463715Forest Bond		break;
28125449c685a4b39534f18869a93896370224463715Forest Bond
28135449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWSENS:
281448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWSENS\n");
28155449c685a4b39534f18869a93896370224463715Forest Bond		rc = -EOPNOTSUPP;
28165449c685a4b39534f18869a93896370224463715Forest Bond		break;
28175449c685a4b39534f18869a93896370224463715Forest Bond
28185e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	case SIOCGIWAPLIST: {
2819915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
2820915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2821915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (wrq->u.data.pointer) {
2822915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
2823915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (rc == 0) {
2824915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (copy_to_user(wrq->u.data.pointer,
2825915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						 buffer,
2826915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches						 (wrq->u.data.length * (sizeof(struct sockaddr) +  sizeof(struct iw_quality)))
2827915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					    ))
2828915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					rc = -EFAULT;
2829915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2830915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2831915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2832915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
28335449c685a4b39534f18869a93896370224463715Forest Bond
28345449c685a4b39534f18869a93896370224463715Forest Bond#ifdef WIRELESS_SPY
2835915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	// Set the spy list
28365449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWSPY:
28375449c685a4b39534f18869a93896370224463715Forest Bond
283848caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWSPY\n");
28395449c685a4b39534f18869a93896370224463715Forest Bond		rc = -EOPNOTSUPP;
28405449c685a4b39534f18869a93896370224463715Forest Bond		break;
28415449c685a4b39534f18869a93896370224463715Forest Bond
28425449c685a4b39534f18869a93896370224463715Forest Bond		// Get the spy list
28435449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWSPY:
28445449c685a4b39534f18869a93896370224463715Forest Bond
284548caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWSPY\n");
28465449c685a4b39534f18869a93896370224463715Forest Bond		rc = -EOPNOTSUPP;
28475449c685a4b39534f18869a93896370224463715Forest Bond		break;
28485449c685a4b39534f18869a93896370224463715Forest Bond
28495449c685a4b39534f18869a93896370224463715Forest Bond#endif // WIRELESS_SPY
28505449c685a4b39534f18869a93896370224463715Forest Bond
28515449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWPRIV:
285248caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWPRIV\n");
28535449c685a4b39534f18869a93896370224463715Forest Bond		rc = -EOPNOTSUPP;
28545449c685a4b39534f18869a93896370224463715Forest Bond		break;
28555449c685a4b39534f18869a93896370224463715Forest Bond
28565449c685a4b39534f18869a93896370224463715Forest Bond//2008-0409-07, <Add> by Einsn Liu
2857915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
28585449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWAUTH:
285948caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWAUTH\n");
28605449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
28615449c685a4b39534f18869a93896370224463715Forest Bond		break;
28625449c685a4b39534f18869a93896370224463715Forest Bond
28635449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWAUTH:
286448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWAUTH\n");
28655449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
28665449c685a4b39534f18869a93896370224463715Forest Bond		break;
28675449c685a4b39534f18869a93896370224463715Forest Bond
28685449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWGENIE:
286948caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWGENIE\n");
28705449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
28715449c685a4b39534f18869a93896370224463715Forest Bond		break;
28725449c685a4b39534f18869a93896370224463715Forest Bond
28735449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWGENIE:
287448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWGENIE\n");
28755449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
28765449c685a4b39534f18869a93896370224463715Forest Bond		break;
28775449c685a4b39534f18869a93896370224463715Forest Bond
28785e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches	case SIOCSIWENCODEEXT: {
2879915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
2880bfd7a2819051fc0ab401609aedbe65df46ed1259Guillaume Clement
288148caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWENCODEEXT\n");
2882915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (wrq->u.encoding.pointer) {
2883915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1);
2884915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) {
2885915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = -E2BIG;
2886915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				break;
2887915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
2888915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (copy_from_user(extra, wrq->u.encoding.pointer, wrq->u.encoding.length)) {
2889915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = -EFAULT;
28905449c685a4b39534f18869a93896370224463715Forest Bond				break;
28915449c685a4b39534f18869a93896370224463715Forest Bond			}
2892915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		} else if (wrq->u.encoding.length != 0) {
2893915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EINVAL;
2894915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
28955449c685a4b39534f18869a93896370224463715Forest Bond		}
2896915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
2897915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2898915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	break;
28995449c685a4b39534f18869a93896370224463715Forest Bond
29005449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCGIWENCODEEXT:
290148caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCGIWENCODEEXT\n");
29025449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
29035449c685a4b39534f18869a93896370224463715Forest Bond		break;
29045449c685a4b39534f18869a93896370224463715Forest Bond
29055449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCSIWMLME:
290648caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug(" SIOCSIWMLME\n");
29075449c685a4b39534f18869a93896370224463715Forest Bond		rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
29085449c685a4b39534f18869a93896370224463715Forest Bond		break;
29095449c685a4b39534f18869a93896370224463715Forest Bond
29105449c685a4b39534f18869a93896370224463715Forest Bond#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
29115449c685a4b39534f18869a93896370224463715Forest Bond//End Add -- //2008-0409-07, <Add> by Einsn Liu
29125449c685a4b39534f18869a93896370224463715Forest Bond
2913915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case IOCTL_CMD_TEST:
29145449c685a4b39534f18869a93896370224463715Forest Bond
29155449c685a4b39534f18869a93896370224463715Forest Bond		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
2916915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = -EFAULT;
2917915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			break;
29185449c685a4b39534f18869a93896370224463715Forest Bond		} else {
2919915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			rc = 0;
29205449c685a4b39534f18869a93896370224463715Forest Bond		}
2921915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pReq = (PSCmdRequest)rq;
2922915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pReq->wResult = MAGIC_CODE;
2923915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		break;
29245449c685a4b39534f18869a93896370224463715Forest Bond
2925915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case IOCTL_CMD_SET:
29265449c685a4b39534f18869a93896370224463715Forest Bond
2927915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#ifdef SndEvt_ToAPI
2928915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if ((((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_EVT) &&
2929915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		    !(pDevice->flags & DEVICE_FLAGS_OPENED))
2930915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#else
2931915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
2932915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			    (((PSCmdRequest)rq)->wCmdCode != WLAN_CMD_SET_WPA))
2933915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#endif
2934915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			{
2935915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = -EFAULT;
2936915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				break;
2937915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			} else {
2938915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				rc = 0;
2939915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
29405449c685a4b39534f18869a93896370224463715Forest Bond
2941bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez		if (test_and_set_bit(0, (void *)&(pMgmt->uCmdBusy)))
2942915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			return -EBUSY;
2943bc5cf6563576bb36baa7e93417b9a2e29999a5c6Guido Martínez
2944915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = private_ioctl(pDevice, rq);
2945915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		clear_bit(0, (void *)&(pMgmt->uCmdBusy));
2946915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		break;
29475449c685a4b39534f18869a93896370224463715Forest Bond
2948915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case IOCTL_CMD_HOSTAPD:
29495449c685a4b39534f18869a93896370224463715Forest Bond
2950915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data);
2951915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		break;
29525449c685a4b39534f18869a93896370224463715Forest Bond
2953915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case IOCTL_CMD_WPA:
29545449c685a4b39534f18869a93896370224463715Forest Bond
2955915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		rc = wpa_ioctl(pDevice, &wrq->u.data);
2956915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		break;
29575449c685a4b39534f18869a93896370224463715Forest Bond
29585449c685a4b39534f18869a93896370224463715Forest Bond	case SIOCETHTOOL:
2959ebc43d093b38262f1fc51018a50892ce3a144852James A Shackleford		return ethtool_ioctl(dev, rq->ifr_data);
2960915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		// All other calls are currently unsupported
29615449c685a4b39534f18869a93896370224463715Forest Bond
29625449c685a4b39534f18869a93896370224463715Forest Bond	default:
29635449c685a4b39534f18869a93896370224463715Forest Bond		rc = -EOPNOTSUPP;
296448caf5a060491edb2e1793539dad72e70c54c869Joe Perches		pr_debug("Ioctl command not support..%x\n", cmd);
2965915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2966915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2967915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2968915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (pDevice->bCommit) {
2969915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2970915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			netif_stop_queue(pDevice->dev);
2971915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_lock_irq(&pDevice->lock);
2972915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL);
2973915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_unlock_irq(&pDevice->lock);
29745e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches		} else {
297548caf5a060491edb2e1793539dad72e70c54c869Joe Perches			pr_debug("Commit the settings\n");
2976915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_lock_irq(&pDevice->lock);
2977915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->bLinkPass = false;
2978915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			memset(pMgmt->abyCurrBSSID, 0, 6);
2979915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pMgmt->eCurrState = WMAC_STATE_IDLE;
2980915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			netif_stop_queue(pDevice->dev);
2981915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2982915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pMgmt->eScanType = WMAC_SCAN_ACTIVE;
29831208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta			if (!pDevice->bWPASuppWextEnabled)
2984915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches#endif
2985915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
2986915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
2987915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			spin_unlock_irq(&pDevice->lock);
2988915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
2989915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		pDevice->bCommit = false;
2990915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
2991915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
2992915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return rc;
29935449c685a4b39534f18869a93896370224463715Forest Bond}
29945449c685a4b39534f18869a93896370224463715Forest Bond
2995ebc43d093b38262f1fc51018a50892ce3a144852James A Shacklefordstatic int ethtool_ioctl(struct net_device *dev, void __user *useraddr)
29965449c685a4b39534f18869a93896370224463715Forest Bond{
29975449c685a4b39534f18869a93896370224463715Forest Bond	u32 ethcmd;
29985449c685a4b39534f18869a93896370224463715Forest Bond
29995449c685a4b39534f18869a93896370224463715Forest Bond	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
30005449c685a4b39534f18869a93896370224463715Forest Bond		return -EFAULT;
30015449c685a4b39534f18869a93896370224463715Forest Bond
3002915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	switch (ethcmd) {
30035449c685a4b39534f18869a93896370224463715Forest Bond	case ETHTOOL_GDRVINFO: {
30045449c685a4b39534f18869a93896370224463715Forest Bond		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
30056b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
30065449c685a4b39534f18869a93896370224463715Forest Bond		strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
30075449c685a4b39534f18869a93896370224463715Forest Bond		strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
30085449c685a4b39534f18869a93896370224463715Forest Bond		if (copy_to_user(useraddr, &info, sizeof(info)))
30095449c685a4b39534f18869a93896370224463715Forest Bond			return -EFAULT;
30105449c685a4b39534f18869a93896370224463715Forest Bond		return 0;
30115449c685a4b39534f18869a93896370224463715Forest Bond	}
30125449c685a4b39534f18869a93896370224463715Forest Bond
3013915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
30145449c685a4b39534f18869a93896370224463715Forest Bond
30155449c685a4b39534f18869a93896370224463715Forest Bond	return -EOPNOTSUPP;
30165449c685a4b39534f18869a93896370224463715Forest Bond}
30175449c685a4b39534f18869a93896370224463715Forest Bond
30185449c685a4b39534f18869a93896370224463715Forest Bond/*------------------------------------------------------------------*/
30195449c685a4b39534f18869a93896370224463715Forest Bond
3020013a468c4504738856d67118492ce7b7fff53a48Charles ClémentMODULE_DEVICE_TABLE(pci, vt6655_pci_id_table);
30215449c685a4b39534f18869a93896370224463715Forest Bond
30225449c685a4b39534f18869a93896370224463715Forest Bondstatic struct pci_driver device_driver = {
302334381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.name = DEVICE_NAME,
302434381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.id_table = vt6655_pci_id_table,
302534381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.probe = vt6655_probe,
302634381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.remove = vt6655_remove,
30275449c685a4b39534f18869a93896370224463715Forest Bond#ifdef CONFIG_PM
302834381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.suspend = viawget_suspend,
302934381c22b0a26ef6663f5fd92574d3f45243cabfPeter Huewe	.resume = viawget_resume,
30305449c685a4b39534f18869a93896370224463715Forest Bond#endif
30315449c685a4b39534f18869a93896370224463715Forest Bond};
30325449c685a4b39534f18869a93896370224463715Forest Bond
3033013a468c4504738856d67118492ce7b7fff53a48Charles Clémentstatic int __init vt6655_init_module(void)
30345449c685a4b39534f18869a93896370224463715Forest Bond{
3035915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int ret;
30365449c685a4b39534f18869a93896370224463715Forest Bond
30375449c685a4b39534f18869a93896370224463715Forest Bond	ret = pci_register_driver(&device_driver);
30385449c685a4b39534f18869a93896370224463715Forest Bond#ifdef CONFIG_PM
3039915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (ret >= 0)
3040915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		register_reboot_notifier(&device_notifier);
30415449c685a4b39534f18869a93896370224463715Forest Bond#endif
30425449c685a4b39534f18869a93896370224463715Forest Bond
3043915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return ret;
30445449c685a4b39534f18869a93896370224463715Forest Bond}
30455449c685a4b39534f18869a93896370224463715Forest Bond
3046013a468c4504738856d67118492ce7b7fff53a48Charles Clémentstatic void __exit vt6655_cleanup_module(void)
30475449c685a4b39534f18869a93896370224463715Forest Bond{
30485449c685a4b39534f18869a93896370224463715Forest Bond#ifdef CONFIG_PM
3049915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	unregister_reboot_notifier(&device_notifier);
30505449c685a4b39534f18869a93896370224463715Forest Bond#endif
3051915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_unregister_driver(&device_driver);
30525449c685a4b39534f18869a93896370224463715Forest Bond}
30535449c685a4b39534f18869a93896370224463715Forest Bond
3054013a468c4504738856d67118492ce7b7fff53a48Charles Clémentmodule_init(vt6655_init_module);
3055013a468c4504738856d67118492ce7b7fff53a48Charles Clémentmodule_exit(vt6655_cleanup_module);
30565449c685a4b39534f18869a93896370224463715Forest Bond
30575449c685a4b39534f18869a93896370224463715Forest Bond#ifdef CONFIG_PM
30585449c685a4b39534f18869a93896370224463715Forest Bondstatic int
30595449c685a4b39534f18869a93896370224463715Forest Bonddevice_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
30605449c685a4b39534f18869a93896370224463715Forest Bond{
3061915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	struct pci_dev *pdev = NULL;
30626b7112719fd48c29f35333ef152a5a450f01dc83Guillaume Clement
3063915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	switch (event) {
3064915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case SYS_DOWN:
3065915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case SYS_HALT:
3066915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	case SYS_POWER_OFF:
3067915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		for_each_pci_dev(pdev) {
3068915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pci_dev_driver(pdev) == &device_driver) {
3069915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				if (pci_get_drvdata(pdev))
3070915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches					viawget_suspend(pdev, PMSG_HIBERNATE);
3071915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
3072915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
3073915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
3074915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return NOTIFY_DONE;
30755449c685a4b39534f18869a93896370224463715Forest Bond}
30765449c685a4b39534f18869a93896370224463715Forest Bond
30775449c685a4b39534f18869a93896370224463715Forest Bondstatic int
3078f408adeb517e1b17102acd889251d5ab60c1fb88Alan Coxviawget_suspend(struct pci_dev *pcid, pm_message_t state)
30795449c685a4b39534f18869a93896370224463715Forest Bond{
3080915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int power_status;   // to silence the compiler
3081915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
30823f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = pci_get_drvdata(pcid);
3083915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject  pMgmt = pDevice->pMgmt;
3084915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
3085915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	netif_stop_queue(pDevice->dev);
3086915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_lock_irq(&pDevice->lock);
3087915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_save_state(pcid);
3088915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	del_timer(&pDevice->sTimerCommand);
3089915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	del_timer(&pMgmt->sTimerSecondCallback);
3090915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
3091915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->uCmdDequeueIdx = 0;
3092915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->uCmdEnqueueIdx = 0;
3093915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bCmdRunning = false;
3094915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACbShutdown(pDevice->PortOffset);
3095915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	MACvSaveContext(pDevice->PortOffset, pDevice->abyMacContext);
3096915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pDevice->bLinkPass = false;
3097915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	memset(pMgmt->abyCurrBSSID, 0, 6);
3098915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pMgmt->eCurrState = WMAC_STATE_IDLE;
3099915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_disable_device(pcid);
3100915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state));
3101915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	spin_unlock_irq(&pDevice->lock);
3102915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
31035449c685a4b39534f18869a93896370224463715Forest Bond}
31045449c685a4b39534f18869a93896370224463715Forest Bond
31055449c685a4b39534f18869a93896370224463715Forest Bondstatic int
31065449c685a4b39534f18869a93896370224463715Forest Bondviawget_resume(struct pci_dev *pcid)
31075449c685a4b39534f18869a93896370224463715Forest Bond{
31083f8597f4e4b39b0505b3891f64d4c3be78d86717Malcolm Priestley	struct vnt_private *pDevice = pci_get_drvdata(pcid);
3109915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	PSMgmtObject  pMgmt = pDevice->pMgmt;
3110915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	int power_status;   // to silence the compiler
3111915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches
31126496c045292b7afe74b5306c123186976f032125Yijing Wang	power_status = pci_set_power_state(pcid, PCI_D0);
31136496c045292b7afe74b5306c123186976f032125Yijing Wang	power_status = pci_enable_wake(pcid, PCI_D0, 0);
3114915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	pci_restore_state(pcid);
3115915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	if (netif_running(pDevice->dev)) {
3116915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_lock_irq(&pDevice->lock);
3117915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
31189f34de35d57c75b769c8ee48ab88ef8bdb7d1bd4Malcolm Priestley		device_init_registers(pDevice);
31191208f14a37fde2669b86bf1b1cd1122ad2ba3579Teodora Baluta		if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
3120915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pMgmt->sNodeDBTable[0].bActive = false;
3121915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			pDevice->bLinkPass = false;
3122915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3123915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				// In Adhoc, BSS state set back to started.
3124915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pMgmt->eCurrState = WMAC_STATE_STARTED;
31255e0cc8a231be82b0ec44cdf2a406b1a97dd3c971Joe Perches			} else {
3126915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pMgmt->eCurrMode = WMAC_MODE_STANDBY;
3127915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches				pMgmt->eCurrState = WMAC_STATE_IDLE;
3128915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches			}
3129915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		}
3130915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		init_timer(&pMgmt->sTimerSecondCallback);
3131915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		init_timer(&pDevice->sTimerCommand);
3132915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
3133915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
3134915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
3135915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
3136915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches		spin_unlock_irq(&pDevice->lock);
3137915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	}
3138915006cddc7979263a0fe1c6cb1369962bfe68f5Joe Perches	return 0;
31395449c685a4b39534f18869a93896370224463715Forest Bond}
31405449c685a4b39534f18869a93896370224463715Forest Bond
31415449c685a4b39534f18869a93896370224463715Forest Bond#endif
3142