aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-29 13:48:48 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-29 13:48:48 -0400
commite389f9aec689209724105ae80a6c91fd2e747bc9 (patch)
tree3cc88a3e785e4f2ffeaa9dad0da695cfa437d4fe
parentf73b0a08eae0e28c50db5dd5ab8245546918bfb6 (diff)
parentb4cf205846463a0a23a917bb18ad833bc9a8c0bb (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (107 commits) smc911x: fix compilation breakage wjen debug is on [netdrvr] eexpress: minor corrections add NAPI support to sb1250-mac.c ixgb: ROUND_UP macro cleanup in drivers/net/ixgb e1000: ROUND_UP macro cleanup in drivers/net/e1000 Generic HDLC sparse annotations e100: Optionally use I/O mode only to access register space e100: allow bad MAC address when running with invalid eeprom csum ehea: fix for dlpar support ehea: fix for sysfs entries 3C509: Remove unnecessary include of <linux/pm_legacy.h> NetXen: Fix for vmalloc issues NetXen: Fixes for Power PC architecture NetXen: Port swap feature for multi port cards NetXen: Removal of redundant macros NetXen: Multi PCI support for Quad cards NetXen: Removal of redundant argument passing NetXen: Use multiple PCI functions [netdrvr e100] experiment with doing RX in a similar manner to eepro100 [PATCH] ieee80211: add missing global needed by IEEE80211_DEBUG_XXXX ...
-rw-r--r--Documentation/DocBook/kernel-api.tmpl6
-rw-r--r--Documentation/networking/bcm43xx.txt97
-rw-r--r--MAINTAINERS20
-rw-r--r--arch/mips/mips-boards/sim/Makefile3
-rw-r--r--arch/mips/mips-boards/sim/sim_platform.c35
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c3
-rw-r--r--crypto/michael_mic.c4
-rw-r--r--drivers/net/3c509.c1
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/chelsio/Makefile4
-rw-r--r--drivers/net/chelsio/common.h6
-rw-r--r--drivers/net/chelsio/cphy.h16
-rw-r--r--drivers/net/chelsio/gmac.h10
-rw-r--r--drivers/net/chelsio/ixf1010.c505
-rw-r--r--drivers/net/chelsio/mac.c2
-rw-r--r--drivers/net/chelsio/mv88e1xxx.c8
-rw-r--r--drivers/net/chelsio/mv88x201x.c8
-rw-r--r--drivers/net/chelsio/my3126.c8
-rw-r--r--drivers/net/chelsio/pm3393.c8
-rw-r--r--drivers/net/chelsio/subr.c199
-rw-r--r--drivers/net/chelsio/vsc7326.c2
-rw-r--r--drivers/net/chelsio/vsc8244.c367
-rw-r--r--drivers/net/chelsio/vsc8244_reg.h172
-rw-r--r--drivers/net/e100.c159
-rw-r--r--drivers/net/e1000/e1000.h3
-rw-r--r--drivers/net/e1000/e1000_ethtool.c34
-rw-r--r--drivers/net/e1000/e1000_main.c45
-rw-r--r--drivers/net/e1000/e1000_param.c4
-rw-r--r--drivers/net/eexpress.c9
-rw-r--r--drivers/net/ehea/ehea.h42
-rw-r--r--drivers/net/ehea/ehea_ethtool.c115
-rw-r--r--drivers/net/ehea/ehea_main.c940
-rw-r--r--drivers/net/ehea/ehea_phyp.c6
-rw-r--r--drivers/net/ehea/ehea_phyp.h6
-rw-r--r--drivers/net/ehea/ehea_qmr.c184
-rw-r--r--drivers/net/ehea/ehea_qmr.h16
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c13
-rw-r--r--drivers/net/ibmveth.c10
-rw-r--r--drivers/net/ixgb/ixgb.h3
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c4
-rw-r--r--drivers/net/ixgb/ixgb_main.c4
-rw-r--r--drivers/net/ixgb/ixgb_param.c8
-rw-r--r--drivers/net/mii.c57
-rw-r--r--drivers/net/mipsnet.c53
-rw-r--r--drivers/net/mv643xx_eth.c59
-rw-r--r--drivers/net/mv643xx_eth.h4
-rw-r--r--drivers/net/netxen/netxen_nic.h189
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c212
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h12
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c401
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h85
-rw-r--r--drivers/net/netxen/netxen_nic_init.c130
-rw-r--r--drivers/net/netxen/netxen_nic_isr.c101
-rw-r--r--drivers/net/netxen/netxen_nic_main.c769
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c168
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h134
-rw-r--r--drivers/net/pcnet32.c159
-rw-r--r--drivers/net/phy/mdio_bus.c19
-rw-r--r--drivers/net/phy/phy.c194
-rw-r--r--drivers/net/phy/phy_device.c114
-rwxr-xr-xdrivers/net/qla3xxx.c371
-rwxr-xr-xdrivers/net/qla3xxx.h33
-rw-r--r--drivers/net/s2io-regs.h2
-rw-r--r--drivers/net/s2io.c78
-rw-r--r--drivers/net/s2io.h8
-rw-r--r--drivers/net/sb1250-mac.c294
-rw-r--r--drivers/net/sgiseeq.c28
-rw-r--r--drivers/net/sk98lin/skge.c20
-rw-r--r--drivers/net/skfp/h/lnkstat.h84
-rw-r--r--drivers/net/skge.c30
-rw-r--r--drivers/net/skge.h10
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/net/tc35815.c2554
-rw-r--r--drivers/net/tulip/dmfe.c118
-rw-r--r--drivers/net/tulip/interrupt.c4
-rw-r--r--drivers/net/tulip/media.c40
-rw-r--r--drivers/net/tulip/tulip.h9
-rw-r--r--drivers/net/tulip/tulip_core.c6
-rw-r--r--drivers/net/tulip/winbond-840.c2
-rw-r--r--drivers/net/ucc_geth.c946
-rw-r--r--drivers/net/ucc_geth.h114
-rw-r--r--drivers/net/ucc_geth_mii.c279
-rw-r--r--drivers/net/ucc_geth_mii.h100
-rw-r--r--drivers/net/ucc_geth_phy.c785
-rw-r--r--drivers/net/ucc_geth_phy.h217
-rw-r--r--drivers/net/wan/hdlc_cisco.c29
-rw-r--r--drivers/net/wan/hdlc_fr.c18
-rw-r--r--drivers/net/wireless/Kconfig13
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/README25
-rw-r--r--drivers/net/wireless/airo.c70
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c23
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.h4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c196
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c9
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c2
-rw-r--r--drivers/net/wireless/ipw2100.c4
-rw-r--r--drivers/net/wireless/ipw2200.c47
-rw-r--r--drivers/net/wireless/libertas/11d.c754
-rw-r--r--drivers/net/wireless/libertas/11d.h105
-rw-r--r--drivers/net/wireless/libertas/LICENSE16
-rw-r--r--drivers/net/wireless/libertas/Makefile21
-rw-r--r--drivers/net/wireless/libertas/README1044
-rw-r--r--drivers/net/wireless/libertas/assoc.c588
-rw-r--r--drivers/net/wireless/libertas/assoc.h30
-rw-r--r--drivers/net/wireless/libertas/cmd.c1958
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c1031
-rw-r--r--drivers/net/wireless/libertas/debugfs.c1935
-rw-r--r--drivers/net/wireless/libertas/debugfs.h6
-rw-r--r--drivers/net/wireless/libertas/decl.h83
-rw-r--r--drivers/net/wireless/libertas/defs.h369
-rw-r--r--drivers/net/wireless/libertas/dev.h403
-rw-r--r--drivers/net/wireless/libertas/ethtool.c184
-rw-r--r--drivers/net/wireless/libertas/fw.c361
-rw-r--r--drivers/net/wireless/libertas/fw.h13
-rw-r--r--drivers/net/wireless/libertas/host.h338
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h693
-rw-r--r--drivers/net/wireless/libertas/if_bootcmd.c38
-rw-r--r--drivers/net/wireless/libertas/if_usb.c952
-rw-r--r--drivers/net/wireless/libertas/if_usb.h109
-rw-r--r--drivers/net/wireless/libertas/ioctl.c2500
-rw-r--r--drivers/net/wireless/libertas/join.c1055
-rw-r--r--drivers/net/wireless/libertas/join.h64
-rw-r--r--drivers/net/wireless/libertas/main.c1258
-rw-r--r--drivers/net/wireless/libertas/radiotap.h57
-rw-r--r--drivers/net/wireless/libertas/rx.c459
-rw-r--r--drivers/net/wireless/libertas/sbi.h40
-rw-r--r--drivers/net/wireless/libertas/scan.c2044
-rw-r--r--drivers/net/wireless/libertas/scan.h216
-rw-r--r--drivers/net/wireless/libertas/thread.h52
-rw-r--r--drivers/net/wireless/libertas/tx.c285
-rw-r--r--drivers/net/wireless/libertas/types.h289
-rw-r--r--drivers/net/wireless/libertas/version.h8
-rw-r--r--drivers/net/wireless/libertas/wext.c2769
-rw-r--r--drivers/net/wireless/libertas/wext.h147
-rw-r--r--drivers/net/wireless/todo.txt15
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c47
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c23
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c18
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h11
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c91
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c317
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c24
-rw-r--r--include/asm-powerpc/ucc_fast.h3
-rw-r--r--include/linux/fsl_devices.h39
-rw-r--r--include/linux/hdlc.h3
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/phy.h1
-rw-r--r--include/linux/wireless.h2
-rw-r--r--include/net/ieee80211.h4
-rw-r--r--include/net/ieee80211_crypt.h4
-rw-r--r--include/net/ieee80211_radiotap.h77
-rw-r--r--net/ieee80211/ieee80211_crypt.c2
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c4
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c6
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c2
-rw-r--r--net/ieee80211/ieee80211_module.c5
-rw-r--r--net/ieee80211/ieee80211_rx.c4
-rw-r--r--net/ieee80211/ieee80211_wx.c4
170 files changed, 29413 insertions, 6144 deletions
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 0bb90237e230..b61dfc79e1b8 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -236,6 +236,12 @@ X!Ilib/string.c
236!Enet/core/dev.c 236!Enet/core/dev.c
237!Enet/ethernet/eth.c 237!Enet/ethernet/eth.c
238!Iinclude/linux/etherdevice.h 238!Iinclude/linux/etherdevice.h
239!Edrivers/net/phy/phy.c
240!Idrivers/net/phy/phy.c
241!Edrivers/net/phy/phy_device.c
242!Idrivers/net/phy/phy_device.c
243!Edrivers/net/phy/mdio_bus.c
244!Idrivers/net/phy/mdio_bus.c
239<!-- FIXME: Removed for now since no structured comments in source 245<!-- FIXME: Removed for now since no structured comments in source
240X!Enet/core/wireless.c 246X!Enet/core/wireless.c
241--> 247-->
diff --git a/Documentation/networking/bcm43xx.txt b/Documentation/networking/bcm43xx.txt
index 28541d2bee1e..a136721499bf 100644
--- a/Documentation/networking/bcm43xx.txt
+++ b/Documentation/networking/bcm43xx.txt
@@ -2,35 +2,88 @@
2 BCM43xx Linux Driver Project 2 BCM43xx Linux Driver Project
3 ============================ 3 ============================
4 4
5About this software 5Introduction
6------------------- 6------------
7 7
8The goal of this project is to develop a linux driver for Broadcom 8Many of the wireless devices found in modern notebook computers are
9BCM43xx chips, based on the specification at 9based on the wireless chips produced by Broadcom. These devices have
10http://bcm-specs.sipsolutions.net/ 10been a problem for Linux users as there is no open-source driver
11available. In addition, Broadcom has not released specifications
12for the device, and driver availability has been limited to the
13binary-only form used in the GPL versions of AP hardware such as the
14Linksys WRT54G, and the Windows and OS X drivers. Before this project
15began, the only way to use these devices were to use the Windows or
16OS X drivers with either the Linuxant or ndiswrapper modules. There
17is a strong penalty if this method is used as loading the binary-only
18module "taints" the kernel, and no kernel developer will help diagnose
19any kernel problems.
11 20
12The project page is http://bcm43xx.berlios.de/ 21Development
22-----------
13 23
24This driver has been developed using
25a clean-room technique that is described at
26http://bcm-specs.sipsolutions.net/ReverseEngineeringProcess. For legal
27reasons, none of the clean-room crew works on the on the Linux driver,
28and none of the Linux developers sees anything but the specifications,
29which are the ultimate product of the reverse-engineering group.
14 30
15Requirements 31Software
16------------ 32--------
33
34Since the release of the 2.6.17 kernel, the bcm43xx driver has been
35distributed with the kernel source, and is prebuilt in most, if not
36all, distributions. There is, however, additional software that is
37required. The firmware used by the chip is the intellectual property
38of Broadcom and they have not given the bcm43xx team redistribution
39rights to this firmware. Since we cannot legally redistribute
40the firwmare we cannot include it with the driver. Furthermore, it
41cannot be placed in the downloadable archives of any distributing
42organization; therefore, the user is responsible for obtaining the
43firmware and placing it in the appropriate location so that the driver
44can find it when initializing.
45
46To help with this process, the bcm43xx developers provide a separate
47program named bcm43xx-fwcutter to "cut" the firmware out of a
48Windows or OS X driver and write the extracted files to the proper
49location. This program is usually provided with the distribution;
50however, it may be downloaded from
51
52http://developer.berlios.de/project/showfiles.php?group_id=4547
17 53
181) Linux Kernel 2.6.16 or later 54The firmware is available in two versions. V3 firmware is used with
19 http://www.kernel.org/ 55the in-kernel bcm43xx driver that uses a software MAC layer called
56SoftMAC, and will have a microcode revision of 0x127 or smaller. The
57V4 firmware is used by an out-of-kernel driver employing a variation of
58the Devicescape MAC layer known as d80211. Once bcm43xx-d80211 reaches
59a satisfactory level of development, it will replace bcm43xx-softmac
60in the kernel as it is much more flexible and powerful.
20 61
21 You may want to configure your kernel with: 62A source for the latest V3 firmware is
22 63
23 CONFIG_DEBUG_FS (optional): 64http://downloads.openwrt.org/sources/wl_apsta-3.130.20.0.o
24 -> Kernel hacking
25 -> Debug Filesystem
26 65
272) SoftMAC IEEE 802.11 Networking Stack extension and patched ieee80211 66Once this file is downloaded, the command
28 modules: 67'bcm43xx-fwcutter -w <dir> <filename>'
29 http://softmac.sipsolutions.net/ 68will extract the microcode and write it to directory
69<dir>. The correct directory will depend on your distribution;
70however, most use '/lib/firmware'. Once this step is completed,
71the bcm3xx driver should load when the system is booted. To see
72any messages relating to the driver, issue the command 'dmesg |
73grep bcm43xx' from a terminal window. If there are any problems,
74please send that output to Bcm43xx-dev@lists.berlios.de.
30 75
313) Firmware Files 76Although the driver has been in-kernel since 2.6.17, the earliest
77version is quite limited in its capability. Patches that include
78all features of later versions are available for the stable kernel
79versions from 2.6.18. These will be needed if you use a BCM4318,
80or a PCI Express version (BCM4311 and BCM4312). In addition, if you
81have an early BCM4306 and more than 1 GB RAM, your kernel will need
82to be patched. These patches, which are being updated regularly,
83are available at ftp://lwfinger.dynalias.org/patches. Look for
84combined_2.6.YY.patch. Of course you will need kernel source downloaded
85from kernel.org, or the source from your distribution.
32 86
33 Please try fwcutter. Fwcutter can extract the firmware from various 87If you build your own kernel, please enable CONFIG_BCM43XX_DEBUG
34 binary driver files. It supports driver files from Windows, MacOS and 88and CONFIG_IEEE80211_SOFTMAC_DEBUG. The log information provided is
35 Linux. You can get fwcutter from http://bcm43xx.berlios.de/. 89essential for solving any problems.
36 Also, fwcutter comes with a README file for further instructions.
diff --git a/MAINTAINERS b/MAINTAINERS
index 993e2a69440e..af1c7926c153 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1582,9 +1582,9 @@ S: Supported
1582 1582
1583HOST AP DRIVER 1583HOST AP DRIVER
1584P: Jouni Malinen 1584P: Jouni Malinen
1585M: jkmaline@cc.hut.fi 1585M: j@w1.fi
1586L: hostap@shmoo.com (subscribers-only)
1586L: linux-wireless@vger.kernel.org 1587L: linux-wireless@vger.kernel.org
1587L: hostap@shmoo.com
1588W: http://hostap.epitest.fi/ 1588W: http://hostap.epitest.fi/
1589S: Maintained 1589S: Maintained
1590 1590
@@ -1811,6 +1811,7 @@ P: Jeff Kirsher
1811M: jeffrey.t.kirsher@intel.com 1811M: jeffrey.t.kirsher@intel.com
1812P: Auke Kok 1812P: Auke Kok
1813M: auke-jan.h.kok@intel.com 1813M: auke-jan.h.kok@intel.com
1814L: e1000-devel@lists.sourceforge.net
1814W: http://sourceforge.net/projects/e1000/ 1815W: http://sourceforge.net/projects/e1000/
1815S: Supported 1816S: Supported
1816 1817
@@ -1825,6 +1826,7 @@ P: Jeff Kirsher
1825M: jeffrey.t.kirsher@intel.com 1826M: jeffrey.t.kirsher@intel.com
1826P: Auke Kok 1827P: Auke Kok
1827M: auke-jan.h.kok@intel.com 1828M: auke-jan.h.kok@intel.com
1829L: e1000-devel@lists.sourceforge.net
1828W: http://sourceforge.net/projects/e1000/ 1830W: http://sourceforge.net/projects/e1000/
1829S: Supported 1831S: Supported
1830 1832
@@ -1839,6 +1841,7 @@ P: Jesse Brandeburg
1839M: jesse.brandeburg@intel.com 1841M: jesse.brandeburg@intel.com
1840P: Auke Kok 1842P: Auke Kok
1841M: auke-jan.h.kok@intel.com 1843M: auke-jan.h.kok@intel.com
1844L: e1000-devel@lists.sourceforge.net
1842W: http://sourceforge.net/projects/e1000/ 1845W: http://sourceforge.net/projects/e1000/
1843S: Supported 1846S: Supported
1844 1847
@@ -2500,6 +2503,19 @@ M: adaplas@gmail.com
2500L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) 2503L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
2501S: Maintained 2504S: Maintained
2502 2505
2506NETERION (S2IO) Xframe 10GbE DRIVER
2507P: Ramkrishna Vepa
2508M: ram.vepa@neterion.com
2509P: Rastapur Santosh
2510M: santosh.rastapur@neterion.com
2511P: Sivakumar Subramani
2512M: sivakumar.subramani@neterion.com
2513P: Sreenivasa Honnur
2514M: sreenivasa.honnur@neterion.com
2515L: netdev@vger.kernel.org
2516W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/TitleIndex?anonymous
2517S: Supported
2518
2503OPENCORES I2C BUS DRIVER 2519OPENCORES I2C BUS DRIVER
2504P: Peter Korsgaard 2520P: Peter Korsgaard
2505M: jacmet@sunsite.dk 2521M: jacmet@sunsite.dk
diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile
index 6aeebc9122f2..dc0bfda11427 100644
--- a/arch/mips/mips-boards/sim/Makefile
+++ b/arch/mips/mips-boards/sim/Makefile
@@ -17,7 +17,8 @@
17# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
18# 18#
19 19
20obj-y := sim_setup.o sim_mem.o sim_time.o sim_int.o sim_cmdline.o 20obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \
21 sim_cmdline.o
21 22
22obj-$(CONFIG_EARLY_PRINTK) += sim_console.o 23obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
23obj-$(CONFIG_SMP) += sim_smp.o 24obj-$(CONFIG_SMP) += sim_smp.o
diff --git a/arch/mips/mips-boards/sim/sim_platform.c b/arch/mips/mips-boards/sim/sim_platform.c
new file mode 100644
index 000000000000..53210a8c5dec
--- /dev/null
+++ b/arch/mips/mips-boards/sim/sim_platform.c
@@ -0,0 +1,35 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 by Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/init.h>
9#include <linux/if_ether.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12
13static char mipsnet_string[] = "mipsnet";
14
15static struct platform_device eth1_device = {
16 .name = mipsnet_string,
17 .id = 0,
18};
19
20/*
21 * Create a platform device for the GPI port that receives the
22 * image data from the embedded camera.
23 */
24static int __init mipsnet_devinit(void)
25{
26 int err;
27
28 err = platform_device_register(&eth1_device);
29 if (err)
30 printk(KERN_ERR "%s: registration failed\n", mipsnet_string);
31
32 return err;
33}
34
35device_initcall(mipsnet_devinit);
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index a457ac1c6639..66137bf2dfb0 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -210,6 +210,9 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
210 uf_regs = uccf->uf_regs; 210 uf_regs = uccf->uf_regs;
211 uccf->p_ucce = (u32 *) & (uf_regs->ucce); 211 uccf->p_ucce = (u32 *) & (uf_regs->ucce);
212 uccf->p_uccm = (u32 *) & (uf_regs->uccm); 212 uccf->p_uccm = (u32 *) & (uf_regs->uccm);
213#ifdef CONFIG_UGETH_TX_ON_DEMAND
214 uccf->p_utodr = (u16 *) & (uf_regs->utodr);
215#endif
213#ifdef STATISTICS 216#ifdef STATISTICS
214 uccf->tx_frames = 0; 217 uccf->tx_frames = 0;
215 uccf->rx_frames = 0; 218 uccf->rx_frames = 0;
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
index 094397b48849..9e917b8011b1 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Michael MIC (IEEE 802.11i/TKIP) keyed digest 4 * Michael MIC (IEEE 802.11i/TKIP) keyed digest
5 * 5 *
6 * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> 6 * Copyright (c) 2004 Jouni Malinen <j@w1.fi>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -173,4 +173,4 @@ module_exit(michael_mic_exit);
173 173
174MODULE_LICENSE("GPL v2"); 174MODULE_LICENSE("GPL v2");
175MODULE_DESCRIPTION("Michael MIC"); 175MODULE_DESCRIPTION("Michael MIC");
176MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); 176MODULE_AUTHOR("Jouni Malinen <j@w1.fi>");
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index c7511c4d3b68..9588da3a30e7 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -83,7 +83,6 @@ static int max_interrupt_work = 10;
83#include <linux/netdevice.h> 83#include <linux/netdevice.h>
84#include <linux/etherdevice.h> 84#include <linux/etherdevice.h>
85#include <linux/pm.h> 85#include <linux/pm.h>
86#include <linux/pm_legacy.h>
87#include <linux/skbuff.h> 86#include <linux/skbuff.h>
88#include <linux/delay.h> /* for udelay() */ 87#include <linux/delay.h> /* for udelay() */
89#include <linux/spinlock.h> 88#include <linux/spinlock.h>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a3d46ea37126..545c405a5cb0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -486,8 +486,8 @@ config SGI_IOC3_ETH_HW_TX_CSUM
486 enables offloading for checksums on transmit. If unsure, say Y. 486 enables offloading for checksums on transmit. If unsure, say Y.
487 487
488config MIPS_SIM_NET 488config MIPS_SIM_NET
489 tristate "MIPS simulator Network device (EXPERIMENTAL)" 489 tristate "MIPS simulator Network device"
490 depends on MIPS_SIM && EXPERIMENTAL 490 depends on NET_ETHERNET && MIPS_SIM
491 help 491 help
492 The MIPSNET device is a simple Ethernet network device which is 492 The MIPSNET device is a simple Ethernet network device which is
493 emulated by the MIPS Simulator. 493 emulated by the MIPS Simulator.
@@ -1444,7 +1444,8 @@ config CS89x0
1444 1444
1445config TC35815 1445config TC35815
1446 tristate "TOSHIBA TC35815 Ethernet support" 1446 tristate "TOSHIBA TC35815 Ethernet support"
1447 depends on NET_PCI && PCI && TOSHIBA_JMR3927 1447 depends on NET_PCI && PCI && MIPS
1448 select MII
1448 1449
1449config DGRS 1450config DGRS
1450 tristate "Digi Intl. RightSwitch SE-X support" 1451 tristate "Digi Intl. RightSwitch SE-X support"
@@ -2291,14 +2292,10 @@ config UGETH_FILTERING
2291 bool "Mac address filtering support" 2292 bool "Mac address filtering support"
2292 depends on UCC_GETH 2293 depends on UCC_GETH
2293 2294
2294config UGETH_TX_ON_DEMOND 2295config UGETH_TX_ON_DEMAND
2295 bool "Transmit on Demond support" 2296 bool "Transmit on Demand support"
2296 depends on UCC_GETH 2297 depends on UCC_GETH
2297 2298
2298config UGETH_HAS_GIGA
2299 bool
2300 depends on UCC_GETH && PPC_MPC836x
2301
2302config MV643XX_ETH 2299config MV643XX_ETH
2303 tristate "MV-643XX Ethernet support" 2300 tristate "MV-643XX Ethernet support"
2304 depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) 2301 depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 58527322a39d..59c0459a037c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -18,7 +18,7 @@ gianfar_driver-objs := gianfar.o \
18 gianfar_sysfs.o 18 gianfar_sysfs.o
19 19
20obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o 20obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
21ucc_geth_driver-objs := ucc_geth.o ucc_geth_phy.o 21ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o
22 22
23# 23#
24# link order important here 24# link order important here
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile
index 382d23f810ab..743ad8b41b5e 100644
--- a/drivers/net/chelsio/Makefile
+++ b/drivers/net/chelsio/Makefile
@@ -4,8 +4,6 @@
4 4
5obj-$(CONFIG_CHELSIO_T1) += cxgb.o 5obj-$(CONFIG_CHELSIO_T1) += cxgb.o
6 6
7cxgb-$(CONFIG_CHELSIO_T1_1G) += ixf1010.o mac.o mv88e1xxx.o vsc7326.o vsc8244.o 7cxgb-$(CONFIG_CHELSIO_T1_1G) += mac.o mv88e1xxx.o vsc7326.o
8cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \ 8cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \
9 mv88x201x.o my3126.o $(cxgb-y) 9 mv88x201x.o my3126.o $(cxgb-y)
10
11
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 787f2f2820fe..8ba702c8b560 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -322,9 +322,9 @@ struct board_info {
322 unsigned char mdio_mdiinv; 322 unsigned char mdio_mdiinv;
323 unsigned char mdio_mdc; 323 unsigned char mdio_mdc;
324 unsigned char mdio_phybaseaddr; 324 unsigned char mdio_phybaseaddr;
325 struct gmac *gmac; 325 const struct gmac *gmac;
326 struct gphy *gphy; 326 const struct gphy *gphy;
327 struct mdio_ops *mdio_ops; 327 const struct mdio_ops *mdio_ops;
328 const char *desc; 328 const char *desc;
329}; 329};
330 330
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
index cf9143499882..79d855e267e0 100644
--- a/drivers/net/chelsio/cphy.h
+++ b/drivers/net/chelsio/cphy.h
@@ -100,7 +100,7 @@ struct cphy {
100 100
101 u32 elmer_gpo; 101 u32 elmer_gpo;
102 102
103 struct cphy_ops *ops; /* PHY operations */ 103 const struct cphy_ops *ops; /* PHY operations */
104 int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr, 104 int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
105 int reg_addr, unsigned int *val); 105 int reg_addr, unsigned int *val);
106 int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr, 106 int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
@@ -136,7 +136,7 @@ static inline int simple_mdio_write(struct cphy *cphy, int reg,
136/* Convenience initializer */ 136/* Convenience initializer */
137static inline void cphy_init(struct cphy *phy, adapter_t *adapter, 137static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
138 int phy_addr, struct cphy_ops *phy_ops, 138 int phy_addr, struct cphy_ops *phy_ops,
139 struct mdio_ops *mdio_ops) 139 const struct mdio_ops *mdio_ops)
140{ 140{
141 phy->adapter = adapter; 141 phy->adapter = adapter;
142 phy->addr = phy_addr; 142 phy->addr = phy_addr;
@@ -151,7 +151,7 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
151struct gphy { 151struct gphy {
152 /* Construct a PHY instance with the given PHY address */ 152 /* Construct a PHY instance with the given PHY address */
153 struct cphy *(*create)(adapter_t *adapter, int phy_addr, 153 struct cphy *(*create)(adapter_t *adapter, int phy_addr,
154 struct mdio_ops *mdio_ops); 154 const struct mdio_ops *mdio_ops);
155 155
156 /* 156 /*
157 * Reset the PHY chip. This resets the whole PHY chip, not individual 157 * Reset the PHY chip. This resets the whole PHY chip, not individual
@@ -160,11 +160,9 @@ struct gphy {
160 int (*reset)(adapter_t *adapter); 160 int (*reset)(adapter_t *adapter);
161}; 161};
162 162
163extern struct gphy t1_my3126_ops; 163extern const struct gphy t1_my3126_ops;
164extern struct gphy t1_mv88e1xxx_ops; 164extern const struct gphy t1_mv88e1xxx_ops;
165extern struct gphy t1_vsc8244_ops; 165extern const struct gphy t1_vsc8244_ops;
166extern struct gphy t1_xpak_ops; 166extern const struct gphy t1_mv88x201x_ops;
167extern struct gphy t1_mv88x201x_ops;
168extern struct gphy t1_dummy_phy_ops;
169 167
170#endif /* _CXGB_CPHY_H_ */ 168#endif /* _CXGB_CPHY_H_ */
diff --git a/drivers/net/chelsio/gmac.h b/drivers/net/chelsio/gmac.h
index 006a2eb2d362..d42337457cf7 100644
--- a/drivers/net/chelsio/gmac.h
+++ b/drivers/net/chelsio/gmac.h
@@ -126,7 +126,7 @@ typedef struct _cmac_instance cmac_instance;
126struct cmac { 126struct cmac {
127 struct cmac_statistics stats; 127 struct cmac_statistics stats;
128 adapter_t *adapter; 128 adapter_t *adapter;
129 struct cmac_ops *ops; 129 const struct cmac_ops *ops;
130 cmac_instance *instance; 130 cmac_instance *instance;
131}; 131};
132 132
@@ -136,11 +136,7 @@ struct gmac {
136 int (*reset)(adapter_t *); 136 int (*reset)(adapter_t *);
137}; 137};
138 138
139extern struct gmac t1_pm3393_ops; 139extern const struct gmac t1_pm3393_ops;
140extern struct gmac t1_chelsio_mac_ops; 140extern const struct gmac t1_vsc7326_ops;
141extern struct gmac t1_vsc7321_ops;
142extern struct gmac t1_vsc7326_ops;
143extern struct gmac t1_ixf1010_ops;
144extern struct gmac t1_dummy_mac_ops;
145 141
146#endif /* _CXGB_GMAC_H_ */ 142#endif /* _CXGB_GMAC_H_ */
diff --git a/drivers/net/chelsio/ixf1010.c b/drivers/net/chelsio/ixf1010.c
deleted file mode 100644
index 10b2a9a19006..000000000000
--- a/drivers/net/chelsio/ixf1010.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/* $Date: 2005/11/12 02:13:49 $ $RCSfile: ixf1010.c,v $ $Revision: 1.36 $ */
2#include "gmac.h"
3#include "elmer0.h"
4
5/* Update fast changing statistics every 15 seconds */
6#define STATS_TICK_SECS 15
7/* 30 minutes for full statistics update */
8#define MAJOR_UPDATE_TICKS (1800 / STATS_TICK_SECS)
9
10/*
11 * The IXF1010 can handle frames up to 16383 bytes but it's optimized for
12 * frames up to 9831 (0x2667) bytes, so we limit jumbo frame size to this.
13 * This length includes ethernet header and FCS.
14 */
15#define MAX_FRAME_SIZE 0x2667
16
17/* MAC registers */
18enum {
19 /* Per-port registers */
20 REG_MACADDR_LOW = 0,
21 REG_MACADDR_HIGH = 0x4,
22 REG_FDFC_TYPE = 0xC,
23 REG_FC_TX_TIMER_VALUE = 0x1c,
24 REG_IPG_RX_TIME1 = 0x28,
25 REG_IPG_RX_TIME2 = 0x2c,
26 REG_IPG_TX_TIME = 0x30,
27 REG_PAUSE_THRES = 0x38,
28 REG_MAX_FRAME_SIZE = 0x3c,
29 REG_RGMII_SPEED = 0x40,
30 REG_FC_ENABLE = 0x48,
31 REG_DISCARD_CTRL_FRAMES = 0x54,
32 REG_DIVERSE_CONFIG = 0x60,
33 REG_RX_FILTER = 0x64,
34 REG_MC_ADDR_LOW = 0x68,
35 REG_MC_ADDR_HIGH = 0x6c,
36
37 REG_RX_OCTETS_OK = 0x80,
38 REG_RX_OCTETS_BAD = 0x84,
39 REG_RX_UC_PKTS = 0x88,
40 REG_RX_MC_PKTS = 0x8c,
41 REG_RX_BC_PKTS = 0x90,
42 REG_RX_FCS_ERR = 0xb0,
43 REG_RX_TAGGED = 0xb4,
44 REG_RX_DATA_ERR = 0xb8,
45 REG_RX_ALIGN_ERR = 0xbc,
46 REG_RX_LONG_ERR = 0xc0,
47 REG_RX_JABBER_ERR = 0xc4,
48 REG_RX_PAUSE_FRAMES = 0xc8,
49 REG_RX_UNKNOWN_CTRL_FRAMES = 0xcc,
50 REG_RX_VERY_LONG_ERR = 0xd0,
51 REG_RX_RUNT_ERR = 0xd4,
52 REG_RX_SHORT_ERR = 0xd8,
53 REG_RX_SYMBOL_ERR = 0xe4,
54
55 REG_TX_OCTETS_OK = 0x100,
56 REG_TX_OCTETS_BAD = 0x104,
57 REG_TX_UC_PKTS = 0x108,
58 REG_TX_MC_PKTS = 0x10c,
59 REG_TX_BC_PKTS = 0x110,
60 REG_TX_EXCESSIVE_LEN_DROP = 0x14c,
61 REG_TX_UNDERRUN = 0x150,
62 REG_TX_TAGGED = 0x154,
63 REG_TX_PAUSE_FRAMES = 0x15C,
64
65 /* Global registers */
66 REG_PORT_ENABLE = 0x1400,
67
68 REG_JTAG_ID = 0x1430,
69
70 RX_FIFO_HIGH_WATERMARK_BASE = 0x1600,
71 RX_FIFO_LOW_WATERMARK_BASE = 0x1628,
72 RX_FIFO_FRAMES_REMOVED_BASE = 0x1650,
73
74 REG_RX_ERR_DROP = 0x167c,
75 REG_RX_FIFO_OVERFLOW_EVENT = 0x1680,
76
77 TX_FIFO_HIGH_WATERMARK_BASE = 0x1800,
78 TX_FIFO_LOW_WATERMARK_BASE = 0x1828,
79 TX_FIFO_XFER_THRES_BASE = 0x1850,
80
81 REG_TX_FIFO_OVERFLOW_EVENT = 0x1878,
82 REG_TX_FIFO_OOS_EVENT = 0x1884,
83
84 TX_FIFO_FRAMES_REMOVED_BASE = 0x1888,
85
86 REG_SPI_RX_BURST = 0x1c00,
87 REG_SPI_RX_TRAINING = 0x1c04,
88 REG_SPI_RX_CALENDAR = 0x1c08,
89 REG_SPI_TX_SYNC = 0x1c0c
90};
91
92enum { /* RMON registers */
93 REG_RxOctetsTotalOK = 0x80,
94 REG_RxOctetsBad = 0x84,
95 REG_RxUCPkts = 0x88,
96 REG_RxMCPkts = 0x8c,
97 REG_RxBCPkts = 0x90,
98 REG_RxJumboPkts = 0xac,
99 REG_RxFCSErrors = 0xb0,
100 REG_RxDataErrors = 0xb8,
101 REG_RxAlignErrors = 0xbc,
102 REG_RxLongErrors = 0xc0,
103 REG_RxJabberErrors = 0xc4,
104 REG_RxPauseMacControlCounter = 0xc8,
105 REG_RxVeryLongErrors = 0xd0,
106 REG_RxRuntErrors = 0xd4,
107 REG_RxShortErrors = 0xd8,
108 REG_RxSequenceErrors = 0xe0,
109 REG_RxSymbolErrors = 0xe4,
110
111 REG_TxOctetsTotalOK = 0x100,
112 REG_TxOctetsBad = 0x104,
113 REG_TxUCPkts = 0x108,
114 REG_TxMCPkts = 0x10c,
115 REG_TxBCPkts = 0x110,
116 REG_TxJumboPkts = 0x12C,
117 REG_TxTotalCollisions = 0x134,
118 REG_TxExcessiveLengthDrop = 0x14c,
119 REG_TxUnderrun = 0x150,
120 REG_TxCRCErrors = 0x158,
121 REG_TxPauseFrames = 0x15c
122};
123
124enum {
125 DIVERSE_CONFIG_PAD_ENABLE = 0x80,
126 DIVERSE_CONFIG_CRC_ADD = 0x40
127};
128
129#define MACREG_BASE 0
130#define MACREG(mac, mac_reg) ((mac)->instance->mac_base + (mac_reg))
131
132struct _cmac_instance {
133 u32 mac_base;
134 u32 index;
135 u32 version;
136 u32 ticks;
137};
138
139static void disable_port(struct cmac *mac)
140{
141 u32 val;
142
143 t1_tpi_read(mac->adapter, REG_PORT_ENABLE, &val);
144 val &= ~(1 << mac->instance->index);
145 t1_tpi_write(mac->adapter, REG_PORT_ENABLE, val);
146}
147
148/*
149 * Read the current values of the RMON counters and add them to the cumulative
150 * port statistics. The HW RMON counters are cleared by this operation.
151 */
152static void port_stats_update(struct cmac *mac)
153{
154 static struct {
155 unsigned int reg;
156 unsigned int offset;
157 } hw_stats[] = {
158
159#define HW_STAT(name, stat_name) \
160 { REG_##name, \
161 (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL }
162
163 /* Rx stats */
164 HW_STAT(RxOctetsTotalOK, RxOctetsOK),
165 HW_STAT(RxOctetsBad, RxOctetsBad),
166 HW_STAT(RxUCPkts, RxUnicastFramesOK),
167 HW_STAT(RxMCPkts, RxMulticastFramesOK),
168 HW_STAT(RxBCPkts, RxBroadcastFramesOK),
169 HW_STAT(RxJumboPkts, RxJumboFramesOK),
170 HW_STAT(RxFCSErrors, RxFCSErrors),
171 HW_STAT(RxAlignErrors, RxAlignErrors),
172 HW_STAT(RxLongErrors, RxFrameTooLongErrors),
173 HW_STAT(RxVeryLongErrors, RxFrameTooLongErrors),
174 HW_STAT(RxPauseMacControlCounter, RxPauseFrames),
175 HW_STAT(RxDataErrors, RxDataErrors),
176 HW_STAT(RxJabberErrors, RxJabberErrors),
177 HW_STAT(RxRuntErrors, RxRuntErrors),
178 HW_STAT(RxShortErrors, RxRuntErrors),
179 HW_STAT(RxSequenceErrors, RxSequenceErrors),
180 HW_STAT(RxSymbolErrors, RxSymbolErrors),
181
182 /* Tx stats (skip collision stats as we are full-duplex only) */
183 HW_STAT(TxOctetsTotalOK, TxOctetsOK),
184 HW_STAT(TxOctetsBad, TxOctetsBad),
185 HW_STAT(TxUCPkts, TxUnicastFramesOK),
186 HW_STAT(TxMCPkts, TxMulticastFramesOK),
187 HW_STAT(TxBCPkts, TxBroadcastFramesOK),
188 HW_STAT(TxJumboPkts, TxJumboFramesOK),
189 HW_STAT(TxPauseFrames, TxPauseFrames),
190 HW_STAT(TxExcessiveLengthDrop, TxLengthErrors),
191 HW_STAT(TxUnderrun, TxUnderrun),
192 HW_STAT(TxCRCErrors, TxFCSErrors)
193 }, *p = hw_stats;
194 u64 *stats = (u64 *) &mac->stats;
195 unsigned int i;
196
197 for (i = 0; i < ARRAY_SIZE(hw_stats); i++) {
198 u32 val;
199
200 t1_tpi_read(mac->adapter, MACREG(mac, p->reg), &val);
201 stats[p->offset] += val;
202 }
203}
204
205/* No-op interrupt operation as this MAC does not support interrupts */
206static int mac_intr_op(struct cmac *mac)
207{
208 return 0;
209}
210
211/* Expect MAC address to be in network byte order. */
212static int mac_set_address(struct cmac *mac, u8 addr[6])
213{
214 u32 addr_lo, addr_hi;
215
216 addr_lo = addr[2];
217 addr_lo = (addr_lo << 8) | addr[3];
218 addr_lo = (addr_lo << 8) | addr[4];
219 addr_lo = (addr_lo << 8) | addr[5];
220
221 addr_hi = addr[0];
222 addr_hi = (addr_hi << 8) | addr[1];
223
224 t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_LOW), addr_lo);
225 t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), addr_hi);
226 return 0;
227}
228
229static int mac_get_address(struct cmac *mac, u8 addr[6])
230{
231 u32 addr_lo, addr_hi;
232
233 t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_LOW), &addr_lo);
234 t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), &addr_hi);
235
236 addr[0] = (u8) (addr_hi >> 8);
237 addr[1] = (u8) addr_hi;
238 addr[2] = (u8) (addr_lo >> 24);
239 addr[3] = (u8) (addr_lo >> 16);
240 addr[4] = (u8) (addr_lo >> 8);
241 addr[5] = (u8) addr_lo;
242 return 0;
243}
244
245/* This is intended to reset a port, not the whole MAC */
246static int mac_reset(struct cmac *mac)
247{
248 return 0;
249}
250
251static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
252{
253 u32 val, new_mode;
254 adapter_t *adapter = mac->adapter;
255 u32 addr_lo, addr_hi;
256 u8 *addr;
257
258 t1_tpi_read(adapter, MACREG(mac, REG_RX_FILTER), &val);
259 new_mode = val & ~7;
260 if (!t1_rx_mode_promisc(rm) && mac->instance->version > 0)
261 new_mode |= 1; /* only set if version > 0 due to erratum */
262 if (!t1_rx_mode_promisc(rm) && !t1_rx_mode_allmulti(rm)
263 && t1_rx_mode_mc_cnt(rm) <= 1)
264 new_mode |= 2;
265 if (new_mode != val)
266 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), new_mode);
267 switch (t1_rx_mode_mc_cnt(rm)) {
268 case 0:
269 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), 0);
270 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), 0);
271 break;
272 case 1:
273 addr = t1_get_next_mcaddr(rm);
274 addr_lo = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
275 addr[5];
276 addr_hi = (addr[0] << 8) | addr[1];
277 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), addr_lo);
278 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), addr_hi);
279 break;
280 default:
281 break;
282 }
283 return 0;
284}
285
286static int mac_set_mtu(struct cmac *mac, int mtu)
287{
288 /* MAX_FRAME_SIZE inludes header + FCS, mtu doesn't */
289 if (mtu > (MAX_FRAME_SIZE - 14 - 4))
290 return -EINVAL;
291 t1_tpi_write(mac->adapter, MACREG(mac, REG_MAX_FRAME_SIZE),
292 mtu + 14 + 4);
293 return 0;
294}
295
296static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
297 int fc)
298{
299 u32 val;
300
301 if (speed >= 0 && speed != SPEED_100 && speed != SPEED_1000)
302 return -1;
303 if (duplex >= 0 && duplex != DUPLEX_FULL)
304 return -1;
305
306 if (speed >= 0) {
307 val = speed == SPEED_100 ? 1 : 2;
308 t1_tpi_write(mac->adapter, MACREG(mac, REG_RGMII_SPEED), val);
309 }
310
311 t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
312 val &= ~3;
313 if (fc & PAUSE_RX)
314 val |= 1;
315 if (fc & PAUSE_TX)
316 val |= 2;
317 t1_tpi_write(mac->adapter, MACREG(mac, REG_FC_ENABLE), val);
318 return 0;
319}
320
321static int mac_get_speed_duplex_fc(struct cmac *mac, int *speed, int *duplex,
322 int *fc)
323{
324 u32 val;
325
326 if (duplex)
327 *duplex = DUPLEX_FULL;
328 if (speed) {
329 t1_tpi_read(mac->adapter, MACREG(mac, REG_RGMII_SPEED),
330 &val);
331 *speed = (val & 2) ? SPEED_1000 : SPEED_100;
332 }
333 if (fc) {
334 t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
335 *fc = 0;
336 if (val & 1)
337 *fc |= PAUSE_RX;
338 if (val & 2)
339 *fc |= PAUSE_TX;
340 }
341 return 0;
342}
343
344static void enable_port(struct cmac *mac)
345{
346 u32 val;
347 u32 index = mac->instance->index;
348 adapter_t *adapter = mac->adapter;
349
350 t1_tpi_read(adapter, MACREG(mac, REG_DIVERSE_CONFIG), &val);
351 val |= DIVERSE_CONFIG_CRC_ADD | DIVERSE_CONFIG_PAD_ENABLE;
352 t1_tpi_write(adapter, MACREG(mac, REG_DIVERSE_CONFIG), val);
353 if (mac->instance->version > 0)
354 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 3);
355 else /* Don't enable unicast address filtering due to IXF1010 bug */
356 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 2);
357
358 t1_tpi_read(adapter, REG_RX_ERR_DROP, &val);
359 val |= (1 << index);
360 t1_tpi_write(adapter, REG_RX_ERR_DROP, val);
361
362 /*
363 * Clear the port RMON registers by adding their current values to the
364 * cumulatice port stats and then clearing the stats. Really.
365 */
366 port_stats_update(mac);
367 memset(&mac->stats, 0, sizeof(struct cmac_statistics));
368 mac->instance->ticks = 0;
369
370 t1_tpi_read(adapter, REG_PORT_ENABLE, &val);
371 val |= (1 << index);
372 t1_tpi_write(adapter, REG_PORT_ENABLE, val);
373
374 index <<= 2;
375 if (is_T2(adapter)) {
376 /* T204: set the Fifo water level & threshold */
377 t1_tpi_write(adapter, RX_FIFO_HIGH_WATERMARK_BASE + index, 0x740);
378 t1_tpi_write(adapter, RX_FIFO_LOW_WATERMARK_BASE + index, 0x730);
379 t1_tpi_write(adapter, TX_FIFO_HIGH_WATERMARK_BASE + index, 0x600);
380 t1_tpi_write(adapter, TX_FIFO_LOW_WATERMARK_BASE + index, 0x1d0);
381 t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x1100);
382 } else {
383 /*
384 * Set the TX Fifo Threshold to 0x400 instead of 0x100 to work around
385 * Underrun problem. Intel has blessed this solution.
386 */
387 t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x400);
388 }
389}
390
391/* IXF1010 ports do not have separate enables for TX and RX */
392static int mac_enable(struct cmac *mac, int which)
393{
394 if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
395 enable_port(mac);
396 return 0;
397}
398
399static int mac_disable(struct cmac *mac, int which)
400{
401 if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
402 disable_port(mac);
403 return 0;
404}
405
406#define RMON_UPDATE(mac, name, stat_name) \
407 t1_tpi_read((mac)->adapter, MACREG(mac, REG_##name), &val); \
408 (mac)->stats.stat_name += val;
409
410/*
411 * This function is called periodically to accumulate the current values of the
412 * RMON counters into the port statistics. Since the counters are only 32 bits
413 * some of them can overflow in less than a minute at GigE speeds, so this
414 * function should be called every 30 seconds or so.
415 *
416 * To cut down on reading costs we update only the octet counters at each tick
417 * and do a full update at major ticks, which can be every 30 minutes or more.
418 */
419static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
420 int flag)
421{
422 if (flag == MAC_STATS_UPDATE_FULL ||
423 MAJOR_UPDATE_TICKS <= mac->instance->ticks) {
424 port_stats_update(mac);
425 mac->instance->ticks = 0;
426 } else {
427 u32 val;
428
429 RMON_UPDATE(mac, RxOctetsTotalOK, RxOctetsOK);
430 RMON_UPDATE(mac, TxOctetsTotalOK, TxOctetsOK);
431 mac->instance->ticks++;
432 }
433 return &mac->stats;
434}
435
436static void mac_destroy(struct cmac *mac)
437{
438 kfree(mac);
439}
440
441static struct cmac_ops ixf1010_ops = {
442 .destroy = mac_destroy,
443 .reset = mac_reset,
444 .interrupt_enable = mac_intr_op,
445 .interrupt_disable = mac_intr_op,
446 .interrupt_clear = mac_intr_op,
447 .enable = mac_enable,
448 .disable = mac_disable,
449 .set_mtu = mac_set_mtu,
450 .set_rx_mode = mac_set_rx_mode,
451 .set_speed_duplex_fc = mac_set_speed_duplex_fc,
452 .get_speed_duplex_fc = mac_get_speed_duplex_fc,
453 .statistics_update = mac_update_statistics,
454 .macaddress_get = mac_get_address,
455 .macaddress_set = mac_set_address,
456};
457
458static int ixf1010_mac_reset(adapter_t *adapter)
459{
460 u32 val;
461
462 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
463 if ((val & 1) != 0) {
464 val &= ~1;
465 t1_tpi_write(adapter, A_ELMER0_GPO, val);
466 udelay(2);
467 }
468 val |= 1;
469 t1_tpi_write(adapter, A_ELMER0_GPO, val);
470 udelay(2);
471
472 t1_tpi_write(adapter, REG_PORT_ENABLE, 0);
473 return 0;
474}
475
476static struct cmac *ixf1010_mac_create(adapter_t *adapter, int index)
477{
478 struct cmac *mac;
479 u32 val;
480
481 if (index > 9)
482 return NULL;
483
484 mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
485 if (!mac)
486 return NULL;
487
488 mac->ops = &ixf1010_ops;
489 mac->instance = (cmac_instance *)(mac + 1);
490
491 mac->instance->mac_base = MACREG_BASE + (index * 0x200);
492 mac->instance->index = index;
493 mac->adapter = adapter;
494 mac->instance->ticks = 0;
495
496 t1_tpi_read(adapter, REG_JTAG_ID, &val);
497 mac->instance->version = val >> 28;
498 return mac;
499}
500
501struct gmac t1_ixf1010_ops = {
502 STATS_TICK_SECS,
503 ixf1010_mac_create,
504 ixf1010_mac_reset
505};
diff --git a/drivers/net/chelsio/mac.c b/drivers/net/chelsio/mac.c
index 6af39dc70459..1d972825eac3 100644
--- a/drivers/net/chelsio/mac.c
+++ b/drivers/net/chelsio/mac.c
@@ -363,6 +363,6 @@ static struct cmac *mac_create(adapter_t *adapter, int index)
363 return mac; 363 return mac;
364} 364}
365 365
366struct gmac t1_chelsio_mac_ops = { 366const struct gmac t1_chelsio_mac_ops = {
367 .create = mac_create 367 .create = mac_create
368}; 368};
diff --git a/drivers/net/chelsio/mv88e1xxx.c b/drivers/net/chelsio/mv88e1xxx.c
index 5867e3b0a887..0632be0d6494 100644
--- a/drivers/net/chelsio/mv88e1xxx.c
+++ b/drivers/net/chelsio/mv88e1xxx.c
@@ -354,7 +354,7 @@ static struct cphy_ops mv88e1xxx_ops = {
354}; 354};
355 355
356static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr, 356static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr,
357 struct mdio_ops *mdio_ops) 357 const struct mdio_ops *mdio_ops)
358{ 358{
359 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); 359 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
360 360
@@ -390,7 +390,7 @@ static int mv88e1xxx_phy_reset(adapter_t* adapter)
390 return 0; 390 return 0;
391} 391}
392 392
393struct gphy t1_mv88e1xxx_ops = { 393const struct gphy t1_mv88e1xxx_ops = {
394 mv88e1xxx_phy_create, 394 .create = mv88e1xxx_phy_create,
395 mv88e1xxx_phy_reset 395 .reset = mv88e1xxx_phy_reset
396}; 396};
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c
index c8e89480d906..cd856041af34 100644
--- a/drivers/net/chelsio/mv88x201x.c
+++ b/drivers/net/chelsio/mv88x201x.c
@@ -208,7 +208,7 @@ static struct cphy_ops mv88x201x_ops = {
208}; 208};
209 209
210static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, 210static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
211 struct mdio_ops *mdio_ops) 211 const struct mdio_ops *mdio_ops)
212{ 212{
213 u32 val; 213 u32 val;
214 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); 214 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
@@ -252,7 +252,7 @@ static int mv88x201x_phy_reset(adapter_t *adapter)
252 return 0; 252 return 0;
253} 253}
254 254
255struct gphy t1_mv88x201x_ops = { 255const struct gphy t1_mv88x201x_ops = {
256 mv88x201x_phy_create, 256 .create = mv88x201x_phy_create,
257 mv88x201x_phy_reset 257 .reset = mv88x201x_phy_reset
258}; 258};
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c
index 87dde3e60046..040acd29995a 100644
--- a/drivers/net/chelsio/my3126.c
+++ b/drivers/net/chelsio/my3126.c
@@ -166,7 +166,7 @@ static struct cphy_ops my3126_ops = {
166}; 166};
167 167
168static struct cphy *my3126_phy_create(adapter_t *adapter, 168static struct cphy *my3126_phy_create(adapter_t *adapter,
169 int phy_addr, struct mdio_ops *mdio_ops) 169 int phy_addr, const struct mdio_ops *mdio_ops)
170{ 170{
171 struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL); 171 struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
172 172
@@ -201,7 +201,7 @@ static int my3126_phy_reset(adapter_t * adapter)
201 return 0; 201 return 0;
202} 202}
203 203
204struct gphy t1_my3126_ops = { 204const struct gphy t1_my3126_ops = {
205 my3126_phy_create, 205 .create = my3126_phy_create,
206 my3126_phy_reset 206 .reset = my3126_phy_reset
207}; 207};
diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c
index 69129edeefd6..678778a8d133 100644
--- a/drivers/net/chelsio/pm3393.c
+++ b/drivers/net/chelsio/pm3393.c
@@ -807,8 +807,8 @@ static int pm3393_mac_reset(adapter_t * adapter)
807 return successful_reset ? 0 : 1; 807 return successful_reset ? 0 : 1;
808} 808}
809 809
810struct gmac t1_pm3393_ops = { 810const struct gmac t1_pm3393_ops = {
811 STATS_TICK_SECS, 811 .stats_update_period = STATS_TICK_SECS,
812 pm3393_mac_create, 812 .create = pm3393_mac_create,
813 pm3393_mac_reset 813 .reset = pm3393_mac_reset,
814}; 814};
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index c2522cdfab37..7de9a611e1f7 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -321,10 +321,10 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
321} 321}
322 322
323#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR) 323#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
324static struct mdio_ops mi1_mdio_ops = { 324static const struct mdio_ops mi1_mdio_ops = {
325 mi1_mdio_init, 325 .init = mi1_mdio_init,
326 mi1_mdio_read, 326 .read = mi1_mdio_read,
327 mi1_mdio_write 327 .write = mi1_mdio_write
328}; 328};
329#endif 329#endif
330 330
@@ -377,10 +377,10 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
377 return 0; 377 return 0;
378} 378}
379 379
380static struct mdio_ops mi1_mdio_ext_ops = { 380static const struct mdio_ops mi1_mdio_ext_ops = {
381 mi1_mdio_init, 381 .init = mi1_mdio_init,
382 mi1_mdio_ext_read, 382 .read = mi1_mdio_ext_read,
383 mi1_mdio_ext_write 383 .write = mi1_mdio_ext_write
384}; 384};
385 385
386enum { 386enum {
@@ -392,63 +392,136 @@ enum {
392 CH_BRD_N204_4CU, 392 CH_BRD_N204_4CU,
393}; 393};
394 394
395static struct board_info t1_board[] = { 395static const struct board_info t1_board[] = {
396 396 {
397{ CHBT_BOARD_CHT110, 1/*ports#*/, 397 .board = CHBT_BOARD_CHT110,
398 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T1, 398 .port_number = 1,
399 CHBT_MAC_PM3393, CHBT_PHY_MY3126, 399 .caps = SUPPORTED_10000baseT_Full,
400 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/, 400 .chip_term = CHBT_TERM_T1,
401 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, 401 .chip_mac = CHBT_MAC_PM3393,
402 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, 402 .chip_phy = CHBT_PHY_MY3126,
403 &t1_my3126_ops, &mi1_mdio_ext_ops, 403 .clock_core = 125000000,
404 "Chelsio T110 1x10GBase-CX4 TOE" }, 404 .clock_mc3 = 150000000,
405 405 .clock_mc4 = 125000000,
406{ CHBT_BOARD_N110, 1/*ports#*/, 406 .espi_nports = 1,
407 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 407 .clock_elmer0 = 44,
408 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 408 .mdio_mdien = 1,
409 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 409 .mdio_mdiinv = 1,
410 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 410 .mdio_mdc = 1,
411 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 411 .mdio_phybaseaddr = 1,
412 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 412 .gmac = &t1_pm3393_ops,
413 "Chelsio N110 1x10GBaseX NIC" }, 413 .gphy = &t1_my3126_ops,
414 414 .mdio_ops = &mi1_mdio_ext_ops,
415{ CHBT_BOARD_N210, 1/*ports#*/, 415 .desc = "Chelsio T110 1x10GBase-CX4 TOE",
416 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2, 416 },
417 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 417
418 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 418 {
419 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 419 .board = CHBT_BOARD_N110,
420 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 420 .port_number = 1,
421 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 421 .caps = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
422 "Chelsio N210 1x10GBaseX NIC" }, 422 .chip_term = CHBT_TERM_T1,
423 423 .chip_mac = CHBT_MAC_PM3393,
424{ CHBT_BOARD_CHT210, 1/*ports#*/, 424 .chip_phy = CHBT_PHY_88X2010,
425 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, 425 .clock_core = 125000000,
426 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 426 .espi_nports = 1,
427 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, 427 .clock_elmer0 = 44,
428 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 428 .mdio_mdien = 0,
429 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 429 .mdio_mdiinv = 0,
430 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 430 .mdio_mdc = 1,
431 "Chelsio T210 1x10GBaseX TOE" }, 431 .mdio_phybaseaddr = 0,
432 432 .gmac = &t1_pm3393_ops,
433{ CHBT_BOARD_CHT210, 1/*ports#*/, 433 .gphy = &t1_mv88x201x_ops,
434 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, 434 .mdio_ops = &mi1_mdio_ext_ops,
435 CHBT_MAC_PM3393, CHBT_PHY_MY3126, 435 .desc = "Chelsio N110 1x10GBaseX NIC",
436 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, 436 },
437 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, 437
438 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, 438 {
439 &t1_my3126_ops, &mi1_mdio_ext_ops, 439 .board = CHBT_BOARD_N210,
440 "Chelsio T210 1x10GBase-CX4 TOE" }, 440 .port_number = 1,
441 .caps = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
442 .chip_term = CHBT_TERM_T2,
443 .chip_mac = CHBT_MAC_PM3393,
444 .chip_phy = CHBT_PHY_88X2010,
445 .clock_core = 125000000,
446 .espi_nports = 1,
447 .clock_elmer0 = 44,
448 .mdio_mdien = 0,
449 .mdio_mdiinv = 0,
450 .mdio_mdc = 1,
451 .mdio_phybaseaddr = 0,
452 .gmac = &t1_pm3393_ops,
453 .gphy = &t1_mv88x201x_ops,
454 .mdio_ops = &mi1_mdio_ext_ops,
455 .desc = "Chelsio N210 1x10GBaseX NIC",
456 },
457
458 {
459 .board = CHBT_BOARD_CHT210,
460 .port_number = 1,
461 .caps = SUPPORTED_10000baseT_Full,
462 .chip_term = CHBT_TERM_T2,
463 .chip_mac = CHBT_MAC_PM3393,
464 .chip_phy = CHBT_PHY_88X2010,
465 .clock_core = 125000000,
466 .clock_mc3 = 133000000,
467 .clock_mc4 = 125000000,
468 .espi_nports = 1,
469 .clock_elmer0 = 44,
470 .mdio_mdien = 0,
471 .mdio_mdiinv = 0,
472 .mdio_mdc = 1,
473 .mdio_phybaseaddr = 0,
474 .gmac = &t1_pm3393_ops,
475 .gphy = &t1_mv88x201x_ops,
476 .mdio_ops = &mi1_mdio_ext_ops,
477 .desc = "Chelsio T210 1x10GBaseX TOE",
478 },
479
480 {
481 .board = CHBT_BOARD_CHT210,
482 .port_number = 1,
483 .caps = SUPPORTED_10000baseT_Full,
484 .chip_term = CHBT_TERM_T2,
485 .chip_mac = CHBT_MAC_PM3393,
486 .chip_phy = CHBT_PHY_MY3126,
487 .clock_core = 125000000,
488 .clock_mc3 = 133000000,
489 .clock_mc4 = 125000000,
490 .espi_nports = 1,
491 .clock_elmer0 = 44,
492 .mdio_mdien = 1,
493 .mdio_mdiinv = 1,
494 .mdio_mdc = 1,
495 .mdio_phybaseaddr = 1,
496 .gmac = &t1_pm3393_ops,
497 .gphy = &t1_my3126_ops,
498 .mdio_ops = &mi1_mdio_ext_ops,
499 .desc = "Chelsio T210 1x10GBase-CX4 TOE",
500 },
441 501
442#ifdef CONFIG_CHELSIO_T1_1G 502#ifdef CONFIG_CHELSIO_T1_1G
443{ CHBT_BOARD_CHN204, 4/*ports#*/, 503 {
444 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | 504 .board = CHBT_BOARD_CHN204,
445 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | 505 .port_number = 4,
446 SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_VSC7321, CHBT_PHY_88E1111, 506 .caps = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full
447 100000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 507 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full
448 4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 508 | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
449 0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_vsc7326_ops, 509 SUPPORTED_PAUSE | SUPPORTED_TP,
450 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 510 .chip_term = CHBT_TERM_T2,
451 "Chelsio N204 4x100/1000BaseT NIC" }, 511 .chip_mac = CHBT_MAC_VSC7321,
512 .chip_phy = CHBT_PHY_88E1111,
513 .clock_core = 100000000,
514 .espi_nports = 4,
515 .clock_elmer0 = 44,
516 .mdio_mdien = 0,
517 .mdio_mdiinv = 0,
518 .mdio_mdc = 0,
519 .mdio_phybaseaddr = 4,
520 .gmac = &t1_vsc7326_ops,
521 .gphy = &t1_mv88e1xxx_ops,
522 .mdio_ops = &mi1_mdio_ops,
523 .desc = "Chelsio N204 4x100/1000BaseT NIC",
524 },
452#endif 525#endif
453 526
454}; 527};
diff --git a/drivers/net/chelsio/vsc7326.c b/drivers/net/chelsio/vsc7326.c
index 534ffa0f616e..99b51f61fe77 100644
--- a/drivers/net/chelsio/vsc7326.c
+++ b/drivers/net/chelsio/vsc7326.c
@@ -723,7 +723,7 @@ static int vsc7326_mac_reset(adapter_t *adapter)
723 return 0; 723 return 0;
724} 724}
725 725
726struct gmac t1_vsc7326_ops = { 726const struct gmac t1_vsc7326_ops = {
727 .stats_update_period = STATS_TICK_SECS, 727 .stats_update_period = STATS_TICK_SECS,
728 .create = vsc7326_mac_create, 728 .create = vsc7326_mac_create,
729 .reset = vsc7326_mac_reset, 729 .reset = vsc7326_mac_reset,
diff --git a/drivers/net/chelsio/vsc8244.c b/drivers/net/chelsio/vsc8244.c
deleted file mode 100644
index 251d4859c91d..000000000000
--- a/drivers/net/chelsio/vsc8244.c
+++ /dev/null
@@ -1,367 +0,0 @@
1/*
2 * This file is part of the Chelsio T2 Ethernet driver.
3 *
4 * Copyright (C) 2005 Chelsio Communications. All rights reserved.
5 *
6 * This program is distributed in the hope that it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
9 * release for licensing terms and conditions.
10 */
11
12#include "common.h"
13#include "cphy.h"
14#include "elmer0.h"
15
16#ifndef ADVERTISE_PAUSE_CAP
17# define ADVERTISE_PAUSE_CAP 0x400
18#endif
19#ifndef ADVERTISE_PAUSE_ASYM
20# define ADVERTISE_PAUSE_ASYM 0x800
21#endif
22
23/* Gigabit MII registers */
24#ifndef MII_CTRL1000
25# define MII_CTRL1000 9
26#endif
27
28#ifndef ADVERTISE_1000FULL
29# define ADVERTISE_1000FULL 0x200
30# define ADVERTISE_1000HALF 0x100
31#endif
32
33/* VSC8244 PHY specific registers. */
34enum {
35 VSC8244_INTR_ENABLE = 25,
36 VSC8244_INTR_STATUS = 26,
37 VSC8244_AUX_CTRL_STAT = 28,
38};
39
40enum {
41 VSC_INTR_RX_ERR = 1 << 0,
42 VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */
43 VSC_INTR_CABLE = 1 << 2, /* cable impairment */
44 VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */
45 VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */
46 VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */
47 VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */
48 VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */
49 VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */
50 VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */
51 VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */
52 VSC_INTR_LINK_CHG = 1 << 13, /* link change */
53 VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */
54};
55
56#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \
57 VSC_INTR_NEG_DONE)
58#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \
59 VSC_INTR_ENABLE)
60
61/* PHY specific auxiliary control & status register fields */
62#define S_ACSR_ACTIPHY_TMR 0
63#define M_ACSR_ACTIPHY_TMR 0x3
64#define V_ACSR_ACTIPHY_TMR(x) ((x) << S_ACSR_ACTIPHY_TMR)
65
66#define S_ACSR_SPEED 3
67#define M_ACSR_SPEED 0x3
68#define G_ACSR_SPEED(x) (((x) >> S_ACSR_SPEED) & M_ACSR_SPEED)
69
70#define S_ACSR_DUPLEX 5
71#define F_ACSR_DUPLEX (1 << S_ACSR_DUPLEX)
72
73#define S_ACSR_ACTIPHY 6
74#define F_ACSR_ACTIPHY (1 << S_ACSR_ACTIPHY)
75
76/*
77 * Reset the PHY. This PHY completes reset immediately so we never wait.
78 */
79static int vsc8244_reset(struct cphy *cphy, int wait)
80{
81 int err;
82 unsigned int ctl;
83
84 err = simple_mdio_read(cphy, MII_BMCR, &ctl);
85 if (err)
86 return err;
87
88 ctl &= ~BMCR_PDOWN;
89 ctl |= BMCR_RESET;
90 return simple_mdio_write(cphy, MII_BMCR, ctl);
91}
92
93static int vsc8244_intr_enable(struct cphy *cphy)
94{
95 simple_mdio_write(cphy, VSC8244_INTR_ENABLE, INTR_MASK);
96
97 /* Enable interrupts through Elmer */
98 if (t1_is_asic(cphy->adapter)) {
99 u32 elmer;
100
101 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
102 elmer |= ELMER0_GP_BIT1;
103 if (is_T2(cphy->adapter))
104 elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4;
105 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
106 }
107
108 return 0;
109}
110
111static int vsc8244_intr_disable(struct cphy *cphy)
112{
113 simple_mdio_write(cphy, VSC8244_INTR_ENABLE, 0);
114
115 if (t1_is_asic(cphy->adapter)) {
116 u32 elmer;
117
118 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
119 elmer &= ~ELMER0_GP_BIT1;
120 if (is_T2(cphy->adapter))
121 elmer &= ~(ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4);
122 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
123 }
124
125 return 0;
126}
127
128static int vsc8244_intr_clear(struct cphy *cphy)
129{
130 u32 val;
131 u32 elmer;
132
133 /* Clear PHY interrupts by reading the register. */
134 simple_mdio_read(cphy, VSC8244_INTR_ENABLE, &val);
135
136 if (t1_is_asic(cphy->adapter)) {
137 t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
138 elmer |= ELMER0_GP_BIT1;
139 if (is_T2(cphy->adapter))
140 elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4;
141 t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
142 }
143
144 return 0;
145}
146
147/*
148 * Force the PHY speed and duplex. This also disables auto-negotiation, except
149 * for 1Gb/s, where auto-negotiation is mandatory.
150 */
151static int vsc8244_set_speed_duplex(struct cphy *phy, int speed, int duplex)
152{
153 int err;
154 unsigned int ctl;
155
156 err = simple_mdio_read(phy, MII_BMCR, &ctl);
157 if (err)
158 return err;
159
160 if (speed >= 0) {
161 ctl &= ~(BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
162 if (speed == SPEED_100)
163 ctl |= BMCR_SPEED100;
164 else if (speed == SPEED_1000)
165 ctl |= BMCR_SPEED1000;
166 }
167 if (duplex >= 0) {
168 ctl &= ~(BMCR_FULLDPLX | BMCR_ANENABLE);
169 if (duplex == DUPLEX_FULL)
170 ctl |= BMCR_FULLDPLX;
171 }
172 if (ctl & BMCR_SPEED1000) /* auto-negotiation required for 1Gb/s */
173 ctl |= BMCR_ANENABLE;
174 return simple_mdio_write(phy, MII_BMCR, ctl);
175}
176
177int t1_mdio_set_bits(struct cphy *phy, int mmd, int reg, unsigned int bits)
178{
179 int ret;
180 unsigned int val;
181
182 ret = mdio_read(phy, mmd, reg, &val);
183 if (!ret)
184 ret = mdio_write(phy, mmd, reg, val | bits);
185 return ret;
186}
187
188static int vsc8244_autoneg_enable(struct cphy *cphy)
189{
190 return t1_mdio_set_bits(cphy, 0, MII_BMCR,
191 BMCR_ANENABLE | BMCR_ANRESTART);
192}
193
194static int vsc8244_autoneg_restart(struct cphy *cphy)
195{
196 return t1_mdio_set_bits(cphy, 0, MII_BMCR, BMCR_ANRESTART);
197}
198
199static int vsc8244_advertise(struct cphy *phy, unsigned int advertise_map)
200{
201 int err;
202 unsigned int val = 0;
203
204 err = simple_mdio_read(phy, MII_CTRL1000, &val);
205 if (err)
206 return err;
207
208 val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
209 if (advertise_map & ADVERTISED_1000baseT_Half)
210 val |= ADVERTISE_1000HALF;
211 if (advertise_map & ADVERTISED_1000baseT_Full)
212 val |= ADVERTISE_1000FULL;
213
214 err = simple_mdio_write(phy, MII_CTRL1000, val);
215 if (err)
216 return err;
217
218 val = 1;
219 if (advertise_map & ADVERTISED_10baseT_Half)
220 val |= ADVERTISE_10HALF;
221 if (advertise_map & ADVERTISED_10baseT_Full)
222 val |= ADVERTISE_10FULL;
223 if (advertise_map & ADVERTISED_100baseT_Half)
224 val |= ADVERTISE_100HALF;
225 if (advertise_map & ADVERTISED_100baseT_Full)
226 val |= ADVERTISE_100FULL;
227 if (advertise_map & ADVERTISED_PAUSE)
228 val |= ADVERTISE_PAUSE_CAP;
229 if (advertise_map & ADVERTISED_ASYM_PAUSE)
230 val |= ADVERTISE_PAUSE_ASYM;
231 return simple_mdio_write(phy, MII_ADVERTISE, val);
232}
233
234static int vsc8244_get_link_status(struct cphy *cphy, int *link_ok,
235 int *speed, int *duplex, int *fc)
236{
237 unsigned int bmcr, status, lpa, adv;
238 int err, sp = -1, dplx = -1, pause = 0;
239
240 err = simple_mdio_read(cphy, MII_BMCR, &bmcr);
241 if (!err)
242 err = simple_mdio_read(cphy, MII_BMSR, &status);
243 if (err)
244 return err;
245
246 if (link_ok) {
247 /*
248 * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
249 * once more to get the current link state.
250 */
251 if (!(status & BMSR_LSTATUS))
252 err = simple_mdio_read(cphy, MII_BMSR, &status);
253 if (err)
254 return err;
255 *link_ok = (status & BMSR_LSTATUS) != 0;
256 }
257 if (!(bmcr & BMCR_ANENABLE)) {
258 dplx = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
259 if (bmcr & BMCR_SPEED1000)
260 sp = SPEED_1000;
261 else if (bmcr & BMCR_SPEED100)
262 sp = SPEED_100;
263 else
264 sp = SPEED_10;
265 } else if (status & BMSR_ANEGCOMPLETE) {
266 err = simple_mdio_read(cphy, VSC8244_AUX_CTRL_STAT, &status);
267 if (err)
268 return err;
269
270 dplx = (status & F_ACSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
271 sp = G_ACSR_SPEED(status);
272 if (sp == 0)
273 sp = SPEED_10;
274 else if (sp == 1)
275 sp = SPEED_100;
276 else
277 sp = SPEED_1000;
278
279 if (fc && dplx == DUPLEX_FULL) {
280 err = simple_mdio_read(cphy, MII_LPA, &lpa);
281 if (!err)
282 err = simple_mdio_read(cphy, MII_ADVERTISE,
283 &adv);
284 if (err)
285 return err;
286
287 if (lpa & adv & ADVERTISE_PAUSE_CAP)
288 pause = PAUSE_RX | PAUSE_TX;
289 else if ((lpa & ADVERTISE_PAUSE_CAP) &&
290 (lpa & ADVERTISE_PAUSE_ASYM) &&
291 (adv & ADVERTISE_PAUSE_ASYM))
292 pause = PAUSE_TX;
293 else if ((lpa & ADVERTISE_PAUSE_ASYM) &&
294 (adv & ADVERTISE_PAUSE_CAP))
295 pause = PAUSE_RX;
296 }
297 }
298 if (speed)
299 *speed = sp;
300 if (duplex)
301 *duplex = dplx;
302 if (fc)
303 *fc = pause;
304 return 0;
305}
306
307static int vsc8244_intr_handler(struct cphy *cphy)
308{
309 unsigned int cause;
310 int err, cphy_cause = 0;
311
312 err = simple_mdio_read(cphy, VSC8244_INTR_STATUS, &cause);
313 if (err)
314 return err;
315
316 cause &= INTR_MASK;
317 if (cause & CFG_CHG_INTR_MASK)
318 cphy_cause |= cphy_cause_link_change;
319 if (cause & (VSC_INTR_RX_FIFO | VSC_INTR_TX_FIFO))
320 cphy_cause |= cphy_cause_fifo_error;
321 return cphy_cause;
322}
323
324static void vsc8244_destroy(struct cphy *cphy)
325{
326 kfree(cphy);
327}
328
329static struct cphy_ops vsc8244_ops = {
330 .destroy = vsc8244_destroy,
331 .reset = vsc8244_reset,
332 .interrupt_enable = vsc8244_intr_enable,
333 .interrupt_disable = vsc8244_intr_disable,
334 .interrupt_clear = vsc8244_intr_clear,
335 .interrupt_handler = vsc8244_intr_handler,
336 .autoneg_enable = vsc8244_autoneg_enable,
337 .autoneg_restart = vsc8244_autoneg_restart,
338 .advertise = vsc8244_advertise,
339 .set_speed_duplex = vsc8244_set_speed_duplex,
340 .get_link_status = vsc8244_get_link_status
341};
342
343static struct cphy* vsc8244_phy_create(adapter_t *adapter, int phy_addr,
344 struct mdio_ops *mdio_ops)
345{
346 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
347
348 if (!cphy)
349 return NULL;
350
351 cphy_init(cphy, adapter, phy_addr, &vsc8244_ops, mdio_ops);
352
353 return cphy;
354}
355
356
357static int vsc8244_phy_reset(adapter_t* adapter)
358{
359 return 0;
360}
361
362struct gphy t1_vsc8244_ops = {
363 vsc8244_phy_create,
364 vsc8244_phy_reset
365};
366
367
diff --git a/drivers/net/chelsio/vsc8244_reg.h b/drivers/net/chelsio/vsc8244_reg.h
deleted file mode 100644
index d3c1829055cb..000000000000
--- a/drivers/net/chelsio/vsc8244_reg.h
+++ /dev/null
@@ -1,172 +0,0 @@
1/* $Date: 2005/11/23 16:28:53 $ $RCSfile: vsc8244_reg.h,v $ $Revision: 1.1 $ */
2#ifndef CHELSIO_MV8E1XXX_H
3#define CHELSIO_MV8E1XXX_H
4
5#ifndef BMCR_SPEED1000
6# define BMCR_SPEED1000 0x40
7#endif
8
9#ifndef ADVERTISE_PAUSE
10# define ADVERTISE_PAUSE 0x400
11#endif
12#ifndef ADVERTISE_PAUSE_ASYM
13# define ADVERTISE_PAUSE_ASYM 0x800
14#endif
15
16/* Gigabit MII registers */
17#define MII_GBMR 1 /* 1000Base-T mode register */
18#define MII_GBCR 9 /* 1000Base-T control register */
19#define MII_GBSR 10 /* 1000Base-T status register */
20
21/* 1000Base-T control register fields */
22#define GBCR_ADV_1000HALF 0x100
23#define GBCR_ADV_1000FULL 0x200
24#define GBCR_PREFER_MASTER 0x400
25#define GBCR_MANUAL_AS_MASTER 0x800
26#define GBCR_MANUAL_CONFIG_ENABLE 0x1000
27
28/* 1000Base-T status register fields */
29#define GBSR_LP_1000HALF 0x400
30#define GBSR_LP_1000FULL 0x800
31#define GBSR_REMOTE_OK 0x1000
32#define GBSR_LOCAL_OK 0x2000
33#define GBSR_LOCAL_MASTER 0x4000
34#define GBSR_MASTER_FAULT 0x8000
35
36/* Vitesse PHY interrupt status bits. */
37#if 0
38#define VSC8244_INTR_JABBER 0x0001
39#define VSC8244_INTR_POLARITY_CHNG 0x0002
40#define VSC8244_INTR_ENG_DETECT_CHNG 0x0010
41#define VSC8244_INTR_DOWNSHIFT 0x0020
42#define VSC8244_INTR_MDI_XOVER_CHNG 0x0040
43#define VSC8244_INTR_FIFO_OVER_UNDER 0x0080
44#define VSC8244_INTR_FALSE_CARRIER 0x0100
45#define VSC8244_INTR_SYMBOL_ERROR 0x0200
46#define VSC8244_INTR_LINK_CHNG 0x0400
47#define VSC8244_INTR_AUTONEG_DONE 0x0800
48#define VSC8244_INTR_PAGE_RECV 0x1000
49#define VSC8244_INTR_DUPLEX_CHNG 0x2000
50#define VSC8244_INTR_SPEED_CHNG 0x4000
51#define VSC8244_INTR_AUTONEG_ERR 0x8000
52#else
53//#define VSC8244_INTR_JABBER 0x0001
54//#define VSC8244_INTR_POLARITY_CHNG 0x0002
55//#define VSC8244_INTR_BIT2 0x0004
56//#define VSC8244_INTR_BIT3 0x0008
57#define VSC8244_INTR_RX_ERR 0x0001
58#define VSC8244_INTR_MASTER_SLAVE 0x0002
59#define VSC8244_INTR_CABLE_IMPAIRED 0x0004
60#define VSC8244_INTR_FALSE_CARRIER 0x0008
61//#define VSC8244_INTR_ENG_DETECT_CHNG 0x0010
62//#define VSC8244_INTR_DOWNSHIFT 0x0020
63//#define VSC8244_INTR_MDI_XOVER_CHNG 0x0040
64//#define VSC8244_INTR_FIFO_OVER_UNDER 0x0080
65#define VSC8244_INTR_BIT4 0x0010
66#define VSC8244_INTR_FIFO_RX 0x0020
67#define VSC8244_INTR_FIFO_OVER_UNDER 0x0040
68#define VSC8244_INTR_LOCK_LOST 0x0080
69//#define VSC8244_INTR_FALSE_CARRIER 0x0100
70//#define VSC8244_INTR_SYMBOL_ERROR 0x0200
71//#define VSC8244_INTR_LINK_CHNG 0x0400
72//#define VSC8244_INTR_AUTONEG_DONE 0x0800
73#define VSC8244_INTR_SYMBOL_ERROR 0x0100
74#define VSC8244_INTR_ENG_DETECT_CHNG 0x0200
75#define VSC8244_INTR_AUTONEG_DONE 0x0400
76#define VSC8244_INTR_AUTONEG_ERR 0x0800
77//#define VSC8244_INTR_PAGE_RECV 0x1000
78//#define VSC8244_INTR_DUPLEX_CHNG 0x2000
79//#define VSC8244_INTR_SPEED_CHNG 0x4000
80//#define VSC8244_INTR_AUTONEG_ERR 0x8000
81#define VSC8244_INTR_DUPLEX_CHNG 0x1000
82#define VSC8244_INTR_LINK_CHNG 0x2000
83#define VSC8244_INTR_SPEED_CHNG 0x4000
84#define VSC8244_INTR_STATUS 0x8000
85#endif
86
87
88/* Vitesse PHY specific registers. */
89#define VSC8244_SPECIFIC_CNTRL_REGISTER 16
90#define VSC8244_SPECIFIC_STATUS_REGISTER 0x1c
91#define VSC8244_INTERRUPT_ENABLE_REGISTER 0x19
92#define VSC8244_INTERRUPT_STATUS_REGISTER 0x1a
93#define VSC8244_EXT_PHY_SPECIFIC_CNTRL_REGISTER 20
94#define VSC8244_RECV_ERR_CNTR_REGISTER 21
95#define VSC8244_RES_REGISTER 22
96#define VSC8244_GLOBAL_STATUS_REGISTER 23
97#define VSC8244_LED_CONTROL_REGISTER 24
98#define VSC8244_MANUAL_LED_OVERRIDE_REGISTER 25
99#define VSC8244_EXT_PHY_SPECIFIC_CNTRL_2_REGISTER 26
100#define VSC8244_EXT_PHY_SPECIFIC_STATUS_REGISTER 27
101#define VSC8244_VIRTUAL_CABLE_TESTER_REGISTER 28
102#define VSC8244_EXTENDED_ADDR_REGISTER 29
103#define VSC8244_EXTENDED_REGISTER 30
104
105/* PHY specific control register fields */
106#define S_PSCR_MDI_XOVER_MODE 5
107#define M_PSCR_MDI_XOVER_MODE 0x3
108#define V_PSCR_MDI_XOVER_MODE(x) ((x) << S_PSCR_MDI_XOVER_MODE)
109#define G_PSCR_MDI_XOVER_MODE(x) (((x) >> S_PSCR_MDI_XOVER_MODE) & M_PSCR_MDI_XOVER_MODE)
110
111/* Extended PHY specific control register fields */
112#define S_DOWNSHIFT_ENABLE 8
113#define V_DOWNSHIFT_ENABLE (1 << S_DOWNSHIFT_ENABLE)
114
115#define S_DOWNSHIFT_CNT 9
116#define M_DOWNSHIFT_CNT 0x7
117#define V_DOWNSHIFT_CNT(x) ((x) << S_DOWNSHIFT_CNT)
118#define G_DOWNSHIFT_CNT(x) (((x) >> S_DOWNSHIFT_CNT) & M_DOWNSHIFT_CNT)
119
120/* PHY specific status register fields */
121#define S_PSSR_JABBER 0
122#define V_PSSR_JABBER (1 << S_PSSR_JABBER)
123
124#define S_PSSR_POLARITY 1
125#define V_PSSR_POLARITY (1 << S_PSSR_POLARITY)
126
127#define S_PSSR_RX_PAUSE 2
128#define V_PSSR_RX_PAUSE (1 << S_PSSR_RX_PAUSE)
129
130#define S_PSSR_TX_PAUSE 3
131#define V_PSSR_TX_PAUSE (1 << S_PSSR_TX_PAUSE)
132
133#define S_PSSR_ENERGY_DETECT 4
134#define V_PSSR_ENERGY_DETECT (1 << S_PSSR_ENERGY_DETECT)
135
136#define S_PSSR_DOWNSHIFT_STATUS 5
137#define V_PSSR_DOWNSHIFT_STATUS (1 << S_PSSR_DOWNSHIFT_STATUS)
138
139#define S_PSSR_MDI 6
140#define V_PSSR_MDI (1 << S_PSSR_MDI)
141
142#define S_PSSR_CABLE_LEN 7
143#define M_PSSR_CABLE_LEN 0x7
144#define V_PSSR_CABLE_LEN(x) ((x) << S_PSSR_CABLE_LEN)
145#define G_PSSR_CABLE_LEN(x) (((x) >> S_PSSR_CABLE_LEN) & M_PSSR_CABLE_LEN)
146
147//#define S_PSSR_LINK 10
148//#define S_PSSR_LINK 13
149#define S_PSSR_LINK 2
150#define V_PSSR_LINK (1 << S_PSSR_LINK)
151
152//#define S_PSSR_STATUS_RESOLVED 11
153//#define S_PSSR_STATUS_RESOLVED 10
154#define S_PSSR_STATUS_RESOLVED 15
155#define V_PSSR_STATUS_RESOLVED (1 << S_PSSR_STATUS_RESOLVED)
156
157#define S_PSSR_PAGE_RECEIVED 12
158#define V_PSSR_PAGE_RECEIVED (1 << S_PSSR_PAGE_RECEIVED)
159
160//#define S_PSSR_DUPLEX 13
161//#define S_PSSR_DUPLEX 12
162#define S_PSSR_DUPLEX 5
163#define V_PSSR_DUPLEX (1 << S_PSSR_DUPLEX)
164
165//#define S_PSSR_SPEED 14
166//#define S_PSSR_SPEED 14
167#define S_PSSR_SPEED 3
168#define M_PSSR_SPEED 0x3
169#define V_PSSR_SPEED(x) ((x) << S_PSSR_SPEED)
170#define G_PSSR_SPEED(x) (((x) >> S_PSSR_SPEED) & M_PSSR_SPEED)
171
172#endif
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 4d0e0aea72bf..61696637a21e 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -159,7 +159,7 @@
159 159
160#define DRV_NAME "e100" 160#define DRV_NAME "e100"
161#define DRV_EXT "-NAPI" 161#define DRV_EXT "-NAPI"
162#define DRV_VERSION "3.5.17-k2"DRV_EXT 162#define DRV_VERSION "3.5.17-k4"DRV_EXT
163#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" 163#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
164#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" 164#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
165#define PFX DRV_NAME ": " 165#define PFX DRV_NAME ": "
@@ -174,10 +174,13 @@ MODULE_VERSION(DRV_VERSION);
174 174
175static int debug = 3; 175static int debug = 3;
176static int eeprom_bad_csum_allow = 0; 176static int eeprom_bad_csum_allow = 0;
177static int use_io = 0;
177module_param(debug, int, 0); 178module_param(debug, int, 0);
178module_param(eeprom_bad_csum_allow, int, 0); 179module_param(eeprom_bad_csum_allow, int, 0);
180module_param(use_io, int, 0);
179MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); 181MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
180MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums"); 182MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums");
183MODULE_PARM_DESC(use_io, "Force use of i/o access mode");
181#define DPRINTK(nlevel, klevel, fmt, args...) \ 184#define DPRINTK(nlevel, klevel, fmt, args...) \
182 (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \ 185 (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
183 printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \ 186 printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
@@ -282,12 +285,6 @@ enum scb_status {
282 rus_mask = 0x3C, 285 rus_mask = 0x3C,
283}; 286};
284 287
285enum ru_state {
286 RU_SUSPENDED = 0,
287 RU_RUNNING = 1,
288 RU_UNINITIALIZED = -1,
289};
290
291enum scb_stat_ack { 288enum scb_stat_ack {
292 stat_ack_not_ours = 0x00, 289 stat_ack_not_ours = 0x00,
293 stat_ack_sw_gen = 0x04, 290 stat_ack_sw_gen = 0x04,
@@ -529,7 +526,6 @@ struct nic {
529 struct rx *rx_to_use; 526 struct rx *rx_to_use;
530 struct rx *rx_to_clean; 527 struct rx *rx_to_clean;
531 struct rfd blank_rfd; 528 struct rfd blank_rfd;
532 enum ru_state ru_running;
533 529
534 spinlock_t cb_lock ____cacheline_aligned; 530 spinlock_t cb_lock ____cacheline_aligned;
535 spinlock_t cmd_lock; 531 spinlock_t cmd_lock;
@@ -591,7 +587,7 @@ static inline void e100_write_flush(struct nic *nic)
591{ 587{
592 /* Flush previous PCI writes through intermediate bridges 588 /* Flush previous PCI writes through intermediate bridges
593 * by doing a benign read */ 589 * by doing a benign read */
594 (void)readb(&nic->csr->scb.status); 590 (void)ioread8(&nic->csr->scb.status);
595} 591}
596 592
597static void e100_enable_irq(struct nic *nic) 593static void e100_enable_irq(struct nic *nic)
@@ -599,7 +595,7 @@ static void e100_enable_irq(struct nic *nic)
599 unsigned long flags; 595 unsigned long flags;
600 596
601 spin_lock_irqsave(&nic->cmd_lock, flags); 597 spin_lock_irqsave(&nic->cmd_lock, flags);
602 writeb(irq_mask_none, &nic->csr->scb.cmd_hi); 598 iowrite8(irq_mask_none, &nic->csr->scb.cmd_hi);
603 e100_write_flush(nic); 599 e100_write_flush(nic);
604 spin_unlock_irqrestore(&nic->cmd_lock, flags); 600 spin_unlock_irqrestore(&nic->cmd_lock, flags);
605} 601}
@@ -609,7 +605,7 @@ static void e100_disable_irq(struct nic *nic)
609 unsigned long flags; 605 unsigned long flags;
610 606
611 spin_lock_irqsave(&nic->cmd_lock, flags); 607 spin_lock_irqsave(&nic->cmd_lock, flags);
612 writeb(irq_mask_all, &nic->csr->scb.cmd_hi); 608 iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi);
613 e100_write_flush(nic); 609 e100_write_flush(nic);
614 spin_unlock_irqrestore(&nic->cmd_lock, flags); 610 spin_unlock_irqrestore(&nic->cmd_lock, flags);
615} 611}
@@ -618,11 +614,11 @@ static void e100_hw_reset(struct nic *nic)
618{ 614{
619 /* Put CU and RU into idle with a selective reset to get 615 /* Put CU and RU into idle with a selective reset to get
620 * device off of PCI bus */ 616 * device off of PCI bus */
621 writel(selective_reset, &nic->csr->port); 617 iowrite32(selective_reset, &nic->csr->port);
622 e100_write_flush(nic); udelay(20); 618 e100_write_flush(nic); udelay(20);
623 619
624 /* Now fully reset device */ 620 /* Now fully reset device */
625 writel(software_reset, &nic->csr->port); 621 iowrite32(software_reset, &nic->csr->port);
626 e100_write_flush(nic); udelay(20); 622 e100_write_flush(nic); udelay(20);
627 623
628 /* Mask off our interrupt line - it's unmasked after reset */ 624 /* Mask off our interrupt line - it's unmasked after reset */
@@ -639,7 +635,7 @@ static int e100_self_test(struct nic *nic)
639 nic->mem->selftest.signature = 0; 635 nic->mem->selftest.signature = 0;
640 nic->mem->selftest.result = 0xFFFFFFFF; 636 nic->mem->selftest.result = 0xFFFFFFFF;
641 637
642 writel(selftest | dma_addr, &nic->csr->port); 638 iowrite32(selftest | dma_addr, &nic->csr->port);
643 e100_write_flush(nic); 639 e100_write_flush(nic);
644 /* Wait 10 msec for self-test to complete */ 640 /* Wait 10 msec for self-test to complete */
645 msleep(10); 641 msleep(10);
@@ -677,23 +673,23 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
677 for(j = 0; j < 3; j++) { 673 for(j = 0; j < 3; j++) {
678 674
679 /* Chip select */ 675 /* Chip select */
680 writeb(eecs | eesk, &nic->csr->eeprom_ctrl_lo); 676 iowrite8(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
681 e100_write_flush(nic); udelay(4); 677 e100_write_flush(nic); udelay(4);
682 678
683 for(i = 31; i >= 0; i--) { 679 for(i = 31; i >= 0; i--) {
684 ctrl = (cmd_addr_data[j] & (1 << i)) ? 680 ctrl = (cmd_addr_data[j] & (1 << i)) ?
685 eecs | eedi : eecs; 681 eecs | eedi : eecs;
686 writeb(ctrl, &nic->csr->eeprom_ctrl_lo); 682 iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo);
687 e100_write_flush(nic); udelay(4); 683 e100_write_flush(nic); udelay(4);
688 684
689 writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo); 685 iowrite8(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
690 e100_write_flush(nic); udelay(4); 686 e100_write_flush(nic); udelay(4);
691 } 687 }
692 /* Wait 10 msec for cmd to complete */ 688 /* Wait 10 msec for cmd to complete */
693 msleep(10); 689 msleep(10);
694 690
695 /* Chip deselect */ 691 /* Chip deselect */
696 writeb(0, &nic->csr->eeprom_ctrl_lo); 692 iowrite8(0, &nic->csr->eeprom_ctrl_lo);
697 e100_write_flush(nic); udelay(4); 693 e100_write_flush(nic); udelay(4);
698 } 694 }
699}; 695};
@@ -709,21 +705,21 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
709 cmd_addr_data = ((op_read << *addr_len) | addr) << 16; 705 cmd_addr_data = ((op_read << *addr_len) | addr) << 16;
710 706
711 /* Chip select */ 707 /* Chip select */
712 writeb(eecs | eesk, &nic->csr->eeprom_ctrl_lo); 708 iowrite8(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
713 e100_write_flush(nic); udelay(4); 709 e100_write_flush(nic); udelay(4);
714 710
715 /* Bit-bang to read word from eeprom */ 711 /* Bit-bang to read word from eeprom */
716 for(i = 31; i >= 0; i--) { 712 for(i = 31; i >= 0; i--) {
717 ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs; 713 ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs;
718 writeb(ctrl, &nic->csr->eeprom_ctrl_lo); 714 iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo);
719 e100_write_flush(nic); udelay(4); 715 e100_write_flush(nic); udelay(4);
720 716
721 writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo); 717 iowrite8(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
722 e100_write_flush(nic); udelay(4); 718 e100_write_flush(nic); udelay(4);
723 719
724 /* Eeprom drives a dummy zero to EEDO after receiving 720 /* Eeprom drives a dummy zero to EEDO after receiving
725 * complete address. Use this to adjust addr_len. */ 721 * complete address. Use this to adjust addr_len. */
726 ctrl = readb(&nic->csr->eeprom_ctrl_lo); 722 ctrl = ioread8(&nic->csr->eeprom_ctrl_lo);
727 if(!(ctrl & eedo) && i > 16) { 723 if(!(ctrl & eedo) && i > 16) {
728 *addr_len -= (i - 16); 724 *addr_len -= (i - 16);
729 i = 17; 725 i = 17;
@@ -733,7 +729,7 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
733 } 729 }
734 730
735 /* Chip deselect */ 731 /* Chip deselect */
736 writeb(0, &nic->csr->eeprom_ctrl_lo); 732 iowrite8(0, &nic->csr->eeprom_ctrl_lo);
737 e100_write_flush(nic); udelay(4); 733 e100_write_flush(nic); udelay(4);
738 734
739 return le16_to_cpu(data); 735 return le16_to_cpu(data);
@@ -804,7 +800,7 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
804 800
805 /* Previous command is accepted when SCB clears */ 801 /* Previous command is accepted when SCB clears */
806 for(i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) { 802 for(i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) {
807 if(likely(!readb(&nic->csr->scb.cmd_lo))) 803 if(likely(!ioread8(&nic->csr->scb.cmd_lo)))
808 break; 804 break;
809 cpu_relax(); 805 cpu_relax();
810 if(unlikely(i > E100_WAIT_SCB_FAST)) 806 if(unlikely(i > E100_WAIT_SCB_FAST))
@@ -816,8 +812,8 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
816 } 812 }
817 813
818 if(unlikely(cmd != cuc_resume)) 814 if(unlikely(cmd != cuc_resume))
819 writel(dma_addr, &nic->csr->scb.gen_ptr); 815 iowrite32(dma_addr, &nic->csr->scb.gen_ptr);
820 writeb(cmd, &nic->csr->scb.cmd_lo); 816 iowrite8(cmd, &nic->csr->scb.cmd_lo);
821 817
822err_unlock: 818err_unlock:
823 spin_unlock_irqrestore(&nic->cmd_lock, flags); 819 spin_unlock_irqrestore(&nic->cmd_lock, flags);
@@ -895,7 +891,7 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
895 */ 891 */
896 spin_lock_irqsave(&nic->mdio_lock, flags); 892 spin_lock_irqsave(&nic->mdio_lock, flags);
897 for (i = 100; i; --i) { 893 for (i = 100; i; --i) {
898 if (readl(&nic->csr->mdi_ctrl) & mdi_ready) 894 if (ioread32(&nic->csr->mdi_ctrl) & mdi_ready)
899 break; 895 break;
900 udelay(20); 896 udelay(20);
901 } 897 }
@@ -905,11 +901,11 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
905 spin_unlock_irqrestore(&nic->mdio_lock, flags); 901 spin_unlock_irqrestore(&nic->mdio_lock, flags);
906 return 0; /* No way to indicate timeout error */ 902 return 0; /* No way to indicate timeout error */
907 } 903 }
908 writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl); 904 iowrite32((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
909 905
910 for (i = 0; i < 100; i++) { 906 for (i = 0; i < 100; i++) {
911 udelay(20); 907 udelay(20);
912 if ((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready) 908 if ((data_out = ioread32(&nic->csr->mdi_ctrl)) & mdi_ready)
913 break; 909 break;
914 } 910 }
915 spin_unlock_irqrestore(&nic->mdio_lock, flags); 911 spin_unlock_irqrestore(&nic->mdio_lock, flags);
@@ -951,7 +947,7 @@ static void e100_get_defaults(struct nic *nic)
951 ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i)); 947 ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
952 948
953 /* Template for a freshly allocated RFD */ 949 /* Template for a freshly allocated RFD */
954 nic->blank_rfd.command = cpu_to_le16(cb_el); 950 nic->blank_rfd.command = cpu_to_le16(cb_el & cb_s);
955 nic->blank_rfd.rbd = 0xFFFFFFFF; 951 nic->blank_rfd.rbd = 0xFFFFFFFF;
956 nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); 952 nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
957 953
@@ -1318,7 +1314,7 @@ static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
1318 } 1314 }
1319 1315
1320 /* ack any interupts, something could have been set */ 1316 /* ack any interupts, something could have been set */
1321 writeb(~0, &nic->csr->scb.stat_ack); 1317 iowrite8(~0, &nic->csr->scb.stat_ack);
1322 1318
1323 /* if the command failed, or is not OK, notify and return */ 1319 /* if the command failed, or is not OK, notify and return */
1324 if (!counter || !(cb->status & cpu_to_le16(cb_ok))) { 1320 if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {
@@ -1580,7 +1576,7 @@ static void e100_watchdog(unsigned long data)
1580 * accidentally, due to hardware that shares a register between the 1576 * accidentally, due to hardware that shares a register between the
1581 * interrupt mask bit and the SW Interrupt generation bit */ 1577 * interrupt mask bit and the SW Interrupt generation bit */
1582 spin_lock_irq(&nic->cmd_lock); 1578 spin_lock_irq(&nic->cmd_lock);
1583 writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi); 1579 iowrite8(ioread8(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
1584 e100_write_flush(nic); 1580 e100_write_flush(nic);
1585 spin_unlock_irq(&nic->cmd_lock); 1581 spin_unlock_irq(&nic->cmd_lock);
1586 1582
@@ -1746,19 +1742,11 @@ static int e100_alloc_cbs(struct nic *nic)
1746 return 0; 1742 return 0;
1747} 1743}
1748 1744
1749static inline void e100_start_receiver(struct nic *nic, struct rx *rx) 1745static inline void e100_start_receiver(struct nic *nic)
1750{ 1746{
1751 if(!nic->rxs) return; 1747 /* Start if RFA is non-NULL */
1752 if(RU_SUSPENDED != nic->ru_running) return; 1748 if(nic->rx_to_clean->skb)
1753 1749 e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr);
1754 /* handle init time starts */
1755 if(!rx) rx = nic->rxs;
1756
1757 /* (Re)start RU if suspended or idle and RFA is non-NULL */
1758 if(rx->skb) {
1759 e100_exec_cmd(nic, ruc_start, rx->dma_addr);
1760 nic->ru_running = RU_RUNNING;
1761 }
1762} 1750}
1763 1751
1764#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) 1752#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
@@ -1787,7 +1775,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1787 put_unaligned(cpu_to_le32(rx->dma_addr), 1775 put_unaligned(cpu_to_le32(rx->dma_addr),
1788 (u32 *)&prev_rfd->link); 1776 (u32 *)&prev_rfd->link);
1789 wmb(); 1777 wmb();
1790 prev_rfd->command &= ~cpu_to_le16(cb_el); 1778 prev_rfd->command &= ~cpu_to_le16(cb_el & cb_s);
1791 pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, 1779 pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
1792 sizeof(struct rfd), PCI_DMA_TODEVICE); 1780 sizeof(struct rfd), PCI_DMA_TODEVICE);
1793 } 1781 }
@@ -1825,10 +1813,6 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
1825 pci_unmap_single(nic->pdev, rx->dma_addr, 1813 pci_unmap_single(nic->pdev, rx->dma_addr,
1826 RFD_BUF_LEN, PCI_DMA_FROMDEVICE); 1814 RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
1827 1815
1828 /* this allows for a fast restart without re-enabling interrupts */
1829 if(le16_to_cpu(rfd->command) & cb_el)
1830 nic->ru_running = RU_SUSPENDED;
1831
1832 /* Pull off the RFD and put the actual data (minus eth hdr) */ 1816 /* Pull off the RFD and put the actual data (minus eth hdr) */
1833 skb_reserve(skb, sizeof(struct rfd)); 1817 skb_reserve(skb, sizeof(struct rfd));
1834 skb_put(skb, actual_size); 1818 skb_put(skb, actual_size);
@@ -1859,45 +1843,18 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
1859 unsigned int work_to_do) 1843 unsigned int work_to_do)
1860{ 1844{
1861 struct rx *rx; 1845 struct rx *rx;
1862 int restart_required = 0;
1863 struct rx *rx_to_start = NULL;
1864
1865 /* are we already rnr? then pay attention!!! this ensures that
1866 * the state machine progression never allows a start with a
1867 * partially cleaned list, avoiding a race between hardware
1868 * and rx_to_clean when in NAPI mode */
1869 if(RU_SUSPENDED == nic->ru_running)
1870 restart_required = 1;
1871 1846
1872 /* Indicate newly arrived packets */ 1847 /* Indicate newly arrived packets */
1873 for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { 1848 for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
1874 int err = e100_rx_indicate(nic, rx, work_done, work_to_do); 1849 if(e100_rx_indicate(nic, rx, work_done, work_to_do))
1875 if(-EAGAIN == err) {
1876 /* hit quota so have more work to do, restart once
1877 * cleanup is complete */
1878 restart_required = 0;
1879 break;
1880 } else if(-ENODATA == err)
1881 break; /* No more to clean */ 1850 break; /* No more to clean */
1882 } 1851 }
1883 1852
1884 /* save our starting point as the place we'll restart the receiver */
1885 if(restart_required)
1886 rx_to_start = nic->rx_to_clean;
1887
1888 /* Alloc new skbs to refill list */ 1853 /* Alloc new skbs to refill list */
1889 for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { 1854 for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
1890 if(unlikely(e100_rx_alloc_skb(nic, rx))) 1855 if(unlikely(e100_rx_alloc_skb(nic, rx)))
1891 break; /* Better luck next time (see watchdog) */ 1856 break; /* Better luck next time (see watchdog) */
1892 } 1857 }
1893
1894 if(restart_required) {
1895 // ack the rnr?
1896 writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
1897 e100_start_receiver(nic, rx_to_start);
1898 if(work_done)
1899 (*work_done)++;
1900 }
1901} 1858}
1902 1859
1903static void e100_rx_clean_list(struct nic *nic) 1860static void e100_rx_clean_list(struct nic *nic)
@@ -1905,8 +1862,6 @@ static void e100_rx_clean_list(struct nic *nic)
1905 struct rx *rx; 1862 struct rx *rx;
1906 unsigned int i, count = nic->params.rfds.count; 1863 unsigned int i, count = nic->params.rfds.count;
1907 1864
1908 nic->ru_running = RU_UNINITIALIZED;
1909
1910 if(nic->rxs) { 1865 if(nic->rxs) {
1911 for(rx = nic->rxs, i = 0; i < count; rx++, i++) { 1866 for(rx = nic->rxs, i = 0; i < count; rx++, i++) {
1912 if(rx->skb) { 1867 if(rx->skb) {
@@ -1928,7 +1883,6 @@ static int e100_rx_alloc_list(struct nic *nic)
1928 unsigned int i, count = nic->params.rfds.count; 1883 unsigned int i, count = nic->params.rfds.count;
1929 1884
1930 nic->rx_to_use = nic->rx_to_clean = NULL; 1885 nic->rx_to_use = nic->rx_to_clean = NULL;
1931 nic->ru_running = RU_UNINITIALIZED;
1932 1886
1933 if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC))) 1887 if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC)))
1934 return -ENOMEM; 1888 return -ENOMEM;
@@ -1943,7 +1897,6 @@ static int e100_rx_alloc_list(struct nic *nic)
1943 } 1897 }
1944 1898
1945 nic->rx_to_use = nic->rx_to_clean = nic->rxs; 1899 nic->rx_to_use = nic->rx_to_clean = nic->rxs;
1946 nic->ru_running = RU_SUSPENDED;
1947 1900
1948 return 0; 1901 return 0;
1949} 1902}
@@ -1952,7 +1905,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
1952{ 1905{
1953 struct net_device *netdev = dev_id; 1906 struct net_device *netdev = dev_id;
1954 struct nic *nic = netdev_priv(netdev); 1907 struct nic *nic = netdev_priv(netdev);
1955 u8 stat_ack = readb(&nic->csr->scb.stat_ack); 1908 u8 stat_ack = ioread8(&nic->csr->scb.stat_ack);
1956 1909
1957 DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack); 1910 DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack);
1958 1911
@@ -1961,11 +1914,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
1961 return IRQ_NONE; 1914 return IRQ_NONE;
1962 1915
1963 /* Ack interrupt(s) */ 1916 /* Ack interrupt(s) */
1964 writeb(stat_ack, &nic->csr->scb.stat_ack); 1917 iowrite8(stat_ack, &nic->csr->scb.stat_ack);
1965
1966 /* We hit Receive No Resource (RNR); restart RU after cleaning */
1967 if(stat_ack & stat_ack_rnr)
1968 nic->ru_running = RU_SUSPENDED;
1969 1918
1970 if(likely(netif_rx_schedule_prep(netdev))) { 1919 if(likely(netif_rx_schedule_prep(netdev))) {
1971 e100_disable_irq(nic); 1920 e100_disable_irq(nic);
@@ -2058,7 +2007,7 @@ static int e100_up(struct nic *nic)
2058 if((err = e100_hw_init(nic))) 2007 if((err = e100_hw_init(nic)))
2059 goto err_clean_cbs; 2008 goto err_clean_cbs;
2060 e100_set_multicast_list(nic->netdev); 2009 e100_set_multicast_list(nic->netdev);
2061 e100_start_receiver(nic, NULL); 2010 e100_start_receiver(nic);
2062 mod_timer(&nic->watchdog, jiffies); 2011 mod_timer(&nic->watchdog, jiffies);
2063 if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, 2012 if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED,
2064 nic->netdev->name, nic->netdev))) 2013 nic->netdev->name, nic->netdev)))
@@ -2107,7 +2056,7 @@ static void e100_tx_timeout_task(struct work_struct *work)
2107 struct net_device *netdev = nic->netdev; 2056 struct net_device *netdev = nic->netdev;
2108 2057
2109 DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", 2058 DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
2110 readb(&nic->csr->scb.status)); 2059 ioread8(&nic->csr->scb.status));
2111 e100_down(netdev_priv(netdev)); 2060 e100_down(netdev_priv(netdev));
2112 e100_up(netdev_priv(netdev)); 2061 e100_up(netdev_priv(netdev));
2113} 2062}
@@ -2139,7 +2088,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
2139 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 2088 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
2140 BMCR_LOOPBACK); 2089 BMCR_LOOPBACK);
2141 2090
2142 e100_start_receiver(nic, NULL); 2091 e100_start_receiver(nic);
2143 2092
2144 if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { 2093 if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) {
2145 err = -ENOMEM; 2094 err = -ENOMEM;
@@ -2230,9 +2179,9 @@ static void e100_get_regs(struct net_device *netdev,
2230 int i; 2179 int i;
2231 2180
2232 regs->version = (1 << 24) | nic->rev_id; 2181 regs->version = (1 << 24) | nic->rev_id;
2233 buff[0] = readb(&nic->csr->scb.cmd_hi) << 24 | 2182 buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 |
2234 readb(&nic->csr->scb.cmd_lo) << 16 | 2183 ioread8(&nic->csr->scb.cmd_lo) << 16 |
2235 readw(&nic->csr->scb.status); 2184 ioread16(&nic->csr->scb.status);
2236 for(i = E100_PHY_REGS; i >= 0; i--) 2185 for(i = E100_PHY_REGS; i >= 0; i--)
2237 buff[1 + E100_PHY_REGS - i] = 2186 buff[1 + E100_PHY_REGS - i] =
2238 mdio_read(netdev, nic->mii.phy_id, i); 2187 mdio_read(netdev, nic->mii.phy_id, i);
@@ -2604,7 +2553,10 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2604 SET_MODULE_OWNER(netdev); 2553 SET_MODULE_OWNER(netdev);
2605 SET_NETDEV_DEV(netdev, &pdev->dev); 2554 SET_NETDEV_DEV(netdev, &pdev->dev);
2606 2555
2607 nic->csr = ioremap(pci_resource_start(pdev, 0), sizeof(struct csr)); 2556 if (use_io)
2557 DPRINTK(PROBE, INFO, "using i/o access mode\n");
2558
2559 nic->csr = pci_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr));
2608 if(!nic->csr) { 2560 if(!nic->csr) {
2609 DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n"); 2561 DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n");
2610 err = -ENOMEM; 2562 err = -ENOMEM;
@@ -2651,11 +2603,16 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2651 2603
2652 memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN); 2604 memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
2653 memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN); 2605 memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
2654 if(!is_valid_ether_addr(netdev->perm_addr)) { 2606 if (!is_valid_ether_addr(netdev->perm_addr)) {
2655 DPRINTK(PROBE, ERR, "Invalid MAC address from " 2607 if (!eeprom_bad_csum_allow) {
2656 "EEPROM, aborting.\n"); 2608 DPRINTK(PROBE, ERR, "Invalid MAC address from "
2657 err = -EAGAIN; 2609 "EEPROM, aborting.\n");
2658 goto err_out_free; 2610 err = -EAGAIN;
2611 goto err_out_free;
2612 } else {
2613 DPRINTK(PROBE, ERR, "Invalid MAC address from EEPROM, "
2614 "you MUST configure one.\n");
2615 }
2659 } 2616 }
2660 2617
2661 /* Wol magic packet can be enabled from eeprom */ 2618 /* Wol magic packet can be enabled from eeprom */
@@ -2676,7 +2633,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2676 2633
2677 DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " 2634 DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, "
2678 "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", 2635 "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
2679 (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, 2636 (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), pdev->irq,
2680 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], 2637 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
2681 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); 2638 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
2682 2639
@@ -2685,7 +2642,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2685err_out_free: 2642err_out_free:
2686 e100_free(nic); 2643 e100_free(nic);
2687err_out_iounmap: 2644err_out_iounmap:
2688 iounmap(nic->csr); 2645 pci_iounmap(pdev, nic->csr);
2689err_out_free_res: 2646err_out_free_res:
2690 pci_release_regions(pdev); 2647 pci_release_regions(pdev);
2691err_out_disable_pdev: 2648err_out_disable_pdev:
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index dd4b728ac4b5..a9ea67e75c1b 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -155,9 +155,6 @@ struct e1000_adapter;
155/* Number of packet split data buffers (not including the header buffer) */ 155/* Number of packet split data buffers (not including the header buffer) */
156#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1 156#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
157 157
158/* only works for sizes that are powers of 2 */
159#define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
160
161/* wrapper around a pointer to a socket buffer, 158/* wrapper around a pointer to a socket buffer,
162 * so a DMA handle can be stored along with the buffer */ 159 * so a DMA handle can be stored along with the buffer */
163struct e1000_buffer { 160struct e1000_buffer {
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 6777887295f5..bb08375b5f13 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -654,14 +654,11 @@ e1000_set_ringparam(struct net_device *netdev,
654 e1000_mac_type mac_type = adapter->hw.mac_type; 654 e1000_mac_type mac_type = adapter->hw.mac_type;
655 struct e1000_tx_ring *txdr, *tx_old; 655 struct e1000_tx_ring *txdr, *tx_old;
656 struct e1000_rx_ring *rxdr, *rx_old; 656 struct e1000_rx_ring *rxdr, *rx_old;
657 int i, err, tx_ring_size, rx_ring_size; 657 int i, err;
658 658
659 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 659 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
660 return -EINVAL; 660 return -EINVAL;
661 661
662 tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
663 rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
664
665 while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) 662 while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
666 msleep(1); 663 msleep(1);
667 664
@@ -672,11 +669,11 @@ e1000_set_ringparam(struct net_device *netdev,
672 rx_old = adapter->rx_ring; 669 rx_old = adapter->rx_ring;
673 670
674 err = -ENOMEM; 671 err = -ENOMEM;
675 txdr = kzalloc(tx_ring_size, GFP_KERNEL); 672 txdr = kcalloc(adapter->num_tx_queues, sizeof(struct e1000_tx_ring), GFP_KERNEL);
676 if (!txdr) 673 if (!txdr)
677 goto err_alloc_tx; 674 goto err_alloc_tx;
678 675
679 rxdr = kzalloc(rx_ring_size, GFP_KERNEL); 676 rxdr = kcalloc(adapter->num_rx_queues, sizeof(struct e1000_rx_ring), GFP_KERNEL);
680 if (!rxdr) 677 if (!rxdr)
681 goto err_alloc_rx; 678 goto err_alloc_rx;
682 679
@@ -686,12 +683,12 @@ e1000_set_ringparam(struct net_device *netdev,
686 rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); 683 rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
687 rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? 684 rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
688 E1000_MAX_RXD : E1000_MAX_82544_RXD)); 685 E1000_MAX_RXD : E1000_MAX_82544_RXD));
689 E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); 686 rxdr->count = ALIGN(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
690 687
691 txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD); 688 txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD);
692 txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ? 689 txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ?
693 E1000_MAX_TXD : E1000_MAX_82544_TXD)); 690 E1000_MAX_TXD : E1000_MAX_82544_TXD));
694 E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 691 txdr->count = ALIGN(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
695 692
696 for (i = 0; i < adapter->num_tx_queues; i++) 693 for (i = 0; i < adapter->num_tx_queues; i++)
697 txdr[i].count = txdr->count; 694 txdr[i].count = txdr->count;
@@ -742,7 +739,7 @@ err_setup:
742 uint32_t pat, value; \ 739 uint32_t pat, value; \
743 uint32_t test[] = \ 740 uint32_t test[] = \
744 {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ 741 {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
745 for (pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \ 742 for (pat = 0; pat < ARRAY_SIZE(test); pat++) { \
746 E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \ 743 E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
747 value = E1000_READ_REG(&adapter->hw, R); \ 744 value = E1000_READ_REG(&adapter->hw, R); \
748 if (value != (test[pat] & W & M)) { \ 745 if (value != (test[pat] & W & M)) { \
@@ -1053,23 +1050,24 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
1053 struct e1000_rx_ring *rxdr = &adapter->test_rx_ring; 1050 struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
1054 struct pci_dev *pdev = adapter->pdev; 1051 struct pci_dev *pdev = adapter->pdev;
1055 uint32_t rctl; 1052 uint32_t rctl;
1056 int size, i, ret_val; 1053 int i, ret_val;
1057 1054
1058 /* Setup Tx descriptor ring and Tx buffers */ 1055 /* Setup Tx descriptor ring and Tx buffers */
1059 1056
1060 if (!txdr->count) 1057 if (!txdr->count)
1061 txdr->count = E1000_DEFAULT_TXD; 1058 txdr->count = E1000_DEFAULT_TXD;
1062 1059
1063 size = txdr->count * sizeof(struct e1000_buffer); 1060 if (!(txdr->buffer_info = kcalloc(txdr->count,
1064 if (!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { 1061 sizeof(struct e1000_buffer),
1062 GFP_KERNEL))) {
1065 ret_val = 1; 1063 ret_val = 1;
1066 goto err_nomem; 1064 goto err_nomem;
1067 } 1065 }
1068 memset(txdr->buffer_info, 0, size);
1069 1066
1070 txdr->size = txdr->count * sizeof(struct e1000_tx_desc); 1067 txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
1071 E1000_ROUNDUP(txdr->size, 4096); 1068 txdr->size = ALIGN(txdr->size, 4096);
1072 if (!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) { 1069 if (!(txdr->desc = pci_alloc_consistent(pdev, txdr->size,
1070 &txdr->dma))) {
1073 ret_val = 2; 1071 ret_val = 2;
1074 goto err_nomem; 1072 goto err_nomem;
1075 } 1073 }
@@ -1116,12 +1114,12 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
1116 if (!rxdr->count) 1114 if (!rxdr->count)
1117 rxdr->count = E1000_DEFAULT_RXD; 1115 rxdr->count = E1000_DEFAULT_RXD;
1118 1116
1119 size = rxdr->count * sizeof(struct e1000_buffer); 1117 if (!(rxdr->buffer_info = kcalloc(rxdr->count,
1120 if (!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { 1118 sizeof(struct e1000_buffer),
1119 GFP_KERNEL))) {
1121 ret_val = 4; 1120 ret_val = 4;
1122 goto err_nomem; 1121 goto err_nomem;
1123 } 1122 }
1124 memset(rxdr->buffer_info, 0, size);
1125 1123
1126 rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); 1124 rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
1127 if (!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) { 1125 if (!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 9267f16b1b32..3a03a74c0609 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -748,9 +748,9 @@ e1000_reset(struct e1000_adapter *adapter)
748 VLAN_TAG_SIZE; 748 VLAN_TAG_SIZE;
749 min_tx_space = min_rx_space; 749 min_tx_space = min_rx_space;
750 min_tx_space *= 2; 750 min_tx_space *= 2;
751 E1000_ROUNDUP(min_tx_space, 1024); 751 min_tx_space = ALIGN(min_tx_space, 1024);
752 min_tx_space >>= 10; 752 min_tx_space >>= 10;
753 E1000_ROUNDUP(min_rx_space, 1024); 753 min_rx_space = ALIGN(min_rx_space, 1024);
754 min_rx_space >>= 10; 754 min_rx_space >>= 10;
755 755
756 /* If current Tx allocation is less than the min Tx FIFO size, 756 /* If current Tx allocation is less than the min Tx FIFO size,
@@ -1354,31 +1354,27 @@ e1000_sw_init(struct e1000_adapter *adapter)
1354static int __devinit 1354static int __devinit
1355e1000_alloc_queues(struct e1000_adapter *adapter) 1355e1000_alloc_queues(struct e1000_adapter *adapter)
1356{ 1356{
1357 int size; 1357 adapter->tx_ring = kcalloc(adapter->num_tx_queues,
1358 1358 sizeof(struct e1000_tx_ring), GFP_KERNEL);
1359 size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
1360 adapter->tx_ring = kmalloc(size, GFP_KERNEL);
1361 if (!adapter->tx_ring) 1359 if (!adapter->tx_ring)
1362 return -ENOMEM; 1360 return -ENOMEM;
1363 memset(adapter->tx_ring, 0, size);
1364 1361
1365 size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues; 1362 adapter->rx_ring = kcalloc(adapter->num_rx_queues,
1366 adapter->rx_ring = kmalloc(size, GFP_KERNEL); 1363 sizeof(struct e1000_rx_ring), GFP_KERNEL);
1367 if (!adapter->rx_ring) { 1364 if (!adapter->rx_ring) {
1368 kfree(adapter->tx_ring); 1365 kfree(adapter->tx_ring);
1369 return -ENOMEM; 1366 return -ENOMEM;
1370 } 1367 }
1371 memset(adapter->rx_ring, 0, size);
1372 1368
1373#ifdef CONFIG_E1000_NAPI 1369#ifdef CONFIG_E1000_NAPI
1374 size = sizeof(struct net_device) * adapter->num_rx_queues; 1370 adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
1375 adapter->polling_netdev = kmalloc(size, GFP_KERNEL); 1371 sizeof(struct net_device),
1372 GFP_KERNEL);
1376 if (!adapter->polling_netdev) { 1373 if (!adapter->polling_netdev) {
1377 kfree(adapter->tx_ring); 1374 kfree(adapter->tx_ring);
1378 kfree(adapter->rx_ring); 1375 kfree(adapter->rx_ring);
1379 return -ENOMEM; 1376 return -ENOMEM;
1380 } 1377 }
1381 memset(adapter->polling_netdev, 0, size);
1382#endif 1378#endif
1383 1379
1384 return E1000_SUCCESS; 1380 return E1000_SUCCESS;
@@ -1560,7 +1556,7 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
1560 /* round up to nearest 4K */ 1556 /* round up to nearest 4K */
1561 1557
1562 txdr->size = txdr->count * sizeof(struct e1000_tx_desc); 1558 txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
1563 E1000_ROUNDUP(txdr->size, 4096); 1559 txdr->size = ALIGN(txdr->size, 4096);
1564 1560
1565 txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); 1561 txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
1566 if (!txdr->desc) { 1562 if (!txdr->desc) {
@@ -1774,18 +1770,18 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
1774 } 1770 }
1775 memset(rxdr->buffer_info, 0, size); 1771 memset(rxdr->buffer_info, 0, size);
1776 1772
1777 size = sizeof(struct e1000_ps_page) * rxdr->count; 1773 rxdr->ps_page = kcalloc(rxdr->count, sizeof(struct e1000_ps_page),
1778 rxdr->ps_page = kmalloc(size, GFP_KERNEL); 1774 GFP_KERNEL);
1779 if (!rxdr->ps_page) { 1775 if (!rxdr->ps_page) {
1780 vfree(rxdr->buffer_info); 1776 vfree(rxdr->buffer_info);
1781 DPRINTK(PROBE, ERR, 1777 DPRINTK(PROBE, ERR,
1782 "Unable to allocate memory for the receive descriptor ring\n"); 1778 "Unable to allocate memory for the receive descriptor ring\n");
1783 return -ENOMEM; 1779 return -ENOMEM;
1784 } 1780 }
1785 memset(rxdr->ps_page, 0, size);
1786 1781
1787 size = sizeof(struct e1000_ps_page_dma) * rxdr->count; 1782 rxdr->ps_page_dma = kcalloc(rxdr->count,
1788 rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL); 1783 sizeof(struct e1000_ps_page_dma),
1784 GFP_KERNEL);
1789 if (!rxdr->ps_page_dma) { 1785 if (!rxdr->ps_page_dma) {
1790 vfree(rxdr->buffer_info); 1786 vfree(rxdr->buffer_info);
1791 kfree(rxdr->ps_page); 1787 kfree(rxdr->ps_page);
@@ -1793,7 +1789,6 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
1793 "Unable to allocate memory for the receive descriptor ring\n"); 1789 "Unable to allocate memory for the receive descriptor ring\n");
1794 return -ENOMEM; 1790 return -ENOMEM;
1795 } 1791 }
1796 memset(rxdr->ps_page_dma, 0, size);
1797 1792
1798 if (adapter->hw.mac_type <= e1000_82547_rev_2) 1793 if (adapter->hw.mac_type <= e1000_82547_rev_2)
1799 desc_len = sizeof(struct e1000_rx_desc); 1794 desc_len = sizeof(struct e1000_rx_desc);
@@ -1803,7 +1798,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
1803 /* Round up to nearest 4K */ 1798 /* Round up to nearest 4K */
1804 1799
1805 rxdr->size = rxdr->count * desc_len; 1800 rxdr->size = rxdr->count * desc_len;
1806 E1000_ROUNDUP(rxdr->size, 4096); 1801 rxdr->size = ALIGN(rxdr->size, 4096);
1807 1802
1808 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); 1803 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
1809 1804
@@ -2667,7 +2662,7 @@ e1000_watchdog(unsigned long data)
2667 2662
2668 netif_carrier_on(netdev); 2663 netif_carrier_on(netdev);
2669 netif_wake_queue(netdev); 2664 netif_wake_queue(netdev);
2670 mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); 2665 mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
2671 adapter->smartspeed = 0; 2666 adapter->smartspeed = 0;
2672 } else { 2667 } else {
2673 /* make sure the receive unit is started */ 2668 /* make sure the receive unit is started */
@@ -2684,7 +2679,7 @@ e1000_watchdog(unsigned long data)
2684 DPRINTK(LINK, INFO, "NIC Link is Down\n"); 2679 DPRINTK(LINK, INFO, "NIC Link is Down\n");
2685 netif_carrier_off(netdev); 2680 netif_carrier_off(netdev);
2686 netif_stop_queue(netdev); 2681 netif_stop_queue(netdev);
2687 mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); 2682 mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
2688 2683
2689 /* 80003ES2LAN workaround-- 2684 /* 80003ES2LAN workaround--
2690 * For packet buffer work-around on link down event; 2685 * For packet buffer work-around on link down event;
@@ -2736,7 +2731,7 @@ e1000_watchdog(unsigned long data)
2736 e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0); 2731 e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
2737 2732
2738 /* Reset the timer */ 2733 /* Reset the timer */
2739 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 2734 mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
2740} 2735}
2741 2736
2742enum latency_range { 2737enum latency_range {
@@ -3175,7 +3170,7 @@ e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
3175 uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head; 3170 uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
3176 uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR; 3171 uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
3177 3172
3178 E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR); 3173 skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
3179 3174
3180 if (adapter->link_duplex != HALF_DUPLEX) 3175 if (adapter->link_duplex != HALF_DUPLEX)
3181 goto no_fifo_stall_required; 3176 goto no_fifo_stall_required;
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index f8862e203ac9..f485874a63f5 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -305,7 +305,7 @@ e1000_check_options(struct e1000_adapter *adapter)
305 if (num_TxDescriptors > bd) { 305 if (num_TxDescriptors > bd) {
306 tx_ring->count = TxDescriptors[bd]; 306 tx_ring->count = TxDescriptors[bd];
307 e1000_validate_option(&tx_ring->count, &opt, adapter); 307 e1000_validate_option(&tx_ring->count, &opt, adapter);
308 E1000_ROUNDUP(tx_ring->count, 308 tx_ring->count = ALIGN(tx_ring->count,
309 REQ_TX_DESCRIPTOR_MULTIPLE); 309 REQ_TX_DESCRIPTOR_MULTIPLE);
310 } else { 310 } else {
311 tx_ring->count = opt.def; 311 tx_ring->count = opt.def;
@@ -331,7 +331,7 @@ e1000_check_options(struct e1000_adapter *adapter)
331 if (num_RxDescriptors > bd) { 331 if (num_RxDescriptors > bd) {
332 rx_ring->count = RxDescriptors[bd]; 332 rx_ring->count = RxDescriptors[bd];
333 e1000_validate_option(&rx_ring->count, &opt, adapter); 333 e1000_validate_option(&rx_ring->count, &opt, adapter);
334 E1000_ROUNDUP(rx_ring->count, 334 rx_ring->count = ALIGN(rx_ring->count,
335 REQ_RX_DESCRIPTOR_MULTIPLE); 335 REQ_RX_DESCRIPTOR_MULTIPLE);
336 } else { 336 } else {
337 rx_ring->count = opt.def; 337 rx_ring->count = opt.def;
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 8aaf5ec0c360..7934ea37f944 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -115,6 +115,7 @@
115#include <linux/mca-legacy.h> 115#include <linux/mca-legacy.h>
116#include <linux/spinlock.h> 116#include <linux/spinlock.h>
117#include <linux/bitops.h> 117#include <linux/bitops.h>
118#include <linux/jiffies.h>
118 119
119#include <asm/system.h> 120#include <asm/system.h>
120#include <asm/io.h> 121#include <asm/io.h>
@@ -556,7 +557,7 @@ static void unstick_cu(struct net_device *dev)
556 557
557 if (lp->started) 558 if (lp->started)
558 { 559 {
559 if ((jiffies - dev->trans_start)>50) 560 if (time_after(jiffies, dev->trans_start + 50))
560 { 561 {
561 if (lp->tx_link==lp->last_tx_restart) 562 if (lp->tx_link==lp->last_tx_restart)
562 { 563 {
@@ -612,7 +613,7 @@ static void unstick_cu(struct net_device *dev)
612 } 613 }
613 else 614 else
614 { 615 {
615 if ((jiffies-lp->init_time)>10) 616 if (time_after(jiffies, lp->init_time + 10))
616 { 617 {
617 unsigned short status = scb_status(dev); 618 unsigned short status = scb_status(dev);
618 printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n", 619 printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
@@ -776,7 +777,7 @@ static unsigned short eexp_start_irq(struct net_device *dev,
776static void eexp_cmd_clear(struct net_device *dev) 777static void eexp_cmd_clear(struct net_device *dev)
777{ 778{
778 unsigned long int oldtime = jiffies; 779 unsigned long int oldtime = jiffies;
779 while (scb_rdcmd(dev) && ((jiffies-oldtime)<10)); 780 while (scb_rdcmd(dev) && (time_before(jiffies, oldtime + 10)));
780 if (scb_rdcmd(dev)) { 781 if (scb_rdcmd(dev)) {
781 printk("%s: command didn't clear\n", dev->name); 782 printk("%s: command didn't clear\n", dev->name);
782 } 783 }
@@ -1649,7 +1650,7 @@ eexp_set_multicast(struct net_device *dev)
1649#endif 1650#endif
1650 oj = jiffies; 1651 oj = jiffies;
1651 while ((SCB_CUstat(scb_status(dev)) == 2) && 1652 while ((SCB_CUstat(scb_status(dev)) == 2) &&
1652 ((jiffies-oj) < 2000)); 1653 (time_before(jiffies, oj + 2000)));
1653 if (SCB_CUstat(scb_status(dev)) == 2) 1654 if (SCB_CUstat(scb_status(dev)) == 2)
1654 printk("%s: warning, CU didn't stop\n", dev->name); 1655 printk("%s: warning, CU didn't stop\n", dev->name);
1655 lp->started &= ~(STARTED_CU); 1656 lp->started &= ~(STARTED_CU);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 42295d61ecd8..602872dbe15f 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41#define DRV_NAME "ehea" 41#define DRV_NAME "ehea"
42#define DRV_VERSION "EHEA_0046" 42#define DRV_VERSION "EHEA_0058"
43 43
44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ 44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -78,10 +78,7 @@
78#define EHEA_RQ2_PKT_SIZE 1522 78#define EHEA_RQ2_PKT_SIZE 1522
79#define EHEA_L_PKT_SIZE 256 /* low latency */ 79#define EHEA_L_PKT_SIZE 256 /* low latency */
80 80
81#define EHEA_POLL_MAX_RWQE 1000
82
83/* Send completion signaling */ 81/* Send completion signaling */
84#define EHEA_SIG_IV_LONG 1
85 82
86/* Protection Domain Identifier */ 83/* Protection Domain Identifier */
87#define EHEA_PD_ID 0xaabcdeff 84#define EHEA_PD_ID 0xaabcdeff
@@ -108,11 +105,7 @@
108#define EHEA_CACHE_LINE 128 105#define EHEA_CACHE_LINE 128
109 106
110/* Memory Regions */ 107/* Memory Regions */
111#define EHEA_MR_MAX_TX_PAGES 20
112#define EHEA_MR_TX_DATA_PN 3
113#define EHEA_MR_ACC_CTRL 0x00800000 108#define EHEA_MR_ACC_CTRL 0x00800000
114#define EHEA_RWQES_PER_MR_RQ2 10
115#define EHEA_RWQES_PER_MR_RQ3 10
116 109
117#define EHEA_WATCH_DOG_TIMEOUT 10*HZ 110#define EHEA_WATCH_DOG_TIMEOUT 10*HZ
118 111
@@ -311,6 +304,7 @@ struct ehea_cq {
311 * Memory Region 304 * Memory Region
312 */ 305 */
313struct ehea_mr { 306struct ehea_mr {
307 struct ehea_adapter *adapter;
314 u64 handle; 308 u64 handle;
315 u64 vaddr; 309 u64 vaddr;
316 u32 lkey; 310 u32 lkey;
@@ -319,17 +313,12 @@ struct ehea_mr {
319/* 313/*
320 * Port state information 314 * Port state information
321 */ 315 */
322struct port_state { 316struct port_stats {
323 int poll_max_processed;
324 int poll_receive_errors; 317 int poll_receive_errors;
325 int ehea_poll;
326 int queue_stopped; 318 int queue_stopped;
327 int min_swqe_avail; 319 int err_tcp_cksum;
328 u64 sqc_stop_sum; 320 int err_ip_cksum;
329 int pkt_send; 321 int err_frame_crc;
330 int pkt_xmit;
331 int send_tasklet;
332 int nwqe;
333}; 322};
334 323
335#define EHEA_IRQ_NAME_SIZE 20 324#define EHEA_IRQ_NAME_SIZE 20
@@ -348,6 +337,7 @@ struct ehea_q_skb_arr {
348 * Port resources 337 * Port resources
349 */ 338 */
350struct ehea_port_res { 339struct ehea_port_res {
340 struct port_stats p_stats;
351 struct ehea_mr send_mr; /* send memory region */ 341 struct ehea_mr send_mr; /* send memory region */
352 struct ehea_mr recv_mr; /* receive memory region */ 342 struct ehea_mr recv_mr; /* receive memory region */
353 spinlock_t xmit_lock; 343 spinlock_t xmit_lock;
@@ -357,9 +347,8 @@ struct ehea_port_res {
357 struct ehea_qp *qp; 347 struct ehea_qp *qp;
358 struct ehea_cq *send_cq; 348 struct ehea_cq *send_cq;
359 struct ehea_cq *recv_cq; 349 struct ehea_cq *recv_cq;
360 struct ehea_eq *send_eq; 350 struct ehea_eq *eq;
361 struct ehea_eq *recv_eq; 351 struct net_device *d_netdev;
362 spinlock_t send_lock;
363 struct ehea_q_skb_arr rq1_skba; 352 struct ehea_q_skb_arr rq1_skba;
364 struct ehea_q_skb_arr rq2_skba; 353 struct ehea_q_skb_arr rq2_skba;
365 struct ehea_q_skb_arr rq3_skba; 354 struct ehea_q_skb_arr rq3_skba;
@@ -369,21 +358,18 @@ struct ehea_port_res {
369 int swqe_refill_th; 358 int swqe_refill_th;
370 atomic_t swqe_avail; 359 atomic_t swqe_avail;
371 int swqe_ll_count; 360 int swqe_ll_count;
372 int swqe_count;
373 u32 swqe_id_counter; 361 u32 swqe_id_counter;
374 u64 tx_packets; 362 u64 tx_packets;
375 struct tasklet_struct send_comp_task;
376 spinlock_t recv_lock;
377 struct port_state p_state;
378 u64 rx_packets; 363 u64 rx_packets;
379 u32 poll_counter; 364 u32 poll_counter;
380}; 365};
381 366
382 367
368#define EHEA_MAX_PORTS 16
383struct ehea_adapter { 369struct ehea_adapter {
384 u64 handle; 370 u64 handle;
385 u8 num_ports; 371 struct ibmebus_dev *ebus_dev;
386 struct ehea_port *port[16]; 372 struct ehea_port *port[EHEA_MAX_PORTS];
387 struct ehea_eq *neq; /* notification event queue */ 373 struct ehea_eq *neq; /* notification event queue */
388 struct workqueue_struct *ehea_wq; 374 struct workqueue_struct *ehea_wq;
389 struct tasklet_struct neq_tasklet; 375 struct tasklet_struct neq_tasklet;
@@ -406,7 +392,7 @@ struct ehea_port {
406 struct net_device *netdev; 392 struct net_device *netdev;
407 struct net_device_stats stats; 393 struct net_device_stats stats;
408 struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; 394 struct ehea_port_res port_res[EHEA_MAX_PORT_RES];
409 struct device_node *of_dev_node; /* Open Firmware Device Node */ 395 struct of_device ofdev; /* Open Firmware Device */
410 struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ 396 struct ehea_mc_list *mc_list; /* Multicast MAC addresses */
411 struct vlan_group *vgrp; 397 struct vlan_group *vgrp;
412 struct ehea_eq *qp_eq; 398 struct ehea_eq *qp_eq;
@@ -415,7 +401,9 @@ struct ehea_port {
415 char int_aff_name[EHEA_IRQ_NAME_SIZE]; 401 char int_aff_name[EHEA_IRQ_NAME_SIZE];
416 int allmulti; /* Indicates IFF_ALLMULTI state */ 402 int allmulti; /* Indicates IFF_ALLMULTI state */
417 int promisc; /* Indicates IFF_PROMISC state */ 403 int promisc; /* Indicates IFF_PROMISC state */
404 int num_tx_qps;
418 int num_add_tx_qps; 405 int num_add_tx_qps;
406 int num_mcs;
419 int resets; 407 int resets;
420 u64 mac_addr; 408 u64 mac_addr;
421 u32 logical_port_id; 409 u32 logical_port_id;
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 9f57c2e78ced..decec8cfe96b 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -144,8 +144,8 @@ static int ehea_nway_reset(struct net_device *dev)
144static void ehea_get_drvinfo(struct net_device *dev, 144static void ehea_get_drvinfo(struct net_device *dev,
145 struct ethtool_drvinfo *info) 145 struct ethtool_drvinfo *info)
146{ 146{
147 strlcpy(info->driver, DRV_NAME, sizeof(info->driver) - 1); 147 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
148 strlcpy(info->version, DRV_VERSION, sizeof(info->version) - 1); 148 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
149} 149}
150 150
151static u32 ehea_get_msglevel(struct net_device *dev) 151static u32 ehea_get_msglevel(struct net_device *dev)
@@ -166,33 +166,23 @@ static u32 ehea_get_rx_csum(struct net_device *dev)
166} 166}
167 167
168static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = { 168static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
169 {"poll_max_processed"},
170 {"queue_stopped"},
171 {"min_swqe_avail"},
172 {"poll_receive_err"},
173 {"pkt_send"},
174 {"pkt_xmit"},
175 {"send_tasklet"},
176 {"ehea_poll"},
177 {"nwqe"},
178 {"swqe_available_0"},
179 {"sig_comp_iv"}, 169 {"sig_comp_iv"},
180 {"swqe_refill_th"}, 170 {"swqe_refill_th"},
181 {"port resets"}, 171 {"port resets"},
182 {"rxo"}, 172 {"Receive errors"},
183 {"rx64"}, 173 {"TCP cksum errors"},
184 {"rx65"}, 174 {"IP cksum errors"},
185 {"rx128"}, 175 {"Frame cksum errors"},
186 {"rx256"}, 176 {"num SQ stopped"},
187 {"rx512"}, 177 {"SQ stopped"},
188 {"rx1024"}, 178 {"PR0 free_swqes"},
189 {"txo"}, 179 {"PR1 free_swqes"},
190 {"tx64"}, 180 {"PR2 free_swqes"},
191 {"tx65"}, 181 {"PR3 free_swqes"},
192 {"tx128"}, 182 {"PR4 free_swqes"},
193 {"tx256"}, 183 {"PR5 free_swqes"},
194 {"tx512"}, 184 {"PR6 free_swqes"},
195 {"tx1024"}, 185 {"PR7 free_swqes"},
196}; 186};
197 187
198static void ehea_get_strings(struct net_device *dev, u32 stringset, u8 *data) 188static void ehea_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -211,63 +201,44 @@ static int ehea_get_stats_count(struct net_device *dev)
211static void ehea_get_ethtool_stats(struct net_device *dev, 201static void ehea_get_ethtool_stats(struct net_device *dev,
212 struct ethtool_stats *stats, u64 *data) 202 struct ethtool_stats *stats, u64 *data)
213{ 203{
214 u64 hret; 204 int i, k, tmp;
215 int i;
216 struct ehea_port *port = netdev_priv(dev); 205 struct ehea_port *port = netdev_priv(dev);
217 struct ehea_adapter *adapter = port->adapter;
218 struct ehea_port_res *pr = &port->port_res[0];
219 struct port_state *p_state = &pr->p_state;
220 struct hcp_ehea_port_cb6 *cb6;
221 206
222 for (i = 0; i < ehea_get_stats_count(dev); i++) 207 for (i = 0; i < ehea_get_stats_count(dev); i++)
223 data[i] = 0; 208 data[i] = 0;
224
225 i = 0; 209 i = 0;
226 210
227 data[i++] = p_state->poll_max_processed;
228 data[i++] = p_state->queue_stopped;
229 data[i++] = p_state->min_swqe_avail;
230 data[i++] = p_state->poll_receive_errors;
231 data[i++] = p_state->pkt_send;
232 data[i++] = p_state->pkt_xmit;
233 data[i++] = p_state->send_tasklet;
234 data[i++] = p_state->ehea_poll;
235 data[i++] = p_state->nwqe;
236 data[i++] = atomic_read(&port->port_res[0].swqe_avail);
237 data[i++] = port->sig_comp_iv; 211 data[i++] = port->sig_comp_iv;
238 data[i++] = port->port_res[0].swqe_refill_th; 212 data[i++] = port->port_res[0].swqe_refill_th;
239 data[i++] = port->resets; 213 data[i++] = port->resets;
240 214
241 cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL); 215 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
242 if (!cb6) { 216 tmp += port->port_res[k].p_stats.poll_receive_errors;
243 ehea_error("no mem for cb6"); 217 data[i++] = tmp;
244 return; 218
245 } 219 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
220 tmp += port->port_res[k].p_stats.err_tcp_cksum;
221 data[i++] = tmp;
222
223 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
224 tmp += port->port_res[k].p_stats.err_ip_cksum;
225 data[i++] = tmp;
226
227 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
228 tmp += port->port_res[k].p_stats.err_frame_crc;
229 data[i++] = tmp;
230
231 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
232 tmp += port->port_res[k].p_stats.queue_stopped;
233 data[i++] = tmp;
234
235 for (k = 0, tmp = 0; k < EHEA_MAX_PORT_RES; k++)
236 tmp |= port->port_res[k].queue_stopped;
237 data[i++] = tmp;
238
239 for (k = 0; k < 8; k++)
240 data[i++] = atomic_read(&port->port_res[k].swqe_avail);
246 241
247 hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id,
248 H_PORT_CB6, H_PORT_CB6_ALL, cb6);
249 if (netif_msg_hw(port))
250 ehea_dump(cb6, sizeof(*cb6), "ehea_get_ethtool_stats");
251
252 if (hret == H_SUCCESS) {
253 data[i++] = cb6->rxo;
254 data[i++] = cb6->rx64;
255 data[i++] = cb6->rx65;
256 data[i++] = cb6->rx128;
257 data[i++] = cb6->rx256;
258 data[i++] = cb6->rx512;
259 data[i++] = cb6->rx1024;
260 data[i++] = cb6->txo;
261 data[i++] = cb6->tx64;
262 data[i++] = cb6->tx65;
263 data[i++] = cb6->tx128;
264 data[i++] = cb6->tx256;
265 data[i++] = cb6->tx512;
266 data[i++] = cb6->tx1024;
267 } else
268 ehea_error("query_ehea_port failed");
269
270 kfree(cb6);
271} 242}
272 243
273const struct ethtool_ops ehea_ethtool_ops = { 244const struct ethtool_ops ehea_ethtool_ops = {
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 58364a0ff378..c7a5614e66c0 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -51,13 +51,18 @@ static int rq1_entries = EHEA_DEF_ENTRIES_RQ1;
51static int rq2_entries = EHEA_DEF_ENTRIES_RQ2; 51static int rq2_entries = EHEA_DEF_ENTRIES_RQ2;
52static int rq3_entries = EHEA_DEF_ENTRIES_RQ3; 52static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
53static int sq_entries = EHEA_DEF_ENTRIES_SQ; 53static int sq_entries = EHEA_DEF_ENTRIES_SQ;
54static int use_mcs = 0;
55static int num_tx_qps = EHEA_NUM_TX_QP;
54 56
55module_param(msg_level, int, 0); 57module_param(msg_level, int, 0);
56module_param(rq1_entries, int, 0); 58module_param(rq1_entries, int, 0);
57module_param(rq2_entries, int, 0); 59module_param(rq2_entries, int, 0);
58module_param(rq3_entries, int, 0); 60module_param(rq3_entries, int, 0);
59module_param(sq_entries, int, 0); 61module_param(sq_entries, int, 0);
62module_param(use_mcs, int, 0);
63module_param(num_tx_qps, int, 0);
60 64
65MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
61MODULE_PARM_DESC(msg_level, "msg_level"); 66MODULE_PARM_DESC(msg_level, "msg_level");
62MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 " 67MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 "
63 "[2^x - 1], x = [6..14]. Default = " 68 "[2^x - 1], x = [6..14]. Default = "
@@ -71,6 +76,29 @@ MODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 "
71MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " 76MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue "
72 "[2^x - 1], x = [6..14]. Default = " 77 "[2^x - 1], x = [6..14]. Default = "
73 __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); 78 __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")");
79MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
80
81static int port_name_cnt = 0;
82
83static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
84 const struct of_device_id *id);
85
86static int __devexit ehea_remove(struct ibmebus_dev *dev);
87
88static struct of_device_id ehea_device_table[] = {
89 {
90 .name = "lhea",
91 .compatible = "IBM,lhea",
92 },
93 {},
94};
95
96static struct ibmebus_driver ehea_driver = {
97 .name = "ehea",
98 .id_table = ehea_device_table,
99 .probe = ehea_probe_adapter,
100 .remove = ehea_remove,
101};
74 102
75void ehea_dump(void *adr, int len, char *msg) { 103void ehea_dump(void *adr, int len, char *msg) {
76 int x; 104 int x;
@@ -197,7 +225,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
197 struct sk_buff *skb = netdev_alloc_skb(dev, packet_size); 225 struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
198 if (!skb) { 226 if (!skb) {
199 ehea_error("%s: no mem for skb/%d wqes filled", 227 ehea_error("%s: no mem for skb/%d wqes filled",
200 dev->name, i); 228 pr->port->netdev->name, i);
201 q_skba->os_skbs = fill_wqes - i; 229 q_skba->os_skbs = fill_wqes - i;
202 ret = -ENOMEM; 230 ret = -ENOMEM;
203 break; 231 break;
@@ -321,6 +349,13 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq,
321{ 349{
322 struct sk_buff *skb; 350 struct sk_buff *skb;
323 351
352 if (cqe->status & EHEA_CQE_STAT_ERR_TCP)
353 pr->p_stats.err_tcp_cksum++;
354 if (cqe->status & EHEA_CQE_STAT_ERR_IP)
355 pr->p_stats.err_ip_cksum++;
356 if (cqe->status & EHEA_CQE_STAT_ERR_CRC)
357 pr->p_stats.err_frame_crc++;
358
324 if (netif_msg_rx_err(pr->port)) { 359 if (netif_msg_rx_err(pr->port)) {
325 ehea_error("CQE Error for QP %d", pr->qp->init_attr.qp_nr); 360 ehea_error("CQE Error for QP %d", pr->qp->init_attr.qp_nr);
326 ehea_dump(cqe, sizeof(*cqe), "CQE"); 361 ehea_dump(cqe, sizeof(*cqe), "CQE");
@@ -345,10 +380,11 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq,
345 return 0; 380 return 0;
346} 381}
347 382
348static int ehea_poll(struct net_device *dev, int *budget) 383static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
384 struct ehea_port_res *pr,
385 int *budget)
349{ 386{
350 struct ehea_port *port = netdev_priv(dev); 387 struct ehea_port *port = pr->port;
351 struct ehea_port_res *pr = &port->port_res[0];
352 struct ehea_qp *qp = pr->qp; 388 struct ehea_qp *qp = pr->qp;
353 struct ehea_cqe *cqe; 389 struct ehea_cqe *cqe;
354 struct sk_buff *skb; 390 struct sk_buff *skb;
@@ -359,14 +395,12 @@ static int ehea_poll(struct net_device *dev, int *budget)
359 int skb_arr_rq2_len = pr->rq2_skba.len; 395 int skb_arr_rq2_len = pr->rq2_skba.len;
360 int skb_arr_rq3_len = pr->rq3_skba.len; 396 int skb_arr_rq3_len = pr->rq3_skba.len;
361 int processed, processed_rq1, processed_rq2, processed_rq3; 397 int processed, processed_rq1, processed_rq2, processed_rq3;
362 int wqe_index, last_wqe_index, rq, intreq, my_quota, port_reset; 398 int wqe_index, last_wqe_index, rq, my_quota, port_reset;
363 399
364 processed = processed_rq1 = processed_rq2 = processed_rq3 = 0; 400 processed = processed_rq1 = processed_rq2 = processed_rq3 = 0;
365 last_wqe_index = 0; 401 last_wqe_index = 0;
366 my_quota = min(*budget, dev->quota); 402 my_quota = min(*budget, dev->quota);
367 my_quota = min(my_quota, EHEA_POLL_MAX_RWQE);
368 403
369 /* rq0 is low latency RQ */
370 cqe = ehea_poll_rq1(qp, &wqe_index); 404 cqe = ehea_poll_rq1(qp, &wqe_index);
371 while ((my_quota > 0) && cqe) { 405 while ((my_quota > 0) && cqe) {
372 ehea_inc_rq1(qp); 406 ehea_inc_rq1(qp);
@@ -386,7 +420,8 @@ static int ehea_poll(struct net_device *dev, int *budget)
386 if (unlikely(!skb)) { 420 if (unlikely(!skb)) {
387 if (netif_msg_rx_err(port)) 421 if (netif_msg_rx_err(port))
388 ehea_error("LL rq1: skb=NULL"); 422 ehea_error("LL rq1: skb=NULL");
389 skb = netdev_alloc_skb(dev, 423
424 skb = netdev_alloc_skb(port->netdev,
390 EHEA_L_PKT_SIZE); 425 EHEA_L_PKT_SIZE);
391 if (!skb) 426 if (!skb)
392 break; 427 break;
@@ -402,7 +437,7 @@ static int ehea_poll(struct net_device *dev, int *budget)
402 ehea_error("rq2: skb=NULL"); 437 ehea_error("rq2: skb=NULL");
403 break; 438 break;
404 } 439 }
405 ehea_fill_skb(dev, skb, cqe); 440 ehea_fill_skb(port->netdev, skb, cqe);
406 processed_rq2++; 441 processed_rq2++;
407 } else { /* RQ3 */ 442 } else { /* RQ3 */
408 skb = get_skb_by_index(skb_arr_rq3, 443 skb = get_skb_by_index(skb_arr_rq3,
@@ -412,7 +447,7 @@ static int ehea_poll(struct net_device *dev, int *budget)
412 ehea_error("rq3: skb=NULL"); 447 ehea_error("rq3: skb=NULL");
413 break; 448 break;
414 } 449 }
415 ehea_fill_skb(dev, skb, cqe); 450 ehea_fill_skb(port->netdev, skb, cqe);
416 processed_rq3++; 451 processed_rq3++;
417 } 452 }
418 453
@@ -421,9 +456,8 @@ static int ehea_poll(struct net_device *dev, int *budget)
421 cqe->vlan_tag); 456 cqe->vlan_tag);
422 else 457 else
423 netif_receive_skb(skb); 458 netif_receive_skb(skb);
424 459 } else {
425 } else { /* Error occured */ 460 pr->p_stats.poll_receive_errors++;
426 pr->p_state.poll_receive_errors++;
427 port_reset = ehea_treat_poll_error(pr, rq, cqe, 461 port_reset = ehea_treat_poll_error(pr, rq, cqe,
428 &processed_rq2, 462 &processed_rq2,
429 &processed_rq3); 463 &processed_rq3);
@@ -433,72 +467,32 @@ static int ehea_poll(struct net_device *dev, int *budget)
433 cqe = ehea_poll_rq1(qp, &wqe_index); 467 cqe = ehea_poll_rq1(qp, &wqe_index);
434 } 468 }
435 469
436 dev->quota -= processed;
437 *budget -= processed;
438
439 pr->p_state.ehea_poll += 1;
440 pr->rx_packets += processed; 470 pr->rx_packets += processed;
471 *budget -= processed;
441 472
442 ehea_refill_rq1(pr, last_wqe_index, processed_rq1); 473 ehea_refill_rq1(pr, last_wqe_index, processed_rq1);
443 ehea_refill_rq2(pr, processed_rq2); 474 ehea_refill_rq2(pr, processed_rq2);
444 ehea_refill_rq3(pr, processed_rq3); 475 ehea_refill_rq3(pr, processed_rq3);
445 476
446 intreq = ((pr->p_state.ehea_poll & 0xF) == 0xF); 477 cqe = ehea_poll_rq1(qp, &wqe_index);
447 478 return cqe;
448 if (!cqe || intreq) {
449 netif_rx_complete(dev);
450 ehea_reset_cq_ep(pr->recv_cq);
451 ehea_reset_cq_n1(pr->recv_cq);
452 cqe = hw_qeit_get_valid(&qp->hw_rqueue1);
453 if (!cqe || intreq)
454 return 0;
455 if (!netif_rx_reschedule(dev, my_quota))
456 return 0;
457 }
458 return 1;
459} 479}
460 480
461void free_sent_skbs(struct ehea_cqe *cqe, struct ehea_port_res *pr) 481static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
462{ 482{
463 struct sk_buff *skb; 483 struct sk_buff *skb;
464 int index, max_index_mask, i;
465
466 index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id);
467 max_index_mask = pr->sq_skba.len - 1;
468 for (i = 0; i < EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); i++) {
469 skb = pr->sq_skba.arr[index];
470 if (likely(skb)) {
471 dev_kfree_skb(skb);
472 pr->sq_skba.arr[index] = NULL;
473 } else {
474 ehea_error("skb=NULL, wr_id=%lX, loop=%d, index=%d",
475 cqe->wr_id, i, index);
476 }
477 index--;
478 index &= max_index_mask;
479 }
480}
481
482#define MAX_SENDCOMP_QUOTA 400
483void ehea_send_irq_tasklet(unsigned long data)
484{
485 struct ehea_port_res *pr = (struct ehea_port_res*)data;
486 struct ehea_cq *send_cq = pr->send_cq; 484 struct ehea_cq *send_cq = pr->send_cq;
487 struct ehea_cqe *cqe; 485 struct ehea_cqe *cqe;
488 int quota = MAX_SENDCOMP_QUOTA; 486 int quota = my_quota;
489 int cqe_counter = 0; 487 int cqe_counter = 0;
490 int swqe_av = 0; 488 int swqe_av = 0;
489 int index;
491 unsigned long flags; 490 unsigned long flags;
492 491
493 do { 492 cqe = ehea_poll_cq(send_cq);
494 cqe = ehea_poll_cq(send_cq); 493 while(cqe && (quota > 0)) {
495 if (!cqe) { 494 ehea_inc_cq(send_cq);
496 ehea_reset_cq_ep(send_cq); 495
497 ehea_reset_cq_n1(send_cq);
498 cqe = ehea_poll_cq(send_cq);
499 if (!cqe)
500 break;
501 }
502 cqe_counter++; 496 cqe_counter++;
503 rmb(); 497 rmb();
504 if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { 498 if (cqe->status & EHEA_CQE_STAT_ERR_MASK) {
@@ -514,17 +508,25 @@ void ehea_send_irq_tasklet(unsigned long data)
514 ehea_dump(cqe, sizeof(*cqe), "CQE"); 508 ehea_dump(cqe, sizeof(*cqe), "CQE");
515 509
516 if (likely(EHEA_BMASK_GET(EHEA_WR_ID_TYPE, cqe->wr_id) 510 if (likely(EHEA_BMASK_GET(EHEA_WR_ID_TYPE, cqe->wr_id)
517 == EHEA_SWQE2_TYPE)) 511 == EHEA_SWQE2_TYPE)) {
518 free_sent_skbs(cqe, pr); 512
513 index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id);
514 skb = pr->sq_skba.arr[index];
515 dev_kfree_skb(skb);
516 pr->sq_skba.arr[index] = NULL;
517 }
519 518
520 swqe_av += EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); 519 swqe_av += EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id);
521 quota--; 520 quota--;
522 } while (quota > 0); 521
522 cqe = ehea_poll_cq(send_cq);
523 };
523 524
524 ehea_update_feca(send_cq, cqe_counter); 525 ehea_update_feca(send_cq, cqe_counter);
525 atomic_add(swqe_av, &pr->swqe_avail); 526 atomic_add(swqe_av, &pr->swqe_avail);
526 527
527 spin_lock_irqsave(&pr->netif_queue, flags); 528 spin_lock_irqsave(&pr->netif_queue, flags);
529
528 if (pr->queue_stopped && (atomic_read(&pr->swqe_avail) 530 if (pr->queue_stopped && (atomic_read(&pr->swqe_avail)
529 >= pr->swqe_refill_th)) { 531 >= pr->swqe_refill_th)) {
530 netif_wake_queue(pr->port->netdev); 532 netif_wake_queue(pr->port->netdev);
@@ -532,22 +534,55 @@ void ehea_send_irq_tasklet(unsigned long data)
532 } 534 }
533 spin_unlock_irqrestore(&pr->netif_queue, flags); 535 spin_unlock_irqrestore(&pr->netif_queue, flags);
534 536
535 if (unlikely(cqe)) 537 return cqe;
536 tasklet_hi_schedule(&pr->send_comp_task);
537} 538}
538 539
539static irqreturn_t ehea_send_irq_handler(int irq, void *param) 540#define EHEA_NAPI_POLL_NUM_BEFORE_IRQ 16
541
542static int ehea_poll(struct net_device *dev, int *budget)
540{ 543{
541 struct ehea_port_res *pr = param; 544 struct ehea_port_res *pr = dev->priv;
542 tasklet_hi_schedule(&pr->send_comp_task); 545 struct ehea_cqe *cqe;
543 return IRQ_HANDLED; 546 struct ehea_cqe *cqe_skb = NULL;
547 int force_irq, wqe_index;
548
549 cqe = ehea_poll_rq1(pr->qp, &wqe_index);
550 cqe_skb = ehea_poll_cq(pr->send_cq);
551
552 force_irq = (pr->poll_counter > EHEA_NAPI_POLL_NUM_BEFORE_IRQ);
553
554 if ((!cqe && !cqe_skb) || force_irq) {
555 pr->poll_counter = 0;
556 netif_rx_complete(dev);
557 ehea_reset_cq_ep(pr->recv_cq);
558 ehea_reset_cq_ep(pr->send_cq);
559 ehea_reset_cq_n1(pr->recv_cq);
560 ehea_reset_cq_n1(pr->send_cq);
561 cqe = ehea_poll_rq1(pr->qp, &wqe_index);
562 cqe_skb = ehea_poll_cq(pr->send_cq);
563
564 if (!cqe && !cqe_skb)
565 return 0;
566
567 if (!netif_rx_reschedule(dev, dev->quota))
568 return 0;
569 }
570
571 cqe = ehea_proc_rwqes(dev, pr, budget);
572 cqe_skb = ehea_proc_cqes(pr, 300);
573
574 if (cqe || cqe_skb)
575 pr->poll_counter++;
576
577 return 1;
544} 578}
545 579
546static irqreturn_t ehea_recv_irq_handler(int irq, void *param) 580static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
547{ 581{
548 struct ehea_port_res *pr = param; 582 struct ehea_port_res *pr = param;
549 struct ehea_port *port = pr->port; 583
550 netif_rx_schedule(port->netdev); 584 netif_rx_schedule(pr->d_netdev);
585
551 return IRQ_HANDLED; 586 return IRQ_HANDLED;
552} 587}
553 588
@@ -580,7 +615,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter,
580{ 615{
581 int i; 616 int i;
582 617
583 for (i = 0; i < adapter->num_ports; i++) 618 for (i = 0; i < EHEA_MAX_PORTS; i++)
584 if (adapter->port[i]) 619 if (adapter->port[i])
585 if (adapter->port[i]->logical_port_id == logical_port) 620 if (adapter->port[i]->logical_port_id == logical_port)
586 return adapter->port[i]; 621 return adapter->port[i];
@@ -650,19 +685,25 @@ int ehea_sense_port_attr(struct ehea_port *port)
650 } 685 }
651 686
652 port->autoneg = 1; 687 port->autoneg = 1;
688 port->num_mcs = cb0->num_default_qps;
653 689
654 /* Number of default QPs */ 690 /* Number of default QPs */
655 port->num_def_qps = cb0->num_default_qps; 691 if (use_mcs)
692 port->num_def_qps = cb0->num_default_qps;
693 else
694 port->num_def_qps = 1;
656 695
657 if (!port->num_def_qps) { 696 if (!port->num_def_qps) {
658 ret = -EINVAL; 697 ret = -EINVAL;
659 goto out_free; 698 goto out_free;
660 } 699 }
661 700
662 if (port->num_def_qps >= EHEA_NUM_TX_QP) 701 port->num_tx_qps = num_tx_qps;
702
703 if (port->num_def_qps >= port->num_tx_qps)
663 port->num_add_tx_qps = 0; 704 port->num_add_tx_qps = 0;
664 else 705 else
665 port->num_add_tx_qps = EHEA_NUM_TX_QP - port->num_def_qps; 706 port->num_add_tx_qps = port->num_tx_qps - port->num_def_qps;
666 707
667 ret = 0; 708 ret = 0;
668out_free: 709out_free:
@@ -882,23 +923,6 @@ static int ehea_reg_interrupts(struct net_device *dev)
882 struct ehea_port_res *pr; 923 struct ehea_port_res *pr;
883 int i, ret; 924 int i, ret;
884 925
885 for (i = 0; i < port->num_def_qps; i++) {
886 pr = &port->port_res[i];
887 snprintf(pr->int_recv_name, EHEA_IRQ_NAME_SIZE - 1
888 , "%s-recv%d", dev->name, i);
889 ret = ibmebus_request_irq(NULL, pr->recv_eq->attr.ist1,
890 ehea_recv_irq_handler,
891 IRQF_DISABLED, pr->int_recv_name, pr);
892 if (ret) {
893 ehea_error("failed registering irq for ehea_recv_int:"
894 "port_res_nr:%d, ist=%X", i,
895 pr->recv_eq->attr.ist1);
896 goto out_free_seq;
897 }
898 if (netif_msg_ifup(port))
899 ehea_info("irq_handle 0x%X for funct ehea_recv_int %d "
900 "registered", pr->recv_eq->attr.ist1, i);
901 }
902 926
903 snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff", 927 snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff",
904 dev->name); 928 dev->name);
@@ -916,41 +940,41 @@ static int ehea_reg_interrupts(struct net_device *dev)
916 ehea_info("irq_handle 0x%X for function qp_aff_irq_handler " 940 ehea_info("irq_handle 0x%X for function qp_aff_irq_handler "
917 "registered", port->qp_eq->attr.ist1); 941 "registered", port->qp_eq->attr.ist1);
918 942
943
919 for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { 944 for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
920 pr = &port->port_res[i]; 945 pr = &port->port_res[i];
921 snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1, 946 snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1,
922 "%s-send%d", dev->name, i); 947 "%s-queue%d", dev->name, i);
923 ret = ibmebus_request_irq(NULL, pr->send_eq->attr.ist1, 948 ret = ibmebus_request_irq(NULL, pr->eq->attr.ist1,
924 ehea_send_irq_handler, 949 ehea_recv_irq_handler,
925 IRQF_DISABLED, pr->int_send_name, 950 IRQF_DISABLED, pr->int_send_name,
926 pr); 951 pr);
927 if (ret) { 952 if (ret) {
928 ehea_error("failed registering irq for ehea_send " 953 ehea_error("failed registering irq for ehea_queue "
929 "port_res_nr:%d, ist=%X", i, 954 "port_res_nr:%d, ist=%X", i,
930 pr->send_eq->attr.ist1); 955 pr->eq->attr.ist1);
931 goto out_free_req; 956 goto out_free_req;
932 } 957 }
933 if (netif_msg_ifup(port)) 958 if (netif_msg_ifup(port))
934 ehea_info("irq_handle 0x%X for function ehea_send_int " 959 ehea_info("irq_handle 0x%X for function ehea_queue_int "
935 "%d registered", pr->send_eq->attr.ist1, i); 960 "%d registered", pr->eq->attr.ist1, i);
936 } 961 }
937out: 962out:
938 return ret; 963 return ret;
939 964
965
940out_free_req: 966out_free_req:
941 while (--i >= 0) { 967 while (--i >= 0) {
942 u32 ist = port->port_res[i].send_eq->attr.ist1; 968 u32 ist = port->port_res[i].eq->attr.ist1;
943 ibmebus_free_irq(NULL, ist, &port->port_res[i]); 969 ibmebus_free_irq(NULL, ist, &port->port_res[i]);
944 } 970 }
971
945out_free_qpeq: 972out_free_qpeq:
946 ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port); 973 ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port);
947 i = port->num_def_qps; 974 i = port->num_def_qps;
948out_free_seq: 975
949 while (--i >= 0) {
950 u32 ist = port->port_res[i].recv_eq->attr.ist1;
951 ibmebus_free_irq(NULL, ist, &port->port_res[i]);
952 }
953 goto out; 976 goto out;
977
954} 978}
955 979
956static void ehea_free_interrupts(struct net_device *dev) 980static void ehea_free_interrupts(struct net_device *dev)
@@ -960,21 +984,13 @@ static void ehea_free_interrupts(struct net_device *dev)
960 int i; 984 int i;
961 985
962 /* send */ 986 /* send */
987
963 for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { 988 for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
964 pr = &port->port_res[i]; 989 pr = &port->port_res[i];
965 ibmebus_free_irq(NULL, pr->send_eq->attr.ist1, pr); 990 ibmebus_free_irq(NULL, pr->eq->attr.ist1, pr);
966 if (netif_msg_intr(port)) 991 if (netif_msg_intr(port))
967 ehea_info("free send irq for res %d with handle 0x%X", 992 ehea_info("free send irq for res %d with handle 0x%X",
968 i, pr->send_eq->attr.ist1); 993 i, pr->eq->attr.ist1);
969 }
970
971 /* receive */
972 for (i = 0; i < port->num_def_qps; i++) {
973 pr = &port->port_res[i];
974 ibmebus_free_irq(NULL, pr->recv_eq->attr.ist1, pr);
975 if (netif_msg_intr(port))
976 ehea_info("free recv irq for res %d with handle 0x%X",
977 i, pr->recv_eq->attr.ist1);
978 } 994 }
979 995
980 /* associated events */ 996 /* associated events */
@@ -1003,8 +1019,13 @@ static int ehea_configure_port(struct ehea_port *port)
1003 PXLY_RC_VLAN_FILTER) 1019 PXLY_RC_VLAN_FILTER)
1004 | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); 1020 | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1);
1005 1021
1006 for (i = 0; i < port->num_def_qps; i++) 1022 for (i = 0; i < port->num_mcs; i++)
1007 cb0->default_qpn_arr[i] = port->port_res[0].qp->init_attr.qp_nr; 1023 if (use_mcs)
1024 cb0->default_qpn_arr[i] =
1025 port->port_res[i].qp->init_attr.qp_nr;
1026 else
1027 cb0->default_qpn_arr[i] =
1028 port->port_res[0].qp->init_attr.qp_nr;
1008 1029
1009 if (netif_msg_ifup(port)) 1030 if (netif_msg_ifup(port))
1010 ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); 1031 ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port");
@@ -1027,52 +1048,35 @@ out:
1027 return ret; 1048 return ret;
1028} 1049}
1029 1050
1030static int ehea_gen_smrs(struct ehea_port_res *pr) 1051int ehea_gen_smrs(struct ehea_port_res *pr)
1031{ 1052{
1032 u64 hret; 1053 int ret;
1033 struct ehea_adapter *adapter = pr->port->adapter; 1054 struct ehea_adapter *adapter = pr->port->adapter;
1034 1055
1035 hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, 1056 ret = ehea_gen_smr(adapter, &adapter->mr, &pr->send_mr);
1036 adapter->mr.vaddr, EHEA_MR_ACC_CTRL, 1057 if (ret)
1037 adapter->pd, &pr->send_mr);
1038 if (hret != H_SUCCESS)
1039 goto out; 1058 goto out;
1040 1059
1041 hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle, 1060 ret = ehea_gen_smr(adapter, &adapter->mr, &pr->recv_mr);
1042 adapter->mr.vaddr, EHEA_MR_ACC_CTRL, 1061 if (ret)
1043 adapter->pd, &pr->recv_mr); 1062 goto out_free;
1044 if (hret != H_SUCCESS)
1045 goto out_freeres;
1046 1063
1047 return 0; 1064 return 0;
1048 1065
1049out_freeres: 1066out_free:
1050 hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); 1067 ehea_rem_mr(&pr->send_mr);
1051 if (hret != H_SUCCESS)
1052 ehea_error("failed freeing SMR");
1053out: 1068out:
1069 ehea_error("Generating SMRS failed\n");
1054 return -EIO; 1070 return -EIO;
1055} 1071}
1056 1072
1057static int ehea_rem_smrs(struct ehea_port_res *pr) 1073int ehea_rem_smrs(struct ehea_port_res *pr)
1058{ 1074{
1059 struct ehea_adapter *adapter = pr->port->adapter; 1075 if ((ehea_rem_mr(&pr->send_mr))
1060 int ret = 0; 1076 || (ehea_rem_mr(&pr->recv_mr)))
1061 u64 hret; 1077 return -EIO;
1062 1078 else
1063 hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle); 1079 return 0;
1064 if (hret != H_SUCCESS) {
1065 ret = -EIO;
1066 ehea_error("failed freeing send SMR for pr=%p", pr);
1067 }
1068
1069 hret = ehea_h_free_resource(adapter->handle, pr->recv_mr.handle);
1070 if (hret != H_SUCCESS) {
1071 ret = -EIO;
1072 ehea_error("failed freeing recv SMR for pr=%p", pr);
1073 }
1074
1075 return ret;
1076} 1080}
1077 1081
1078static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) 1082static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries)
@@ -1103,25 +1107,17 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
1103 memset(pr, 0, sizeof(struct ehea_port_res)); 1107 memset(pr, 0, sizeof(struct ehea_port_res));
1104 1108
1105 pr->port = port; 1109 pr->port = port;
1106 spin_lock_init(&pr->send_lock);
1107 spin_lock_init(&pr->recv_lock);
1108 spin_lock_init(&pr->xmit_lock); 1110 spin_lock_init(&pr->xmit_lock);
1109 spin_lock_init(&pr->netif_queue); 1111 spin_lock_init(&pr->netif_queue);
1110 1112
1111 pr->recv_eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); 1113 pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0);
1112 if (!pr->recv_eq) { 1114 if (!pr->eq) {
1113 ehea_error("create_eq failed (recv_eq)"); 1115 ehea_error("create_eq failed (eq)");
1114 goto out_free;
1115 }
1116
1117 pr->send_eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0);
1118 if (!pr->send_eq) {
1119 ehea_error("create_eq failed (send_eq)");
1120 goto out_free; 1116 goto out_free;
1121 } 1117 }
1122 1118
1123 pr->recv_cq = ehea_create_cq(adapter, pr_cfg->max_entries_rcq, 1119 pr->recv_cq = ehea_create_cq(adapter, pr_cfg->max_entries_rcq,
1124 pr->recv_eq->fw_handle, 1120 pr->eq->fw_handle,
1125 port->logical_port_id); 1121 port->logical_port_id);
1126 if (!pr->recv_cq) { 1122 if (!pr->recv_cq) {
1127 ehea_error("create_cq failed (cq_recv)"); 1123 ehea_error("create_cq failed (cq_recv)");
@@ -1129,7 +1125,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
1129 } 1125 }
1130 1126
1131 pr->send_cq = ehea_create_cq(adapter, pr_cfg->max_entries_scq, 1127 pr->send_cq = ehea_create_cq(adapter, pr_cfg->max_entries_scq,
1132 pr->send_eq->fw_handle, 1128 pr->eq->fw_handle,
1133 port->logical_port_id); 1129 port->logical_port_id);
1134 if (!pr->send_cq) { 1130 if (!pr->send_cq) {
1135 ehea_error("create_cq failed (cq_send)"); 1131 ehea_error("create_cq failed (cq_send)");
@@ -1194,11 +1190,20 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
1194 ret = -EIO; 1190 ret = -EIO;
1195 goto out_free; 1191 goto out_free;
1196 } 1192 }
1197 tasklet_init(&pr->send_comp_task, ehea_send_irq_tasklet, 1193
1198 (unsigned long)pr);
1199 atomic_set(&pr->swqe_avail, init_attr->act_nr_send_wqes - 1); 1194 atomic_set(&pr->swqe_avail, init_attr->act_nr_send_wqes - 1);
1200 1195
1201 kfree(init_attr); 1196 kfree(init_attr);
1197
1198 pr->d_netdev = alloc_netdev(0, "", ether_setup);
1199 if (!pr->d_netdev)
1200 goto out_free;
1201 pr->d_netdev->priv = pr;
1202 pr->d_netdev->weight = 64;
1203 pr->d_netdev->poll = ehea_poll;
1204 set_bit(__LINK_STATE_START, &pr->d_netdev->state);
1205 strcpy(pr->d_netdev->name, port->netdev->name);
1206
1202 ret = 0; 1207 ret = 0;
1203 goto out; 1208 goto out;
1204 1209
@@ -1211,8 +1216,7 @@ out_free:
1211 ehea_destroy_qp(pr->qp); 1216 ehea_destroy_qp(pr->qp);
1212 ehea_destroy_cq(pr->send_cq); 1217 ehea_destroy_cq(pr->send_cq);
1213 ehea_destroy_cq(pr->recv_cq); 1218 ehea_destroy_cq(pr->recv_cq);
1214 ehea_destroy_eq(pr->send_eq); 1219 ehea_destroy_eq(pr->eq);
1215 ehea_destroy_eq(pr->recv_eq);
1216out: 1220out:
1217 return ret; 1221 return ret;
1218} 1222}
@@ -1221,13 +1225,14 @@ static int ehea_clean_portres(struct ehea_port *port, struct ehea_port_res *pr)
1221{ 1225{
1222 int ret, i; 1226 int ret, i;
1223 1227
1228 free_netdev(pr->d_netdev);
1229
1224 ret = ehea_destroy_qp(pr->qp); 1230 ret = ehea_destroy_qp(pr->qp);
1225 1231
1226 if (!ret) { 1232 if (!ret) {
1227 ehea_destroy_cq(pr->send_cq); 1233 ehea_destroy_cq(pr->send_cq);
1228 ehea_destroy_cq(pr->recv_cq); 1234 ehea_destroy_cq(pr->recv_cq);
1229 ehea_destroy_eq(pr->send_eq); 1235 ehea_destroy_eq(pr->eq);
1230 ehea_destroy_eq(pr->recv_eq);
1231 1236
1232 for (i = 0; i < pr->rq1_skba.len; i++) 1237 for (i = 0; i < pr->rq1_skba.len; i++)
1233 if (pr->rq1_skba.arr[i]) 1238 if (pr->rq1_skba.arr[i])
@@ -1792,6 +1797,22 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
1792 dev_kfree_skb(skb); 1797 dev_kfree_skb(skb);
1793} 1798}
1794 1799
1800static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps)
1801{
1802 struct tcphdr *tcp;
1803 u32 tmp;
1804
1805 if ((skb->protocol == htons(ETH_P_IP)) &&
1806 (skb->nh.iph->protocol == IPPROTO_TCP)) {
1807 tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4));
1808 tmp = (tcp->source + (tcp->dest << 16)) % 31;
1809 tmp += skb->nh.iph->daddr % 31;
1810 return tmp % num_qps;
1811 }
1812 else
1813 return 0;
1814}
1815
1795static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) 1816static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
1796{ 1817{
1797 struct ehea_port *port = netdev_priv(dev); 1818 struct ehea_port *port = netdev_priv(dev);
@@ -1799,9 +1820,17 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
1799 unsigned long flags; 1820 unsigned long flags;
1800 u32 lkey; 1821 u32 lkey;
1801 int swqe_index; 1822 int swqe_index;
1802 struct ehea_port_res *pr = &port->port_res[0]; 1823 struct ehea_port_res *pr;
1824
1825 pr = &port->port_res[ehea_hash_skb(skb, port->num_tx_qps)];
1803 1826
1804 spin_lock(&pr->xmit_lock); 1827 if (!spin_trylock(&pr->xmit_lock))
1828 return NETDEV_TX_BUSY;
1829
1830 if (pr->queue_stopped) {
1831 spin_unlock(&pr->xmit_lock);
1832 return NETDEV_TX_BUSY;
1833 }
1805 1834
1806 swqe = ehea_get_swqe(pr->qp, &swqe_index); 1835 swqe = ehea_get_swqe(pr->qp, &swqe_index);
1807 memset(swqe, 0, SWQE_HEADER_SIZE); 1836 memset(swqe, 0, SWQE_HEADER_SIZE);
@@ -1824,6 +1853,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
1824 swqe->wr_id = 1853 swqe->wr_id =
1825 EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE2_TYPE) 1854 EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE2_TYPE)
1826 | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, pr->swqe_id_counter) 1855 | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, pr->swqe_id_counter)
1856 | EHEA_BMASK_SET(EHEA_WR_ID_REFILL, 1)
1827 | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, pr->sq_skba.index); 1857 | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, pr->sq_skba.index);
1828 pr->sq_skba.arr[pr->sq_skba.index] = skb; 1858 pr->sq_skba.arr[pr->sq_skba.index] = skb;
1829 1859
@@ -1832,14 +1862,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
1832 1862
1833 lkey = pr->send_mr.lkey; 1863 lkey = pr->send_mr.lkey;
1834 ehea_xmit2(skb, dev, swqe, lkey); 1864 ehea_xmit2(skb, dev, swqe, lkey);
1835 1865 swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION;
1836 if (pr->swqe_count >= (EHEA_SIG_IV_LONG - 1)) {
1837 swqe->wr_id |= EHEA_BMASK_SET(EHEA_WR_ID_REFILL,
1838 EHEA_SIG_IV_LONG);
1839 swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION;
1840 pr->swqe_count = 0;
1841 } else
1842 pr->swqe_count += 1;
1843 } 1866 }
1844 pr->swqe_id_counter += 1; 1867 pr->swqe_id_counter += 1;
1845 1868
@@ -1859,6 +1882,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
1859 if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { 1882 if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) {
1860 spin_lock_irqsave(&pr->netif_queue, flags); 1883 spin_lock_irqsave(&pr->netif_queue, flags);
1861 if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { 1884 if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) {
1885 pr->p_stats.queue_stopped++;
1862 netif_stop_queue(dev); 1886 netif_stop_queue(dev);
1863 pr->queue_stopped = 1; 1887 pr->queue_stopped = 1;
1864 } 1888 }
@@ -2060,7 +2084,7 @@ static int ehea_port_res_setup(struct ehea_port *port, int def_qps,
2060 } 2084 }
2061 2085
2062 pr_cfg.max_entries_rcq = rq1_entries + rq2_entries + rq3_entries; 2086 pr_cfg.max_entries_rcq = rq1_entries + rq2_entries + rq3_entries;
2063 pr_cfg.max_entries_scq = sq_entries; 2087 pr_cfg.max_entries_scq = sq_entries * 2;
2064 pr_cfg.max_entries_sq = sq_entries; 2088 pr_cfg.max_entries_sq = sq_entries;
2065 pr_cfg.max_entries_rq1 = rq1_entries; 2089 pr_cfg.max_entries_rq1 = rq1_entries;
2066 pr_cfg.max_entries_rq2 = rq2_entries; 2090 pr_cfg.max_entries_rq2 = rq2_entries;
@@ -2109,6 +2133,28 @@ static int ehea_clean_all_portres(struct ehea_port *port)
2109 return ret; 2133 return ret;
2110} 2134}
2111 2135
2136static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
2137{
2138 int i;
2139
2140 for (i=0; i < EHEA_MAX_PORTS; i++)
2141 if (adapter->port[i])
2142 return;
2143
2144 ehea_rem_mr(&adapter->mr);
2145}
2146
2147static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
2148{
2149 int i;
2150
2151 for (i=0; i < EHEA_MAX_PORTS; i++)
2152 if (adapter->port[i])
2153 return 0;
2154
2155 return ehea_reg_kernel_mr(adapter, &adapter->mr);
2156}
2157
2112static int ehea_up(struct net_device *dev) 2158static int ehea_up(struct net_device *dev)
2113{ 2159{
2114 int ret, i; 2160 int ret, i;
@@ -2208,8 +2254,10 @@ static int ehea_down(struct net_device *dev)
2208 ehea_drop_multicast_list(dev); 2254 ehea_drop_multicast_list(dev);
2209 ehea_free_interrupts(dev); 2255 ehea_free_interrupts(dev);
2210 2256
2211 for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) 2257 for (i = 0; i < port->num_def_qps; i++)
2212 tasklet_kill(&port->port_res[i].send_comp_task); 2258 while (test_bit(__LINK_STATE_RX_SCHED,
2259 &port->port_res[i].d_netdev->state))
2260 msleep(1);
2213 2261
2214 ehea_broadcast_reg_helper(port, H_DEREG_BCMC); 2262 ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
2215 ret = ehea_clean_all_portres(port); 2263 ret = ehea_clean_all_portres(port);
@@ -2276,8 +2324,6 @@ static void ehea_tx_watchdog(struct net_device *dev)
2276int ehea_sense_adapter_attr(struct ehea_adapter *adapter) 2324int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
2277{ 2325{
2278 struct hcp_query_ehea *cb; 2326 struct hcp_query_ehea *cb;
2279 struct device_node *lhea_dn = NULL;
2280 struct device_node *eth_dn = NULL;
2281 u64 hret; 2327 u64 hret;
2282 int ret; 2328 int ret;
2283 2329
@@ -2294,18 +2340,6 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
2294 goto out_herr; 2340 goto out_herr;
2295 } 2341 }
2296 2342
2297 /* Determine the number of available logical ports
2298 * by counting the child nodes of the lhea OFDT entry
2299 */
2300 adapter->num_ports = 0;
2301 lhea_dn = of_find_node_by_name(lhea_dn, "lhea");
2302 do {
2303 eth_dn = of_get_next_child(lhea_dn, eth_dn);
2304 if (eth_dn)
2305 adapter->num_ports++;
2306 } while ( eth_dn );
2307 of_node_put(lhea_dn);
2308
2309 adapter->max_mc_mac = cb->max_mc_mac - 1; 2343 adapter->max_mc_mac = cb->max_mc_mac - 1;
2310 ret = 0; 2344 ret = 0;
2311 2345
@@ -2315,79 +2349,188 @@ out:
2315 return ret; 2349 return ret;
2316} 2350}
2317 2351
2318static int ehea_setup_single_port(struct ehea_port *port, 2352int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
2319 struct device_node *dn)
2320{ 2353{
2321 int ret;
2322 u64 hret;
2323 struct net_device *dev = port->netdev;
2324 struct ehea_adapter *adapter = port->adapter;
2325 struct hcp_ehea_port_cb4 *cb4; 2354 struct hcp_ehea_port_cb4 *cb4;
2326 u32 *dn_log_port_id; 2355 u64 hret;
2327 int jumbo = 0; 2356 int ret = 0;
2328
2329 sema_init(&port->port_lock, 1);
2330 port->state = EHEA_PORT_DOWN;
2331 port->sig_comp_iv = sq_entries / 10;
2332
2333 if (!dn) {
2334 ehea_error("bad device node: dn=%p", dn);
2335 ret = -EINVAL;
2336 goto out;
2337 }
2338
2339 port->of_dev_node = dn;
2340
2341 /* Determine logical port id */
2342 dn_log_port_id = (u32*)get_property(dn, "ibm,hea-port-no", NULL);
2343
2344 if (!dn_log_port_id) {
2345 ehea_error("bad device node: dn_log_port_id=%p",
2346 dn_log_port_id);
2347 ret = -EINVAL;
2348 goto out;
2349 }
2350 port->logical_port_id = *dn_log_port_id;
2351
2352 port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL);
2353 if (!port->mc_list) {
2354 ret = -ENOMEM;
2355 goto out;
2356 }
2357
2358 INIT_LIST_HEAD(&port->mc_list->list);
2359 2357
2360 ret = ehea_sense_port_attr(port); 2358 *jumbo = 0;
2361 if (ret)
2362 goto out;
2363 2359
2364 /* Enable Jumbo frames */ 2360 /* (Try to) enable *jumbo frames */
2365 cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); 2361 cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
2366 if (!cb4) { 2362 if (!cb4) {
2367 ehea_error("no mem for cb4"); 2363 ehea_error("no mem for cb4");
2364 ret = -ENOMEM;
2365 goto out;
2368 } else { 2366 } else {
2369 hret = ehea_h_query_ehea_port(adapter->handle, 2367 hret = ehea_h_query_ehea_port(port->adapter->handle,
2370 port->logical_port_id, 2368 port->logical_port_id,
2371 H_PORT_CB4, 2369 H_PORT_CB4,
2372 H_PORT_CB4_JUMBO, cb4); 2370 H_PORT_CB4_JUMBO, cb4);
2373
2374 if (hret == H_SUCCESS) { 2371 if (hret == H_SUCCESS) {
2375 if (cb4->jumbo_frame) 2372 if (cb4->jumbo_frame)
2376 jumbo = 1; 2373 *jumbo = 1;
2377 else { 2374 else {
2378 cb4->jumbo_frame = 1; 2375 cb4->jumbo_frame = 1;
2379 hret = ehea_h_modify_ehea_port(adapter->handle, 2376 hret = ehea_h_modify_ehea_port(port->adapter->
2377 handle,
2380 port-> 2378 port->
2381 logical_port_id, 2379 logical_port_id,
2382 H_PORT_CB4, 2380 H_PORT_CB4,
2383 H_PORT_CB4_JUMBO, 2381 H_PORT_CB4_JUMBO,
2384 cb4); 2382 cb4);
2385 if (hret == H_SUCCESS) 2383 if (hret == H_SUCCESS)
2386 jumbo = 1; 2384 *jumbo = 1;
2387 } 2385 }
2388 } 2386 } else
2387 ret = -EINVAL;
2388
2389 kfree(cb4); 2389 kfree(cb4);
2390 } 2390 }
2391out:
2392 return ret;
2393}
2394
2395static ssize_t ehea_show_port_id(struct device *dev,
2396 struct device_attribute *attr, char *buf)
2397{
2398 struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
2399 return sprintf(buf, "0x%X", port->logical_port_id);
2400}
2401
2402static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
2403 NULL);
2404
2405static void __devinit logical_port_release(struct device *dev)
2406{
2407 struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
2408 of_node_put(port->ofdev.node);
2409}
2410
2411static int ehea_driver_sysfs_add(struct device *dev,
2412 struct device_driver *driver)
2413{
2414 int ret;
2415
2416 ret = sysfs_create_link(&driver->kobj, &dev->kobj,
2417 kobject_name(&dev->kobj));
2418 if (ret == 0) {
2419 ret = sysfs_create_link(&dev->kobj, &driver->kobj,
2420 "driver");
2421 if (ret)
2422 sysfs_remove_link(&driver->kobj,
2423 kobject_name(&dev->kobj));
2424 }
2425 return ret;
2426}
2427
2428static void ehea_driver_sysfs_remove(struct device *dev,
2429 struct device_driver *driver)
2430{
2431 struct device_driver *drv = driver;
2432
2433 if (drv) {
2434 sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
2435 sysfs_remove_link(&dev->kobj, "driver");
2436 }
2437}
2438
2439static struct device *ehea_register_port(struct ehea_port *port,
2440 struct device_node *dn)
2441{
2442 int ret;
2443
2444 port->ofdev.node = of_node_get(dn);
2445 port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev;
2446 port->ofdev.dev.bus = &ibmebus_bus_type;
2447
2448 sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
2449 port->ofdev.dev.release = logical_port_release;
2450
2451 ret = of_device_register(&port->ofdev);
2452 if (ret) {
2453 ehea_error("failed to register device. ret=%d", ret);
2454 goto out;
2455 }
2456
2457 ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
2458 if (ret) {
2459 ehea_error("failed to register attributes, ret=%d", ret);
2460 goto out_unreg_of_dev;
2461 }
2462
2463 ret = ehea_driver_sysfs_add(&port->ofdev.dev, &ehea_driver.driver);
2464 if (ret) {
2465 ehea_error("failed to register sysfs driver link");
2466 goto out_rem_dev_file;
2467 }
2468
2469 return &port->ofdev.dev;
2470
2471out_rem_dev_file:
2472 device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id);
2473out_unreg_of_dev:
2474 of_device_unregister(&port->ofdev);
2475out:
2476 return NULL;
2477}
2478
2479static void ehea_unregister_port(struct ehea_port *port)
2480{
2481 ehea_driver_sysfs_remove(&port->ofdev.dev, &ehea_driver.driver);
2482 device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id);
2483 of_device_unregister(&port->ofdev);
2484}
2485
2486struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
2487 u32 logical_port_id,
2488 struct device_node *dn)
2489{
2490 int ret;
2491 struct net_device *dev;
2492 struct ehea_port *port;
2493 struct device *port_dev;
2494 int jumbo;
2495
2496 /* allocate memory for the port structures */
2497 dev = alloc_etherdev(sizeof(struct ehea_port));
2498
2499 if (!dev) {
2500 ehea_error("no mem for net_device");
2501 ret = -ENOMEM;
2502 goto out_err;
2503 }
2504
2505 port = netdev_priv(dev);
2506
2507 sema_init(&port->port_lock, 1);
2508 port->state = EHEA_PORT_DOWN;
2509 port->sig_comp_iv = sq_entries / 10;
2510
2511 port->adapter = adapter;
2512 port->netdev = dev;
2513 port->logical_port_id = logical_port_id;
2514
2515 port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT);
2516
2517 port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL);
2518 if (!port->mc_list) {
2519 ret = -ENOMEM;
2520 goto out_free_ethdev;
2521 }
2522
2523 INIT_LIST_HEAD(&port->mc_list->list);
2524
2525 ret = ehea_sense_port_attr(port);
2526 if (ret)
2527 goto out_free_mc_list;
2528
2529 port_dev = ehea_register_port(port, dn);
2530 if (!port_dev)
2531 goto out_free_mc_list;
2532
2533 SET_NETDEV_DEV(dev, port_dev);
2391 2534
2392 /* initialize net_device structure */ 2535 /* initialize net_device structure */
2393 SET_MODULE_OWNER(dev); 2536 SET_MODULE_OWNER(dev);
@@ -2420,84 +2563,225 @@ static int ehea_setup_single_port(struct ehea_port *port,
2420 ret = register_netdev(dev); 2563 ret = register_netdev(dev);
2421 if (ret) { 2564 if (ret) {
2422 ehea_error("register_netdev failed. ret=%d", ret); 2565 ehea_error("register_netdev failed. ret=%d", ret);
2423 goto out_free; 2566 goto out_unreg_port;
2424 } 2567 }
2425 2568
2569 ret = ehea_get_jumboframe_status(port, &jumbo);
2570 if (ret)
2571 ehea_error("failed determining jumbo frame status for %s",
2572 port->netdev->name);
2573
2426 ehea_info("%s: Jumbo frames are %sabled", dev->name, 2574 ehea_info("%s: Jumbo frames are %sabled", dev->name,
2427 jumbo == 1 ? "en" : "dis"); 2575 jumbo == 1 ? "en" : "dis");
2428 2576
2429 port->netdev = dev; 2577 return port;
2430 ret = 0;
2431 goto out;
2432 2578
2433out_free: 2579out_unreg_port:
2580 ehea_unregister_port(port);
2581
2582out_free_mc_list:
2434 kfree(port->mc_list); 2583 kfree(port->mc_list);
2435out: 2584
2436 return ret; 2585out_free_ethdev:
2586 free_netdev(dev);
2587
2588out_err:
2589 ehea_error("setting up logical port with id=%d failed, ret=%d",
2590 logical_port_id, ret);
2591 return NULL;
2592}
2593
2594static void ehea_shutdown_single_port(struct ehea_port *port)
2595{
2596 unregister_netdev(port->netdev);
2597 ehea_unregister_port(port);
2598 kfree(port->mc_list);
2599 free_netdev(port->netdev);
2437} 2600}
2438 2601
2439static int ehea_setup_ports(struct ehea_adapter *adapter) 2602static int ehea_setup_ports(struct ehea_adapter *adapter)
2440{ 2603{
2441 int ret; 2604 struct device_node *lhea_dn;
2442 int port_setup_ok = 0; 2605 struct device_node *eth_dn = NULL;
2606
2607 u32 *dn_log_port_id;
2608 int i = 0;
2609
2610 lhea_dn = adapter->ebus_dev->ofdev.node;
2611 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
2612
2613 dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
2614 NULL);
2615 if (!dn_log_port_id) {
2616 ehea_error("bad device node: eth_dn name=%s",
2617 eth_dn->full_name);
2618 continue;
2619 }
2620
2621 if (ehea_add_adapter_mr(adapter)) {
2622 ehea_error("creating MR failed");
2623 of_node_put(eth_dn);
2624 return -EIO;
2625 }
2626
2627 adapter->port[i] = ehea_setup_single_port(adapter,
2628 *dn_log_port_id,
2629 eth_dn);
2630 if (adapter->port[i])
2631 ehea_info("%s -> logical port id #%d",
2632 adapter->port[i]->netdev->name,
2633 *dn_log_port_id);
2634 else
2635 ehea_remove_adapter_mr(adapter);
2636
2637 i++;
2638 };
2639
2640 return 0;
2641}
2642
2643static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
2644 u32 logical_port_id)
2645{
2646 struct device_node *lhea_dn;
2647 struct device_node *eth_dn = NULL;
2648 u32 *dn_log_port_id;
2649
2650 lhea_dn = adapter->ebus_dev->ofdev.node;
2651 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
2652
2653 dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
2654 NULL);
2655 if (dn_log_port_id)
2656 if (*dn_log_port_id == logical_port_id)
2657 return eth_dn;
2658 };
2659
2660 return NULL;
2661}
2662
2663static ssize_t ehea_probe_port(struct device *dev,
2664 struct device_attribute *attr,
2665 const char *buf, size_t count)
2666{
2667 struct ehea_adapter *adapter = dev->driver_data;
2443 struct ehea_port *port; 2668 struct ehea_port *port;
2444 struct device_node *dn = NULL; 2669 struct device_node *eth_dn = NULL;
2445 struct net_device *dev;
2446 int i; 2670 int i;
2447 2671
2448 /* get port properties for all ports */ 2672 u32 logical_port_id;
2449 for (i = 0; i < adapter->num_ports; i++) {
2450 2673
2451 if (adapter->port[i]) 2674 sscanf(buf, "%X", &logical_port_id);
2452 continue; /* port already up and running */
2453 2675
2454 /* allocate memory for the port structures */ 2676 port = ehea_get_port(adapter, logical_port_id);
2455 dev = alloc_etherdev(sizeof(struct ehea_port));
2456 2677
2457 if (!dev) { 2678 if (port) {
2458 ehea_error("no mem for net_device"); 2679 ehea_info("adding port with logical port id=%d failed. port "
2459 break; 2680 "already configured as %s.", logical_port_id,
2460 } 2681 port->netdev->name);
2682 return -EINVAL;
2683 }
2461 2684
2462 port = netdev_priv(dev); 2685 eth_dn = ehea_get_eth_dn(adapter, logical_port_id);
2463 port->adapter = adapter;
2464 port->netdev = dev;
2465 adapter->port[i] = port;
2466 port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT);
2467 2686
2468 dn = of_find_node_by_name(dn, "ethernet"); 2687 if (!eth_dn) {
2469 ret = ehea_setup_single_port(port, dn); 2688 ehea_info("no logical port with id %d found", logical_port_id);
2470 if (ret) { 2689 return -EINVAL;
2471 /* Free mem for this port struct. The others will be
2472 processed on rollback */
2473 free_netdev(dev);
2474 adapter->port[i] = NULL;
2475 ehea_error("eHEA port %d setup failed, ret=%d", i, ret);
2476 }
2477 } 2690 }
2478 2691
2479 of_node_put(dn); 2692 if (ehea_add_adapter_mr(adapter)) {
2693 ehea_error("creating MR failed");
2694 return -EIO;
2695 }
2480 2696
2481 /* Check for succesfully set up ports */ 2697 port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);
2482 for (i = 0; i < adapter->num_ports; i++)
2483 if (adapter->port[i])
2484 port_setup_ok++;
2485 2698
2486 if (port_setup_ok) 2699 of_node_put(eth_dn);
2487 ret = 0; /* At least some ports are setup correctly */ 2700
2488 else 2701 if (port) {
2489 ret = -EINVAL; 2702 for (i=0; i < EHEA_MAX_PORTS; i++)
2703 if (!adapter->port[i]) {
2704 adapter->port[i] = port;
2705 break;
2706 }
2707
2708 ehea_info("added %s (logical port id=%d)", port->netdev->name,
2709 logical_port_id);
2710 } else {
2711 ehea_remove_adapter_mr(adapter);
2712 return -EIO;
2713 }
2714
2715 return (ssize_t) count;
2716}
2717
2718static ssize_t ehea_remove_port(struct device *dev,
2719 struct device_attribute *attr,
2720 const char *buf, size_t count)
2721{
2722 struct ehea_adapter *adapter = dev->driver_data;
2723 struct ehea_port *port;
2724 int i;
2725 u32 logical_port_id;
2726
2727 sscanf(buf, "%X", &logical_port_id);
2728
2729 port = ehea_get_port(adapter, logical_port_id);
2730
2731 if (port) {
2732 ehea_info("removed %s (logical port id=%d)", port->netdev->name,
2733 logical_port_id);
2734
2735 ehea_shutdown_single_port(port);
2736
2737 for (i=0; i < EHEA_MAX_PORTS; i++)
2738 if (adapter->port[i] == port) {
2739 adapter->port[i] = NULL;
2740 break;
2741 }
2742 } else {
2743 ehea_error("removing port with logical port id=%d failed. port "
2744 "not configured.", logical_port_id);
2745 return -EINVAL;
2746 }
2747
2748 ehea_remove_adapter_mr(adapter);
2749
2750 return (ssize_t) count;
2751}
2752
2753static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port);
2754static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port);
2490 2755
2756int ehea_create_device_sysfs(struct ibmebus_dev *dev)
2757{
2758 int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port);
2759 if (ret)
2760 goto out;
2761
2762 ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port);
2763out:
2491 return ret; 2764 return ret;
2492} 2765}
2493 2766
2494static int __devinit ehea_probe(struct ibmebus_dev *dev, 2767void ehea_remove_device_sysfs(struct ibmebus_dev *dev)
2495 const struct of_device_id *id) 2768{
2769 device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port);
2770 device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port);
2771}
2772
2773static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
2774 const struct of_device_id *id)
2496{ 2775{
2497 struct ehea_adapter *adapter; 2776 struct ehea_adapter *adapter;
2498 u64 *adapter_handle; 2777 u64 *adapter_handle;
2499 int ret; 2778 int ret;
2500 2779
2780 if (!dev || !dev->ofdev.node) {
2781 ehea_error("Invalid ibmebus device probed");
2782 return -EINVAL;
2783 }
2784
2501 adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); 2785 adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
2502 if (!adapter) { 2786 if (!adapter) {
2503 ret = -ENOMEM; 2787 ret = -ENOMEM;
@@ -2505,6 +2789,8 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2505 goto out; 2789 goto out;
2506 } 2790 }
2507 2791
2792 adapter->ebus_dev = dev;
2793
2508 adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", 2794 adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle",
2509 NULL); 2795 NULL);
2510 if (adapter_handle) 2796 if (adapter_handle)
@@ -2521,26 +2807,21 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2521 2807
2522 dev->ofdev.dev.driver_data = adapter; 2808 dev->ofdev.dev.driver_data = adapter;
2523 2809
2524 ret = ehea_reg_mr_adapter(adapter);
2525 if (ret) {
2526 dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n");
2527 goto out_free_ad;
2528 }
2529 2810
2530 /* initialize adapter and ports */ 2811 /* initialize adapter and ports */
2531 /* get adapter properties */ 2812 /* get adapter properties */
2532 ret = ehea_sense_adapter_attr(adapter); 2813 ret = ehea_sense_adapter_attr(adapter);
2533 if (ret) { 2814 if (ret) {
2534 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); 2815 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
2535 goto out_free_res; 2816 goto out_free_ad;
2536 } 2817 }
2537 dev_info(&dev->ofdev.dev, "%d eHEA ports found\n", adapter->num_ports);
2538 2818
2539 adapter->neq = ehea_create_eq(adapter, 2819 adapter->neq = ehea_create_eq(adapter,
2540 EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); 2820 EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
2541 if (!adapter->neq) { 2821 if (!adapter->neq) {
2822 ret = -EIO;
2542 dev_err(&dev->ofdev.dev, "NEQ creation failed"); 2823 dev_err(&dev->ofdev.dev, "NEQ creation failed");
2543 goto out_free_res; 2824 goto out_free_ad;
2544 } 2825 }
2545 2826
2546 tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, 2827 tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
@@ -2555,18 +2836,27 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2555 } 2836 }
2556 2837
2557 adapter->ehea_wq = create_workqueue("ehea_wq"); 2838 adapter->ehea_wq = create_workqueue("ehea_wq");
2558 if (!adapter->ehea_wq) 2839 if (!adapter->ehea_wq) {
2840 ret = -EIO;
2559 goto out_free_irq; 2841 goto out_free_irq;
2842 }
2843
2844 ret = ehea_create_device_sysfs(dev);
2845 if (ret)
2846 goto out_kill_wq;
2560 2847
2561 ret = ehea_setup_ports(adapter); 2848 ret = ehea_setup_ports(adapter);
2562 if (ret) { 2849 if (ret) {
2563 dev_err(&dev->ofdev.dev, "setup_ports failed"); 2850 dev_err(&dev->ofdev.dev, "setup_ports failed");
2564 goto out_kill_wq; 2851 goto out_rem_dev_sysfs;
2565 } 2852 }
2566 2853
2567 ret = 0; 2854 ret = 0;
2568 goto out; 2855 goto out;
2569 2856
2857out_rem_dev_sysfs:
2858 ehea_remove_device_sysfs(dev);
2859
2570out_kill_wq: 2860out_kill_wq:
2571 destroy_workqueue(adapter->ehea_wq); 2861 destroy_workqueue(adapter->ehea_wq);
2572 2862
@@ -2576,45 +2866,32 @@ out_free_irq:
2576out_kill_eq: 2866out_kill_eq:
2577 ehea_destroy_eq(adapter->neq); 2867 ehea_destroy_eq(adapter->neq);
2578 2868
2579out_free_res:
2580 ehea_h_free_resource(adapter->handle, adapter->mr.handle);
2581
2582out_free_ad: 2869out_free_ad:
2583 kfree(adapter); 2870 kfree(adapter);
2584out: 2871out:
2585 return ret; 2872 return ret;
2586} 2873}
2587 2874
2588static void ehea_shutdown_single_port(struct ehea_port *port)
2589{
2590 unregister_netdev(port->netdev);
2591 kfree(port->mc_list);
2592 free_netdev(port->netdev);
2593}
2594
2595static int __devexit ehea_remove(struct ibmebus_dev *dev) 2875static int __devexit ehea_remove(struct ibmebus_dev *dev)
2596{ 2876{
2597 struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; 2877 struct ehea_adapter *adapter = dev->ofdev.dev.driver_data;
2598 u64 hret;
2599 int i; 2878 int i;
2600 2879
2601 for (i = 0; i < adapter->num_ports; i++) 2880 for (i = 0; i < EHEA_MAX_PORTS; i++)
2602 if (adapter->port[i]) { 2881 if (adapter->port[i]) {
2603 ehea_shutdown_single_port(adapter->port[i]); 2882 ehea_shutdown_single_port(adapter->port[i]);
2604 adapter->port[i] = NULL; 2883 adapter->port[i] = NULL;
2605 } 2884 }
2885
2886 ehea_remove_device_sysfs(dev);
2887
2606 destroy_workqueue(adapter->ehea_wq); 2888 destroy_workqueue(adapter->ehea_wq);
2607 2889
2608 ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); 2890 ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
2609 tasklet_kill(&adapter->neq_tasklet); 2891 tasklet_kill(&adapter->neq_tasklet);
2610 2892
2611 ehea_destroy_eq(adapter->neq); 2893 ehea_destroy_eq(adapter->neq);
2612 2894 ehea_remove_adapter_mr(adapter);
2613 hret = ehea_h_free_resource(adapter->handle, adapter->mr.handle);
2614 if (hret) {
2615 dev_err(&dev->ofdev.dev, "free_resource_mr failed");
2616 return -EIO;
2617 }
2618 kfree(adapter); 2895 kfree(adapter);
2619 return 0; 2896 return 0;
2620} 2897}
@@ -2647,21 +2924,6 @@ static int check_module_parm(void)
2647 return ret; 2924 return ret;
2648} 2925}
2649 2926
2650static struct of_device_id ehea_device_table[] = {
2651 {
2652 .name = "lhea",
2653 .compatible = "IBM,lhea",
2654 },
2655 {},
2656};
2657
2658static struct ibmebus_driver ehea_driver = {
2659 .name = "ehea",
2660 .id_table = ehea_device_table,
2661 .probe = ehea_probe,
2662 .remove = ehea_remove,
2663};
2664
2665int __init ehea_module_init(void) 2927int __init ehea_module_init(void)
2666{ 2928{
2667 int ret; 2929 int ret;
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index bc3c00547264..95c4a7f9cc88 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -478,12 +478,14 @@ u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle)
478 0, 0, 0, 0, 0, 0); /* R7-R12 */ 478 0, 0, 0, 0, 0, 0); /* R7-R12 */
479} 479}
480 480
481u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) 481u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle,
482 u64 force_bit)
482{ 483{
483 return ehea_plpar_hcall_norets(H_FREE_RESOURCE, 484 return ehea_plpar_hcall_norets(H_FREE_RESOURCE,
484 adapter_handle, /* R4 */ 485 adapter_handle, /* R4 */
485 res_handle, /* R5 */ 486 res_handle, /* R5 */
486 0, 0, 0, 0, 0); /* R6-R10 */ 487 force_bit,
488 0, 0, 0, 0); /* R7-R10 */
487} 489}
488 490
489u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, 491u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr,
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index 90acddb068a1..d17a45a7e717 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -414,7 +414,11 @@ u64 ehea_h_register_rpage(const u64 adapter_handle,
414 414
415u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle); 415u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle);
416 416
417u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle); 417#define FORCE_FREE 1
418#define NORMAL_FREE 0
419
420u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle,
421 u64 force_bit);
418 422
419u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, 423u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr,
420 const u64 length, const u32 access_ctrl, 424 const u64 length, const u32 access_ctrl,
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 96ff3b679996..f24a8862977d 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -197,7 +197,7 @@ out_kill_hwq:
197 hw_queue_dtor(&cq->hw_queue); 197 hw_queue_dtor(&cq->hw_queue);
198 198
199out_freeres: 199out_freeres:
200 ehea_h_free_resource(adapter->handle, cq->fw_handle); 200 ehea_h_free_resource(adapter->handle, cq->fw_handle, FORCE_FREE);
201 201
202out_freemem: 202out_freemem:
203 kfree(cq); 203 kfree(cq);
@@ -206,25 +206,38 @@ out_nomem:
206 return NULL; 206 return NULL;
207} 207}
208 208
209int ehea_destroy_cq(struct ehea_cq *cq) 209u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force)
210{ 210{
211 u64 adapter_handle, hret; 211 u64 hret;
212 u64 adapter_handle = cq->adapter->handle;
213
214 /* deregister all previous registered pages */
215 hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force);
216 if (hret != H_SUCCESS)
217 return hret;
218
219 hw_queue_dtor(&cq->hw_queue);
220 kfree(cq);
221
222 return hret;
223}
212 224
225int ehea_destroy_cq(struct ehea_cq *cq)
226{
227 u64 hret;
213 if (!cq) 228 if (!cq)
214 return 0; 229 return 0;
215 230
216 adapter_handle = cq->adapter->handle; 231 if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) {
232 ehea_error_data(cq->adapter, cq->fw_handle);
233 hret = ehea_destroy_cq_res(cq, FORCE_FREE);
234 }
217 235
218 /* deregister all previous registered pages */
219 hret = ehea_h_free_resource(adapter_handle, cq->fw_handle);
220 if (hret != H_SUCCESS) { 236 if (hret != H_SUCCESS) {
221 ehea_error("destroy CQ failed"); 237 ehea_error("destroy CQ failed");
222 return -EIO; 238 return -EIO;
223 } 239 }
224 240
225 hw_queue_dtor(&cq->hw_queue);
226 kfree(cq);
227
228 return 0; 241 return 0;
229} 242}
230 243
@@ -297,7 +310,7 @@ out_kill_hwq:
297 hw_queue_dtor(&eq->hw_queue); 310 hw_queue_dtor(&eq->hw_queue);
298 311
299out_freeres: 312out_freeres:
300 ehea_h_free_resource(adapter->handle, eq->fw_handle); 313 ehea_h_free_resource(adapter->handle, eq->fw_handle, FORCE_FREE);
301 314
302out_freemem: 315out_freemem:
303 kfree(eq); 316 kfree(eq);
@@ -316,27 +329,41 @@ struct ehea_eqe *ehea_poll_eq(struct ehea_eq *eq)
316 return eqe; 329 return eqe;
317} 330}
318 331
319int ehea_destroy_eq(struct ehea_eq *eq) 332u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force)
320{ 333{
321 u64 hret; 334 u64 hret;
322 unsigned long flags; 335 unsigned long flags;
323 336
324 if (!eq)
325 return 0;
326
327 spin_lock_irqsave(&eq->spinlock, flags); 337 spin_lock_irqsave(&eq->spinlock, flags);
328 338
329 hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle); 339 hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle, force);
330 spin_unlock_irqrestore(&eq->spinlock, flags); 340 spin_unlock_irqrestore(&eq->spinlock, flags);
331 341
332 if (hret != H_SUCCESS) { 342 if (hret != H_SUCCESS)
333 ehea_error("destroy_eq failed"); 343 return hret;
334 return -EIO;
335 }
336 344
337 hw_queue_dtor(&eq->hw_queue); 345 hw_queue_dtor(&eq->hw_queue);
338 kfree(eq); 346 kfree(eq);
339 347
348 return hret;
349}
350
351int ehea_destroy_eq(struct ehea_eq *eq)
352{
353 u64 hret;
354 if (!eq)
355 return 0;
356
357 if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) {
358 ehea_error_data(eq->adapter, eq->fw_handle);
359 hret = ehea_destroy_eq_res(eq, FORCE_FREE);
360 }
361
362 if (hret != H_SUCCESS) {
363 ehea_error("destroy EQ failed");
364 return -EIO;
365 }
366
340 return 0; 367 return 0;
341} 368}
342 369
@@ -471,41 +498,56 @@ out_kill_hwsq:
471 498
472out_freeres: 499out_freeres:
473 ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle); 500 ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle);
474 ehea_h_free_resource(adapter->handle, qp->fw_handle); 501 ehea_h_free_resource(adapter->handle, qp->fw_handle, FORCE_FREE);
475 502
476out_freemem: 503out_freemem:
477 kfree(qp); 504 kfree(qp);
478 return NULL; 505 return NULL;
479} 506}
480 507
481int ehea_destroy_qp(struct ehea_qp *qp) 508u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force)
482{ 509{
483 u64 hret; 510 u64 hret;
484 struct ehea_qp_init_attr *qp_attr = &qp->init_attr; 511 struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
485 512
486 if (!qp)
487 return 0;
488 513
489 ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); 514 ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
490 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle); 515 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
491 if (hret != H_SUCCESS) { 516 if (hret != H_SUCCESS)
492 ehea_error("destroy_qp failed"); 517 return hret;
493 return -EIO;
494 }
495 518
496 hw_queue_dtor(&qp->hw_squeue); 519 hw_queue_dtor(&qp->hw_squeue);
497 hw_queue_dtor(&qp->hw_rqueue1); 520 hw_queue_dtor(&qp->hw_rqueue1);
498 521
499 if (qp_attr->rq_count > 1) 522 if (qp_attr->rq_count > 1)
500 hw_queue_dtor(&qp->hw_rqueue2); 523 hw_queue_dtor(&qp->hw_rqueue2);
501 if (qp_attr->rq_count > 2) 524 if (qp_attr->rq_count > 2)
502 hw_queue_dtor(&qp->hw_rqueue3); 525 hw_queue_dtor(&qp->hw_rqueue3);
503 kfree(qp); 526 kfree(qp);
504 527
505 return 0; 528 return hret;
506} 529}
507 530
508int ehea_reg_mr_adapter(struct ehea_adapter *adapter) 531int ehea_destroy_qp(struct ehea_qp *qp)
532{
533 u64 hret;
534 if (!qp)
535 return 0;
536
537 if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
538 ehea_error_data(qp->adapter, qp->fw_handle);
539 hret = ehea_destroy_qp_res(qp, FORCE_FREE);
540 }
541
542 if (hret != H_SUCCESS) {
543 ehea_error("destroy QP failed");
544 return -EIO;
545 }
546
547 return 0;
548}
549
550int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
509{ 551{
510 int i, k, ret; 552 int i, k, ret;
511 u64 hret, pt_abs, start, end, nr_pages; 553 u64 hret, pt_abs, start, end, nr_pages;
@@ -526,14 +568,14 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter)
526 568
527 hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start, 569 hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start,
528 acc_ctrl, adapter->pd, 570 acc_ctrl, adapter->pd,
529 &adapter->mr.handle, &adapter->mr.lkey); 571 &mr->handle, &mr->lkey);
530 if (hret != H_SUCCESS) { 572 if (hret != H_SUCCESS) {
531 ehea_error("alloc_resource_mr failed"); 573 ehea_error("alloc_resource_mr failed");
532 ret = -EIO; 574 ret = -EIO;
533 goto out; 575 goto out;
534 } 576 }
535 577
536 adapter->mr.vaddr = KERNELBASE; 578 mr->vaddr = KERNELBASE;
537 k = 0; 579 k = 0;
538 580
539 while (nr_pages > 0) { 581 while (nr_pages > 0) {
@@ -545,7 +587,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter)
545 EHEA_PAGESIZE))); 587 EHEA_PAGESIZE)));
546 588
547 hret = ehea_h_register_rpage_mr(adapter->handle, 589 hret = ehea_h_register_rpage_mr(adapter->handle,
548 adapter->mr.handle, 0, 590 mr->handle, 0,
549 0, (u64)pt_abs, 591 0, (u64)pt_abs,
550 num_pages); 592 num_pages);
551 nr_pages -= num_pages; 593 nr_pages -= num_pages;
@@ -554,34 +596,68 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter)
554 (k * EHEA_PAGESIZE))); 596 (k * EHEA_PAGESIZE)));
555 597
556 hret = ehea_h_register_rpage_mr(adapter->handle, 598 hret = ehea_h_register_rpage_mr(adapter->handle,
557 adapter->mr.handle, 0, 599 mr->handle, 0,
558 0, abs_adr,1); 600 0, abs_adr,1);
559 nr_pages--; 601 nr_pages--;
560 } 602 }
561 603
562 if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) { 604 if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) {
563 ehea_h_free_resource(adapter->handle, 605 ehea_h_free_resource(adapter->handle,
564 adapter->mr.handle); 606 mr->handle, FORCE_FREE);
565 ehea_error("register_rpage_mr failed: hret = %lX", 607 ehea_error("register_rpage_mr failed");
566 hret);
567 ret = -EIO; 608 ret = -EIO;
568 goto out; 609 goto out;
569 } 610 }
570 } 611 }
571 612
572 if (hret != H_SUCCESS) { 613 if (hret != H_SUCCESS) {
573 ehea_h_free_resource(adapter->handle, adapter->mr.handle); 614 ehea_h_free_resource(adapter->handle, mr->handle,
574 ehea_error("register_rpage failed for last page: hret = %lX", 615 FORCE_FREE);
575 hret); 616 ehea_error("register_rpage failed for last page");
576 ret = -EIO; 617 ret = -EIO;
577 goto out; 618 goto out;
578 } 619 }
620
621 mr->adapter = adapter;
579 ret = 0; 622 ret = 0;
580out: 623out:
581 kfree(pt); 624 kfree(pt);
582 return ret; 625 return ret;
583} 626}
584 627
628int ehea_rem_mr(struct ehea_mr *mr)
629{
630 u64 hret;
631
632 if (!mr || !mr->adapter)
633 return -EINVAL;
634
635 hret = ehea_h_free_resource(mr->adapter->handle, mr->handle,
636 FORCE_FREE);
637 if (hret != H_SUCCESS) {
638 ehea_error("destroy MR failed");
639 return -EIO;
640 }
641
642 return 0;
643}
644
645int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr,
646 struct ehea_mr *shared_mr)
647{
648 u64 hret;
649
650 hret = ehea_h_register_smr(adapter->handle, old_mr->handle,
651 old_mr->vaddr, EHEA_MR_ACC_CTRL,
652 adapter->pd, shared_mr);
653 if (hret != H_SUCCESS)
654 return -EIO;
655
656 shared_mr->adapter = adapter;
657
658 return 0;
659}
660
585void print_error_data(u64 *data) 661void print_error_data(u64 *data)
586{ 662{
587 int length; 663 int length;
@@ -597,6 +673,14 @@ void print_error_data(u64 *data)
597 ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " 673 ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, "
598 "port=%lX", resource, data[6], data[12], data[22]); 674 "port=%lX", resource, data[6], data[12], data[22]);
599 675
676 if (type == 0x4) /* Completion Queue */
677 ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource,
678 data[6]);
679
680 if (type == 0x3) /* Event Queue */
681 ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource,
682 data[6]);
683
600 ehea_dump(data, length, "error data"); 684 ehea_dump(data, length, "error data");
601} 685}
602 686
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index 1ff60983504d..c0eb3e03a102 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -142,6 +142,8 @@ struct ehea_rwqe {
142#define EHEA_CQE_STAT_ERR_MASK 0x721F 142#define EHEA_CQE_STAT_ERR_MASK 0x721F
143#define EHEA_CQE_STAT_FAT_ERR_MASK 0x1F 143#define EHEA_CQE_STAT_FAT_ERR_MASK 0x1F
144#define EHEA_CQE_STAT_ERR_TCP 0x4000 144#define EHEA_CQE_STAT_ERR_TCP 0x4000
145#define EHEA_CQE_STAT_ERR_IP 0x2000
146#define EHEA_CQE_STAT_ERR_CRC 0x1000
145 147
146struct ehea_cqe { 148struct ehea_cqe {
147 u64 wr_id; /* work request ID from WQE */ 149 u64 wr_id; /* work request ID from WQE */
@@ -320,6 +322,11 @@ static inline struct ehea_cqe *ehea_poll_rq1(struct ehea_qp *qp, int *wqe_index)
320 return hw_qeit_get_valid(queue); 322 return hw_qeit_get_valid(queue);
321} 323}
322 324
325static inline void ehea_inc_cq(struct ehea_cq *cq)
326{
327 hw_qeit_inc(&cq->hw_queue);
328}
329
323static inline void ehea_inc_rq1(struct ehea_qp *qp) 330static inline void ehea_inc_rq1(struct ehea_qp *qp)
324{ 331{
325 hw_qeit_inc(&qp->hw_rqueue1); 332 hw_qeit_inc(&qp->hw_rqueue1);
@@ -327,7 +334,7 @@ static inline void ehea_inc_rq1(struct ehea_qp *qp)
327 334
328static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq) 335static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq)
329{ 336{
330 return hw_qeit_get_inc_valid(&my_cq->hw_queue); 337 return hw_qeit_get_valid(&my_cq->hw_queue);
331} 338}
332 339
333#define EHEA_CQ_REGISTER_ORIG 0 340#define EHEA_CQ_REGISTER_ORIG 0
@@ -356,7 +363,12 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter * adapter, u32 pd,
356 363
357int ehea_destroy_qp(struct ehea_qp *qp); 364int ehea_destroy_qp(struct ehea_qp *qp);
358 365
359int ehea_reg_mr_adapter(struct ehea_adapter *adapter); 366int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr);
367
368int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr,
369 struct ehea_mr *shared_mr);
370
371int ehea_rem_mr(struct ehea_mr *mr);
360 372
361void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); 373void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle);
362 374
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 30baf6ecfc63..17ac6975d70d 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -415,11 +415,18 @@ static int ser12_open(struct net_device *dev)
415 415
416 if (!dev || !bc) 416 if (!dev || !bc)
417 return -ENXIO; 417 return -ENXIO;
418 if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT || 418 if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT ||
419 dev->irq < 2 || dev->irq > 15) 419 dev->irq < 2 || dev->irq > NR_IRQS) {
420 printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) "
421 "or irq (2 <= irq <= %d)\n",
422 0xffff-SER12_EXTENT, NR_IRQS);
420 return -ENXIO; 423 return -ENXIO;
421 if (bc->baud < 300 || bc->baud > 4800) 424 }
425 if (bc->baud < 300 || bc->baud > 4800) {
426 printk(KERN_INFO "baycom_ser_fdx: invalid baudrate "
427 "(300...4800)\n");
422 return -EINVAL; 428 return -EINVAL;
429 }
423 if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) { 430 if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) {
424 printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy \n", 431 printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy \n",
425 dev->base_addr); 432 dev->base_addr);
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 0573fcfcb2c4..3bec0f733f01 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -93,7 +93,7 @@ static void ibmveth_proc_unregister_driver(void);
93static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); 93static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
94static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); 94static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
95static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); 95static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance);
96static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); 96static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
97static struct kobj_type ktype_veth_pool; 97static struct kobj_type ktype_veth_pool;
98 98
99#ifdef CONFIG_PROC_FS 99#ifdef CONFIG_PROC_FS
@@ -389,7 +389,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
389 } 389 }
390} 390}
391 391
392static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) 392static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
393{ 393{
394 ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); 394 ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
395 395
@@ -953,14 +953,16 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
953 ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n", 953 ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n",
954 dev->unit_address); 954 dev->unit_address);
955 955
956 mac_addr_p = (unsigned char *) vio_get_attribute(dev, VETH_MAC_ADDR, 0); 956 mac_addr_p = (unsigned char *) vio_get_attribute(dev,
957 VETH_MAC_ADDR, NULL);
957 if(!mac_addr_p) { 958 if(!mac_addr_p) {
958 printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR " 959 printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR "
959 "attribute\n", __FILE__, __LINE__); 960 "attribute\n", __FILE__, __LINE__);
960 return 0; 961 return 0;
961 } 962 }
962 963
963 mcastFilterSize_p= (unsigned int *) vio_get_attribute(dev, VETH_MCAST_FILTER_SIZE, 0); 964 mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev,
965 VETH_MCAST_FILTER_SIZE, NULL);
964 if(!mcastFilterSize_p) { 966 if(!mcastFilterSize_p) {
965 printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find " 967 printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find "
966 "VETH_MCAST_FILTER_SIZE attribute\n", 968 "VETH_MCAST_FILTER_SIZE attribute\n",
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index cf30a1059ce0..c8e90861f869 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -111,9 +111,6 @@ struct ixgb_adapter;
111/* How many Rx Buffers do we bundle into one write to the hardware ? */ 111/* How many Rx Buffers do we bundle into one write to the hardware ? */
112#define IXGB_RX_BUFFER_WRITE 8 /* Must be power of 2 */ 112#define IXGB_RX_BUFFER_WRITE 8 /* Must be power of 2 */
113 113
114/* only works for sizes that are powers of 2 */
115#define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
116
117/* wrapper around a pointer to a socket buffer, 114/* wrapper around a pointer to a socket buffer,
118 * so a DMA handle can be stored along with the buffer */ 115 * so a DMA handle can be stored along with the buffer */
119struct ixgb_buffer { 116struct ixgb_buffer {
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index d6628bd9590a..afde84868bea 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -577,11 +577,11 @@ ixgb_set_ringparam(struct net_device *netdev,
577 577
578 rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD); 578 rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD);
579 rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD); 579 rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD);
580 IXGB_ROUNDUP(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 580 rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
581 581
582 txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD); 582 txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD);
583 txdr->count = min(txdr->count,(uint32_t)MAX_TXD); 583 txdr->count = min(txdr->count,(uint32_t)MAX_TXD);
584 IXGB_ROUNDUP(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 584 txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
585 585
586 if(netif_running(adapter->netdev)) { 586 if(netif_running(adapter->netdev)) {
587 /* Try to get new resources before deleting old */ 587 /* Try to get new resources before deleting old */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index dfde80e54aef..6d2b059371f1 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -685,7 +685,7 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
685 /* round up to nearest 4K */ 685 /* round up to nearest 4K */
686 686
687 txdr->size = txdr->count * sizeof(struct ixgb_tx_desc); 687 txdr->size = txdr->count * sizeof(struct ixgb_tx_desc);
688 IXGB_ROUNDUP(txdr->size, 4096); 688 txdr->size = ALIGN(txdr->size, 4096);
689 689
690 txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); 690 txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
691 if(!txdr->desc) { 691 if(!txdr->desc) {
@@ -774,7 +774,7 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
774 /* Round up to nearest 4K */ 774 /* Round up to nearest 4K */
775 775
776 rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc); 776 rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc);
777 IXGB_ROUNDUP(rxdr->size, 4096); 777 rxdr->size = ALIGN(rxdr->size, 4096);
778 778
779 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); 779 rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
780 780
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index b27442a121f2..5d5ddabf4360 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -245,8 +245,6 @@ ixgb_validate_option(int *value, struct ixgb_option *opt)
245 return -1; 245 return -1;
246} 246}
247 247
248#define LIST_LEN(l) (sizeof(l) / sizeof(l[0]))
249
250/** 248/**
251 * ixgb_check_options - Range Checking for Command Line Parameters 249 * ixgb_check_options - Range Checking for Command Line Parameters
252 * @adapter: board private structure 250 * @adapter: board private structure
@@ -284,7 +282,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
284 } else { 282 } else {
285 tx_ring->count = opt.def; 283 tx_ring->count = opt.def;
286 } 284 }
287 IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 285 tx_ring->count = ALIGN(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
288 } 286 }
289 { /* Receive Descriptor Count */ 287 { /* Receive Descriptor Count */
290 struct ixgb_option opt = { 288 struct ixgb_option opt = {
@@ -303,7 +301,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
303 } else { 301 } else {
304 rx_ring->count = opt.def; 302 rx_ring->count = opt.def;
305 } 303 }
306 IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 304 rx_ring->count = ALIGN(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
307 } 305 }
308 { /* Receive Checksum Offload Enable */ 306 { /* Receive Checksum Offload Enable */
309 struct ixgb_option opt = { 307 struct ixgb_option opt = {
@@ -335,7 +333,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
335 .name = "Flow Control", 333 .name = "Flow Control",
336 .err = "reading default settings from EEPROM", 334 .err = "reading default settings from EEPROM",
337 .def = ixgb_fc_tx_pause, 335 .def = ixgb_fc_tx_pause,
338 .arg = { .l = { .nr = LIST_LEN(fc_list), 336 .arg = { .l = { .nr = ARRAY_SIZE(fc_list),
339 .p = fc_list }} 337 .p = fc_list }}
340 }; 338 };
341 339
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 2912a34f597b..92056051f269 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -33,6 +33,13 @@
33#include <linux/ethtool.h> 33#include <linux/ethtool.h>
34#include <linux/mii.h> 34#include <linux/mii.h>
35 35
36/**
37 * mii_ethtool_gset - get settings that are specified in @ecmd
38 * @mii: MII interface
39 * @ecmd: requested ethtool_cmd
40 *
41 * Returns 0 for success, negative on error.
42 */
36int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) 43int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
37{ 44{
38 struct net_device *dev = mii->dev; 45 struct net_device *dev = mii->dev;
@@ -114,6 +121,13 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
114 return 0; 121 return 0;
115} 122}
116 123
124/**
125 * mii_ethtool_sset - set settings that are specified in @ecmd
126 * @mii: MII interface
127 * @ecmd: requested ethtool_cmd
128 *
129 * Returns 0 for success, negative on error.
130 */
117int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) 131int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
118{ 132{
119 struct net_device *dev = mii->dev; 133 struct net_device *dev = mii->dev;
@@ -207,6 +221,10 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
207 return 0; 221 return 0;
208} 222}
209 223
224/**
225 * mii_check_gmii_support - check if the MII supports Gb interfaces
226 * @mii: the MII interface
227 */
210int mii_check_gmii_support(struct mii_if_info *mii) 228int mii_check_gmii_support(struct mii_if_info *mii)
211{ 229{
212 int reg; 230 int reg;
@@ -221,6 +239,12 @@ int mii_check_gmii_support(struct mii_if_info *mii)
221 return 0; 239 return 0;
222} 240}
223 241
242/**
243 * mii_link_ok - is link status up/ok
244 * @mii: the MII interface
245 *
246 * Returns 1 if the MII reports link status up/ok, 0 otherwise.
247 */
224int mii_link_ok (struct mii_if_info *mii) 248int mii_link_ok (struct mii_if_info *mii)
225{ 249{
226 /* first, a dummy read, needed to latch some MII phys */ 250 /* first, a dummy read, needed to latch some MII phys */
@@ -230,6 +254,12 @@ int mii_link_ok (struct mii_if_info *mii)
230 return 0; 254 return 0;
231} 255}
232 256
257/**
258 * mii_nway_restart - restart NWay (autonegotiation) for this interface
259 * @mii: the MII interface
260 *
261 * Returns 0 on success, negative on error.
262 */
233int mii_nway_restart (struct mii_if_info *mii) 263int mii_nway_restart (struct mii_if_info *mii)
234{ 264{
235 int bmcr; 265 int bmcr;
@@ -247,6 +277,14 @@ int mii_nway_restart (struct mii_if_info *mii)
247 return r; 277 return r;
248} 278}
249 279
280/**
281 * mii_check_link - check MII link status
282 * @mii: MII interface
283 *
284 * If the link status changed (previous != current), call
285 * netif_carrier_on() if current link status is Up or call
286 * netif_carrier_off() if current link status is Down.
287 */
250void mii_check_link (struct mii_if_info *mii) 288void mii_check_link (struct mii_if_info *mii)
251{ 289{
252 int cur_link = mii_link_ok(mii); 290 int cur_link = mii_link_ok(mii);
@@ -258,6 +296,15 @@ void mii_check_link (struct mii_if_info *mii)
258 netif_carrier_off(mii->dev); 296 netif_carrier_off(mii->dev);
259} 297}
260 298
299/**
300 * mii_check_media - check the MII interface for a duplex change
301 * @mii: the MII interface
302 * @ok_to_print: OK to print link up/down messages
303 * @init_media: OK to save duplex mode in @mii
304 *
305 * Returns 1 if the duplex mode changed, 0 if not.
306 * If the media type is forced, always returns 0.
307 */
261unsigned int mii_check_media (struct mii_if_info *mii, 308unsigned int mii_check_media (struct mii_if_info *mii,
262 unsigned int ok_to_print, 309 unsigned int ok_to_print,
263 unsigned int init_media) 310 unsigned int init_media)
@@ -326,6 +373,16 @@ unsigned int mii_check_media (struct mii_if_info *mii,
326 return 0; /* duplex did not change */ 373 return 0; /* duplex did not change */
327} 374}
328 375
376/**
377 * generic_mii_ioctl - main MII ioctl interface
378 * @mii_if: the MII interface
379 * @mii_data: MII ioctl data structure
380 * @cmd: MII ioctl command
381 * @duplex_chg_out: pointer to @duplex_changed status if there was no
382 * ioctl error
383 *
384 * Returns 0 on success, negative on error.
385 */
329int generic_mii_ioctl(struct mii_if_info *mii_if, 386int generic_mii_ioctl(struct mii_if_info *mii_if,
330 struct mii_ioctl_data *mii_data, int cmd, 387 struct mii_ioctl_data *mii_data, int cmd,
331 unsigned int *duplex_chg_out) 388 unsigned int *duplex_chg_out)
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 403f63afd201..638a279ec505 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -26,8 +26,6 @@ struct mipsnet_priv {
26 struct net_device_stats stats; 26 struct net_device_stats stats;
27}; 27};
28 28
29static struct platform_device *mips_plat_dev;
30
31static char mipsnet_string[] = "mipsnet"; 29static char mipsnet_string[] = "mipsnet";
32 30
33/* 31/*
@@ -297,64 +295,17 @@ static struct device_driver mipsnet_driver = {
297 .remove = __devexit_p(mipsnet_device_remove), 295 .remove = __devexit_p(mipsnet_device_remove),
298}; 296};
299 297
300static void mipsnet_platform_release(struct device *device)
301{
302 struct platform_device *pldev;
303
304 /* free device */
305 pldev = to_platform_device(device);
306 kfree(pldev);
307}
308
309static int __init mipsnet_init_module(void) 298static int __init mipsnet_init_module(void)
310{ 299{
311 struct platform_device *pldev;
312 int err; 300 int err;
313 301
314 printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " 302 printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
315 "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); 303 "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
316 304
317 if (driver_register(&mipsnet_driver)) { 305 err = driver_register(&mipsnet_driver);
306 if (err)
318 printk(KERN_ERR "Driver registration failed\n"); 307 printk(KERN_ERR "Driver registration failed\n");
319 err = -ENODEV;
320 goto out;
321 }
322
323 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
324 err = -ENOMEM;
325 goto out_unregister_driver;
326 }
327
328 memset (pldev, 0, sizeof (*pldev));
329 pldev->name = mipsnet_string;
330 pldev->id = 0;
331 pldev->dev.release = mipsnet_platform_release;
332 308
333 if (platform_device_register(pldev)) {
334 err = -ENODEV;
335 goto out_free_pldev;
336 }
337
338 if (!pldev->dev.driver) {
339 /*
340 * The driver was not bound to this device, there was
341 * no hardware at this address. Unregister it, as the
342 * release fuction will take care of freeing the
343 * allocated structure
344 */
345 platform_device_unregister (pldev);
346 }
347
348 mips_plat_dev = pldev;
349
350 return 0;
351
352out_free_pldev:
353 kfree(pldev);
354
355out_unregister_driver:
356 driver_unregister(&mipsnet_driver);
357out:
358 return err; 309 return err;
359} 310}
360 311
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index ab15ecd4b3d6..1799eee88db7 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -51,8 +51,8 @@
51#include "mv643xx_eth.h" 51#include "mv643xx_eth.h"
52 52
53/* Static function declarations */ 53/* Static function declarations */
54static void eth_port_uc_addr_get(struct net_device *dev, 54static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr);
55 unsigned char *MacAddr); 55static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr);
56static void eth_port_set_multicast_list(struct net_device *); 56static void eth_port_set_multicast_list(struct net_device *);
57static void mv643xx_eth_port_enable_tx(unsigned int port_num, 57static void mv643xx_eth_port_enable_tx(unsigned int port_num,
58 unsigned int queues); 58 unsigned int queues);
@@ -1381,7 +1381,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1381 port_num = mp->port_num = pd->port_number; 1381 port_num = mp->port_num = pd->port_number;
1382 1382
1383 /* set default config values */ 1383 /* set default config values */
1384 eth_port_uc_addr_get(dev, dev->dev_addr); 1384 eth_port_uc_addr_get(port_num, dev->dev_addr);
1385 mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE; 1385 mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
1386 mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; 1386 mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
1387 1387
@@ -1839,26 +1839,9 @@ static void eth_port_start(struct net_device *dev)
1839} 1839}
1840 1840
1841/* 1841/*
1842 * eth_port_uc_addr_set - This function Set the port Unicast address. 1842 * eth_port_uc_addr_set - Write a MAC address into the port's hw registers
1843 *
1844 * DESCRIPTION:
1845 * This function Set the port Ethernet MAC address.
1846 *
1847 * INPUT:
1848 * unsigned int eth_port_num Port number.
1849 * char * p_addr Address to be set
1850 *
1851 * OUTPUT:
1852 * Set MAC address low and high registers. also calls
1853 * eth_port_set_filter_table_entry() to set the unicast
1854 * table with the proper information.
1855 *
1856 * RETURN:
1857 * N/A.
1858 *
1859 */ 1843 */
1860static void eth_port_uc_addr_set(unsigned int eth_port_num, 1844static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr)
1861 unsigned char *p_addr)
1862{ 1845{
1863 unsigned int mac_h; 1846 unsigned int mac_h;
1864 unsigned int mac_l; 1847 unsigned int mac_l;
@@ -1868,40 +1851,24 @@ static void eth_port_uc_addr_set(unsigned int eth_port_num,
1868 mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | 1851 mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
1869 (p_addr[3] << 0); 1852 (p_addr[3] << 0);
1870 1853
1871 mv_write(MV643XX_ETH_MAC_ADDR_LOW(eth_port_num), mac_l); 1854 mv_write(MV643XX_ETH_MAC_ADDR_LOW(port_num), mac_l);
1872 mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h); 1855 mv_write(MV643XX_ETH_MAC_ADDR_HIGH(port_num), mac_h);
1873 1856
1874 /* Accept frames of this address */ 1857 /* Accept frames with this address */
1875 table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(eth_port_num); 1858 table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(port_num);
1876 eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f); 1859 eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f);
1877} 1860}
1878 1861
1879/* 1862/*
1880 * eth_port_uc_addr_get - This function retrieves the port Unicast address 1863 * eth_port_uc_addr_get - Read the MAC address from the port's hw registers
1881 * (MAC address) from the ethernet hw registers.
1882 *
1883 * DESCRIPTION:
1884 * This function retrieves the port Ethernet MAC address.
1885 *
1886 * INPUT:
1887 * unsigned int eth_port_num Port number.
1888 * char *MacAddr pointer where the MAC address is stored
1889 *
1890 * OUTPUT:
1891 * Copy the MAC address to the location pointed to by MacAddr
1892 *
1893 * RETURN:
1894 * N/A.
1895 *
1896 */ 1864 */
1897static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *p_addr) 1865static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr)
1898{ 1866{
1899 struct mv643xx_private *mp = netdev_priv(dev);
1900 unsigned int mac_h; 1867 unsigned int mac_h;
1901 unsigned int mac_l; 1868 unsigned int mac_l;
1902 1869
1903 mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(mp->port_num)); 1870 mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(port_num));
1904 mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(mp->port_num)); 1871 mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(port_num));
1905 1872
1906 p_addr[0] = (mac_h >> 24) & 0xff; 1873 p_addr[0] = (mac_h >> 24) & 0xff;
1907 p_addr[1] = (mac_h >> 16) & 0xff; 1874 p_addr[1] = (mac_h >> 16) & 0xff;
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index 7d4e90cf49e8..82f8c0cbfb64 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -346,10 +346,6 @@ static void eth_port_init(struct mv643xx_private *mp);
346static void eth_port_reset(unsigned int eth_port_num); 346static void eth_port_reset(unsigned int eth_port_num);
347static void eth_port_start(struct net_device *dev); 347static void eth_port_start(struct net_device *dev);
348 348
349/* Port MAC address routines */
350static void eth_port_uc_addr_set(unsigned int eth_port_num,
351 unsigned char *p_addr);
352
353/* PHY and MIB routines */ 349/* PHY and MIB routines */
354static void ethernet_phy_reset(unsigned int eth_port_num); 350static void ethernet_phy_reset(unsigned int eth_port_num);
355 351
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index dd8ce35332fe..ad6688eab265 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -64,9 +64,9 @@
64#include "netxen_nic_hw.h" 64#include "netxen_nic_hw.h"
65 65
66#define _NETXEN_NIC_LINUX_MAJOR 3 66#define _NETXEN_NIC_LINUX_MAJOR 3
67#define _NETXEN_NIC_LINUX_MINOR 3 67#define _NETXEN_NIC_LINUX_MINOR 4
68#define _NETXEN_NIC_LINUX_SUBVERSION 3 68#define _NETXEN_NIC_LINUX_SUBVERSION 2
69#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" 69#define NETXEN_NIC_LINUX_VERSIONID "3.4.2"
70 70
71#define NUM_FLASH_SECTORS (64) 71#define NUM_FLASH_SECTORS (64)
72#define FLASH_SECTOR_SIZE (64 * 1024) 72#define FLASH_SECTOR_SIZE (64 * 1024)
@@ -131,8 +131,8 @@ extern struct workqueue_struct *netxen_workq;
131#define FIRST_PAGE_GROUP_START 0 131#define FIRST_PAGE_GROUP_START 0
132#define FIRST_PAGE_GROUP_END 0x100000 132#define FIRST_PAGE_GROUP_END 0x100000
133 133
134#define SECOND_PAGE_GROUP_START 0x4000000 134#define SECOND_PAGE_GROUP_START 0x6000000
135#define SECOND_PAGE_GROUP_END 0x66BC000 135#define SECOND_PAGE_GROUP_END 0x68BC000
136 136
137#define THIRD_PAGE_GROUP_START 0x70E4000 137#define THIRD_PAGE_GROUP_START 0x70E4000
138#define THIRD_PAGE_GROUP_END 0x8000000 138#define THIRD_PAGE_GROUP_END 0x8000000
@@ -205,6 +205,8 @@ enum {
205 205
206#define MAX_CMD_DESCRIPTORS 1024 206#define MAX_CMD_DESCRIPTORS 1024
207#define MAX_RCV_DESCRIPTORS 16384 207#define MAX_RCV_DESCRIPTORS 16384
208#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4)
209#define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4)
208#define MAX_JUMBO_RCV_DESCRIPTORS 1024 210#define MAX_JUMBO_RCV_DESCRIPTORS 1024
209#define MAX_LRO_RCV_DESCRIPTORS 64 211#define MAX_LRO_RCV_DESCRIPTORS 64
210#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS 212#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
@@ -230,7 +232,9 @@ enum {
230 (((index) + (count)) & ((length) - 1)) 232 (((index) + (count)) & ((length) - 1))
231 233
232#define MPORT_SINGLE_FUNCTION_MODE 0x1111 234#define MPORT_SINGLE_FUNCTION_MODE 0x1111
235#define MPORT_MULTI_FUNCTION_MODE 0x2222
233 236
237#include "netxen_nic_phan_reg.h"
234extern unsigned long long netxen_dma_mask; 238extern unsigned long long netxen_dma_mask;
235extern unsigned long last_schedule_time; 239extern unsigned long last_schedule_time;
236 240
@@ -300,6 +304,8 @@ struct netxen_ring_ctx {
300 304
301#define netxen_set_cmd_desc_port(cmd_desc, var) \ 305#define netxen_set_cmd_desc_port(cmd_desc, var) \
302 ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) 306 ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
307#define netxen_set_cmd_desc_ctxid(cmd_desc, var) \
308 ((cmd_desc)->port_ctxid |= ((var) & 0xF0))
303 309
304#define netxen_set_cmd_desc_flags(cmd_desc, val) \ 310#define netxen_set_cmd_desc_flags(cmd_desc, val) \
305 ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ 311 ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \
@@ -442,7 +448,7 @@ struct status_desc {
442 /* Bit pattern: 0-6 lro_count indicates frag sequence, 448 /* Bit pattern: 0-6 lro_count indicates frag sequence,
443 7 last_frag indicates last frag */ 449 7 last_frag indicates last frag */
444 u8 lro; 450 u8 lro;
445} __attribute__ ((aligned(8))); 451} __attribute__ ((aligned(16)));
446 452
447enum { 453enum {
448 NETXEN_RCV_PEG_0 = 0, 454 NETXEN_RCV_PEG_0 = 0,
@@ -703,10 +709,8 @@ extern char netxen_nic_driver_name[];
703#else 709#else
704#define DPRINTK(klevel, fmt, args...) do { \ 710#define DPRINTK(klevel, fmt, args...) do { \
705 printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\ 711 printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
706 (adapter != NULL && \ 712 (adapter != NULL && adapter->netdev != NULL) ? \
707 adapter->port[0] != NULL && \ 713 adapter->netdev->name : NULL, \
708 adapter->port[0]->netdev != NULL) ? \
709 adapter->port[0]->netdev->name : NULL, \
710 ## args); } while(0) 714 ## args); } while(0)
711#endif 715#endif
712 716
@@ -722,6 +726,18 @@ struct netxen_skb_frag {
722 u32 length; 726 u32 length;
723}; 727};
724 728
729#define _netxen_set_bits(config_word, start, bits, val) {\
730 unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));\
731 unsigned long long __tvalue = (val); \
732 (config_word) &= ~__tmask; \
733 (config_word) |= (((__tvalue) << (start)) & __tmask); \
734}
735
736#define _netxen_clear_bits(config_word, start, bits) {\
737 unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start)); \
738 (config_word) &= ~__tmask; \
739}
740
725/* Following defines are for the state of the buffers */ 741/* Following defines are for the state of the buffers */
726#define NETXEN_BUFFER_FREE 0 742#define NETXEN_BUFFER_FREE 0
727#define NETXEN_BUFFER_BUSY 1 743#define NETXEN_BUFFER_BUSY 1
@@ -766,6 +782,8 @@ struct netxen_hardware_context {
766 void __iomem *pci_base0; 782 void __iomem *pci_base0;
767 void __iomem *pci_base1; 783 void __iomem *pci_base1;
768 void __iomem *pci_base2; 784 void __iomem *pci_base2;
785 unsigned long first_page_group_end;
786 unsigned long first_page_group_start;
769 void __iomem *db_base; 787 void __iomem *db_base;
770 unsigned long db_len; 788 unsigned long db_len;
771 789
@@ -780,6 +798,7 @@ struct netxen_hardware_context {
780 struct pci_dev *cmd_desc_pdev; 798 struct pci_dev *cmd_desc_pdev;
781 dma_addr_t cmd_desc_phys_addr; 799 dma_addr_t cmd_desc_phys_addr;
782 struct netxen_adapter *adapter; 800 struct netxen_adapter *adapter;
801 int pci_func;
783}; 802};
784 803
785#define RCV_RING_LRO RCV_DESC_LRO 804#define RCV_RING_LRO RCV_DESC_LRO
@@ -788,17 +807,27 @@ struct netxen_hardware_context {
788#define ETHERNET_FCS_SIZE 4 807#define ETHERNET_FCS_SIZE 4
789 808
790struct netxen_adapter_stats { 809struct netxen_adapter_stats {
791 u64 ints; 810 u64 rcvdbadskb;
792 u64 hostints; 811 u64 xmitcalled;
793 u64 otherints; 812 u64 xmitedframes;
794 u64 process_rcv; 813 u64 xmitfinished;
795 u64 process_xmit; 814 u64 badskblen;
796 u64 noxmitdone; 815 u64 nocmddescriptor;
797 u64 xmitcsummed; 816 u64 polled;
798 u64 post_called; 817 u64 uphappy;
799 u64 posted; 818 u64 updropped;
800 u64 lastposted; 819 u64 uplcong;
801 u64 goodskbposts; 820 u64 uphcong;
821 u64 upmcong;
822 u64 updunno;
823 u64 skbfreed;
824 u64 txdropped;
825 u64 txnullskb;
826 u64 csummed;
827 u64 no_rcv;
828 u64 rxbytes;
829 u64 txbytes;
830 u64 ints;
802}; 831};
803 832
804/* 833/*
@@ -846,13 +875,20 @@ struct netxen_dummy_dma {
846 875
847struct netxen_adapter { 876struct netxen_adapter {
848 struct netxen_hardware_context ahw; 877 struct netxen_hardware_context ahw;
849 int port_count; /* Number of configured ports */ 878
850 int active_ports; /* Number of open ports */ 879 struct netxen_adapter *master;
851 struct netxen_port *port[NETXEN_MAX_PORTS]; /* ptr to each port */ 880 struct net_device *netdev;
881 struct pci_dev *pdev;
882 struct net_device_stats net_stats;
883 unsigned char mac_addr[ETH_ALEN];
884 int mtu;
885 int portnum;
886
852 spinlock_t tx_lock; 887 spinlock_t tx_lock;
853 spinlock_t lock; 888 spinlock_t lock;
854 struct work_struct watchdog_task; 889 struct work_struct watchdog_task;
855 struct timer_list watchdog_timer; 890 struct timer_list watchdog_timer;
891 struct work_struct tx_timeout_task;
856 892
857 u32 curr_window; 893 u32 curr_window;
858 894
@@ -875,6 +911,15 @@ struct netxen_adapter {
875 u32 temp; 911 u32 temp;
876 912
877 struct netxen_adapter_stats stats; 913 struct netxen_adapter_stats stats;
914
915 u16 portno;
916 u16 link_speed;
917 u16 link_duplex;
918 u16 state;
919 u16 link_autoneg;
920 int rcsum;
921 int status;
922 spinlock_t stats_lock;
878 923
879 struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ 924 struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
880 925
@@ -891,65 +936,23 @@ struct netxen_adapter {
891 struct netxen_ring_ctx *ctx_desc; 936 struct netxen_ring_ctx *ctx_desc;
892 struct pci_dev *ctx_desc_pdev; 937 struct pci_dev *ctx_desc_pdev;
893 dma_addr_t ctx_desc_phys_addr; 938 dma_addr_t ctx_desc_phys_addr;
894 int (*enable_phy_interrupts) (struct netxen_adapter *, int); 939 int (*enable_phy_interrupts) (struct netxen_adapter *);
895 int (*disable_phy_interrupts) (struct netxen_adapter *, int); 940 int (*disable_phy_interrupts) (struct netxen_adapter *);
896 void (*handle_phy_intr) (struct netxen_adapter *); 941 void (*handle_phy_intr) (struct netxen_adapter *);
897 int (*macaddr_set) (struct netxen_port *, netxen_ethernet_macaddr_t); 942 int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
898 int (*set_mtu) (struct netxen_port *, int); 943 int (*set_mtu) (struct netxen_adapter *, int);
899 int (*set_promisc) (struct netxen_adapter *, int, 944 int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t);
900 netxen_niu_prom_mode_t); 945 int (*unset_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t);
901 int (*unset_promisc) (struct netxen_adapter *, int, 946 int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
902 netxen_niu_prom_mode_t); 947 int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
903 int (*phy_read) (struct netxen_adapter *, long phy, long reg, u32 *);
904 int (*phy_write) (struct netxen_adapter *, long phy, long reg, u32 val);
905 int (*init_port) (struct netxen_adapter *, int); 948 int (*init_port) (struct netxen_adapter *, int);
906 void (*init_niu) (struct netxen_adapter *); 949 void (*init_niu) (struct netxen_adapter *);
907 int (*stop_port) (struct netxen_adapter *, int); 950 int (*stop_port) (struct netxen_adapter *);
908}; /* netxen_adapter structure */ 951}; /* netxen_adapter structure */
909 952
910/* Max number of xmit producer threads that can run simultaneously */ 953/* Max number of xmit producer threads that can run simultaneously */
911#define MAX_XMIT_PRODUCERS 16 954#define MAX_XMIT_PRODUCERS 16
912 955
913struct netxen_port_stats {
914 u64 rcvdbadskb;
915 u64 xmitcalled;
916 u64 xmitedframes;
917 u64 xmitfinished;
918 u64 badskblen;
919 u64 nocmddescriptor;
920 u64 polled;
921 u64 uphappy;
922 u64 updropped;
923 u64 uplcong;
924 u64 uphcong;
925 u64 upmcong;
926 u64 updunno;
927 u64 skbfreed;
928 u64 txdropped;
929 u64 txnullskb;
930 u64 csummed;
931 u64 no_rcv;
932 u64 rxbytes;
933 u64 txbytes;
934};
935
936struct netxen_port {
937 struct netxen_adapter *adapter;
938
939 u16 portnum; /* GBE port number */
940 u16 link_speed;
941 u16 link_duplex;
942 u16 link_autoneg;
943
944 int flags;
945
946 struct net_device *netdev;
947 struct pci_dev *pdev;
948 struct net_device_stats net_stats;
949 struct netxen_port_stats stats;
950 struct work_struct tx_timeout_task;
951};
952
953#define PCI_OFFSET_FIRST_RANGE(adapter, off) \ 956#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
954 ((adapter)->ahw.pci_base0 + (off)) 957 ((adapter)->ahw.pci_base0 + (off))
955#define PCI_OFFSET_SECOND_RANGE(adapter, off) \ 958#define PCI_OFFSET_SECOND_RANGE(adapter, off) \
@@ -987,32 +990,26 @@ static inline void __iomem *pci_base(struct netxen_adapter *adapter,
987 return NULL; 990 return NULL;
988} 991}
989 992
990int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, 993int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
991 int port); 994int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
992int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, 995int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
993 int port); 996int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter);
994int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter, 997int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter);
995 int port); 998int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter);
996int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter,
997 int port);
998int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter,
999 int port);
1000int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter,
1001 int port);
1002void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter); 999void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter);
1003void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter); 1000void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter);
1004void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, 1001void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port,
1005 long enable); 1002 long enable);
1006void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, 1003void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port,
1007 long enable); 1004 long enable);
1008int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg, 1005int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
1009 __u32 * readval); 1006 __u32 * readval);
1010int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, 1007int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
1011 long reg, __u32 val); 1008 long reg, __u32 val);
1012 1009
1013/* Functions available from netxen_nic_hw.c */ 1010/* Functions available from netxen_nic_hw.c */
1014int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu); 1011int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
1015int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu); 1012int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
1016void netxen_nic_init_niu_gb(struct netxen_adapter *adapter); 1013void netxen_nic_init_niu_gb(struct netxen_adapter *adapter);
1017void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw); 1014void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw);
1018void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); 1015void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
@@ -1027,6 +1024,7 @@ int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
1027 int len); 1024 int len);
1028void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, 1025void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
1029 unsigned long off, int data); 1026 unsigned long off, int data);
1027int netxen_nic_erase_pxe(struct netxen_adapter *adapter);
1030 1028
1031/* Functions from netxen_nic_init.c */ 1029/* Functions from netxen_nic_init.c */
1032void netxen_free_adapter_offload(struct netxen_adapter *adapter); 1030void netxen_free_adapter_offload(struct netxen_adapter *adapter);
@@ -1051,11 +1049,8 @@ int netxen_do_rom_se(struct netxen_adapter *adapter, int addr);
1051 1049
1052/* Functions from netxen_nic_isr.c */ 1050/* Functions from netxen_nic_isr.c */
1053void netxen_nic_isr_other(struct netxen_adapter *adapter); 1051void netxen_nic_isr_other(struct netxen_adapter *adapter);
1054void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 port, 1052void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link);
1055 u32 link); 1053void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable);
1056void netxen_handle_port_int(struct netxen_adapter *adapter, u32 port,
1057 u32 enable);
1058void netxen_nic_stop_all_ports(struct netxen_adapter *adapter);
1059void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); 1054void netxen_initialize_adapter_sw(struct netxen_adapter *adapter);
1060void netxen_initialize_adapter_hw(struct netxen_adapter *adapter); 1055void netxen_initialize_adapter_hw(struct netxen_adapter *adapter);
1061void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, 1056void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
@@ -1110,6 +1105,7 @@ static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
1110 1105
1111 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { 1106 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
1112 mask = 0xbff; 1107 mask = 0xbff;
1108 writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
1113 writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, 1109 writel(mask, PCI_OFFSET_SECOND_RANGE(adapter,
1114 ISR_INT_TARGET_MASK)); 1110 ISR_INT_TARGET_MASK));
1115 } 1111 }
@@ -1174,4 +1170,5 @@ extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
1174 1170
1175extern struct ethtool_ops netxen_nic_ethtool_ops; 1171extern struct ethtool_ops netxen_nic_ethtool_ops;
1176 1172
1173extern int physical_port[]; /* physical port # from virtual port.*/
1177#endif /* __NETXEN_NIC_H_ */ 1174#endif /* __NETXEN_NIC_H_ */
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index ee1b5a24cbe7..16fabb377488 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -40,8 +40,8 @@
40#include <linux/ethtool.h> 40#include <linux/ethtool.h>
41#include <linux/version.h> 41#include <linux/version.h>
42 42
43#include "netxen_nic_hw.h"
44#include "netxen_nic.h" 43#include "netxen_nic.h"
44#include "netxen_nic_hw.h"
45#include "netxen_nic_phan_reg.h" 45#include "netxen_nic_phan_reg.h"
46 46
47struct netxen_nic_stats { 47struct netxen_nic_stats {
@@ -50,8 +50,8 @@ struct netxen_nic_stats {
50 int stat_offset; 50 int stat_offset;
51}; 51};
52 52
53#define NETXEN_NIC_STAT(m) sizeof(((struct netxen_port *)0)->m), \ 53#define NETXEN_NIC_STAT(m) sizeof(((struct netxen_adapter *)0)->m), \
54 offsetof(struct netxen_port, m) 54 offsetof(struct netxen_adapter, m)
55 55
56#define NETXEN_NIC_PORT_WINDOW 0x10000 56#define NETXEN_NIC_PORT_WINDOW 0x10000
57#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF 57#define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
@@ -100,8 +100,7 @@ static int netxen_nic_get_eeprom_len(struct net_device *dev)
100static void 100static void
101netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) 101netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
102{ 102{
103 struct netxen_port *port = netdev_priv(dev); 103 struct netxen_adapter *adapter = netdev_priv(dev);
104 struct netxen_adapter *adapter = port->adapter;
105 u32 fw_major = 0; 104 u32 fw_major = 0;
106 u32 fw_minor = 0; 105 u32 fw_minor = 0;
107 u32 fw_build = 0; 106 u32 fw_build = 0;
@@ -115,7 +114,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
115 fw_build = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); 114 fw_build = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
116 sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); 115 sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
117 116
118 strncpy(drvinfo->bus_info, pci_name(port->pdev), 32); 117 strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
119 drvinfo->n_stats = NETXEN_NIC_STATS_LEN; 118 drvinfo->n_stats = NETXEN_NIC_STATS_LEN;
120 drvinfo->testinfo_len = NETXEN_NIC_TEST_LEN; 119 drvinfo->testinfo_len = NETXEN_NIC_TEST_LEN;
121 drvinfo->regdump_len = NETXEN_NIC_REGS_LEN; 120 drvinfo->regdump_len = NETXEN_NIC_REGS_LEN;
@@ -125,8 +124,7 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
125static int 124static int
126netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 125netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
127{ 126{
128 struct netxen_port *port = netdev_priv(dev); 127 struct netxen_adapter *adapter = netdev_priv(dev);
129 struct netxen_adapter *adapter = port->adapter;
130 struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg; 128 struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg;
131 129
132 /* read which mode */ 130 /* read which mode */
@@ -146,8 +144,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
146 ecmd->port = PORT_TP; 144 ecmd->port = PORT_TP;
147 145
148 if (netif_running(dev)) { 146 if (netif_running(dev)) {
149 ecmd->speed = port->link_speed; 147 ecmd->speed = adapter->link_speed;
150 ecmd->duplex = port->link_duplex; 148 ecmd->duplex = adapter->link_duplex;
151 } else 149 } else
152 return -EIO; /* link absent */ 150 return -EIO; /* link absent */
153 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { 151 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
@@ -165,7 +163,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
165 } else 163 } else
166 return -EIO; 164 return -EIO;
167 165
168 ecmd->phy_address = port->portnum; 166 ecmd->phy_address = adapter->portnum;
169 ecmd->transceiver = XCVR_EXTERNAL; 167 ecmd->transceiver = XCVR_EXTERNAL;
170 168
171 switch ((netxen_brdtype_t) boardinfo->board_type) { 169 switch ((netxen_brdtype_t) boardinfo->board_type) {
@@ -179,7 +177,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
179 ecmd->port = PORT_TP; 177 ecmd->port = PORT_TP;
180 ecmd->autoneg = (boardinfo->board_type == 178 ecmd->autoneg = (boardinfo->board_type ==
181 NETXEN_BRDTYPE_P2_SB31_10G_CX4) ? 179 NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
182 (AUTONEG_DISABLE) : (port->link_autoneg); 180 (AUTONEG_DISABLE) : (adapter->link_autoneg);
183 break; 181 break;
184 case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: 182 case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
185 case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: 183 case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -206,23 +204,22 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
206static int 204static int
207netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 205netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
208{ 206{
209 struct netxen_port *port = netdev_priv(dev); 207 struct netxen_adapter *adapter = netdev_priv(dev);
210 struct netxen_adapter *adapter = port->adapter;
211 __u32 status; 208 __u32 status;
212 209
213 /* read which mode */ 210 /* read which mode */
214 if (adapter->ahw.board_type == NETXEN_NIC_GBE) { 211 if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
215 /* autonegotiation */ 212 /* autonegotiation */
216 if (adapter->phy_write 213 if (adapter->phy_write
217 && adapter->phy_write(adapter, port->portnum, 214 && adapter->phy_write(adapter,
218 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 215 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
219 ecmd->autoneg) != 0) 216 ecmd->autoneg) != 0)
220 return -EIO; 217 return -EIO;
221 else 218 else
222 port->link_autoneg = ecmd->autoneg; 219 adapter->link_autoneg = ecmd->autoneg;
223 220
224 if (adapter->phy_read 221 if (adapter->phy_read
225 && adapter->phy_read(adapter, port->portnum, 222 && adapter->phy_read(adapter,
226 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 223 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
227 &status) != 0) 224 &status) != 0)
228 return -EIO; 225 return -EIO;
@@ -245,13 +242,13 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
245 if (ecmd->duplex == DUPLEX_FULL) 242 if (ecmd->duplex == DUPLEX_FULL)
246 netxen_set_phy_duplex(status); 243 netxen_set_phy_duplex(status);
247 if (adapter->phy_write 244 if (adapter->phy_write
248 && adapter->phy_write(adapter, port->portnum, 245 && adapter->phy_write(adapter,
249 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 246 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
250 *((int *)&status)) != 0) 247 *((int *)&status)) != 0)
251 return -EIO; 248 return -EIO;
252 else { 249 else {
253 port->link_speed = ecmd->speed; 250 adapter->link_speed = ecmd->speed;
254 port->link_duplex = ecmd->duplex; 251 adapter->link_duplex = ecmd->duplex;
255 } 252 }
256 } else 253 } else
257 return -EOPNOTSUPP; 254 return -EOPNOTSUPP;
@@ -360,15 +357,14 @@ static struct netxen_niu_regs niu_registers[] = {
360static void 357static void
361netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) 358netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
362{ 359{
363 struct netxen_port *port = netdev_priv(dev); 360 struct netxen_adapter *adapter = netdev_priv(dev);
364 struct netxen_adapter *adapter = port->adapter;
365 __u32 mode, *regs_buff = p; 361 __u32 mode, *regs_buff = p;
366 void __iomem *addr; 362 void __iomem *addr;
367 int i, window; 363 int i, window;
368 364
369 memset(p, 0, NETXEN_NIC_REGS_LEN); 365 memset(p, 0, NETXEN_NIC_REGS_LEN);
370 regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | 366 regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
371 (port->pdev)->device; 367 (adapter->pdev)->device;
372 /* which mode */ 368 /* which mode */
373 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, &regs_buff[0]); 369 NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, &regs_buff[0]);
374 mode = regs_buff[0]; 370 mode = regs_buff[0];
@@ -383,7 +379,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
383 for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) { 379 for (i = 3; niu_registers[mode].reg[i - 3] != -1; i++) {
384 /* GB: port specific registers */ 380 /* GB: port specific registers */
385 if (mode == 0 && i >= 19) 381 if (mode == 0 && i >= 19)
386 window = port->portnum * NETXEN_NIC_PORT_WINDOW; 382 window = physical_port[adapter->portnum] *
383 NETXEN_NIC_PORT_WINDOW;
387 384
388 NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. 385 NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode].
389 reg[i - 3] + window, 386 reg[i - 3] + window,
@@ -395,15 +392,14 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
395 392
396static u32 netxen_nic_test_link(struct net_device *dev) 393static u32 netxen_nic_test_link(struct net_device *dev)
397{ 394{
398 struct netxen_port *port = netdev_priv(dev); 395 struct netxen_adapter *adapter = netdev_priv(dev);
399 struct netxen_adapter *adapter = port->adapter;
400 __u32 status; 396 __u32 status;
401 int val; 397 int val;
402 398
403 /* read which mode */ 399 /* read which mode */
404 if (adapter->ahw.board_type == NETXEN_NIC_GBE) { 400 if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
405 if (adapter->phy_read 401 if (adapter->phy_read
406 && adapter->phy_read(adapter, port->portnum, 402 && adapter->phy_read(adapter,
407 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 403 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
408 &status) != 0) 404 &status) != 0)
409 return -EIO; 405 return -EIO;
@@ -422,15 +418,15 @@ static int
422netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, 418netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
423 u8 * bytes) 419 u8 * bytes)
424{ 420{
425 struct netxen_port *port = netdev_priv(dev); 421 struct netxen_adapter *adapter = netdev_priv(dev);
426 struct netxen_adapter *adapter = port->adapter;
427 int offset; 422 int offset;
428 int ret; 423 int ret;
429 424
430 if (eeprom->len == 0) 425 if (eeprom->len == 0)
431 return -EINVAL; 426 return -EINVAL;
432 427
433 eeprom->magic = (port->pdev)->vendor | ((port->pdev)->device << 16); 428 eeprom->magic = (adapter->pdev)->vendor |
429 ((adapter->pdev)->device << 16);
434 offset = eeprom->offset; 430 offset = eeprom->offset;
435 431
436 ret = netxen_rom_fast_read_words(adapter, offset, bytes, 432 ret = netxen_rom_fast_read_words(adapter, offset, bytes,
@@ -445,8 +441,7 @@ static int
445netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, 441netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
446 u8 * bytes) 442 u8 * bytes)
447{ 443{
448 struct netxen_port *port = netdev_priv(dev); 444 struct netxen_adapter *adapter = netdev_priv(dev);
449 struct netxen_adapter *adapter = port->adapter;
450 int offset = eeprom->offset; 445 int offset = eeprom->offset;
451 static int flash_start; 446 static int flash_start;
452 static int ready_to_flash; 447 static int ready_to_flash;
@@ -516,8 +511,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
516static void 511static void
517netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) 512netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
518{ 513{
519 struct netxen_port *port = netdev_priv(dev); 514 struct netxen_adapter *adapter = netdev_priv(dev);
520 struct netxen_adapter *adapter = port->adapter;
521 int i; 515 int i;
522 516
523 ring->rx_pending = 0; 517 ring->rx_pending = 0;
@@ -541,19 +535,45 @@ static void
541netxen_nic_get_pauseparam(struct net_device *dev, 535netxen_nic_get_pauseparam(struct net_device *dev,
542 struct ethtool_pauseparam *pause) 536 struct ethtool_pauseparam *pause)
543{ 537{
544 struct netxen_port *port = netdev_priv(dev); 538 struct netxen_adapter *adapter = netdev_priv(dev);
545 struct netxen_adapter *adapter = port->adapter;
546 __u32 val; 539 __u32 val;
540 int port = physical_port[adapter->portnum];
547 541
548 if (adapter->ahw.board_type == NETXEN_NIC_GBE) { 542 if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
543 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
544 return;
549 /* get flow control settings */ 545 /* get flow control settings */
550 netxen_nic_read_w0(adapter, 546 netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
551 NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), 547 &val);
552 &val);
553 pause->rx_pause = netxen_gb_get_rx_flowctl(val); 548 pause->rx_pause = netxen_gb_get_rx_flowctl(val);
554 pause->tx_pause = netxen_gb_get_tx_flowctl(val); 549 netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
555 /* get autoneg settings */ 550 switch (port) {
556 pause->autoneg = port->link_autoneg; 551 case 0:
552 pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
553 break;
554 case 1:
555 pause->tx_pause = !(netxen_gb_get_gb1_mask(val));
556 break;
557 case 2:
558 pause->tx_pause = !(netxen_gb_get_gb2_mask(val));
559 break;
560 case 3:
561 default:
562 pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
563 break;
564 }
565 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
566 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
567 return;
568 pause->rx_pause = 1;
569 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
570 if (port == 0)
571 pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
572 else
573 pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
574 } else {
575 printk(KERN_ERR"%s: Unknown board type: %x\n",
576 netxen_nic_driver_name, adapter->ahw.board_type);
557 } 577 }
558} 578}
559 579
@@ -561,42 +581,76 @@ static int
561netxen_nic_set_pauseparam(struct net_device *dev, 581netxen_nic_set_pauseparam(struct net_device *dev,
562 struct ethtool_pauseparam *pause) 582 struct ethtool_pauseparam *pause)
563{ 583{
564 struct netxen_port *port = netdev_priv(dev); 584 struct netxen_adapter *adapter = netdev_priv(dev);
565 struct netxen_adapter *adapter = port->adapter;
566 __u32 val; 585 __u32 val;
567 unsigned int autoneg; 586 int port = physical_port[adapter->portnum];
568
569 /* read mode */ 587 /* read mode */
570 if (adapter->ahw.board_type == NETXEN_NIC_GBE) { 588 if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
589 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
590 return -EIO;
571 /* set flow control */ 591 /* set flow control */
572 netxen_nic_read_w0(adapter, 592 netxen_nic_read_w0(adapter,
573 NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), 593 NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
574 (u32 *) & val); 594
575 if (pause->tx_pause)
576 netxen_gb_tx_flowctl(val);
577 else
578 netxen_gb_unset_tx_flowctl(val);
579 if (pause->rx_pause) 595 if (pause->rx_pause)
580 netxen_gb_rx_flowctl(val); 596 netxen_gb_rx_flowctl(val);
581 else 597 else
582 netxen_gb_unset_rx_flowctl(val); 598 netxen_gb_unset_rx_flowctl(val);
583 599
584 netxen_nic_write_w0(adapter, 600 netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
585 NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), 601 val);
586 *&val);
587 /* set autoneg */ 602 /* set autoneg */
588 autoneg = pause->autoneg; 603 netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
589 if (adapter->phy_write 604 switch (port) {
590 && adapter->phy_write(adapter, port->portnum, 605 case 0:
591 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 606 if (pause->tx_pause)
592 autoneg) != 0) 607 netxen_gb_unset_gb0_mask(val);
608 else
609 netxen_gb_set_gb0_mask(val);
610 break;
611 case 1:
612 if (pause->tx_pause)
613 netxen_gb_unset_gb1_mask(val);
614 else
615 netxen_gb_set_gb1_mask(val);
616 break;
617 case 2:
618 if (pause->tx_pause)
619 netxen_gb_unset_gb2_mask(val);
620 else
621 netxen_gb_set_gb2_mask(val);
622 break;
623 case 3:
624 default:
625 if (pause->tx_pause)
626 netxen_gb_unset_gb3_mask(val);
627 else
628 netxen_gb_set_gb3_mask(val);
629 break;
630 }
631 netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
632 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
633 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
593 return -EIO; 634 return -EIO;
594 else { 635 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
595 port->link_autoneg = pause->autoneg; 636 if (port == 0) {
596 return 0; 637 if (pause->tx_pause)
638 netxen_xg_unset_xg0_mask(val);
639 else
640 netxen_xg_set_xg0_mask(val);
641 } else {
642 if (pause->tx_pause)
643 netxen_xg_unset_xg1_mask(val);
644 else
645 netxen_xg_set_xg1_mask(val);
597 } 646 }
598 } else 647 netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
599 return -EOPNOTSUPP; 648 } else {
649 printk(KERN_ERR "%s: Unknown board type: %x\n",
650 netxen_nic_driver_name,
651 adapter->ahw.board_type);
652 }
653 return 0;
600} 654}
601 655
602static int netxen_nic_reg_test(struct net_device *dev) 656static int netxen_nic_reg_test(struct net_device *dev)
@@ -627,23 +681,12 @@ static void
627netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, 681netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
628 u64 * data) 682 u64 * data)
629{ 683{
630 if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* offline tests */ 684 memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);
631 /* link test */ 685 if ((data[0] = netxen_nic_reg_test(dev)))
632 if ((data[1] = (u64) netxen_nic_test_link(dev))) 686 eth_test->flags |= ETH_TEST_FL_FAILED;
633 eth_test->flags |= ETH_TEST_FL_FAILED; 687 /* link test */
634 688 if ((data[1] = (u64) netxen_nic_test_link(dev)))
635 /* register tests */ 689 eth_test->flags |= ETH_TEST_FL_FAILED;
636 if ((data[0] = netxen_nic_reg_test(dev)))
637 eth_test->flags |= ETH_TEST_FL_FAILED;
638 } else { /* online tests */
639 /* register tests */
640 if((data[0] = netxen_nic_reg_test(dev)))
641 eth_test->flags |= ETH_TEST_FL_FAILED;
642
643 /* link test */
644 if ((data[1] = (u64) netxen_nic_test_link(dev)))
645 eth_test->flags |= ETH_TEST_FL_FAILED;
646 }
647} 690}
648 691
649static void 692static void
@@ -675,12 +718,13 @@ static void
675netxen_nic_get_ethtool_stats(struct net_device *dev, 718netxen_nic_get_ethtool_stats(struct net_device *dev,
676 struct ethtool_stats *stats, u64 * data) 719 struct ethtool_stats *stats, u64 * data)
677{ 720{
678 struct netxen_port *port = netdev_priv(dev); 721 struct netxen_adapter *adapter = netdev_priv(dev);
679 int index; 722 int index;
680 723
681 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) { 724 for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {
682 char *p = 725 char *p =
683 (char *)port + netxen_nic_gstrings_stats[index].stat_offset; 726 (char *)adapter +
727 netxen_nic_gstrings_stats[index].stat_offset;
684 data[index] = 728 data[index] =
685 (netxen_nic_gstrings_stats[index].sizeof_stat == 729 (netxen_nic_gstrings_stats[index].sizeof_stat ==
686 sizeof(u64)) ? *(u64 *) p : *(u32 *) p; 730 sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index fe8b675f9e72..608e37b349b4 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -467,6 +467,8 @@ enum {
467#define NETXEN_PCI_OCM1 (0x05100000UL) 467#define NETXEN_PCI_OCM1 (0x05100000UL)
468#define NETXEN_PCI_OCM1_MAX (0x051fffffUL) 468#define NETXEN_PCI_OCM1_MAX (0x051fffffUL)
469#define NETXEN_PCI_CRBSPACE (0x06000000UL) 469#define NETXEN_PCI_CRBSPACE (0x06000000UL)
470#define NETXEN_PCI_128MB_SIZE (0x08000000UL)
471#define NETXEN_PCI_32MB_SIZE (0x02000000UL)
470 472
471#define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM) 473#define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM)
472 474
@@ -484,6 +486,7 @@ enum {
484 /* 10 seconds before we give up */ 486 /* 10 seconds before we give up */
485#define NETXEN_NIU_PHY_WAITMAX 50 487#define NETXEN_NIU_PHY_WAITMAX 50
486#define NETXEN_NIU_MAX_GBE_PORTS 4 488#define NETXEN_NIU_MAX_GBE_PORTS 4
489#define NETXEN_NIU_MAX_XG_PORTS 2
487 490
488#define NETXEN_NIU_MODE (NETXEN_CRB_NIU + 0x00000) 491#define NETXEN_NIU_MODE (NETXEN_CRB_NIU + 0x00000)
489 492
@@ -527,6 +530,7 @@ enum {
527#define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) 530#define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098)
528#define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) 531#define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc)
529#define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) 532#define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128)
533#define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c)
530 534
531#define NETXEN_NIU_FULL_LEVEL_XG (NETXEN_CRB_NIU + 0x00450) 535#define NETXEN_NIU_FULL_LEVEL_XG (NETXEN_CRB_NIU + 0x00450)
532 536
@@ -649,11 +653,19 @@ enum {
649#define PCIX_MS_WINDOW (0x10204) 653#define PCIX_MS_WINDOW (0x10204)
650#define PCIX_SN_WINDOW (0x10208) 654#define PCIX_SN_WINDOW (0x10208)
651#define PCIX_CRB_WINDOW (0x10210) 655#define PCIX_CRB_WINDOW (0x10210)
656#define PCIX_CRB_WINDOW_F0 (0x10210)
657#define PCIX_CRB_WINDOW_F1 (0x10230)
658#define PCIX_CRB_WINDOW_F2 (0x10250)
659#define PCIX_CRB_WINDOW_F3 (0x10270)
652 660
653#define PCIX_TARGET_STATUS (0x10118) 661#define PCIX_TARGET_STATUS (0x10118)
654#define PCIX_TARGET_MASK (0x10128) 662#define PCIX_TARGET_MASK (0x10128)
655 663
656#define PCIX_MSI_F0 (0x13000) 664#define PCIX_MSI_F0 (0x13000)
665#define PCIX_MSI_F1 (0x13004)
666#define PCIX_MSI_F2 (0x13008)
667#define PCIX_MSI_F3 (0x1300c)
668#define PCIX_MSI_F(i) (0x13000+((i)*4))
657 669
658#define PCIX_PS_MEM_SPACE (0x90000) 670#define PCIX_PS_MEM_SPACE (0x90000)
659 671
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 0fba8f190762..baff17a24d63 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -33,10 +33,225 @@
33 33
34#include "netxen_nic.h" 34#include "netxen_nic.h"
35#include "netxen_nic_hw.h" 35#include "netxen_nic_hw.h"
36#define DEFINE_GLOBAL_RECV_CRB
36#include "netxen_nic_phan_reg.h" 37#include "netxen_nic_phan_reg.h"
37 38
39
38#include <net/ip.h> 40#include <net/ip.h>
39 41
42struct netxen_recv_crb recv_crb_registers[] = {
43 /*
44 * Instance 0.
45 */
46 {
47 /* rcv_desc_crb: */
48 {
49 {
50 /* crb_rcv_producer_offset: */
51 NETXEN_NIC_REG(0x100),
52 /* crb_rcv_consumer_offset: */
53 NETXEN_NIC_REG(0x104),
54 /* crb_gloablrcv_ring: */
55 NETXEN_NIC_REG(0x108),
56 /* crb_rcv_ring_size */
57 NETXEN_NIC_REG(0x10c),
58
59 },
60 /* Jumbo frames */
61 {
62 /* crb_rcv_producer_offset: */
63 NETXEN_NIC_REG(0x110),
64 /* crb_rcv_consumer_offset: */
65 NETXEN_NIC_REG(0x114),
66 /* crb_gloablrcv_ring: */
67 NETXEN_NIC_REG(0x118),
68 /* crb_rcv_ring_size */
69 NETXEN_NIC_REG(0x11c),
70 },
71 /* LRO */
72 {
73 /* crb_rcv_producer_offset: */
74 NETXEN_NIC_REG(0x120),
75 /* crb_rcv_consumer_offset: */
76 NETXEN_NIC_REG(0x124),
77 /* crb_gloablrcv_ring: */
78 NETXEN_NIC_REG(0x128),
79 /* crb_rcv_ring_size */
80 NETXEN_NIC_REG(0x12c),
81 }
82 },
83 /* crb_rcvstatus_ring: */
84 NETXEN_NIC_REG(0x130),
85 /* crb_rcv_status_producer: */
86 NETXEN_NIC_REG(0x134),
87 /* crb_rcv_status_consumer: */
88 NETXEN_NIC_REG(0x138),
89 /* crb_rcvpeg_state: */
90 NETXEN_NIC_REG(0x13c),
91 /* crb_status_ring_size */
92 NETXEN_NIC_REG(0x140),
93
94 },
95 /*
96 * Instance 1,
97 */
98 {
99 /* rcv_desc_crb: */
100 {
101 {
102 /* crb_rcv_producer_offset: */
103 NETXEN_NIC_REG(0x144),
104 /* crb_rcv_consumer_offset: */
105 NETXEN_NIC_REG(0x148),
106 /* crb_globalrcv_ring: */
107 NETXEN_NIC_REG(0x14c),
108 /* crb_rcv_ring_size */
109 NETXEN_NIC_REG(0x150),
110
111 },
112 /* Jumbo frames */
113 {
114 /* crb_rcv_producer_offset: */
115 NETXEN_NIC_REG(0x154),
116 /* crb_rcv_consumer_offset: */
117 NETXEN_NIC_REG(0x158),
118 /* crb_globalrcv_ring: */
119 NETXEN_NIC_REG(0x15c),
120 /* crb_rcv_ring_size */
121 NETXEN_NIC_REG(0x160),
122 },
123 /* LRO */
124 {
125 /* crb_rcv_producer_offset: */
126 NETXEN_NIC_REG(0x164),
127 /* crb_rcv_consumer_offset: */
128 NETXEN_NIC_REG(0x168),
129 /* crb_globalrcv_ring: */
130 NETXEN_NIC_REG(0x16c),
131 /* crb_rcv_ring_size */
132 NETXEN_NIC_REG(0x170),
133 }
134
135 },
136 /* crb_rcvstatus_ring: */
137 NETXEN_NIC_REG(0x174),
138 /* crb_rcv_status_producer: */
139 NETXEN_NIC_REG(0x178),
140 /* crb_rcv_status_consumer: */
141 NETXEN_NIC_REG(0x17c),
142 /* crb_rcvpeg_state: */
143 NETXEN_NIC_REG(0x180),
144 /* crb_status_ring_size */
145 NETXEN_NIC_REG(0x184),
146 },
147 /*
148 * Instance 2,
149 */
150 {
151 {
152 {
153 /* crb_rcv_producer_offset: */
154 NETXEN_NIC_REG(0x1d8),
155 /* crb_rcv_consumer_offset: */
156 NETXEN_NIC_REG(0x1dc),
157 /* crb_gloablrcv_ring: */
158 NETXEN_NIC_REG(0x1f0),
159 /* crb_rcv_ring_size */
160 NETXEN_NIC_REG(0x1f4),
161 },
162 /* Jumbo frames */
163 {
164 /* crb_rcv_producer_offset: */
165 NETXEN_NIC_REG(0x1f8),
166 /* crb_rcv_consumer_offset: */
167 NETXEN_NIC_REG(0x1fc),
168 /* crb_gloablrcv_ring: */
169 NETXEN_NIC_REG(0x200),
170 /* crb_rcv_ring_size */
171 NETXEN_NIC_REG(0x204),
172 },
173 /* LRO */
174 {
175 /* crb_rcv_producer_offset: */
176 NETXEN_NIC_REG(0x208),
177 /* crb_rcv_consumer_offset: */
178 NETXEN_NIC_REG(0x20c),
179 /* crb_gloablrcv_ring: */
180 NETXEN_NIC_REG(0x210),
181 /* crb_rcv_ring_size */
182 NETXEN_NIC_REG(0x214),
183 }
184 },
185 /* crb_rcvstatus_ring: */
186 NETXEN_NIC_REG(0x218),
187 /* crb_rcv_status_producer: */
188 NETXEN_NIC_REG(0x21c),
189 /* crb_rcv_status_consumer: */
190 NETXEN_NIC_REG(0x220),
191 /* crb_rcvpeg_state: */
192 NETXEN_NIC_REG(0x224),
193 /* crb_status_ring_size */
194 NETXEN_NIC_REG(0x228),
195 },
196 /*
197 * Instance 3,
198 */
199 {
200 {
201 {
202 /* crb_rcv_producer_offset: */
203 NETXEN_NIC_REG(0x22c),
204 /* crb_rcv_consumer_offset: */
205 NETXEN_NIC_REG(0x230),
206 /* crb_gloablrcv_ring: */
207 NETXEN_NIC_REG(0x234),
208 /* crb_rcv_ring_size */
209 NETXEN_NIC_REG(0x238),
210 },
211 /* Jumbo frames */
212 {
213 /* crb_rcv_producer_offset: */
214 NETXEN_NIC_REG(0x23c),
215 /* crb_rcv_consumer_offset: */
216 NETXEN_NIC_REG(0x240),
217 /* crb_gloablrcv_ring: */
218 NETXEN_NIC_REG(0x244),
219 /* crb_rcv_ring_size */
220 NETXEN_NIC_REG(0x248),
221 },
222 /* LRO */
223 {
224 /* crb_rcv_producer_offset: */
225 NETXEN_NIC_REG(0x24c),
226 /* crb_rcv_consumer_offset: */
227 NETXEN_NIC_REG(0x250),
228 /* crb_gloablrcv_ring: */
229 NETXEN_NIC_REG(0x254),
230 /* crb_rcv_ring_size */
231 NETXEN_NIC_REG(0x258),
232 }
233 },
234 /* crb_rcvstatus_ring: */
235 NETXEN_NIC_REG(0x25c),
236 /* crb_rcv_status_producer: */
237 NETXEN_NIC_REG(0x260),
238 /* crb_rcv_status_consumer: */
239 NETXEN_NIC_REG(0x264),
240 /* crb_rcvpeg_state: */
241 NETXEN_NIC_REG(0x268),
242 /* crb_status_ring_size */
243 NETXEN_NIC_REG(0x26c),
244 },
245};
246
247u64 ctx_addr_sig_regs[][3] = {
248 {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
249 {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
250 {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
251 {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
252};
253
254
40/* PCI Windowing for DDR regions. */ 255/* PCI Windowing for DDR regions. */
41 256
42#define ADDR_IN_RANGE(addr, low, high) \ 257#define ADDR_IN_RANGE(addr, low, high) \
@@ -70,8 +285,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter);
70 285
71int netxen_nic_set_mac(struct net_device *netdev, void *p) 286int netxen_nic_set_mac(struct net_device *netdev, void *p)
72{ 287{
73 struct netxen_port *port = netdev_priv(netdev); 288 struct netxen_adapter *adapter = netdev_priv(netdev);
74 struct netxen_adapter *adapter = port->adapter;
75 struct sockaddr *addr = p; 289 struct sockaddr *addr = p;
76 290
77 if (netif_running(netdev)) 291 if (netif_running(netdev))
@@ -84,7 +298,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
84 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 298 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
85 299
86 if (adapter->macaddr_set) 300 if (adapter->macaddr_set)
87 adapter->macaddr_set(port, addr->sa_data); 301 adapter->macaddr_set(adapter, addr->sa_data);
88 302
89 return 0; 303 return 0;
90} 304}
@@ -94,56 +308,19 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
94 */ 308 */
95void netxen_nic_set_multi(struct net_device *netdev) 309void netxen_nic_set_multi(struct net_device *netdev)
96{ 310{
97 struct netxen_port *port = netdev_priv(netdev); 311 struct netxen_adapter *adapter = netdev_priv(netdev);
98 struct netxen_adapter *adapter = port->adapter;
99 struct dev_mc_list *mc_ptr; 312 struct dev_mc_list *mc_ptr;
100 __u32 netxen_mac_addr_cntl_data = 0;
101 313
102 mc_ptr = netdev->mc_list; 314 mc_ptr = netdev->mc_list;
103 if (netdev->flags & IFF_PROMISC) { 315 if (netdev->flags & IFF_PROMISC) {
104 if (adapter->set_promisc) 316 if (adapter->set_promisc)
105 adapter->set_promisc(adapter, 317 adapter->set_promisc(adapter,
106 port->portnum,
107 NETXEN_NIU_PROMISC_MODE); 318 NETXEN_NIU_PROMISC_MODE);
108 } else { 319 } else {
109 if (adapter->unset_promisc && 320 if (adapter->unset_promisc)
110 adapter->ahw.boardcfg.board_type
111 != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
112 adapter->unset_promisc(adapter, 321 adapter->unset_promisc(adapter,
113 port->portnum,
114 NETXEN_NIU_NON_PROMISC_MODE); 322 NETXEN_NIU_NON_PROMISC_MODE);
115 } 323 }
116 if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
117 netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03);
118 netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
119 netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x00);
120 netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x00);
121 netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x00);
122 netxen_nic_mcr_set_enable_xtnd0(netxen_mac_addr_cntl_data);
123 netxen_nic_mcr_set_enable_xtnd1(netxen_mac_addr_cntl_data);
124 netxen_nic_mcr_set_enable_xtnd2(netxen_mac_addr_cntl_data);
125 netxen_nic_mcr_set_enable_xtnd3(netxen_mac_addr_cntl_data);
126 } else {
127 netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x00);
128 netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
129 netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x01);
130 netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x02);
131 netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x03);
132 }
133 writel(netxen_mac_addr_cntl_data,
134 NETXEN_CRB_NORMALIZE(adapter, NETXEN_MAC_ADDR_CNTL_REG));
135 if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
136 writel(netxen_mac_addr_cntl_data,
137 NETXEN_CRB_NORMALIZE(adapter,
138 NETXEN_MULTICAST_ADDR_HI_0));
139 } else {
140 writel(netxen_mac_addr_cntl_data,
141 NETXEN_CRB_NORMALIZE(adapter,
142 NETXEN_MULTICAST_ADDR_HI_1));
143 }
144 netxen_mac_addr_cntl_data = 0;
145 writel(netxen_mac_addr_cntl_data,
146 NETXEN_CRB_NORMALIZE(adapter, NETXEN_NIU_GB_DROP_WRONGADDR));
147} 324}
148 325
149/* 326/*
@@ -152,8 +329,7 @@ void netxen_nic_set_multi(struct net_device *netdev)
152 */ 329 */
153int netxen_nic_change_mtu(struct net_device *netdev, int mtu) 330int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
154{ 331{
155 struct netxen_port *port = netdev_priv(netdev); 332 struct netxen_adapter *adapter = netdev_priv(netdev);
156 struct netxen_adapter *adapter = port->adapter;
157 int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; 333 int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE;
158 334
159 if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { 335 if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) {
@@ -163,7 +339,7 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
163 } 339 }
164 340
165 if (adapter->set_mtu) 341 if (adapter->set_mtu)
166 adapter->set_mtu(port, mtu); 342 adapter->set_mtu(adapter, mtu);
167 netdev->mtu = mtu; 343 netdev->mtu = mtu;
168 344
169 return 0; 345 return 0;
@@ -180,9 +356,9 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
180 void *addr; 356 void *addr;
181 int loops = 0, err = 0; 357 int loops = 0, err = 0;
182 int ctx, ring; 358 int ctx, ring;
183 u32 card_cmdring = 0;
184 struct netxen_recv_context *recv_ctx; 359 struct netxen_recv_context *recv_ctx;
185 struct netxen_rcv_desc_ctx *rcv_desc; 360 struct netxen_rcv_desc_ctx *rcv_desc;
361 int func_id = adapter->portnum;
186 362
187 DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, 363 DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
188 PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); 364 PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
@@ -191,11 +367,6 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
191 DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, 367 DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
192 pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); 368 pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
193 369
194 /* Window 1 call */
195 card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
196
197 DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n",
198 card_cmdring);
199 370
200 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 371 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
201 DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); 372 DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
@@ -229,7 +400,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
229 (dma_addr_t *) & adapter->ctx_desc_phys_addr, 400 (dma_addr_t *) & adapter->ctx_desc_phys_addr,
230 &adapter->ctx_desc_pdev); 401 &adapter->ctx_desc_pdev);
231 402
232 printk("ctx_desc_phys_addr: 0x%llx\n", 403 printk(KERN_INFO "ctx_desc_phys_addr: 0x%llx\n",
233 (unsigned long long) adapter->ctx_desc_phys_addr); 404 (unsigned long long) adapter->ctx_desc_phys_addr);
234 if (addr == NULL) { 405 if (addr == NULL) {
235 DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); 406 DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
@@ -238,6 +409,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
238 } 409 }
239 memset(addr, 0, sizeof(struct netxen_ring_ctx)); 410 memset(addr, 0, sizeof(struct netxen_ring_ctx));
240 adapter->ctx_desc = (struct netxen_ring_ctx *)addr; 411 adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
412 adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
241 adapter->ctx_desc->cmd_consumer_offset = 413 adapter->ctx_desc->cmd_consumer_offset =
242 cpu_to_le64(adapter->ctx_desc_phys_addr + 414 cpu_to_le64(adapter->ctx_desc_phys_addr +
243 sizeof(struct netxen_ring_ctx)); 415 sizeof(struct netxen_ring_ctx));
@@ -249,7 +421,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
249 adapter->max_tx_desc_count, 421 adapter->max_tx_desc_count,
250 (dma_addr_t *) & hw->cmd_desc_phys_addr, 422 (dma_addr_t *) & hw->cmd_desc_phys_addr,
251 &adapter->ahw.cmd_desc_pdev); 423 &adapter->ahw.cmd_desc_pdev);
252 printk("cmd_desc_phys_addr: 0x%llx\n", 424 printk(KERN_INFO "cmd_desc_phys_addr: 0x%llx\n",
253 (unsigned long long) hw->cmd_desc_phys_addr); 425 (unsigned long long) hw->cmd_desc_phys_addr);
254 426
255 if (addr == NULL) { 427 if (addr == NULL) {
@@ -308,11 +480,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
308 /* Window = 1 */ 480 /* Window = 1 */
309 481
310 writel(lower32(adapter->ctx_desc_phys_addr), 482 writel(lower32(adapter->ctx_desc_phys_addr),
311 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO)); 483 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO(func_id)));
312 writel(upper32(adapter->ctx_desc_phys_addr), 484 writel(upper32(adapter->ctx_desc_phys_addr),
313 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI)); 485 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id)));
314 writel(NETXEN_CTX_SIGNATURE, 486 writel(NETXEN_CTX_SIGNATURE | func_id,
315 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG)); 487 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id)));
316 return err; 488 return err;
317} 489}
318 490
@@ -339,10 +511,6 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
339 adapter->ahw.cmd_desc_phys_addr); 511 adapter->ahw.cmd_desc_phys_addr);
340 adapter->ahw.cmd_desc_head = NULL; 512 adapter->ahw.cmd_desc_head = NULL;
341 } 513 }
342 /* Special handling: there are 2 ports on this board */
343 if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
344 adapter->ahw.max_ports = 2;
345 }
346 514
347 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 515 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
348 recv_ctx = &adapter->recv_ctx[ctx]; 516 recv_ctx = &adapter->recv_ctx[ctx];
@@ -385,7 +553,6 @@ void netxen_tso_check(struct netxen_adapter *adapter,
385 return; 553 return;
386 } 554 }
387 } 555 }
388 adapter->stats.xmitcsummed++;
389 desc->tcp_hdr_offset = skb_transport_offset(skb); 556 desc->tcp_hdr_offset = skb_transport_offset(skb);
390 desc->ip_hdr_offset = skb_network_offset(skb); 557 desc->ip_hdr_offset = skb_network_offset(skb);
391} 558}
@@ -475,7 +642,30 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
475 642
476 if (adapter->curr_window == wndw) 643 if (adapter->curr_window == wndw)
477 return; 644 return;
478 645 switch(adapter->ahw.pci_func) {
646 case 0:
647 offset = PCI_OFFSET_SECOND_RANGE(adapter,
648 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
649 break;
650 case 1:
651 offset = PCI_OFFSET_SECOND_RANGE(adapter,
652 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F1));
653 break;
654 case 2:
655 offset = PCI_OFFSET_SECOND_RANGE(adapter,
656 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F2));
657 break;
658 case 3:
659 offset = PCI_OFFSET_SECOND_RANGE(adapter,
660 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3));
661 break;
662 default:
663 printk(KERN_INFO "Changing the window for PCI function"
664 "%d\n", adapter->ahw.pci_func);
665 offset = PCI_OFFSET_SECOND_RANGE(adapter,
666 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
667 break;
668 }
479 /* 669 /*
480 * Move the CRB window. 670 * Move the CRB window.
481 * We need to write to the "direct access" region of PCI 671 * We need to write to the "direct access" region of PCI
@@ -484,9 +674,6 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
484 * register address is received by PCI. The direct region bypasses 674 * register address is received by PCI. The direct region bypasses
485 * the CRB bus. 675 * the CRB bus.
486 */ 676 */
487 offset =
488 PCI_OFFSET_SECOND_RANGE(adapter,
489 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
490 677
491 if (wndw & 0x1) 678 if (wndw & 0x1)
492 wndw = NETXEN_WINDOW_ONE; 679 wndw = NETXEN_WINDOW_ONE;
@@ -504,7 +691,10 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
504 count++; 691 count++;
505 } 692 }
506 693
507 adapter->curr_window = wndw; 694 if (wndw == NETXEN_WINDOW_ONE)
695 adapter->curr_window = 1;
696 else
697 adapter->curr_window = 0;
508} 698}
509 699
510void netxen_load_firmware(struct netxen_adapter *adapter) 700void netxen_load_firmware(struct netxen_adapter *adapter)
@@ -749,6 +939,17 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
749 return addr; 939 return addr;
750} 940}
751 941
942int
943netxen_nic_erase_pxe(struct netxen_adapter *adapter)
944{
945 if (netxen_rom_fast_write(adapter, PXE_START, 0) == -1) {
946 printk(KERN_ERR "%s: erase pxe failed\n",
947 netxen_nic_driver_name);
948 return -1;
949 }
950 return 0;
951}
952
752int netxen_nic_get_board_info(struct netxen_adapter *adapter) 953int netxen_nic_get_board_info(struct netxen_adapter *adapter)
753{ 954{
754 int rv = 0; 955 int rv = 0;
@@ -810,43 +1011,29 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
810 1011
811/* NIU access sections */ 1012/* NIU access sections */
812 1013
813int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu) 1014int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
814{ 1015{
815 struct netxen_adapter *adapter = port->adapter;
816 netxen_nic_write_w0(adapter, 1016 netxen_nic_write_w0(adapter,
817 NETXEN_NIU_GB_MAX_FRAME_SIZE(port->portnum), 1017 NETXEN_NIU_GB_MAX_FRAME_SIZE(
818 new_mtu); 1018 physical_port[adapter->portnum]), new_mtu);
819 return 0; 1019 return 0;
820} 1020}
821 1021
822int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu) 1022int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
823{ 1023{
824 struct netxen_adapter *adapter = port->adapter;
825 new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; 1024 new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
826 if (port->portnum == 0) 1025 if (physical_port[adapter->portnum] == 0)
827 netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); 1026 netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
828 else if (port->portnum == 1) 1027 new_mtu);
829 netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); 1028 else
1029 netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
1030 new_mtu);
830 return 0; 1031 return 0;
831} 1032}
832 1033
833void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) 1034void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
834{ 1035{
835 int portno; 1036 netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]);
836 for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++)
837 netxen_niu_gbe_init_port(adapter, portno);
838}
839
840void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
841{
842 int port_nr;
843 struct netxen_port *port;
844
845 for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
846 port = adapter->port[port_nr];
847 if (adapter->stop_port)
848 adapter->stop_port(adapter, port->portnum);
849 }
850} 1037}
851 1038
852void 1039void
@@ -865,9 +1052,8 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
865 } 1052 }
866} 1053}
867 1054
868void netxen_nic_set_link_parameters(struct netxen_port *port) 1055void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
869{ 1056{
870 struct netxen_adapter *adapter = port->adapter;
871 __u32 status; 1057 __u32 status;
872 __u32 autoneg; 1058 __u32 autoneg;
873 __u32 mode; 1059 __u32 mode;
@@ -876,47 +1062,47 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
876 if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ 1062 if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */
877 if (adapter->phy_read 1063 if (adapter->phy_read
878 && adapter-> 1064 && adapter->
879 phy_read(adapter, port->portnum, 1065 phy_read(adapter,
880 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 1066 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
881 &status) == 0) { 1067 &status) == 0) {
882 if (netxen_get_phy_link(status)) { 1068 if (netxen_get_phy_link(status)) {
883 switch (netxen_get_phy_speed(status)) { 1069 switch (netxen_get_phy_speed(status)) {
884 case 0: 1070 case 0:
885 port->link_speed = SPEED_10; 1071 adapter->link_speed = SPEED_10;
886 break; 1072 break;
887 case 1: 1073 case 1:
888 port->link_speed = SPEED_100; 1074 adapter->link_speed = SPEED_100;
889 break; 1075 break;
890 case 2: 1076 case 2:
891 port->link_speed = SPEED_1000; 1077 adapter->link_speed = SPEED_1000;
892 break; 1078 break;
893 default: 1079 default:
894 port->link_speed = -1; 1080 adapter->link_speed = -1;
895 break; 1081 break;
896 } 1082 }
897 switch (netxen_get_phy_duplex(status)) { 1083 switch (netxen_get_phy_duplex(status)) {
898 case 0: 1084 case 0:
899 port->link_duplex = DUPLEX_HALF; 1085 adapter->link_duplex = DUPLEX_HALF;
900 break; 1086 break;
901 case 1: 1087 case 1:
902 port->link_duplex = DUPLEX_FULL; 1088 adapter->link_duplex = DUPLEX_FULL;
903 break; 1089 break;
904 default: 1090 default:
905 port->link_duplex = -1; 1091 adapter->link_duplex = -1;
906 break; 1092 break;
907 } 1093 }
908 if (adapter->phy_read 1094 if (adapter->phy_read
909 && adapter-> 1095 && adapter->
910 phy_read(adapter, port->portnum, 1096 phy_read(adapter,
911 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 1097 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
912 &autoneg) != 0) 1098 &autoneg) != 0)
913 port->link_autoneg = autoneg; 1099 adapter->link_autoneg = autoneg;
914 } else 1100 } else
915 goto link_down; 1101 goto link_down;
916 } else { 1102 } else {
917 link_down: 1103 link_down:
918 port->link_speed = -1; 1104 adapter->link_speed = -1;
919 port->link_duplex = -1; 1105 adapter->link_duplex = -1;
920 } 1106 }
921 } 1107 }
922} 1108}
@@ -930,7 +1116,7 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
930 char brd_name[NETXEN_MAX_SHORT_NAME]; 1116 char brd_name[NETXEN_MAX_SHORT_NAME];
931 struct netxen_new_user_info user_info; 1117 struct netxen_new_user_info user_info;
932 int i, addr = USER_START; 1118 int i, addr = USER_START;
933 u32 *ptr32; 1119 __le32 *ptr32;
934 1120
935 struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); 1121 struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
936 if (board_info->magic != NETXEN_BDINFO_MAGIC) { 1122 if (board_info->magic != NETXEN_BDINFO_MAGIC) {
@@ -956,7 +1142,6 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
956 netxen_nic_driver_name); 1142 netxen_nic_driver_name);
957 return; 1143 return;
958 } 1144 }
959 *ptr32 = le32_to_cpu(*ptr32);
960 ptr32++; 1145 ptr32++;
961 addr += sizeof(u32); 1146 addr += sizeof(u32);
962 } 1147 }
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index ab1112eb1b0d..245bf13c7ba2 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -6,12 +6,12 @@
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2 7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version. 8 * of the License, or (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -87,7 +87,7 @@ struct netxen_adapter;
87 *(u32 *)Y = readl((void __iomem*) addr); 87 *(u32 *)Y = readl((void __iomem*) addr);
88 88
89struct netxen_port; 89struct netxen_port;
90void netxen_nic_set_link_parameters(struct netxen_port *port); 90void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
91void netxen_nic_flash_print(struct netxen_adapter *adapter); 91void netxen_nic_flash_print(struct netxen_adapter *adapter);
92int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, 92int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off,
93 void *data, int len); 93 void *data, int len);
@@ -220,6 +220,69 @@ typedef enum {
220 _netxen_crb_get_bit(config_word, 1) 220 _netxen_crb_get_bit(config_word, 1)
221#define netxen_get_gb_mii_mgmt_notvalid(config_word) \ 221#define netxen_get_gb_mii_mgmt_notvalid(config_word) \
222 _netxen_crb_get_bit(config_word, 2) 222 _netxen_crb_get_bit(config_word, 2)
223/*
224 * NIU XG Pause Ctl Register
225 *
226 * Bit 0 : xg0_mask => 1:disable tx pause frames
227 * Bit 1 : xg0_request => 1:request single pause frame
228 * Bit 2 : xg0_on_off => 1:request is pause on, 0:off
229 * Bit 3 : xg1_mask => 1:disable tx pause frames
230 * Bit 4 : xg1_request => 1:request single pause frame
231 * Bit 5 : xg1_on_off => 1:request is pause on, 0:off
232 */
233
234#define netxen_xg_set_xg0_mask(config_word) \
235 ((config_word) |= 1 << 0)
236#define netxen_xg_set_xg1_mask(config_word) \
237 ((config_word) |= 1 << 3)
238
239#define netxen_xg_get_xg0_mask(config_word) \
240 _netxen_crb_get_bit((config_word), 0)
241#define netxen_xg_get_xg1_mask(config_word) \
242 _netxen_crb_get_bit((config_word), 3)
243
244#define netxen_xg_unset_xg0_mask(config_word) \
245 ((config_word) &= ~(1 << 0))
246#define netxen_xg_unset_xg1_mask(config_word) \
247 ((config_word) &= ~(1 << 3))
248
249/*
250 * NIU XG Pause Ctl Register
251 *
252 * Bit 0 : xg0_mask => 1:disable tx pause frames
253 * Bit 1 : xg0_request => 1:request single pause frame
254 * Bit 2 : xg0_on_off => 1:request is pause on, 0:off
255 * Bit 3 : xg1_mask => 1:disable tx pause frames
256 * Bit 4 : xg1_request => 1:request single pause frame
257 * Bit 5 : xg1_on_off => 1:request is pause on, 0:off
258 */
259#define netxen_gb_set_gb0_mask(config_word) \
260 ((config_word) |= 1 << 0)
261#define netxen_gb_set_gb1_mask(config_word) \
262 ((config_word) |= 1 << 2)
263#define netxen_gb_set_gb2_mask(config_word) \
264 ((config_word) |= 1 << 4)
265#define netxen_gb_set_gb3_mask(config_word) \
266 ((config_word) |= 1 << 6)
267
268#define netxen_gb_get_gb0_mask(config_word) \
269 _netxen_crb_get_bit((config_word), 0)
270#define netxen_gb_get_gb1_mask(config_word) \
271 _netxen_crb_get_bit((config_word), 2)
272#define netxen_gb_get_gb2_mask(config_word) \
273 _netxen_crb_get_bit((config_word), 4)
274#define netxen_gb_get_gb3_mask(config_word) \
275 _netxen_crb_get_bit((config_word), 6)
276
277#define netxen_gb_unset_gb0_mask(config_word) \
278 ((config_word) &= ~(1 << 0))
279#define netxen_gb_unset_gb1_mask(config_word) \
280 ((config_word) &= ~(1 << 2))
281#define netxen_gb_unset_gb2_mask(config_word) \
282 ((config_word) &= ~(1 << 4))
283#define netxen_gb_unset_gb3_mask(config_word) \
284 ((config_word) &= ~(1 << 6))
285
223 286
224/* 287/*
225 * PHY-Specific MII control/status registers. 288 * PHY-Specific MII control/status registers.
@@ -452,21 +515,21 @@ typedef enum {
452 ((config) |= (((val) & 0x0f) << 28)) 515 ((config) |= (((val) & 0x0f) << 28))
453 516
454/* Set promiscuous mode for a GbE interface */ 517/* Set promiscuous mode for a GbE interface */
455int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, 518int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
456 netxen_niu_prom_mode_t mode); 519 netxen_niu_prom_mode_t mode);
457int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 520int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
458 int port, netxen_niu_prom_mode_t mode); 521 netxen_niu_prom_mode_t mode);
459 522
460/* get/set the MAC address for a given MAC */ 523/* get/set the MAC address for a given MAC */
461int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int port, 524int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
462 netxen_ethernet_macaddr_t * addr); 525 netxen_ethernet_macaddr_t * addr);
463int netxen_niu_macaddr_set(struct netxen_port *port, 526int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
464 netxen_ethernet_macaddr_t addr); 527 netxen_ethernet_macaddr_t addr);
465 528
466/* XG versons */ 529/* XG versons */
467int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int port, 530int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
468 netxen_ethernet_macaddr_t * addr); 531 netxen_ethernet_macaddr_t * addr);
469int netxen_niu_xg_macaddr_set(struct netxen_port *port, 532int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
470 netxen_ethernet_macaddr_t addr); 533 netxen_ethernet_macaddr_t addr);
471 534
472/* Generic enable for GbE ports. Will detect the speed of the link. */ 535/* Generic enable for GbE ports. Will detect the speed of the link. */
@@ -475,8 +538,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
475int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port); 538int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
476 539
477/* Disable a GbE interface */ 540/* Disable a GbE interface */
478int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port); 541int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter);
479 542
480int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port); 543int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
481 544
482#endif /* __NETXEN_NIC_HW_H_ */ 545#endif /* __NETXEN_NIC_HW_H_ */
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 5cd40562da7c..cf0e96adfe44 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -139,7 +139,7 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
139 return err; 139 return err;
140 } 140 }
141 /* Window 1 call */ 141 /* Window 1 call */
142 writel(MPORT_SINGLE_FUNCTION_MODE, 142 writel(MPORT_MULTI_FUNCTION_MODE,
143 NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); 143 NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
144 writel(PHAN_INITIALIZE_ACK, 144 writel(PHAN_INITIALIZE_ACK,
145 NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); 145 NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
@@ -226,7 +226,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
226 adapter->unset_promisc = netxen_niu_set_promiscuous_mode; 226 adapter->unset_promisc = netxen_niu_set_promiscuous_mode;
227 adapter->phy_read = netxen_niu_gbe_phy_read; 227 adapter->phy_read = netxen_niu_gbe_phy_read;
228 adapter->phy_write = netxen_niu_gbe_phy_write; 228 adapter->phy_write = netxen_niu_gbe_phy_write;
229 adapter->init_port = netxen_niu_gbe_init_port;
230 adapter->init_niu = netxen_nic_init_niu_gb; 229 adapter->init_niu = netxen_nic_init_niu_gb;
231 adapter->stop_port = netxen_niu_disable_gbe_port; 230 adapter->stop_port = netxen_niu_disable_gbe_port;
232 break; 231 break;
@@ -277,8 +276,8 @@ u32 netxen_decode_crb_addr(u32 addr)
277 return (pci_base + offset); 276 return (pci_base + offset);
278} 277}
279 278
280static long rom_max_timeout = 10000; 279static long rom_max_timeout = 100;
281static long rom_lock_timeout = 1000000; 280static long rom_lock_timeout = 10000;
282static long rom_write_timeout = 700; 281static long rom_write_timeout = 700;
283 282
284static inline int rom_lock(struct netxen_adapter *adapter) 283static inline int rom_lock(struct netxen_adapter *adapter)
@@ -438,9 +437,9 @@ do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
438 437
439 for (addridx = addr; addridx < (addr + size); addridx += 4) { 438 for (addridx = addr; addridx < (addr + size); addridx += 4) {
440 ret = do_rom_fast_read(adapter, addridx, (int *)bytes); 439 ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
441 *(int *)bytes = cpu_to_le32(*(int *)bytes);
442 if (ret != 0) 440 if (ret != 0)
443 break; 441 break;
442 *(int *)bytes = cpu_to_le32(*(int *)bytes);
444 bytes += 4; 443 bytes += 4;
445 } 444 }
446 445
@@ -499,7 +498,6 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
499 int data; 498 int data;
500 499
501 data = le32_to_cpu((*(u32*)bytes)); 500 data = le32_to_cpu((*(u32*)bytes));
502
503 ret = do_rom_fast_write(adapter, addridx, data); 501 ret = do_rom_fast_write(adapter, addridx, data);
504 if (ret < 0) 502 if (ret < 0)
505 return ret; 503 return ret;
@@ -953,7 +951,8 @@ void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
953 951
954 if (!pegtune_val) { 952 if (!pegtune_val) {
955 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); 953 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
956 while (val != PHAN_INITIALIZE_COMPLETE && loops < 200000) { 954 while (val != PHAN_INITIALIZE_COMPLETE &&
955 val != PHAN_INITIALIZE_ACK && loops < 200000) {
957 udelay(100); 956 udelay(100);
958 schedule(); 957 schedule();
959 val = 958 val =
@@ -990,9 +989,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
990 989
991static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) 990static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
992{ 991{
993 int port_num; 992 struct net_device *netdev = adapter->netdev;
994 struct netxen_port *port;
995 struct net_device *netdev;
996 uint32_t temp, temp_state, temp_val; 993 uint32_t temp, temp_state, temp_val;
997 int rv = 0; 994 int rv = 0;
998 995
@@ -1006,14 +1003,9 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
1006 "%s: Device temperature %d degrees C exceeds" 1003 "%s: Device temperature %d degrees C exceeds"
1007 " maximum allowed. Hardware has been shut down.\n", 1004 " maximum allowed. Hardware has been shut down.\n",
1008 netxen_nic_driver_name, temp_val); 1005 netxen_nic_driver_name, temp_val);
1009 for (port_num = 0; port_num < adapter->ahw.max_ports;
1010 port_num++) {
1011 port = adapter->port[port_num];
1012 netdev = port->netdev;
1013 1006
1014 netif_carrier_off(netdev); 1007 netif_carrier_off(netdev);
1015 netif_stop_queue(netdev); 1008 netif_stop_queue(netdev);
1016 }
1017 rv = 1; 1009 rv = 1;
1018 } else if (temp_state == NX_TEMP_WARN) { 1010 } else if (temp_state == NX_TEMP_WARN) {
1019 if (adapter->temp == NX_TEMP_NORMAL) { 1011 if (adapter->temp == NX_TEMP_NORMAL) {
@@ -1037,29 +1029,23 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
1037 1029
1038void netxen_watchdog_task(struct work_struct *work) 1030void netxen_watchdog_task(struct work_struct *work)
1039{ 1031{
1040 int port_num;
1041 struct netxen_port *port;
1042 struct net_device *netdev; 1032 struct net_device *netdev;
1043 struct netxen_adapter *adapter = 1033 struct netxen_adapter *adapter =
1044 container_of(work, struct netxen_adapter, watchdog_task); 1034 container_of(work, struct netxen_adapter, watchdog_task);
1045 1035
1046 if (netxen_nic_check_temp(adapter)) 1036 if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter))
1047 return; 1037 return;
1048 1038
1049 for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) { 1039 netdev = adapter->netdev;
1050 port = adapter->port[port_num]; 1040 if ((netif_running(netdev)) && !netif_carrier_ok(netdev)) {
1051 netdev = port->netdev; 1041 printk(KERN_INFO "%s port %d, %s carrier is now ok\n",
1052 1042 netxen_nic_driver_name, adapter->portnum, netdev->name);
1053 if ((netif_running(netdev)) && !netif_carrier_ok(netdev)) { 1043 netif_carrier_on(netdev);
1054 printk(KERN_INFO "%s port %d, %s carrier is now ok\n",
1055 netxen_nic_driver_name, port_num, netdev->name);
1056 netif_carrier_on(netdev);
1057 }
1058
1059 if (netif_queue_stopped(netdev))
1060 netif_wake_queue(netdev);
1061 } 1044 }
1062 1045
1046 if (netif_queue_stopped(netdev))
1047 netif_wake_queue(netdev);
1048
1063 if (adapter->handle_phy_intr) 1049 if (adapter->handle_phy_intr)
1064 adapter->handle_phy_intr(adapter); 1050 adapter->handle_phy_intr(adapter);
1065 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1051 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1074,9 +1060,8 @@ void
1074netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, 1060netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
1075 struct status_desc *desc) 1061 struct status_desc *desc)
1076{ 1062{
1077 struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)]; 1063 struct pci_dev *pdev = adapter->pdev;
1078 struct pci_dev *pdev = port->pdev; 1064 struct net_device *netdev = adapter->netdev;
1079 struct net_device *netdev = port->netdev;
1080 int index = netxen_get_sts_refhandle(desc); 1065 int index = netxen_get_sts_refhandle(desc);
1081 struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); 1066 struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
1082 struct netxen_rx_buffer *buffer; 1067 struct netxen_rx_buffer *buffer;
@@ -1126,7 +1111,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
1126 skb = (struct sk_buff *)buffer->skb; 1111 skb = (struct sk_buff *)buffer->skb;
1127 1112
1128 if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) { 1113 if (likely(netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) {
1129 port->stats.csummed++; 1114 adapter->stats.csummed++;
1130 skb->ip_summed = CHECKSUM_UNNECESSARY; 1115 skb->ip_summed = CHECKSUM_UNNECESSARY;
1131 } 1116 }
1132 if (desc_ctx == RCV_DESC_LRO_CTXID) { 1117 if (desc_ctx == RCV_DESC_LRO_CTXID) {
@@ -1146,27 +1131,27 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
1146 */ 1131 */
1147 switch (ret) { 1132 switch (ret) {
1148 case NET_RX_SUCCESS: 1133 case NET_RX_SUCCESS:
1149 port->stats.uphappy++; 1134 adapter->stats.uphappy++;
1150 break; 1135 break;
1151 1136
1152 case NET_RX_CN_LOW: 1137 case NET_RX_CN_LOW:
1153 port->stats.uplcong++; 1138 adapter->stats.uplcong++;
1154 break; 1139 break;
1155 1140
1156 case NET_RX_CN_MOD: 1141 case NET_RX_CN_MOD:
1157 port->stats.upmcong++; 1142 adapter->stats.upmcong++;
1158 break; 1143 break;
1159 1144
1160 case NET_RX_CN_HIGH: 1145 case NET_RX_CN_HIGH:
1161 port->stats.uphcong++; 1146 adapter->stats.uphcong++;
1162 break; 1147 break;
1163 1148
1164 case NET_RX_DROP: 1149 case NET_RX_DROP:
1165 port->stats.updropped++; 1150 adapter->stats.updropped++;
1166 break; 1151 break;
1167 1152
1168 default: 1153 default:
1169 port->stats.updunno++; 1154 adapter->stats.updunno++;
1170 break; 1155 break;
1171 } 1156 }
1172 1157
@@ -1178,14 +1163,13 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
1178 /* 1163 /*
1179 * We just consumed one buffer so post a buffer. 1164 * We just consumed one buffer so post a buffer.
1180 */ 1165 */
1181 adapter->stats.post_called++;
1182 buffer->skb = NULL; 1166 buffer->skb = NULL;
1183 buffer->state = NETXEN_BUFFER_FREE; 1167 buffer->state = NETXEN_BUFFER_FREE;
1184 buffer->lro_current_frags = 0; 1168 buffer->lro_current_frags = 0;
1185 buffer->lro_expected_frags = 0; 1169 buffer->lro_expected_frags = 0;
1186 1170
1187 port->stats.no_rcv++; 1171 adapter->stats.no_rcv++;
1188 port->stats.rxbytes += length; 1172 adapter->stats.rxbytes += length;
1189} 1173}
1190 1174
1191/* Process Receive status ring */ 1175/* Process Receive status ring */
@@ -1226,7 +1210,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
1226 1210
1227 /* update the consumer index in phantom */ 1211 /* update the consumer index in phantom */
1228 if (count) { 1212 if (count) {
1229 adapter->stats.process_rcv++;
1230 recv_ctx->status_rx_consumer = consumer; 1213 recv_ctx->status_rx_consumer = consumer;
1231 recv_ctx->status_rx_producer = producer; 1214 recv_ctx->status_rx_producer = producer;
1232 1215
@@ -1249,13 +1232,10 @@ int netxen_process_cmd_ring(unsigned long data)
1249 int count1 = 0; 1232 int count1 = 0;
1250 int count2 = 0; 1233 int count2 = 0;
1251 struct netxen_cmd_buffer *buffer; 1234 struct netxen_cmd_buffer *buffer;
1252 struct netxen_port *port; /* port #1 */
1253 struct netxen_port *nport;
1254 struct pci_dev *pdev; 1235 struct pci_dev *pdev;
1255 struct netxen_skb_frag *frag; 1236 struct netxen_skb_frag *frag;
1256 u32 i; 1237 u32 i;
1257 struct sk_buff *skb = NULL; 1238 struct sk_buff *skb = NULL;
1258 int p;
1259 int done; 1239 int done;
1260 1240
1261 spin_lock(&adapter->tx_lock); 1241 spin_lock(&adapter->tx_lock);
@@ -1276,7 +1256,6 @@ int netxen_process_cmd_ring(unsigned long data)
1276 } 1256 }
1277 1257
1278 adapter->proc_cmd_buf_counter++; 1258 adapter->proc_cmd_buf_counter++;
1279 adapter->stats.process_xmit++;
1280 /* 1259 /*
1281 * Not needed - does not seem to be used anywhere. 1260 * Not needed - does not seem to be used anywhere.
1282 * adapter->cmd_consumer = consumer; 1261 * adapter->cmd_consumer = consumer;
@@ -1285,8 +1264,7 @@ int netxen_process_cmd_ring(unsigned long data)
1285 1264
1286 while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) { 1265 while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
1287 buffer = &adapter->cmd_buf_arr[last_consumer]; 1266 buffer = &adapter->cmd_buf_arr[last_consumer];
1288 port = adapter->port[buffer->port]; 1267 pdev = adapter->pdev;
1289 pdev = port->pdev;
1290 frag = &buffer->frag_array[0]; 1268 frag = &buffer->frag_array[0];
1291 skb = buffer->skb; 1269 skb = buffer->skb;
1292 if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { 1270 if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) {
@@ -1299,24 +1277,23 @@ int netxen_process_cmd_ring(unsigned long data)
1299 PCI_DMA_TODEVICE); 1277 PCI_DMA_TODEVICE);
1300 } 1278 }
1301 1279
1302 port->stats.skbfreed++; 1280 adapter->stats.skbfreed++;
1303 dev_kfree_skb_any(skb); 1281 dev_kfree_skb_any(skb);
1304 skb = NULL; 1282 skb = NULL;
1305 } else if (adapter->proc_cmd_buf_counter == 1) { 1283 } else if (adapter->proc_cmd_buf_counter == 1) {
1306 port->stats.txnullskb++; 1284 adapter->stats.txnullskb++;
1307 } 1285 }
1308 if (unlikely(netif_queue_stopped(port->netdev) 1286 if (unlikely(netif_queue_stopped(adapter->netdev)
1309 && netif_carrier_ok(port->netdev)) 1287 && netif_carrier_ok(adapter->netdev))
1310 && ((jiffies - port->netdev->trans_start) > 1288 && ((jiffies - adapter->netdev->trans_start) >
1311 port->netdev->watchdog_timeo)) { 1289 adapter->netdev->watchdog_timeo)) {
1312 SCHEDULE_WORK(&port->tx_timeout_task); 1290 SCHEDULE_WORK(&adapter->tx_timeout_task);
1313 } 1291 }
1314 1292
1315 last_consumer = get_next_index(last_consumer, 1293 last_consumer = get_next_index(last_consumer,
1316 adapter->max_tx_desc_count); 1294 adapter->max_tx_desc_count);
1317 count1++; 1295 count1++;
1318 } 1296 }
1319 adapter->stats.noxmitdone += count1;
1320 1297
1321 count2 = 0; 1298 count2 = 0;
1322 spin_lock(&adapter->tx_lock); 1299 spin_lock(&adapter->tx_lock);
@@ -1336,13 +1313,10 @@ int netxen_process_cmd_ring(unsigned long data)
1336 } 1313 }
1337 } 1314 }
1338 if (count1 || count2) { 1315 if (count1 || count2) {
1339 for (p = 0; p < adapter->ahw.max_ports; p++) { 1316 if (netif_queue_stopped(adapter->netdev)
1340 nport = adapter->port[p]; 1317 && (adapter->flags & NETXEN_NETDEV_STATUS)) {
1341 if (netif_queue_stopped(nport->netdev) 1318 netif_wake_queue(adapter->netdev);
1342 && (nport->flags & NETXEN_NETDEV_STATUS)) { 1319 adapter->flags &= ~NETXEN_NETDEV_STATUS;
1343 netif_wake_queue(nport->netdev);
1344 nport->flags &= ~NETXEN_NETDEV_STATUS;
1345 }
1346 } 1320 }
1347 } 1321 }
1348 /* 1322 /*
@@ -1388,7 +1362,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1388 netxen_ctx_msg msg = 0; 1362 netxen_ctx_msg msg = 0;
1389 dma_addr_t dma; 1363 dma_addr_t dma;
1390 1364
1391 adapter->stats.post_called++;
1392 rcv_desc = &recv_ctx->rcv_desc[ringid]; 1365 rcv_desc = &recv_ctx->rcv_desc[ringid];
1393 1366
1394 producer = rcv_desc->producer; 1367 producer = rcv_desc->producer;
@@ -1441,8 +1414,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1441 if (count) { 1414 if (count) {
1442 rcv_desc->begin_alloc = index; 1415 rcv_desc->begin_alloc = index;
1443 rcv_desc->rcv_pending += count; 1416 rcv_desc->rcv_pending += count;
1444 adapter->stats.lastposted = count;
1445 adapter->stats.posted += count;
1446 rcv_desc->producer = producer; 1417 rcv_desc->producer = producer;
1447 if (rcv_desc->rcv_free >= 32) { 1418 if (rcv_desc->rcv_free >= 32) {
1448 rcv_desc->rcv_free = 0; 1419 rcv_desc->rcv_free = 0;
@@ -1450,7 +1421,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1450 writel((producer - 1) & 1421 writel((producer - 1) &
1451 (rcv_desc->max_rx_desc_count - 1), 1422 (rcv_desc->max_rx_desc_count - 1),
1452 NETXEN_CRB_NORMALIZE(adapter, 1423 NETXEN_CRB_NORMALIZE(adapter,
1453 recv_crb_registers[0]. 1424 recv_crb_registers[
1425 adapter->portnum].
1454 rcv_desc_crb[ringid]. 1426 rcv_desc_crb[ringid].
1455 crb_rcv_producer_offset)); 1427 crb_rcv_producer_offset));
1456 /* 1428 /*
@@ -1463,7 +1435,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
1463 ((producer - 1435 ((producer -
1464 1) & (rcv_desc-> 1436 1) & (rcv_desc->
1465 max_rx_desc_count - 1))); 1437 max_rx_desc_count - 1)));
1466 netxen_set_msg_ctxid(msg, 0); 1438 netxen_set_msg_ctxid(msg, adapter->portnum);
1467 netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid)); 1439 netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
1468 writel(msg, 1440 writel(msg,
1469 DB_NORMALIZE(adapter, 1441 DB_NORMALIZE(adapter,
@@ -1485,7 +1457,6 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
1485 int count = 0; 1457 int count = 0;
1486 int index = 0; 1458 int index = 0;
1487 1459
1488 adapter->stats.post_called++;
1489 rcv_desc = &recv_ctx->rcv_desc[ringid]; 1460 rcv_desc = &recv_ctx->rcv_desc[ringid];
1490 1461
1491 producer = rcv_desc->producer; 1462 producer = rcv_desc->producer;
@@ -1532,8 +1503,6 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
1532 if (count) { 1503 if (count) {
1533 rcv_desc->begin_alloc = index; 1504 rcv_desc->begin_alloc = index;
1534 rcv_desc->rcv_pending += count; 1505 rcv_desc->rcv_pending += count;
1535 adapter->stats.lastposted = count;
1536 adapter->stats.posted += count;
1537 rcv_desc->producer = producer; 1506 rcv_desc->producer = producer;
1538 if (rcv_desc->rcv_free >= 32) { 1507 if (rcv_desc->rcv_free >= 32) {
1539 rcv_desc->rcv_free = 0; 1508 rcv_desc->rcv_free = 0;
@@ -1541,7 +1510,8 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
1541 writel((producer - 1) & 1510 writel((producer - 1) &
1542 (rcv_desc->max_rx_desc_count - 1), 1511 (rcv_desc->max_rx_desc_count - 1),
1543 NETXEN_CRB_NORMALIZE(adapter, 1512 NETXEN_CRB_NORMALIZE(adapter,
1544 recv_crb_registers[0]. 1513 recv_crb_registers[
1514 adapter->portnum].
1545 rcv_desc_crb[ringid]. 1515 rcv_desc_crb[ringid].
1546 crb_rcv_producer_offset)); 1516 crb_rcv_producer_offset));
1547 wmb(); 1517 wmb();
@@ -1562,13 +1532,7 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
1562 1532
1563void netxen_nic_clear_stats(struct netxen_adapter *adapter) 1533void netxen_nic_clear_stats(struct netxen_adapter *adapter)
1564{ 1534{
1565 struct netxen_port *port;
1566 int port_num;
1567
1568 memset(&adapter->stats, 0, sizeof(adapter->stats)); 1535 memset(&adapter->stats, 0, sizeof(adapter->stats));
1569 for (port_num = 0; port_num < adapter->ahw.max_ports; port_num++) { 1536 return;
1570 port = adapter->port[port_num];
1571 memset(&port->stats, 0, sizeof(port->stats));
1572 }
1573} 1537}
1574 1538
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c
index be366e48007c..b213b062eb56 100644
--- a/drivers/net/netxen/netxen_nic_isr.c
+++ b/drivers/net/netxen/netxen_nic_isr.c
@@ -6,12 +6,12 @@
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2 7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version. 8 * of the License, or (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, but 10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -40,35 +40,35 @@
40 */ 40 */
41struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) 41struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
42{ 42{
43 struct netxen_port *port = netdev_priv(netdev); 43 struct netxen_adapter *adapter = netdev_priv(netdev);
44 struct net_device_stats *stats = &port->net_stats; 44 struct net_device_stats *stats = &adapter->net_stats;
45 45
46 memset(stats, 0, sizeof(*stats)); 46 memset(stats, 0, sizeof(*stats));
47 47
48 /* total packets received */ 48 /* total packets received */
49 stats->rx_packets = port->stats.no_rcv; 49 stats->rx_packets = adapter->stats.no_rcv;
50 /* total packets transmitted */ 50 /* total packets transmitted */
51 stats->tx_packets = port->stats.xmitedframes + port->stats.xmitfinished; 51 stats->tx_packets = adapter->stats.xmitedframes +
52 adapter->stats.xmitfinished;
52 /* total bytes received */ 53 /* total bytes received */
53 stats->rx_bytes = port->stats.rxbytes; 54 stats->rx_bytes = adapter->stats.rxbytes;
54 /* total bytes transmitted */ 55 /* total bytes transmitted */
55 stats->tx_bytes = port->stats.txbytes; 56 stats->tx_bytes = adapter->stats.txbytes;
56 /* bad packets received */ 57 /* bad packets received */
57 stats->rx_errors = port->stats.rcvdbadskb; 58 stats->rx_errors = adapter->stats.rcvdbadskb;
58 /* packet transmit problems */ 59 /* packet transmit problems */
59 stats->tx_errors = port->stats.nocmddescriptor; 60 stats->tx_errors = adapter->stats.nocmddescriptor;
60 /* no space in linux buffers */ 61 /* no space in linux buffers */
61 stats->rx_dropped = port->stats.updropped; 62 stats->rx_dropped = adapter->stats.updropped;
62 /* no space available in linux */ 63 /* no space available in linux */
63 stats->tx_dropped = port->stats.txdropped; 64 stats->tx_dropped = adapter->stats.txdropped;
64 65
65 return stats; 66 return stats;
66} 67}
67 68
68void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, 69void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link)
69 u32 link)
70{ 70{
71 struct net_device *netdev = (adapter->port[portno])->netdev; 71 struct net_device *netdev = adapter->netdev;
72 72
73 if (link) 73 if (link)
74 netif_carrier_on(netdev); 74 netif_carrier_on(netdev);
@@ -76,15 +76,13 @@ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
76 netif_carrier_off(netdev); 76 netif_carrier_off(netdev);
77} 77}
78 78
79void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, 79void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
80 u32 enable)
81{ 80{
82 __u32 int_src; 81 __u32 int_src;
83 struct netxen_port *port;
84 82
85 /* This should clear the interrupt source */ 83 /* This should clear the interrupt source */
86 if (adapter->phy_read) 84 if (adapter->phy_read)
87 adapter->phy_read(adapter, portno, 85 adapter->phy_read(adapter,
88 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, 86 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
89 &int_src); 87 &int_src);
90 if (int_src == 0) { 88 if (int_src == 0) {
@@ -92,9 +90,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
92 return; 90 return;
93 } 91 }
94 if (adapter->disable_phy_interrupts) 92 if (adapter->disable_phy_interrupts)
95 adapter->disable_phy_interrupts(adapter, portno); 93 adapter->disable_phy_interrupts(adapter);
96
97 port = adapter->port[portno];
98 94
99 if (netxen_get_phy_int_jabber(int_src)) 95 if (netxen_get_phy_int_jabber(int_src))
100 DPRINTK(INFO, "Jabber interrupt \n"); 96 DPRINTK(INFO, "Jabber interrupt \n");
@@ -115,64 +111,57 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
115 DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); 111 DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
116 112
117 if (adapter->phy_read 113 if (adapter->phy_read
118 && adapter->phy_read(adapter, portno, 114 && adapter->phy_read(adapter,
119 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 115 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
120 &status) == 0) { 116 &status) == 0) {
121 if (netxen_get_phy_int_link_status_changed(int_src)) { 117 if (netxen_get_phy_int_link_status_changed(int_src)) {
122 if (netxen_get_phy_link(status)) { 118 if (netxen_get_phy_link(status)) {
123 netxen_niu_gbe_init_port(adapter, 119 printk(KERN_INFO "%s: %s Link UP\n",
124 portno);
125 printk("%s: %s Link UP\n",
126 netxen_nic_driver_name, 120 netxen_nic_driver_name,
127 port->netdev->name); 121 adapter->netdev->name);
128 122
129 } else { 123 } else {
130 printk("%s: %s Link DOWN\n", 124 printk(KERN_INFO "%s: %s Link DOWN\n",
131 netxen_nic_driver_name, 125 netxen_nic_driver_name,
132 port->netdev->name); 126 adapter->netdev->name);
133 } 127 }
134 netxen_indicate_link_status(adapter, portno, 128 netxen_indicate_link_status(adapter,
135 netxen_get_phy_link 129 netxen_get_phy_link
136 (status)); 130 (status));
137 } 131 }
138 } 132 }
139 } 133 }
140 if (adapter->enable_phy_interrupts) 134 if (adapter->enable_phy_interrupts)
141 adapter->enable_phy_interrupts(adapter, portno); 135 adapter->enable_phy_interrupts(adapter);
142} 136}
143 137
144void netxen_nic_isr_other(struct netxen_adapter *adapter) 138void netxen_nic_isr_other(struct netxen_adapter *adapter)
145{ 139{
146 u32 portno; 140 int portno = adapter->portnum;
147 u32 val, linkup, qg_linksup; 141 u32 val, linkup, qg_linksup;
148 142
149 /* verify the offset */ 143 /* verify the offset */
150 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); 144 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
145 val = val >> physical_port[adapter->portnum];
151 if (val == adapter->ahw.qg_linksup) 146 if (val == adapter->ahw.qg_linksup)
152 return; 147 return;
153 148
154 qg_linksup = adapter->ahw.qg_linksup; 149 qg_linksup = adapter->ahw.qg_linksup;
155 adapter->ahw.qg_linksup = val; 150 adapter->ahw.qg_linksup = val;
156 DPRINTK(INFO, "link update 0x%08x\n", val); 151 DPRINTK(INFO, "link update 0x%08x\n", val);
157 for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
158 linkup = val & 1;
159 if (linkup != (qg_linksup & 1)) {
160 printk(KERN_INFO "%s: %s PORT %d link %s\n",
161 adapter->port[portno]->netdev->name,
162 netxen_nic_driver_name, portno,
163 ((linkup == 0) ? "down" : "up"));
164 netxen_indicate_link_status(adapter, portno, linkup);
165 if (linkup)
166 netxen_nic_set_link_parameters(adapter->
167 port[portno]);
168 152
169 } 153 linkup = val & 1;
170 val = val >> 1;
171 qg_linksup = qg_linksup >> 1;
172 }
173 154
174 adapter->stats.otherints++; 155 if (linkup != (qg_linksup & 1)) {
156 printk(KERN_INFO "%s: %s PORT %d link %s\n",
157 adapter->netdev->name,
158 netxen_nic_driver_name, portno,
159 ((linkup == 0) ? "down" : "up"));
160 netxen_indicate_link_status(adapter, linkup);
161 if (linkup)
162 netxen_nic_set_link_parameters(adapter);
175 163
164 }
176} 165}
177 166
178void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter) 167void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
@@ -182,26 +171,28 @@ void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
182 171
183void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) 172void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
184{ 173{
185 struct net_device *netdev = adapter->port[0]->netdev; 174 struct net_device *netdev = adapter->netdev;
186 u32 val; 175 u32 val, val1;
187 176
188 /* WINDOW = 1 */ 177 /* WINDOW = 1 */
189 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); 178 val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
179 val >>= (physical_port[adapter->portnum] * 8);
180 val1 = val & 0xff;
190 181
191 if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) { 182 if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
192 printk(KERN_INFO "%s: %s NIC Link is down\n", 183 printk(KERN_INFO "%s: %s NIC Link is down\n",
193 netxen_nic_driver_name, netdev->name); 184 netxen_nic_driver_name, netdev->name);
194 adapter->ahw.xg_linkup = 0; 185 adapter->ahw.xg_linkup = 0;
195 /* read twice to clear sticky bits */ 186 /* read twice to clear sticky bits */
196 /* WINDOW = 0 */ 187 /* WINDOW = 0 */
197 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val); 188 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
198 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val); 189 netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
199 190
200 if ((val & 0xffb) != 0xffb) { 191 if ((val & 0xffb) != 0xffb) {
201 printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n", 192 printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n",
202 netxen_nic_driver_name, val); 193 netxen_nic_driver_name, val1);
203 } 194 }
204 } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) { 195 } else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) {
205 printk(KERN_INFO "%s: %s NIC Link is up\n", 196 printk(KERN_INFO "%s: %s NIC Link is up\n",
206 netxen_nic_driver_name, netdev->name); 197 netxen_nic_driver_name, netdev->name);
207 adapter->ahw.xg_linkup = 1; 198 adapter->ahw.xg_linkup = 1;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index ab25c225a07e..4e32bb678ea9 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -36,7 +36,6 @@
36#include "netxen_nic_hw.h" 36#include "netxen_nic_hw.h"
37 37
38#include "netxen_nic.h" 38#include "netxen_nic.h"
39#define DEFINE_GLOBAL_RECV_CRB
40#include "netxen_nic_phan_reg.h" 39#include "netxen_nic_phan_reg.h"
41 40
42#include <linux/dma-mapping.h> 41#include <linux/dma-mapping.h>
@@ -77,6 +76,8 @@ static void netxen_nic_poll_controller(struct net_device *netdev);
77#endif 76#endif
78static irqreturn_t netxen_intr(int irq, void *data); 77static irqreturn_t netxen_intr(int irq, void *data);
79 78
79int physical_port[] = {0, 1, 2, 3};
80
80/* PCI Device ID Table */ 81/* PCI Device ID Table */
81static struct pci_device_id netxen_pci_tbl[] __devinitdata = { 82static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
82 {PCI_DEVICE(0x4040, 0x0001)}, 83 {PCI_DEVICE(0x4040, 0x0001)},
@@ -94,6 +95,67 @@ MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
94struct workqueue_struct *netxen_workq; 95struct workqueue_struct *netxen_workq;
95static void netxen_watchdog(unsigned long); 96static void netxen_watchdog(unsigned long);
96 97
98static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
99 uint32_t crb_producer)
100{
101 switch (adapter->portnum) {
102 case 0:
103 writel(crb_producer, NETXEN_CRB_NORMALIZE
104 (adapter, CRB_CMD_PRODUCER_OFFSET));
105 return;
106 case 1:
107 writel(crb_producer, NETXEN_CRB_NORMALIZE
108 (adapter, CRB_CMD_PRODUCER_OFFSET_1));
109 return;
110 case 2:
111 writel(crb_producer, NETXEN_CRB_NORMALIZE
112 (adapter, CRB_CMD_PRODUCER_OFFSET_2));
113 return;
114 case 3:
115 writel(crb_producer, NETXEN_CRB_NORMALIZE
116 (adapter, CRB_CMD_PRODUCER_OFFSET_3));
117 return;
118 default:
119 printk(KERN_WARNING "We tried to update "
120 "CRB_CMD_PRODUCER_OFFSET for invalid "
121 "PCI function id %d\n",
122 adapter->portnum);
123 return;
124 }
125}
126
127static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
128 u32 crb_consumer)
129{
130 switch (adapter->portnum) {
131 case 0:
132 writel(crb_consumer, NETXEN_CRB_NORMALIZE
133 (adapter, CRB_CMD_CONSUMER_OFFSET));
134 return;
135 case 1:
136 writel(crb_consumer, NETXEN_CRB_NORMALIZE
137 (adapter, CRB_CMD_CONSUMER_OFFSET_1));
138 return;
139 case 2:
140 writel(crb_consumer, NETXEN_CRB_NORMALIZE
141 (adapter, CRB_CMD_CONSUMER_OFFSET_2));
142 return;
143 case 3:
144 writel(crb_consumer, NETXEN_CRB_NORMALIZE
145 (adapter, CRB_CMD_CONSUMER_OFFSET_3));
146 return;
147 default:
148 printk(KERN_WARNING "We tried to update "
149 "CRB_CMD_PRODUCER_OFFSET for invalid "
150 "PCI function id %d\n",
151 adapter->portnum);
152 return;
153 }
154}
155
156#define ADAPTER_LIST_SIZE 12
157int netxen_cards_found;
158
97/* 159/*
98 * netxen_nic_probe() 160 * netxen_nic_probe()
99 * 161 *
@@ -111,26 +173,30 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
111{ 173{
112 struct net_device *netdev = NULL; 174 struct net_device *netdev = NULL;
113 struct netxen_adapter *adapter = NULL; 175 struct netxen_adapter *adapter = NULL;
114 struct netxen_port *port = NULL;
115 void __iomem *mem_ptr0 = NULL; 176 void __iomem *mem_ptr0 = NULL;
116 void __iomem *mem_ptr1 = NULL; 177 void __iomem *mem_ptr1 = NULL;
117 void __iomem *mem_ptr2 = NULL; 178 void __iomem *mem_ptr2 = NULL;
179 unsigned long first_page_group_end;
180 unsigned long first_page_group_start;
181
118 182
119 u8 __iomem *db_ptr = NULL; 183 u8 __iomem *db_ptr = NULL;
120 unsigned long mem_base, mem_len, db_base, db_len; 184 unsigned long mem_base, mem_len, db_base, db_len;
121 int pci_using_dac, i, err; 185 int pci_using_dac, i = 0, err;
122 int ring; 186 int ring;
123 struct netxen_recv_context *recv_ctx = NULL; 187 struct netxen_recv_context *recv_ctx = NULL;
124 struct netxen_rcv_desc_ctx *rcv_desc = NULL; 188 struct netxen_rcv_desc_ctx *rcv_desc = NULL;
125 struct netxen_cmd_buffer *cmd_buf_arr = NULL; 189 struct netxen_cmd_buffer *cmd_buf_arr = NULL;
126 u64 mac_addr[FLASH_NUM_PORTS + 1]; 190 u64 mac_addr[FLASH_NUM_PORTS + 1];
127 int valid_mac = 0; 191 int valid_mac = 0;
192 u32 val;
193 int pci_func_id = PCI_FUNC(pdev->devfn);
128 194
129 printk(KERN_INFO "%s \n", netxen_nic_driver_string); 195 printk(KERN_INFO "%s \n", netxen_nic_driver_string);
130 /* In current scheme, we use only PCI function 0 */ 196
131 if (PCI_FUNC(pdev->devfn) != 0) { 197 if (pdev->class != 0x020000) {
132 DPRINTK(ERR, "NetXen function %d will not be enabled.\n", 198 printk(KERN_ERR"NetXen function %d, class %x will not"
133 PCI_FUNC(pdev->devfn)); 199 "be enabled.\n",pci_func_id, pdev->class);
134 return -ENODEV; 200 return -ENODEV;
135 } 201 }
136 if ((err = pci_enable_device(pdev))) 202 if ((err = pci_enable_device(pdev)))
@@ -157,18 +223,52 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
157 pci_using_dac = 0; 223 pci_using_dac = 0;
158 } 224 }
159 225
226
227 netdev = alloc_etherdev(sizeof(struct netxen_adapter));
228 if(!netdev) {
229 printk(KERN_ERR"%s: Failed to allocate memory for the "
230 "device block.Check system memory resource"
231 " usage.\n", netxen_nic_driver_name);
232 goto err_out_free_res;
233 }
234
235 SET_MODULE_OWNER(netdev);
236 SET_NETDEV_DEV(netdev, &pdev->dev);
237
238 adapter = netdev->priv;
239 memset(adapter, 0 , sizeof(struct netxen_adapter));
240
241 adapter->ahw.pdev = pdev;
242 adapter->ahw.pci_func = pci_func_id;
243 spin_lock_init(&adapter->tx_lock);
244 spin_lock_init(&adapter->lock);
245
160 /* remap phys address */ 246 /* remap phys address */
161 mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ 247 mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
162 mem_len = pci_resource_len(pdev, 0); 248 mem_len = pci_resource_len(pdev, 0);
163 249
164 /* 128 Meg of memory */ 250 /* 128 Meg of memory */
165 mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); 251 if (mem_len == NETXEN_PCI_128MB_SIZE) {
166 mem_ptr1 = 252 mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
167 ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE); 253 mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START,
168 mem_ptr2 = 254 SECOND_PAGE_GROUP_SIZE);
169 ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); 255 mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
256 THIRD_PAGE_GROUP_SIZE);
257 first_page_group_start = FIRST_PAGE_GROUP_START;
258 first_page_group_end = FIRST_PAGE_GROUP_END;
259 } else if (mem_len == NETXEN_PCI_32MB_SIZE) {
260 mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
261 mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
262 SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
263 first_page_group_start = 0;
264 first_page_group_end = 0;
265 } else {
266 err = -EIO;
267 goto err_out_free_netdev;
268 }
170 269
171 if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { 270 if (((mem_ptr0 == 0UL) && (mem_len == NETXEN_PCI_128MB_SIZE)) ||
271 (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
172 DPRINTK(ERR, 272 DPRINTK(ERR,
173 "Cannot remap adapter memory aborting.:" 273 "Cannot remap adapter memory aborting.:"
174 "0 -> %p, 1 -> %p, 2 -> %p\n", 274 "0 -> %p, 1 -> %p, 2 -> %p\n",
@@ -198,30 +298,87 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
198 } 298 }
199 DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); 299 DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
200 300
201/* 301 adapter->ahw.pci_base0 = mem_ptr0;
202 * Allocate a adapter structure which will manage all the initialization 302 adapter->ahw.first_page_group_start = first_page_group_start;
203 * as well as the common resources for all ports... 303 adapter->ahw.first_page_group_end = first_page_group_end;
204 * all the ports will have pointer to this adapter as well as Adapter 304 adapter->ahw.pci_base1 = mem_ptr1;
205 * will have pointers of all the ports structures. 305 adapter->ahw.pci_base2 = mem_ptr2;
206 */ 306 adapter->ahw.db_base = db_ptr;
307 adapter->ahw.db_len = db_len;
207 308
208 /* One adapter structure for all 4 ports.... */ 309 adapter->netdev = netdev;
209 adapter = kzalloc(sizeof(struct netxen_adapter), GFP_KERNEL); 310 adapter->pdev = pdev;
210 if (adapter == NULL) { 311 adapter->portnum = pci_func_id;
211 printk(KERN_ERR "%s: Could not allocate adapter memory:%d\n", 312
212 netxen_nic_driver_name, 313 netdev->open = netxen_nic_open;
213 (int)sizeof(struct netxen_adapter)); 314 netdev->stop = netxen_nic_close;
214 err = -ENOMEM; 315 netdev->hard_start_xmit = netxen_nic_xmit_frame;
215 goto err_out_dbunmap; 316 netdev->get_stats = netxen_nic_get_stats;
216 } 317 netdev->set_multicast_list = netxen_nic_set_multi;
318 netdev->set_mac_address = netxen_nic_set_mac;
319 netdev->change_mtu = netxen_nic_change_mtu;
320 netdev->tx_timeout = netxen_tx_timeout;
321 netdev->watchdog_timeo = HZ;
322
323 netxen_nic_change_mtu(netdev, netdev->mtu);
324
325 SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
326 netdev->poll = netxen_nic_poll;
327 netdev->weight = NETXEN_NETDEV_WEIGHT;
328#ifdef CONFIG_NET_POLL_CONTROLLER
329 netdev->poll_controller = netxen_nic_poll_controller;
330#endif
331 /* ScatterGather support */
332 netdev->features = NETIF_F_SG;
333 netdev->features |= NETIF_F_IP_CSUM;
334 netdev->features |= NETIF_F_TSO;
335
336 if (pci_using_dac)
337 netdev->features |= NETIF_F_HIGHDMA;
338
339 if (pci_enable_msi(pdev)) {
340 adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
341 printk(KERN_WARNING "%s: unable to allocate MSI interrupt"
342 " error\n", netxen_nic_driver_name);
343 } else
344 adapter->flags |= NETXEN_NIC_MSI_ENABLED;
345
346 netdev->irq = pdev->irq;
347 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
217 348
218 adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; 349 /*
219 adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; 350 * Set the CRB window to invalid. If any register in window 0 is
351 * accessed it should set the window to 0 and then reset it to 1.
352 */
353 adapter->curr_window = 255;
354
355 /* initialize the adapter */
356 netxen_initialize_adapter_hw(adapter);
357
358#ifdef CONFIG_PPC
359 if ((adapter->ahw.boardcfg.board_type ==
360 NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) &&
361 (pci_func_id == 2))
362 goto err_out_free_adapter;
363#endif /* CONFIG_PPC */
364
365 /*
366 * Adapter in our case is quad port so initialize it before
367 * initializing the ports
368 */
369
370 netxen_initialize_adapter_ops(adapter);
371
372 adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
373 if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
374 (adapter->ahw.boardcfg.board_type ==
375 NETXEN_BRDTYPE_P2_SB31_2G))
376 adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
377 else
378 adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
220 adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; 379 adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
221 adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; 380 adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
222 381
223 pci_set_drvdata(pdev, adapter);
224
225 cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); 382 cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
226 if (cmd_buf_arr == NULL) { 383 if (cmd_buf_arr == NULL) {
227 printk(KERN_ERR 384 printk(KERN_ERR
@@ -231,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
231 goto err_out_free_adapter; 388 goto err_out_free_adapter;
232 } 389 }
233 memset(cmd_buf_arr, 0, TX_RINGSIZE); 390 memset(cmd_buf_arr, 0, TX_RINGSIZE);
391 adapter->cmd_buf_arr = cmd_buf_arr;
234 392
235 for (i = 0; i < MAX_RCV_CTX; ++i) { 393 for (i = 0; i < MAX_RCV_CTX; ++i) {
236 recv_ctx = &adapter->recv_ctx[i]; 394 recv_ctx = &adapter->recv_ctx[i];
@@ -278,33 +436,20 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
278 436
279 } 437 }
280 438
281 adapter->cmd_buf_arr = cmd_buf_arr;
282 adapter->ahw.pci_base0 = mem_ptr0;
283 adapter->ahw.pci_base1 = mem_ptr1;
284 adapter->ahw.pci_base2 = mem_ptr2;
285 adapter->ahw.db_base = db_ptr;
286 adapter->ahw.db_len = db_len;
287 spin_lock_init(&adapter->tx_lock);
288 spin_lock_init(&adapter->lock);
289 netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ 439 netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */
290#ifdef CONFIG_IA64
291 netxen_pinit_from_rom(adapter, 0);
292 udelay(500);
293 netxen_load_firmware(adapter);
294#endif
295 440
296 /* 441 /* Mezz cards have PCI function 0,2,3 enabled */
297 * Set the CRB window to invalid. If any register in window 0 is 442 if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
298 * accessed it should set the window to 0 and then reset it to 1. 443 && (pci_func_id >= 2))
299 */ 444 adapter->portnum = pci_func_id - 2;
300 adapter->curr_window = 255;
301 /*
302 * Adapter in our case is quad port so initialize it before
303 * initializing the ports
304 */
305 netxen_initialize_adapter_hw(adapter); /* initialize the adapter */
306 445
307 netxen_initialize_adapter_ops(adapter); 446#ifdef CONFIG_IA64
447 if(adapter->portnum == 0) {
448 netxen_pinit_from_rom(adapter, 0);
449 udelay(500);
450 netxen_load_firmware(adapter);
451 }
452#endif
308 453
309 init_timer(&adapter->watchdog_timer); 454 init_timer(&adapter->watchdog_timer);
310 adapter->ahw.xg_linkup = 0; 455 adapter->ahw.xg_linkup = 0;
@@ -315,12 +460,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
315 adapter->proc_cmd_buf_counter = 0; 460 adapter->proc_cmd_buf_counter = 0;
316 adapter->ahw.revision_id = nx_p2_id; 461 adapter->ahw.revision_id = nx_p2_id;
317 462
318 if (pci_enable_msi(pdev)) { 463 /* make sure Window == 1 */
319 adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; 464 netxen_nic_pci_change_crbwindow(adapter, 1);
320 printk(KERN_WARNING "%s: unable to allocate MSI interrupt" 465
321 " error\n", netxen_nic_driver_name); 466 netxen_nic_update_cmd_producer(adapter, 0);
322 } else 467 netxen_nic_update_cmd_consumer(adapter, 0);
323 adapter->flags |= NETXEN_NIC_MSI_ENABLED; 468 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
324 469
325 if (netxen_is_flash_supported(adapter) == 0 && 470 if (netxen_is_flash_supported(adapter) == 0 &&
326 netxen_get_flash_mac_addr(adapter, mac_addr) == 0) 471 netxen_get_flash_mac_addr(adapter, mac_addr) == 0)
@@ -328,153 +473,118 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
328 else 473 else
329 valid_mac = 0; 474 valid_mac = 0;
330 475
331 /* 476 if (valid_mac) {
332 * Initialize all the CRB registers here. 477 unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum];
333 */ 478 netdev->dev_addr[0] = *(p + 5);
334 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); 479 netdev->dev_addr[1] = *(p + 4);
335 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); 480 netdev->dev_addr[2] = *(p + 3);
336 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); 481 netdev->dev_addr[3] = *(p + 2);
337 482 netdev->dev_addr[4] = *(p + 1);
338 /* do this before waking up pegs so that we have valid dummy dma addr */ 483 netdev->dev_addr[5] = *(p + 0);
339 err = netxen_initialize_adapter_offload(adapter); 484
340 if (err) { 485 memcpy(netdev->perm_addr, netdev->dev_addr,
341 goto err_out_free_dev; 486 netdev->addr_len);
487 if (!is_valid_ether_addr(netdev->perm_addr)) {
488 printk(KERN_ERR "%s: Bad MAC address "
489 "%02x:%02x:%02x:%02x:%02x:%02x.\n",
490 netxen_nic_driver_name,
491 netdev->dev_addr[0],
492 netdev->dev_addr[1],
493 netdev->dev_addr[2],
494 netdev->dev_addr[3],
495 netdev->dev_addr[4],
496 netdev->dev_addr[5]);
497 } else {
498 if (adapter->macaddr_set)
499 adapter->macaddr_set(adapter,
500 netdev->dev_addr);
501 }
342 } 502 }
343 503
344 /* Unlock the HW, prompting the boot sequence */ 504 if (adapter->portnum == 0) {
345 writel(1, 505 err = netxen_initialize_adapter_offload(adapter);
346 NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); 506 if (err)
347 507 goto err_out_free_rx_buffer;
348 /* Handshake with the card before we register the devices. */ 508 val = readl(NETXEN_CRB_NORMALIZE(adapter,
349 netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); 509 NETXEN_CAM_RAM(0x1fc)));
350 510 if (val == 0x55555555) {
351 /* initialize the all the ports */ 511 /* This is the first boot after power up */
352 adapter->active_ports = 0; 512 val = readl(NETXEN_CRB_NORMALIZE(adapter,
353 513 NETXEN_ROMUSB_GLB_SW_RESET));
354 for (i = 0; i < adapter->ahw.max_ports; i++) { 514 printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val);
355 netdev = alloc_etherdev(sizeof(struct netxen_port)); 515 if (val != 0x80000f) {
356 if (!netdev) { 516 /* clear the register for future unloads/loads */
357 printk(KERN_ERR "%s: could not allocate netdev for port" 517 writel(0, NETXEN_CRB_NORMALIZE(adapter,
358 " %d\n", netxen_nic_driver_name, i + 1); 518 NETXEN_CAM_RAM(0x1fc)));
519 printk(KERN_ERR "ERROR in NetXen HW init sequence.\n");
520 err = -ENODEV;
359 goto err_out_free_dev; 521 goto err_out_free_dev;
360 } 522 }
361 523
362 SET_MODULE_OWNER(netdev); 524 /* clear the register for future unloads/loads */
363 SET_NETDEV_DEV(netdev, &pdev->dev); 525 writel(0, NETXEN_CRB_NORMALIZE(adapter,
364 526 NETXEN_CAM_RAM(0x1fc)));
365 port = netdev_priv(netdev);
366 port->netdev = netdev;
367 port->pdev = pdev;
368 port->adapter = adapter;
369 port->portnum = i; /* Gigabit port number from 0-3 */
370
371 netdev->open = netxen_nic_open;
372 netdev->stop = netxen_nic_close;
373 netdev->hard_start_xmit = netxen_nic_xmit_frame;
374 netdev->get_stats = netxen_nic_get_stats;
375 netdev->set_multicast_list = netxen_nic_set_multi;
376 netdev->set_mac_address = netxen_nic_set_mac;
377 netdev->change_mtu = netxen_nic_change_mtu;
378 netdev->tx_timeout = netxen_tx_timeout;
379 netdev->watchdog_timeo = HZ;
380
381 netxen_nic_change_mtu(netdev, netdev->mtu);
382
383 SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
384 netdev->poll = netxen_nic_poll;
385 netdev->weight = NETXEN_NETDEV_WEIGHT;
386#ifdef CONFIG_NET_POLL_CONTROLLER
387 netdev->poll_controller = netxen_nic_poll_controller;
388#endif
389 /* ScatterGather support */
390 netdev->features = NETIF_F_SG;
391 netdev->features |= NETIF_F_IP_CSUM;
392 netdev->features |= NETIF_F_TSO;
393
394 if (pci_using_dac)
395 netdev->features |= NETIF_F_HIGHDMA;
396
397 if (valid_mac) {
398 unsigned char *p = (unsigned char *)&mac_addr[i];
399 netdev->dev_addr[0] = *(p + 5);
400 netdev->dev_addr[1] = *(p + 4);
401 netdev->dev_addr[2] = *(p + 3);
402 netdev->dev_addr[3] = *(p + 2);
403 netdev->dev_addr[4] = *(p + 1);
404 netdev->dev_addr[5] = *(p + 0);
405
406 memcpy(netdev->perm_addr, netdev->dev_addr,
407 netdev->addr_len);
408 if (!is_valid_ether_addr(netdev->perm_addr)) {
409 printk(KERN_ERR "%s: Bad MAC address "
410 "%02x:%02x:%02x:%02x:%02x:%02x.\n",
411 netxen_nic_driver_name,
412 netdev->dev_addr[0],
413 netdev->dev_addr[1],
414 netdev->dev_addr[2],
415 netdev->dev_addr[3],
416 netdev->dev_addr[4],
417 netdev->dev_addr[5]);
418 } else {
419 if (adapter->macaddr_set)
420 adapter->macaddr_set(port,
421 netdev->dev_addr);
422 }
423 } 527 }
424 INIT_WORK(&port->tx_timeout_task, netxen_tx_timeout_task); 528 printk(KERN_INFO "State: 0x%0x\n",
425 netif_carrier_off(netdev); 529 readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
426 netif_stop_queue(netdev);
427 530
428 if ((err = register_netdev(netdev))) { 531 /*
429 printk(KERN_ERR "%s: register_netdev failed port #%d" 532 * Tell the hardware our version number.
430 " aborting\n", netxen_nic_driver_name, i + 1); 533 */
431 err = -EIO; 534 i = (_NETXEN_NIC_LINUX_MAJOR << 16)
432 free_netdev(netdev); 535 | ((_NETXEN_NIC_LINUX_MINOR << 8))
433 goto err_out_free_dev; 536 | (_NETXEN_NIC_LINUX_SUBVERSION);
434 } 537 writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION));
435 adapter->port_count++; 538
436 adapter->port[i] = port; 539 /* Unlock the HW, prompting the boot sequence */
540 writel(1,
541 NETXEN_CRB_NORMALIZE(adapter,
542 NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
543 /* Handshake with the card before we register the devices. */
544 netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
437 } 545 }
438 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); 546
439 netxen_pinit_from_rom(adapter, 0);
440 udelay(500);
441 netxen_load_firmware(adapter);
442 netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
443 /* 547 /*
444 * delay a while to ensure that the Pegs are up & running. 548 * See if the firmware gave us a virtual-physical port mapping.
445 * Otherwise, we might see some flaky behaviour.
446 */ 549 */
447 udelay(100); 550 i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum)));
551 if (i != 0x55555555)
552 physical_port[adapter->portnum] = i;
553
554 netif_carrier_off(netdev);
555 netif_stop_queue(netdev);
556
557 if ((err = register_netdev(netdev))) {
558 printk(KERN_ERR "%s: register_netdev failed port #%d"
559 " aborting\n", netxen_nic_driver_name,
560 adapter->portnum);
561 err = -EIO;
562 goto err_out_free_dev;
563 }
564
565 pci_set_drvdata(pdev, adapter);
448 566
449 switch (adapter->ahw.board_type) { 567 switch (adapter->ahw.board_type) {
450 case NETXEN_NIC_GBE: 568 case NETXEN_NIC_GBE:
451 printk("%s: QUAD GbE board initialized\n", 569 printk(KERN_INFO "%s: QUAD GbE board initialized\n",
452 netxen_nic_driver_name); 570 netxen_nic_driver_name);
453 break; 571 break;
454 572
455 case NETXEN_NIC_XGBE: 573 case NETXEN_NIC_XGBE:
456 printk("%s: XGbE board initialized\n", netxen_nic_driver_name); 574 printk(KERN_INFO "%s: XGbE board initialized\n",
457 break; 575 netxen_nic_driver_name);
576 break;
458 } 577 }
459 578
460 adapter->driver_mismatch = 0; 579 adapter->driver_mismatch = 0;
461 580
462 return 0; 581 return 0;
463 582
464 err_out_free_dev: 583err_out_free_dev:
465 if (adapter->flags & NETXEN_NIC_MSI_ENABLED) 584 if (adapter->portnum == 0)
466 pci_disable_msi(pdev); 585 netxen_free_adapter_offload(adapter);
467 for (i = 0; i < adapter->port_count; i++) {
468 port = adapter->port[i];
469 if ((port) && (port->netdev)) {
470 unregister_netdev(port->netdev);
471 free_netdev(port->netdev);
472 }
473 }
474 586
475 netxen_free_adapter_offload(adapter); 587err_out_free_rx_buffer:
476
477 err_out_free_rx_buffer:
478 for (i = 0; i < MAX_RCV_CTX; ++i) { 588 for (i = 0; i < MAX_RCV_CTX; ++i) {
479 recv_ctx = &adapter->recv_ctx[i]; 589 recv_ctx = &adapter->recv_ctx[i];
480 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { 590 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
@@ -487,15 +597,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
487 } 597 }
488 vfree(cmd_buf_arr); 598 vfree(cmd_buf_arr);
489 599
490 err_out_free_adapter: 600err_out_free_adapter:
601 if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
602 pci_disable_msi(pdev);
603
491 pci_set_drvdata(pdev, NULL); 604 pci_set_drvdata(pdev, NULL);
492 kfree(adapter);
493 605
494 err_out_dbunmap:
495 if (db_ptr) 606 if (db_ptr)
496 iounmap(db_ptr); 607 iounmap(db_ptr);
497 608
498 err_out_iounmap: 609err_out_iounmap:
499 if (mem_ptr0) 610 if (mem_ptr0)
500 iounmap(mem_ptr0); 611 iounmap(mem_ptr0);
501 if (mem_ptr1) 612 if (mem_ptr1)
@@ -503,9 +614,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
503 if (mem_ptr2) 614 if (mem_ptr2)
504 iounmap(mem_ptr2); 615 iounmap(mem_ptr2);
505 616
506 err_out_free_res: 617err_out_free_netdev:
618 free_netdev(netdev);
619
620err_out_free_res:
507 pci_release_regions(pdev); 621 pci_release_regions(pdev);
508 err_out_disable_pdev: 622
623err_out_disable_pdev:
509 pci_disable_device(pdev); 624 pci_disable_device(pdev);
510 return err; 625 return err;
511} 626}
@@ -513,7 +628,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
513static void __devexit netxen_nic_remove(struct pci_dev *pdev) 628static void __devexit netxen_nic_remove(struct pci_dev *pdev)
514{ 629{
515 struct netxen_adapter *adapter; 630 struct netxen_adapter *adapter;
516 struct netxen_port *port; 631 struct net_device *netdev;
517 struct netxen_rx_buffer *buffer; 632 struct netxen_rx_buffer *buffer;
518 struct netxen_recv_context *recv_ctx; 633 struct netxen_recv_context *recv_ctx;
519 struct netxen_rcv_desc_ctx *rcv_desc; 634 struct netxen_rcv_desc_ctx *rcv_desc;
@@ -524,38 +639,34 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
524 if (adapter == NULL) 639 if (adapter == NULL)
525 return; 640 return;
526 641
642 netdev = adapter->netdev;
643
644 netxen_nic_disable_int(adapter);
527 if (adapter->irq) 645 if (adapter->irq)
528 free_irq(adapter->irq, adapter); 646 free_irq(adapter->irq, adapter);
529 netxen_nic_stop_all_ports(adapter); 647
530 /* leave the hw in the same state as reboot */ 648 if (adapter->stop_port)
531 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); 649 adapter->stop_port(adapter);
532 netxen_pinit_from_rom(adapter, 0);
533 udelay(500);
534 netxen_load_firmware(adapter);
535 netxen_free_adapter_offload(adapter);
536
537 mdelay(1000); /* Delay for a while to drain the DMA engines */
538 for (i = 0; i < adapter->port_count; i++) {
539 port = adapter->port[i];
540 if ((port) && (port->netdev)) {
541 unregister_netdev(port->netdev);
542 free_netdev(port->netdev);
543 }
544 }
545 650
546 if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) 651 if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
547 pci_disable_msi(pdev); 652 pci_disable_msi(pdev);
548 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
549 netxen_free_hw_resources(adapter);
550 653
551 iounmap(adapter->ahw.db_base); 654 if (adapter->portnum == 0)
552 iounmap(adapter->ahw.pci_base0); 655 netxen_free_adapter_offload(adapter);
553 iounmap(adapter->ahw.pci_base1);
554 iounmap(adapter->ahw.pci_base2);
555 656
556 pci_release_regions(pdev); 657 if (adapter->irq)
557 pci_disable_device(pdev); 658 free_irq(adapter->irq, adapter);
558 pci_set_drvdata(pdev, NULL); 659 if(adapter->portnum == 0) {
660 /* leave the hw in the same state as reboot */
661 writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
662 netxen_pinit_from_rom(adapter, 0);
663 udelay(500);
664 netxen_load_firmware(adapter);
665 netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
666 }
667
668 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
669 netxen_free_hw_resources(adapter);
559 670
560 for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { 671 for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
561 recv_ctx = &adapter->recv_ctx[ctxid]; 672 recv_ctx = &adapter->recv_ctx[ctxid];
@@ -575,8 +686,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
575 } 686 }
576 } 687 }
577 688
689 unregister_netdev(netdev);
690
578 vfree(adapter->cmd_buf_arr); 691 vfree(adapter->cmd_buf_arr);
579 kfree(adapter); 692
693 iounmap(adapter->ahw.db_base);
694 iounmap(adapter->ahw.pci_base0);
695 iounmap(adapter->ahw.pci_base1);
696 iounmap(adapter->ahw.pci_base2);
697
698 pci_release_regions(pdev);
699 pci_disable_device(pdev);
700 pci_set_drvdata(pdev, NULL);
701
702 free_netdev(netdev);
580} 703}
581 704
582/* 705/*
@@ -585,8 +708,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
585 */ 708 */
586static int netxen_nic_open(struct net_device *netdev) 709static int netxen_nic_open(struct net_device *netdev)
587{ 710{
588 struct netxen_port *port = netdev_priv(netdev); 711 struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv;
589 struct netxen_adapter *adapter = port->adapter;
590 int err = 0; 712 int err = 0;
591 int ctx, ring; 713 int ctx, ring;
592 714
@@ -597,8 +719,6 @@ static int netxen_nic_open(struct net_device *netdev)
597 return -EIO; 719 return -EIO;
598 } 720 }
599 netxen_nic_flash_print(adapter); 721 netxen_nic_flash_print(adapter);
600 if (adapter->init_niu)
601 adapter->init_niu(adapter);
602 722
603 /* setup all the resources for the Phantom... */ 723 /* setup all the resources for the Phantom... */
604 /* this include the descriptors for rcv, tx, and status */ 724 /* this include the descriptors for rcv, tx, and status */
@@ -609,21 +729,14 @@ static int netxen_nic_open(struct net_device *netdev)
609 err); 729 err);
610 return err; 730 return err;
611 } 731 }
612 if (adapter->init_port
613 && adapter->init_port(adapter, port->portnum) != 0) {
614 printk(KERN_ERR "%s: Failed to initialize port %d\n",
615 netxen_nic_driver_name, port->portnum);
616 netxen_free_hw_resources(adapter);
617 return -EIO;
618 }
619 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 732 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
620 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) 733 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
621 netxen_post_rx_buffers(adapter, ctx, ring); 734 netxen_post_rx_buffers(adapter, ctx, ring);
622 } 735 }
623 adapter->irq = adapter->ahw.pdev->irq; 736 adapter->irq = adapter->ahw.pdev->irq;
624 err = request_irq(adapter->ahw.pdev->irq, &netxen_intr, 737 err = request_irq(adapter->ahw.pdev->irq, netxen_intr,
625 IRQF_SHARED | IRQF_SAMPLE_RANDOM, 738 SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
626 netdev->name, adapter); 739 adapter);
627 if (err) { 740 if (err) {
628 printk(KERN_ERR "request_irq failed with: %d\n", err); 741 printk(KERN_ERR "request_irq failed with: %d\n", err);
629 netxen_free_hw_resources(adapter); 742 netxen_free_hw_resources(adapter);
@@ -632,23 +745,28 @@ static int netxen_nic_open(struct net_device *netdev)
632 745
633 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; 746 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
634 } 747 }
635 adapter->active_ports++; 748 if (!adapter->driver_mismatch)
636 if (adapter->active_ports == 1) { 749 mod_timer(&adapter->watchdog_timer, jiffies);
637 if (!adapter->driver_mismatch)
638 mod_timer(&adapter->watchdog_timer, jiffies);
639 750
640 netxen_nic_enable_int(adapter); 751 netxen_nic_enable_int(adapter);
641 }
642 752
643 /* Done here again so that even if phantom sw overwrote it, 753 /* Done here again so that even if phantom sw overwrote it,
644 * we set it */ 754 * we set it */
645 if (adapter->macaddr_set) 755 if (adapter->macaddr_set)
646 adapter->macaddr_set(port, netdev->dev_addr); 756 adapter->macaddr_set(adapter, netdev->dev_addr);
647 netxen_nic_set_link_parameters(port); 757 if (adapter->init_port
758 && adapter->init_port(adapter, adapter->portnum) != 0) {
759 del_timer_sync(&adapter->watchdog_timer);
760 printk(KERN_ERR "%s: Failed to initialize port %d\n",
761 netxen_nic_driver_name, adapter->portnum);
762 return -EIO;
763 }
764
765 netxen_nic_set_link_parameters(adapter);
648 766
649 netxen_nic_set_multi(netdev); 767 netxen_nic_set_multi(netdev);
650 if (adapter->set_mtu) 768 if (adapter->set_mtu)
651 adapter->set_mtu(port, netdev->mtu); 769 adapter->set_mtu(adapter, netdev->mtu);
652 770
653 if (!adapter->driver_mismatch) 771 if (!adapter->driver_mismatch)
654 netif_start_queue(netdev); 772 netif_start_queue(netdev);
@@ -661,8 +779,7 @@ static int netxen_nic_open(struct net_device *netdev)
661 */ 779 */
662static int netxen_nic_close(struct net_device *netdev) 780static int netxen_nic_close(struct net_device *netdev)
663{ 781{
664 struct netxen_port *port = netdev_priv(netdev); 782 struct netxen_adapter *adapter = netdev_priv(netdev);
665 struct netxen_adapter *adapter = port->adapter;
666 int i, j; 783 int i, j;
667 struct netxen_cmd_buffer *cmd_buff; 784 struct netxen_cmd_buffer *cmd_buff;
668 struct netxen_skb_frag *buffrag; 785 struct netxen_skb_frag *buffrag;
@@ -670,47 +787,39 @@ static int netxen_nic_close(struct net_device *netdev)
670 netif_carrier_off(netdev); 787 netif_carrier_off(netdev);
671 netif_stop_queue(netdev); 788 netif_stop_queue(netdev);
672 789
673 adapter->active_ports--; 790 cmd_buff = adapter->cmd_buf_arr;
674 791 for (i = 0; i < adapter->max_tx_desc_count; i++) {
675 if (!adapter->active_ports) { 792 buffrag = cmd_buff->frag_array;
676 netxen_nic_disable_int(adapter); 793 if (buffrag->dma) {
677 cmd_buff = adapter->cmd_buf_arr; 794 pci_unmap_single(adapter->pdev, buffrag->dma,
678 for (i = 0; i < adapter->max_tx_desc_count; i++) { 795 buffrag->length, PCI_DMA_TODEVICE);
679 buffrag = cmd_buff->frag_array; 796 buffrag->dma = (u64) NULL;
797 }
798 for (j = 0; j < cmd_buff->frag_count; j++) {
799 buffrag++;
680 if (buffrag->dma) { 800 if (buffrag->dma) {
681 pci_unmap_single(port->pdev, buffrag->dma, 801 pci_unmap_page(adapter->pdev, buffrag->dma,
682 buffrag->length, 802 buffrag->length,
683 PCI_DMA_TODEVICE); 803 PCI_DMA_TODEVICE);
684 buffrag->dma = (u64) NULL; 804 buffrag->dma = (u64) NULL;
685 } 805 }
686 for (j = 0; j < cmd_buff->frag_count; j++) {
687 buffrag++;
688 if (buffrag->dma) {
689 pci_unmap_page(port->pdev,
690 buffrag->dma,
691 buffrag->length,
692 PCI_DMA_TODEVICE);
693 buffrag->dma = (u64) NULL;
694 }
695 }
696 /* Free the skb we received in netxen_nic_xmit_frame */
697 if (cmd_buff->skb) {
698 dev_kfree_skb_any(cmd_buff->skb);
699 cmd_buff->skb = NULL;
700 }
701 cmd_buff++;
702 } 806 }
703 FLUSH_SCHEDULED_WORK(); 807 /* Free the skb we received in netxen_nic_xmit_frame */
704 del_timer_sync(&adapter->watchdog_timer); 808 if (cmd_buff->skb) {
809 dev_kfree_skb_any(cmd_buff->skb);
810 cmd_buff->skb = NULL;
811 }
812 cmd_buff++;
705 } 813 }
814 FLUSH_SCHEDULED_WORK();
815 del_timer_sync(&adapter->watchdog_timer);
706 816
707 return 0; 817 return 0;
708} 818}
709 819
710static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 820static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
711{ 821{
712 struct netxen_port *port = netdev_priv(netdev); 822 struct netxen_adapter *adapter = netdev_priv(netdev);
713 struct netxen_adapter *adapter = port->adapter;
714 struct netxen_hardware_context *hw = &adapter->ahw; 823 struct netxen_hardware_context *hw = &adapter->ahw;
715 unsigned int first_seg_len = skb->len - skb->data_len; 824 unsigned int first_seg_len = skb->len - skb->data_len;
716 struct netxen_skb_frag *buffrag; 825 struct netxen_skb_frag *buffrag;
@@ -728,12 +837,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
728 u32 last_cmd_consumer = 0; 837 u32 last_cmd_consumer = 0;
729 int no_of_desc; 838 int no_of_desc;
730 839
731 port->stats.xmitcalled++; 840 adapter->stats.xmitcalled++;
732 frag_count = skb_shinfo(skb)->nr_frags + 1; 841 frag_count = skb_shinfo(skb)->nr_frags + 1;
733 842
734 if (unlikely(skb->len <= 0)) { 843 if (unlikely(skb->len <= 0)) {
735 dev_kfree_skb_any(skb); 844 dev_kfree_skb_any(skb);
736 port->stats.badskblen++; 845 adapter->stats.badskblen++;
737 return NETDEV_TX_OK; 846 return NETDEV_TX_OK;
738 } 847 }
739 848
@@ -742,7 +851,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
742 "too large, can handle only %d frags\n", 851 "too large, can handle only %d frags\n",
743 netxen_nic_driver_name, netdev->name, 852 netxen_nic_driver_name, netdev->name,
744 frag_count, MAX_BUFFERS_PER_CMD); 853 frag_count, MAX_BUFFERS_PER_CMD);
745 port->stats.txdropped++; 854 adapter->stats.txdropped++;
746 if ((++dropped_packet & 0xff) == 0xff) 855 if ((++dropped_packet & 0xff) == 0xff)
747 printk("%s: %s droppped packets = %d\n", 856 printk("%s: %s droppped packets = %d\n",
748 netxen_nic_driver_name, netdev->name, 857 netxen_nic_driver_name, netdev->name,
@@ -759,7 +868,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
759 */ 868 */
760 retry_getting_window: 869 retry_getting_window:
761 spin_lock_bh(&adapter->tx_lock); 870 spin_lock_bh(&adapter->tx_lock);
762 if (adapter->total_threads == MAX_XMIT_PRODUCERS) { 871 if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
763 spin_unlock_bh(&adapter->tx_lock); 872 spin_unlock_bh(&adapter->tx_lock);
764 /* 873 /*
765 * Yield CPU 874 * Yield CPU
@@ -792,15 +901,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
792 if ((k + no_of_desc) >= 901 if ((k + no_of_desc) >=
793 ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count : 902 ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
794 last_cmd_consumer)) { 903 last_cmd_consumer)) {
795 port->stats.nocmddescriptor++;
796 DPRINTK(ERR, "No command descriptors available,"
797 " producer = %d, consumer = %d count=%llu,"
798 " dropping packet\n", producer,
799 adapter->last_cmd_consumer,
800 port->stats.nocmddescriptor);
801
802 netif_stop_queue(netdev); 904 netif_stop_queue(netdev);
803 port->flags |= NETXEN_NETDEV_STATUS; 905 adapter->flags |= NETXEN_NETDEV_STATUS;
804 spin_unlock_bh(&adapter->tx_lock); 906 spin_unlock_bh(&adapter->tx_lock);
805 return NETDEV_TX_BUSY; 907 return NETDEV_TX_BUSY;
806 } 908 }
@@ -828,16 +930,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
828 pbuf->skb = skb; 930 pbuf->skb = skb;
829 pbuf->cmd = TX_ETHER_PKT; 931 pbuf->cmd = TX_ETHER_PKT;
830 pbuf->frag_count = frag_count; 932 pbuf->frag_count = frag_count;
831 pbuf->port = port->portnum; 933 pbuf->port = adapter->portnum;
832 buffrag = &pbuf->frag_array[0]; 934 buffrag = &pbuf->frag_array[0];
833 buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len, 935 buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
834 PCI_DMA_TODEVICE); 936 PCI_DMA_TODEVICE);
835 buffrag->length = first_seg_len; 937 buffrag->length = first_seg_len;
836 netxen_set_cmd_desc_totallength(hwdesc, skb->len); 938 netxen_set_cmd_desc_totallength(hwdesc, skb->len);
837 netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); 939 netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
838 netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); 940 netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
839 941
840 netxen_set_cmd_desc_port(hwdesc, port->portnum); 942 netxen_set_cmd_desc_port(hwdesc, adapter->portnum);
943 netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum);
841 hwdesc->buffer1_length = cpu_to_le16(first_seg_len); 944 hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
842 hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); 945 hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
843 946
@@ -860,7 +963,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
860 offset = frag->page_offset; 963 offset = frag->page_offset;
861 964
862 temp_len = len; 965 temp_len = len;
863 temp_dma = pci_map_page(port->pdev, frag->page, offset, 966 temp_dma = pci_map_page(adapter->pdev, frag->page, offset,
864 len, PCI_DMA_TODEVICE); 967 len, PCI_DMA_TODEVICE);
865 968
866 buffrag++; 969 buffrag++;
@@ -927,21 +1030,29 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
927 producer = get_next_index(producer, max_tx_desc_count); 1030 producer = get_next_index(producer, max_tx_desc_count);
928 } 1031 }
929 } 1032 }
1033
1034 i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]);
1035
1036 hw->cmd_desc_head[saved_producer].flags_opcode =
1037 cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode);
1038 hw->cmd_desc_head[saved_producer].num_of_buffers_total_length =
1039 cpu_to_le32(hw->cmd_desc_head[saved_producer].
1040 num_of_buffers_total_length);
1041
930 spin_lock_bh(&adapter->tx_lock); 1042 spin_lock_bh(&adapter->tx_lock);
931 port->stats.txbytes += 1043 adapter->stats.txbytes += i;
932 netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); 1044
933 /* Code to update the adapter considering how many producer threads 1045 /* Code to update the adapter considering how many producer threads
934 are currently working */ 1046 are currently working */
935 if ((--adapter->num_threads) == 0) { 1047 if ((--adapter->num_threads) == 0) {
936 /* This is the last thread */ 1048 /* This is the last thread */
937 u32 crb_producer = adapter->cmd_producer; 1049 u32 crb_producer = adapter->cmd_producer;
938 writel(crb_producer, 1050 netxen_nic_update_cmd_producer(adapter, crb_producer);
939 NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET));
940 wmb(); 1051 wmb();
941 adapter->total_threads = 0; 1052 adapter->total_threads = 0;
942 } 1053 }
943 1054
944 port->stats.xmitfinished++; 1055 adapter->stats.xmitfinished++;
945 spin_unlock_bh(&adapter->tx_lock); 1056 spin_unlock_bh(&adapter->tx_lock);
946 1057
947 netdev->trans_start = jiffies; 1058 netdev->trans_start = jiffies;
@@ -961,27 +1072,26 @@ static void netxen_watchdog(unsigned long v)
961 1072
962static void netxen_tx_timeout(struct net_device *netdev) 1073static void netxen_tx_timeout(struct net_device *netdev)
963{ 1074{
964 struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); 1075 struct netxen_adapter *adapter = (struct netxen_adapter *)
965 1076 netdev_priv(netdev);
966 SCHEDULE_WORK(&port->tx_timeout_task); 1077 SCHEDULE_WORK(&adapter->tx_timeout_task);
967} 1078}
968 1079
969static void netxen_tx_timeout_task(struct work_struct *work) 1080static void netxen_tx_timeout_task(struct work_struct *work)
970{ 1081{
971 struct netxen_port *port = 1082 struct netxen_adapter *adapter =
972 container_of(work, struct netxen_port, tx_timeout_task); 1083 container_of(work, struct netxen_adapter, tx_timeout_task);
973 struct net_device *netdev = port->netdev;
974 unsigned long flags; 1084 unsigned long flags;
975 1085
976 printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", 1086 printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
977 netxen_nic_driver_name, netdev->name); 1087 netxen_nic_driver_name, adapter->netdev->name);
978 1088
979 spin_lock_irqsave(&port->adapter->lock, flags); 1089 spin_lock_irqsave(&adapter->lock, flags);
980 netxen_nic_close(netdev); 1090 netxen_nic_close(adapter->netdev);
981 netxen_nic_open(netdev); 1091 netxen_nic_open(adapter->netdev);
982 spin_unlock_irqrestore(&port->adapter->lock, flags); 1092 spin_unlock_irqrestore(&adapter->lock, flags);
983 netdev->trans_start = jiffies; 1093 adapter->netdev->trans_start = jiffies;
984 netif_wake_queue(netdev); 1094 netif_wake_queue(adapter->netdev);
985} 1095}
986 1096
987static int 1097static int
@@ -990,17 +1100,16 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
990 u32 ret = 0; 1100 u32 ret = 0;
991 1101
992 DPRINTK(INFO, "Entered handle ISR\n"); 1102 DPRINTK(INFO, "Entered handle ISR\n");
993
994 adapter->stats.ints++; 1103 adapter->stats.ints++;
995 1104
996 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { 1105 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
997 int count = 0; 1106 int count = 0;
998 u32 mask; 1107 u32 mask;
999 mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); 1108 u32 our_int = 0;
1000 if ((mask & 0x80) == 0) { 1109 our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
1001 /* not our interrupt */ 1110 /* not our interrupt */
1111 if ((our_int & (0x80 << adapter->portnum)) == 0)
1002 return ret; 1112 return ret;
1003 }
1004 netxen_nic_disable_int(adapter); 1113 netxen_nic_disable_int(adapter);
1005 /* Window = 0 or 1 */ 1114 /* Window = 0 or 1 */
1006 do { 1115 do {
@@ -1012,7 +1121,6 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
1012 printk("Could not disable interrupt completely\n"); 1121 printk("Could not disable interrupt completely\n");
1013 1122
1014 } 1123 }
1015 adapter->stats.hostints++;
1016 1124
1017 if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { 1125 if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
1018 if (netif_rx_schedule_prep(netdev)) { 1126 if (netif_rx_schedule_prep(netdev)) {
@@ -1046,33 +1154,24 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
1046irqreturn_t netxen_intr(int irq, void *data) 1154irqreturn_t netxen_intr(int irq, void *data)
1047{ 1155{
1048 struct netxen_adapter *adapter; 1156 struct netxen_adapter *adapter;
1049 struct netxen_port *port;
1050 struct net_device *netdev; 1157 struct net_device *netdev;
1051 int i;
1052 1158
1053 if (unlikely(!irq)) { 1159 if (unlikely(!irq)) {
1054 return IRQ_NONE; /* Not our interrupt */ 1160 return IRQ_NONE; /* Not our interrupt */
1055 } 1161 }
1056 1162
1057 adapter = (struct netxen_adapter *)data; 1163 adapter = (struct netxen_adapter *)data;
1058 for (i = 0; i < adapter->ahw.max_ports; i++) { 1164 netdev = adapter->netdev;
1059 port = adapter->port[i]; 1165 /* process our status queue (for all 4 ports) */
1060 netdev = port->netdev; 1166 if (netif_running(netdev))
1061 1167 netxen_handle_int(adapter, netdev);
1062 /* process our status queue (for all 4 ports) */
1063 if (netif_running(netdev)) {
1064 netxen_handle_int(adapter, netdev);
1065 break;
1066 }
1067 }
1068 1168
1069 return IRQ_HANDLED; 1169 return IRQ_HANDLED;
1070} 1170}
1071 1171
1072static int netxen_nic_poll(struct net_device *netdev, int *budget) 1172static int netxen_nic_poll(struct net_device *netdev, int *budget)
1073{ 1173{
1074 struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); 1174 struct netxen_adapter *adapter = netdev_priv(netdev);
1075 struct netxen_adapter *adapter = port->adapter;
1076 int work_to_do = min(*budget, netdev->quota); 1175 int work_to_do = min(*budget, netdev->quota);
1077 int done = 1; 1176 int done = 1;
1078 int ctx; 1177 int ctx;
@@ -1080,7 +1179,6 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
1080 int work_done = 0; 1179 int work_done = 0;
1081 1180
1082 DPRINTK(INFO, "polling for %d descriptors\n", *budget); 1181 DPRINTK(INFO, "polling for %d descriptors\n", *budget);
1083 port->stats.polled++;
1084 1182
1085 work_done = 0; 1183 work_done = 0;
1086 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 1184 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -1124,8 +1222,7 @@ static int netxen_nic_poll(struct net_device *netdev, int *budget)
1124#ifdef CONFIG_NET_POLL_CONTROLLER 1222#ifdef CONFIG_NET_POLL_CONTROLLER
1125static void netxen_nic_poll_controller(struct net_device *netdev) 1223static void netxen_nic_poll_controller(struct net_device *netdev)
1126{ 1224{
1127 struct netxen_port *port = netdev_priv(netdev); 1225 struct netxen_adapter *adapter = netdev_priv(netdev);
1128 struct netxen_adapter *adapter = port->adapter;
1129 disable_irq(adapter->irq); 1226 disable_irq(adapter->irq);
1130 netxen_intr(adapter->irq, adapter); 1227 netxen_intr(adapter->irq, adapter);
1131 enable_irq(adapter->irq); 1228 enable_irq(adapter->irq);
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index d5d95074e569..cef90a78351e 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -88,12 +88,13 @@ static inline int phy_unlock(struct netxen_adapter *adapter)
88 * -1 on error 88 * -1 on error
89 * 89 *
90 */ 90 */
91int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, 91int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
92 long reg, __u32 * readval) 92 __u32 * readval)
93{ 93{
94 long timeout = 0; 94 long timeout = 0;
95 long result = 0; 95 long result = 0;
96 long restore = 0; 96 long restore = 0;
97 long phy = physical_port[adapter->portnum];
97 __u32 address; 98 __u32 address;
98 __u32 command; 99 __u32 command;
99 __u32 status; 100 __u32 status;
@@ -183,12 +184,13 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
183 * -1 on error 184 * -1 on error
184 * 185 *
185 */ 186 */
186int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, 187int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
187 long phy, long reg, __u32 val) 188 __u32 val)
188{ 189{
189 long timeout = 0; 190 long timeout = 0;
190 long result = 0; 191 long result = 0;
191 long restore = 0; 192 long restore = 0;
193 long phy = physical_port[adapter->portnum];
192 __u32 address; 194 __u32 address;
193 __u32 command; 195 __u32 command;
194 __u32 status; 196 __u32 status;
@@ -258,15 +260,13 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
258 return result; 260 return result;
259} 261}
260 262
261int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter, 263int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
262 int port)
263{ 264{
264 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f); 265 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
265 return 0; 266 return 0;
266} 267}
267 268
268int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, 269int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
269 int port)
270{ 270{
271 int result = 0; 271 int result = 0;
272 __u32 enable = 0; 272 __u32 enable = 0;
@@ -275,7 +275,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
275 netxen_set_phy_int_speed_changed(enable); 275 netxen_set_phy_int_speed_changed(enable);
276 276
277 if (0 != 277 if (0 !=
278 netxen_niu_gbe_phy_write(adapter, port, 278 netxen_niu_gbe_phy_write(adapter,
279 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 279 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
280 enable)) 280 enable))
281 result = -EIO; 281 result = -EIO;
@@ -283,38 +283,34 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
283 return result; 283 return result;
284} 284}
285 285
286int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter, 286int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
287 int port)
288{ 287{
289 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f); 288 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
290 return 0; 289 return 0;
291} 290}
292 291
293int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter, 292int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
294 int port)
295{ 293{
296 int result = 0; 294 int result = 0;
297 if (0 != 295 if (0 !=
298 netxen_niu_gbe_phy_write(adapter, port, 296 netxen_niu_gbe_phy_write(adapter,
299 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0)) 297 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
300 result = -EIO; 298 result = -EIO;
301 299
302 return result; 300 return result;
303} 301}
304 302
305int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter, 303int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
306 int port)
307{ 304{
308 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1); 305 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
309 return 0; 306 return 0;
310} 307}
311 308
312int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter, 309int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
313 int port)
314{ 310{
315 int result = 0; 311 int result = 0;
316 if (0 != 312 if (0 !=
317 netxen_niu_gbe_phy_write(adapter, port, 313 netxen_niu_gbe_phy_write(adapter,
318 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, 314 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
319 -EIO)) 315 -EIO))
320 result = -EIO; 316 result = -EIO;
@@ -355,9 +351,9 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
355 0x5); 351 0x5);
356 } 352 }
357 353
358 if (netxen_niu_gbe_enable_phy_interrupts(adapter, port)) 354 if (netxen_niu_gbe_enable_phy_interrupts(adapter))
359 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); 355 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
360 if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) 356 if (netxen_niu_gbe_clear_phy_interrupts(adapter))
361 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); 357 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
362} 358}
363 359
@@ -393,9 +389,9 @@ void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
393 0x5); 389 0x5);
394 } 390 }
395 391
396 if (netxen_niu_gbe_enable_phy_interrupts(adapter, port)) 392 if (netxen_niu_gbe_enable_phy_interrupts(adapter))
397 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); 393 printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
398 if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) 394 if (netxen_niu_gbe_clear_phy_interrupts(adapter))
399 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); 395 printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
400} 396}
401 397
@@ -404,11 +400,11 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
404 int result = 0; 400 int result = 0;
405 __u32 status; 401 __u32 status;
406 if (adapter->disable_phy_interrupts) 402 if (adapter->disable_phy_interrupts)
407 adapter->disable_phy_interrupts(adapter, port); 403 adapter->disable_phy_interrupts(adapter);
408 mdelay(2); 404 mdelay(2);
409 405
410 if (0 == 406 if (0 ==
411 netxen_niu_gbe_phy_read(adapter, port, 407 netxen_niu_gbe_phy_read(adapter,
412 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 408 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
413 &status)) { 409 &status)) {
414 if (netxen_get_phy_link(status)) { 410 if (netxen_get_phy_link(status)) {
@@ -439,13 +435,13 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
439 | NETXEN_GB_MAC_ENABLE_TX_RX 435 | NETXEN_GB_MAC_ENABLE_TX_RX
440 | 436 |
441 NETXEN_GB_MAC_PAUSED_FRMS); 437 NETXEN_GB_MAC_PAUSED_FRMS);
442 if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) 438 if (netxen_niu_gbe_clear_phy_interrupts(adapter))
443 printk(KERN_ERR PFX 439 printk(KERN_ERR PFX
444 "ERROR clearing PHY interrupts\n"); 440 "ERROR clearing PHY interrupts\n");
445 if (netxen_niu_gbe_enable_phy_interrupts(adapter, port)) 441 if (netxen_niu_gbe_enable_phy_interrupts(adapter))
446 printk(KERN_ERR PFX 442 printk(KERN_ERR PFX
447 "ERROR enabling PHY interrupts\n"); 443 "ERROR enabling PHY interrupts\n");
448 if (netxen_niu_gbe_clear_phy_interrupts(adapter, port)) 444 if (netxen_niu_gbe_clear_phy_interrupts(adapter))
449 printk(KERN_ERR PFX 445 printk(KERN_ERR PFX
450 "ERROR clearing PHY interrupts\n"); 446 "ERROR clearing PHY interrupts\n");
451 result = -1; 447 result = -1;
@@ -458,26 +454,18 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
458 454
459int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) 455int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
460{ 456{
461 u32 reg = 0, ret = 0; 457 u32 reg;
458 u32 portnum = physical_port[adapter->portnum];
462 459
463 if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) { 460 netxen_crb_writelit_adapter(adapter,
464 netxen_crb_writelit_adapter(adapter, 461 NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
465 NETXEN_NIU_XG1_CONFIG_0, 0x5); 462 netxen_nic_hw_read_wx(adapter,
466 /* XXX hack for Mez cards: both ports in promisc mode */ 463 NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), &reg, 4);
467 netxen_nic_hw_read_wx(adapter, 464 reg = (reg & ~0x2000UL);
468 NETXEN_NIU_XGE_CONFIG_1, &reg, 4); 465 netxen_crb_writelit_adapter(adapter,
469 reg = (reg | 0x2000UL); 466 NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), reg);
470 netxen_crb_writelit_adapter(adapter,
471 NETXEN_NIU_XGE_CONFIG_1, reg);
472 reg = 0;
473 netxen_nic_hw_read_wx(adapter,
474 NETXEN_NIU_XG1_CONFIG_1, &reg, 4);
475 reg = (reg | 0x2000UL);
476 netxen_crb_writelit_adapter(adapter,
477 NETXEN_NIU_XG1_CONFIG_1, reg);
478 }
479 467
480 return ret; 468 return 0;
481} 469}
482 470
483/* 471/*
@@ -498,7 +486,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
498 * The read of the PHY INT status will clear the pending 486 * The read of the PHY INT status will clear the pending
499 * interrupt status 487 * interrupt status
500 */ 488 */
501 if (netxen_niu_gbe_phy_read(adapter, port, 489 if (netxen_niu_gbe_phy_read(adapter,
502 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, 490 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
503 &int_src) != 0) 491 &int_src) != 0)
504 result = -EINVAL; 492 result = -EINVAL;
@@ -535,7 +523,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
535 printk(KERN_INFO PFX 523 printk(KERN_INFO PFX
536 "speed_changed or link status changed"); 524 "speed_changed or link status changed");
537 if (netxen_niu_gbe_phy_read 525 if (netxen_niu_gbe_phy_read
538 (adapter, port, 526 (adapter,
539 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 527 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
540 &status) == 0) { 528 &status) == 0) {
541 if (netxen_get_phy_speed(status) == 2) { 529 if (netxen_get_phy_speed(status) == 2) {
@@ -581,10 +569,11 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
581 * Note that the passed-in value must already be in network byte order. 569 * Note that the passed-in value must already be in network byte order.
582 */ 570 */
583int netxen_niu_macaddr_get(struct netxen_adapter *adapter, 571int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
584 int phy, netxen_ethernet_macaddr_t * addr) 572 netxen_ethernet_macaddr_t * addr)
585{ 573{
586 u32 stationhigh; 574 u32 stationhigh;
587 u32 stationlow; 575 u32 stationlow;
576 int phy = physical_port[adapter->portnum];
588 u8 val[8]; 577 u8 val[8];
589 578
590 if (addr == NULL) 579 if (addr == NULL)
@@ -610,13 +599,12 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
610 * Set the station MAC address. 599 * Set the station MAC address.
611 * Note that the passed-in value must already be in network byte order. 600 * Note that the passed-in value must already be in network byte order.
612 */ 601 */
613int netxen_niu_macaddr_set(struct netxen_port *port, 602int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
614 netxen_ethernet_macaddr_t addr) 603 netxen_ethernet_macaddr_t addr)
615{ 604{
616 u8 temp[4]; 605 u8 temp[4];
617 u32 val; 606 u32 val;
618 struct netxen_adapter *adapter = port->adapter; 607 int phy = physical_port[adapter->portnum];
619 int phy = port->portnum;
620 unsigned char mac_addr[6]; 608 unsigned char mac_addr[6];
621 int i; 609 int i;
622 610
@@ -634,7 +622,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
634 (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) 622 (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
635 return -2; 623 return -2;
636 624
637 netxen_niu_macaddr_get(adapter, phy, 625 netxen_niu_macaddr_get(adapter,
638 (netxen_ethernet_macaddr_t *) mac_addr); 626 (netxen_ethernet_macaddr_t *) mac_addr);
639 if (memcmp(mac_addr, addr, 6) == 0) 627 if (memcmp(mac_addr, addr, 6) == 0)
640 break; 628 break;
@@ -642,7 +630,7 @@ int netxen_niu_macaddr_set(struct netxen_port *port,
642 630
643 if (i == 10) { 631 if (i == 10) {
644 printk(KERN_ERR "%s: cannot set Mac addr for %s\n", 632 printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
645 netxen_nic_driver_name, port->netdev->name); 633 netxen_nic_driver_name, adapter->netdev->name);
646 printk(KERN_ERR "MAC address set: " 634 printk(KERN_ERR "MAC address set: "
647 "%02x:%02x:%02x:%02x:%02x:%02x.\n", 635 "%02x:%02x:%02x:%02x:%02x:%02x.\n",
648 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 636 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
@@ -735,13 +723,13 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
735} 723}
736 724
737/* Disable a GbE interface */ 725/* Disable a GbE interface */
738int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) 726int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
739{ 727{
740 __u32 mac_cfg0; 728 __u32 mac_cfg0;
729 u32 port = physical_port[adapter->portnum];
741 730
742 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 731 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
743 return -EINVAL; 732 return -EINVAL;
744
745 mac_cfg0 = 0; 733 mac_cfg0 = 0;
746 netxen_gb_soft_reset(mac_cfg0); 734 netxen_gb_soft_reset(mac_cfg0);
747 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 735 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
@@ -751,13 +739,13 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port)
751} 739}
752 740
753/* Disable an XG interface */ 741/* Disable an XG interface */
754int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) 742int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
755{ 743{
756 __u32 mac_cfg; 744 __u32 mac_cfg;
745 u32 port = physical_port[adapter->portnum];
757 746
758 if (port != 0) 747 if (port != 0)
759 return -EINVAL; 748 return -EINVAL;
760
761 mac_cfg = 0; 749 mac_cfg = 0;
762 netxen_xg_soft_reset(mac_cfg); 750 netxen_xg_soft_reset(mac_cfg);
763 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0, 751 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0,
@@ -767,10 +755,11 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port)
767} 755}
768 756
769/* Set promiscuous mode for a GbE interface */ 757/* Set promiscuous mode for a GbE interface */
770int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, 758int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
771 netxen_niu_prom_mode_t mode) 759 netxen_niu_prom_mode_t mode)
772{ 760{
773 __u32 reg; 761 __u32 reg;
762 u32 port = physical_port[adapter->portnum];
774 763
775 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 764 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
776 return -EINVAL; 765 return -EINVAL;
@@ -824,25 +813,50 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port,
824 * Set the MAC address for an XG port 813 * Set the MAC address for an XG port
825 * Note that the passed-in value must already be in network byte order. 814 * Note that the passed-in value must already be in network byte order.
826 */ 815 */
827int netxen_niu_xg_macaddr_set(struct netxen_port *port, 816int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
828 netxen_ethernet_macaddr_t addr) 817 netxen_ethernet_macaddr_t addr)
829{ 818{
819 int phy = physical_port[adapter->portnum];
830 u8 temp[4]; 820 u8 temp[4];
831 u32 val; 821 u32 val;
832 struct netxen_adapter *adapter = port->adapter; 822
823 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
824 return -EIO;
833 825
834 temp[0] = temp[1] = 0; 826 temp[0] = temp[1] = 0;
835 memcpy(temp + 2, addr, 2); 827 switch (phy) {
836 val = le32_to_cpu(*(__le32 *)temp); 828 case 0:
837 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, 829 memcpy(temp + 2, addr, 2);
838 &val, 4)) 830 val = le32_to_cpu(*(__le32 *)temp);
831 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
832 &val, 4))
839 return -EIO; 833 return -EIO;
840 834
841 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); 835 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
842 val = le32_to_cpu(*(__le32 *)temp); 836 val = le32_to_cpu(*(__le32 *)temp);
843 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, 837 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
844 &val, 4)) 838 &val, 4))
839 return -EIO;
840 break;
841
842 case 1:
843 memcpy(temp + 2, addr, 2);
844 val = le32_to_cpu(*(__le32 *)temp);
845 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
846 &val, 4))
847 return -EIO;
848
849 memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
850 val = le32_to_cpu(*(__le32 *)temp);
851 if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
852 &val, 4))
845 return -EIO; 853 return -EIO;
854 break;
855
856 default:
857 printk(KERN_ERR "Unknown port %d\n", phy);
858 break;
859 }
846 860
847 return 0; 861 return 0;
848} 862}
@@ -851,9 +865,10 @@ int netxen_niu_xg_macaddr_set(struct netxen_port *port,
851 * Return the current station MAC address. 865 * Return the current station MAC address.
852 * Note that the passed-in value must already be in network byte order. 866 * Note that the passed-in value must already be in network byte order.
853 */ 867 */
854int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, 868int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
855 netxen_ethernet_macaddr_t * addr) 869 netxen_ethernet_macaddr_t * addr)
856{ 870{
871 int phy = physical_port[adapter->portnum];
857 u32 stationhigh; 872 u32 stationhigh;
858 u32 stationlow; 873 u32 stationlow;
859 u8 val[8]; 874 u8 val[8];
@@ -878,21 +893,24 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy,
878} 893}
879 894
880int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 895int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
881 int port, netxen_niu_prom_mode_t mode) 896 netxen_niu_prom_mode_t mode)
882{ 897{
883 __u32 reg; 898 __u32 reg;
899 u32 port = physical_port[adapter->portnum];
884 900
885 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 901 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
886 return -EINVAL; 902 return -EINVAL;
887 903
888 if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1, &reg, 4)) 904 if (netxen_nic_hw_read_wx(adapter,
889 return -EIO; 905 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
906 return -EIO;
890 if (mode == NETXEN_NIU_PROMISC_MODE) 907 if (mode == NETXEN_NIU_PROMISC_MODE)
891 reg = (reg | 0x2000UL); 908 reg = (reg | 0x2000UL);
892 else 909 else
893 reg = (reg & ~0x2000UL); 910 reg = (reg & ~0x2000UL);
894 911
895 netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1, reg); 912 netxen_crb_writelit_adapter(adapter,
913 NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
896 914
897 return 0; 915 return 0;
898} 916}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 0c7c94328b7f..9457fc7249c8 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -100,8 +100,21 @@
100 100
101#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac) 101#define CRB_CMD_PRODUCER_OFFSET_1 NETXEN_NIC_REG(0x1ac)
102#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) 102#define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0)
103#define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8)
104#define CRB_CMD_CONSUMER_OFFSET_2 NETXEN_NIC_REG(0x1bc)
105
106// 1c0 to 1cc used for signature reg
107#define CRB_CMD_PRODUCER_OFFSET_3 NETXEN_NIC_REG(0x1d0)
108#define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4)
103#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4) 109#define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4)
104 110
111#define CRB_V2P_0 NETXEN_NIC_REG(0x290)
112#define CRB_V2P_1 NETXEN_NIC_REG(0x294)
113#define CRB_V2P_2 NETXEN_NIC_REG(0x298)
114#define CRB_V2P_3 NETXEN_NIC_REG(0x29c)
115#define CRB_V2P(port) (CRB_V2P_0+((port)*4))
116#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0)
117
105/* used for ethtool tests */ 118/* used for ethtool tests */
106#define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) 119#define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280)
107 120
@@ -139,128 +152,13 @@ struct netxen_recv_crb {
139}; 152};
140 153
141#if defined(DEFINE_GLOBAL_RECV_CRB) 154#if defined(DEFINE_GLOBAL_RECV_CRB)
142struct netxen_recv_crb recv_crb_registers[] = {
143 /*
144 * Instance 0.
145 */
146 {
147 /* rcv_desc_crb: */
148 {
149 {
150 /* crb_rcv_producer_offset: */
151 NETXEN_NIC_REG(0x100),
152 /* crb_rcv_consumer_offset: */
153 NETXEN_NIC_REG(0x104),
154 /* crb_gloablrcv_ring: */
155 NETXEN_NIC_REG(0x108),
156 /* crb_rcv_ring_size */
157 NETXEN_NIC_REG(0x10c),
158
159 },
160 /* Jumbo frames */
161 {
162 /* crb_rcv_producer_offset: */
163 NETXEN_NIC_REG(0x110),
164 /* crb_rcv_consumer_offset: */
165 NETXEN_NIC_REG(0x114),
166 /* crb_gloablrcv_ring: */
167 NETXEN_NIC_REG(0x118),
168 /* crb_rcv_ring_size */
169 NETXEN_NIC_REG(0x11c),
170 },
171 /* LRO */
172 {
173 /* crb_rcv_producer_offset: */
174 NETXEN_NIC_REG(0x120),
175 /* crb_rcv_consumer_offset: */
176 NETXEN_NIC_REG(0x124),
177 /* crb_gloablrcv_ring: */
178 NETXEN_NIC_REG(0x128),
179 /* crb_rcv_ring_size */
180 NETXEN_NIC_REG(0x12c),
181 }
182 },
183 /* crb_rcvstatus_ring: */
184 NETXEN_NIC_REG(0x130),
185 /* crb_rcv_status_producer: */
186 NETXEN_NIC_REG(0x134),
187 /* crb_rcv_status_consumer: */
188 NETXEN_NIC_REG(0x138),
189 /* crb_rcvpeg_state: */
190 NETXEN_NIC_REG(0x13c),
191 /* crb_status_ring_size */
192 NETXEN_NIC_REG(0x140),
193
194 },
195 /*
196 * Instance 1,
197 */
198 {
199 /* rcv_desc_crb: */
200 {
201 {
202 /* crb_rcv_producer_offset: */
203 NETXEN_NIC_REG(0x144),
204 /* crb_rcv_consumer_offset: */
205 NETXEN_NIC_REG(0x148),
206 /* crb_globalrcv_ring: */
207 NETXEN_NIC_REG(0x14c),
208 /* crb_rcv_ring_size */
209 NETXEN_NIC_REG(0x150),
210
211 },
212 /* Jumbo frames */
213 {
214 /* crb_rcv_producer_offset: */
215 NETXEN_NIC_REG(0x154),
216 /* crb_rcv_consumer_offset: */
217 NETXEN_NIC_REG(0x158),
218 /* crb_globalrcv_ring: */
219 NETXEN_NIC_REG(0x15c),
220 /* crb_rcv_ring_size */
221 NETXEN_NIC_REG(0x160),
222 },
223 /* LRO */
224 {
225 /* crb_rcv_producer_offset: */
226 NETXEN_NIC_REG(0x164),
227 /* crb_rcv_consumer_offset: */
228 NETXEN_NIC_REG(0x168),
229 /* crb_globalrcv_ring: */
230 NETXEN_NIC_REG(0x16c),
231 /* crb_rcv_ring_size */
232 NETXEN_NIC_REG(0x170),
233 }
234
235 },
236 /* crb_rcvstatus_ring: */
237 NETXEN_NIC_REG(0x174),
238 /* crb_rcv_status_producer: */
239 NETXEN_NIC_REG(0x178),
240 /* crb_rcv_status_consumer: */
241 NETXEN_NIC_REG(0x17c),
242 /* crb_rcvpeg_state: */
243 NETXEN_NIC_REG(0x180),
244 /* crb_status_ring_size */
245 NETXEN_NIC_REG(0x184),
246
247 },
248};
249
250u64 ctx_addr_sig_regs[][3] = {
251 {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
252 {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
253 {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
254 {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
255};
256
257#else 155#else
258extern struct netxen_recv_crb recv_crb_registers[]; 156extern struct netxen_recv_crb recv_crb_registers[];
259extern u64 ctx_addr_sig_regs[][3]; 157extern u64 ctx_addr_sig_regs[][3];
260#define CRB_CTX_ADDR_REG_LO (ctx_addr_sig_regs[0][0])
261#define CRB_CTX_ADDR_REG_HI (ctx_addr_sig_regs[0][2])
262#define CRB_CTX_SIGNATURE_REG (ctx_addr_sig_regs[0][1])
263#endif /* DEFINE_GLOBAL_RECEIVE_CRB */ 158#endif /* DEFINE_GLOBAL_RECEIVE_CRB */
159#define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0])
160#define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2])
161#define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1])
264 162
265/* 163/*
266 * Temperature control. 164 * Temperature control.
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 0791360a6a66..9c171a7390e2 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -253,12 +253,12 @@ struct pcnet32_access {
253 * so the structure should be allocated using pci_alloc_consistent(). 253 * so the structure should be allocated using pci_alloc_consistent().
254 */ 254 */
255struct pcnet32_private { 255struct pcnet32_private {
256 struct pcnet32_init_block init_block; 256 struct pcnet32_init_block *init_block;
257 /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */ 257 /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
258 struct pcnet32_rx_head *rx_ring; 258 struct pcnet32_rx_head *rx_ring;
259 struct pcnet32_tx_head *tx_ring; 259 struct pcnet32_tx_head *tx_ring;
260 dma_addr_t dma_addr;/* DMA address of beginning of this 260 dma_addr_t init_dma_addr;/* DMA address of beginning of the init block,
261 object, returned by pci_alloc_consistent */ 261 returned by pci_alloc_consistent */
262 struct pci_dev *pci_dev; 262 struct pci_dev *pci_dev;
263 const char *name; 263 const char *name;
264 /* The saved address of a sent-in-place packet/buffer, for skfree(). */ 264 /* The saved address of a sent-in-place packet/buffer, for skfree(). */
@@ -653,7 +653,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
653 653
654static void pcnet32_purge_rx_ring(struct net_device *dev) 654static void pcnet32_purge_rx_ring(struct net_device *dev)
655{ 655{
656 struct pcnet32_private *lp = dev->priv; 656 struct pcnet32_private *lp = netdev_priv(dev);
657 int i; 657 int i;
658 658
659 /* free all allocated skbuffs */ 659 /* free all allocated skbuffs */
@@ -681,7 +681,7 @@ static void pcnet32_poll_controller(struct net_device *dev)
681 681
682static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 682static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
683{ 683{
684 struct pcnet32_private *lp = dev->priv; 684 struct pcnet32_private *lp = netdev_priv(dev);
685 unsigned long flags; 685 unsigned long flags;
686 int r = -EOPNOTSUPP; 686 int r = -EOPNOTSUPP;
687 687
@@ -696,7 +696,7 @@ static int pcnet32_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
696 696
697static int pcnet32_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 697static int pcnet32_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
698{ 698{
699 struct pcnet32_private *lp = dev->priv; 699 struct pcnet32_private *lp = netdev_priv(dev);
700 unsigned long flags; 700 unsigned long flags;
701 int r = -EOPNOTSUPP; 701 int r = -EOPNOTSUPP;
702 702
@@ -711,7 +711,7 @@ static int pcnet32_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
711static void pcnet32_get_drvinfo(struct net_device *dev, 711static void pcnet32_get_drvinfo(struct net_device *dev,
712 struct ethtool_drvinfo *info) 712 struct ethtool_drvinfo *info)
713{ 713{
714 struct pcnet32_private *lp = dev->priv; 714 struct pcnet32_private *lp = netdev_priv(dev);
715 715
716 strcpy(info->driver, DRV_NAME); 716 strcpy(info->driver, DRV_NAME);
717 strcpy(info->version, DRV_VERSION); 717 strcpy(info->version, DRV_VERSION);
@@ -723,7 +723,7 @@ static void pcnet32_get_drvinfo(struct net_device *dev,
723 723
724static u32 pcnet32_get_link(struct net_device *dev) 724static u32 pcnet32_get_link(struct net_device *dev)
725{ 725{
726 struct pcnet32_private *lp = dev->priv; 726 struct pcnet32_private *lp = netdev_priv(dev);
727 unsigned long flags; 727 unsigned long flags;
728 int r; 728 int r;
729 729
@@ -743,19 +743,19 @@ static u32 pcnet32_get_link(struct net_device *dev)
743 743
744static u32 pcnet32_get_msglevel(struct net_device *dev) 744static u32 pcnet32_get_msglevel(struct net_device *dev)
745{ 745{
746 struct pcnet32_private *lp = dev->priv; 746 struct pcnet32_private *lp = netdev_priv(dev);
747 return lp->msg_enable; 747 return lp->msg_enable;
748} 748}
749 749
750static void pcnet32_set_msglevel(struct net_device *dev, u32 value) 750static void pcnet32_set_msglevel(struct net_device *dev, u32 value)
751{ 751{
752 struct pcnet32_private *lp = dev->priv; 752 struct pcnet32_private *lp = netdev_priv(dev);
753 lp->msg_enable = value; 753 lp->msg_enable = value;
754} 754}
755 755
756static int pcnet32_nway_reset(struct net_device *dev) 756static int pcnet32_nway_reset(struct net_device *dev)
757{ 757{
758 struct pcnet32_private *lp = dev->priv; 758 struct pcnet32_private *lp = netdev_priv(dev);
759 unsigned long flags; 759 unsigned long flags;
760 int r = -EOPNOTSUPP; 760 int r = -EOPNOTSUPP;
761 761
@@ -770,7 +770,7 @@ static int pcnet32_nway_reset(struct net_device *dev)
770static void pcnet32_get_ringparam(struct net_device *dev, 770static void pcnet32_get_ringparam(struct net_device *dev,
771 struct ethtool_ringparam *ering) 771 struct ethtool_ringparam *ering)
772{ 772{
773 struct pcnet32_private *lp = dev->priv; 773 struct pcnet32_private *lp = netdev_priv(dev);
774 774
775 ering->tx_max_pending = TX_MAX_RING_SIZE; 775 ering->tx_max_pending = TX_MAX_RING_SIZE;
776 ering->tx_pending = lp->tx_ring_size; 776 ering->tx_pending = lp->tx_ring_size;
@@ -781,7 +781,7 @@ static void pcnet32_get_ringparam(struct net_device *dev,
781static int pcnet32_set_ringparam(struct net_device *dev, 781static int pcnet32_set_ringparam(struct net_device *dev,
782 struct ethtool_ringparam *ering) 782 struct ethtool_ringparam *ering)
783{ 783{
784 struct pcnet32_private *lp = dev->priv; 784 struct pcnet32_private *lp = netdev_priv(dev);
785 unsigned long flags; 785 unsigned long flags;
786 unsigned int size; 786 unsigned int size;
787 ulong ioaddr = dev->base_addr; 787 ulong ioaddr = dev->base_addr;
@@ -847,7 +847,7 @@ static int pcnet32_self_test_count(struct net_device *dev)
847static void pcnet32_ethtool_test(struct net_device *dev, 847static void pcnet32_ethtool_test(struct net_device *dev,
848 struct ethtool_test *test, u64 * data) 848 struct ethtool_test *test, u64 * data)
849{ 849{
850 struct pcnet32_private *lp = dev->priv; 850 struct pcnet32_private *lp = netdev_priv(dev);
851 int rc; 851 int rc;
852 852
853 if (test->flags == ETH_TEST_FL_OFFLINE) { 853 if (test->flags == ETH_TEST_FL_OFFLINE) {
@@ -868,7 +868,7 @@ static void pcnet32_ethtool_test(struct net_device *dev,
868 868
869static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) 869static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
870{ 870{
871 struct pcnet32_private *lp = dev->priv; 871 struct pcnet32_private *lp = netdev_priv(dev);
872 struct pcnet32_access *a = &lp->a; /* access to registers */ 872 struct pcnet32_access *a = &lp->a; /* access to registers */
873 ulong ioaddr = dev->base_addr; /* card base I/O address */ 873 ulong ioaddr = dev->base_addr; /* card base I/O address */
874 struct sk_buff *skb; /* sk buff */ 874 struct sk_buff *skb; /* sk buff */
@@ -1047,7 +1047,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
1047 1047
1048static void pcnet32_led_blink_callback(struct net_device *dev) 1048static void pcnet32_led_blink_callback(struct net_device *dev)
1049{ 1049{
1050 struct pcnet32_private *lp = dev->priv; 1050 struct pcnet32_private *lp = netdev_priv(dev);
1051 struct pcnet32_access *a = &lp->a; 1051 struct pcnet32_access *a = &lp->a;
1052 ulong ioaddr = dev->base_addr; 1052 ulong ioaddr = dev->base_addr;
1053 unsigned long flags; 1053 unsigned long flags;
@@ -1064,7 +1064,7 @@ static void pcnet32_led_blink_callback(struct net_device *dev)
1064 1064
1065static int pcnet32_phys_id(struct net_device *dev, u32 data) 1065static int pcnet32_phys_id(struct net_device *dev, u32 data)
1066{ 1066{
1067 struct pcnet32_private *lp = dev->priv; 1067 struct pcnet32_private *lp = netdev_priv(dev);
1068 struct pcnet32_access *a = &lp->a; 1068 struct pcnet32_access *a = &lp->a;
1069 ulong ioaddr = dev->base_addr; 1069 ulong ioaddr = dev->base_addr;
1070 unsigned long flags; 1070 unsigned long flags;
@@ -1109,7 +1109,7 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
1109 int can_sleep) 1109 int can_sleep)
1110{ 1110{
1111 int csr5; 1111 int csr5;
1112 struct pcnet32_private *lp = dev->priv; 1112 struct pcnet32_private *lp = netdev_priv(dev);
1113 struct pcnet32_access *a = &lp->a; 1113 struct pcnet32_access *a = &lp->a;
1114 ulong ioaddr = dev->base_addr; 1114 ulong ioaddr = dev->base_addr;
1115 int ticks; 1115 int ticks;
@@ -1257,7 +1257,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
1257 1257
1258static int pcnet32_rx(struct net_device *dev, int quota) 1258static int pcnet32_rx(struct net_device *dev, int quota)
1259{ 1259{
1260 struct pcnet32_private *lp = dev->priv; 1260 struct pcnet32_private *lp = netdev_priv(dev);
1261 int entry = lp->cur_rx & lp->rx_mod_mask; 1261 int entry = lp->cur_rx & lp->rx_mod_mask;
1262 struct pcnet32_rx_head *rxp = &lp->rx_ring[entry]; 1262 struct pcnet32_rx_head *rxp = &lp->rx_ring[entry];
1263 int npackets = 0; 1263 int npackets = 0;
@@ -1282,7 +1282,7 @@ static int pcnet32_rx(struct net_device *dev, int quota)
1282 1282
1283static int pcnet32_tx(struct net_device *dev) 1283static int pcnet32_tx(struct net_device *dev)
1284{ 1284{
1285 struct pcnet32_private *lp = dev->priv; 1285 struct pcnet32_private *lp = netdev_priv(dev);
1286 unsigned int dirty_tx = lp->dirty_tx; 1286 unsigned int dirty_tx = lp->dirty_tx;
1287 int delta; 1287 int delta;
1288 int must_restart = 0; 1288 int must_restart = 0;
@@ -1381,7 +1381,7 @@ static int pcnet32_tx(struct net_device *dev)
1381#ifdef CONFIG_PCNET32_NAPI 1381#ifdef CONFIG_PCNET32_NAPI
1382static int pcnet32_poll(struct net_device *dev, int *budget) 1382static int pcnet32_poll(struct net_device *dev, int *budget)
1383{ 1383{
1384 struct pcnet32_private *lp = dev->priv; 1384 struct pcnet32_private *lp = netdev_priv(dev);
1385 int quota = min(dev->quota, *budget); 1385 int quota = min(dev->quota, *budget);
1386 unsigned long ioaddr = dev->base_addr; 1386 unsigned long ioaddr = dev->base_addr;
1387 unsigned long flags; 1387 unsigned long flags;
@@ -1428,7 +1428,7 @@ static int pcnet32_poll(struct net_device *dev, int *budget)
1428#define PCNET32_MAX_PHYS 32 1428#define PCNET32_MAX_PHYS 32
1429static int pcnet32_get_regs_len(struct net_device *dev) 1429static int pcnet32_get_regs_len(struct net_device *dev)
1430{ 1430{
1431 struct pcnet32_private *lp = dev->priv; 1431 struct pcnet32_private *lp = netdev_priv(dev);
1432 int j = lp->phycount * PCNET32_REGS_PER_PHY; 1432 int j = lp->phycount * PCNET32_REGS_PER_PHY;
1433 1433
1434 return ((PCNET32_NUM_REGS + j) * sizeof(u16)); 1434 return ((PCNET32_NUM_REGS + j) * sizeof(u16));
@@ -1439,7 +1439,7 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1439{ 1439{
1440 int i, csr0; 1440 int i, csr0;
1441 u16 *buff = ptr; 1441 u16 *buff = ptr;
1442 struct pcnet32_private *lp = dev->priv; 1442 struct pcnet32_private *lp = netdev_priv(dev);
1443 struct pcnet32_access *a = &lp->a; 1443 struct pcnet32_access *a = &lp->a;
1444 ulong ioaddr = dev->base_addr; 1444 ulong ioaddr = dev->base_addr;
1445 unsigned long flags; 1445 unsigned long flags;
@@ -1592,7 +1592,6 @@ static int __devinit
1592pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) 1592pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1593{ 1593{
1594 struct pcnet32_private *lp; 1594 struct pcnet32_private *lp;
1595 dma_addr_t lp_dma_addr;
1596 int i, media; 1595 int i, media;
1597 int fdx, mii, fset, dxsuflo; 1596 int fdx, mii, fset, dxsuflo;
1598 int chip_version; 1597 int chip_version;
@@ -1714,7 +1713,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1714 dxsuflo = 1; 1713 dxsuflo = 1;
1715 } 1714 }
1716 1715
1717 dev = alloc_etherdev(0); 1716 dev = alloc_etherdev(sizeof(*lp));
1718 if (!dev) { 1717 if (!dev) {
1719 if (pcnet32_debug & NETIF_MSG_PROBE) 1718 if (pcnet32_debug & NETIF_MSG_PROBE)
1720 printk(KERN_ERR PFX "Memory allocation failed.\n"); 1719 printk(KERN_ERR PFX "Memory allocation failed.\n");
@@ -1805,25 +1804,22 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1805 } 1804 }
1806 1805
1807 dev->base_addr = ioaddr; 1806 dev->base_addr = ioaddr;
1807 lp = netdev_priv(dev);
1808 /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */ 1808 /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
1809 if ((lp = 1809 if ((lp->init_block =
1810 pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) { 1810 pci_alloc_consistent(pdev, sizeof(*lp->init_block), &lp->init_dma_addr)) == NULL) {
1811 if (pcnet32_debug & NETIF_MSG_PROBE) 1811 if (pcnet32_debug & NETIF_MSG_PROBE)
1812 printk(KERN_ERR PFX 1812 printk(KERN_ERR PFX
1813 "Consistent memory allocation failed.\n"); 1813 "Consistent memory allocation failed.\n");
1814 ret = -ENOMEM; 1814 ret = -ENOMEM;
1815 goto err_free_netdev; 1815 goto err_free_netdev;
1816 } 1816 }
1817
1818 memset(lp, 0, sizeof(*lp));
1819 lp->dma_addr = lp_dma_addr;
1820 lp->pci_dev = pdev; 1817 lp->pci_dev = pdev;
1821 1818
1822 spin_lock_init(&lp->lock); 1819 spin_lock_init(&lp->lock);
1823 1820
1824 SET_MODULE_OWNER(dev); 1821 SET_MODULE_OWNER(dev);
1825 SET_NETDEV_DEV(dev, &pdev->dev); 1822 SET_NETDEV_DEV(dev, &pdev->dev);
1826 dev->priv = lp;
1827 lp->name = chipname; 1823 lp->name = chipname;
1828 lp->shared_irq = shared; 1824 lp->shared_irq = shared;
1829 lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */ 1825 lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
@@ -1870,23 +1866,21 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1870 && dev->dev_addr[2] == 0x75) 1866 && dev->dev_addr[2] == 0x75)
1871 lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; 1867 lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
1872 1868
1873 lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ 1869 lp->init_block->mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
1874 lp->init_block.tlen_rlen = 1870 lp->init_block->tlen_rlen =
1875 le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); 1871 le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
1876 for (i = 0; i < 6; i++) 1872 for (i = 0; i < 6; i++)
1877 lp->init_block.phys_addr[i] = dev->dev_addr[i]; 1873 lp->init_block->phys_addr[i] = dev->dev_addr[i];
1878 lp->init_block.filter[0] = 0x00000000; 1874 lp->init_block->filter[0] = 0x00000000;
1879 lp->init_block.filter[1] = 0x00000000; 1875 lp->init_block->filter[1] = 0x00000000;
1880 lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); 1876 lp->init_block->rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr);
1881 lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); 1877 lp->init_block->tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr);
1882 1878
1883 /* switch pcnet32 to 32bit mode */ 1879 /* switch pcnet32 to 32bit mode */
1884 a->write_bcr(ioaddr, 20, 2); 1880 a->write_bcr(ioaddr, 20, 2);
1885 1881
1886 a->write_csr(ioaddr, 1, (lp->dma_addr + offsetof(struct pcnet32_private, 1882 a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
1887 init_block)) & 0xffff); 1883 a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
1888 a->write_csr(ioaddr, 2, (lp->dma_addr + offsetof(struct pcnet32_private,
1889 init_block)) >> 16);
1890 1884
1891 if (pdev) { /* use the IRQ provided by PCI */ 1885 if (pdev) { /* use the IRQ provided by PCI */
1892 dev->irq = pdev->irq; 1886 dev->irq = pdev->irq;
@@ -1992,7 +1986,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1992 err_free_ring: 1986 err_free_ring:
1993 pcnet32_free_ring(dev); 1987 pcnet32_free_ring(dev);
1994 err_free_consistent: 1988 err_free_consistent:
1995 pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); 1989 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
1990 lp->init_block, lp->init_dma_addr);
1996 err_free_netdev: 1991 err_free_netdev:
1997 free_netdev(dev); 1992 free_netdev(dev);
1998 err_release_region: 1993 err_release_region:
@@ -2003,7 +1998,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
2003/* if any allocation fails, caller must also call pcnet32_free_ring */ 1998/* if any allocation fails, caller must also call pcnet32_free_ring */
2004static int pcnet32_alloc_ring(struct net_device *dev, char *name) 1999static int pcnet32_alloc_ring(struct net_device *dev, char *name)
2005{ 2000{
2006 struct pcnet32_private *lp = dev->priv; 2001 struct pcnet32_private *lp = netdev_priv(dev);
2007 2002
2008 lp->tx_ring = pci_alloc_consistent(lp->pci_dev, 2003 lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
2009 sizeof(struct pcnet32_tx_head) * 2004 sizeof(struct pcnet32_tx_head) *
@@ -2070,7 +2065,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, char *name)
2070 2065
2071static void pcnet32_free_ring(struct net_device *dev) 2066static void pcnet32_free_ring(struct net_device *dev)
2072{ 2067{
2073 struct pcnet32_private *lp = dev->priv; 2068 struct pcnet32_private *lp = netdev_priv(dev);
2074 2069
2075 kfree(lp->tx_skbuff); 2070 kfree(lp->tx_skbuff);
2076 lp->tx_skbuff = NULL; 2071 lp->tx_skbuff = NULL;
@@ -2103,7 +2098,7 @@ static void pcnet32_free_ring(struct net_device *dev)
2103 2098
2104static int pcnet32_open(struct net_device *dev) 2099static int pcnet32_open(struct net_device *dev)
2105{ 2100{
2106 struct pcnet32_private *lp = dev->priv; 2101 struct pcnet32_private *lp = netdev_priv(dev);
2107 unsigned long ioaddr = dev->base_addr; 2102 unsigned long ioaddr = dev->base_addr;
2108 u16 val; 2103 u16 val;
2109 int i; 2104 int i;
@@ -2134,8 +2129,7 @@ static int pcnet32_open(struct net_device *dev)
2134 "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n", 2129 "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
2135 dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr), 2130 dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr),
2136 (u32) (lp->rx_ring_dma_addr), 2131 (u32) (lp->rx_ring_dma_addr),
2137 (u32) (lp->dma_addr + 2132 (u32) (lp->init_dma_addr));
2138 offsetof(struct pcnet32_private, init_block)));
2139 2133
2140 /* set/reset autoselect bit */ 2134 /* set/reset autoselect bit */
2141 val = lp->a.read_bcr(ioaddr, 2) & ~2; 2135 val = lp->a.read_bcr(ioaddr, 2) & ~2;
@@ -2274,7 +2268,7 @@ static int pcnet32_open(struct net_device *dev)
2274 } 2268 }
2275#endif 2269#endif
2276 2270
2277 lp->init_block.mode = 2271 lp->init_block->mode =
2278 le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); 2272 le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
2279 pcnet32_load_multicast(dev); 2273 pcnet32_load_multicast(dev);
2280 2274
@@ -2284,12 +2278,8 @@ static int pcnet32_open(struct net_device *dev)
2284 } 2278 }
2285 2279
2286 /* Re-initialize the PCNET32, and start it when done. */ 2280 /* Re-initialize the PCNET32, and start it when done. */
2287 lp->a.write_csr(ioaddr, 1, (lp->dma_addr + 2281 lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
2288 offsetof(struct pcnet32_private, 2282 lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
2289 init_block)) & 0xffff);
2290 lp->a.write_csr(ioaddr, 2,
2291 (lp->dma_addr +
2292 offsetof(struct pcnet32_private, init_block)) >> 16);
2293 2283
2294 lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ 2284 lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
2295 lp->a.write_csr(ioaddr, CSR0, CSR0_INIT); 2285 lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
@@ -2316,8 +2306,7 @@ static int pcnet32_open(struct net_device *dev)
2316 printk(KERN_DEBUG 2306 printk(KERN_DEBUG
2317 "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n", 2307 "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
2318 dev->name, i, 2308 dev->name, i,
2319 (u32) (lp->dma_addr + 2309 (u32) (lp->init_dma_addr),
2320 offsetof(struct pcnet32_private, init_block)),
2321 lp->a.read_csr(ioaddr, CSR0)); 2310 lp->a.read_csr(ioaddr, CSR0));
2322 2311
2323 spin_unlock_irqrestore(&lp->lock, flags); 2312 spin_unlock_irqrestore(&lp->lock, flags);
@@ -2355,7 +2344,7 @@ static int pcnet32_open(struct net_device *dev)
2355 2344
2356static void pcnet32_purge_tx_ring(struct net_device *dev) 2345static void pcnet32_purge_tx_ring(struct net_device *dev)
2357{ 2346{
2358 struct pcnet32_private *lp = dev->priv; 2347 struct pcnet32_private *lp = netdev_priv(dev);
2359 int i; 2348 int i;
2360 2349
2361 for (i = 0; i < lp->tx_ring_size; i++) { 2350 for (i = 0; i < lp->tx_ring_size; i++) {
@@ -2375,7 +2364,7 @@ static void pcnet32_purge_tx_ring(struct net_device *dev)
2375/* Initialize the PCNET32 Rx and Tx rings. */ 2364/* Initialize the PCNET32 Rx and Tx rings. */
2376static int pcnet32_init_ring(struct net_device *dev) 2365static int pcnet32_init_ring(struct net_device *dev)
2377{ 2366{
2378 struct pcnet32_private *lp = dev->priv; 2367 struct pcnet32_private *lp = netdev_priv(dev);
2379 int i; 2368 int i;
2380 2369
2381 lp->tx_full = 0; 2370 lp->tx_full = 0;
@@ -2417,12 +2406,12 @@ static int pcnet32_init_ring(struct net_device *dev)
2417 lp->tx_dma_addr[i] = 0; 2406 lp->tx_dma_addr[i] = 0;
2418 } 2407 }
2419 2408
2420 lp->init_block.tlen_rlen = 2409 lp->init_block->tlen_rlen =
2421 le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits); 2410 le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
2422 for (i = 0; i < 6; i++) 2411 for (i = 0; i < 6; i++)
2423 lp->init_block.phys_addr[i] = dev->dev_addr[i]; 2412 lp->init_block->phys_addr[i] = dev->dev_addr[i];
2424 lp->init_block.rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr); 2413 lp->init_block->rx_ring = (u32) le32_to_cpu(lp->rx_ring_dma_addr);
2425 lp->init_block.tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr); 2414 lp->init_block->tx_ring = (u32) le32_to_cpu(lp->tx_ring_dma_addr);
2426 wmb(); /* Make sure all changes are visible */ 2415 wmb(); /* Make sure all changes are visible */
2427 return 0; 2416 return 0;
2428} 2417}
@@ -2433,7 +2422,7 @@ static int pcnet32_init_ring(struct net_device *dev)
2433 */ 2422 */
2434static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) 2423static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
2435{ 2424{
2436 struct pcnet32_private *lp = dev->priv; 2425 struct pcnet32_private *lp = netdev_priv(dev);
2437 unsigned long ioaddr = dev->base_addr; 2426 unsigned long ioaddr = dev->base_addr;
2438 int i; 2427 int i;
2439 2428
@@ -2463,7 +2452,7 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
2463 2452
2464static void pcnet32_tx_timeout(struct net_device *dev) 2453static void pcnet32_tx_timeout(struct net_device *dev)
2465{ 2454{
2466 struct pcnet32_private *lp = dev->priv; 2455 struct pcnet32_private *lp = netdev_priv(dev);
2467 unsigned long ioaddr = dev->base_addr, flags; 2456 unsigned long ioaddr = dev->base_addr, flags;
2468 2457
2469 spin_lock_irqsave(&lp->lock, flags); 2458 spin_lock_irqsave(&lp->lock, flags);
@@ -2504,7 +2493,7 @@ static void pcnet32_tx_timeout(struct net_device *dev)
2504 2493
2505static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) 2494static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
2506{ 2495{
2507 struct pcnet32_private *lp = dev->priv; 2496 struct pcnet32_private *lp = netdev_priv(dev);
2508 unsigned long ioaddr = dev->base_addr; 2497 unsigned long ioaddr = dev->base_addr;
2509 u16 status; 2498 u16 status;
2510 int entry; 2499 int entry;
@@ -2569,7 +2558,7 @@ pcnet32_interrupt(int irq, void *dev_id)
2569 int boguscnt = max_interrupt_work; 2558 int boguscnt = max_interrupt_work;
2570 2559
2571 ioaddr = dev->base_addr; 2560 ioaddr = dev->base_addr;
2572 lp = dev->priv; 2561 lp = netdev_priv(dev);
2573 2562
2574 spin_lock(&lp->lock); 2563 spin_lock(&lp->lock);
2575 2564
@@ -2651,7 +2640,7 @@ pcnet32_interrupt(int irq, void *dev_id)
2651static int pcnet32_close(struct net_device *dev) 2640static int pcnet32_close(struct net_device *dev)
2652{ 2641{
2653 unsigned long ioaddr = dev->base_addr; 2642 unsigned long ioaddr = dev->base_addr;
2654 struct pcnet32_private *lp = dev->priv; 2643 struct pcnet32_private *lp = netdev_priv(dev);
2655 unsigned long flags; 2644 unsigned long flags;
2656 2645
2657 del_timer_sync(&lp->watchdog_timer); 2646 del_timer_sync(&lp->watchdog_timer);
@@ -2692,7 +2681,7 @@ static int pcnet32_close(struct net_device *dev)
2692 2681
2693static struct net_device_stats *pcnet32_get_stats(struct net_device *dev) 2682static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
2694{ 2683{
2695 struct pcnet32_private *lp = dev->priv; 2684 struct pcnet32_private *lp = netdev_priv(dev);
2696 unsigned long ioaddr = dev->base_addr; 2685 unsigned long ioaddr = dev->base_addr;
2697 unsigned long flags; 2686 unsigned long flags;
2698 2687
@@ -2706,8 +2695,8 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
2706/* taken from the sunlance driver, which it took from the depca driver */ 2695/* taken from the sunlance driver, which it took from the depca driver */
2707static void pcnet32_load_multicast(struct net_device *dev) 2696static void pcnet32_load_multicast(struct net_device *dev)
2708{ 2697{
2709 struct pcnet32_private *lp = dev->priv; 2698 struct pcnet32_private *lp = netdev_priv(dev);
2710 volatile struct pcnet32_init_block *ib = &lp->init_block; 2699 volatile struct pcnet32_init_block *ib = lp->init_block;
2711 volatile u16 *mcast_table = (u16 *) & ib->filter; 2700 volatile u16 *mcast_table = (u16 *) & ib->filter;
2712 struct dev_mc_list *dmi = dev->mc_list; 2701 struct dev_mc_list *dmi = dev->mc_list;
2713 unsigned long ioaddr = dev->base_addr; 2702 unsigned long ioaddr = dev->base_addr;
@@ -2756,7 +2745,7 @@ static void pcnet32_load_multicast(struct net_device *dev)
2756static void pcnet32_set_multicast_list(struct net_device *dev) 2745static void pcnet32_set_multicast_list(struct net_device *dev)
2757{ 2746{
2758 unsigned long ioaddr = dev->base_addr, flags; 2747 unsigned long ioaddr = dev->base_addr, flags;
2759 struct pcnet32_private *lp = dev->priv; 2748 struct pcnet32_private *lp = netdev_priv(dev);
2760 int csr15, suspended; 2749 int csr15, suspended;
2761 2750
2762 spin_lock_irqsave(&lp->lock, flags); 2751 spin_lock_irqsave(&lp->lock, flags);
@@ -2767,12 +2756,12 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
2767 if (netif_msg_hw(lp)) 2756 if (netif_msg_hw(lp))
2768 printk(KERN_INFO "%s: Promiscuous mode enabled.\n", 2757 printk(KERN_INFO "%s: Promiscuous mode enabled.\n",
2769 dev->name); 2758 dev->name);
2770 lp->init_block.mode = 2759 lp->init_block->mode =
2771 le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << 2760 le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
2772 7); 2761 7);
2773 lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000); 2762 lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000);
2774 } else { 2763 } else {
2775 lp->init_block.mode = 2764 lp->init_block->mode =
2776 le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); 2765 le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
2777 lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff); 2766 lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff);
2778 pcnet32_load_multicast(dev); 2767 pcnet32_load_multicast(dev);
@@ -2795,7 +2784,7 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
2795/* This routine assumes that the lp->lock is held */ 2784/* This routine assumes that the lp->lock is held */
2796static int mdio_read(struct net_device *dev, int phy_id, int reg_num) 2785static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
2797{ 2786{
2798 struct pcnet32_private *lp = dev->priv; 2787 struct pcnet32_private *lp = netdev_priv(dev);
2799 unsigned long ioaddr = dev->base_addr; 2788 unsigned long ioaddr = dev->base_addr;
2800 u16 val_out; 2789 u16 val_out;
2801 2790
@@ -2811,7 +2800,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
2811/* This routine assumes that the lp->lock is held */ 2800/* This routine assumes that the lp->lock is held */
2812static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val) 2801static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
2813{ 2802{
2814 struct pcnet32_private *lp = dev->priv; 2803 struct pcnet32_private *lp = netdev_priv(dev);
2815 unsigned long ioaddr = dev->base_addr; 2804 unsigned long ioaddr = dev->base_addr;
2816 2805
2817 if (!lp->mii) 2806 if (!lp->mii)
@@ -2823,7 +2812,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
2823 2812
2824static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 2813static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2825{ 2814{
2826 struct pcnet32_private *lp = dev->priv; 2815 struct pcnet32_private *lp = netdev_priv(dev);
2827 int rc; 2816 int rc;
2828 unsigned long flags; 2817 unsigned long flags;
2829 2818
@@ -2841,7 +2830,7 @@ static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2841 2830
2842static int pcnet32_check_otherphy(struct net_device *dev) 2831static int pcnet32_check_otherphy(struct net_device *dev)
2843{ 2832{
2844 struct pcnet32_private *lp = dev->priv; 2833 struct pcnet32_private *lp = netdev_priv(dev);
2845 struct mii_if_info mii = lp->mii_if; 2834 struct mii_if_info mii = lp->mii_if;
2846 u16 bmcr; 2835 u16 bmcr;
2847 int i; 2836 int i;
@@ -2888,7 +2877,7 @@ static int pcnet32_check_otherphy(struct net_device *dev)
2888 2877
2889static void pcnet32_check_media(struct net_device *dev, int verbose) 2878static void pcnet32_check_media(struct net_device *dev, int verbose)
2890{ 2879{
2891 struct pcnet32_private *lp = dev->priv; 2880 struct pcnet32_private *lp = netdev_priv(dev);
2892 int curr_link; 2881 int curr_link;
2893 int prev_link = netif_carrier_ok(dev) ? 1 : 0; 2882 int prev_link = netif_carrier_ok(dev) ? 1 : 0;
2894 u32 bcr9; 2883 u32 bcr9;
@@ -2944,7 +2933,7 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
2944 2933
2945static void pcnet32_watchdog(struct net_device *dev) 2934static void pcnet32_watchdog(struct net_device *dev)
2946{ 2935{
2947 struct pcnet32_private *lp = dev->priv; 2936 struct pcnet32_private *lp = netdev_priv(dev);
2948 unsigned long flags; 2937 unsigned long flags;
2949 2938
2950 /* Print the link status if it has changed */ 2939 /* Print the link status if it has changed */
@@ -2960,12 +2949,13 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
2960 struct net_device *dev = pci_get_drvdata(pdev); 2949 struct net_device *dev = pci_get_drvdata(pdev);
2961 2950
2962 if (dev) { 2951 if (dev) {
2963 struct pcnet32_private *lp = dev->priv; 2952 struct pcnet32_private *lp = netdev_priv(dev);
2964 2953
2965 unregister_netdev(dev); 2954 unregister_netdev(dev);
2966 pcnet32_free_ring(dev); 2955 pcnet32_free_ring(dev);
2967 release_region(dev->base_addr, PCNET32_TOTAL_SIZE); 2956 release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
2968 pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); 2957 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
2958 lp->init_block, lp->init_dma_addr);
2969 free_netdev(dev); 2959 free_netdev(dev);
2970 pci_disable_device(pdev); 2960 pci_disable_device(pdev);
2971 pci_set_drvdata(pdev, NULL); 2961 pci_set_drvdata(pdev, NULL);
@@ -3040,12 +3030,13 @@ static void __exit pcnet32_cleanup_module(void)
3040 struct net_device *next_dev; 3030 struct net_device *next_dev;
3041 3031
3042 while (pcnet32_dev) { 3032 while (pcnet32_dev) {
3043 struct pcnet32_private *lp = pcnet32_dev->priv; 3033 struct pcnet32_private *lp = netdev_priv(pcnet32_dev);
3044 next_dev = lp->next; 3034 next_dev = lp->next;
3045 unregister_netdev(pcnet32_dev); 3035 unregister_netdev(pcnet32_dev);
3046 pcnet32_free_ring(pcnet32_dev); 3036 pcnet32_free_ring(pcnet32_dev);
3047 release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); 3037 release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
3048 pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); 3038 pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
3039 lp->init_block, lp->init_dma_addr);
3049 free_netdev(pcnet32_dev); 3040 free_netdev(pcnet32_dev);
3050 pcnet32_dev = next_dev; 3041 pcnet32_dev = next_dev;
3051 } 3042 }
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index b31ce278bf35..fc4aee96cdfd 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -35,10 +35,14 @@
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37 37
38/* mdiobus_register 38/**
39 * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
40 * @bus: target mii_bus
39 * 41 *
40 * description: Called by a bus driver to bring up all the PHYs 42 * Description: Called by a bus driver to bring up all the PHYs
41 * on a given bus, and attach them to the bus 43 * on a given bus, and attach them to the bus.
44 *
45 * Returns 0 on success or < 0 on error.
42 */ 46 */
43int mdiobus_register(struct mii_bus *bus) 47int mdiobus_register(struct mii_bus *bus)
44{ 48{
@@ -114,10 +118,13 @@ void mdiobus_unregister(struct mii_bus *bus)
114} 118}
115EXPORT_SYMBOL(mdiobus_unregister); 119EXPORT_SYMBOL(mdiobus_unregister);
116 120
117/* mdio_bus_match 121/**
122 * mdio_bus_match - determine if given PHY driver supports the given PHY device
123 * @dev: target PHY device
124 * @drv: given PHY driver
118 * 125 *
119 * description: Given a PHY device, and a PHY driver, return 1 if 126 * Description: Given a PHY device, and a PHY driver, return 1 if
120 * the driver supports the device. Otherwise, return 0 127 * the driver supports the device. Otherwise, return 0.
121 */ 128 */
122static int mdio_bus_match(struct device *dev, struct device_driver *drv) 129static int mdio_bus_match(struct device *dev, struct device_driver *drv)
123{ 130{
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c94a1fb3a4be..eed433d6056a 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -39,7 +39,9 @@
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42/* Convenience function to print out the current phy status 42/**
43 * phy_print_status - Convenience function to print out the current phy status
44 * @phydev: the phy_device struct
43 */ 45 */
44void phy_print_status(struct phy_device *phydev) 46void phy_print_status(struct phy_device *phydev)
45{ 47{
@@ -55,10 +57,15 @@ void phy_print_status(struct phy_device *phydev)
55EXPORT_SYMBOL(phy_print_status); 57EXPORT_SYMBOL(phy_print_status);
56 58
57 59
58/* Convenience functions for reading/writing a given PHY 60/**
59 * register. They MUST NOT be called from interrupt context, 61 * phy_read - Convenience function for reading a given PHY register
62 * @phydev: the phy_device struct
63 * @regnum: register number to read
64 *
65 * NOTE: MUST NOT be called from interrupt context,
60 * because the bus read/write functions may wait for an interrupt 66 * because the bus read/write functions may wait for an interrupt
61 * to conclude the operation. */ 67 * to conclude the operation.
68 */
62int phy_read(struct phy_device *phydev, u16 regnum) 69int phy_read(struct phy_device *phydev, u16 regnum)
63{ 70{
64 int retval; 71 int retval;
@@ -72,6 +79,16 @@ int phy_read(struct phy_device *phydev, u16 regnum)
72} 79}
73EXPORT_SYMBOL(phy_read); 80EXPORT_SYMBOL(phy_read);
74 81
82/**
83 * phy_write - Convenience function for writing a given PHY register
84 * @phydev: the phy_device struct
85 * @regnum: register number to write
86 * @val: value to write to @regnum
87 *
88 * NOTE: MUST NOT be called from interrupt context,
89 * because the bus read/write functions may wait for an interrupt
90 * to conclude the operation.
91 */
75int phy_write(struct phy_device *phydev, u16 regnum, u16 val) 92int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
76{ 93{
77 int err; 94 int err;
@@ -85,7 +102,15 @@ int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
85} 102}
86EXPORT_SYMBOL(phy_write); 103EXPORT_SYMBOL(phy_write);
87 104
88 105/**
106 * phy_clear_interrupt - Ack the phy device's interrupt
107 * @phydev: the phy_device struct
108 *
109 * If the @phydev driver has an ack_interrupt function, call it to
110 * ack and clear the phy device's interrupt.
111 *
112 * Returns 0 on success on < 0 on error.
113 */
89int phy_clear_interrupt(struct phy_device *phydev) 114int phy_clear_interrupt(struct phy_device *phydev)
90{ 115{
91 int err = 0; 116 int err = 0;
@@ -96,7 +121,13 @@ int phy_clear_interrupt(struct phy_device *phydev)
96 return err; 121 return err;
97} 122}
98 123
99 124/**
125 * phy_config_interrupt - configure the PHY device for the requested interrupts
126 * @phydev: the phy_device struct
127 * @interrupts: interrupt flags to configure for this @phydev
128 *
129 * Returns 0 on success on < 0 on error.
130 */
100int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) 131int phy_config_interrupt(struct phy_device *phydev, u32 interrupts)
101{ 132{
102 int err = 0; 133 int err = 0;
@@ -109,9 +140,11 @@ int phy_config_interrupt(struct phy_device *phydev, u32 interrupts)
109} 140}
110 141
111 142
112/* phy_aneg_done 143/**
144 * phy_aneg_done - return auto-negotiation status
145 * @phydev: target phy_device struct
113 * 146 *
114 * description: Reads the status register and returns 0 either if 147 * Description: Reads the status register and returns 0 either if
115 * auto-negotiation is incomplete, or if there was an error. 148 * auto-negotiation is incomplete, or if there was an error.
116 * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done. 149 * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
117 */ 150 */
@@ -173,9 +206,12 @@ static const struct phy_setting settings[] = {
173 206
174#define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting)) 207#define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting))
175 208
176/* phy_find_setting 209/**
210 * phy_find_setting - find a PHY settings array entry that matches speed & duplex
211 * @speed: speed to match
212 * @duplex: duplex to match
177 * 213 *
178 * description: Searches the settings array for the setting which 214 * Description: Searches the settings array for the setting which
179 * matches the desired speed and duplex, and returns the index 215 * matches the desired speed and duplex, and returns the index
180 * of that setting. Returns the index of the last setting if 216 * of that setting. Returns the index of the last setting if
181 * none of the others match. 217 * none of the others match.
@@ -192,11 +228,12 @@ static inline int phy_find_setting(int speed, int duplex)
192 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; 228 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
193} 229}
194 230
195/* phy_find_valid 231/**
196 * idx: The first index in settings[] to search 232 * phy_find_valid - find a PHY setting that matches the requested features mask
197 * features: A mask of the valid settings 233 * @idx: The first index in settings[] to search
234 * @features: A mask of the valid settings
198 * 235 *
199 * description: Returns the index of the first valid setting less 236 * Description: Returns the index of the first valid setting less
200 * than or equal to the one pointed to by idx, as determined by 237 * than or equal to the one pointed to by idx, as determined by
201 * the mask in features. Returns the index of the last setting 238 * the mask in features. Returns the index of the last setting
202 * if nothing else matches. 239 * if nothing else matches.
@@ -209,11 +246,13 @@ static inline int phy_find_valid(int idx, u32 features)
209 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; 246 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
210} 247}
211 248
212/* phy_sanitize_settings 249/**
250 * phy_sanitize_settings - make sure the PHY is set to supported speed and duplex
251 * @phydev: the target phy_device struct
213 * 252 *
214 * description: Make sure the PHY is set to supported speeds and 253 * Description: Make sure the PHY is set to supported speeds and
215 * duplexes. Drop down by one in this order: 1000/FULL, 254 * duplexes. Drop down by one in this order: 1000/FULL,
216 * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF 255 * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF.
217 */ 256 */
218void phy_sanitize_settings(struct phy_device *phydev) 257void phy_sanitize_settings(struct phy_device *phydev)
219{ 258{
@@ -232,16 +271,17 @@ void phy_sanitize_settings(struct phy_device *phydev)
232} 271}
233EXPORT_SYMBOL(phy_sanitize_settings); 272EXPORT_SYMBOL(phy_sanitize_settings);
234 273
235/* phy_ethtool_sset: 274/**
236 * A generic ethtool sset function. Handles all the details 275 * phy_ethtool_sset - generic ethtool sset function, handles all the details
276 * @phydev: target phy_device struct
277 * @cmd: ethtool_cmd
237 * 278 *
238 * A few notes about parameter checking: 279 * A few notes about parameter checking:
239 * - We don't set port or transceiver, so we don't care what they 280 * - We don't set port or transceiver, so we don't care what they
240 * were set to. 281 * were set to.
241 * - phy_start_aneg() will make sure forced settings are sane, and 282 * - phy_start_aneg() will make sure forced settings are sane, and
242 * choose the next best ones from the ones selected, so we don't 283 * choose the next best ones from the ones selected, so we don't
243 * care if ethtool tries to give us bad values 284 * care if ethtool tries to give us bad values.
244 *
245 */ 285 */
246int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) 286int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
247{ 287{
@@ -304,9 +344,15 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
304} 344}
305EXPORT_SYMBOL(phy_ethtool_gset); 345EXPORT_SYMBOL(phy_ethtool_gset);
306 346
307/* Note that this function is currently incompatible with the 347/**
348 * phy_mii_ioctl - generic PHY MII ioctl interface
349 * @phydev: the phy_device struct
350 * @mii_data: MII ioctl data
351 * @cmd: ioctl cmd to execute
352 *
353 * Note that this function is currently incompatible with the
308 * PHYCONTROL layer. It changes registers without regard to 354 * PHYCONTROL layer. It changes registers without regard to
309 * current state. Use at own risk 355 * current state. Use at own risk.
310 */ 356 */
311int phy_mii_ioctl(struct phy_device *phydev, 357int phy_mii_ioctl(struct phy_device *phydev,
312 struct mii_ioctl_data *mii_data, int cmd) 358 struct mii_ioctl_data *mii_data, int cmd)
@@ -336,6 +382,12 @@ int phy_mii_ioctl(struct phy_device *phydev,
336 phydev->duplex = DUPLEX_FULL; 382 phydev->duplex = DUPLEX_FULL;
337 else 383 else
338 phydev->duplex = DUPLEX_HALF; 384 phydev->duplex = DUPLEX_HALF;
385 if ((!phydev->autoneg) &&
386 (val & BMCR_SPEED1000))
387 phydev->speed = SPEED_1000;
388 else if ((!phydev->autoneg) &&
389 (val & BMCR_SPEED100))
390 phydev->speed = SPEED_100;
339 break; 391 break;
340 case MII_ADVERTISE: 392 case MII_ADVERTISE:
341 phydev->advertising = val; 393 phydev->advertising = val;
@@ -358,13 +410,14 @@ int phy_mii_ioctl(struct phy_device *phydev,
358 return 0; 410 return 0;
359} 411}
360 412
361/* phy_start_aneg 413/**
414 * phy_start_aneg - start auto-negotiation for this PHY device
415 * @phydev: the phy_device struct
362 * 416 *
363 * description: Sanitizes the settings (if we're not 417 * Description: Sanitizes the settings (if we're not autonegotiating
364 * autonegotiating them), and then calls the driver's 418 * them), and then calls the driver's config_aneg function.
365 * config_aneg function. If the PHYCONTROL Layer is operating, 419 * If the PHYCONTROL Layer is operating, we change the state to
366 * we change the state to reflect the beginning of 420 * reflect the beginning of Auto-negotiation or forcing.
367 * Auto-negotiation or forcing.
368 */ 421 */
369int phy_start_aneg(struct phy_device *phydev) 422int phy_start_aneg(struct phy_device *phydev)
370{ 423{
@@ -400,15 +453,19 @@ EXPORT_SYMBOL(phy_start_aneg);
400static void phy_change(struct work_struct *work); 453static void phy_change(struct work_struct *work);
401static void phy_timer(unsigned long data); 454static void phy_timer(unsigned long data);
402 455
403/* phy_start_machine: 456/**
457 * phy_start_machine - start PHY state machine tracking
458 * @phydev: the phy_device struct
459 * @handler: callback function for state change notifications
404 * 460 *
405 * description: The PHY infrastructure can run a state machine 461 * Description: The PHY infrastructure can run a state machine
406 * which tracks whether the PHY is starting up, negotiating, 462 * which tracks whether the PHY is starting up, negotiating,
407 * etc. This function starts the timer which tracks the state 463 * etc. This function starts the timer which tracks the state
408 * of the PHY. If you want to be notified when the state 464 * of the PHY. If you want to be notified when the state changes,
409 * changes, pass in the callback, otherwise, pass NULL. If you 465 * pass in the callback @handler, otherwise, pass NULL. If you
410 * want to maintain your own state machine, do not call this 466 * want to maintain your own state machine, do not call this
411 * function. */ 467 * function.
468 */
412void phy_start_machine(struct phy_device *phydev, 469void phy_start_machine(struct phy_device *phydev,
413 void (*handler)(struct net_device *)) 470 void (*handler)(struct net_device *))
414{ 471{
@@ -420,9 +477,11 @@ void phy_start_machine(struct phy_device *phydev,
420 mod_timer(&phydev->phy_timer, jiffies + HZ); 477 mod_timer(&phydev->phy_timer, jiffies + HZ);
421} 478}
422 479
423/* phy_stop_machine 480/**
481 * phy_stop_machine - stop the PHY state machine tracking
482 * @phydev: target phy_device struct
424 * 483 *
425 * description: Stops the state machine timer, sets the state to UP 484 * Description: Stops the state machine timer, sets the state to UP
426 * (unless it wasn't up yet). This function must be called BEFORE 485 * (unless it wasn't up yet). This function must be called BEFORE
427 * phy_detach. 486 * phy_detach.
428 */ 487 */
@@ -438,12 +497,14 @@ void phy_stop_machine(struct phy_device *phydev)
438 phydev->adjust_state = NULL; 497 phydev->adjust_state = NULL;
439} 498}
440 499
441/* phy_force_reduction 500/**
501 * phy_force_reduction - reduce PHY speed/duplex settings by one step
502 * @phydev: target phy_device struct
442 * 503 *
443 * description: Reduces the speed/duplex settings by 504 * Description: Reduces the speed/duplex settings by one notch,
444 * one notch. The order is so: 505 * in this order--
445 * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, 506 * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF.
446 * 10/FULL, 10/HALF. The function bottoms out at 10/HALF. 507 * The function bottoms out at 10/HALF.
447 */ 508 */
448static void phy_force_reduction(struct phy_device *phydev) 509static void phy_force_reduction(struct phy_device *phydev)
449{ 510{
@@ -464,7 +525,9 @@ static void phy_force_reduction(struct phy_device *phydev)
464} 525}
465 526
466 527
467/* phy_error: 528/**
529 * phy_error - enter HALTED state for this PHY device
530 * @phydev: target phy_device struct
468 * 531 *
469 * Moves the PHY to the HALTED state in response to a read 532 * Moves the PHY to the HALTED state in response to a read
470 * or write error, and tells the controller the link is down. 533 * or write error, and tells the controller the link is down.
@@ -478,9 +541,12 @@ void phy_error(struct phy_device *phydev)
478 spin_unlock(&phydev->lock); 541 spin_unlock(&phydev->lock);
479} 542}
480 543
481/* phy_interrupt 544/**
545 * phy_interrupt - PHY interrupt handler
546 * @irq: interrupt line
547 * @phy_dat: phy_device pointer
482 * 548 *
483 * description: When a PHY interrupt occurs, the handler disables 549 * Description: When a PHY interrupt occurs, the handler disables
484 * interrupts, and schedules a work task to clear the interrupt. 550 * interrupts, and schedules a work task to clear the interrupt.
485 */ 551 */
486static irqreturn_t phy_interrupt(int irq, void *phy_dat) 552static irqreturn_t phy_interrupt(int irq, void *phy_dat)
@@ -501,7 +567,10 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
501 return IRQ_HANDLED; 567 return IRQ_HANDLED;
502} 568}
503 569
504/* Enable the interrupts from the PHY side */ 570/**
571 * phy_enable_interrupts - Enable the interrupts from the PHY side
572 * @phydev: target phy_device struct
573 */
505int phy_enable_interrupts(struct phy_device *phydev) 574int phy_enable_interrupts(struct phy_device *phydev)
506{ 575{
507 int err; 576 int err;
@@ -517,7 +586,10 @@ int phy_enable_interrupts(struct phy_device *phydev)
517} 586}
518EXPORT_SYMBOL(phy_enable_interrupts); 587EXPORT_SYMBOL(phy_enable_interrupts);
519 588
520/* Disable the PHY interrupts from the PHY side */ 589/**
590 * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
591 * @phydev: target phy_device struct
592 */
521int phy_disable_interrupts(struct phy_device *phydev) 593int phy_disable_interrupts(struct phy_device *phydev)
522{ 594{
523 int err; 595 int err;
@@ -543,13 +615,15 @@ phy_err:
543} 615}
544EXPORT_SYMBOL(phy_disable_interrupts); 616EXPORT_SYMBOL(phy_disable_interrupts);
545 617
546/* phy_start_interrupts 618/**
619 * phy_start_interrupts - request and enable interrupts for a PHY device
620 * @phydev: target phy_device struct
547 * 621 *
548 * description: Request the interrupt for the given PHY. If 622 * Description: Request the interrupt for the given PHY.
549 * this fails, then we set irq to PHY_POLL. 623 * If this fails, then we set irq to PHY_POLL.
550 * Otherwise, we enable the interrupts in the PHY. 624 * Otherwise, we enable the interrupts in the PHY.
551 * Returns 0 on success.
552 * This should only be called with a valid IRQ number. 625 * This should only be called with a valid IRQ number.
626 * Returns 0 on success or < 0 on error.
553 */ 627 */
554int phy_start_interrupts(struct phy_device *phydev) 628int phy_start_interrupts(struct phy_device *phydev)
555{ 629{
@@ -574,6 +648,10 @@ int phy_start_interrupts(struct phy_device *phydev)
574} 648}
575EXPORT_SYMBOL(phy_start_interrupts); 649EXPORT_SYMBOL(phy_start_interrupts);
576 650
651/**
652 * phy_stop_interrupts - disable interrupts from a PHY device
653 * @phydev: target phy_device struct
654 */
577int phy_stop_interrupts(struct phy_device *phydev) 655int phy_stop_interrupts(struct phy_device *phydev)
578{ 656{
579 int err; 657 int err;
@@ -596,7 +674,10 @@ int phy_stop_interrupts(struct phy_device *phydev)
596EXPORT_SYMBOL(phy_stop_interrupts); 674EXPORT_SYMBOL(phy_stop_interrupts);
597 675
598 676
599/* Scheduled by the phy_interrupt/timer to handle PHY changes */ 677/**
678 * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes
679 * @work: work_struct that describes the work to be done
680 */
600static void phy_change(struct work_struct *work) 681static void phy_change(struct work_struct *work)
601{ 682{
602 int err; 683 int err;
@@ -630,7 +711,10 @@ phy_err:
630 phy_error(phydev); 711 phy_error(phydev);
631} 712}
632 713
633/* Bring down the PHY link, and stop checking the status. */ 714/**
715 * phy_stop - Bring down the PHY link, and stop checking the status
716 * @phydev: target phy_device struct
717 */
634void phy_stop(struct phy_device *phydev) 718void phy_stop(struct phy_device *phydev)
635{ 719{
636 spin_lock(&phydev->lock); 720 spin_lock(&phydev->lock);
@@ -659,9 +743,11 @@ out_unlock:
659} 743}
660 744
661 745
662/* phy_start 746/**
747 * phy_start - start or restart a PHY device
748 * @phydev: target phy_device struct
663 * 749 *
664 * description: Indicates the attached device's readiness to 750 * Description: Indicates the attached device's readiness to
665 * handle PHY-related work. Used during startup to start the 751 * handle PHY-related work. Used during startup to start the
666 * PHY, and after a call to phy_stop() to resume operation. 752 * PHY, and after a call to phy_stop() to resume operation.
667 * Also used to indicate the MDIO bus has cleared an error 753 * Also used to indicate the MDIO bus has cleared an error
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 8f01952c4850..a8b74cdab1ea 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -74,11 +74,13 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
74} 74}
75EXPORT_SYMBOL(phy_device_create); 75EXPORT_SYMBOL(phy_device_create);
76 76
77/* get_phy_device 77/**
78 * get_phy_device - reads the specified PHY device and returns its @phy_device struct
79 * @bus: the target MII bus
80 * @addr: PHY address on the MII bus
78 * 81 *
79 * description: Reads the ID registers of the PHY at addr on the 82 * Description: Reads the ID registers of the PHY at @addr on the
80 * bus, then allocates and returns the phy_device to 83 * @bus, then allocates and returns the phy_device to represent it.
81 * represent it.
82 */ 84 */
83struct phy_device * get_phy_device(struct mii_bus *bus, int addr) 85struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
84{ 86{
@@ -112,23 +114,33 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
112 return dev; 114 return dev;
113} 115}
114 116
115/* phy_prepare_link: 117/**
118 * phy_prepare_link - prepares the PHY layer to monitor link status
119 * @phydev: target phy_device struct
120 * @handler: callback function for link status change notifications
116 * 121 *
117 * description: Tells the PHY infrastructure to handle the 122 * Description: Tells the PHY infrastructure to handle the
118 * gory details on monitoring link status (whether through 123 * gory details on monitoring link status (whether through
119 * polling or an interrupt), and to call back to the 124 * polling or an interrupt), and to call back to the
120 * connected device driver when the link status changes. 125 * connected device driver when the link status changes.
121 * If you want to monitor your own link state, don't call 126 * If you want to monitor your own link state, don't call
122 * this function */ 127 * this function.
128 */
123void phy_prepare_link(struct phy_device *phydev, 129void phy_prepare_link(struct phy_device *phydev,
124 void (*handler)(struct net_device *)) 130 void (*handler)(struct net_device *))
125{ 131{
126 phydev->adjust_link = handler; 132 phydev->adjust_link = handler;
127} 133}
128 134
129/* phy_connect: 135/**
136 * phy_connect - connect an ethernet device to a PHY device
137 * @dev: the network device to connect
138 * @phy_id: the PHY device to connect
139 * @handler: callback function for state change notifications
140 * @flags: PHY device's dev_flags
141 * @interface: PHY device's interface
130 * 142 *
131 * description: Convenience function for connecting ethernet 143 * Description: Convenience function for connecting ethernet
132 * devices to PHY devices. The default behavior is for 144 * devices to PHY devices. The default behavior is for
133 * the PHY infrastructure to handle everything, and only notify 145 * the PHY infrastructure to handle everything, and only notify
134 * the connected driver when the link status changes. If you 146 * the connected driver when the link status changes. If you
@@ -158,6 +170,10 @@ struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
158} 170}
159EXPORT_SYMBOL(phy_connect); 171EXPORT_SYMBOL(phy_connect);
160 172
173/**
174 * phy_disconnect - disable interrupts, stop state machine, and detach a PHY device
175 * @phydev: target phy_device struct
176 */
161void phy_disconnect(struct phy_device *phydev) 177void phy_disconnect(struct phy_device *phydev)
162{ 178{
163 if (phydev->irq > 0) 179 if (phydev->irq > 0)
@@ -171,21 +187,25 @@ void phy_disconnect(struct phy_device *phydev)
171} 187}
172EXPORT_SYMBOL(phy_disconnect); 188EXPORT_SYMBOL(phy_disconnect);
173 189
174/* phy_attach: 190static int phy_compare_id(struct device *dev, void *data)
191{
192 return strcmp((char *)data, dev->bus_id) ? 0 : 1;
193}
194
195/**
196 * phy_attach - attach a network device to a particular PHY device
197 * @dev: network device to attach
198 * @phy_id: PHY device to attach
199 * @flags: PHY device's dev_flags
200 * @interface: PHY device's interface
175 * 201 *
176 * description: Called by drivers to attach to a particular PHY 202 * Description: Called by drivers to attach to a particular PHY
177 * device. The phy_device is found, and properly hooked up 203 * device. The phy_device is found, and properly hooked up
178 * to the phy_driver. If no driver is attached, then the 204 * to the phy_driver. If no driver is attached, then the
179 * genphy_driver is used. The phy_device is given a ptr to 205 * genphy_driver is used. The phy_device is given a ptr to
180 * the attaching device, and given a callback for link status 206 * the attaching device, and given a callback for link status
181 * change. The phy_device is returned to the attaching 207 * change. The phy_device is returned to the attaching driver.
182 * driver.
183 */ 208 */
184static int phy_compare_id(struct device *dev, void *data)
185{
186 return strcmp((char *)data, dev->bus_id) ? 0 : 1;
187}
188
189struct phy_device *phy_attach(struct net_device *dev, 209struct phy_device *phy_attach(struct net_device *dev,
190 const char *phy_id, u32 flags, phy_interface_t interface) 210 const char *phy_id, u32 flags, phy_interface_t interface)
191{ 211{
@@ -246,6 +266,10 @@ struct phy_device *phy_attach(struct net_device *dev,
246} 266}
247EXPORT_SYMBOL(phy_attach); 267EXPORT_SYMBOL(phy_attach);
248 268
269/**
270 * phy_detach - detach a PHY device from its network device
271 * @phydev: target phy_device struct
272 */
249void phy_detach(struct phy_device *phydev) 273void phy_detach(struct phy_device *phydev)
250{ 274{
251 phydev->attached_dev = NULL; 275 phydev->attached_dev = NULL;
@@ -262,11 +286,13 @@ EXPORT_SYMBOL(phy_detach);
262 286
263/* Generic PHY support and helper functions */ 287/* Generic PHY support and helper functions */
264 288
265/* genphy_config_advert 289/**
290 * genphy_config_advert - sanitize and advertise auto-negotation parameters
291 * @phydev: target phy_device struct
266 * 292 *
267 * description: Writes MII_ADVERTISE with the appropriate values, 293 * Description: Writes MII_ADVERTISE with the appropriate values,
268 * after sanitizing the values to make sure we only advertise 294 * after sanitizing the values to make sure we only advertise
269 * what is supported 295 * what is supported.
270 */ 296 */
271int genphy_config_advert(struct phy_device *phydev) 297int genphy_config_advert(struct phy_device *phydev)
272{ 298{
@@ -328,11 +354,14 @@ int genphy_config_advert(struct phy_device *phydev)
328} 354}
329EXPORT_SYMBOL(genphy_config_advert); 355EXPORT_SYMBOL(genphy_config_advert);
330 356
331/* genphy_setup_forced 357/**
358 * genphy_setup_forced - configures/forces speed/duplex from @phydev
359 * @phydev: target phy_device struct
332 * 360 *
333 * description: Configures MII_BMCR to force speed/duplex 361 * Description: Configures MII_BMCR to force speed/duplex
334 * to the values in phydev. Assumes that the values are valid. 362 * to the values in phydev. Assumes that the values are valid.
335 * Please see phy_sanitize_settings() */ 363 * Please see phy_sanitize_settings().
364 */
336int genphy_setup_forced(struct phy_device *phydev) 365int genphy_setup_forced(struct phy_device *phydev)
337{ 366{
338 int ctl = BMCR_RESET; 367 int ctl = BMCR_RESET;
@@ -361,7 +390,10 @@ int genphy_setup_forced(struct phy_device *phydev)
361} 390}
362 391
363 392
364/* Enable and Restart Autonegotiation */ 393/**
394 * genphy_restart_aneg - Enable and Restart Autonegotiation
395 * @phydev: target phy_device struct
396 */
365int genphy_restart_aneg(struct phy_device *phydev) 397int genphy_restart_aneg(struct phy_device *phydev)
366{ 398{
367 int ctl; 399 int ctl;
@@ -382,11 +414,13 @@ int genphy_restart_aneg(struct phy_device *phydev)
382} 414}
383 415
384 416
385/* genphy_config_aneg 417/**
418 * genphy_config_aneg - restart auto-negotiation or write BMCR
419 * @phydev: target phy_device struct
386 * 420 *
387 * description: If auto-negotiation is enabled, we configure the 421 * Description: If auto-negotiation is enabled, we configure the
388 * advertising, and then restart auto-negotiation. If it is not 422 * advertising, and then restart auto-negotiation. If it is not
389 * enabled, then we write the BMCR 423 * enabled, then we write the BMCR.
390 */ 424 */
391int genphy_config_aneg(struct phy_device *phydev) 425int genphy_config_aneg(struct phy_device *phydev)
392{ 426{
@@ -406,11 +440,13 @@ int genphy_config_aneg(struct phy_device *phydev)
406} 440}
407EXPORT_SYMBOL(genphy_config_aneg); 441EXPORT_SYMBOL(genphy_config_aneg);
408 442
409/* genphy_update_link 443/**
444 * genphy_update_link - update link status in @phydev
445 * @phydev: target phy_device struct
410 * 446 *
411 * description: Update the value in phydev->link to reflect the 447 * Description: Update the value in phydev->link to reflect the
412 * current link value. In order to do this, we need to read 448 * current link value. In order to do this, we need to read
413 * the status register twice, keeping the second value 449 * the status register twice, keeping the second value.
414 */ 450 */
415int genphy_update_link(struct phy_device *phydev) 451int genphy_update_link(struct phy_device *phydev)
416{ 452{
@@ -437,9 +473,11 @@ int genphy_update_link(struct phy_device *phydev)
437} 473}
438EXPORT_SYMBOL(genphy_update_link); 474EXPORT_SYMBOL(genphy_update_link);
439 475
440/* genphy_read_status 476/**
477 * genphy_read_status - check the link status and update current link state
478 * @phydev: target phy_device struct
441 * 479 *
442 * description: Check the link, then figure out the current state 480 * Description: Check the link, then figure out the current state
443 * by comparing what we advertise with what the link partner 481 * by comparing what we advertise with what the link partner
444 * advertises. Start by checking the gigabit possibilities, 482 * advertises. Start by checking the gigabit possibilities,
445 * then move on to 10/100. 483 * then move on to 10/100.
@@ -579,9 +617,11 @@ static int genphy_config_init(struct phy_device *phydev)
579} 617}
580 618
581 619
582/* phy_probe 620/**
621 * phy_probe - probe and init a PHY device
622 * @dev: device to probe and init
583 * 623 *
584 * description: Take care of setting up the phy_device structure, 624 * Description: Take care of setting up the phy_device structure,
585 * set the state to READY (the driver's init function should 625 * set the state to READY (the driver's init function should
586 * set it to STARTING if needed). 626 * set it to STARTING if needed).
587 */ 627 */
@@ -643,6 +683,10 @@ static int phy_remove(struct device *dev)
643 return 0; 683 return 0;
644} 684}
645 685
686/**
687 * phy_driver_register - register a phy_driver with the PHY layer
688 * @new_driver: new phy_driver to register
689 */
646int phy_driver_register(struct phy_driver *new_driver) 690int phy_driver_register(struct phy_driver *new_driver)
647{ 691{
648 int retval; 692 int retval;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 7b80fb7a9d9b..d8766c0e8255 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -39,7 +39,7 @@
39 39
40#define DRV_NAME "qla3xxx" 40#define DRV_NAME "qla3xxx"
41#define DRV_STRING "QLogic ISP3XXX Network Driver" 41#define DRV_STRING "QLogic ISP3XXX Network Driver"
42#define DRV_VERSION "v2.03.00-k3" 42#define DRV_VERSION "v2.03.00-k4"
43#define PFX DRV_NAME " " 43#define PFX DRV_NAME " "
44 44
45static const char ql3xxx_driver_name[] = DRV_NAME; 45static const char ql3xxx_driver_name[] = DRV_NAME;
@@ -72,6 +72,30 @@ static struct pci_device_id ql3xxx_pci_tbl[] __devinitdata = {
72MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl); 72MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl);
73 73
74/* 74/*
75 * These are the known PHY's which are used
76 */
77typedef enum {
78 PHY_TYPE_UNKNOWN = 0,
79 PHY_VITESSE_VSC8211,
80 PHY_AGERE_ET1011C,
81 MAX_PHY_DEV_TYPES
82} PHY_DEVICE_et;
83
84typedef struct {
85 PHY_DEVICE_et phyDevice;
86 u32 phyIdOUI;
87 u16 phyIdModel;
88 char *name;
89} PHY_DEVICE_INFO_t;
90
91static const PHY_DEVICE_INFO_t PHY_DEVICES[] =
92 {{PHY_TYPE_UNKNOWN, 0x000000, 0x0, "PHY_TYPE_UNKNOWN"},
93 {PHY_VITESSE_VSC8211, 0x0003f1, 0xb, "PHY_VITESSE_VSC8211"},
94 {PHY_AGERE_ET1011C, 0x00a0bc, 0x1, "PHY_AGERE_ET1011C"},
95};
96
97
98/*
75 * Caller must take hw_lock. 99 * Caller must take hw_lock.
76 */ 100 */
77static int ql_sem_spinlock(struct ql3_adapter *qdev, 101static int ql_sem_spinlock(struct ql3_adapter *qdev,
@@ -662,7 +686,7 @@ static u8 ql_mii_disable_scan_mode(struct ql3_adapter *qdev)
662} 686}
663 687
664static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, 688static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
665 u16 regAddr, u16 value, u32 mac_index) 689 u16 regAddr, u16 value, u32 phyAddr)
666{ 690{
667 struct ql3xxx_port_registers __iomem *port_regs = 691 struct ql3xxx_port_registers __iomem *port_regs =
668 qdev->mem_map_registers; 692 qdev->mem_map_registers;
@@ -680,7 +704,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
680 } 704 }
681 705
682 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, 706 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg,
683 PHYAddr[mac_index] | regAddr); 707 phyAddr | regAddr);
684 708
685 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value); 709 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value);
686 710
@@ -701,7 +725,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
701} 725}
702 726
703static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, 727static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr,
704 u16 * value, u32 mac_index) 728 u16 * value, u32 phyAddr)
705{ 729{
706 struct ql3xxx_port_registers __iomem *port_regs = 730 struct ql3xxx_port_registers __iomem *port_regs =
707 qdev->mem_map_registers; 731 qdev->mem_map_registers;
@@ -720,7 +744,7 @@ static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr,
720 } 744 }
721 745
722 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, 746 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg,
723 PHYAddr[mac_index] | regAddr); 747 phyAddr | regAddr);
724 748
725 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, 749 ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg,
726 (MAC_MII_CONTROL_RC << 16)); 750 (MAC_MII_CONTROL_RC << 16));
@@ -850,28 +874,31 @@ static void ql_petbi_start_neg(struct ql3_adapter *qdev)
850 874
851} 875}
852 876
853static void ql_petbi_reset_ex(struct ql3_adapter *qdev, u32 mac_index) 877static void ql_petbi_reset_ex(struct ql3_adapter *qdev)
854{ 878{
855 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET, 879 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET,
856 mac_index); 880 PHYAddr[qdev->mac_index]);
857} 881}
858 882
859static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) 883static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev)
860{ 884{
861 u16 reg; 885 u16 reg;
862 886
863 /* Enable Auto-negotiation sense */ 887 /* Enable Auto-negotiation sense */
864 ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg, mac_index); 888 ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg,
889 PHYAddr[qdev->mac_index]);
865 reg |= PETBI_TBI_AUTO_SENSE; 890 reg |= PETBI_TBI_AUTO_SENSE;
866 ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, mac_index); 891 ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg,
892 PHYAddr[qdev->mac_index]);
867 893
868 ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER, 894 ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER,
869 PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, mac_index); 895 PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX,
896 PHYAddr[qdev->mac_index]);
870 897
871 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, 898 ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG,
872 PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG | 899 PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG |
873 PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000, 900 PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000,
874 mac_index); 901 PHYAddr[qdev->mac_index]);
875} 902}
876 903
877static void ql_petbi_init(struct ql3_adapter *qdev) 904static void ql_petbi_init(struct ql3_adapter *qdev)
@@ -880,10 +907,10 @@ static void ql_petbi_init(struct ql3_adapter *qdev)
880 ql_petbi_start_neg(qdev); 907 ql_petbi_start_neg(qdev);
881} 908}
882 909
883static void ql_petbi_init_ex(struct ql3_adapter *qdev, u32 mac_index) 910static void ql_petbi_init_ex(struct ql3_adapter *qdev)
884{ 911{
885 ql_petbi_reset_ex(qdev, mac_index); 912 ql_petbi_reset_ex(qdev);
886 ql_petbi_start_neg_ex(qdev, mac_index); 913 ql_petbi_start_neg_ex(qdev);
887} 914}
888 915
889static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev) 916static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev)
@@ -896,33 +923,128 @@ static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev)
896 return (reg & PETBI_NEG_PAUSE_MASK) == PETBI_NEG_PAUSE; 923 return (reg & PETBI_NEG_PAUSE_MASK) == PETBI_NEG_PAUSE;
897} 924}
898 925
926static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr)
927{
928 printk(KERN_INFO "%s: enabling Agere specific PHY\n", qdev->ndev->name);
929 /* power down device bit 11 = 1 */
930 ql_mii_write_reg_ex(qdev, 0x00, 0x1940, miiAddr);
931 /* enable diagnostic mode bit 2 = 1 */
932 ql_mii_write_reg_ex(qdev, 0x12, 0x840e, miiAddr);
933 /* 1000MB amplitude adjust (see Agere errata) */
934 ql_mii_write_reg_ex(qdev, 0x10, 0x8805, miiAddr);
935 /* 1000MB amplitude adjust (see Agere errata) */
936 ql_mii_write_reg_ex(qdev, 0x11, 0xf03e, miiAddr);
937 /* 100MB amplitude adjust (see Agere errata) */
938 ql_mii_write_reg_ex(qdev, 0x10, 0x8806, miiAddr);
939 /* 100MB amplitude adjust (see Agere errata) */
940 ql_mii_write_reg_ex(qdev, 0x11, 0x003e, miiAddr);
941 /* 10MB amplitude adjust (see Agere errata) */
942 ql_mii_write_reg_ex(qdev, 0x10, 0x8807, miiAddr);
943 /* 10MB amplitude adjust (see Agere errata) */
944 ql_mii_write_reg_ex(qdev, 0x11, 0x1f00, miiAddr);
945 /* point to hidden reg 0x2806 */
946 ql_mii_write_reg_ex(qdev, 0x10, 0x2806, miiAddr);
947 /* Write new PHYAD w/bit 5 set */
948 ql_mii_write_reg_ex(qdev, 0x11, 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr);
949 /*
950 * Disable diagnostic mode bit 2 = 0
951 * Power up device bit 11 = 0
952 * Link up (on) and activity (blink)
953 */
954 ql_mii_write_reg(qdev, 0x12, 0x840a);
955 ql_mii_write_reg(qdev, 0x00, 0x1140);
956 ql_mii_write_reg(qdev, 0x1c, 0xfaf0);
957}
958
959static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev,
960 u16 phyIdReg0, u16 phyIdReg1)
961{
962 PHY_DEVICE_et result = PHY_TYPE_UNKNOWN;
963 u32 oui;
964 u16 model;
965 int i;
966
967 if (phyIdReg0 == 0xffff) {
968 return result;
969 }
970
971 if (phyIdReg1 == 0xffff) {
972 return result;
973 }
974
975 /* oui is split between two registers */
976 oui = (phyIdReg0 << 6) | ((phyIdReg1 & PHY_OUI_1_MASK) >> 10);
977
978 model = (phyIdReg1 & PHY_MODEL_MASK) >> 4;
979
980 /* Scan table for this PHY */
981 for(i = 0; i < MAX_PHY_DEV_TYPES; i++) {
982 if ((oui == PHY_DEVICES[i].phyIdOUI) && (model == PHY_DEVICES[i].phyIdModel))
983 {
984 result = PHY_DEVICES[i].phyDevice;
985
986 printk(KERN_INFO "%s: Phy: %s\n",
987 qdev->ndev->name, PHY_DEVICES[i].name);
988
989 break;
990 }
991 }
992
993 return result;
994}
995
899static int ql_phy_get_speed(struct ql3_adapter *qdev) 996static int ql_phy_get_speed(struct ql3_adapter *qdev)
900{ 997{
901 u16 reg; 998 u16 reg;
902 999
1000 switch(qdev->phyType) {
1001 case PHY_AGERE_ET1011C:
1002 {
1003 if (ql_mii_read_reg(qdev, 0x1A, &reg) < 0)
1004 return 0;
1005
1006 reg = (reg >> 8) & 3;
1007 break;
1008 }
1009 default:
903 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0) 1010 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0)
904 return 0; 1011 return 0;
905 1012
906 reg = (((reg & 0x18) >> 3) & 3); 1013 reg = (((reg & 0x18) >> 3) & 3);
1014 }
907 1015
908 if (reg == 2) 1016 switch(reg) {
1017 case 2:
909 return SPEED_1000; 1018 return SPEED_1000;
910 else if (reg == 1) 1019 case 1:
911 return SPEED_100; 1020 return SPEED_100;
912 else if (reg == 0) 1021 case 0:
913 return SPEED_10; 1022 return SPEED_10;
914 else 1023 default:
915 return -1; 1024 return -1;
1025 }
916} 1026}
917 1027
918static int ql_is_full_dup(struct ql3_adapter *qdev) 1028static int ql_is_full_dup(struct ql3_adapter *qdev)
919{ 1029{
920 u16 reg; 1030 u16 reg;
921 1031
922 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0) 1032 switch(qdev->phyType) {
923 return 0; 1033 case PHY_AGERE_ET1011C:
924 1034 {
925 return (reg & PHY_AUX_DUPLEX_STAT) != 0; 1035 if (ql_mii_read_reg(qdev, 0x1A, &reg))
1036 return 0;
1037
1038 return ((reg & 0x0080) && (reg & 0x1000)) != 0;
1039 }
1040 case PHY_VITESSE_VSC8211:
1041 default:
1042 {
1043 if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, &reg) < 0)
1044 return 0;
1045 return (reg & PHY_AUX_DUPLEX_STAT) != 0;
1046 }
1047 }
926} 1048}
927 1049
928static int ql_is_phy_neg_pause(struct ql3_adapter *qdev) 1050static int ql_is_phy_neg_pause(struct ql3_adapter *qdev)
@@ -935,6 +1057,73 @@ static int ql_is_phy_neg_pause(struct ql3_adapter *qdev)
935 return (reg & PHY_NEG_PAUSE) != 0; 1057 return (reg & PHY_NEG_PAUSE) != 0;
936} 1058}
937 1059
1060static int PHY_Setup(struct ql3_adapter *qdev)
1061{
1062 u16 reg1;
1063 u16 reg2;
1064 bool agereAddrChangeNeeded = false;
1065 u32 miiAddr = 0;
1066 int err;
1067
1068 /* Determine the PHY we are using by reading the ID's */
1069 err = ql_mii_read_reg(qdev, PHY_ID_0_REG, &reg1);
1070 if(err != 0) {
1071 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n",
1072 qdev->ndev->name);
1073 return err;
1074 }
1075
1076 err = ql_mii_read_reg(qdev, PHY_ID_1_REG, &reg2);
1077 if(err != 0) {
1078 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n",
1079 qdev->ndev->name);
1080 return err;
1081 }
1082
1083 /* Check if we have a Agere PHY */
1084 if ((reg1 == 0xffff) || (reg2 == 0xffff)) {
1085
1086 /* Determine which MII address we should be using
1087 determined by the index of the card */
1088 if (qdev->mac_index == 0) {
1089 miiAddr = MII_AGERE_ADDR_1;
1090 } else {
1091 miiAddr = MII_AGERE_ADDR_2;
1092 }
1093
1094 err =ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, &reg1, miiAddr);
1095 if(err != 0) {
1096 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n",
1097 qdev->ndev->name);
1098 return err;
1099 }
1100
1101 err = ql_mii_read_reg_ex(qdev, PHY_ID_1_REG, &reg2, miiAddr);
1102 if(err != 0) {
1103 printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n",
1104 qdev->ndev->name);
1105 return err;
1106 }
1107
1108 /* We need to remember to initialize the Agere PHY */
1109 agereAddrChangeNeeded = true;
1110 }
1111
1112 /* Determine the particular PHY we have on board to apply
1113 PHY specific initializations */
1114 qdev->phyType = getPhyType(qdev, reg1, reg2);
1115
1116 if ((qdev->phyType == PHY_AGERE_ET1011C) && agereAddrChangeNeeded) {
1117 /* need this here so address gets changed */
1118 phyAgereSpecificInit(qdev, miiAddr);
1119 } else if (qdev->phyType == PHY_TYPE_UNKNOWN) {
1120 printk(KERN_ERR "%s: PHY is unknown\n", qdev->ndev->name);
1121 return -EIO;
1122 }
1123
1124 return 0;
1125}
1126
938/* 1127/*
939 * Caller holds hw_lock. 1128 * Caller holds hw_lock.
940 */ 1129 */
@@ -1205,15 +1394,14 @@ static int ql_link_down_detect_clear(struct ql3_adapter *qdev)
1205/* 1394/*
1206 * Caller holds hw_lock. 1395 * Caller holds hw_lock.
1207 */ 1396 */
1208static int ql_this_adapter_controls_port(struct ql3_adapter *qdev, 1397static int ql_this_adapter_controls_port(struct ql3_adapter *qdev)
1209 u32 mac_index)
1210{ 1398{
1211 struct ql3xxx_port_registers __iomem *port_regs = 1399 struct ql3xxx_port_registers __iomem *port_regs =
1212 qdev->mem_map_registers; 1400 qdev->mem_map_registers;
1213 u32 bitToCheck = 0; 1401 u32 bitToCheck = 0;
1214 u32 temp; 1402 u32 temp;
1215 1403
1216 switch (mac_index) { 1404 switch (qdev->mac_index) {
1217 case 0: 1405 case 0:
1218 bitToCheck = PORT_STATUS_F1_ENABLED; 1406 bitToCheck = PORT_STATUS_F1_ENABLED;
1219 break; 1407 break;
@@ -1238,27 +1426,96 @@ static int ql_this_adapter_controls_port(struct ql3_adapter *qdev,
1238 } 1426 }
1239} 1427}
1240 1428
1241static void ql_phy_reset_ex(struct ql3_adapter *qdev, u32 mac_index) 1429static void ql_phy_reset_ex(struct ql3_adapter *qdev)
1242{ 1430{
1243 ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, mac_index); 1431 ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET,
1432 PHYAddr[qdev->mac_index]);
1244} 1433}
1245 1434
1246static void ql_phy_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) 1435static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
1247{ 1436{
1248 u16 reg; 1437 u16 reg;
1438 u16 portConfiguration;
1439
1440 if(qdev->phyType == PHY_AGERE_ET1011C) {
1441 /* turn off external loopback */
1442 ql_mii_write_reg(qdev, 0x13, 0x0000);
1443 }
1444
1445 if(qdev->mac_index == 0)
1446 portConfiguration = qdev->nvram_data.macCfg_port0.portConfiguration;
1447 else
1448 portConfiguration = qdev->nvram_data.macCfg_port1.portConfiguration;
1449
1450 /* Some HBA's in the field are set to 0 and they need to
1451 be reinterpreted with a default value */
1452 if(portConfiguration == 0)
1453 portConfiguration = PORT_CONFIG_DEFAULT;
1454
1455 /* Set the 1000 advertisements */
1456 ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, &reg,
1457 PHYAddr[qdev->mac_index]);
1458 reg &= ~PHY_GIG_ALL_PARAMS;
1459
1460 if(portConfiguration &
1461 PORT_CONFIG_FULL_DUPLEX_ENABLED &
1462 PORT_CONFIG_1000MB_SPEED) {
1463 reg |= PHY_GIG_ADV_1000F;
1464 }
1465
1466 if(portConfiguration &
1467 PORT_CONFIG_HALF_DUPLEX_ENABLED &
1468 PORT_CONFIG_1000MB_SPEED) {
1469 reg |= PHY_GIG_ADV_1000H;
1470 }
1249 1471
1250 ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, 1472 ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
1251 PHY_NEG_PAUSE | PHY_NEG_ADV_SPEED | 1, mac_index); 1473 PHYAddr[qdev->mac_index]);
1252 1474
1253 ql_mii_read_reg_ex(qdev, CONTROL_REG, &reg, mac_index); 1475 /* Set the 10/100 & pause negotiation advertisements */
1254 ql_mii_write_reg_ex(qdev, CONTROL_REG, reg | PHY_CTRL_RESTART_NEG, 1476 ql_mii_read_reg_ex(qdev, PHY_NEG_ADVER, &reg,
1255 mac_index); 1477 PHYAddr[qdev->mac_index]);
1478 reg &= ~PHY_NEG_ALL_PARAMS;
1479
1480 if(portConfiguration & PORT_CONFIG_SYM_PAUSE_ENABLED)
1481 reg |= PHY_NEG_ASY_PAUSE | PHY_NEG_SYM_PAUSE;
1482
1483 if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) {
1484 if(portConfiguration & PORT_CONFIG_100MB_SPEED)
1485 reg |= PHY_NEG_ADV_100F;
1486
1487 if(portConfiguration & PORT_CONFIG_10MB_SPEED)
1488 reg |= PHY_NEG_ADV_10F;
1489 }
1490
1491 if(portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) {
1492 if(portConfiguration & PORT_CONFIG_100MB_SPEED)
1493 reg |= PHY_NEG_ADV_100H;
1494
1495 if(portConfiguration & PORT_CONFIG_10MB_SPEED)
1496 reg |= PHY_NEG_ADV_10H;
1497 }
1498
1499 if(portConfiguration &
1500 PORT_CONFIG_1000MB_SPEED) {
1501 reg |= 1;
1502 }
1503
1504 ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg,
1505 PHYAddr[qdev->mac_index]);
1506
1507 ql_mii_read_reg_ex(qdev, CONTROL_REG, &reg, PHYAddr[qdev->mac_index]);
1508
1509 ql_mii_write_reg_ex(qdev, CONTROL_REG,
1510 reg | PHY_CTRL_RESTART_NEG | PHY_CTRL_AUTO_NEG,
1511 PHYAddr[qdev->mac_index]);
1256} 1512}
1257 1513
1258static void ql_phy_init_ex(struct ql3_adapter *qdev, u32 mac_index) 1514static void ql_phy_init_ex(struct ql3_adapter *qdev)
1259{ 1515{
1260 ql_phy_reset_ex(qdev, mac_index); 1516 ql_phy_reset_ex(qdev);
1261 ql_phy_start_neg_ex(qdev, mac_index); 1517 PHY_Setup(qdev);
1518 ql_phy_start_neg_ex(qdev);
1262} 1519}
1263 1520
1264/* 1521/*
@@ -1295,14 +1552,17 @@ static int ql_port_start(struct ql3_adapter *qdev)
1295{ 1552{
1296 if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, 1553 if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
1297 (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 1554 (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
1298 2) << 7)) 1555 2) << 7)) {
1556 printk(KERN_ERR "%s: Could not get hw lock for GIO\n",
1557 qdev->ndev->name);
1299 return -1; 1558 return -1;
1559 }
1300 1560
1301 if (ql_is_fiber(qdev)) { 1561 if (ql_is_fiber(qdev)) {
1302 ql_petbi_init(qdev); 1562 ql_petbi_init(qdev);
1303 } else { 1563 } else {
1304 /* Copper port */ 1564 /* Copper port */
1305 ql_phy_init_ex(qdev, qdev->mac_index); 1565 ql_phy_init_ex(qdev);
1306 } 1566 }
1307 1567
1308 ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); 1568 ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK);
@@ -1453,7 +1713,7 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
1453 */ 1713 */
1454static void ql_get_phy_owner(struct ql3_adapter *qdev) 1714static void ql_get_phy_owner(struct ql3_adapter *qdev)
1455{ 1715{
1456 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1716 if (ql_this_adapter_controls_port(qdev))
1457 set_bit(QL_LINK_MASTER,&qdev->flags); 1717 set_bit(QL_LINK_MASTER,&qdev->flags);
1458 else 1718 else
1459 clear_bit(QL_LINK_MASTER,&qdev->flags); 1719 clear_bit(QL_LINK_MASTER,&qdev->flags);
@@ -1467,11 +1727,11 @@ static void ql_init_scan_mode(struct ql3_adapter *qdev)
1467 ql_mii_enable_scan_mode(qdev); 1727 ql_mii_enable_scan_mode(qdev);
1468 1728
1469 if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { 1729 if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) {
1470 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1730 if (ql_this_adapter_controls_port(qdev))
1471 ql_petbi_init_ex(qdev, qdev->mac_index); 1731 ql_petbi_init_ex(qdev);
1472 } else { 1732 } else {
1473 if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) 1733 if (ql_this_adapter_controls_port(qdev))
1474 ql_phy_init_ex(qdev, qdev->mac_index); 1734 ql_phy_init_ex(qdev);
1475 } 1735 }
1476} 1736}
1477 1737
@@ -1624,6 +1884,23 @@ static void ql_set_msglevel(struct net_device *ndev, u32 value)
1624 qdev->msg_enable = value; 1884 qdev->msg_enable = value;
1625} 1885}
1626 1886
1887static void ql_get_pauseparam(struct net_device *ndev,
1888 struct ethtool_pauseparam *pause)
1889{
1890 struct ql3_adapter *qdev = netdev_priv(ndev);
1891 struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
1892
1893 u32 reg;
1894 if(qdev->mac_index == 0)
1895 reg = ql_read_page0_reg(qdev, &port_regs->mac0ConfigReg);
1896 else
1897 reg = ql_read_page0_reg(qdev, &port_regs->mac1ConfigReg);
1898
1899 pause->autoneg = ql_get_auto_cfg_status(qdev);
1900 pause->rx_pause = (reg & MAC_CONFIG_REG_RF) >> 2;
1901 pause->tx_pause = (reg & MAC_CONFIG_REG_TF) >> 1;
1902}
1903
1627static const struct ethtool_ops ql3xxx_ethtool_ops = { 1904static const struct ethtool_ops ql3xxx_ethtool_ops = {
1628 .get_settings = ql_get_settings, 1905 .get_settings = ql_get_settings,
1629 .get_drvinfo = ql_get_drvinfo, 1906 .get_drvinfo = ql_get_drvinfo,
@@ -1631,6 +1908,7 @@ static const struct ethtool_ops ql3xxx_ethtool_ops = {
1631 .get_link = ethtool_op_get_link, 1908 .get_link = ethtool_op_get_link,
1632 .get_msglevel = ql_get_msglevel, 1909 .get_msglevel = ql_get_msglevel,
1633 .set_msglevel = ql_set_msglevel, 1910 .set_msglevel = ql_set_msglevel,
1911 .get_pauseparam = ql_get_pauseparam,
1634}; 1912};
1635 1913
1636static int ql_populate_free_queue(struct ql3_adapter *qdev) 1914static int ql_populate_free_queue(struct ql3_adapter *qdev)
@@ -1815,14 +2093,14 @@ invalid_seg_count:
1815 atomic_inc(&qdev->tx_count); 2093 atomic_inc(&qdev->tx_count);
1816} 2094}
1817 2095
1818void ql_get_sbuf(struct ql3_adapter *qdev) 2096static void ql_get_sbuf(struct ql3_adapter *qdev)
1819{ 2097{
1820 if (++qdev->small_buf_index == NUM_SMALL_BUFFERS) 2098 if (++qdev->small_buf_index == NUM_SMALL_BUFFERS)
1821 qdev->small_buf_index = 0; 2099 qdev->small_buf_index = 0;
1822 qdev->small_buf_release_cnt++; 2100 qdev->small_buf_release_cnt++;
1823} 2101}
1824 2102
1825struct ql_rcv_buf_cb *ql_get_lbuf(struct ql3_adapter *qdev) 2103static struct ql_rcv_buf_cb *ql_get_lbuf(struct ql3_adapter *qdev)
1826{ 2104{
1827 struct ql_rcv_buf_cb *lrg_buf_cb = NULL; 2105 struct ql_rcv_buf_cb *lrg_buf_cb = NULL;
1828 lrg_buf_cb = &qdev->lrg_buf[qdev->lrg_buf_index]; 2106 lrg_buf_cb = &qdev->lrg_buf[qdev->lrg_buf_index];
@@ -3074,6 +3352,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
3074 goto out; 3352 goto out;
3075 } 3353 }
3076 3354
3355 PHY_Setup(qdev);
3077 ql_init_scan_mode(qdev); 3356 ql_init_scan_mode(qdev);
3078 ql_get_phy_owner(qdev); 3357 ql_get_phy_owner(qdev);
3079 3358
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 0203f88f0544..4a832c46c274 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -293,6 +293,16 @@ struct net_rsp_iocb {
293 293
294#define MII_SCAN_REGISTER 0x00000001 294#define MII_SCAN_REGISTER 0x00000001
295 295
296#define PHY_ID_0_REG 2
297#define PHY_ID_1_REG 3
298
299#define PHY_OUI_1_MASK 0xfc00
300#define PHY_MODEL_MASK 0x03f0
301
302/* Address for the Agere Phy */
303#define MII_AGERE_ADDR_1 0x00001000
304#define MII_AGERE_ADDR_2 0x00001100
305
296/* 32-bit ispControlStatus */ 306/* 32-bit ispControlStatus */
297enum { 307enum {
298 ISP_CONTROL_NP_MASK = 0x0003, 308 ISP_CONTROL_NP_MASK = 0x0003,
@@ -789,6 +799,7 @@ enum {
789 PHY_CTRL_LOOPBACK = 0x4000, 799 PHY_CTRL_LOOPBACK = 0x4000,
790 800
791 PETBI_CONTROL_REG = 0x00, 801 PETBI_CONTROL_REG = 0x00,
802 PETBI_CTRL_ALL_PARAMS = 0x7140,
792 PETBI_CTRL_SOFT_RESET = 0x8000, 803 PETBI_CTRL_SOFT_RESET = 0x8000,
793 PETBI_CTRL_AUTO_NEG = 0x1000, 804 PETBI_CTRL_AUTO_NEG = 0x1000,
794 PETBI_CTRL_RESTART_NEG = 0x0200, 805 PETBI_CTRL_RESTART_NEG = 0x0200,
@@ -811,6 +822,23 @@ enum {
811 PETBI_EXPANSION_REG = 0x06, 822 PETBI_EXPANSION_REG = 0x06,
812 PETBI_EXP_PAGE_RX = 0x0002, 823 PETBI_EXP_PAGE_RX = 0x0002,
813 824
825 PHY_GIG_CONTROL = 9,
826 PHY_GIG_ENABLE_MAN = 0x1000, /* Enable Master/Slave Manual Config*/
827 PHY_GIG_SET_MASTER = 0x0800, /* Set Master (slave if clear)*/
828 PHY_GIG_ALL_PARAMS = 0x0300,
829 PHY_GIG_ADV_1000F = 0x0200,
830 PHY_GIG_ADV_1000H = 0x0100,
831
832 PHY_NEG_ADVER = 4,
833 PHY_NEG_ALL_PARAMS = 0x0fe0,
834 PHY_NEG_ASY_PAUSE = 0x0800,
835 PHY_NEG_SYM_PAUSE = 0x0400,
836 PHY_NEG_ADV_SPEED = 0x01e0,
837 PHY_NEG_ADV_100F = 0x0100,
838 PHY_NEG_ADV_100H = 0x0080,
839 PHY_NEG_ADV_10F = 0x0040,
840 PHY_NEG_ADV_10H = 0x0020,
841
814 PETBI_TBI_CTRL = 0x11, 842 PETBI_TBI_CTRL = 0x11,
815 PETBI_TBI_RESET = 0x8000, 843 PETBI_TBI_RESET = 0x8000,
816 PETBI_TBI_AUTO_SENSE = 0x0100, 844 PETBI_TBI_AUTO_SENSE = 0x0100,
@@ -826,8 +854,7 @@ enum {
826 PHY_AUX_RESET_STICK = 0x0002, 854 PHY_AUX_RESET_STICK = 0x0002,
827 PHY_NEG_PAUSE = 0x0400, 855 PHY_NEG_PAUSE = 0x0400,
828 PHY_CTRL_SOFT_RESET = 0x8000, 856 PHY_CTRL_SOFT_RESET = 0x8000,
829 PHY_NEG_ADVER = 4, 857 PHY_CTRL_AUTO_NEG = 0x1000,
830 PHY_NEG_ADV_SPEED = 0x01e0,
831 PHY_CTRL_RESTART_NEG = 0x0200, 858 PHY_CTRL_RESTART_NEG = 0x0200,
832}; 859};
833enum { 860enum {
@@ -892,6 +919,7 @@ enum {EEPROM_SIZE = FM93C86A_SIZE_16,
892 u16 pauseThreshold_mac; 919 u16 pauseThreshold_mac;
893 u16 resumeThreshold_mac; 920 u16 resumeThreshold_mac;
894 u16 portConfiguration; 921 u16 portConfiguration;
922#define PORT_CONFIG_DEFAULT 0xf700
895#define PORT_CONFIG_AUTO_NEG_ENABLED 0x8000 923#define PORT_CONFIG_AUTO_NEG_ENABLED 0x8000
896#define PORT_CONFIG_SYM_PAUSE_ENABLED 0x4000 924#define PORT_CONFIG_SYM_PAUSE_ENABLED 0x4000
897#define PORT_CONFIG_FULL_DUPLEX_ENABLED 0x2000 925#define PORT_CONFIG_FULL_DUPLEX_ENABLED 0x2000
@@ -1259,6 +1287,7 @@ struct ql3_adapter {
1259 struct delayed_work tx_timeout_work; 1287 struct delayed_work tx_timeout_work;
1260 u32 max_frame_size; 1288 u32 max_frame_size;
1261 u32 device_id; 1289 u32 device_id;
1290 u16 phyType;
1262}; 1291};
1263 1292
1264#endif /* _QLA3XXX_H_ */ 1293#endif /* _QLA3XXX_H_ */
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 33fb7f3b7041..4cb710bbe729 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -1,6 +1,6 @@
1/************************************************************************ 1/************************************************************************
2 * regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC 2 * regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
3 * Copyright(c) 2002-2005 Neterion Inc. 3 * Copyright(c) 2002-2007 Neterion Inc.
4 4
5 * This software may be used and distributed according to the terms of 5 * This software may be used and distributed according to the terms of
6 * the GNU General Public License (GPL), incorporated herein by reference. 6 * the GNU General Public License (GPL), incorporated herein by reference.
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 600d3ff347fc..290e1c1f30c6 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1,6 +1,6 @@
1/************************************************************************ 1/************************************************************************
2 * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC 2 * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
3 * Copyright(c) 2002-2005 Neterion Inc. 3 * Copyright(c) 2002-2007 Neterion Inc.
4 4
5 * This software may be used and distributed according to the terms of 5 * This software may be used and distributed according to the terms of
6 * the GNU General Public License (GPL), incorporated herein by reference. 6 * the GNU General Public License (GPL), incorporated herein by reference.
@@ -84,7 +84,7 @@
84#include "s2io.h" 84#include "s2io.h"
85#include "s2io-regs.h" 85#include "s2io-regs.h"
86 86
87#define DRV_VERSION "2.0.17.1" 87#define DRV_VERSION "2.0.22.1"
88 88
89/* S2io Driver name & version. */ 89/* S2io Driver name & version. */
90static char s2io_driver_name[] = "Neterion"; 90static char s2io_driver_name[] = "Neterion";
@@ -316,7 +316,7 @@ static void s2io_vlan_rx_register(struct net_device *dev,
316} 316}
317 317
318/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ 318/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
319int vlan_strip_flag; 319static int vlan_strip_flag;
320 320
321/* Unregister the vlan */ 321/* Unregister the vlan */
322static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) 322static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
@@ -394,7 +394,6 @@ static const u64 fix_mac[] = {
394 END_SIGN 394 END_SIGN
395}; 395};
396 396
397MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>");
398MODULE_LICENSE("GPL"); 397MODULE_LICENSE("GPL");
399MODULE_VERSION(DRV_VERSION); 398MODULE_VERSION(DRV_VERSION);
400 399
@@ -516,7 +515,7 @@ static int init_shared_mem(struct s2io_nic *nic)
516 mac_control->fifos[i].list_info = kmalloc(list_holder_size, 515 mac_control->fifos[i].list_info = kmalloc(list_holder_size,
517 GFP_KERNEL); 516 GFP_KERNEL);
518 if (!mac_control->fifos[i].list_info) { 517 if (!mac_control->fifos[i].list_info) {
519 DBG_PRINT(ERR_DBG, 518 DBG_PRINT(INFO_DBG,
520 "Malloc failed for list_info\n"); 519 "Malloc failed for list_info\n");
521 return -ENOMEM; 520 return -ENOMEM;
522 } 521 }
@@ -542,9 +541,9 @@ static int init_shared_mem(struct s2io_nic *nic)
542 tmp_v = pci_alloc_consistent(nic->pdev, 541 tmp_v = pci_alloc_consistent(nic->pdev,
543 PAGE_SIZE, &tmp_p); 542 PAGE_SIZE, &tmp_p);
544 if (!tmp_v) { 543 if (!tmp_v) {
545 DBG_PRINT(ERR_DBG, 544 DBG_PRINT(INFO_DBG,
546 "pci_alloc_consistent "); 545 "pci_alloc_consistent ");
547 DBG_PRINT(ERR_DBG, "failed for TxDL\n"); 546 DBG_PRINT(INFO_DBG, "failed for TxDL\n");
548 return -ENOMEM; 547 return -ENOMEM;
549 } 548 }
550 /* If we got a zero DMA address(can happen on 549 /* If we got a zero DMA address(can happen on
@@ -561,9 +560,9 @@ static int init_shared_mem(struct s2io_nic *nic)
561 tmp_v = pci_alloc_consistent(nic->pdev, 560 tmp_v = pci_alloc_consistent(nic->pdev,
562 PAGE_SIZE, &tmp_p); 561 PAGE_SIZE, &tmp_p);
563 if (!tmp_v) { 562 if (!tmp_v) {
564 DBG_PRINT(ERR_DBG, 563 DBG_PRINT(INFO_DBG,
565 "pci_alloc_consistent "); 564 "pci_alloc_consistent ");
566 DBG_PRINT(ERR_DBG, "failed for TxDL\n"); 565 DBG_PRINT(INFO_DBG, "failed for TxDL\n");
567 return -ENOMEM; 566 return -ENOMEM;
568 } 567 }
569 } 568 }
@@ -2187,7 +2186,7 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
2187 /* skb_shinfo(skb)->frag_list will have L4 data payload */ 2186 /* skb_shinfo(skb)->frag_list will have L4 data payload */
2188 skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); 2187 skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
2189 if (skb_shinfo(skb)->frag_list == NULL) { 2188 if (skb_shinfo(skb)->frag_list == NULL) {
2190 DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n ", dev->name); 2189 DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
2191 return -ENOMEM ; 2190 return -ENOMEM ;
2192 } 2191 }
2193 frag_list = skb_shinfo(skb)->frag_list; 2192 frag_list = skb_shinfo(skb)->frag_list;
@@ -2242,6 +2241,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2242 struct buffAdd *ba; 2241 struct buffAdd *ba;
2243 unsigned long flags; 2242 unsigned long flags;
2244 struct RxD_t *first_rxdp = NULL; 2243 struct RxD_t *first_rxdp = NULL;
2244 u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
2245 2245
2246 mac_control = &nic->mac_control; 2246 mac_control = &nic->mac_control;
2247 config = &nic->config; 2247 config = &nic->config;
@@ -2313,8 +2313,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2313 /* allocate skb */ 2313 /* allocate skb */
2314 skb = dev_alloc_skb(size); 2314 skb = dev_alloc_skb(size);
2315 if(!skb) { 2315 if(!skb) {
2316 DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); 2316 DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
2317 DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); 2317 DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
2318 if (first_rxdp) { 2318 if (first_rxdp) {
2319 wmb(); 2319 wmb();
2320 first_rxdp->Control_1 |= RXD_OWN_XENA; 2320 first_rxdp->Control_1 |= RXD_OWN_XENA;
@@ -2342,7 +2342,14 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2342 * payload 2342 * payload
2343 */ 2343 */
2344 2344
2345 /* save the buffer pointers to avoid frequent dma mapping */
2346 Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
2347 Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
2345 memset(rxdp, 0, sizeof(struct RxD3)); 2348 memset(rxdp, 0, sizeof(struct RxD3));
2349 /* restore the buffer pointers for dma sync*/
2350 ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr;
2351 ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr;
2352
2346 ba = &mac_control->rings[ring_no].ba[block_no][off]; 2353 ba = &mac_control->rings[ring_no].ba[block_no][off];
2347 skb_reserve(skb, BUF0_LEN); 2354 skb_reserve(skb, BUF0_LEN);
2348 tmp = (u64)(unsigned long) skb->data; 2355 tmp = (u64)(unsigned long) skb->data;
@@ -2573,8 +2580,8 @@ static int s2io_poll(struct net_device *dev, int *budget)
2573 2580
2574 for (i = 0; i < config->rx_ring_num; i++) { 2581 for (i = 0; i < config->rx_ring_num; i++) {
2575 if (fill_rx_buffers(nic, i) == -ENOMEM) { 2582 if (fill_rx_buffers(nic, i) == -ENOMEM) {
2576 DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); 2583 DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
2577 DBG_PRINT(ERR_DBG, " in Rx Poll!!\n"); 2584 DBG_PRINT(INFO_DBG, " in Rx Poll!!\n");
2578 break; 2585 break;
2579 } 2586 }
2580 } 2587 }
@@ -2590,8 +2597,8 @@ no_rx:
2590 2597
2591 for (i = 0; i < config->rx_ring_num; i++) { 2598 for (i = 0; i < config->rx_ring_num; i++) {
2592 if (fill_rx_buffers(nic, i) == -ENOMEM) { 2599 if (fill_rx_buffers(nic, i) == -ENOMEM) {
2593 DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); 2600 DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
2594 DBG_PRINT(ERR_DBG, " in Rx Poll!!\n"); 2601 DBG_PRINT(INFO_DBG, " in Rx Poll!!\n");
2595 break; 2602 break;
2596 } 2603 }
2597 } 2604 }
@@ -2640,8 +2647,8 @@ static void s2io_netpoll(struct net_device *dev)
2640 2647
2641 for (i = 0; i < config->rx_ring_num; i++) { 2648 for (i = 0; i < config->rx_ring_num; i++) {
2642 if (fill_rx_buffers(nic, i) == -ENOMEM) { 2649 if (fill_rx_buffers(nic, i) == -ENOMEM) {
2643 DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); 2650 DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
2644 DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n"); 2651 DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n");
2645 break; 2652 break;
2646 } 2653 }
2647 } 2654 }
@@ -3307,6 +3314,7 @@ static void s2io_reset(struct s2io_nic * sp)
3307 u16 subid, pci_cmd; 3314 u16 subid, pci_cmd;
3308 int i; 3315 int i;
3309 u16 val16; 3316 u16 val16;
3317 unsigned long long reset_cnt = 0;
3310 DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n", 3318 DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
3311 __FUNCTION__, sp->dev->name); 3319 __FUNCTION__, sp->dev->name);
3312 3320
@@ -3372,6 +3380,11 @@ new_way:
3372 3380
3373 /* Reset device statistics maintained by OS */ 3381 /* Reset device statistics maintained by OS */
3374 memset(&sp->stats, 0, sizeof (struct net_device_stats)); 3382 memset(&sp->stats, 0, sizeof (struct net_device_stats));
3383 /* save reset count */
3384 reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
3385 memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
3386 /* restore reset count */
3387 sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
3375 3388
3376 /* SXE-002: Configure link and activity LED to turn it off */ 3389 /* SXE-002: Configure link and activity LED to turn it off */
3377 subid = sp->pdev->subsystem_device; 3390 subid = sp->pdev->subsystem_device;
@@ -3659,7 +3672,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
3659 nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry), 3672 nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
3660 GFP_KERNEL); 3673 GFP_KERNEL);
3661 if (nic->entries == NULL) { 3674 if (nic->entries == NULL) {
3662 DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); 3675 DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
3663 return -ENOMEM; 3676 return -ENOMEM;
3664 } 3677 }
3665 memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); 3678 memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
@@ -3668,7 +3681,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
3668 kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry), 3681 kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
3669 GFP_KERNEL); 3682 GFP_KERNEL);
3670 if (nic->s2io_entries == NULL) { 3683 if (nic->s2io_entries == NULL) {
3671 DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); 3684 DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
3672 kfree(nic->entries); 3685 kfree(nic->entries);
3673 return -ENOMEM; 3686 return -ENOMEM;
3674 } 3687 }
@@ -4019,7 +4032,7 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
4019 DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); 4032 DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
4020 DBG_PRINT(INTR_DBG, "PANIC levels\n"); 4033 DBG_PRINT(INTR_DBG, "PANIC levels\n");
4021 if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { 4034 if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
4022 DBG_PRINT(ERR_DBG, "Out of memory in %s", 4035 DBG_PRINT(INFO_DBG, "Out of memory in %s",
4023 __FUNCTION__); 4036 __FUNCTION__);
4024 clear_bit(0, (&sp->tasklet_status)); 4037 clear_bit(0, (&sp->tasklet_status));
4025 return -1; 4038 return -1;
@@ -4029,8 +4042,8 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
4029 tasklet_schedule(&sp->task); 4042 tasklet_schedule(&sp->task);
4030 4043
4031 } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { 4044 } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
4032 DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); 4045 DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name);
4033 DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); 4046 DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
4034 } 4047 }
4035 return 0; 4048 return 0;
4036} 4049}
@@ -4279,9 +4292,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
4279 if (cnt == 5) 4292 if (cnt == 5)
4280 break; /* Updt failed */ 4293 break; /* Updt failed */
4281 } while(1); 4294 } while(1);
4282 } else { 4295 }
4283 memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
4284 }
4285} 4296}
4286 4297
4287/** 4298/**
@@ -5949,12 +5960,12 @@ static void s2io_tasklet(unsigned long dev_addr)
5949 for (i = 0; i < config->rx_ring_num; i++) { 5960 for (i = 0; i < config->rx_ring_num; i++) {
5950 ret = fill_rx_buffers(sp, i); 5961 ret = fill_rx_buffers(sp, i);
5951 if (ret == -ENOMEM) { 5962 if (ret == -ENOMEM) {
5952 DBG_PRINT(ERR_DBG, "%s: Out of ", 5963 DBG_PRINT(INFO_DBG, "%s: Out of ",
5953 dev->name); 5964 dev->name);
5954 DBG_PRINT(ERR_DBG, "memory in tasklet\n"); 5965 DBG_PRINT(ERR_DBG, "memory in tasklet\n");
5955 break; 5966 break;
5956 } else if (ret == -EFILL) { 5967 } else if (ret == -EFILL) {
5957 DBG_PRINT(ERR_DBG, 5968 DBG_PRINT(INFO_DBG,
5958 "%s: Rx Ring %d is full\n", 5969 "%s: Rx Ring %d is full\n",
5959 dev->name, i); 5970 dev->name, i);
5960 break; 5971 break;
@@ -6065,8 +6076,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
6065 } else { 6076 } else {
6066 *skb = dev_alloc_skb(size); 6077 *skb = dev_alloc_skb(size);
6067 if (!(*skb)) { 6078 if (!(*skb)) {
6068 DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); 6079 DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
6069 DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); 6080 DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
6070 return -ENOMEM ; 6081 return -ENOMEM ;
6071 } 6082 }
6072 /* storing the mapped addr in a temp variable 6083 /* storing the mapped addr in a temp variable
@@ -6088,7 +6099,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
6088 } else { 6099 } else {
6089 *skb = dev_alloc_skb(size); 6100 *skb = dev_alloc_skb(size);
6090 if (!(*skb)) { 6101 if (!(*skb)) {
6091 DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", 6102 DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
6092 dev->name); 6103 dev->name);
6093 return -ENOMEM; 6104 return -ENOMEM;
6094 } 6105 }
@@ -6115,7 +6126,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
6115 } else { 6126 } else {
6116 *skb = dev_alloc_skb(size); 6127 *skb = dev_alloc_skb(size);
6117 if (!(*skb)) { 6128 if (!(*skb)) {
6118 DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", 6129 DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
6119 dev->name); 6130 dev->name);
6120 return -ENOMEM; 6131 return -ENOMEM;
6121 } 6132 }
@@ -6616,7 +6627,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
6616 6627
6617 /* Updating statistics */ 6628 /* Updating statistics */
6618 rxdp->Host_Control = 0; 6629 rxdp->Host_Control = 0;
6619 sp->rx_pkt_count++;
6620 sp->stats.rx_packets++; 6630 sp->stats.rx_packets++;
6621 if (sp->rxd_mode == RXD_MODE_1) { 6631 if (sp->rxd_mode == RXD_MODE_1) {
6622 int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); 6632 int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -7252,7 +7262,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
7252 goto register_failed; 7262 goto register_failed;
7253 } 7263 }
7254 s2io_vpd_read(sp); 7264 s2io_vpd_read(sp);
7255 DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); 7265 DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
7256 DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, 7266 DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name,
7257 sp->product_name, get_xena_rev_id(sp->pdev)); 7267 sp->product_name, get_xena_rev_id(sp->pdev));
7258 DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, 7268 DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 803137ca4b6c..a656d18b33df 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -1,6 +1,6 @@
1/************************************************************************ 1/************************************************************************
2 * s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC 2 * s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
3 * Copyright(c) 2002-2005 Neterion Inc. 3 * Copyright(c) 2002-2007 Neterion Inc.
4 4
5 * This software may be used and distributed according to the terms of 5 * This software may be used and distributed according to the terms of
6 * the GNU General Public License (GPL), incorporated herein by reference. 6 * the GNU General Public License (GPL), incorporated herein by reference.
@@ -760,7 +760,6 @@ struct s2io_nic {
760#define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED 760#define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED
761 761
762 struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; 762 struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED];
763 struct mac_addr pre_mac_addr[MAX_MAC_SUPPORTED];
764 763
765 struct net_device_stats stats; 764 struct net_device_stats stats;
766 int high_dma_flag; 765 int high_dma_flag;
@@ -794,11 +793,6 @@ struct s2io_nic {
794 u16 all_multi_pos; 793 u16 all_multi_pos;
795 u16 promisc_flg; 794 u16 promisc_flg;
796 795
797 u16 tx_pkt_count;
798 u16 rx_pkt_count;
799 u16 tx_err_count;
800 u16 rx_err_count;
801
802 /* Id timer, used to blink NIC to physically identify NIC. */ 796 /* Id timer, used to blink NIC to physically identify NIC. */
803 struct timer_list id_timer; 797 struct timer_list id_timer;
804 798
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 0a3a379b634c..132e2148b21c 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -95,19 +95,28 @@ MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS));
95#endif 95#endif
96 96
97#ifdef CONFIG_SBMAC_COALESCE 97#ifdef CONFIG_SBMAC_COALESCE
98static int int_pktcnt = 0; 98static int int_pktcnt_tx = 255;
99module_param(int_pktcnt, int, S_IRUGO); 99module_param(int_pktcnt_tx, int, S_IRUGO);
100MODULE_PARM_DESC(int_pktcnt, "Packet count"); 100MODULE_PARM_DESC(int_pktcnt_tx, "TX packet count");
101 101
102static int int_timeout = 0; 102static int int_timeout_tx = 255;
103module_param(int_timeout, int, S_IRUGO); 103module_param(int_timeout_tx, int, S_IRUGO);
104MODULE_PARM_DESC(int_timeout, "Timeout value"); 104MODULE_PARM_DESC(int_timeout_tx, "TX timeout value");
105
106static int int_pktcnt_rx = 64;
107module_param(int_pktcnt_rx, int, S_IRUGO);
108MODULE_PARM_DESC(int_pktcnt_rx, "RX packet count");
109
110static int int_timeout_rx = 64;
111module_param(int_timeout_rx, int, S_IRUGO);
112MODULE_PARM_DESC(int_timeout_rx, "RX timeout value");
105#endif 113#endif
106 114
107#include <asm/sibyte/sb1250.h> 115#include <asm/sibyte/sb1250.h>
108#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) 116#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
109#include <asm/sibyte/bcm1480_regs.h> 117#include <asm/sibyte/bcm1480_regs.h>
110#include <asm/sibyte/bcm1480_int.h> 118#include <asm/sibyte/bcm1480_int.h>
119#define R_MAC_DMA_OODPKTLOST_RX R_MAC_DMA_OODPKTLOST
111#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) 120#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
112#include <asm/sibyte/sb1250_regs.h> 121#include <asm/sibyte/sb1250_regs.h>
113#include <asm/sibyte/sb1250_int.h> 122#include <asm/sibyte/sb1250_int.h>
@@ -155,8 +164,8 @@ typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
155 164
156#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES) 165#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
157 166
158#define SBMAC_MAX_TXDESCR 32 167#define SBMAC_MAX_TXDESCR 256
159#define SBMAC_MAX_RXDESCR 32 168#define SBMAC_MAX_RXDESCR 256
160 169
161#define ETHER_ALIGN 2 170#define ETHER_ALIGN 2
162#define ETHER_ADDR_LEN 6 171#define ETHER_ADDR_LEN 6
@@ -185,10 +194,10 @@ typedef struct sbmacdma_s {
185 * associated with it. 194 * associated with it.
186 */ 195 */
187 196
188 struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */ 197 struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */
189 int sbdma_channel; /* channel number */ 198 int sbdma_channel; /* channel number */
190 int sbdma_txdir; /* direction (1=transmit) */ 199 int sbdma_txdir; /* direction (1=transmit) */
191 int sbdma_maxdescr; /* total # of descriptors in ring */ 200 int sbdma_maxdescr; /* total # of descriptors in ring */
192#ifdef CONFIG_SBMAC_COALESCE 201#ifdef CONFIG_SBMAC_COALESCE
193 int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt*/ 202 int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt*/
194 int sbdma_int_timeout; /* # usec rx/tx interrupt */ 203 int sbdma_int_timeout; /* # usec rx/tx interrupt */
@@ -197,13 +206,16 @@ typedef struct sbmacdma_s {
197 volatile void __iomem *sbdma_config0; /* DMA config register 0 */ 206 volatile void __iomem *sbdma_config0; /* DMA config register 0 */
198 volatile void __iomem *sbdma_config1; /* DMA config register 1 */ 207 volatile void __iomem *sbdma_config1; /* DMA config register 1 */
199 volatile void __iomem *sbdma_dscrbase; /* Descriptor base address */ 208 volatile void __iomem *sbdma_dscrbase; /* Descriptor base address */
200 volatile void __iomem *sbdma_dscrcnt; /* Descriptor count register */ 209 volatile void __iomem *sbdma_dscrcnt; /* Descriptor count register */
201 volatile void __iomem *sbdma_curdscr; /* current descriptor address */ 210 volatile void __iomem *sbdma_curdscr; /* current descriptor address */
211 volatile void __iomem *sbdma_oodpktlost;/* pkt drop (rx only) */
212
202 213
203 /* 214 /*
204 * This stuff is for maintenance of the ring 215 * This stuff is for maintenance of the ring
205 */ 216 */
206 217
218 sbdmadscr_t *sbdma_dscrtable_unaligned;
207 sbdmadscr_t *sbdma_dscrtable; /* base of descriptor table */ 219 sbdmadscr_t *sbdma_dscrtable; /* base of descriptor table */
208 sbdmadscr_t *sbdma_dscrtable_end; /* end of descriptor table */ 220 sbdmadscr_t *sbdma_dscrtable_end; /* end of descriptor table */
209 221
@@ -286,8 +298,8 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *m);
286static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m); 298static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m);
287static void sbdma_emptyring(sbmacdma_t *d); 299static void sbdma_emptyring(sbmacdma_t *d);
288static void sbdma_fillring(sbmacdma_t *d); 300static void sbdma_fillring(sbmacdma_t *d);
289static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d); 301static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, int work_to_do, int poll);
290static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d); 302static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll);
291static int sbmac_initctx(struct sbmac_softc *s); 303static int sbmac_initctx(struct sbmac_softc *s);
292static void sbmac_channel_start(struct sbmac_softc *s); 304static void sbmac_channel_start(struct sbmac_softc *s);
293static void sbmac_channel_stop(struct sbmac_softc *s); 305static void sbmac_channel_stop(struct sbmac_softc *s);
@@ -308,6 +320,8 @@ static struct net_device_stats *sbmac_get_stats(struct net_device *dev);
308static void sbmac_set_rx_mode(struct net_device *dev); 320static void sbmac_set_rx_mode(struct net_device *dev);
309static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 321static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
310static int sbmac_close(struct net_device *dev); 322static int sbmac_close(struct net_device *dev);
323static int sbmac_poll(struct net_device *poll_dev, int *budget);
324
311static int sbmac_mii_poll(struct sbmac_softc *s,int noisy); 325static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
312static int sbmac_mii_probe(struct net_device *dev); 326static int sbmac_mii_probe(struct net_device *dev);
313 327
@@ -679,6 +693,10 @@ static void sbdma_initctx(sbmacdma_t *d,
679 int txrx, 693 int txrx,
680 int maxdescr) 694 int maxdescr)
681{ 695{
696#ifdef CONFIG_SBMAC_COALESCE
697 int int_pktcnt, int_timeout;
698#endif
699
682 /* 700 /*
683 * Save away interesting stuff in the structure 701 * Save away interesting stuff in the structure
684 */ 702 */
@@ -728,6 +746,11 @@ static void sbdma_initctx(sbmacdma_t *d,
728 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); 746 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT);
729 d->sbdma_curdscr = 747 d->sbdma_curdscr =
730 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); 748 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR);
749 if (d->sbdma_txdir)
750 d->sbdma_oodpktlost = NULL;
751 else
752 d->sbdma_oodpktlost =
753 s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_OODPKTLOST_RX);
731 754
732 /* 755 /*
733 * Allocate memory for the ring 756 * Allocate memory for the ring
@@ -735,6 +758,7 @@ static void sbdma_initctx(sbmacdma_t *d,
735 758
736 d->sbdma_maxdescr = maxdescr; 759 d->sbdma_maxdescr = maxdescr;
737 760
761 d->sbdma_dscrtable_unaligned =
738 d->sbdma_dscrtable = (sbdmadscr_t *) 762 d->sbdma_dscrtable = (sbdmadscr_t *)
739 kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL); 763 kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
740 764
@@ -765,12 +789,14 @@ static void sbdma_initctx(sbmacdma_t *d,
765 * Setup Rx/Tx DMA coalescing defaults 789 * Setup Rx/Tx DMA coalescing defaults
766 */ 790 */
767 791
792 int_pktcnt = (txrx == DMA_TX) ? int_pktcnt_tx : int_pktcnt_rx;
768 if ( int_pktcnt ) { 793 if ( int_pktcnt ) {
769 d->sbdma_int_pktcnt = int_pktcnt; 794 d->sbdma_int_pktcnt = int_pktcnt;
770 } else { 795 } else {
771 d->sbdma_int_pktcnt = 1; 796 d->sbdma_int_pktcnt = 1;
772 } 797 }
773 798
799 int_timeout = (txrx == DMA_TX) ? int_timeout_tx : int_timeout_rx;
774 if ( int_timeout ) { 800 if ( int_timeout ) {
775 d->sbdma_int_timeout = int_timeout; 801 d->sbdma_int_timeout = int_timeout;
776 } else { 802 } else {
@@ -1125,32 +1151,63 @@ static void sbdma_fillring(sbmacdma_t *d)
1125 } 1151 }
1126} 1152}
1127 1153
1154#ifdef CONFIG_NET_POLL_CONTROLLER
1155static void sbmac_netpoll(struct net_device *netdev)
1156{
1157 struct sbmac_softc *sc = netdev_priv(netdev);
1158 int irq = sc->sbm_dev->irq;
1159
1160 __raw_writeq(0, sc->sbm_imr);
1161
1162 sbmac_intr(irq, netdev, NULL);
1163
1164#ifdef CONFIG_SBMAC_COALESCE
1165 __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
1166 ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0),
1167 sc->sbm_imr);
1168#else
1169 __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
1170 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr);
1171#endif
1172}
1173#endif
1128 1174
1129/********************************************************************** 1175/**********************************************************************
1130 * SBDMA_RX_PROCESS(sc,d) 1176 * SBDMA_RX_PROCESS(sc,d,work_to_do,poll)
1131 * 1177 *
1132 * Process "completed" receive buffers on the specified DMA channel. 1178 * Process "completed" receive buffers on the specified DMA channel.
1133 * Note that this isn't really ideal for priority channels, since
1134 * it processes all of the packets on a given channel before
1135 * returning.
1136 * 1179 *
1137 * Input parameters: 1180 * Input parameters:
1138 * sc - softc structure 1181 * sc - softc structure
1139 * d - DMA channel context 1182 * d - DMA channel context
1183 * work_to_do - no. of packets to process before enabling interrupt
1184 * again (for NAPI)
1185 * poll - 1: using polling (for NAPI)
1140 * 1186 *
1141 * Return value: 1187 * Return value:
1142 * nothing 1188 * nothing
1143 ********************************************************************* */ 1189 ********************************************************************* */
1144 1190
1145static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d) 1191static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d,
1192 int work_to_do, int poll)
1146{ 1193{
1147 int curidx; 1194 int curidx;
1148 int hwidx; 1195 int hwidx;
1149 sbdmadscr_t *dsc; 1196 sbdmadscr_t *dsc;
1150 struct sk_buff *sb; 1197 struct sk_buff *sb;
1151 int len; 1198 int len;
1199 int work_done = 0;
1200 int dropped = 0;
1152 1201
1153 for (;;) { 1202 prefetch(d);
1203
1204again:
1205 /* Check if the HW dropped any frames */
1206 sc->sbm_stats.rx_fifo_errors
1207 += __raw_readq(sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff;
1208 __raw_writeq(0, sc->sbm_rxdma.sbdma_oodpktlost);
1209
1210 while (work_to_do-- > 0) {
1154 /* 1211 /*
1155 * figure out where we are (as an index) and where 1212 * figure out where we are (as an index) and where
1156 * the hardware is (also as an index) 1213 * the hardware is (also as an index)
@@ -1162,7 +1219,12 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1162 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) 1219 * (sbdma_remptr) and the physical address (sbdma_curdscr CSR)
1163 */ 1220 */
1164 1221
1165 curidx = d->sbdma_remptr - d->sbdma_dscrtable; 1222 dsc = d->sbdma_remptr;
1223 curidx = dsc - d->sbdma_dscrtable;
1224
1225 prefetch(dsc);
1226 prefetch(&d->sbdma_ctxtable[curidx]);
1227
1166 hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - 1228 hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
1167 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); 1229 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
1168 1230
@@ -1173,13 +1235,12 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1173 */ 1235 */
1174 1236
1175 if (curidx == hwidx) 1237 if (curidx == hwidx)
1176 break; 1238 goto done;
1177 1239
1178 /* 1240 /*
1179 * Otherwise, get the packet's sk_buff ptr back 1241 * Otherwise, get the packet's sk_buff ptr back
1180 */ 1242 */
1181 1243
1182 dsc = &(d->sbdma_dscrtable[curidx]);
1183 sb = d->sbdma_ctxtable[curidx]; 1244 sb = d->sbdma_ctxtable[curidx];
1184 d->sbdma_ctxtable[curidx] = NULL; 1245 d->sbdma_ctxtable[curidx] = NULL;
1185 1246
@@ -1191,7 +1252,7 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1191 * receive ring. 1252 * receive ring.
1192 */ 1253 */
1193 1254
1194 if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) { 1255 if (likely (!(dsc->dscr_a & M_DMA_ETHRX_BAD))) {
1195 1256
1196 /* 1257 /*
1197 * Add a new buffer to replace the old one. If we fail 1258 * Add a new buffer to replace the old one. If we fail
@@ -1199,9 +1260,14 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1199 * packet and put it right back on the receive ring. 1260 * packet and put it right back on the receive ring.
1200 */ 1261 */
1201 1262
1202 if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) { 1263 if (unlikely (sbdma_add_rcvbuffer(d,NULL) ==
1203 sc->sbm_stats.rx_dropped++; 1264 -ENOBUFS)) {
1265 sc->sbm_stats.rx_dropped++;
1204 sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ 1266 sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */
1267 /* No point in continuing at the moment */
1268 printk(KERN_ERR "dropped packet (1)\n");
1269 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
1270 goto done;
1205 } else { 1271 } else {
1206 /* 1272 /*
1207 * Set length into the packet 1273 * Set length into the packet
@@ -1213,8 +1279,6 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1213 * receive ring. Pass the buffer to 1279 * receive ring. Pass the buffer to
1214 * the kernel 1280 * the kernel
1215 */ 1281 */
1216 sc->sbm_stats.rx_bytes += len;
1217 sc->sbm_stats.rx_packets++;
1218 sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); 1282 sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev);
1219 /* Check hw IPv4/TCP checksum if supported */ 1283 /* Check hw IPv4/TCP checksum if supported */
1220 if (sc->rx_hw_checksum == ENABLE) { 1284 if (sc->rx_hw_checksum == ENABLE) {
@@ -1226,8 +1290,22 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1226 sb->ip_summed = CHECKSUM_NONE; 1290 sb->ip_summed = CHECKSUM_NONE;
1227 } 1291 }
1228 } 1292 }
1229 1293 prefetch(sb->data);
1230 netif_rx(sb); 1294 prefetch((const void *)(((char *)sb->data)+32));
1295 if (poll)
1296 dropped = netif_receive_skb(sb);
1297 else
1298 dropped = netif_rx(sb);
1299
1300 if (dropped == NET_RX_DROP) {
1301 sc->sbm_stats.rx_dropped++;
1302 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
1303 goto done;
1304 }
1305 else {
1306 sc->sbm_stats.rx_bytes += len;
1307 sc->sbm_stats.rx_packets++;
1308 }
1231 } 1309 }
1232 } else { 1310 } else {
1233 /* 1311 /*
@@ -1244,12 +1322,16 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1244 */ 1322 */
1245 1323
1246 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); 1324 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
1247 1325 work_done++;
1248 } 1326 }
1327 if (!poll) {
1328 work_to_do = 32;
1329 goto again; /* collect fifo drop statistics again */
1330 }
1331done:
1332 return work_done;
1249} 1333}
1250 1334
1251
1252
1253/********************************************************************** 1335/**********************************************************************
1254 * SBDMA_TX_PROCESS(sc,d) 1336 * SBDMA_TX_PROCESS(sc,d)
1255 * 1337 *
@@ -1261,22 +1343,30 @@ static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1261 * 1343 *
1262 * Input parameters: 1344 * Input parameters:
1263 * sc - softc structure 1345 * sc - softc structure
1264 * d - DMA channel context 1346 * d - DMA channel context
1347 * poll - 1: using polling (for NAPI)
1265 * 1348 *
1266 * Return value: 1349 * Return value:
1267 * nothing 1350 * nothing
1268 ********************************************************************* */ 1351 ********************************************************************* */
1269 1352
1270static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d) 1353static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
1271{ 1354{
1272 int curidx; 1355 int curidx;
1273 int hwidx; 1356 int hwidx;
1274 sbdmadscr_t *dsc; 1357 sbdmadscr_t *dsc;
1275 struct sk_buff *sb; 1358 struct sk_buff *sb;
1276 unsigned long flags; 1359 unsigned long flags;
1360 int packets_handled = 0;
1277 1361
1278 spin_lock_irqsave(&(sc->sbm_lock), flags); 1362 spin_lock_irqsave(&(sc->sbm_lock), flags);
1279 1363
1364 if (d->sbdma_remptr == d->sbdma_addptr)
1365 goto end_unlock;
1366
1367 hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
1368 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
1369
1280 for (;;) { 1370 for (;;) {
1281 /* 1371 /*
1282 * figure out where we are (as an index) and where 1372 * figure out where we are (as an index) and where
@@ -1290,8 +1380,6 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1290 */ 1380 */
1291 1381
1292 curidx = d->sbdma_remptr - d->sbdma_dscrtable; 1382 curidx = d->sbdma_remptr - d->sbdma_dscrtable;
1293 hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
1294 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
1295 1383
1296 /* 1384 /*
1297 * If they're the same, that means we've processed all 1385 * If they're the same, that means we've processed all
@@ -1329,6 +1417,8 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1329 1417
1330 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); 1418 d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
1331 1419
1420 packets_handled++;
1421
1332 } 1422 }
1333 1423
1334 /* 1424 /*
@@ -1337,8 +1427,10 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
1337 * watermark on the transmit queue. 1427 * watermark on the transmit queue.
1338 */ 1428 */
1339 1429
1340 netif_wake_queue(d->sbdma_eth->sbm_dev); 1430 if (packets_handled)
1431 netif_wake_queue(d->sbdma_eth->sbm_dev);
1341 1432
1433end_unlock:
1342 spin_unlock_irqrestore(&(sc->sbm_lock), flags); 1434 spin_unlock_irqrestore(&(sc->sbm_lock), flags);
1343 1435
1344} 1436}
@@ -1412,9 +1504,9 @@ static int sbmac_initctx(struct sbmac_softc *s)
1412 1504
1413static void sbdma_uninitctx(struct sbmacdma_s *d) 1505static void sbdma_uninitctx(struct sbmacdma_s *d)
1414{ 1506{
1415 if (d->sbdma_dscrtable) { 1507 if (d->sbdma_dscrtable_unaligned) {
1416 kfree(d->sbdma_dscrtable); 1508 kfree(d->sbdma_dscrtable_unaligned);
1417 d->sbdma_dscrtable = NULL; 1509 d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = NULL;
1418 } 1510 }
1419 1511
1420 if (d->sbdma_ctxtable) { 1512 if (d->sbdma_ctxtable) {
@@ -1612,15 +1704,9 @@ static void sbmac_channel_start(struct sbmac_softc *s)
1612#endif 1704#endif
1613 1705
1614#ifdef CONFIG_SBMAC_COALESCE 1706#ifdef CONFIG_SBMAC_COALESCE
1615 /*
1616 * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
1617 */
1618 __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | 1707 __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
1619 ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr); 1708 ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
1620#else 1709#else
1621 /*
1622 * Accept any kind of interrupt on TX and RX DMA channel 0
1623 */
1624 __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | 1710 __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
1625 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr); 1711 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
1626#endif 1712#endif
@@ -2053,57 +2139,46 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
2053 uint64_t isr; 2139 uint64_t isr;
2054 int handled = 0; 2140 int handled = 0;
2055 2141
2056 for (;;) { 2142 /*
2057 2143 * Read the ISR (this clears the bits in the real
2058 /* 2144 * register, except for counter addr)
2059 * Read the ISR (this clears the bits in the real 2145 */
2060 * register, except for counter addr)
2061 */
2062 2146
2063 isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; 2147 isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
2064 2148
2065 if (isr == 0) 2149 if (isr == 0)
2066 break; 2150 return IRQ_RETVAL(0);
2151 handled = 1;
2067 2152
2068 handled = 1; 2153 /*
2069 2154 * Transmits on channel 0
2070 /* 2155 */
2071 * Transmits on channel 0
2072 */
2073 2156
2074 if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) { 2157 if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
2075 sbdma_tx_process(sc,&(sc->sbm_txdma)); 2158 sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
2159#ifdef CONFIG_NETPOLL_TRAP
2160 if (netpoll_trap()) {
2161 if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
2162 __netif_schedule(dev);
2076 } 2163 }
2164#endif
2165 }
2077 2166
2078 /* 2167 if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
2079 * Receives on channel 0 2168 if (netif_rx_schedule_prep(dev)) {
2080 */ 2169 __raw_writeq(0, sc->sbm_imr);
2081 2170 __netif_rx_schedule(dev);
2082 /* 2171 /* Depend on the exit from poll to reenable intr */
2083 * It's important to test all the bits (or at least the 2172 }
2084 * EOP_SEEN bit) when deciding to do the RX process 2173 else {
2085 * particularly when coalescing, to make sure we 2174 /* may leave some packets behind */
2086 * take care of the following: 2175 sbdma_rx_process(sc,&(sc->sbm_rxdma),
2087 * 2176 SBMAC_MAX_RXDESCR * 2, 0);
2088 * If you have some packets waiting (have been received
2089 * but no interrupt) and get a TX interrupt before
2090 * the RX timer or counter expires, reading the ISR
2091 * above will clear the timer and counter, and you
2092 * won't get another interrupt until a packet shows
2093 * up to start the timer again. Testing
2094 * EOP_SEEN here takes care of this case.
2095 * (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0)
2096 */
2097
2098
2099 if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
2100 sbdma_rx_process(sc,&(sc->sbm_rxdma));
2101 } 2177 }
2102 } 2178 }
2103 return IRQ_RETVAL(handled); 2179 return IRQ_RETVAL(handled);
2104} 2180}
2105 2181
2106
2107/********************************************************************** 2182/**********************************************************************
2108 * SBMAC_START_TX(skb,dev) 2183 * SBMAC_START_TX(skb,dev)
2109 * 2184 *
@@ -2233,8 +2308,6 @@ static void sbmac_setmulti(struct sbmac_softc *sc)
2233 } 2308 }
2234} 2309}
2235 2310
2236
2237
2238#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) 2311#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
2239/********************************************************************** 2312/**********************************************************************
2240 * SBMAC_PARSE_XDIGIT(str) 2313 * SBMAC_PARSE_XDIGIT(str)
@@ -2397,8 +2470,13 @@ static int sbmac_init(struct net_device *dev, int idx)
2397 dev->do_ioctl = sbmac_mii_ioctl; 2470 dev->do_ioctl = sbmac_mii_ioctl;
2398 dev->tx_timeout = sbmac_tx_timeout; 2471 dev->tx_timeout = sbmac_tx_timeout;
2399 dev->watchdog_timeo = TX_TIMEOUT; 2472 dev->watchdog_timeo = TX_TIMEOUT;
2473 dev->poll = sbmac_poll;
2474 dev->weight = 16;
2400 2475
2401 dev->change_mtu = sb1250_change_mtu; 2476 dev->change_mtu = sb1250_change_mtu;
2477#ifdef CONFIG_NET_POLL_CONTROLLER
2478 dev->poll_controller = sbmac_netpoll;
2479#endif
2402 2480
2403 /* This is needed for PASS2 for Rx H/W checksum feature */ 2481 /* This is needed for PASS2 for Rx H/W checksum feature */
2404 sbmac_set_iphdr_offset(sc); 2482 sbmac_set_iphdr_offset(sc);
@@ -2796,7 +2874,39 @@ static int sbmac_close(struct net_device *dev)
2796 return 0; 2874 return 0;
2797} 2875}
2798 2876
2877static int sbmac_poll(struct net_device *dev, int *budget)
2878{
2879 int work_to_do;
2880 int work_done;
2881 struct sbmac_softc *sc = netdev_priv(dev);
2882
2883 work_to_do = min(*budget, dev->quota);
2884 work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), work_to_do, 1);
2799 2885
2886 if (work_done > work_to_do)
2887 printk(KERN_ERR "%s exceeded work_to_do budget=%d quota=%d work-done=%d\n",
2888 sc->sbm_dev->name, *budget, dev->quota, work_done);
2889
2890 sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
2891
2892 *budget -= work_done;
2893 dev->quota -= work_done;
2894
2895 if (work_done < work_to_do) {
2896 netif_rx_complete(dev);
2897
2898#ifdef CONFIG_SBMAC_COALESCE
2899 __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
2900 ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0),
2901 sc->sbm_imr);
2902#else
2903 __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
2904 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr);
2905#endif
2906 }
2907
2908 return (work_done >= work_to_do);
2909}
2800 2910
2801#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) 2911#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
2802static void 2912static void
@@ -2883,7 +2993,7 @@ sbmac_init_module(void)
2883 2993
2884 /* 2994 /*
2885 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero 2995 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
2886 * value for us by the firmware if we're going to use this MAC. 2996 * value for us by the firmware if we are going to use this MAC.
2887 * If we find a zero, skip this MAC. 2997 * If we find a zero, skip this MAC.
2888 */ 2998 */
2889 2999
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index d8c9c5d66d4f..1fc77300b055 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -624,7 +624,7 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
624 624
625#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) 625#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
626 626
627static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq) 627static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
628{ 628{
629 struct sgiseeq_init_block *sr; 629 struct sgiseeq_init_block *sr;
630 struct sgiseeq_private *sp; 630 struct sgiseeq_private *sp;
@@ -650,7 +650,9 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
650 650
651#define EADDR_NVOFS 250 651#define EADDR_NVOFS 250
652 for (i = 0; i < 3; i++) { 652 for (i = 0; i < 3; i++) {
653 unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); 653 unsigned short tmp = has_eeprom ?
654 ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) :
655 ip22_nvram_read(EADDR_NVOFS / 2+i);
654 656
655 dev->dev_addr[2 * i] = tmp >> 8; 657 dev->dev_addr[2 * i] = tmp >> 8;
656 dev->dev_addr[2 * i + 1] = tmp & 0xff; 658 dev->dev_addr[2 * i + 1] = tmp & 0xff;
@@ -683,6 +685,11 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
683 sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP | 685 sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
684 HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026; 686 HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
685 687
688 /* Setup PIO and DMA transfer timing */
689 sp->hregs->pconfig = 0x161;
690 sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
691 HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
692
686 /* Reset the chip. */ 693 /* Reset the chip. */
687 hpc3_eth_reset(sp->hregs); 694 hpc3_eth_reset(sp->hregs);
688 695
@@ -729,8 +736,23 @@ err_out:
729 736
730static int __init sgiseeq_probe(void) 737static int __init sgiseeq_probe(void)
731{ 738{
739 unsigned int tmp, ret1, ret2 = 0;
740
732 /* On board adapter on 1st HPC is always present */ 741 /* On board adapter on 1st HPC is always present */
733 return sgiseeq_init(hpc3c0, SGI_ENET_IRQ); 742 ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0);
743 /* Let's see if second HPC is there */
744 if (!(ip22_is_fullhouse()) &&
745 get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) {
746 sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 |
747 SGIMC_GIOPAR_EXP164 |
748 SGIMC_GIOPAR_HPC264;
749 hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
750 /* interrupt/config register on Challenge S Mezz board */
751 hpc3c1->pbus_extregs[0][0] = 0x30;
752 ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1);
753 }
754
755 return (ret1 & ret2) ? ret1 : 0;
734} 756}
735 757
736static void __exit sgiseeq_exit(void) 758static void __exit sgiseeq_exit(void)
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index e0a93005e6dc..bf218621db16 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -5123,7 +5123,12 @@ static int skge_resume(struct pci_dev *pdev)
5123 5123
5124 pci_set_power_state(pdev, PCI_D0); 5124 pci_set_power_state(pdev, PCI_D0);
5125 pci_restore_state(pdev); 5125 pci_restore_state(pdev);
5126 pci_enable_device(pdev); 5126 ret = pci_enable_device(pdev);
5127 if (ret) {
5128 printk(KERN_WARNING "sk98lin: unable to enable device %s "
5129 "in resume\n", dev->name);
5130 goto err_out;
5131 }
5127 pci_set_master(pdev); 5132 pci_set_master(pdev);
5128 if (pAC->GIni.GIMacsFound == 2) 5133 if (pAC->GIni.GIMacsFound == 2)
5129 ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); 5134 ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
@@ -5131,10 +5136,8 @@ static int skge_resume(struct pci_dev *pdev)
5131 ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); 5136 ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev);
5132 if (ret) { 5137 if (ret) {
5133 printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); 5138 printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
5134 pAC->AllocFlag &= ~SK_ALLOC_IRQ; 5139 ret = -EBUSY;
5135 dev->irq = 0; 5140 goto err_out_disable_pdev;
5136 pci_disable_device(pdev);
5137 return -EBUSY;
5138 } 5141 }
5139 5142
5140 netif_device_attach(dev); 5143 netif_device_attach(dev);
@@ -5151,6 +5154,13 @@ static int skge_resume(struct pci_dev *pdev)
5151 } 5154 }
5152 5155
5153 return 0; 5156 return 0;
5157
5158err_out_disable_pdev:
5159 pci_disable_device(pdev);
5160err_out:
5161 pAC->AllocFlag &= ~SK_ALLOC_IRQ;
5162 dev->irq = 0;
5163 return ret;
5154} 5164}
5155#else 5165#else
5156#define skge_suspend NULL 5166#define skge_suspend NULL
diff --git a/drivers/net/skfp/h/lnkstat.h b/drivers/net/skfp/h/lnkstat.h
deleted file mode 100644
index c73dcd96a40f..000000000000
--- a/drivers/net/skfp/h/lnkstat.h
+++ /dev/null
@@ -1,84 +0,0 @@
1/******************************************************************************
2 *
3 * (C)Copyright 1998,1999 SysKonnect,
4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * The information in this file is provided "AS IS" without warranty.
12 *
13 ******************************************************************************/
14
15/*
16 * Definition of the Error Log Structure
17 * This structure will be copied into the Error Log buffer
18 * during the NDIS General Request ReadErrorLog by the MAC Driver
19 */
20
21struct s_error_log {
22
23 /*
24 * place holder for token ring adapter error log (zeros)
25 */
26 u_char reserved_0 ; /* byte 0 inside Error Log */
27 u_char reserved_1 ; /* byte 1 */
28 u_char reserved_2 ; /* byte 2 */
29 u_char reserved_3 ; /* byte 3 */
30 u_char reserved_4 ; /* byte 4 */
31 u_char reserved_5 ; /* byte 5 */
32 u_char reserved_6 ; /* byte 6 */
33 u_char reserved_7 ; /* byte 7 */
34 u_char reserved_8 ; /* byte 8 */
35 u_char reserved_9 ; /* byte 9 */
36 u_char reserved_10 ; /* byte 10 */
37 u_char reserved_11 ; /* byte 11 */
38 u_char reserved_12 ; /* byte 12 */
39 u_char reserved_13 ; /* byte 13 */
40
41 /*
42 * FDDI link statistics
43 */
44/*
45 * smt error low
46 */
47#define SMT_ERL_AEB (1<<15) /* A elast. buffer */
48#define SMT_ERL_BLC (1<<14) /* B link error condition */
49#define SMT_ERL_ALC (1<<13) /* A link error condition */
50#define SMT_ERL_NCC (1<<12) /* not copied condition */
51#define SMT_ERL_FEC (1<<11) /* frame error condition */
52
53/*
54 * smt event low
55 */
56#define SMT_EVL_NCE (1<<5)
57
58 u_short smt_error_low ; /* byte 14/15 */
59 u_short smt_error_high ; /* byte 16/17 */
60 u_short smt_event_low ; /* byte 18/19 */
61 u_short smt_event_high ; /* byte 20/21 */
62 u_short connection_policy_violation ; /* byte 22/23 */
63 u_short port_event ; /* byte 24/25 */
64 u_short set_count_low ; /* byte 26/27 */
65 u_short set_count_high ; /* byte 28/29 */
66 u_short aci_id_code ; /* byte 30/31 */
67 u_short purge_frame_counter ; /* byte 32/33 */
68
69 /*
70 * CMT and RMT state machines
71 */
72 u_short ecm_state ; /* byte 34/35 */
73 u_short pcm_a_state ; /* byte 36/37 */
74 u_short pcm_b_state ; /* byte 38/39 */
75 u_short cfm_state ; /* byte 40/41 */
76 u_short rmt_state ; /* byte 42/43 */
77
78 u_short not_used[30] ; /* byte 44-103 */
79
80 u_short ucode_version_level ; /* byte 104/105 */
81
82 u_short not_used_1 ; /* byte 106/107 */
83 u_short not_used_2 ; /* byte 108/109 */
84} ;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index f1a0e6c0fbdd..21afe108d3cb 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -42,7 +42,7 @@
42#include "skge.h" 42#include "skge.h"
43 43
44#define DRV_NAME "skge" 44#define DRV_NAME "skge"
45#define DRV_VERSION "1.10" 45#define DRV_VERSION "1.11"
46#define PFX DRV_NAME " " 46#define PFX DRV_NAME " "
47 47
48#define DEFAULT_TX_RING_SIZE 128 48#define DEFAULT_TX_RING_SIZE 128
@@ -2621,6 +2621,7 @@ static int skge_down(struct net_device *dev)
2621 2621
2622static inline int skge_avail(const struct skge_ring *ring) 2622static inline int skge_avail(const struct skge_ring *ring)
2623{ 2623{
2624 smp_mb();
2624 return ((ring->to_clean > ring->to_use) ? 0 : ring->count) 2625 return ((ring->to_clean > ring->to_use) ? 0 : ring->count)
2625 + (ring->to_clean - ring->to_use) - 1; 2626 + (ring->to_clean - ring->to_use) - 1;
2626} 2627}
@@ -2709,6 +2710,8 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
2709 dev->name, e - skge->tx_ring.start, skb->len); 2710 dev->name, e - skge->tx_ring.start, skb->len);
2710 2711
2711 skge->tx_ring.to_use = e->next; 2712 skge->tx_ring.to_use = e->next;
2713 smp_wmb();
2714
2712 if (skge_avail(&skge->tx_ring) <= TX_LOW_WATER) { 2715 if (skge_avail(&skge->tx_ring) <= TX_LOW_WATER) {
2713 pr_debug("%s: transmit queue full\n", dev->name); 2716 pr_debug("%s: transmit queue full\n", dev->name);
2714 netif_stop_queue(dev); 2717 netif_stop_queue(dev);
@@ -2726,8 +2729,6 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
2726{ 2729{
2727 struct pci_dev *pdev = skge->hw->pdev; 2730 struct pci_dev *pdev = skge->hw->pdev;
2728 2731
2729 BUG_ON(!e->skb);
2730
2731 /* skb header vs. fragment */ 2732 /* skb header vs. fragment */
2732 if (control & BMU_STF) 2733 if (control & BMU_STF)
2733 pci_unmap_single(pdev, pci_unmap_addr(e, mapaddr), 2734 pci_unmap_single(pdev, pci_unmap_addr(e, mapaddr),
@@ -2745,7 +2746,6 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
2745 2746
2746 dev_kfree_skb(e->skb); 2747 dev_kfree_skb(e->skb);
2747 } 2748 }
2748 e->skb = NULL;
2749} 2749}
2750 2750
2751/* Free all buffers in transmit ring */ 2751/* Free all buffers in transmit ring */
@@ -3017,21 +3017,29 @@ static void skge_tx_done(struct net_device *dev)
3017 3017
3018 skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); 3018 skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
3019 3019
3020 netif_tx_lock(dev);
3021 for (e = ring->to_clean; e != ring->to_use; e = e->next) { 3020 for (e = ring->to_clean; e != ring->to_use; e = e->next) {
3022 struct skge_tx_desc *td = e->desc; 3021 u32 control = ((const struct skge_tx_desc *) e->desc)->control;
3023 3022
3024 if (td->control & BMU_OWN) 3023 if (control & BMU_OWN)
3025 break; 3024 break;
3026 3025
3027 skge_tx_free(skge, e, td->control); 3026 skge_tx_free(skge, e, control);
3028 } 3027 }
3029 skge->tx_ring.to_clean = e; 3028 skge->tx_ring.to_clean = e;
3030 3029
3031 if (skge_avail(&skge->tx_ring) > TX_LOW_WATER) 3030 /* Can run lockless until we need to synchronize to restart queue. */
3032 netif_wake_queue(dev); 3031 smp_mb();
3032
3033 if (unlikely(netif_queue_stopped(dev) &&
3034 skge_avail(&skge->tx_ring) > TX_LOW_WATER)) {
3035 netif_tx_lock(dev);
3036 if (unlikely(netif_queue_stopped(dev) &&
3037 skge_avail(&skge->tx_ring) > TX_LOW_WATER)) {
3038 netif_wake_queue(dev);
3033 3039
3034 netif_tx_unlock(dev); 3040 }
3041 netif_tx_unlock(dev);
3042 }
3035} 3043}
3036 3044
3037static int skge_poll(struct net_device *dev, int *budget) 3045static int skge_poll(struct net_device *dev, int *budget)
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 86467ae74d45..edd71468220c 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -232,7 +232,6 @@ enum {
232 IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */ 232 IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */
233 233
234 IS_ERR_MSK = IS_IRQ_MST_ERR | IS_IRQ_STAT 234 IS_ERR_MSK = IS_IRQ_MST_ERR | IS_IRQ_STAT
235 | IS_NO_STAT_M1 | IS_NO_STAT_M2
236 | IS_RAM_RD_PAR | IS_RAM_WR_PAR 235 | IS_RAM_RD_PAR | IS_RAM_WR_PAR
237 | IS_M1_PAR_ERR | IS_M2_PAR_ERR 236 | IS_M1_PAR_ERR | IS_M2_PAR_ERR
238 | IS_R1_PAR_ERR | IS_R2_PAR_ERR, 237 | IS_R1_PAR_ERR | IS_R2_PAR_ERR,
@@ -2447,15 +2446,15 @@ enum pause_status {
2447 2446
2448 2447
2449struct skge_port { 2448struct skge_port {
2450 u32 msg_enable;
2451 struct skge_hw *hw; 2449 struct skge_hw *hw;
2452 struct net_device *netdev; 2450 struct net_device *netdev;
2453 int port; 2451 int port;
2452 u32 msg_enable;
2454 2453
2455 struct skge_ring tx_ring; 2454 struct skge_ring tx_ring;
2456 struct skge_ring rx_ring;
2457 2455
2458 struct net_device_stats net_stats; 2456 struct skge_ring rx_ring ____cacheline_aligned_in_smp;
2457 unsigned int rx_buf_size;
2459 2458
2460 struct timer_list link_timer; 2459 struct timer_list link_timer;
2461 enum pause_control flow_control; 2460 enum pause_control flow_control;
@@ -2471,7 +2470,8 @@ struct skge_port {
2471 void *mem; /* PCI memory for rings */ 2470 void *mem; /* PCI memory for rings */
2472 dma_addr_t dma; 2471 dma_addr_t dma;
2473 unsigned long mem_size; 2472 unsigned long mem_size;
2474 unsigned int rx_buf_size; 2473
2474 struct net_device_stats net_stats;
2475}; 2475};
2476 2476
2477 2477
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 8a2109a913b6..81f24847c963 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -499,7 +499,7 @@ static inline void smc911x_rcv(struct net_device *dev)
499 SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); 499 SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_));
500 SMC_PULL_DATA(data, pkt_len+2+3); 500 SMC_PULL_DATA(data, pkt_len+2+3);
501 501
502 DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name,); 502 DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name);
503 PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); 503 PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64);
504 dev->last_rx = jiffies; 504 dev->last_rx = jiffies;
505 skb->protocol = eth_type_trans(skb, dev); 505 skb->protocol = eth_type_trans(skb, dev);
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index d7741e23f8de..f1e2dfc795a2 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1,35 +1,34 @@
1/* tc35815.c: A TOSHIBA TC35815CF PCI 10/100Mbps ethernet driver for linux. 1/*
2 * 2 * tc35815.c: A TOSHIBA TC35815CF PCI 10/100Mbps ethernet driver for linux.
3 * Copyright 2001 MontaVista Software Inc.
4 * Author: MontaVista Software, Inc.
5 * ahennessy@mvista.com
6 * 3 *
7 * Based on skelton.c by Donald Becker. 4 * Based on skelton.c by Donald Becker.
8 * Copyright (C) 2000-2001 Toshiba Corporation
9 * 5 *
10 * This program is free software; you can redistribute it and/or modify it 6 * This driver is a replacement of older and less maintained version.
11 * under the terms of the GNU General Public License as published by the 7 * This is a header of the older version:
12 * Free Software Foundation; either version 2 of the License, or (at your 8 * -----<snip>-----
13 * option) any later version. 9 * Copyright 2001 MontaVista Software Inc.
10 * Author: MontaVista Software, Inc.
11 * ahennessy@mvista.com
12 * Copyright (C) 2000-2001 Toshiba Corporation
13 * static const char *version =
14 * "tc35815.c:v0.00 26/07/2000 by Toshiba Corporation\n";
15 * -----<snip>-----
14 * 16 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * This file is subject to the terms and conditions of the GNU General Public
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * License. See the file "COPYING" in the main directory of this archive
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * for more details.
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * 20 *
26 * You should have received a copy of the GNU General Public License along 21 * (C) Copyright TOSHIBA CORPORATION 2004-2005
27 * with this program; if not, write to the Free Software Foundation, Inc., 22 * All Rights Reserved.
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */ 23 */
30 24
31static const char *version = 25#ifdef TC35815_NAPI
32 "tc35815.c:v0.00 26/07/2000 by Toshiba Corporation\n"; 26#define DRV_VERSION "1.35-NAPI"
27#else
28#define DRV_VERSION "1.35"
29#endif
30static const char *version = "tc35815.c:v" DRV_VERSION "\n";
31#define MODNAME "tc35815"
33 32
34#include <linux/module.h> 33#include <linux/module.h>
35#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -40,6 +39,7 @@ static const char *version =
40#include <linux/in.h> 39#include <linux/in.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/spinlock.h>
43#include <linux/errno.h> 43#include <linux/errno.h>
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/netdevice.h> 45#include <linux/netdevice.h>
@@ -47,36 +47,47 @@ static const char *version =
47#include <linux/skbuff.h> 47#include <linux/skbuff.h>
48#include <linux/delay.h> 48#include <linux/delay.h>
49#include <linux/pci.h> 49#include <linux/pci.h>
50#include <linux/proc_fs.h> 50#include <linux/mii.h>
51#include <linux/spinlock.h> 51#include <linux/ethtool.h>
52#include <linux/bitops.h>
53
54#include <asm/system.h>
55#include <asm/io.h> 52#include <asm/io.h>
56#include <asm/dma.h>
57#include <asm/byteorder.h> 53#include <asm/byteorder.h>
58 54
59/*
60 * The name of the card. Is used for messages and in the requests for
61 * io regions, irqs and dma channels
62 */
63static const char* cardname = "TC35815CF";
64#define TC35815_PROC_ENTRY "net/tc35815"
65
66#define TC35815_MODULE_NAME "TC35815CF"
67#define TX_TIMEOUT (4*HZ)
68
69/* First, a few definitions that the brave might change. */ 55/* First, a few definitions that the brave might change. */
70 56
71/* use 0 for production, 1 for verification, >2 for debug */
72#ifndef TC35815_DEBUG
73#define TC35815_DEBUG 1
74#endif
75static unsigned int tc35815_debug = TC35815_DEBUG;
76
77#define GATHER_TXINT /* On-Demand Tx Interrupt */ 57#define GATHER_TXINT /* On-Demand Tx Interrupt */
58#define WORKAROUND_LOSTCAR
59#define WORKAROUND_100HALF_PROMISC
60/* #define TC35815_USE_PACKEDBUFFER */
61
62typedef enum {
63 TC35815CF = 0,
64 TC35815_NWU,
65 TC35815_TX4939,
66} board_t;
67
68/* indexed by board_t, above */
69static const struct {
70 const char *name;
71} board_info[] __devinitdata = {
72 { "TOSHIBA TC35815CF 10/100BaseTX" },
73 { "TOSHIBA TC35815 with Wake on LAN" },
74 { "TOSHIBA TC35815/TX4939" },
75};
76
77static const struct pci_device_id tc35815_pci_tbl[] = {
78 {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815CF), .driver_data = TC35815CF },
79 {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_NWU), .driver_data = TC35815_NWU },
80 {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939), .driver_data = TC35815_TX4939 },
81 {0,}
82};
83MODULE_DEVICE_TABLE (pci, tc35815_pci_tbl);
78 84
79#define vtonocache(p) KSEG1ADDR(virt_to_phys(p)) 85/* see MODULE_PARM_DESC */
86static struct tc35815_options {
87 int speed;
88 int duplex;
89 int doforce;
90} options;
80 91
81/* 92/*
82 * Registers 93 * Registers
@@ -119,6 +130,11 @@ struct tc35815_regs {
119 * Bit assignments 130 * Bit assignments
120 */ 131 */
121/* DMA_Ctl bit asign ------------------------------------------------------- */ 132/* DMA_Ctl bit asign ------------------------------------------------------- */
133#define DMA_RxAlign 0x00c00000 /* 1:Reception Alignment */
134#define DMA_RxAlign_1 0x00400000
135#define DMA_RxAlign_2 0x00800000
136#define DMA_RxAlign_3 0x00c00000
137#define DMA_M66EnStat 0x00080000 /* 1:66MHz Enable State */
122#define DMA_IntMask 0x00040000 /* 1:Interupt mask */ 138#define DMA_IntMask 0x00040000 /* 1:Interupt mask */
123#define DMA_SWIntReq 0x00020000 /* 1:Software Interrupt request */ 139#define DMA_SWIntReq 0x00020000 /* 1:Software Interrupt request */
124#define DMA_TxWakeUp 0x00010000 /* 1:Transmit Wake Up */ 140#define DMA_TxWakeUp 0x00010000 /* 1:Transmit Wake Up */
@@ -269,42 +285,6 @@ struct tc35815_regs {
269#define MD_CA_Wr 0x00000400 /* 1:Write 0:Read */ 285#define MD_CA_Wr 0x00000400 /* 1:Write 0:Read */
270 286
271 287
272/* MII register offsets */
273#define MII_CONTROL 0x0000
274#define MII_STATUS 0x0001
275#define MII_PHY_ID0 0x0002
276#define MII_PHY_ID1 0x0003
277#define MII_ANAR 0x0004
278#define MII_ANLPAR 0x0005
279#define MII_ANER 0x0006
280/* MII Control register bit definitions. */
281#define MIICNTL_FDX 0x0100
282#define MIICNTL_RST_AUTO 0x0200
283#define MIICNTL_ISOLATE 0x0400
284#define MIICNTL_PWRDWN 0x0800
285#define MIICNTL_AUTO 0x1000
286#define MIICNTL_SPEED 0x2000
287#define MIICNTL_LPBK 0x4000
288#define MIICNTL_RESET 0x8000
289/* MII Status register bit significance. */
290#define MIISTAT_EXT 0x0001
291#define MIISTAT_JAB 0x0002
292#define MIISTAT_LINK 0x0004
293#define MIISTAT_CAN_AUTO 0x0008
294#define MIISTAT_FAULT 0x0010
295#define MIISTAT_AUTO_DONE 0x0020
296#define MIISTAT_CAN_T 0x0800
297#define MIISTAT_CAN_T_FDX 0x1000
298#define MIISTAT_CAN_TX 0x2000
299#define MIISTAT_CAN_TX_FDX 0x4000
300#define MIISTAT_CAN_T4 0x8000
301/* MII Auto-Negotiation Expansion/RemoteEnd Register Bits */
302#define MII_AN_TX_FDX 0x0100
303#define MII_AN_TX_HDX 0x0080
304#define MII_AN_10_FDX 0x0040
305#define MII_AN_10_HDX 0x0020
306
307
308/* 288/*
309 * Descriptors 289 * Descriptors
310 */ 290 */
@@ -352,32 +332,51 @@ struct BDesc {
352 332
353#ifdef NO_CHECK_CARRIER 333#ifdef NO_CHECK_CARRIER
354#define TX_CTL_CMD (Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \ 334#define TX_CTL_CMD (Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
355 Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \ 335 Tx_EnExColl | Tx_EnExDefer | Tx_EnUnder | \
356 Tx_En) /* maybe 0x7d01 */ 336 Tx_En) /* maybe 0x7b01 */
357#else 337#else
358#define TX_CTL_CMD (Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \ 338#define TX_CTL_CMD (Tx_EnComp | Tx_EnTxPar | Tx_EnLateColl | \
359 Tx_EnExColl | Tx_EnExDefer | Tx_EnUnder | \ 339 Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \
360 Tx_En) /* maybe 0x7f01 */ 340 Tx_En) /* maybe 0x7b01 */
361#endif 341#endif
362#define RX_CTL_CMD (Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \ 342#define RX_CTL_CMD (Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \
363 | Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn) /* maybe 0x6f01 */ 343 | Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn) /* maybe 0x6f01 */
364
365#define INT_EN_CMD (Int_NRAbtEn | \ 344#define INT_EN_CMD (Int_NRAbtEn | \
366 Int_DParDEn | Int_DParErrEn | \ 345 Int_DmParErrEn | Int_DParDEn | Int_DParErrEn | \
367 Int_SSysErrEn | Int_RMasAbtEn | Int_RTargAbtEn | \ 346 Int_SSysErrEn | Int_RMasAbtEn | Int_RTargAbtEn | \
368 Int_STargAbtEn | \ 347 Int_STargAbtEn | \
369 Int_BLExEn | Int_FDAExEn) /* maybe 0xb7f*/ 348 Int_BLExEn | Int_FDAExEn) /* maybe 0xb7f*/
349#define DMA_CTL_CMD DMA_BURST_SIZE
350#define HAVE_DMA_RXALIGN(lp) likely((lp)->boardtype != TC35815CF)
370 351
371/* Tuning parameters */ 352/* Tuning parameters */
372#define DMA_BURST_SIZE 32 353#define DMA_BURST_SIZE 32
373#define TX_THRESHOLD 1024 354#define TX_THRESHOLD 1024
355#define TX_THRESHOLD_MAX 1536 /* used threshold with packet max byte for low pci transfer ability.*/
356#define TX_THRESHOLD_KEEP_LIMIT 10 /* setting threshold max value when overrun error occured this count. */
374 357
358/* 16 + RX_BUF_NUM * 8 + RX_FD_NUM * 16 + TX_FD_NUM * 32 <= PAGE_SIZE*FD_PAGE_NUM */
359#ifdef TC35815_USE_PACKEDBUFFER
375#define FD_PAGE_NUM 2 360#define FD_PAGE_NUM 2
376#define FD_PAGE_ORDER 1 361#define RX_BUF_NUM 8 /* >= 2 */
377/* 16 + RX_BUF_PAGES * 8 + RX_FD_NUM * 16 + TX_FD_NUM * 32 <= PAGE_SIZE*2 */
378#define RX_BUF_PAGES 8 /* >= 2 */
379#define RX_FD_NUM 250 /* >= 32 */ 362#define RX_FD_NUM 250 /* >= 32 */
380#define TX_FD_NUM 128 363#define TX_FD_NUM 128
364#define RX_BUF_SIZE PAGE_SIZE
365#else /* TC35815_USE_PACKEDBUFFER */
366#define FD_PAGE_NUM 4
367#define RX_BUF_NUM 128 /* < 256 */
368#define RX_FD_NUM 256 /* >= 32 */
369#define TX_FD_NUM 128
370#if RX_CTL_CMD & Rx_LongEn
371#define RX_BUF_SIZE PAGE_SIZE
372#elif RX_CTL_CMD & Rx_StripCRC
373#define RX_BUF_SIZE ALIGN(ETH_FRAME_LEN + 4 + 2, 32) /* +2: reserve */
374#else
375#define RX_BUF_SIZE ALIGN(ETH_FRAME_LEN + 2, 32) /* +2: reserve */
376#endif
377#endif /* TC35815_USE_PACKEDBUFFER */
378#define RX_FD_RESERVE (2 / 2) /* max 2 BD per RxFD */
379#define NAPI_WEIGHT 16
381 380
382struct TxFD { 381struct TxFD {
383 struct FDesc fd; 382 struct FDesc fd;
@@ -392,18 +391,27 @@ struct RxFD {
392 391
393struct FrFD { 392struct FrFD {
394 struct FDesc fd; 393 struct FDesc fd;
395 struct BDesc bd[RX_BUF_PAGES]; 394 struct BDesc bd[RX_BUF_NUM];
396}; 395};
397 396
398 397
399extern unsigned long tc_readl(volatile __u32 *addr); 398#define tc_readl(addr) readl(addr)
400extern void tc_writel(unsigned long data, volatile __u32 *addr); 399#define tc_writel(d, addr) writel(d, addr)
400
401#define TC35815_TX_TIMEOUT msecs_to_jiffies(400)
401 402
402dma_addr_t priv_dma_handle; 403/* Timer state engine. */
404enum tc35815_timer_state {
405 arbwait = 0, /* Waiting for auto negotiation to complete. */
406 lupwait = 1, /* Auto-neg complete, awaiting link-up status. */
407 ltrywait = 2, /* Forcing try of all modes, from fastest to slowest. */
408 asleep = 3, /* Time inactive. */
409 lcheck = 4, /* Check link status. */
410};
403 411
404/* Information that need to be kept for each board. */ 412/* Information that need to be kept for each board. */
405struct tc35815_local { 413struct tc35815_local {
406 struct net_device *next_module; 414 struct pci_dev *pci_dev;
407 415
408 /* statistics */ 416 /* statistics */
409 struct net_device_stats stats; 417 struct net_device_stats stats;
@@ -411,216 +419,372 @@ struct tc35815_local {
411 int max_tx_qlen; 419 int max_tx_qlen;
412 int tx_ints; 420 int tx_ints;
413 int rx_ints; 421 int rx_ints;
422 int tx_underrun;
414 } lstats; 423 } lstats;
415 424
416 int tbusy; 425 /* Tx control lock. This protects the transmit buffer ring
417 int option; 426 * state along with the "tx full" state of the driver. This
418#define TC35815_OPT_AUTO 0x00 427 * means all netif_queue flow control actions are protected
419#define TC35815_OPT_10M 0x01 428 * by this lock as well.
420#define TC35815_OPT_100M 0x02 429 */
421#define TC35815_OPT_FULLDUP 0x04 430 spinlock_t lock;
422 int linkspeed; /* 10 or 100 */ 431
432 int phy_addr;
423 int fullduplex; 433 int fullduplex;
434 unsigned short saved_lpa;
435 struct timer_list timer;
436 enum tc35815_timer_state timer_state; /* State of auto-neg timer. */
437 unsigned int timer_ticks; /* Number of clicks at each state */
424 438
425 /* 439 /*
426 * Transmitting: Batch Mode. 440 * Transmitting: Batch Mode.
427 * 1 BD in 1 TxFD. 441 * 1 BD in 1 TxFD.
428 * Receiving: Packing Mode. 442 * Receiving: Packing Mode. (TC35815_USE_PACKEDBUFFER)
429 * 1 circular FD for Free Buffer List. 443 * 1 circular FD for Free Buffer List.
430 * RX_BUG_PAGES BD in Free Buffer FD. 444 * RX_BUF_NUM BD in Free Buffer FD.
431 * One Free Buffer BD has PAGE_SIZE data buffer. 445 * One Free Buffer BD has PAGE_SIZE data buffer.
446 * Or Non-Packing Mode.
447 * 1 circular FD for Free Buffer List.
448 * RX_BUF_NUM BD in Free Buffer FD.
449 * One Free Buffer BD has ETH_FRAME_LEN data buffer.
432 */ 450 */
433 struct pci_dev *pdev; 451 void * fd_buf; /* for TxFD, RxFD, FrFD */
434 dma_addr_t fd_buf_dma_handle; 452 dma_addr_t fd_buf_dma;
435 void * fd_buf; /* for TxFD, TxFD, FrFD */
436 struct TxFD *tfd_base; 453 struct TxFD *tfd_base;
437 int tfd_start; 454 unsigned int tfd_start;
438 int tfd_end; 455 unsigned int tfd_end;
439 struct RxFD *rfd_base; 456 struct RxFD *rfd_base;
440 struct RxFD *rfd_limit; 457 struct RxFD *rfd_limit;
441 struct RxFD *rfd_cur; 458 struct RxFD *rfd_cur;
442 struct FrFD *fbl_ptr; 459 struct FrFD *fbl_ptr;
460#ifdef TC35815_USE_PACKEDBUFFER
443 unsigned char fbl_curid; 461 unsigned char fbl_curid;
444 dma_addr_t data_buf_dma_handle[RX_BUF_PAGES]; 462 void * data_buf[RX_BUF_NUM]; /* packing */
445 void * data_buf[RX_BUF_PAGES]; /* packing */ 463 dma_addr_t data_buf_dma[RX_BUF_NUM];
446 spinlock_t lock; 464 struct {
465 struct sk_buff *skb;
466 dma_addr_t skb_dma;
467 } tx_skbs[TX_FD_NUM];
468#else
469 unsigned int fbl_count;
470 struct {
471 struct sk_buff *skb;
472 dma_addr_t skb_dma;
473 } tx_skbs[TX_FD_NUM], rx_skbs[RX_BUF_NUM];
474#endif
475 struct mii_if_info mii;
476 unsigned short mii_id[2];
477 u32 msg_enable;
478 board_t boardtype;
447}; 479};
448 480
449/* Index to functions, as function prototypes. */ 481static inline dma_addr_t fd_virt_to_bus(struct tc35815_local *lp, void *virt)
482{
483 return lp->fd_buf_dma + ((u8 *)virt - (u8 *)lp->fd_buf);
484}
485#ifdef DEBUG
486static inline void *fd_bus_to_virt(struct tc35815_local *lp, dma_addr_t bus)
487{
488 return (void *)((u8 *)lp->fd_buf + (bus - lp->fd_buf_dma));
489}
490#endif
491#ifdef TC35815_USE_PACKEDBUFFER
492static inline void *rxbuf_bus_to_virt(struct tc35815_local *lp, dma_addr_t bus)
493{
494 int i;
495 for (i = 0; i < RX_BUF_NUM; i++) {
496 if (bus >= lp->data_buf_dma[i] &&
497 bus < lp->data_buf_dma[i] + PAGE_SIZE)
498 return (void *)((u8 *)lp->data_buf[i] +
499 (bus - lp->data_buf_dma[i]));
500 }
501 return NULL;
502}
450 503
451static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq); 504#define TC35815_DMA_SYNC_ONDEMAND
505static void* alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle)
506{
507#ifdef TC35815_DMA_SYNC_ONDEMAND
508 void *buf;
509 /* pci_map + pci_dma_sync will be more effective than
510 * pci_alloc_consistent on some archs. */
511 if ((buf = (void *)__get_free_page(GFP_ATOMIC)) == NULL)
512 return NULL;
513 *dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE,
514 PCI_DMA_FROMDEVICE);
515 if (pci_dma_mapping_error(*dma_handle)) {
516 free_page((unsigned long)buf);
517 return NULL;
518 }
519 return buf;
520#else
521 return pci_alloc_consistent(hwdev, PAGE_SIZE, dma_handle);
522#endif
523}
524
525static void free_rxbuf_page(struct pci_dev *hwdev, void *buf, dma_addr_t dma_handle)
526{
527#ifdef TC35815_DMA_SYNC_ONDEMAND
528 pci_unmap_single(hwdev, dma_handle, PAGE_SIZE, PCI_DMA_FROMDEVICE);
529 free_page((unsigned long)buf);
530#else
531 pci_free_consistent(hwdev, PAGE_SIZE, buf, dma_handle);
532#endif
533}
534#else /* TC35815_USE_PACKEDBUFFER */
535static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
536 struct pci_dev *hwdev,
537 dma_addr_t *dma_handle)
538{
539 struct sk_buff *skb;
540 skb = dev_alloc_skb(RX_BUF_SIZE);
541 if (!skb)
542 return NULL;
543 skb->dev = dev;
544 *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
545 PCI_DMA_FROMDEVICE);
546 if (pci_dma_mapping_error(*dma_handle)) {
547 dev_kfree_skb_any(skb);
548 return NULL;
549 }
550 skb_reserve(skb, 2); /* make IP header 4byte aligned */
551 return skb;
552}
553
554static void free_rxbuf_skb(struct pci_dev *hwdev, struct sk_buff *skb, dma_addr_t dma_handle)
555{
556 pci_unmap_single(hwdev, dma_handle, RX_BUF_SIZE,
557 PCI_DMA_FROMDEVICE);
558 dev_kfree_skb_any(skb);
559}
560#endif /* TC35815_USE_PACKEDBUFFER */
561
562/* Index to functions, as function prototypes. */
452 563
453static int tc35815_open(struct net_device *dev); 564static int tc35815_open(struct net_device *dev);
454static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev); 565static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
455static void tc35815_tx_timeout(struct net_device *dev); 566static irqreturn_t tc35815_interrupt(int irq, void *dev_id);
456static irqreturn_t tc35815_interrupt(int irq, void *dev_id); 567#ifdef TC35815_NAPI
568static int tc35815_rx(struct net_device *dev, int limit);
569static int tc35815_poll(struct net_device *dev, int *budget);
570#else
457static void tc35815_rx(struct net_device *dev); 571static void tc35815_rx(struct net_device *dev);
572#endif
458static void tc35815_txdone(struct net_device *dev); 573static void tc35815_txdone(struct net_device *dev);
459static int tc35815_close(struct net_device *dev); 574static int tc35815_close(struct net_device *dev);
460static struct net_device_stats *tc35815_get_stats(struct net_device *dev); 575static struct net_device_stats *tc35815_get_stats(struct net_device *dev);
461static void tc35815_set_multicast_list(struct net_device *dev); 576static void tc35815_set_multicast_list(struct net_device *dev);
577static void tc35815_tx_timeout(struct net_device *dev);
578static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
579#ifdef CONFIG_NET_POLL_CONTROLLER
580static void tc35815_poll_controller(struct net_device *dev);
581#endif
582static const struct ethtool_ops tc35815_ethtool_ops;
462 583
584/* Example routines you must write ;->. */
463static void tc35815_chip_reset(struct net_device *dev); 585static void tc35815_chip_reset(struct net_device *dev);
464static void tc35815_chip_init(struct net_device *dev); 586static void tc35815_chip_init(struct net_device *dev);
587static void tc35815_find_phy(struct net_device *dev);
465static void tc35815_phy_chip_init(struct net_device *dev); 588static void tc35815_phy_chip_init(struct net_device *dev);
466 589
467/* A list of all installed tc35815 devices. */ 590#ifdef DEBUG
468static struct net_device *root_tc35815_dev = NULL; 591static void panic_queues(struct net_device *dev);
592#endif
469 593
470/* 594static void tc35815_timer(unsigned long data);
471 * PCI device identifiers for "new style" Linux PCI Device Drivers 595static void tc35815_start_auto_negotiation(struct net_device *dev,
472 */ 596 struct ethtool_cmd *ep);
473static struct pci_device_id tc35815_pci_tbl[] = { 597static int tc_mdio_read(struct net_device *dev, int phy_id, int location);
474 { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 598static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
475 { 0, } 599 int val);
476};
477 600
478MODULE_DEVICE_TABLE (pci, tc35815_pci_tbl); 601static void __devinit tc35815_init_dev_addr (struct net_device *dev)
602{
603 struct tc35815_regs __iomem *tr =
604 (struct tc35815_regs __iomem *)dev->base_addr;
605 int i;
479 606
480int 607 /* dev_addr will be overwritten on NETDEV_REGISTER event */
481tc35815_probe(struct pci_dev *pdev, 608 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
482 const struct pci_device_id *ent) 609 ;
610 for (i = 0; i < 6; i += 2) {
611 unsigned short data;
612 tc_writel(PROM_Busy | PROM_Read | (i / 2 + 2), &tr->PROM_Ctl);
613 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
614 ;
615 data = tc_readl(&tr->PROM_Data);
616 dev->dev_addr[i] = data & 0xff;
617 dev->dev_addr[i+1] = data >> 8;
618 }
619}
620
621static int __devinit tc35815_init_one (struct pci_dev *pdev,
622 const struct pci_device_id *ent)
483{ 623{
484 int err = 0; 624 void __iomem *ioaddr = NULL;
485 int ret; 625 struct net_device *dev;
486 unsigned long pci_memaddr; 626 struct tc35815_local *lp;
487 unsigned int pci_irq_line; 627 int rc;
628 unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
629
630 static int printed_version;
631 if (!printed_version++) {
632 printk(version);
633 dev_printk(KERN_DEBUG, &pdev->dev,
634 "speed:%d duplex:%d doforce:%d\n",
635 options.speed, options.duplex, options.doforce);
636 }
488 637
489 printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device); 638 if (!pdev->irq) {
639 dev_warn(&pdev->dev, "no IRQ assigned.\n");
640 return -ENODEV;
641 }
490 642
491 err = pci_enable_device(pdev); 643 /* dev zeroed in alloc_etherdev */
492 if (err) 644 dev = alloc_etherdev (sizeof (*lp));
493 return err; 645 if (dev == NULL) {
646 dev_err(&pdev->dev, "unable to alloc new ethernet\n");
647 return -ENOMEM;
648 }
649 SET_MODULE_OWNER(dev);
650 SET_NETDEV_DEV(dev, &pdev->dev);
651 lp = dev->priv;
652
653 /* enable device (incl. PCI PM wakeup), and bus-mastering */
654 rc = pci_enable_device (pdev);
655 if (rc)
656 goto err_out;
494 657
495 pci_memaddr = pci_resource_start (pdev, 1); 658 mmio_start = pci_resource_start (pdev, 1);
659 mmio_end = pci_resource_end (pdev, 1);
660 mmio_flags = pci_resource_flags (pdev, 1);
661 mmio_len = pci_resource_len (pdev, 1);
496 662
497 printk(KERN_INFO " pci_memaddr=%#08lx resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0)); 663 /* set this immediately, we need to know before
664 * we talk to the chip directly */
498 665
499 if (!pci_memaddr) { 666 /* make sure PCI base addr 1 is MMIO */
500 printk(KERN_WARNING "no PCI MEM resources, aborting\n"); 667 if (!(mmio_flags & IORESOURCE_MEM)) {
501 ret = -ENODEV; 668 dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
669 rc = -ENODEV;
502 goto err_out; 670 goto err_out;
503 } 671 }
504 pci_irq_line = pdev->irq; 672
505 /* irq disabled. */ 673 /* check for weird/broken PCI region reporting */
506 if (pci_irq_line == 0) { 674 if ((mmio_len < sizeof(struct tc35815_regs))) {
507 printk(KERN_WARNING "no PCI irq, aborting\n"); 675 dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n");
508 ret = -ENODEV; 676 rc = -ENODEV;
509 goto err_out; 677 goto err_out;
510 } 678 }
511 679
512 ret = tc35815_probe1(pdev, pci_memaddr, pci_irq_line); 680 rc = pci_request_regions (pdev, MODNAME);
513 if (ret) 681 if (rc)
514 goto err_out; 682 goto err_out;
515 683
516 pci_set_master(pdev); 684 pci_set_master (pdev);
517
518 return 0;
519 685
520err_out: 686 /* ioremap MMIO region */
521 pci_disable_device(pdev); 687 ioaddr = ioremap (mmio_start, mmio_len);
522 return ret; 688 if (ioaddr == NULL) {
523} 689 dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
690 rc = -EIO;
691 goto err_out_free_res;
692 }
524 693
525static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq) 694 /* Initialize the device structure. */
526{ 695 dev->open = tc35815_open;
527 static unsigned version_printed = 0; 696 dev->hard_start_xmit = tc35815_send_packet;
528 int i, ret; 697 dev->stop = tc35815_close;
529 struct tc35815_local *lp; 698 dev->get_stats = tc35815_get_stats;
530 struct tc35815_regs *tr; 699 dev->set_multicast_list = tc35815_set_multicast_list;
531 struct net_device *dev; 700 dev->do_ioctl = tc35815_ioctl;
701 dev->ethtool_ops = &tc35815_ethtool_ops;
702 dev->tx_timeout = tc35815_tx_timeout;
703 dev->watchdog_timeo = TC35815_TX_TIMEOUT;
704#ifdef TC35815_NAPI
705 dev->poll = tc35815_poll;
706 dev->weight = NAPI_WEIGHT;
707#endif
708#ifdef CONFIG_NET_POLL_CONTROLLER
709 dev->poll_controller = tc35815_poll_controller;
710#endif
532 711
533 /* Allocate a new 'dev' if needed. */ 712 dev->irq = pdev->irq;
534 dev = alloc_etherdev(sizeof(struct tc35815_local)); 713 dev->base_addr = (unsigned long) ioaddr;
535 if (dev == NULL)
536 return -ENOMEM;
537 714
538 /* 715 /* dev->priv/lp zeroed and aligned in alloc_etherdev */
539 * alloc_etherdev allocs and zeros dev->priv
540 */
541 lp = dev->priv; 716 lp = dev->priv;
717 spin_lock_init(&lp->lock);
718 lp->pci_dev = pdev;
719 lp->boardtype = ent->driver_data;
542 720
543 if (tc35815_debug && version_printed++ == 0) 721 lp->msg_enable = NETIF_MSG_TX_ERR | NETIF_MSG_HW | NETIF_MSG_DRV | NETIF_MSG_LINK;
544 printk(KERN_DEBUG "%s", version); 722 pci_set_drvdata(pdev, dev);
545
546 /* Fill in the 'dev' fields. */
547 dev->irq = irq;
548 dev->base_addr = (unsigned long)ioremap(base_addr,
549 sizeof(struct tc35815_regs));
550 if (!dev->base_addr) {
551 ret = -ENOMEM;
552 goto err_out;
553 }
554 tr = (struct tc35815_regs*)dev->base_addr;
555 723
724 /* Soft reset the chip. */
556 tc35815_chip_reset(dev); 725 tc35815_chip_reset(dev);
557 726
558 /* Retrieve and print the ethernet address. */ 727 /* Retrieve the ethernet address. */
559 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) 728 tc35815_init_dev_addr(dev);
560 ; 729
561 for (i = 0; i < 6; i += 2) { 730 rc = register_netdev (dev);
562 unsigned short data; 731 if (rc)
563 tc_writel(PROM_Busy | PROM_Read | (i / 2 + 2), &tr->PROM_Ctl); 732 goto err_out_unmap;
564 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) 733
565 ; 734 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
566 data = tc_readl(&tr->PROM_Data); 735 printk(KERN_INFO "%s: %s at 0x%lx, "
567 dev->dev_addr[i] = data & 0xff; 736 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
568 dev->dev_addr[i+1] = data >> 8; 737 "IRQ %d\n",
569 } 738 dev->name,
739 board_info[ent->driver_data].name,
740 dev->base_addr,
741 dev->dev_addr[0], dev->dev_addr[1],
742 dev->dev_addr[2], dev->dev_addr[3],
743 dev->dev_addr[4], dev->dev_addr[5],
744 dev->irq);
745
746 setup_timer(&lp->timer, tc35815_timer, (unsigned long) dev);
747 lp->mii.dev = dev;
748 lp->mii.mdio_read = tc_mdio_read;
749 lp->mii.mdio_write = tc_mdio_write;
750 lp->mii.phy_id_mask = 0x1f;
751 lp->mii.reg_num_mask = 0x1f;
752 tc35815_find_phy(dev);
753 lp->mii.phy_id = lp->phy_addr;
754 lp->mii.full_duplex = 0;
755 lp->mii.force_media = 0;
570 756
571 /* Initialize the device structure. */ 757 return 0;
572 lp->pdev = pdev;
573 lp->next_module = root_tc35815_dev;
574 root_tc35815_dev = dev;
575 758
576 spin_lock_init(&lp->lock); 759err_out_unmap:
760 iounmap(ioaddr);
761err_out_free_res:
762 pci_release_regions (pdev);
763err_out:
764 free_netdev (dev);
765 return rc;
766}
577 767
578 if (dev->mem_start > 0) {
579 lp->option = dev->mem_start;
580 if ((lp->option & TC35815_OPT_10M) &&
581 (lp->option & TC35815_OPT_100M)) {
582 /* if both speed speficied, auto select. */
583 lp->option &= ~(TC35815_OPT_10M | TC35815_OPT_100M);
584 }
585 }
586 //XXX fixme
587 lp->option |= TC35815_OPT_10M;
588 768
589 /* do auto negotiation */ 769static void __devexit tc35815_remove_one (struct pci_dev *pdev)
590 tc35815_phy_chip_init(dev); 770{
771 struct net_device *dev = pci_get_drvdata (pdev);
772 unsigned long mmio_addr;
591 773
592 dev->open = tc35815_open; 774 mmio_addr = dev->base_addr;
593 dev->stop = tc35815_close;
594 dev->tx_timeout = tc35815_tx_timeout;
595 dev->watchdog_timeo = TX_TIMEOUT;
596 dev->hard_start_xmit = tc35815_send_packet;
597 dev->get_stats = tc35815_get_stats;
598 dev->set_multicast_list = tc35815_set_multicast_list;
599 SET_MODULE_OWNER(dev);
600 SET_NETDEV_DEV(dev, &pdev->dev);
601 775
602 ret = register_netdev(dev); 776 unregister_netdev (dev);
603 if (ret)
604 goto err_out_iounmap;
605 777
606 printk(KERN_INFO "%s: %s found at %#x, irq %d, MAC", 778 if (mmio_addr) {
607 dev->name, cardname, base_addr, irq); 779 iounmap ((void __iomem *)mmio_addr);
608 for (i = 0; i < 6; i++) 780 pci_release_regions (pdev);
609 printk(" %2.2x", dev->dev_addr[i]); 781 }
610 printk("\n");
611 printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
612 dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
613 782
614 return 0; 783 free_netdev (dev);
615 784
616err_out_iounmap: 785 pci_set_drvdata (pdev, NULL);
617 iounmap((void *) dev->base_addr);
618err_out:
619 free_netdev(dev);
620 return ret;
621} 786}
622 787
623
624static int 788static int
625tc35815_init_queues(struct net_device *dev) 789tc35815_init_queues(struct net_device *dev)
626{ 790{
@@ -629,44 +793,64 @@ tc35815_init_queues(struct net_device *dev)
629 unsigned long fd_addr; 793 unsigned long fd_addr;
630 794
631 if (!lp->fd_buf) { 795 if (!lp->fd_buf) {
632 if (sizeof(struct FDesc) + 796 BUG_ON(sizeof(struct FDesc) +
633 sizeof(struct BDesc) * RX_BUF_PAGES + 797 sizeof(struct BDesc) * RX_BUF_NUM +
634 sizeof(struct FDesc) * RX_FD_NUM + 798 sizeof(struct FDesc) * RX_FD_NUM +
635 sizeof(struct TxFD) * TX_FD_NUM > PAGE_SIZE * FD_PAGE_NUM) { 799 sizeof(struct TxFD) * TX_FD_NUM >
636 printk(KERN_WARNING "%s: Invalid Queue Size.\n", dev->name); 800 PAGE_SIZE * FD_PAGE_NUM);
637 return -ENOMEM;
638 }
639 801
640 if ((lp->fd_buf = (void *)__get_free_pages(GFP_KERNEL, FD_PAGE_ORDER)) == 0) 802 if ((lp->fd_buf = pci_alloc_consistent(lp->pci_dev, PAGE_SIZE * FD_PAGE_NUM, &lp->fd_buf_dma)) == 0)
641 return -ENOMEM; 803 return -ENOMEM;
642 for (i = 0; i < RX_BUF_PAGES; i++) { 804 for (i = 0; i < RX_BUF_NUM; i++) {
643 if ((lp->data_buf[i] = (void *)get_zeroed_page(GFP_KERNEL)) == 0) { 805#ifdef TC35815_USE_PACKEDBUFFER
806 if ((lp->data_buf[i] = alloc_rxbuf_page(lp->pci_dev, &lp->data_buf_dma[i])) == NULL) {
644 while (--i >= 0) { 807 while (--i >= 0) {
645 free_page((unsigned long)lp->data_buf[i]); 808 free_rxbuf_page(lp->pci_dev,
646 lp->data_buf[i] = 0; 809 lp->data_buf[i],
810 lp->data_buf_dma[i]);
811 lp->data_buf[i] = NULL;
647 } 812 }
648 free_page((unsigned long)lp->fd_buf); 813 pci_free_consistent(lp->pci_dev,
649 lp->fd_buf = 0; 814 PAGE_SIZE * FD_PAGE_NUM,
815 lp->fd_buf,
816 lp->fd_buf_dma);
817 lp->fd_buf = NULL;
818 return -ENOMEM;
819 }
820#else
821 lp->rx_skbs[i].skb =
822 alloc_rxbuf_skb(dev, lp->pci_dev,
823 &lp->rx_skbs[i].skb_dma);
824 if (!lp->rx_skbs[i].skb) {
825 while (--i >= 0) {
826 free_rxbuf_skb(lp->pci_dev,
827 lp->rx_skbs[i].skb,
828 lp->rx_skbs[i].skb_dma);
829 lp->rx_skbs[i].skb = NULL;
830 }
831 pci_free_consistent(lp->pci_dev,
832 PAGE_SIZE * FD_PAGE_NUM,
833 lp->fd_buf,
834 lp->fd_buf_dma);
835 lp->fd_buf = NULL;
650 return -ENOMEM; 836 return -ENOMEM;
651 } 837 }
652#ifdef __mips__
653 dma_cache_wback_inv((unsigned long)lp->data_buf[i], PAGE_SIZE * FD_PAGE_NUM);
654#endif 838#endif
655 } 839 }
656#ifdef __mips__ 840 printk(KERN_DEBUG "%s: FD buf %p DataBuf",
657 dma_cache_wback_inv((unsigned long)lp->fd_buf, PAGE_SIZE * FD_PAGE_NUM); 841 dev->name, lp->fd_buf);
842#ifdef TC35815_USE_PACKEDBUFFER
843 printk(" DataBuf");
844 for (i = 0; i < RX_BUF_NUM; i++)
845 printk(" %p", lp->data_buf[i]);
658#endif 846#endif
847 printk("\n");
659 } else { 848 } else {
660 memset(lp->fd_buf, 0, PAGE_SIZE * FD_PAGE_NUM); 849 for (i = 0; i < FD_PAGE_NUM; i++) {
661#ifdef __mips__ 850 clear_page((void *)((unsigned long)lp->fd_buf + i * PAGE_SIZE));
662 dma_cache_wback_inv((unsigned long)lp->fd_buf, PAGE_SIZE * FD_PAGE_NUM); 851 }
663#endif
664 } 852 }
665#ifdef __mips__
666 fd_addr = (unsigned long)vtonocache(lp->fd_buf);
667#else
668 fd_addr = (unsigned long)lp->fd_buf; 853 fd_addr = (unsigned long)lp->fd_buf;
669#endif
670 854
671 /* Free Descriptors (for Receive) */ 855 /* Free Descriptors (for Receive) */
672 lp->rfd_base = (struct RxFD *)fd_addr; 856 lp->rfd_base = (struct RxFD *)fd_addr;
@@ -675,34 +859,66 @@ tc35815_init_queues(struct net_device *dev)
675 lp->rfd_base[i].fd.FDCtl = cpu_to_le32(FD_CownsFD); 859 lp->rfd_base[i].fd.FDCtl = cpu_to_le32(FD_CownsFD);
676 } 860 }
677 lp->rfd_cur = lp->rfd_base; 861 lp->rfd_cur = lp->rfd_base;
678 lp->rfd_limit = (struct RxFD *)(fd_addr - 862 lp->rfd_limit = (struct RxFD *)fd_addr - (RX_FD_RESERVE + 1);
679 sizeof(struct FDesc) -
680 sizeof(struct BDesc) * 30);
681 863
682 /* Transmit Descriptors */ 864 /* Transmit Descriptors */
683 lp->tfd_base = (struct TxFD *)fd_addr; 865 lp->tfd_base = (struct TxFD *)fd_addr;
684 fd_addr += sizeof(struct TxFD) * TX_FD_NUM; 866 fd_addr += sizeof(struct TxFD) * TX_FD_NUM;
685 for (i = 0; i < TX_FD_NUM; i++) { 867 for (i = 0; i < TX_FD_NUM; i++) {
686 lp->tfd_base[i].fd.FDNext = cpu_to_le32(virt_to_bus(&lp->tfd_base[i+1])); 868 lp->tfd_base[i].fd.FDNext = cpu_to_le32(fd_virt_to_bus(lp, &lp->tfd_base[i+1]));
687 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0); 869 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0xffffffff);
688 lp->tfd_base[i].fd.FDCtl = cpu_to_le32(0); 870 lp->tfd_base[i].fd.FDCtl = cpu_to_le32(0);
689 } 871 }
690 lp->tfd_base[TX_FD_NUM-1].fd.FDNext = cpu_to_le32(virt_to_bus(&lp->tfd_base[0])); 872 lp->tfd_base[TX_FD_NUM-1].fd.FDNext = cpu_to_le32(fd_virt_to_bus(lp, &lp->tfd_base[0]));
691 lp->tfd_start = 0; 873 lp->tfd_start = 0;
692 lp->tfd_end = 0; 874 lp->tfd_end = 0;
693 875
694 /* Buffer List (for Receive) */ 876 /* Buffer List (for Receive) */
695 lp->fbl_ptr = (struct FrFD *)fd_addr; 877 lp->fbl_ptr = (struct FrFD *)fd_addr;
696 lp->fbl_ptr->fd.FDNext = cpu_to_le32(virt_to_bus(lp->fbl_ptr)); 878 lp->fbl_ptr->fd.FDNext = cpu_to_le32(fd_virt_to_bus(lp, lp->fbl_ptr));
697 lp->fbl_ptr->fd.FDCtl = cpu_to_le32(RX_BUF_PAGES | FD_CownsFD); 879 lp->fbl_ptr->fd.FDCtl = cpu_to_le32(RX_BUF_NUM | FD_CownsFD);
698 for (i = 0; i < RX_BUF_PAGES; i++) { 880#ifndef TC35815_USE_PACKEDBUFFER
699 lp->fbl_ptr->bd[i].BuffData = cpu_to_le32(virt_to_bus(lp->data_buf[i])); 881 /*
882 * move all allocated skbs to head of rx_skbs[] array.
883 * fbl_count mighe not be RX_BUF_NUM if alloc_rxbuf_skb() in
884 * tc35815_rx() had failed.
885 */
886 lp->fbl_count = 0;
887 for (i = 0; i < RX_BUF_NUM; i++) {
888 if (lp->rx_skbs[i].skb) {
889 if (i != lp->fbl_count) {
890 lp->rx_skbs[lp->fbl_count].skb =
891 lp->rx_skbs[i].skb;
892 lp->rx_skbs[lp->fbl_count].skb_dma =
893 lp->rx_skbs[i].skb_dma;
894 }
895 lp->fbl_count++;
896 }
897 }
898#endif
899 for (i = 0; i < RX_BUF_NUM; i++) {
900#ifdef TC35815_USE_PACKEDBUFFER
901 lp->fbl_ptr->bd[i].BuffData = cpu_to_le32(lp->data_buf_dma[i]);
902#else
903 if (i >= lp->fbl_count) {
904 lp->fbl_ptr->bd[i].BuffData = 0;
905 lp->fbl_ptr->bd[i].BDCtl = 0;
906 continue;
907 }
908 lp->fbl_ptr->bd[i].BuffData =
909 cpu_to_le32(lp->rx_skbs[i].skb_dma);
910#endif
700 /* BDID is index of FrFD.bd[] */ 911 /* BDID is index of FrFD.bd[] */
701 lp->fbl_ptr->bd[i].BDCtl = 912 lp->fbl_ptr->bd[i].BDCtl =
702 cpu_to_le32(BD_CownsBD | (i << BD_RxBDID_SHIFT) | PAGE_SIZE); 913 cpu_to_le32(BD_CownsBD | (i << BD_RxBDID_SHIFT) |
914 RX_BUF_SIZE);
703 } 915 }
916#ifdef TC35815_USE_PACKEDBUFFER
704 lp->fbl_curid = 0; 917 lp->fbl_curid = 0;
918#endif
705 919
920 printk(KERN_DEBUG "%s: TxFD %p RxFD %p FrFD %p\n",
921 dev->name, lp->tfd_base, lp->rfd_base, lp->fbl_ptr);
706 return 0; 922 return 0;
707} 923}
708 924
@@ -713,11 +929,25 @@ tc35815_clear_queues(struct net_device *dev)
713 int i; 929 int i;
714 930
715 for (i = 0; i < TX_FD_NUM; i++) { 931 for (i = 0; i < TX_FD_NUM; i++) {
716 struct sk_buff *skb = (struct sk_buff *) 932 u32 fdsystem = le32_to_cpu(lp->tfd_base[i].fd.FDSystem);
717 le32_to_cpu(lp->tfd_base[i].fd.FDSystem); 933 struct sk_buff *skb =
718 if (skb) 934 fdsystem != 0xffffffff ?
935 lp->tx_skbs[fdsystem].skb : NULL;
936#ifdef DEBUG
937 if (lp->tx_skbs[i].skb != skb) {
938 printk("%s: tx_skbs mismatch(%d).\n", dev->name, i);
939 panic_queues(dev);
940 }
941#else
942 BUG_ON(lp->tx_skbs[i].skb != skb);
943#endif
944 if (skb) {
945 pci_unmap_single(lp->pci_dev, lp->tx_skbs[i].skb_dma, skb->len, PCI_DMA_TODEVICE);
946 lp->tx_skbs[i].skb = NULL;
947 lp->tx_skbs[i].skb_dma = 0;
719 dev_kfree_skb_any(skb); 948 dev_kfree_skb_any(skb);
720 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0); 949 }
950 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0xffffffff);
721 } 951 }
722 952
723 tc35815_init_queues(dev); 953 tc35815_init_queues(dev);
@@ -731,28 +961,53 @@ tc35815_free_queues(struct net_device *dev)
731 961
732 if (lp->tfd_base) { 962 if (lp->tfd_base) {
733 for (i = 0; i < TX_FD_NUM; i++) { 963 for (i = 0; i < TX_FD_NUM; i++) {
734 struct sk_buff *skb = (struct sk_buff *) 964 u32 fdsystem = le32_to_cpu(lp->tfd_base[i].fd.FDSystem);
735 le32_to_cpu(lp->tfd_base[i].fd.FDSystem); 965 struct sk_buff *skb =
736 if (skb) 966 fdsystem != 0xffffffff ?
737 dev_kfree_skb_any(skb); 967 lp->tx_skbs[fdsystem].skb : NULL;
738 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0); 968#ifdef DEBUG
969 if (lp->tx_skbs[i].skb != skb) {
970 printk("%s: tx_skbs mismatch(%d).\n", dev->name, i);
971 panic_queues(dev);
972 }
973#else
974 BUG_ON(lp->tx_skbs[i].skb != skb);
975#endif
976 if (skb) {
977 dev_kfree_skb(skb);
978 pci_unmap_single(lp->pci_dev, lp->tx_skbs[i].skb_dma, skb->len, PCI_DMA_TODEVICE);
979 lp->tx_skbs[i].skb = NULL;
980 lp->tx_skbs[i].skb_dma = 0;
981 }
982 lp->tfd_base[i].fd.FDSystem = cpu_to_le32(0xffffffff);
739 } 983 }
740 } 984 }
741 985
742 lp->rfd_base = NULL; 986 lp->rfd_base = NULL;
743 lp->rfd_base = NULL;
744 lp->rfd_limit = NULL; 987 lp->rfd_limit = NULL;
745 lp->rfd_cur = NULL; 988 lp->rfd_cur = NULL;
746 lp->fbl_ptr = NULL; 989 lp->fbl_ptr = NULL;
747 990
748 for (i = 0; i < RX_BUF_PAGES; i++) { 991 for (i = 0; i < RX_BUF_NUM; i++) {
749 if (lp->data_buf[i]) 992#ifdef TC35815_USE_PACKEDBUFFER
750 free_page((unsigned long)lp->data_buf[i]); 993 if (lp->data_buf[i]) {
751 lp->data_buf[i] = 0; 994 free_rxbuf_page(lp->pci_dev,
995 lp->data_buf[i], lp->data_buf_dma[i]);
996 lp->data_buf[i] = NULL;
997 }
998#else
999 if (lp->rx_skbs[i].skb) {
1000 free_rxbuf_skb(lp->pci_dev, lp->rx_skbs[i].skb,
1001 lp->rx_skbs[i].skb_dma);
1002 lp->rx_skbs[i].skb = NULL;
1003 }
1004#endif
1005 }
1006 if (lp->fd_buf) {
1007 pci_free_consistent(lp->pci_dev, PAGE_SIZE * FD_PAGE_NUM,
1008 lp->fd_buf, lp->fd_buf_dma);
1009 lp->fd_buf = NULL;
752 } 1010 }
753 if (lp->fd_buf)
754 __free_pages(lp->fd_buf, FD_PAGE_ORDER);
755 lp->fd_buf = NULL;
756} 1011}
757 1012
758static void 1013static void
@@ -792,6 +1047,7 @@ dump_rxfd(struct RxFD *fd)
792 return bd_count; 1047 return bd_count;
793} 1048}
794 1049
1050#if defined(DEBUG) || defined(TC35815_USE_PACKEDBUFFER)
795static void 1051static void
796dump_frfd(struct FrFD *fd) 1052dump_frfd(struct FrFD *fd)
797{ 1053{
@@ -802,20 +1058,22 @@ dump_frfd(struct FrFD *fd)
802 le32_to_cpu(fd->fd.FDStat), 1058 le32_to_cpu(fd->fd.FDStat),
803 le32_to_cpu(fd->fd.FDCtl)); 1059 le32_to_cpu(fd->fd.FDCtl));
804 printk("BD: "); 1060 printk("BD: ");
805 for (i = 0; i < RX_BUF_PAGES; i++) 1061 for (i = 0; i < RX_BUF_NUM; i++)
806 printk(" %08x %08x", 1062 printk(" %08x %08x",
807 le32_to_cpu(fd->bd[i].BuffData), 1063 le32_to_cpu(fd->bd[i].BuffData),
808 le32_to_cpu(fd->bd[i].BDCtl)); 1064 le32_to_cpu(fd->bd[i].BDCtl));
809 printk("\n"); 1065 printk("\n");
810} 1066}
1067#endif
811 1068
1069#ifdef DEBUG
812static void 1070static void
813panic_queues(struct net_device *dev) 1071panic_queues(struct net_device *dev)
814{ 1072{
815 struct tc35815_local *lp = dev->priv; 1073 struct tc35815_local *lp = dev->priv;
816 int i; 1074 int i;
817 1075
818 printk("TxFD base %p, start %d, end %d\n", 1076 printk("TxFD base %p, start %u, end %u\n",
819 lp->tfd_base, lp->tfd_start, lp->tfd_end); 1077 lp->tfd_base, lp->tfd_start, lp->tfd_end);
820 printk("RxFD base %p limit %p cur %p\n", 1078 printk("RxFD base %p limit %p cur %p\n",
821 lp->rfd_base, lp->rfd_limit, lp->rfd_cur); 1079 lp->rfd_base, lp->rfd_limit, lp->rfd_cur);
@@ -829,31 +1087,13 @@ panic_queues(struct net_device *dev)
829 dump_frfd(lp->fbl_ptr); 1087 dump_frfd(lp->fbl_ptr);
830 panic("%s: Illegal queue state.", dev->name); 1088 panic("%s: Illegal queue state.", dev->name);
831} 1089}
832
833#if 0
834static void print_buf(char *add, int length)
835{
836 int i;
837 int len = length;
838
839 printk("print_buf(%08x)(%x)\n", (unsigned int) add,length);
840
841 if (len > 100)
842 len = 100;
843 for (i = 0; i < len; i++) {
844 printk(" %2.2X", (unsigned char) add[i]);
845 if (!(i % 16))
846 printk("\n");
847 }
848 printk("\n");
849}
850#endif 1090#endif
851 1091
852static void print_eth(char *add) 1092static void print_eth(char *add)
853{ 1093{
854 int i; 1094 int i;
855 1095
856 printk("print_eth(%08x)\n", (unsigned int) add); 1096 printk("print_eth(%p)\n", add);
857 for (i = 0; i < 6; i++) 1097 for (i = 0; i < 6; i++)
858 printk(" %2.2X", (unsigned char) add[i + 6]); 1098 printk(" %2.2X", (unsigned char) add[i + 6]);
859 printk(" =>"); 1099 printk(" =>");
@@ -862,6 +1102,73 @@ static void print_eth(char *add)
862 printk(" : %2.2X%2.2X\n", (unsigned char) add[12], (unsigned char) add[13]); 1102 printk(" : %2.2X%2.2X\n", (unsigned char) add[12], (unsigned char) add[13]);
863} 1103}
864 1104
1105static int tc35815_tx_full(struct net_device *dev)
1106{
1107 struct tc35815_local *lp = dev->priv;
1108 return ((lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end);
1109}
1110
1111static void tc35815_restart(struct net_device *dev)
1112{
1113 struct tc35815_local *lp = dev->priv;
1114 int pid = lp->phy_addr;
1115 int do_phy_reset = 1;
1116 del_timer(&lp->timer); /* Kill if running */
1117
1118 if (lp->mii_id[0] == 0x0016 && (lp->mii_id[1] & 0xfc00) == 0xf800) {
1119 /* Resetting PHY cause problem on some chip... (SEEQ 80221) */
1120 do_phy_reset = 0;
1121 }
1122 if (do_phy_reset) {
1123 int timeout;
1124 tc_mdio_write(dev, pid, MII_BMCR, BMCR_RESET);
1125 timeout = 100;
1126 while (--timeout) {
1127 if (!(tc_mdio_read(dev, pid, MII_BMCR) & BMCR_RESET))
1128 break;
1129 udelay(1);
1130 }
1131 if (!timeout)
1132 printk(KERN_ERR "%s: BMCR reset failed.\n", dev->name);
1133 }
1134
1135 tc35815_chip_reset(dev);
1136 tc35815_clear_queues(dev);
1137 tc35815_chip_init(dev);
1138 /* Reconfigure CAM again since tc35815_chip_init() initialize it. */
1139 tc35815_set_multicast_list(dev);
1140}
1141
1142static void tc35815_tx_timeout(struct net_device *dev)
1143{
1144 struct tc35815_local *lp = dev->priv;
1145 struct tc35815_regs __iomem *tr =
1146 (struct tc35815_regs __iomem *)dev->base_addr;
1147
1148 printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
1149 dev->name, tc_readl(&tr->Tx_Stat));
1150
1151 /* Try to restart the adaptor. */
1152 spin_lock_irq(&lp->lock);
1153 tc35815_restart(dev);
1154 spin_unlock_irq(&lp->lock);
1155
1156 lp->stats.tx_errors++;
1157
1158 /* If we have space available to accept new transmit
1159 * requests, wake up the queueing layer. This would
1160 * be the case if the chipset_init() call above just
1161 * flushes out the tx queue and empties it.
1162 *
1163 * If instead, the tx queue is retained then the
1164 * netif_wake_queue() call should be placed in the
1165 * TX completion interrupt handler of the driver instead
1166 * of here.
1167 */
1168 if (!tc35815_tx_full(dev))
1169 netif_wake_queue(dev);
1170}
1171
865/* 1172/*
866 * Open/initialize the board. This is called (in the current kernel) 1173 * Open/initialize the board. This is called (in the current kernel)
867 * sometime after booting when the 'ifconfig' program is run. 1174 * sometime after booting when the 'ifconfig' program is run.
@@ -874,16 +1181,16 @@ static int
874tc35815_open(struct net_device *dev) 1181tc35815_open(struct net_device *dev)
875{ 1182{
876 struct tc35815_local *lp = dev->priv; 1183 struct tc35815_local *lp = dev->priv;
1184
877 /* 1185 /*
878 * This is used if the interrupt line can turned off (shared). 1186 * This is used if the interrupt line can turned off (shared).
879 * See 3c503.c for an example of selecting the IRQ at config-time. 1187 * See 3c503.c for an example of selecting the IRQ at config-time.
880 */ 1188 */
881 1189 if (request_irq(dev->irq, &tc35815_interrupt, IRQF_SHARED, dev->name, dev)) {
882 if (dev->irq == 0 ||
883 request_irq(dev->irq, &tc35815_interrupt, IRQF_SHARED, cardname, dev)) {
884 return -EAGAIN; 1190 return -EAGAIN;
885 } 1191 }
886 1192
1193 del_timer(&lp->timer); /* Kill if running */
887 tc35815_chip_reset(dev); 1194 tc35815_chip_reset(dev);
888 1195
889 if (tc35815_init_queues(dev) != 0) { 1196 if (tc35815_init_queues(dev) != 0) {
@@ -892,138 +1199,119 @@ tc35815_open(struct net_device *dev)
892 } 1199 }
893 1200
894 /* Reset the hardware here. Don't forget to set the station address. */ 1201 /* Reset the hardware here. Don't forget to set the station address. */
1202 spin_lock_irq(&lp->lock);
895 tc35815_chip_init(dev); 1203 tc35815_chip_init(dev);
1204 spin_unlock_irq(&lp->lock);
896 1205
897 lp->tbusy = 0; 1206 /* We are now ready to accept transmit requeusts from
1207 * the queueing layer of the networking.
1208 */
898 netif_start_queue(dev); 1209 netif_start_queue(dev);
899 1210
900 return 0; 1211 return 0;
901} 1212}
902 1213
903static void tc35815_tx_timeout(struct net_device *dev) 1214/* This will only be invoked if your driver is _not_ in XOFF state.
904{ 1215 * What this means is that you need not check it, and that this
905 struct tc35815_local *lp = dev->priv; 1216 * invariant will hold if you make sure that the netif_*_queue()
906 struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr; 1217 * calls are done at the proper times.
907 unsigned long flags; 1218 */
908
909 spin_lock_irqsave(&lp->lock, flags);
910 printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
911 dev->name, tc_readl(&tr->Tx_Stat));
912 /* Try to restart the adaptor. */
913 tc35815_chip_reset(dev);
914 tc35815_clear_queues(dev);
915 tc35815_chip_init(dev);
916 lp->tbusy=0;
917 spin_unlock_irqrestore(&lp->lock, flags);
918 dev->trans_start = jiffies;
919 netif_wake_queue(dev);
920}
921
922static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev) 1219static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
923{ 1220{
924 struct tc35815_local *lp = dev->priv; 1221 struct tc35815_local *lp = dev->priv;
925 struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr; 1222 struct TxFD *txfd;
926 1223 unsigned long flags;
927 if (netif_queue_stopped(dev)) {
928 /*
929 * If we get here, some higher level has decided we are broken.
930 * There should really be a "kick me" function call instead.
931 */
932 int tickssofar = jiffies - dev->trans_start;
933 if (tickssofar < 5)
934 return 1;
935 printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
936 dev->name, tc_readl(&tr->Tx_Stat));
937 /* Try to restart the adaptor. */
938 tc35815_chip_reset(dev);
939 tc35815_clear_queues(dev);
940 tc35815_chip_init(dev);
941 lp->tbusy=0;
942 dev->trans_start = jiffies;
943 netif_wake_queue(dev);
944 }
945 1224
946 /* 1225 /* If some error occurs while trying to transmit this
947 * Block a timer-based transmit from overlapping. This could better be 1226 * packet, you should return '1' from this function.
948 * done with atomic_swap(1, lp->tbusy), but set_bit() works as well. 1227 * In such a case you _may not_ do anything to the
1228 * SKB, it is still owned by the network queueing
1229 * layer when an error is returned. This means you
1230 * may not modify any SKB fields, you may not free
1231 * the SKB, etc.
949 */ 1232 */
950 if (test_and_set_bit(0, (void*)&lp->tbusy) != 0) {
951 printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
952 dev_kfree_skb_any(skb);
953 } else {
954 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
955 unsigned char *buf = skb->data;
956 struct TxFD *txfd = &lp->tfd_base[lp->tfd_start];
957 unsigned long flags;
958 lp->stats.tx_bytes += skb->len;
959 1233
1234 /* This is the most common case for modern hardware.
1235 * The spinlock protects this code from the TX complete
1236 * hardware interrupt handler. Queue flow control is
1237 * thus managed under this lock as well.
1238 */
1239 spin_lock_irqsave(&lp->lock, flags);
960 1240
961#ifdef __mips__ 1241 /* failsafe... (handle txdone now if half of FDs are used) */
962 dma_cache_wback_inv((unsigned long)buf, length); 1242 if ((lp->tfd_start + TX_FD_NUM - lp->tfd_end) % TX_FD_NUM >
1243 TX_FD_NUM / 2)
1244 tc35815_txdone(dev);
1245
1246 if (netif_msg_pktdata(lp))
1247 print_eth(skb->data);
1248#ifdef DEBUG
1249 if (lp->tx_skbs[lp->tfd_start].skb) {
1250 printk("%s: tx_skbs conflict.\n", dev->name);
1251 panic_queues(dev);
1252 }
1253#else
1254 BUG_ON(lp->tx_skbs[lp->tfd_start].skb);
963#endif 1255#endif
964 1256 lp->tx_skbs[lp->tfd_start].skb = skb;
965 spin_lock_irqsave(&lp->lock, flags); 1257 lp->tx_skbs[lp->tfd_start].skb_dma = pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
966 1258
967 /* failsafe... */ 1259 /*add to ring */
968 if (lp->tfd_start != lp->tfd_end) 1260 txfd = &lp->tfd_base[lp->tfd_start];
969 tc35815_txdone(dev); 1261 txfd->bd.BuffData = cpu_to_le32(lp->tx_skbs[lp->tfd_start].skb_dma);
970 1262 txfd->bd.BDCtl = cpu_to_le32(skb->len);
971 1263 txfd->fd.FDSystem = cpu_to_le32(lp->tfd_start);
972 txfd->bd.BuffData = cpu_to_le32(virt_to_bus(buf)); 1264 txfd->fd.FDCtl = cpu_to_le32(FD_CownsFD | (1 << FD_BDCnt_SHIFT));
973 1265
974 txfd->bd.BDCtl = cpu_to_le32(length); 1266 if (lp->tfd_start == lp->tfd_end) {
975 txfd->fd.FDSystem = cpu_to_le32((__u32)skb); 1267 struct tc35815_regs __iomem *tr =
976 txfd->fd.FDCtl = cpu_to_le32(FD_CownsFD | (1 << FD_BDCnt_SHIFT)); 1268 (struct tc35815_regs __iomem *)dev->base_addr;
977 1269 /* Start DMA Transmitter. */
978 if (lp->tfd_start == lp->tfd_end) { 1270 txfd->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
979 /* Start DMA Transmitter. */
980 txfd->fd.FDNext |= cpu_to_le32(FD_Next_EOL);
981#ifdef GATHER_TXINT 1271#ifdef GATHER_TXINT
982 txfd->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx); 1272 txfd->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
983#endif 1273#endif
984 if (tc35815_debug > 2) { 1274 if (netif_msg_tx_queued(lp)) {
985 printk("%s: starting TxFD.\n", dev->name); 1275 printk("%s: starting TxFD.\n", dev->name);
986 dump_txfd(txfd); 1276 dump_txfd(txfd);
987 if (tc35815_debug > 3)
988 print_eth(buf);
989 }
990 tc_writel(virt_to_bus(txfd), &tr->TxFrmPtr);
991 } else {
992 txfd->fd.FDNext &= cpu_to_le32(~FD_Next_EOL);
993 if (tc35815_debug > 2) {
994 printk("%s: queueing TxFD.\n", dev->name);
995 dump_txfd(txfd);
996 if (tc35815_debug > 3)
997 print_eth(buf);
998 }
999 } 1277 }
1000 lp->tfd_start = (lp->tfd_start + 1) % TX_FD_NUM; 1278 tc_writel(fd_virt_to_bus(lp, txfd), &tr->TxFrmPtr);
1279 } else {
1280 txfd->fd.FDNext &= cpu_to_le32(~FD_Next_EOL);
1281 if (netif_msg_tx_queued(lp)) {
1282 printk("%s: queueing TxFD.\n", dev->name);
1283 dump_txfd(txfd);
1284 }
1285 }
1286 lp->tfd_start = (lp->tfd_start + 1) % TX_FD_NUM;
1001 1287
1002 dev->trans_start = jiffies; 1288 dev->trans_start = jiffies;
1003 1289
1004 if ((lp->tfd_start + 1) % TX_FD_NUM != lp->tfd_end) { 1290 /* If we just used up the very last entry in the
1005 /* we can send another packet */ 1291 * TX ring on this device, tell the queueing
1006 lp->tbusy = 0; 1292 * layer to send no more.
1007 netif_start_queue(dev); 1293 */
1008 } else { 1294 if (tc35815_tx_full(dev)) {
1009 netif_stop_queue(dev); 1295 if (netif_msg_tx_queued(lp))
1010 if (tc35815_debug > 1) 1296 printk(KERN_WARNING "%s: TxFD Exhausted.\n", dev->name);
1011 printk(KERN_WARNING "%s: TxFD Exhausted.\n", dev->name); 1297 netif_stop_queue(dev);
1012 }
1013 spin_unlock_irqrestore(&lp->lock, flags);
1014 } 1298 }
1015 1299
1300 /* When the TX completion hw interrupt arrives, this
1301 * is when the transmit statistics are updated.
1302 */
1303
1304 spin_unlock_irqrestore(&lp->lock, flags);
1016 return 0; 1305 return 0;
1017} 1306}
1018 1307
1019#define FATAL_ERROR_INT \ 1308#define FATAL_ERROR_INT \
1020 (Int_IntPCI | Int_DmParErr | Int_IntNRAbt) 1309 (Int_IntPCI | Int_DmParErr | Int_IntNRAbt)
1021static void tc35815_fatal_error_interrupt(struct net_device *dev, int status) 1310static void tc35815_fatal_error_interrupt(struct net_device *dev, u32 status)
1022{ 1311{
1023 static int count; 1312 static int count;
1024 printk(KERN_WARNING "%s: Fatal Error Intterrupt (%#x):", 1313 printk(KERN_WARNING "%s: Fatal Error Intterrupt (%#x):",
1025 dev->name, status); 1314 dev->name, status);
1026
1027 if (status & Int_IntPCI) 1315 if (status & Int_IntPCI)
1028 printk(" IntPCI"); 1316 printk(" IntPCI");
1029 if (status & Int_DmParErr) 1317 if (status & Int_DmParErr)
@@ -1033,110 +1321,170 @@ static void tc35815_fatal_error_interrupt(struct net_device *dev, int status)
1033 printk("\n"); 1321 printk("\n");
1034 if (count++ > 100) 1322 if (count++ > 100)
1035 panic("%s: Too many fatal errors.", dev->name); 1323 panic("%s: Too many fatal errors.", dev->name);
1036 printk(KERN_WARNING "%s: Resetting %s...\n", dev->name, cardname); 1324 printk(KERN_WARNING "%s: Resetting ...\n", dev->name);
1037 /* Try to restart the adaptor. */ 1325 /* Try to restart the adaptor. */
1038 tc35815_chip_reset(dev); 1326 tc35815_restart(dev);
1039 tc35815_clear_queues(dev); 1327}
1040 tc35815_chip_init(dev); 1328
1329#ifdef TC35815_NAPI
1330static int tc35815_do_interrupt(struct net_device *dev, u32 status, int limit)
1331#else
1332static int tc35815_do_interrupt(struct net_device *dev, u32 status)
1333#endif
1334{
1335 struct tc35815_local *lp = dev->priv;
1336 struct tc35815_regs __iomem *tr =
1337 (struct tc35815_regs __iomem *)dev->base_addr;
1338 int ret = -1;
1339
1340 /* Fatal errors... */
1341 if (status & FATAL_ERROR_INT) {
1342 tc35815_fatal_error_interrupt(dev, status);
1343 return 0;
1344 }
1345 /* recoverable errors */
1346 if (status & Int_IntFDAEx) {
1347 /* disable FDAEx int. (until we make rooms...) */
1348 tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En);
1349 printk(KERN_WARNING
1350 "%s: Free Descriptor Area Exhausted (%#x).\n",
1351 dev->name, status);
1352 lp->stats.rx_dropped++;
1353 ret = 0;
1354 }
1355 if (status & Int_IntBLEx) {
1356 /* disable BLEx int. (until we make rooms...) */
1357 tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En);
1358 printk(KERN_WARNING
1359 "%s: Buffer List Exhausted (%#x).\n",
1360 dev->name, status);
1361 lp->stats.rx_dropped++;
1362 ret = 0;
1363 }
1364 if (status & Int_IntExBD) {
1365 printk(KERN_WARNING
1366 "%s: Excessive Buffer Descriptiors (%#x).\n",
1367 dev->name, status);
1368 lp->stats.rx_length_errors++;
1369 ret = 0;
1370 }
1371
1372 /* normal notification */
1373 if (status & Int_IntMacRx) {
1374 /* Got a packet(s). */
1375#ifdef TC35815_NAPI
1376 ret = tc35815_rx(dev, limit);
1377#else
1378 tc35815_rx(dev);
1379 ret = 0;
1380#endif
1381 lp->lstats.rx_ints++;
1382 }
1383 if (status & Int_IntMacTx) {
1384 /* Transmit complete. */
1385 lp->lstats.tx_ints++;
1386 tc35815_txdone(dev);
1387 netif_wake_queue(dev);
1388 ret = 0;
1389 }
1390 return ret;
1041} 1391}
1042 1392
1043/* 1393/*
1044 * The typical workload of the driver: 1394 * The typical workload of the driver:
1045 * Handle the network interface interrupts. 1395 * Handle the network interface interrupts.
1046 */ 1396 */
1047static irqreturn_t tc35815_interrupt(int irq, void *dev_id) 1397static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
1048{ 1398{
1049 struct net_device *dev = dev_id; 1399 struct net_device *dev = dev_id;
1050 struct tc35815_regs *tr; 1400 struct tc35815_regs __iomem *tr =
1051 struct tc35815_local *lp; 1401 (struct tc35815_regs __iomem *)dev->base_addr;
1052 int status, boguscount = 0; 1402#ifdef TC35815_NAPI
1053 int handled = 0; 1403 u32 dmactl = tc_readl(&tr->DMA_Ctl);
1054 1404
1055 if (dev == NULL) { 1405 if (!(dmactl & DMA_IntMask)) {
1056 printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq); 1406 /* disable interrupts */
1057 return IRQ_NONE; 1407 tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
1058 } 1408 if (netif_rx_schedule_prep(dev))
1059 1409 __netif_rx_schedule(dev);
1060 tr = (struct tc35815_regs*)dev->base_addr; 1410 else {
1061 lp = dev->priv; 1411 printk(KERN_ERR "%s: interrupt taken in poll\n",
1062 1412 dev->name);
1063 do { 1413 BUG();
1064 status = tc_readl(&tr->Int_Src);
1065 if (status == 0)
1066 break;
1067 handled = 1;
1068 tc_writel(status, &tr->Int_Src); /* write to clear */
1069
1070 /* Fatal errors... */
1071 if (status & FATAL_ERROR_INT) {
1072 tc35815_fatal_error_interrupt(dev, status);
1073 break;
1074 }
1075 /* recoverable errors */
1076 if (status & Int_IntFDAEx) {
1077 /* disable FDAEx int. (until we make rooms...) */
1078 tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En);
1079 printk(KERN_WARNING
1080 "%s: Free Descriptor Area Exhausted (%#x).\n",
1081 dev->name, status);
1082 lp->stats.rx_dropped++;
1083 }
1084 if (status & Int_IntBLEx) {
1085 /* disable BLEx int. (until we make rooms...) */
1086 tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En);
1087 printk(KERN_WARNING
1088 "%s: Buffer List Exhausted (%#x).\n",
1089 dev->name, status);
1090 lp->stats.rx_dropped++;
1091 }
1092 if (status & Int_IntExBD) {
1093 printk(KERN_WARNING
1094 "%s: Excessive Buffer Descriptiors (%#x).\n",
1095 dev->name, status);
1096 lp->stats.rx_length_errors++;
1097 }
1098 /* normal notification */
1099 if (status & Int_IntMacRx) {
1100 /* Got a packet(s). */
1101 lp->lstats.rx_ints++;
1102 tc35815_rx(dev);
1103 }
1104 if (status & Int_IntMacTx) {
1105 lp->lstats.tx_ints++;
1106 tc35815_txdone(dev);
1107 } 1414 }
1108 } while (++boguscount < 20) ; 1415 (void)tc_readl(&tr->Int_Src); /* flush */
1416 return IRQ_HANDLED;
1417 }
1418 return IRQ_NONE;
1419#else
1420 struct tc35815_local *lp = dev->priv;
1421 int handled;
1422 u32 status;
1423
1424 spin_lock(&lp->lock);
1425 status = tc_readl(&tr->Int_Src);
1426 tc_writel(status, &tr->Int_Src); /* write to clear */
1427 handled = tc35815_do_interrupt(dev, status);
1428 (void)tc_readl(&tr->Int_Src); /* flush */
1429 spin_unlock(&lp->lock);
1430 return IRQ_RETVAL(handled >= 0);
1431#endif /* TC35815_NAPI */
1432}
1109 1433
1110 return IRQ_RETVAL(handled); 1434#ifdef CONFIG_NET_POLL_CONTROLLER
1435static void tc35815_poll_controller(struct net_device *dev)
1436{
1437 disable_irq(dev->irq);
1438 tc35815_interrupt(dev->irq, dev);
1439 enable_irq(dev->irq);
1111} 1440}
1441#endif
1112 1442
1113/* We have a good packet(s), get it/them out of the buffers. */ 1443/* We have a good packet(s), get it/them out of the buffers. */
1444#ifdef TC35815_NAPI
1445static int
1446tc35815_rx(struct net_device *dev, int limit)
1447#else
1114static void 1448static void
1115tc35815_rx(struct net_device *dev) 1449tc35815_rx(struct net_device *dev)
1450#endif
1116{ 1451{
1117 struct tc35815_local *lp = dev->priv; 1452 struct tc35815_local *lp = dev->priv;
1118 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
1119 unsigned int fdctl; 1453 unsigned int fdctl;
1120 int i; 1454 int i;
1121 int buf_free_count = 0; 1455 int buf_free_count = 0;
1122 int fd_free_count = 0; 1456 int fd_free_count = 0;
1457#ifdef TC35815_NAPI
1458 int received = 0;
1459#endif
1123 1460
1124 while (!((fdctl = le32_to_cpu(lp->rfd_cur->fd.FDCtl)) & FD_CownsFD)) { 1461 while (!((fdctl = le32_to_cpu(lp->rfd_cur->fd.FDCtl)) & FD_CownsFD)) {
1125 int status = le32_to_cpu(lp->rfd_cur->fd.FDStat); 1462 int status = le32_to_cpu(lp->rfd_cur->fd.FDStat);
1126 int pkt_len = fdctl & FD_FDLength_MASK; 1463 int pkt_len = fdctl & FD_FDLength_MASK;
1127 struct RxFD *next_rfd;
1128 int bd_count = (fdctl & FD_BDCnt_MASK) >> FD_BDCnt_SHIFT; 1464 int bd_count = (fdctl & FD_BDCnt_MASK) >> FD_BDCnt_SHIFT;
1465#ifdef DEBUG
1466 struct RxFD *next_rfd;
1467#endif
1468#if (RX_CTL_CMD & Rx_StripCRC) == 0
1469 pkt_len -= 4;
1470#endif
1129 1471
1130 if (tc35815_debug > 2) 1472 if (netif_msg_rx_status(lp))
1131 dump_rxfd(lp->rfd_cur); 1473 dump_rxfd(lp->rfd_cur);
1132 if (status & Rx_Good) { 1474 if (status & Rx_Good) {
1133 /* Malloc up new buffer. */
1134 struct sk_buff *skb; 1475 struct sk_buff *skb;
1135 unsigned char *data; 1476 unsigned char *data;
1136 int cur_bd, offset; 1477 int cur_bd;
1137 1478#ifdef TC35815_USE_PACKEDBUFFER
1138 lp->stats.rx_bytes += pkt_len; 1479 int offset;
1480#endif
1139 1481
1482#ifdef TC35815_NAPI
1483 if (--limit < 0)
1484 break;
1485#endif
1486#ifdef TC35815_USE_PACKEDBUFFER
1487 BUG_ON(bd_count > 2);
1140 skb = dev_alloc_skb(pkt_len + 2); /* +2: for reserve */ 1488 skb = dev_alloc_skb(pkt_len + 2); /* +2: for reserve */
1141 if (skb == NULL) { 1489 if (skb == NULL) {
1142 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", 1490 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
@@ -1154,25 +1502,69 @@ tc35815_rx(struct net_device *dev)
1154 while (offset < pkt_len && cur_bd < bd_count) { 1502 while (offset < pkt_len && cur_bd < bd_count) {
1155 int len = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BDCtl) & 1503 int len = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BDCtl) &
1156 BD_BuffLength_MASK; 1504 BD_BuffLength_MASK;
1157 void *rxbuf = 1505 dma_addr_t dma = le32_to_cpu(lp->rfd_cur->bd[cur_bd].BuffData);
1158 bus_to_virt(le32_to_cpu(lp->rfd_cur->bd[cur_bd].BuffData)); 1506 void *rxbuf = rxbuf_bus_to_virt(lp, dma);
1159#ifdef __mips__ 1507 if (offset + len > pkt_len)
1160 dma_cache_inv((unsigned long)rxbuf, len); 1508 len = pkt_len - offset;
1509#ifdef TC35815_DMA_SYNC_ONDEMAND
1510 pci_dma_sync_single_for_cpu(lp->pci_dev,
1511 dma, len,
1512 PCI_DMA_FROMDEVICE);
1161#endif 1513#endif
1162 memcpy(data + offset, rxbuf, len); 1514 memcpy(data + offset, rxbuf, len);
1515#ifdef TC35815_DMA_SYNC_ONDEMAND
1516 pci_dma_sync_single_for_device(lp->pci_dev,
1517 dma, len,
1518 PCI_DMA_FROMDEVICE);
1519#endif
1163 offset += len; 1520 offset += len;
1164 cur_bd++; 1521 cur_bd++;
1165 } 1522 }
1166#if 0 1523#else /* TC35815_USE_PACKEDBUFFER */
1167 print_buf(data,pkt_len); 1524 BUG_ON(bd_count > 1);
1525 cur_bd = (le32_to_cpu(lp->rfd_cur->bd[0].BDCtl)
1526 & BD_RxBDID_MASK) >> BD_RxBDID_SHIFT;
1527#ifdef DEBUG
1528 if (cur_bd >= RX_BUF_NUM) {
1529 printk("%s: invalid BDID.\n", dev->name);
1530 panic_queues(dev);
1531 }
1532 BUG_ON(lp->rx_skbs[cur_bd].skb_dma !=
1533 (le32_to_cpu(lp->rfd_cur->bd[0].BuffData) & ~3));
1534 if (!lp->rx_skbs[cur_bd].skb) {
1535 printk("%s: NULL skb.\n", dev->name);
1536 panic_queues(dev);
1537 }
1538#else
1539 BUG_ON(cur_bd >= RX_BUF_NUM);
1168#endif 1540#endif
1169 if (tc35815_debug > 3) 1541 skb = lp->rx_skbs[cur_bd].skb;
1542 prefetch(skb->data);
1543 lp->rx_skbs[cur_bd].skb = NULL;
1544 lp->fbl_count--;
1545 pci_unmap_single(lp->pci_dev,
1546 lp->rx_skbs[cur_bd].skb_dma,
1547 RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
1548 if (!HAVE_DMA_RXALIGN(lp))
1549 memmove(skb->data, skb->data - 2, pkt_len);
1550 data = skb_put(skb, pkt_len);
1551#endif /* TC35815_USE_PACKEDBUFFER */
1552 if (netif_msg_pktdata(lp))
1170 print_eth(data); 1553 print_eth(data);
1171 skb->protocol = eth_type_trans(skb, dev); 1554 skb->protocol = eth_type_trans(skb, dev);
1555#ifdef TC35815_NAPI
1556 netif_receive_skb(skb);
1557 received++;
1558#else
1172 netif_rx(skb); 1559 netif_rx(skb);
1560#endif
1561 dev->last_rx = jiffies;
1173 lp->stats.rx_packets++; 1562 lp->stats.rx_packets++;
1563 lp->stats.rx_bytes += pkt_len;
1174 } else { 1564 } else {
1175 lp->stats.rx_errors++; 1565 lp->stats.rx_errors++;
1566 printk(KERN_DEBUG "%s: Rx error (status %x)\n",
1567 dev->name, status & Rx_Stat_Mask);
1176 /* WORKAROUND: LongErr and CRCErr means Overflow. */ 1568 /* WORKAROUND: LongErr and CRCErr means Overflow. */
1177 if ((status & Rx_LongErr) && (status & Rx_CRCErr)) { 1569 if ((status & Rx_LongErr) && (status & Rx_CRCErr)) {
1178 status &= ~(Rx_LongErr|Rx_CRCErr); 1570 status &= ~(Rx_LongErr|Rx_CRCErr);
@@ -1189,63 +1581,150 @@ tc35815_rx(struct net_device *dev)
1189 int bdctl = le32_to_cpu(lp->rfd_cur->bd[bd_count - 1].BDCtl); 1581 int bdctl = le32_to_cpu(lp->rfd_cur->bd[bd_count - 1].BDCtl);
1190 unsigned char id = 1582 unsigned char id =
1191 (bdctl & BD_RxBDID_MASK) >> BD_RxBDID_SHIFT; 1583 (bdctl & BD_RxBDID_MASK) >> BD_RxBDID_SHIFT;
1192 if (id >= RX_BUF_PAGES) { 1584#ifdef DEBUG
1585 if (id >= RX_BUF_NUM) {
1193 printk("%s: invalid BDID.\n", dev->name); 1586 printk("%s: invalid BDID.\n", dev->name);
1194 panic_queues(dev); 1587 panic_queues(dev);
1195 } 1588 }
1589#else
1590 BUG_ON(id >= RX_BUF_NUM);
1591#endif
1196 /* free old buffers */ 1592 /* free old buffers */
1197 while (lp->fbl_curid != id) { 1593#ifdef TC35815_USE_PACKEDBUFFER
1198 bdctl = le32_to_cpu(lp->fbl_ptr->bd[lp->fbl_curid].BDCtl); 1594 while (lp->fbl_curid != id)
1595#else
1596 while (lp->fbl_count < RX_BUF_NUM)
1597#endif
1598 {
1599#ifdef TC35815_USE_PACKEDBUFFER
1600 unsigned char curid = lp->fbl_curid;
1601#else
1602 unsigned char curid =
1603 (id + 1 + lp->fbl_count) % RX_BUF_NUM;
1604#endif
1605 struct BDesc *bd = &lp->fbl_ptr->bd[curid];
1606#ifdef DEBUG
1607 bdctl = le32_to_cpu(bd->BDCtl);
1199 if (bdctl & BD_CownsBD) { 1608 if (bdctl & BD_CownsBD) {
1200 printk("%s: Freeing invalid BD.\n", 1609 printk("%s: Freeing invalid BD.\n",
1201 dev->name); 1610 dev->name);
1202 panic_queues(dev); 1611 panic_queues(dev);
1203 } 1612 }
1613#endif
1204 /* pass BD to controler */ 1614 /* pass BD to controler */
1615#ifndef TC35815_USE_PACKEDBUFFER
1616 if (!lp->rx_skbs[curid].skb) {
1617 lp->rx_skbs[curid].skb =
1618 alloc_rxbuf_skb(dev,
1619 lp->pci_dev,
1620 &lp->rx_skbs[curid].skb_dma);
1621 if (!lp->rx_skbs[curid].skb)
1622 break; /* try on next reception */
1623 bd->BuffData = cpu_to_le32(lp->rx_skbs[curid].skb_dma);
1624 }
1625#endif /* TC35815_USE_PACKEDBUFFER */
1205 /* Note: BDLength was modified by chip. */ 1626 /* Note: BDLength was modified by chip. */
1206 lp->fbl_ptr->bd[lp->fbl_curid].BDCtl = 1627 bd->BDCtl = cpu_to_le32(BD_CownsBD |
1207 cpu_to_le32(BD_CownsBD | 1628 (curid << BD_RxBDID_SHIFT) |
1208 (lp->fbl_curid << BD_RxBDID_SHIFT) | 1629 RX_BUF_SIZE);
1209 PAGE_SIZE); 1630#ifdef TC35815_USE_PACKEDBUFFER
1210 lp->fbl_curid = 1631 lp->fbl_curid = (curid + 1) % RX_BUF_NUM;
1211 (lp->fbl_curid + 1) % RX_BUF_PAGES; 1632 if (netif_msg_rx_status(lp)) {
1212 if (tc35815_debug > 2) {
1213 printk("%s: Entering new FBD %d\n", 1633 printk("%s: Entering new FBD %d\n",
1214 dev->name, lp->fbl_curid); 1634 dev->name, lp->fbl_curid);
1215 dump_frfd(lp->fbl_ptr); 1635 dump_frfd(lp->fbl_ptr);
1216 } 1636 }
1637#else
1638 lp->fbl_count++;
1639#endif
1217 buf_free_count++; 1640 buf_free_count++;
1218 } 1641 }
1219 } 1642 }
1220 1643
1221 /* put RxFD back to controller */ 1644 /* put RxFD back to controller */
1222 next_rfd = bus_to_virt(le32_to_cpu(lp->rfd_cur->fd.FDNext)); 1645#ifdef DEBUG
1223#ifdef __mips__ 1646 next_rfd = fd_bus_to_virt(lp,
1224 next_rfd = (struct RxFD *)vtonocache(next_rfd); 1647 le32_to_cpu(lp->rfd_cur->fd.FDNext));
1225#endif
1226 if (next_rfd < lp->rfd_base || next_rfd > lp->rfd_limit) { 1648 if (next_rfd < lp->rfd_base || next_rfd > lp->rfd_limit) {
1227 printk("%s: RxFD FDNext invalid.\n", dev->name); 1649 printk("%s: RxFD FDNext invalid.\n", dev->name);
1228 panic_queues(dev); 1650 panic_queues(dev);
1229 } 1651 }
1652#endif
1230 for (i = 0; i < (bd_count + 1) / 2 + 1; i++) { 1653 for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
1231 /* pass FD to controler */ 1654 /* pass FD to controler */
1232 lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead); /* for debug */ 1655#ifdef DEBUG
1656 lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);
1657#else
1658 lp->rfd_cur->fd.FDNext = cpu_to_le32(FD_Next_EOL);
1659#endif
1233 lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD); 1660 lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD);
1234 lp->rfd_cur++; 1661 lp->rfd_cur++;
1235 fd_free_count++; 1662 fd_free_count++;
1236 } 1663 }
1237 1664 if (lp->rfd_cur > lp->rfd_limit)
1238 lp->rfd_cur = next_rfd; 1665 lp->rfd_cur = lp->rfd_base;
1666#ifdef DEBUG
1667 if (lp->rfd_cur != next_rfd)
1668 printk("rfd_cur = %p, next_rfd %p\n",
1669 lp->rfd_cur, next_rfd);
1670#endif
1239 } 1671 }
1240 1672
1241 /* re-enable BL/FDA Exhaust interrupts. */ 1673 /* re-enable BL/FDA Exhaust interrupts. */
1242 if (fd_free_count) { 1674 if (fd_free_count) {
1243 tc_writel(tc_readl(&tr->Int_En) | Int_FDAExEn, &tr->Int_En); 1675 struct tc35815_regs __iomem *tr =
1676 (struct tc35815_regs __iomem *)dev->base_addr;
1677 u32 en, en_old = tc_readl(&tr->Int_En);
1678 en = en_old | Int_FDAExEn;
1244 if (buf_free_count) 1679 if (buf_free_count)
1245 tc_writel(tc_readl(&tr->Int_En) | Int_BLExEn, &tr->Int_En); 1680 en |= Int_BLExEn;
1681 if (en != en_old)
1682 tc_writel(en, &tr->Int_En);
1246 } 1683 }
1684#ifdef TC35815_NAPI
1685 return received;
1686#endif
1247} 1687}
1248 1688
1689#ifdef TC35815_NAPI
1690static int
1691tc35815_poll(struct net_device *dev, int *budget)
1692{
1693 struct tc35815_local *lp = dev->priv;
1694 struct tc35815_regs __iomem *tr =
1695 (struct tc35815_regs __iomem *)dev->base_addr;
1696 int limit = min(*budget, dev->quota);
1697 int received = 0, handled;
1698 u32 status;
1699
1700 spin_lock(&lp->lock);
1701 status = tc_readl(&tr->Int_Src);
1702 do {
1703 tc_writel(status, &tr->Int_Src); /* write to clear */
1704
1705 handled = tc35815_do_interrupt(dev, status, limit);
1706 if (handled >= 0) {
1707 received += handled;
1708 limit -= handled;
1709 if (limit <= 0)
1710 break;
1711 }
1712 status = tc_readl(&tr->Int_Src);
1713 } while (status);
1714 spin_unlock(&lp->lock);
1715
1716 dev->quota -= received;
1717 *budget -= received;
1718 if (limit <= 0)
1719 return 1;
1720
1721 netif_rx_complete(dev);
1722 /* enable interrupts */
1723 tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
1724 return 0;
1725}
1726#endif
1727
1249#ifdef NO_CHECK_CARRIER 1728#ifdef NO_CHECK_CARRIER
1250#define TX_STA_ERR (Tx_ExColl|Tx_Under|Tx_Defer|Tx_LateColl|Tx_TxPar|Tx_SQErr) 1729#define TX_STA_ERR (Tx_ExColl|Tx_Under|Tx_Defer|Tx_LateColl|Tx_TxPar|Tx_SQErr)
1251#else 1730#else
@@ -1264,9 +1743,17 @@ tc35815_check_tx_stat(struct net_device *dev, int status)
1264 if (status & Tx_TxColl_MASK) 1743 if (status & Tx_TxColl_MASK)
1265 lp->stats.collisions += status & Tx_TxColl_MASK; 1744 lp->stats.collisions += status & Tx_TxColl_MASK;
1266 1745
1746#ifndef NO_CHECK_CARRIER
1747 /* TX4939 does not have NCarr */
1748 if (lp->boardtype == TC35815_TX4939)
1749 status &= ~Tx_NCarr;
1750#ifdef WORKAROUND_LOSTCAR
1267 /* WORKAROUND: ignore LostCrS in full duplex operation */ 1751 /* WORKAROUND: ignore LostCrS in full duplex operation */
1268 if (lp->fullduplex) 1752 if ((lp->timer_state != asleep && lp->timer_state != lcheck)
1753 || lp->fullduplex)
1269 status &= ~Tx_NCarr; 1754 status &= ~Tx_NCarr;
1755#endif
1756#endif
1270 1757
1271 if (!(status & TX_STA_ERR)) { 1758 if (!(status & TX_STA_ERR)) {
1272 /* no error. */ 1759 /* no error. */
@@ -1282,6 +1769,15 @@ tc35815_check_tx_stat(struct net_device *dev, int status)
1282 if (status & Tx_Under) { 1769 if (status & Tx_Under) {
1283 lp->stats.tx_fifo_errors++; 1770 lp->stats.tx_fifo_errors++;
1284 msg = "Tx FIFO Underrun."; 1771 msg = "Tx FIFO Underrun.";
1772 if (lp->lstats.tx_underrun < TX_THRESHOLD_KEEP_LIMIT) {
1773 lp->lstats.tx_underrun++;
1774 if (lp->lstats.tx_underrun >= TX_THRESHOLD_KEEP_LIMIT) {
1775 struct tc35815_regs __iomem *tr =
1776 (struct tc35815_regs __iomem *)dev->base_addr;
1777 tc_writel(TX_THRESHOLD_MAX, &tr->TxThrsh);
1778 msg = "Tx FIFO Underrun.Change Tx threshold to max.";
1779 }
1780 }
1285 } 1781 }
1286 if (status & Tx_Defer) { 1782 if (status & Tx_Defer) {
1287 lp->stats.tx_fifo_errors++; 1783 lp->stats.tx_fifo_errors++;
@@ -1305,18 +1801,19 @@ tc35815_check_tx_stat(struct net_device *dev, int status)
1305 lp->stats.tx_heartbeat_errors++; 1801 lp->stats.tx_heartbeat_errors++;
1306 msg = "Signal Quality Error."; 1802 msg = "Signal Quality Error.";
1307 } 1803 }
1308 if (msg) 1804 if (msg && netif_msg_tx_err(lp))
1309 printk(KERN_WARNING "%s: %s (%#x)\n", dev->name, msg, status); 1805 printk(KERN_WARNING "%s: %s (%#x)\n", dev->name, msg, status);
1310} 1806}
1311 1807
1808/* This handles TX complete events posted by the device
1809 * via interrupts.
1810 */
1312static void 1811static void
1313tc35815_txdone(struct net_device *dev) 1812tc35815_txdone(struct net_device *dev)
1314{ 1813{
1315 struct tc35815_local *lp = dev->priv; 1814 struct tc35815_local *lp = dev->priv;
1316 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
1317 struct TxFD *txfd; 1815 struct TxFD *txfd;
1318 unsigned int fdctl; 1816 unsigned int fdctl;
1319 int num_done = 0;
1320 1817
1321 txfd = &lp->tfd_base[lp->tfd_end]; 1818 txfd = &lp->tfd_base[lp->tfd_end];
1322 while (lp->tfd_start != lp->tfd_end && 1819 while (lp->tfd_start != lp->tfd_end &&
@@ -1324,38 +1821,61 @@ tc35815_txdone(struct net_device *dev)
1324 int status = le32_to_cpu(txfd->fd.FDStat); 1821 int status = le32_to_cpu(txfd->fd.FDStat);
1325 struct sk_buff *skb; 1822 struct sk_buff *skb;
1326 unsigned long fdnext = le32_to_cpu(txfd->fd.FDNext); 1823 unsigned long fdnext = le32_to_cpu(txfd->fd.FDNext);
1824 u32 fdsystem = le32_to_cpu(txfd->fd.FDSystem);
1327 1825
1328 if (tc35815_debug > 2) { 1826 if (netif_msg_tx_done(lp)) {
1329 printk("%s: complete TxFD.\n", dev->name); 1827 printk("%s: complete TxFD.\n", dev->name);
1330 dump_txfd(txfd); 1828 dump_txfd(txfd);
1331 } 1829 }
1332 tc35815_check_tx_stat(dev, status); 1830 tc35815_check_tx_stat(dev, status);
1333 1831
1334 skb = (struct sk_buff *)le32_to_cpu(txfd->fd.FDSystem); 1832 skb = fdsystem != 0xffffffff ?
1833 lp->tx_skbs[fdsystem].skb : NULL;
1834#ifdef DEBUG
1835 if (lp->tx_skbs[lp->tfd_end].skb != skb) {
1836 printk("%s: tx_skbs mismatch.\n", dev->name);
1837 panic_queues(dev);
1838 }
1839#else
1840 BUG_ON(lp->tx_skbs[lp->tfd_end].skb != skb);
1841#endif
1335 if (skb) { 1842 if (skb) {
1843 lp->stats.tx_bytes += skb->len;
1844 pci_unmap_single(lp->pci_dev, lp->tx_skbs[lp->tfd_end].skb_dma, skb->len, PCI_DMA_TODEVICE);
1845 lp->tx_skbs[lp->tfd_end].skb = NULL;
1846 lp->tx_skbs[lp->tfd_end].skb_dma = 0;
1847#ifdef TC35815_NAPI
1336 dev_kfree_skb_any(skb); 1848 dev_kfree_skb_any(skb);
1849#else
1850 dev_kfree_skb_irq(skb);
1851#endif
1337 } 1852 }
1338 txfd->fd.FDSystem = cpu_to_le32(0); 1853 txfd->fd.FDSystem = cpu_to_le32(0xffffffff);
1339 1854
1340 num_done++;
1341 lp->tfd_end = (lp->tfd_end + 1) % TX_FD_NUM; 1855 lp->tfd_end = (lp->tfd_end + 1) % TX_FD_NUM;
1342 txfd = &lp->tfd_base[lp->tfd_end]; 1856 txfd = &lp->tfd_base[lp->tfd_end];
1343 if ((fdnext & ~FD_Next_EOL) != virt_to_bus(txfd)) { 1857#ifdef DEBUG
1858 if ((fdnext & ~FD_Next_EOL) != fd_virt_to_bus(lp, txfd)) {
1344 printk("%s: TxFD FDNext invalid.\n", dev->name); 1859 printk("%s: TxFD FDNext invalid.\n", dev->name);
1345 panic_queues(dev); 1860 panic_queues(dev);
1346 } 1861 }
1862#endif
1347 if (fdnext & FD_Next_EOL) { 1863 if (fdnext & FD_Next_EOL) {
1348 /* DMA Transmitter has been stopping... */ 1864 /* DMA Transmitter has been stopping... */
1349 if (lp->tfd_end != lp->tfd_start) { 1865 if (lp->tfd_end != lp->tfd_start) {
1866 struct tc35815_regs __iomem *tr =
1867 (struct tc35815_regs __iomem *)dev->base_addr;
1350 int head = (lp->tfd_start + TX_FD_NUM - 1) % TX_FD_NUM; 1868 int head = (lp->tfd_start + TX_FD_NUM - 1) % TX_FD_NUM;
1351 struct TxFD* txhead = &lp->tfd_base[head]; 1869 struct TxFD* txhead = &lp->tfd_base[head];
1352 int qlen = (lp->tfd_start + TX_FD_NUM 1870 int qlen = (lp->tfd_start + TX_FD_NUM
1353 - lp->tfd_end) % TX_FD_NUM; 1871 - lp->tfd_end) % TX_FD_NUM;
1354 1872
1873#ifdef DEBUG
1355 if (!(le32_to_cpu(txfd->fd.FDCtl) & FD_CownsFD)) { 1874 if (!(le32_to_cpu(txfd->fd.FDCtl) & FD_CownsFD)) {
1356 printk("%s: TxFD FDCtl invalid.\n", dev->name); 1875 printk("%s: TxFD FDCtl invalid.\n", dev->name);
1357 panic_queues(dev); 1876 panic_queues(dev);
1358 } 1877 }
1878#endif
1359 /* log max queue length */ 1879 /* log max queue length */
1360 if (lp->lstats.max_tx_qlen < qlen) 1880 if (lp->lstats.max_tx_qlen < qlen)
1361 lp->lstats.max_tx_qlen = qlen; 1881 lp->lstats.max_tx_qlen = qlen;
@@ -1366,21 +1886,23 @@ tc35815_txdone(struct net_device *dev)
1366#ifdef GATHER_TXINT 1886#ifdef GATHER_TXINT
1367 txhead->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx); 1887 txhead->fd.FDCtl |= cpu_to_le32(FD_FrmOpt_IntTx);
1368#endif 1888#endif
1369 if (tc35815_debug > 2) { 1889 if (netif_msg_tx_queued(lp)) {
1370 printk("%s: start TxFD on queue.\n", 1890 printk("%s: start TxFD on queue.\n",
1371 dev->name); 1891 dev->name);
1372 dump_txfd(txfd); 1892 dump_txfd(txfd);
1373 } 1893 }
1374 tc_writel(virt_to_bus(txfd), &tr->TxFrmPtr); 1894 tc_writel(fd_virt_to_bus(lp, txfd), &tr->TxFrmPtr);
1375 } 1895 }
1376 break; 1896 break;
1377 } 1897 }
1378 } 1898 }
1379 1899
1380 if (num_done > 0 && lp->tbusy) { 1900 /* If we had stopped the queue due to a "tx full"
1381 lp->tbusy = 0; 1901 * condition, and space has now been made available,
1382 netif_start_queue(dev); 1902 * wake up the queue.
1383 } 1903 */
1904 if (netif_queue_stopped(dev) && ! tc35815_tx_full(dev))
1905 netif_wake_queue(dev);
1384} 1906}
1385 1907
1386/* The inverse routine to tc35815_open(). */ 1908/* The inverse routine to tc35815_open(). */
@@ -1388,18 +1910,18 @@ static int
1388tc35815_close(struct net_device *dev) 1910tc35815_close(struct net_device *dev)
1389{ 1911{
1390 struct tc35815_local *lp = dev->priv; 1912 struct tc35815_local *lp = dev->priv;
1391
1392 lp->tbusy = 1;
1393 netif_stop_queue(dev); 1913 netif_stop_queue(dev);
1394 1914
1395 /* Flush the Tx and disable Rx here. */ 1915 /* Flush the Tx and disable Rx here. */
1396 1916
1917 del_timer(&lp->timer); /* Kill if running */
1397 tc35815_chip_reset(dev); 1918 tc35815_chip_reset(dev);
1398 free_irq(dev->irq, dev); 1919 free_irq(dev->irq, dev);
1399 1920
1400 tc35815_free_queues(dev); 1921 tc35815_free_queues(dev);
1401 1922
1402 return 0; 1923 return 0;
1924
1403} 1925}
1404 1926
1405/* 1927/*
@@ -1409,29 +1931,29 @@ tc35815_close(struct net_device *dev)
1409static struct net_device_stats *tc35815_get_stats(struct net_device *dev) 1931static struct net_device_stats *tc35815_get_stats(struct net_device *dev)
1410{ 1932{
1411 struct tc35815_local *lp = dev->priv; 1933 struct tc35815_local *lp = dev->priv;
1412 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr; 1934 struct tc35815_regs __iomem *tr =
1413 unsigned long flags; 1935 (struct tc35815_regs __iomem *)dev->base_addr;
1414
1415 if (netif_running(dev)) { 1936 if (netif_running(dev)) {
1416 spin_lock_irqsave(&lp->lock, flags);
1417 /* Update the statistics from the device registers. */ 1937 /* Update the statistics from the device registers. */
1418 lp->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt); 1938 lp->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt);
1419 spin_unlock_irqrestore(&lp->lock, flags);
1420 } 1939 }
1421 1940
1422 return &lp->stats; 1941 return &lp->stats;
1423} 1942}
1424 1943
1425static void tc35815_set_cam_entry(struct tc35815_regs *tr, int index, unsigned char *addr) 1944static void tc35815_set_cam_entry(struct net_device *dev, int index, unsigned char *addr)
1426{ 1945{
1946 struct tc35815_local *lp = dev->priv;
1947 struct tc35815_regs __iomem *tr =
1948 (struct tc35815_regs __iomem *)dev->base_addr;
1427 int cam_index = index * 6; 1949 int cam_index = index * 6;
1428 unsigned long cam_data; 1950 u32 cam_data;
1429 unsigned long saved_addr; 1951 u32 saved_addr;
1430 saved_addr = tc_readl(&tr->CAM_Adr); 1952 saved_addr = tc_readl(&tr->CAM_Adr);
1431 1953
1432 if (tc35815_debug > 1) { 1954 if (netif_msg_hw(lp)) {
1433 int i; 1955 int i;
1434 printk(KERN_DEBUG "%s: CAM %d:", cardname, index); 1956 printk(KERN_DEBUG "%s: CAM %d:", dev->name, index);
1435 for (i = 0; i < 6; i++) 1957 for (i = 0; i < 6; i++)
1436 printk(" %02x", addr[i]); 1958 printk(" %02x", addr[i]);
1437 printk("\n"); 1959 printk("\n");
@@ -1458,14 +1980,6 @@ static void tc35815_set_cam_entry(struct tc35815_regs *tr, int index, unsigned c
1458 tc_writel(cam_data, &tr->CAM_Data); 1980 tc_writel(cam_data, &tr->CAM_Data);
1459 } 1981 }
1460 1982
1461 if (tc35815_debug > 2) {
1462 int i;
1463 for (i = cam_index / 4; i < cam_index / 4 + 2; i++) {
1464 tc_writel(i * 4, &tr->CAM_Adr);
1465 printk("CAM 0x%x: %08lx",
1466 i * 4, tc_readl(&tr->CAM_Data));
1467 }
1468 }
1469 tc_writel(saved_addr, &tr->CAM_Adr); 1983 tc_writel(saved_addr, &tr->CAM_Adr);
1470} 1984}
1471 1985
@@ -1480,10 +1994,19 @@ static void tc35815_set_cam_entry(struct tc35815_regs *tr, int index, unsigned c
1480static void 1994static void
1481tc35815_set_multicast_list(struct net_device *dev) 1995tc35815_set_multicast_list(struct net_device *dev)
1482{ 1996{
1483 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr; 1997 struct tc35815_regs __iomem *tr =
1998 (struct tc35815_regs __iomem *)dev->base_addr;
1484 1999
1485 if (dev->flags&IFF_PROMISC) 2000 if (dev->flags&IFF_PROMISC)
1486 { 2001 {
2002#ifdef WORKAROUND_100HALF_PROMISC
2003 /* With some (all?) 100MHalf HUB, controller will hang
2004 * if we enabled promiscuous mode before linkup... */
2005 struct tc35815_local *lp = dev->priv;
2006 int pid = lp->phy_addr;
2007 if (!(tc_mdio_read(dev, pid, MII_BMSR) & BMSR_LSTATUS))
2008 return;
2009#endif
1487 /* Enable promiscuous mode */ 2010 /* Enable promiscuous mode */
1488 tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl); 2011 tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl);
1489 } 2012 }
@@ -1505,7 +2028,7 @@ tc35815_set_multicast_list(struct net_device *dev)
1505 if (!cur_addr) 2028 if (!cur_addr)
1506 break; 2029 break;
1507 /* entry 0,1 is reserved. */ 2030 /* entry 0,1 is reserved. */
1508 tc35815_set_cam_entry(tr, i + 2, cur_addr->dmi_addr); 2031 tc35815_set_cam_entry(dev, i + 2, cur_addr->dmi_addr);
1509 ena_bits |= CAM_Ena_Bit(i + 2); 2032 ena_bits |= CAM_Ena_Bit(i + 2);
1510 } 2033 }
1511 tc_writel(ena_bits, &tr->CAM_Ena); 2034 tc_writel(ena_bits, &tr->CAM_Ena);
@@ -1517,122 +2040,753 @@ tc35815_set_multicast_list(struct net_device *dev)
1517 } 2040 }
1518} 2041}
1519 2042
1520static unsigned long tc_phy_read(struct net_device *dev, struct tc35815_regs *tr, int phy, int phy_reg) 2043static void tc35815_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1521{ 2044{
1522 struct tc35815_local *lp = dev->priv; 2045 struct tc35815_local *lp = dev->priv;
1523 unsigned long data; 2046 strcpy(info->driver, MODNAME);
1524 unsigned long flags; 2047 strcpy(info->version, DRV_VERSION);
2048 strcpy(info->bus_info, pci_name(lp->pci_dev));
2049}
1525 2050
1526 spin_lock_irqsave(&lp->lock, flags); 2051static int tc35815_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2052{
2053 struct tc35815_local *lp = dev->priv;
2054 spin_lock_irq(&lp->lock);
2055 mii_ethtool_gset(&lp->mii, cmd);
2056 spin_unlock_irq(&lp->lock);
2057 return 0;
2058}
1527 2059
1528 tc_writel(MD_CA_Busy | (phy << 5) | phy_reg, &tr->MD_CA); 2060static int tc35815_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2061{
2062 struct tc35815_local *lp = dev->priv;
2063 int rc;
2064#if 1 /* use our negotiation method... */
2065 /* Verify the settings we care about. */
2066 if (cmd->autoneg != AUTONEG_ENABLE &&
2067 cmd->autoneg != AUTONEG_DISABLE)
2068 return -EINVAL;
2069 if (cmd->autoneg == AUTONEG_DISABLE &&
2070 ((cmd->speed != SPEED_100 &&
2071 cmd->speed != SPEED_10) ||
2072 (cmd->duplex != DUPLEX_HALF &&
2073 cmd->duplex != DUPLEX_FULL)))
2074 return -EINVAL;
2075
2076 /* Ok, do it to it. */
2077 spin_lock_irq(&lp->lock);
2078 del_timer(&lp->timer);
2079 tc35815_start_auto_negotiation(dev, cmd);
2080 spin_unlock_irq(&lp->lock);
2081 rc = 0;
2082#else
2083 spin_lock_irq(&lp->lock);
2084 rc = mii_ethtool_sset(&lp->mii, cmd);
2085 spin_unlock_irq(&lp->lock);
2086#endif
2087 return rc;
2088}
2089
2090static int tc35815_nway_reset(struct net_device *dev)
2091{
2092 struct tc35815_local *lp = dev->priv;
2093 int rc;
2094 spin_lock_irq(&lp->lock);
2095 rc = mii_nway_restart(&lp->mii);
2096 spin_unlock_irq(&lp->lock);
2097 return rc;
2098}
2099
2100static u32 tc35815_get_link(struct net_device *dev)
2101{
2102 struct tc35815_local *lp = dev->priv;
2103 int rc;
2104 spin_lock_irq(&lp->lock);
2105 rc = mii_link_ok(&lp->mii);
2106 spin_unlock_irq(&lp->lock);
2107 return rc;
2108}
2109
2110static u32 tc35815_get_msglevel(struct net_device *dev)
2111{
2112 struct tc35815_local *lp = dev->priv;
2113 return lp->msg_enable;
2114}
2115
2116static void tc35815_set_msglevel(struct net_device *dev, u32 datum)
2117{
2118 struct tc35815_local *lp = dev->priv;
2119 lp->msg_enable = datum;
2120}
2121
2122static int tc35815_get_stats_count(struct net_device *dev)
2123{
2124 struct tc35815_local *lp = dev->priv;
2125 return sizeof(lp->lstats) / sizeof(int);
2126}
2127
2128static void tc35815_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
2129{
2130 struct tc35815_local *lp = dev->priv;
2131 data[0] = lp->lstats.max_tx_qlen;
2132 data[1] = lp->lstats.tx_ints;
2133 data[2] = lp->lstats.rx_ints;
2134 data[3] = lp->lstats.tx_underrun;
2135}
2136
2137static struct {
2138 const char str[ETH_GSTRING_LEN];
2139} ethtool_stats_keys[] = {
2140 { "max_tx_qlen" },
2141 { "tx_ints" },
2142 { "rx_ints" },
2143 { "tx_underrun" },
2144};
2145
2146static void tc35815_get_strings(struct net_device *dev, u32 stringset, u8 *data)
2147{
2148 memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
2149}
2150
2151static const struct ethtool_ops tc35815_ethtool_ops = {
2152 .get_drvinfo = tc35815_get_drvinfo,
2153 .get_settings = tc35815_get_settings,
2154 .set_settings = tc35815_set_settings,
2155 .nway_reset = tc35815_nway_reset,
2156 .get_link = tc35815_get_link,
2157 .get_msglevel = tc35815_get_msglevel,
2158 .set_msglevel = tc35815_set_msglevel,
2159 .get_strings = tc35815_get_strings,
2160 .get_stats_count = tc35815_get_stats_count,
2161 .get_ethtool_stats = tc35815_get_ethtool_stats,
2162 .get_perm_addr = ethtool_op_get_perm_addr,
2163};
2164
2165static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2166{
2167 struct tc35815_local *lp = dev->priv;
2168 int rc;
2169
2170 if (!netif_running(dev))
2171 return -EINVAL;
2172
2173 spin_lock_irq(&lp->lock);
2174 rc = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL);
2175 spin_unlock_irq(&lp->lock);
2176
2177 return rc;
2178}
2179
2180static int tc_mdio_read(struct net_device *dev, int phy_id, int location)
2181{
2182 struct tc35815_regs __iomem *tr =
2183 (struct tc35815_regs __iomem *)dev->base_addr;
2184 u32 data;
2185 tc_writel(MD_CA_Busy | (phy_id << 5) | location, &tr->MD_CA);
1529 while (tc_readl(&tr->MD_CA) & MD_CA_Busy) 2186 while (tc_readl(&tr->MD_CA) & MD_CA_Busy)
1530 ; 2187 ;
1531 data = tc_readl(&tr->MD_Data); 2188 data = tc_readl(&tr->MD_Data);
1532 spin_unlock_irqrestore(&lp->lock, flags); 2189 return data & 0xffff;
1533 return data; 2190}
2191
2192static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
2193 int val)
2194{
2195 struct tc35815_regs __iomem *tr =
2196 (struct tc35815_regs __iomem *)dev->base_addr;
2197 tc_writel(val, &tr->MD_Data);
2198 tc_writel(MD_CA_Busy | MD_CA_Wr | (phy_id << 5) | location, &tr->MD_CA);
2199 while (tc_readl(&tr->MD_CA) & MD_CA_Busy)
2200 ;
1534} 2201}
1535 2202
1536static void tc_phy_write(struct net_device *dev, unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg) 2203/* Auto negotiation. The scheme is very simple. We have a timer routine
2204 * that keeps watching the auto negotiation process as it progresses.
2205 * The DP83840 is first told to start doing it's thing, we set up the time
2206 * and place the timer state machine in it's initial state.
2207 *
2208 * Here the timer peeks at the DP83840 status registers at each click to see
2209 * if the auto negotiation has completed, we assume here that the DP83840 PHY
2210 * will time out at some point and just tell us what (didn't) happen. For
2211 * complete coverage we only allow so many of the ticks at this level to run,
2212 * when this has expired we print a warning message and try another strategy.
2213 * This "other" strategy is to force the interface into various speed/duplex
2214 * configurations and we stop when we see a link-up condition before the
2215 * maximum number of "peek" ticks have occurred.
2216 *
2217 * Once a valid link status has been detected we configure the BigMAC and
2218 * the rest of the Happy Meal to speak the most efficient protocol we could
2219 * get a clean link for. The priority for link configurations, highest first
2220 * is:
2221 * 100 Base-T Full Duplex
2222 * 100 Base-T Half Duplex
2223 * 10 Base-T Full Duplex
2224 * 10 Base-T Half Duplex
2225 *
2226 * We start a new timer now, after a successful auto negotiation status has
2227 * been detected. This timer just waits for the link-up bit to get set in
2228 * the BMCR of the DP83840. When this occurs we print a kernel log message
2229 * describing the link type in use and the fact that it is up.
2230 *
2231 * If a fatal error of some sort is signalled and detected in the interrupt
2232 * service routine, and the chip is reset, or the link is ifconfig'd down
2233 * and then back up, this entire process repeats itself all over again.
2234 */
2235/* Note: Above comments are come from sunhme driver. */
2236
2237static int tc35815_try_next_permutation(struct net_device *dev)
1537{ 2238{
1538 struct tc35815_local *lp = dev->priv; 2239 struct tc35815_local *lp = dev->priv;
1539 unsigned long flags; 2240 int pid = lp->phy_addr;
2241 unsigned short bmcr;
1540 2242
1541 spin_lock_irqsave(&lp->lock, flags); 2243 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
1542 2244
1543 tc_writel(d, &tr->MD_Data); 2245 /* Downgrade from full to half duplex. Only possible via ethtool. */
1544 tc_writel(MD_CA_Busy | MD_CA_Wr | (phy << 5) | phy_reg, &tr->MD_CA); 2246 if (bmcr & BMCR_FULLDPLX) {
1545 while (tc_readl(&tr->MD_CA) & MD_CA_Busy) 2247 bmcr &= ~BMCR_FULLDPLX;
1546 ; 2248 printk(KERN_DEBUG "%s: try next permutation (BMCR %x)\n", dev->name, bmcr);
1547 spin_unlock_irqrestore(&lp->lock, flags); 2249 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2250 return 0;
2251 }
2252
2253 /* Downgrade from 100 to 10. */
2254 if (bmcr & BMCR_SPEED100) {
2255 bmcr &= ~BMCR_SPEED100;
2256 printk(KERN_DEBUG "%s: try next permutation (BMCR %x)\n", dev->name, bmcr);
2257 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2258 return 0;
2259 }
2260
2261 /* We've tried everything. */
2262 return -1;
1548} 2263}
1549 2264
1550static void tc35815_phy_chip_init(struct net_device *dev) 2265static void
2266tc35815_display_link_mode(struct net_device *dev)
1551{ 2267{
1552 struct tc35815_local *lp = dev->priv; 2268 struct tc35815_local *lp = dev->priv;
1553 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr; 2269 int pid = lp->phy_addr;
1554 static int first = 1; 2270 unsigned short lpa, bmcr;
1555 unsigned short ctl; 2271 char *speed = "", *duplex = "";
1556 2272
1557 if (first) { 2273 lpa = tc_mdio_read(dev, pid, MII_LPA);
1558 unsigned short id0, id1; 2274 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
1559 int count; 2275 if (options.speed ? (bmcr & BMCR_SPEED100) : (lpa & (LPA_100HALF | LPA_100FULL)))
1560 first = 0; 2276 speed = "100Mb/s";
1561 2277 else
1562 /* first data written to the PHY will be an ID number */ 2278 speed = "10Mb/s";
1563 tc_phy_write(dev, 0, tr, 0, MII_CONTROL); /* ID:0 */ 2279 if (options.duplex ? (bmcr & BMCR_FULLDPLX) : (lpa & (LPA_100FULL | LPA_10FULL)))
1564#if 0 2280 duplex = "Full Duplex";
1565 tc_phy_write(dev, MIICNTL_RESET, tr, 0, MII_CONTROL); 2281 else
1566 printk(KERN_INFO "%s: Resetting PHY...", dev->name); 2282 duplex = "Half Duplex";
1567 while (tc_phy_read(dev, tr, 0, MII_CONTROL) & MIICNTL_RESET) 2283
1568 ; 2284 if (netif_msg_link(lp))
1569 printk("\n"); 2285 printk(KERN_INFO "%s: Link is up at %s, %s.\n",
1570 tc_phy_write(dev, MIICNTL_AUTO|MIICNTL_SPEED|MIICNTL_FDX, tr, 0, 2286 dev->name, speed, duplex);
1571 MII_CONTROL); 2287 printk(KERN_DEBUG "%s: MII BMCR %04x BMSR %04x LPA %04x\n",
1572#endif 2288 dev->name,
1573 id0 = tc_phy_read(dev, tr, 0, MII_PHY_ID0); 2289 bmcr, tc_mdio_read(dev, pid, MII_BMSR), lpa);
1574 id1 = tc_phy_read(dev, tr, 0, MII_PHY_ID1); 2290}
1575 printk(KERN_DEBUG "%s: PHY ID %04x %04x\n", dev->name, 2291
1576 id0, id1); 2292static void tc35815_display_forced_link_mode(struct net_device *dev)
1577 if (lp->option & TC35815_OPT_10M) { 2293{
1578 lp->linkspeed = 10; 2294 struct tc35815_local *lp = dev->priv;
1579 lp->fullduplex = (lp->option & TC35815_OPT_FULLDUP) != 0; 2295 int pid = lp->phy_addr;
1580 } else if (lp->option & TC35815_OPT_100M) { 2296 unsigned short bmcr;
1581 lp->linkspeed = 100; 2297 char *speed = "", *duplex = "";
1582 lp->fullduplex = (lp->option & TC35815_OPT_FULLDUP) != 0; 2298
2299 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2300 if (bmcr & BMCR_SPEED100)
2301 speed = "100Mb/s";
2302 else
2303 speed = "10Mb/s";
2304 if (bmcr & BMCR_FULLDPLX)
2305 duplex = "Full Duplex.\n";
2306 else
2307 duplex = "Half Duplex.\n";
2308
2309 if (netif_msg_link(lp))
2310 printk(KERN_INFO "%s: Link has been forced up at %s, %s",
2311 dev->name, speed, duplex);
2312}
2313
2314static void tc35815_set_link_modes(struct net_device *dev)
2315{
2316 struct tc35815_local *lp = dev->priv;
2317 struct tc35815_regs __iomem *tr =
2318 (struct tc35815_regs __iomem *)dev->base_addr;
2319 int pid = lp->phy_addr;
2320 unsigned short bmcr, lpa;
2321 int speed;
2322
2323 if (lp->timer_state == arbwait) {
2324 lpa = tc_mdio_read(dev, pid, MII_LPA);
2325 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2326 printk(KERN_DEBUG "%s: MII BMCR %04x BMSR %04x LPA %04x\n",
2327 dev->name,
2328 bmcr, tc_mdio_read(dev, pid, MII_BMSR), lpa);
2329 if (!(lpa & (LPA_10HALF | LPA_10FULL |
2330 LPA_100HALF | LPA_100FULL))) {
2331 /* fall back to 10HALF */
2332 printk(KERN_INFO "%s: bad ability %04x - falling back to 10HD.\n",
2333 dev->name, lpa);
2334 lpa = LPA_10HALF;
2335 }
2336 if (options.duplex ? (bmcr & BMCR_FULLDPLX) : (lpa & (LPA_100FULL | LPA_10FULL)))
2337 lp->fullduplex = 1;
2338 else
2339 lp->fullduplex = 0;
2340 if (options.speed ? (bmcr & BMCR_SPEED100) : (lpa & (LPA_100HALF | LPA_100FULL)))
2341 speed = 100;
2342 else
2343 speed = 10;
2344 } else {
2345 /* Forcing a link mode. */
2346 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2347 if (bmcr & BMCR_FULLDPLX)
2348 lp->fullduplex = 1;
2349 else
2350 lp->fullduplex = 0;
2351 if (bmcr & BMCR_SPEED100)
2352 speed = 100;
2353 else
2354 speed = 10;
2355 }
2356
2357 tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_HaltReq, &tr->MAC_Ctl);
2358 if (lp->fullduplex) {
2359 tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_FullDup, &tr->MAC_Ctl);
2360 } else {
2361 tc_writel(tc_readl(&tr->MAC_Ctl) & ~MAC_FullDup, &tr->MAC_Ctl);
2362 }
2363 tc_writel(tc_readl(&tr->MAC_Ctl) & ~MAC_HaltReq, &tr->MAC_Ctl);
2364
2365 /* TX4939 PCFG.SPEEDn bit will be changed on NETDEV_CHANGE event. */
2366
2367#ifndef NO_CHECK_CARRIER
2368 /* TX4939 does not have EnLCarr */
2369 if (lp->boardtype != TC35815_TX4939) {
2370#ifdef WORKAROUND_LOSTCAR
2371 /* WORKAROUND: enable LostCrS only if half duplex operation */
2372 if (!lp->fullduplex && lp->boardtype != TC35815_TX4939)
2373 tc_writel(tc_readl(&tr->Tx_Ctl) | Tx_EnLCarr, &tr->Tx_Ctl);
2374#endif
2375 }
2376#endif
2377 lp->mii.full_duplex = lp->fullduplex;
2378}
2379
2380static void tc35815_timer(unsigned long data)
2381{
2382 struct net_device *dev = (struct net_device *)data;
2383 struct tc35815_local *lp = dev->priv;
2384 int pid = lp->phy_addr;
2385 unsigned short bmsr, bmcr, lpa;
2386 int restart_timer = 0;
2387
2388 spin_lock_irq(&lp->lock);
2389
2390 lp->timer_ticks++;
2391 switch (lp->timer_state) {
2392 case arbwait:
2393 /*
2394 * Only allow for 5 ticks, thats 10 seconds and much too
2395 * long to wait for arbitration to complete.
2396 */
2397 /* TC35815 need more times... */
2398 if (lp->timer_ticks >= 10) {
2399 /* Enter force mode. */
2400 if (!options.doforce) {
2401 printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful,"
2402 " cable probblem?\n", dev->name);
2403 /* Try to restart the adaptor. */
2404 tc35815_restart(dev);
2405 goto out;
2406 }
2407 printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful,"
2408 " trying force link mode\n", dev->name);
2409 printk(KERN_DEBUG "%s: BMCR %x BMSR %x\n", dev->name,
2410 tc_mdio_read(dev, pid, MII_BMCR),
2411 tc_mdio_read(dev, pid, MII_BMSR));
2412 bmcr = BMCR_SPEED100;
2413 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2414
2415 /*
2416 * OK, seems we need do disable the transceiver
2417 * for the first tick to make sure we get an
2418 * accurate link state at the second tick.
2419 */
2420
2421 lp->timer_state = ltrywait;
2422 lp->timer_ticks = 0;
2423 restart_timer = 1;
1583 } else { 2424 } else {
1584 /* auto negotiation */ 2425 /* Anything interesting happen? */
1585 unsigned long neg_result; 2426 bmsr = tc_mdio_read(dev, pid, MII_BMSR);
1586 tc_phy_write(dev, MIICNTL_AUTO | MIICNTL_RST_AUTO, tr, 0, MII_CONTROL); 2427 if (bmsr & BMSR_ANEGCOMPLETE) {
1587 printk(KERN_INFO "%s: Auto Negotiation...", dev->name); 2428 /* Just what we've been waiting for... */
1588 count = 0; 2429 tc35815_set_link_modes(dev);
1589 while (!(tc_phy_read(dev, tr, 0, MII_STATUS) & MIISTAT_AUTO_DONE)) { 2430
1590 if (count++ > 5000) { 2431 /*
1591 printk(" failed. Assume 10Mbps\n"); 2432 * Success, at least so far, advance our state
1592 lp->linkspeed = 10; 2433 * engine.
1593 lp->fullduplex = 0; 2434 */
1594 goto done; 2435 lp->timer_state = lupwait;
2436 restart_timer = 1;
2437 } else {
2438 restart_timer = 1;
2439 }
2440 }
2441 break;
2442
2443 case lupwait:
2444 /*
2445 * Auto negotiation was successful and we are awaiting a
2446 * link up status. I have decided to let this timer run
2447 * forever until some sort of error is signalled, reporting
2448 * a message to the user at 10 second intervals.
2449 */
2450 bmsr = tc_mdio_read(dev, pid, MII_BMSR);
2451 if (bmsr & BMSR_LSTATUS) {
2452 /*
2453 * Wheee, it's up, display the link mode in use and put
2454 * the timer to sleep.
2455 */
2456 tc35815_display_link_mode(dev);
2457 netif_carrier_on(dev);
2458#ifdef WORKAROUND_100HALF_PROMISC
2459 /* delayed promiscuous enabling */
2460 if (dev->flags & IFF_PROMISC)
2461 tc35815_set_multicast_list(dev);
2462#endif
2463#if 1
2464 lp->saved_lpa = tc_mdio_read(dev, pid, MII_LPA);
2465 lp->timer_state = lcheck;
2466 restart_timer = 1;
2467#else
2468 lp->timer_state = asleep;
2469 restart_timer = 0;
2470#endif
2471 } else {
2472 if (lp->timer_ticks >= 10) {
2473 printk(KERN_NOTICE "%s: Auto negotiation successful, link still "
2474 "not completely up.\n", dev->name);
2475 lp->timer_ticks = 0;
2476 restart_timer = 1;
2477 } else {
2478 restart_timer = 1;
2479 }
2480 }
2481 break;
2482
2483 case ltrywait:
2484 /*
2485 * Making the timeout here too long can make it take
2486 * annoyingly long to attempt all of the link mode
2487 * permutations, but then again this is essentially
2488 * error recovery code for the most part.
2489 */
2490 bmsr = tc_mdio_read(dev, pid, MII_BMSR);
2491 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2492 if (lp->timer_ticks == 1) {
2493 /*
2494 * Re-enable transceiver, we'll re-enable the
2495 * transceiver next tick, then check link state
2496 * on the following tick.
2497 */
2498 restart_timer = 1;
2499 break;
2500 }
2501 if (lp->timer_ticks == 2) {
2502 restart_timer = 1;
2503 break;
2504 }
2505 if (bmsr & BMSR_LSTATUS) {
2506 /* Force mode selection success. */
2507 tc35815_display_forced_link_mode(dev);
2508 netif_carrier_on(dev);
2509 tc35815_set_link_modes(dev);
2510#ifdef WORKAROUND_100HALF_PROMISC
2511 /* delayed promiscuous enabling */
2512 if (dev->flags & IFF_PROMISC)
2513 tc35815_set_multicast_list(dev);
2514#endif
2515#if 1
2516 lp->saved_lpa = tc_mdio_read(dev, pid, MII_LPA);
2517 lp->timer_state = lcheck;
2518 restart_timer = 1;
2519#else
2520 lp->timer_state = asleep;
2521 restart_timer = 0;
2522#endif
2523 } else {
2524 if (lp->timer_ticks >= 4) { /* 6 seconds or so... */
2525 int ret;
2526
2527 ret = tc35815_try_next_permutation(dev);
2528 if (ret == -1) {
2529 /*
2530 * Aieee, tried them all, reset the
2531 * chip and try all over again.
2532 */
2533 printk(KERN_NOTICE "%s: Link down, "
2534 "cable problem?\n",
2535 dev->name);
2536
2537 /* Try to restart the adaptor. */
2538 tc35815_restart(dev);
2539 goto out;
1595 } 2540 }
1596 if (count % 512 == 0) 2541 lp->timer_ticks = 0;
1597 printk("."); 2542 restart_timer = 1;
1598 mdelay(1); 2543 } else {
2544 restart_timer = 1;
2545 }
2546 }
2547 break;
2548
2549 case lcheck:
2550 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2551 lpa = tc_mdio_read(dev, pid, MII_LPA);
2552 if (bmcr & (BMCR_PDOWN | BMCR_ISOLATE | BMCR_RESET)) {
2553 printk(KERN_ERR "%s: PHY down? (BMCR %x)\n", dev->name,
2554 bmcr);
2555 } else if ((lp->saved_lpa ^ lpa) &
2556 (LPA_100FULL|LPA_100HALF|LPA_10FULL|LPA_10HALF)) {
2557 printk(KERN_NOTICE "%s: link status changed"
2558 " (BMCR %x LPA %x->%x)\n", dev->name,
2559 bmcr, lp->saved_lpa, lpa);
2560 } else {
2561 /* go on */
2562 restart_timer = 1;
2563 break;
2564 }
2565 /* Try to restart the adaptor. */
2566 tc35815_restart(dev);
2567 goto out;
2568
2569 case asleep:
2570 default:
2571 /* Can't happens.... */
2572 printk(KERN_ERR "%s: Aieee, link timer is asleep but we got "
2573 "one anyways!\n", dev->name);
2574 restart_timer = 0;
2575 lp->timer_ticks = 0;
2576 lp->timer_state = asleep; /* foo on you */
2577 break;
2578 }
2579
2580 if (restart_timer) {
2581 lp->timer.expires = jiffies + msecs_to_jiffies(1200);
2582 add_timer(&lp->timer);
2583 }
2584out:
2585 spin_unlock_irq(&lp->lock);
2586}
2587
2588static void tc35815_start_auto_negotiation(struct net_device *dev,
2589 struct ethtool_cmd *ep)
2590{
2591 struct tc35815_local *lp = dev->priv;
2592 int pid = lp->phy_addr;
2593 unsigned short bmsr, bmcr, advertize;
2594 int timeout;
2595
2596 netif_carrier_off(dev);
2597 bmsr = tc_mdio_read(dev, pid, MII_BMSR);
2598 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2599 advertize = tc_mdio_read(dev, pid, MII_ADVERTISE);
2600
2601 if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
2602 if (options.speed || options.duplex) {
2603 /* Advertise only specified configuration. */
2604 advertize &= ~(ADVERTISE_10HALF |
2605 ADVERTISE_10FULL |
2606 ADVERTISE_100HALF |
2607 ADVERTISE_100FULL);
2608 if (options.speed != 10) {
2609 if (options.duplex != 1)
2610 advertize |= ADVERTISE_100FULL;
2611 if (options.duplex != 2)
2612 advertize |= ADVERTISE_100HALF;
2613 }
2614 if (options.speed != 100) {
2615 if (options.duplex != 1)
2616 advertize |= ADVERTISE_10FULL;
2617 if (options.duplex != 2)
2618 advertize |= ADVERTISE_10HALF;
1599 } 2619 }
1600 printk(" done.\n"); 2620 if (options.speed == 100)
1601 neg_result = tc_phy_read(dev, tr, 0, MII_ANLPAR); 2621 bmcr |= BMCR_SPEED100;
1602 if (neg_result & (MII_AN_TX_FDX | MII_AN_TX_HDX)) 2622 else if (options.speed == 10)
1603 lp->linkspeed = 100; 2623 bmcr &= ~BMCR_SPEED100;
2624 if (options.duplex == 2)
2625 bmcr |= BMCR_FULLDPLX;
2626 else if (options.duplex == 1)
2627 bmcr &= ~BMCR_FULLDPLX;
2628 } else {
2629 /* Advertise everything we can support. */
2630 if (bmsr & BMSR_10HALF)
2631 advertize |= ADVERTISE_10HALF;
1604 else 2632 else
1605 lp->linkspeed = 10; 2633 advertize &= ~ADVERTISE_10HALF;
1606 if (neg_result & (MII_AN_TX_FDX | MII_AN_10_FDX)) 2634 if (bmsr & BMSR_10FULL)
1607 lp->fullduplex = 1; 2635 advertize |= ADVERTISE_10FULL;
1608 else 2636 else
1609 lp->fullduplex = 0; 2637 advertize &= ~ADVERTISE_10FULL;
1610 done: 2638 if (bmsr & BMSR_100HALF)
1611 ; 2639 advertize |= ADVERTISE_100HALF;
2640 else
2641 advertize &= ~ADVERTISE_100HALF;
2642 if (bmsr & BMSR_100FULL)
2643 advertize |= ADVERTISE_100FULL;
2644 else
2645 advertize &= ~ADVERTISE_100FULL;
2646 }
2647
2648 tc_mdio_write(dev, pid, MII_ADVERTISE, advertize);
2649
2650 /* Enable Auto-Negotiation, this is usually on already... */
2651 bmcr |= BMCR_ANENABLE;
2652 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2653
2654 /* Restart it to make sure it is going. */
2655 bmcr |= BMCR_ANRESTART;
2656 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2657 printk(KERN_DEBUG "%s: ADVERTISE %x BMCR %x\n", dev->name, advertize, bmcr);
2658
2659 /* BMCR_ANRESTART self clears when the process has begun. */
2660 timeout = 64; /* More than enough. */
2661 while (--timeout) {
2662 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2663 if (!(bmcr & BMCR_ANRESTART))
2664 break; /* got it. */
2665 udelay(10);
1612 } 2666 }
2667 if (!timeout) {
2668 printk(KERN_ERR "%s: TC35815 would not start auto "
2669 "negotiation BMCR=0x%04x\n",
2670 dev->name, bmcr);
2671 printk(KERN_NOTICE "%s: Performing force link "
2672 "detection.\n", dev->name);
2673 goto force_link;
2674 } else {
2675 printk(KERN_DEBUG "%s: auto negotiation started.\n", dev->name);
2676 lp->timer_state = arbwait;
2677 }
2678 } else {
2679force_link:
2680 /* Force the link up, trying first a particular mode.
2681 * Either we are here at the request of ethtool or
2682 * because the Happy Meal would not start to autoneg.
2683 */
2684
2685 /* Disable auto-negotiation in BMCR, enable the duplex and
2686 * speed setting, init the timer state machine, and fire it off.
2687 */
2688 if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
2689 bmcr = BMCR_SPEED100;
2690 } else {
2691 if (ep->speed == SPEED_100)
2692 bmcr = BMCR_SPEED100;
2693 else
2694 bmcr = 0;
2695 if (ep->duplex == DUPLEX_FULL)
2696 bmcr |= BMCR_FULLDPLX;
2697 }
2698 tc_mdio_write(dev, pid, MII_BMCR, bmcr);
2699
2700 /* OK, seems we need do disable the transceiver for the first
2701 * tick to make sure we get an accurate link state at the
2702 * second tick.
2703 */
2704 lp->timer_state = ltrywait;
1613 } 2705 }
1614 2706
1615 ctl = 0; 2707 del_timer(&lp->timer);
1616 if (lp->linkspeed == 100) 2708 lp->timer_ticks = 0;
1617 ctl |= MIICNTL_SPEED; 2709 lp->timer.expires = jiffies + msecs_to_jiffies(1200);
1618 if (lp->fullduplex) 2710 add_timer(&lp->timer);
1619 ctl |= MIICNTL_FDX; 2711}
1620 tc_phy_write(dev, ctl, tr, 0, MII_CONTROL);
1621 2712
1622 if (lp->fullduplex) { 2713static void tc35815_find_phy(struct net_device *dev)
1623 tc_writel(tc_readl(&tr->MAC_Ctl) | MAC_FullDup, &tr->MAC_Ctl); 2714{
2715 struct tc35815_local *lp = dev->priv;
2716 int pid = lp->phy_addr;
2717 unsigned short id0;
2718
2719 /* find MII phy */
2720 for (pid = 31; pid >= 0; pid--) {
2721 id0 = tc_mdio_read(dev, pid, MII_BMSR);
2722 if (id0 != 0xffff && id0 != 0x0000 &&
2723 (id0 & BMSR_RESV) != (0xffff & BMSR_RESV) /* paranoia? */
2724 ) {
2725 lp->phy_addr = pid;
2726 break;
2727 }
1624 } 2728 }
2729 if (pid < 0) {
2730 printk(KERN_ERR "%s: No MII Phy found.\n",
2731 dev->name);
2732 lp->phy_addr = pid = 0;
2733 }
2734
2735 lp->mii_id[0] = tc_mdio_read(dev, pid, MII_PHYSID1);
2736 lp->mii_id[1] = tc_mdio_read(dev, pid, MII_PHYSID2);
2737 if (netif_msg_hw(lp))
2738 printk(KERN_INFO "%s: PHY(%02x) ID %04x %04x\n", dev->name,
2739 pid, lp->mii_id[0], lp->mii_id[1]);
1625} 2740}
1626 2741
1627static void tc35815_chip_reset(struct net_device *dev) 2742static void tc35815_phy_chip_init(struct net_device *dev)
1628{ 2743{
1629 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr; 2744 struct tc35815_local *lp = dev->priv;
2745 int pid = lp->phy_addr;
2746 unsigned short bmcr;
2747 struct ethtool_cmd ecmd, *ep;
2748
2749 /* dis-isolate if needed. */
2750 bmcr = tc_mdio_read(dev, pid, MII_BMCR);
2751 if (bmcr & BMCR_ISOLATE) {
2752 int count = 32;
2753 printk(KERN_DEBUG "%s: unisolating...", dev->name);
2754 tc_mdio_write(dev, pid, MII_BMCR, bmcr & ~BMCR_ISOLATE);
2755 while (--count) {
2756 if (!(tc_mdio_read(dev, pid, MII_BMCR) & BMCR_ISOLATE))
2757 break;
2758 udelay(20);
2759 }
2760 printk(" %s.\n", count ? "done" : "failed");
2761 }
2762
2763 if (options.speed && options.duplex) {
2764 ecmd.autoneg = AUTONEG_DISABLE;
2765 ecmd.speed = options.speed == 10 ? SPEED_10 : SPEED_100;
2766 ecmd.duplex = options.duplex == 1 ? DUPLEX_HALF : DUPLEX_FULL;
2767 ep = &ecmd;
2768 } else {
2769 ep = NULL;
2770 }
2771 tc35815_start_auto_negotiation(dev, ep);
2772}
1630 2773
2774static void tc35815_chip_reset(struct net_device *dev)
2775{
2776 struct tc35815_regs __iomem *tr =
2777 (struct tc35815_regs __iomem *)dev->base_addr;
2778 int i;
1631 /* reset the controller */ 2779 /* reset the controller */
1632 tc_writel(MAC_Reset, &tr->MAC_Ctl); 2780 tc_writel(MAC_Reset, &tr->MAC_Ctl);
1633 while (tc_readl(&tr->MAC_Ctl) & MAC_Reset) 2781 udelay(4); /* 3200ns */
1634 ; 2782 i = 0;
1635 2783 while (tc_readl(&tr->MAC_Ctl) & MAC_Reset) {
2784 if (i++ > 100) {
2785 printk(KERN_ERR "%s: MAC reset failed.\n", dev->name);
2786 break;
2787 }
2788 mdelay(1);
2789 }
1636 tc_writel(0, &tr->MAC_Ctl); 2790 tc_writel(0, &tr->MAC_Ctl);
1637 2791
1638 /* initialize registers to default value */ 2792 /* initialize registers to default value */
@@ -1650,90 +2804,142 @@ static void tc35815_chip_reset(struct net_device *dev)
1650 tc_writel(0, &tr->CAM_Ena); 2804 tc_writel(0, &tr->CAM_Ena);
1651 (void)tc_readl(&tr->Miss_Cnt); /* Read to clear */ 2805 (void)tc_readl(&tr->Miss_Cnt); /* Read to clear */
1652 2806
2807 /* initialize internal SRAM */
2808 tc_writel(DMA_TestMode, &tr->DMA_Ctl);
2809 for (i = 0; i < 0x1000; i += 4) {
2810 tc_writel(i, &tr->CAM_Adr);
2811 tc_writel(0, &tr->CAM_Data);
2812 }
2813 tc_writel(0, &tr->DMA_Ctl);
1653} 2814}
1654 2815
1655static void tc35815_chip_init(struct net_device *dev) 2816static void tc35815_chip_init(struct net_device *dev)
1656{ 2817{
1657 struct tc35815_local *lp = dev->priv; 2818 struct tc35815_local *lp = dev->priv;
1658 struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr; 2819 struct tc35815_regs __iomem *tr =
1659 unsigned long flags; 2820 (struct tc35815_regs __iomem *)dev->base_addr;
1660 unsigned long txctl = TX_CTL_CMD; 2821 unsigned long txctl = TX_CTL_CMD;
1661 2822
1662 tc35815_phy_chip_init(dev); 2823 tc35815_phy_chip_init(dev);
1663 2824
1664 /* load station address to CAM */ 2825 /* load station address to CAM */
1665 tc35815_set_cam_entry(tr, CAM_ENTRY_SOURCE, dev->dev_addr); 2826 tc35815_set_cam_entry(dev, CAM_ENTRY_SOURCE, dev->dev_addr);
1666 2827
1667 /* Enable CAM (broadcast and unicast) */ 2828 /* Enable CAM (broadcast and unicast) */
1668 tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena); 2829 tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena);
1669 tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl); 2830 tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl);
1670 2831
1671 spin_lock_irqsave(&lp->lock, flags); 2832 /* Use DMA_RxAlign_2 to make IP header 4-byte aligned. */
1672 2833 if (HAVE_DMA_RXALIGN(lp))
1673 tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl); 2834 tc_writel(DMA_BURST_SIZE | DMA_RxAlign_2, &tr->DMA_Ctl);
1674 2835 else
2836 tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl);
2837#ifdef TC35815_USE_PACKEDBUFFER
1675 tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize); /* Packing */ 2838 tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize); /* Packing */
2839#else
2840 tc_writel(ETH_ZLEN, &tr->RxFragSize);
2841#endif
1676 tc_writel(0, &tr->TxPollCtr); /* Batch mode */ 2842 tc_writel(0, &tr->TxPollCtr); /* Batch mode */
1677 tc_writel(TX_THRESHOLD, &tr->TxThrsh); 2843 tc_writel(TX_THRESHOLD, &tr->TxThrsh);
1678 tc_writel(INT_EN_CMD, &tr->Int_En); 2844 tc_writel(INT_EN_CMD, &tr->Int_En);
1679 2845
1680 /* set queues */ 2846 /* set queues */
1681 tc_writel(virt_to_bus(lp->rfd_base), &tr->FDA_Bas); 2847 tc_writel(fd_virt_to_bus(lp, lp->rfd_base), &tr->FDA_Bas);
1682 tc_writel((unsigned long)lp->rfd_limit - (unsigned long)lp->rfd_base, 2848 tc_writel((unsigned long)lp->rfd_limit - (unsigned long)lp->rfd_base,
1683 &tr->FDA_Lim); 2849 &tr->FDA_Lim);
1684 /* 2850 /*
1685 * Activation method: 2851 * Activation method:
1686 * First, enable eht MAC Transmitter and the DMA Receive circuits. 2852 * First, enable the MAC Transmitter and the DMA Receive circuits.
1687 * Then enable the DMA Transmitter and the MAC Receive circuits. 2853 * Then enable the DMA Transmitter and the MAC Receive circuits.
1688 */ 2854 */
1689 tc_writel(virt_to_bus(lp->fbl_ptr), &tr->BLFrmPtr); /* start DMA receiver */ 2855 tc_writel(fd_virt_to_bus(lp, lp->fbl_ptr), &tr->BLFrmPtr); /* start DMA receiver */
1690 tc_writel(RX_CTL_CMD, &tr->Rx_Ctl); /* start MAC receiver */ 2856 tc_writel(RX_CTL_CMD, &tr->Rx_Ctl); /* start MAC receiver */
2857
1691 /* start MAC transmitter */ 2858 /* start MAC transmitter */
2859#ifndef NO_CHECK_CARRIER
2860 /* TX4939 does not have EnLCarr */
2861 if (lp->boardtype == TC35815_TX4939)
2862 txctl &= ~Tx_EnLCarr;
2863#ifdef WORKAROUND_LOSTCAR
1692 /* WORKAROUND: ignore LostCrS in full duplex operation */ 2864 /* WORKAROUND: ignore LostCrS in full duplex operation */
1693 if (lp->fullduplex) 2865 if ((lp->timer_state != asleep && lp->timer_state != lcheck) ||
1694 txctl = TX_CTL_CMD & ~Tx_EnLCarr; 2866 lp->fullduplex)
2867 txctl &= ~Tx_EnLCarr;
2868#endif
2869#endif /* !NO_CHECK_CARRIER */
1695#ifdef GATHER_TXINT 2870#ifdef GATHER_TXINT
1696 txctl &= ~Tx_EnComp; /* disable global tx completion int. */ 2871 txctl &= ~Tx_EnComp; /* disable global tx completion int. */
1697#endif 2872#endif
1698 tc_writel(txctl, &tr->Tx_Ctl); 2873 tc_writel(txctl, &tr->Tx_Ctl);
1699#if 0 /* No need to polling */ 2874}
1700 tc_writel(virt_to_bus(lp->tfd_base), &tr->TxFrmPtr); /* start DMA transmitter */ 2875
1701#endif 2876#ifdef CONFIG_PM
2877static int tc35815_suspend(struct pci_dev *pdev, pm_message_t state)
2878{
2879 struct net_device *dev = pci_get_drvdata(pdev);
2880 struct tc35815_local *lp = dev->priv;
2881 unsigned long flags;
2882
2883 pci_save_state(pdev);
2884 if (!netif_running(dev))
2885 return 0;
2886 netif_device_detach(dev);
2887 spin_lock_irqsave(&lp->lock, flags);
2888 del_timer(&lp->timer); /* Kill if running */
2889 tc35815_chip_reset(dev);
1702 spin_unlock_irqrestore(&lp->lock, flags); 2890 spin_unlock_irqrestore(&lp->lock, flags);
2891 pci_set_power_state(pdev, PCI_D3hot);
2892 return 0;
1703} 2893}
1704 2894
1705static struct pci_driver tc35815_driver = { 2895static int tc35815_resume(struct pci_dev *pdev)
1706 .name = TC35815_MODULE_NAME, 2896{
1707 .probe = tc35815_probe, 2897 struct net_device *dev = pci_get_drvdata(pdev);
1708 .remove = NULL, 2898 struct tc35815_local *lp = dev->priv;
1709 .id_table = tc35815_pci_tbl, 2899 unsigned long flags;
2900
2901 pci_restore_state(pdev);
2902 if (!netif_running(dev))
2903 return 0;
2904 pci_set_power_state(pdev, PCI_D0);
2905 spin_lock_irqsave(&lp->lock, flags);
2906 tc35815_restart(dev);
2907 spin_unlock_irqrestore(&lp->lock, flags);
2908 netif_device_attach(dev);
2909 return 0;
2910}
2911#endif /* CONFIG_PM */
2912
2913static struct pci_driver tc35815_pci_driver = {
2914 .name = MODNAME,
2915 .id_table = tc35815_pci_tbl,
2916 .probe = tc35815_init_one,
2917 .remove = __devexit_p(tc35815_remove_one),
2918#ifdef CONFIG_PM
2919 .suspend = tc35815_suspend,
2920 .resume = tc35815_resume,
2921#endif
1710}; 2922};
1711 2923
2924module_param_named(speed, options.speed, int, 0);
2925MODULE_PARM_DESC(speed, "0:auto, 10:10Mbps, 100:100Mbps");
2926module_param_named(duplex, options.duplex, int, 0);
2927MODULE_PARM_DESC(duplex, "0:auto, 1:half, 2:full");
2928module_param_named(doforce, options.doforce, int, 0);
2929MODULE_PARM_DESC(doforce, "try force link mode if auto-negotiation failed");
2930
1712static int __init tc35815_init_module(void) 2931static int __init tc35815_init_module(void)
1713{ 2932{
1714 return pci_register_driver(&tc35815_driver); 2933 return pci_register_driver(&tc35815_pci_driver);
1715} 2934}
1716 2935
1717static void __exit tc35815_cleanup_module(void) 2936static void __exit tc35815_cleanup_module(void)
1718{ 2937{
1719 struct net_device *next_dev; 2938 pci_unregister_driver(&tc35815_pci_driver);
1720
1721 /*
1722 * TODO: implement a tc35815_driver.remove hook, and
1723 * move this code into that function. Then, delete
1724 * all root_tc35815_dev list handling code.
1725 */
1726 while (root_tc35815_dev) {
1727 struct net_device *dev = root_tc35815_dev;
1728 next_dev = ((struct tc35815_local *)dev->priv)->next_module;
1729 iounmap((void *)(dev->base_addr));
1730 unregister_netdev(dev);
1731 free_netdev(dev);
1732 root_tc35815_dev = next_dev;
1733 }
1734
1735 pci_unregister_driver(&tc35815_driver);
1736} 2939}
1737 2940
1738module_init(tc35815_init_module); 2941module_init(tc35815_init_module);
1739module_exit(tc35815_cleanup_module); 2942module_exit(tc35815_cleanup_module);
2943
2944MODULE_DESCRIPTION("TOSHIBA TC35815 PCI 10M/100M Ethernet driver");
2945MODULE_LICENSE("GPL");
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index b3a64ca98634..4ed67ff0e81e 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -55,9 +55,6 @@
55 55
56 TODO 56 TODO
57 57
58 Implement pci_driver::suspend() and pci_driver::resume()
59 power management methods.
60
61 Check on 64 bit boxes. 58 Check on 64 bit boxes.
62 Check and fix on big endian boxes. 59 Check and fix on big endian boxes.
63 60
@@ -125,6 +122,11 @@
125#define DM9801_NOISE_FLOOR 8 122#define DM9801_NOISE_FLOOR 8
126#define DM9802_NOISE_FLOOR 5 123#define DM9802_NOISE_FLOOR 5
127 124
125#define DMFE_WOL_LINKCHANGE 0x20000000
126#define DMFE_WOL_SAMPLEPACKET 0x10000000
127#define DMFE_WOL_MAGICPACKET 0x08000000
128
129
128#define DMFE_10MHF 0 130#define DMFE_10MHF 0
129#define DMFE_100MHF 1 131#define DMFE_100MHF 1
130#define DMFE_10MFD 4 132#define DMFE_10MFD 4
@@ -251,6 +253,7 @@ struct dmfe_board_info {
251 u8 wait_reset; /* Hardware failed, need to reset */ 253 u8 wait_reset; /* Hardware failed, need to reset */
252 u8 dm910x_chk_mode; /* Operating mode check */ 254 u8 dm910x_chk_mode; /* Operating mode check */
253 u8 first_in_callback; /* Flag to record state */ 255 u8 first_in_callback; /* Flag to record state */
256 u8 wol_mode; /* user WOL settings */
254 struct timer_list timer; 257 struct timer_list timer;
255 258
256 /* System defined statistic counter */ 259 /* System defined statistic counter */
@@ -431,6 +434,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
431 db->chip_id = ent->driver_data; 434 db->chip_id = ent->driver_data;
432 db->ioaddr = pci_resource_start(pdev, 0); 435 db->ioaddr = pci_resource_start(pdev, 0);
433 db->chip_revision = dev_rev; 436 db->chip_revision = dev_rev;
437 db->wol_mode = 0;
434 438
435 db->pdev = pdev; 439 db->pdev = pdev;
436 440
@@ -1065,7 +1069,11 @@ static void dmfe_set_filter_mode(struct DEVICE * dev)
1065 spin_unlock_irqrestore(&db->lock, flags); 1069 spin_unlock_irqrestore(&db->lock, flags);
1066} 1070}
1067 1071
1068static void netdev_get_drvinfo(struct net_device *dev, 1072/*
1073 * Ethtool interace
1074 */
1075
1076static void dmfe_ethtool_get_drvinfo(struct net_device *dev,
1069 struct ethtool_drvinfo *info) 1077 struct ethtool_drvinfo *info)
1070{ 1078{
1071 struct dmfe_board_info *np = netdev_priv(dev); 1079 struct dmfe_board_info *np = netdev_priv(dev);
@@ -1079,9 +1087,35 @@ static void netdev_get_drvinfo(struct net_device *dev,
1079 dev->base_addr, dev->irq); 1087 dev->base_addr, dev->irq);
1080} 1088}
1081 1089
1090static int dmfe_ethtool_set_wol(struct net_device *dev,
1091 struct ethtool_wolinfo *wolinfo)
1092{
1093 struct dmfe_board_info *db = netdev_priv(dev);
1094
1095 if (wolinfo->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
1096 WAKE_ARP | WAKE_MAGICSECURE))
1097 return -EOPNOTSUPP;
1098
1099 db->wol_mode = wolinfo->wolopts;
1100 return 0;
1101}
1102
1103static void dmfe_ethtool_get_wol(struct net_device *dev,
1104 struct ethtool_wolinfo *wolinfo)
1105{
1106 struct dmfe_board_info *db = netdev_priv(dev);
1107
1108 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
1109 wolinfo->wolopts = db->wol_mode;
1110 return;
1111}
1112
1113
1082static const struct ethtool_ops netdev_ethtool_ops = { 1114static const struct ethtool_ops netdev_ethtool_ops = {
1083 .get_drvinfo = netdev_get_drvinfo, 1115 .get_drvinfo = dmfe_ethtool_get_drvinfo,
1084 .get_link = ethtool_op_get_link, 1116 .get_link = ethtool_op_get_link,
1117 .set_wol = dmfe_ethtool_set_wol,
1118 .get_wol = dmfe_ethtool_get_wol,
1085}; 1119};
1086 1120
1087/* 1121/*
@@ -2050,11 +2084,85 @@ static struct pci_device_id dmfe_pci_tbl[] = {
2050MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); 2084MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
2051 2085
2052 2086
2087#ifdef CONFIG_PM
2088static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
2089{
2090 struct net_device *dev = pci_get_drvdata(pci_dev);
2091 struct dmfe_board_info *db = netdev_priv(dev);
2092 u32 tmp;
2093
2094 /* Disable upper layer interface */
2095 netif_device_detach(dev);
2096
2097 /* Disable Tx/Rx */
2098 db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);
2099 update_cr6(db->cr6_data, dev->base_addr);
2100
2101 /* Disable Interrupt */
2102 outl(0, dev->base_addr + DCR7);
2103 outl(inl (dev->base_addr + DCR5), dev->base_addr + DCR5);
2104
2105 /* Fre RX buffers */
2106 dmfe_free_rxbuffer(db);
2107
2108 /* Enable WOL */
2109 pci_read_config_dword(pci_dev, 0x40, &tmp);
2110 tmp &= ~(DMFE_WOL_LINKCHANGE|DMFE_WOL_MAGICPACKET);
2111
2112 if (db->wol_mode & WAKE_PHY)
2113 tmp |= DMFE_WOL_LINKCHANGE;
2114 if (db->wol_mode & WAKE_MAGIC)
2115 tmp |= DMFE_WOL_MAGICPACKET;
2116
2117 pci_write_config_dword(pci_dev, 0x40, tmp);
2118
2119 pci_enable_wake(pci_dev, PCI_D3hot, 1);
2120 pci_enable_wake(pci_dev, PCI_D3cold, 1);
2121
2122 /* Power down device*/
2123 pci_set_power_state(pci_dev, pci_choose_state (pci_dev,state));
2124 pci_save_state(pci_dev);
2125
2126 return 0;
2127}
2128
2129static int dmfe_resume(struct pci_dev *pci_dev)
2130{
2131 struct net_device *dev = pci_get_drvdata(pci_dev);
2132 u32 tmp;
2133
2134 pci_restore_state(pci_dev);
2135 pci_set_power_state(pci_dev, PCI_D0);
2136
2137 /* Re-initilize DM910X board */
2138 dmfe_init_dm910x(dev);
2139
2140 /* Disable WOL */
2141 pci_read_config_dword(pci_dev, 0x40, &tmp);
2142
2143 tmp &= ~(DMFE_WOL_LINKCHANGE | DMFE_WOL_MAGICPACKET);
2144 pci_write_config_dword(pci_dev, 0x40, tmp);
2145
2146 pci_enable_wake(pci_dev, PCI_D3hot, 0);
2147 pci_enable_wake(pci_dev, PCI_D3cold, 0);
2148
2149 /* Restart upper layer interface */
2150 netif_device_attach(dev);
2151
2152 return 0;
2153}
2154#else
2155#define dmfe_suspend NULL
2156#define dmfe_resume NULL
2157#endif
2158
2053static struct pci_driver dmfe_driver = { 2159static struct pci_driver dmfe_driver = {
2054 .name = "dmfe", 2160 .name = "dmfe",
2055 .id_table = dmfe_pci_tbl, 2161 .id_table = dmfe_pci_tbl,
2056 .probe = dmfe_init_one, 2162 .probe = dmfe_init_one,
2057 .remove = __devexit_p(dmfe_remove_one), 2163 .remove = __devexit_p(dmfe_remove_one),
2164 .suspend = dmfe_suspend,
2165 .resume = dmfe_resume
2058}; 2166};
2059 2167
2060MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); 2168MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index e86df07769a1..9b08afbd1f65 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -673,7 +673,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
673 if (tp->link_change) 673 if (tp->link_change)
674 (tp->link_change)(dev, csr5); 674 (tp->link_change)(dev, csr5);
675 } 675 }
676 if (csr5 & SytemError) { 676 if (csr5 & SystemError) {
677 int error = (csr5 >> 23) & 7; 677 int error = (csr5 >> 23) & 7;
678 /* oops, we hit a PCI error. The code produced corresponds 678 /* oops, we hit a PCI error. The code produced corresponds
679 * to the reason: 679 * to the reason:
@@ -743,7 +743,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
743 TxFIFOUnderflow | 743 TxFIFOUnderflow |
744 TxJabber | 744 TxJabber |
745 TPLnkFail | 745 TPLnkFail |
746 SytemError )) != 0); 746 SystemError )) != 0);
747#else 747#else
748 } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0); 748 } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
749 749
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index 20bd52b86993..b56256636543 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -44,8 +44,10 @@ static const unsigned char comet_miireg2offset[32] = {
44 44
45/* MII transceiver control section. 45/* MII transceiver control section.
46 Read and write the MII registers using software-generated serial 46 Read and write the MII registers using software-generated serial
47 MDIO protocol. See the MII specifications or DP83840A data sheet 47 MDIO protocol.
48 for details. */ 48 See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
49 or DP83840A data sheet for more details.
50 */
49 51
50int tulip_mdio_read(struct net_device *dev, int phy_id, int location) 52int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
51{ 53{
@@ -261,24 +263,56 @@ void tulip_select_media(struct net_device *dev, int startup)
261 u16 *reset_sequence = &((u16*)(p+3))[init_length]; 263 u16 *reset_sequence = &((u16*)(p+3))[init_length];
262 int reset_length = p[2 + init_length*2]; 264 int reset_length = p[2 + init_length*2];
263 misc_info = reset_sequence + reset_length; 265 misc_info = reset_sequence + reset_length;
264 if (startup) 266 if (startup) {
267 int timeout = 10; /* max 1 ms */
265 for (i = 0; i < reset_length; i++) 268 for (i = 0; i < reset_length; i++)
266 iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); 269 iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
270
271 /* flush posted writes */
272 ioread32(ioaddr + CSR15);
273
274 /* Sect 3.10.3 in DP83840A.pdf (p39) */
275 udelay(500);
276
277 /* Section 4.2 in DP83840A.pdf (p43) */
278 /* and IEEE 802.3 "22.2.4.1.1 Reset" */
279 while (timeout-- &&
280 (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
281 udelay(100);
282 }
267 for (i = 0; i < init_length; i++) 283 for (i = 0; i < init_length; i++)
268 iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); 284 iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
285
286 ioread32(ioaddr + CSR15); /* flush posted writes */
269 } else { 287 } else {
270 u8 *init_sequence = p + 2; 288 u8 *init_sequence = p + 2;
271 u8 *reset_sequence = p + 3 + init_length; 289 u8 *reset_sequence = p + 3 + init_length;
272 int reset_length = p[2 + init_length]; 290 int reset_length = p[2 + init_length];
273 misc_info = (u16*)(reset_sequence + reset_length); 291 misc_info = (u16*)(reset_sequence + reset_length);
274 if (startup) { 292 if (startup) {
293 int timeout = 10; /* max 1 ms */
275 iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); 294 iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
276 for (i = 0; i < reset_length; i++) 295 for (i = 0; i < reset_length; i++)
277 iowrite32(reset_sequence[i], ioaddr + CSR12); 296 iowrite32(reset_sequence[i], ioaddr + CSR12);
297
298 /* flush posted writes */
299 ioread32(ioaddr + CSR12);
300
301 /* Sect 3.10.3 in DP83840A.pdf (p39) */
302 udelay(500);
303
304 /* Section 4.2 in DP83840A.pdf (p43) */
305 /* and IEEE 802.3 "22.2.4.1.1 Reset" */
306 while (timeout-- &&
307 (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
308 udelay(100);
278 } 309 }
279 for (i = 0; i < init_length; i++) 310 for (i = 0; i < init_length; i++)
280 iowrite32(init_sequence[i], ioaddr + CSR12); 311 iowrite32(init_sequence[i], ioaddr + CSR12);
312
313 ioread32(ioaddr + CSR12); /* flush posted writes */
281 } 314 }
315
282 tmp_info = get_u16(&misc_info[1]); 316 tmp_info = get_u16(&misc_info[1]);
283 if (tmp_info) 317 if (tmp_info)
284 tp->advertising[phy_num] = tmp_info | 1; 318 tp->advertising[phy_num] = tmp_info | 1;
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 25f25da76917..c840d2e67b23 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -132,7 +132,7 @@ enum pci_cfg_driver_reg {
132/* The bits in the CSR5 status registers, mostly interrupt sources. */ 132/* The bits in the CSR5 status registers, mostly interrupt sources. */
133enum status_bits { 133enum status_bits {
134 TimerInt = 0x800, 134 TimerInt = 0x800,
135 SytemError = 0x2000, 135 SystemError = 0x2000,
136 TPLnkFail = 0x1000, 136 TPLnkFail = 0x1000,
137 TPLnkPass = 0x10, 137 TPLnkPass = 0x10,
138 NormalIntr = 0x10000, 138 NormalIntr = 0x10000,
@@ -482,8 +482,11 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
482 udelay(10); 482 udelay(10);
483 483
484 if (!i) 484 if (!i)
485 printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", 485 printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
486 pci_name(tp->pdev)); 486 " (CSR5 0x%x CSR6 0x%x)\n",
487 pci_name(tp->pdev),
488 ioread32(ioaddr + CSR5),
489 ioread32(ioaddr + CSR6));
487 } 490 }
488} 491}
489 492
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index e9bf526ec534..041af63f2811 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -17,11 +17,11 @@
17 17
18#define DRV_NAME "tulip" 18#define DRV_NAME "tulip"
19#ifdef CONFIG_TULIP_NAPI 19#ifdef CONFIG_TULIP_NAPI
20#define DRV_VERSION "1.1.14-NAPI" /* Keep at least for test */ 20#define DRV_VERSION "1.1.15-NAPI" /* Keep at least for test */
21#else 21#else
22#define DRV_VERSION "1.1.14" 22#define DRV_VERSION "1.1.15"
23#endif 23#endif
24#define DRV_RELDATE "May 11, 2002" 24#define DRV_RELDATE "Feb 27, 2007"
25 25
26 26
27#include <linux/module.h> 27#include <linux/module.h>
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 5b71ac78bca2..fa440706fb4a 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1147,7 +1147,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
1147 } 1147 }
1148 1148
1149 /* Abnormal error summary/uncommon events handlers. */ 1149 /* Abnormal error summary/uncommon events handlers. */
1150 if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError | 1150 if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SystemError |
1151 TimerInt | TxDied)) 1151 TimerInt | TxDied))
1152 netdev_error(dev, intr_status); 1152 netdev_error(dev, intr_status);
1153 1153
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 639e1e6913bf..16b9acdabbe8 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -29,6 +29,7 @@
29#include <linux/fsl_devices.h> 29#include <linux/fsl_devices.h>
30#include <linux/ethtool.h> 30#include <linux/ethtool.h>
31#include <linux/mii.h> 31#include <linux/mii.h>
32#include <linux/phy.h>
32#include <linux/workqueue.h> 33#include <linux/workqueue.h>
33 34
34#include <asm/of_platform.h> 35#include <asm/of_platform.h>
@@ -41,12 +42,13 @@
41#include <asm/ucc_fast.h> 42#include <asm/ucc_fast.h>
42 43
43#include "ucc_geth.h" 44#include "ucc_geth.h"
44#include "ucc_geth_phy.h" 45#include "ucc_geth_mii.h"
45 46
46#undef DEBUG 47#undef DEBUG
47 48
48#define DRV_DESC "QE UCC Gigabit Ethernet Controller version:Sept 11, 2006" 49#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
49#define DRV_NAME "ucc_geth" 50#define DRV_NAME "ucc_geth"
51#define DRV_VERSION "1.1"
50 52
51#define ugeth_printk(level, format, arg...) \ 53#define ugeth_printk(level, format, arg...) \
52 printk(level format "\n", ## arg) 54 printk(level format "\n", ## arg)
@@ -73,22 +75,13 @@ static struct ucc_geth_info ugeth_primary_info = {
73 .bd_mem_part = MEM_PART_SYSTEM, 75 .bd_mem_part = MEM_PART_SYSTEM,
74 .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, 76 .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
75 .max_rx_buf_length = 1536, 77 .max_rx_buf_length = 1536,
76/* FIXME: should be changed in run time for 1G and 100M */ 78 /* adjusted at startup if max-speed 1000 */
77#ifdef CONFIG_UGETH_HAS_GIGA
78 .urfs = UCC_GETH_URFS_GIGA_INIT,
79 .urfet = UCC_GETH_URFET_GIGA_INIT,
80 .urfset = UCC_GETH_URFSET_GIGA_INIT,
81 .utfs = UCC_GETH_UTFS_GIGA_INIT,
82 .utfet = UCC_GETH_UTFET_GIGA_INIT,
83 .utftt = UCC_GETH_UTFTT_GIGA_INIT,
84#else
85 .urfs = UCC_GETH_URFS_INIT, 79 .urfs = UCC_GETH_URFS_INIT,
86 .urfet = UCC_GETH_URFET_INIT, 80 .urfet = UCC_GETH_URFET_INIT,
87 .urfset = UCC_GETH_URFSET_INIT, 81 .urfset = UCC_GETH_URFSET_INIT,
88 .utfs = UCC_GETH_UTFS_INIT, 82 .utfs = UCC_GETH_UTFS_INIT,
89 .utfet = UCC_GETH_UTFET_INIT, 83 .utfet = UCC_GETH_UTFET_INIT,
90 .utftt = UCC_GETH_UTFTT_INIT, 84 .utftt = UCC_GETH_UTFTT_INIT,
91#endif
92 .ufpt = 256, 85 .ufpt = 256,
93 .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET, 86 .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET,
94 .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL, 87 .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL,
@@ -217,70 +210,6 @@ static struct list_head *dequeue(struct list_head *lh)
217 } 210 }
218} 211}
219 212
220static int get_interface_details(enum enet_interface enet_interface,
221 enum enet_speed *speed,
222 int *r10m,
223 int *rmm,
224 int *rpm,
225 int *tbi, int *limited_to_full_duplex)
226{
227 /* Analyze enet_interface according to Interface Mode
228 Configuration table */
229 switch (enet_interface) {
230 case ENET_10_MII:
231 *speed = ENET_SPEED_10BT;
232 break;
233 case ENET_10_RMII:
234 *speed = ENET_SPEED_10BT;
235 *r10m = 1;
236 *rmm = 1;
237 break;
238 case ENET_10_RGMII:
239 *speed = ENET_SPEED_10BT;
240 *rpm = 1;
241 *r10m = 1;
242 *limited_to_full_duplex = 1;
243 break;
244 case ENET_100_MII:
245 *speed = ENET_SPEED_100BT;
246 break;
247 case ENET_100_RMII:
248 *speed = ENET_SPEED_100BT;
249 *rmm = 1;
250 break;
251 case ENET_100_RGMII:
252 *speed = ENET_SPEED_100BT;
253 *rpm = 1;
254 *limited_to_full_duplex = 1;
255 break;
256 case ENET_1000_GMII:
257 *speed = ENET_SPEED_1000BT;
258 *limited_to_full_duplex = 1;
259 break;
260 case ENET_1000_RGMII:
261 *speed = ENET_SPEED_1000BT;
262 *rpm = 1;
263 *limited_to_full_duplex = 1;
264 break;
265 case ENET_1000_TBI:
266 *speed = ENET_SPEED_1000BT;
267 *tbi = 1;
268 *limited_to_full_duplex = 1;
269 break;
270 case ENET_1000_RTBI:
271 *speed = ENET_SPEED_1000BT;
272 *rpm = 1;
273 *tbi = 1;
274 *limited_to_full_duplex = 1;
275 break;
276 default:
277 return -EINVAL;
278 break;
279 }
280
281 return 0;
282}
283
284static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) 213static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
285{ 214{
286 struct sk_buff *skb = NULL; 215 struct sk_buff *skb = NULL;
@@ -758,24 +687,6 @@ static void dump_regs(struct ucc_geth_private *ugeth)
758 ugeth_info("hafdup : addr - 0x%08x, val - 0x%08x", 687 ugeth_info("hafdup : addr - 0x%08x, val - 0x%08x",
759 (u32) & ugeth->ug_regs->hafdup, 688 (u32) & ugeth->ug_regs->hafdup,
760 in_be32(&ugeth->ug_regs->hafdup)); 689 in_be32(&ugeth->ug_regs->hafdup));
761 ugeth_info("miimcfg : addr - 0x%08x, val - 0x%08x",
762 (u32) & ugeth->ug_regs->miimng.miimcfg,
763 in_be32(&ugeth->ug_regs->miimng.miimcfg));
764 ugeth_info("miimcom : addr - 0x%08x, val - 0x%08x",
765 (u32) & ugeth->ug_regs->miimng.miimcom,
766 in_be32(&ugeth->ug_regs->miimng.miimcom));
767 ugeth_info("miimadd : addr - 0x%08x, val - 0x%08x",
768 (u32) & ugeth->ug_regs->miimng.miimadd,
769 in_be32(&ugeth->ug_regs->miimng.miimadd));
770 ugeth_info("miimcon : addr - 0x%08x, val - 0x%08x",
771 (u32) & ugeth->ug_regs->miimng.miimcon,
772 in_be32(&ugeth->ug_regs->miimng.miimcon));
773 ugeth_info("miimstat : addr - 0x%08x, val - 0x%08x",
774 (u32) & ugeth->ug_regs->miimng.miimstat,
775 in_be32(&ugeth->ug_regs->miimng.miimstat));
776 ugeth_info("miimmind : addr - 0x%08x, val - 0x%08x",
777 (u32) & ugeth->ug_regs->miimng.miimind,
778 in_be32(&ugeth->ug_regs->miimng.miimind));
779 ugeth_info("ifctl : addr - 0x%08x, val - 0x%08x", 690 ugeth_info("ifctl : addr - 0x%08x, val - 0x%08x",
780 (u32) & ugeth->ug_regs->ifctl, 691 (u32) & ugeth->ug_regs->ifctl,
781 in_be32(&ugeth->ug_regs->ifctl)); 692 in_be32(&ugeth->ug_regs->ifctl));
@@ -1425,27 +1336,6 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
1425 return 0; 1336 return 0;
1426} 1337}
1427 1338
1428static int init_mac_duplex_mode(int full_duplex,
1429 int limited_to_full_duplex,
1430 volatile u32 *maccfg2_register)
1431{
1432 u32 value = 0;
1433
1434 /* some interfaces must work in full duplex mode */
1435 if ((full_duplex == 0) && (limited_to_full_duplex == 1))
1436 return -EINVAL;
1437
1438 value = in_be32(maccfg2_register);
1439
1440 if (full_duplex)
1441 value |= MACCFG2_FDX;
1442 else
1443 value &= ~MACCFG2_FDX;
1444
1445 out_be32(maccfg2_register, value);
1446 return 0;
1447}
1448
1449static int init_check_frame_length_mode(int length_check, 1339static int init_check_frame_length_mode(int length_check,
1450 volatile u32 *maccfg2_register) 1340 volatile u32 *maccfg2_register)
1451{ 1341{
@@ -1477,40 +1367,6 @@ static int init_preamble_length(u8 preamble_length,
1477 return 0; 1367 return 0;
1478} 1368}
1479 1369
1480static int init_mii_management_configuration(int reset_mgmt,
1481 int preamble_supress,
1482 volatile u32 *miimcfg_register,
1483 volatile u32 *miimind_register)
1484{
1485 unsigned int timeout = PHY_INIT_TIMEOUT;
1486 u32 value = 0;
1487
1488 value = in_be32(miimcfg_register);
1489 if (reset_mgmt) {
1490 value |= MIIMCFG_RESET_MANAGEMENT;
1491 out_be32(miimcfg_register, value);
1492 }
1493
1494 value = 0;
1495
1496 if (preamble_supress)
1497 value |= MIIMCFG_NO_PREAMBLE;
1498
1499 value |= UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT;
1500 out_be32(miimcfg_register, value);
1501
1502 /* Wait until the bus is free */
1503 while ((in_be32(miimind_register) & MIIMIND_BUSY) && timeout--)
1504 cpu_relax();
1505
1506 if (timeout <= 0) {
1507 ugeth_err("%s: The MII Bus is stuck!", __FUNCTION__);
1508 return -ETIMEDOUT;
1509 }
1510
1511 return 0;
1512}
1513
1514static int init_rx_parameters(int reject_broadcast, 1370static int init_rx_parameters(int reject_broadcast,
1515 int receive_short_frames, 1371 int receive_short_frames,
1516 int promiscuous, volatile u32 *upsmr_register) 1372 int promiscuous, volatile u32 *upsmr_register)
@@ -1570,10 +1426,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1570 struct ucc_geth_info *ug_info; 1426 struct ucc_geth_info *ug_info;
1571 struct ucc_geth *ug_regs; 1427 struct ucc_geth *ug_regs;
1572 struct ucc_fast *uf_regs; 1428 struct ucc_fast *uf_regs;
1573 enum enet_speed speed; 1429 int ret_val;
1574 int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = 1430 u32 upsmr, maccfg2, tbiBaseAddress;
1575 0, limited_to_full_duplex = 0;
1576 u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
1577 u16 value; 1431 u16 value;
1578 1432
1579 ugeth_vdbg("%s: IN", __FUNCTION__); 1433 ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -1582,24 +1436,13 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1582 ug_regs = ugeth->ug_regs; 1436 ug_regs = ugeth->ug_regs;
1583 uf_regs = ugeth->uccf->uf_regs; 1437 uf_regs = ugeth->uccf->uf_regs;
1584 1438
1585 /* Analyze enet_interface according to Interface Mode Configuration
1586 table */
1587 ret_val =
1588 get_interface_details(ug_info->enet_interface, &speed, &r10m, &rmm,
1589 &rpm, &tbi, &limited_to_full_duplex);
1590 if (ret_val != 0) {
1591 ugeth_err
1592 ("%s: half duplex not supported in requested configuration.",
1593 __FUNCTION__);
1594 return ret_val;
1595 }
1596
1597 /* Set MACCFG2 */ 1439 /* Set MACCFG2 */
1598 maccfg2 = in_be32(&ug_regs->maccfg2); 1440 maccfg2 = in_be32(&ug_regs->maccfg2);
1599 maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK; 1441 maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
1600 if ((speed == ENET_SPEED_10BT) || (speed == ENET_SPEED_100BT)) 1442 if ((ugeth->max_speed == SPEED_10) ||
1443 (ugeth->max_speed == SPEED_100))
1601 maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; 1444 maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
1602 else if (speed == ENET_SPEED_1000BT) 1445 else if (ugeth->max_speed == SPEED_1000)
1603 maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; 1446 maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
1604 maccfg2 |= ug_info->padAndCrc; 1447 maccfg2 |= ug_info->padAndCrc;
1605 out_be32(&ug_regs->maccfg2, maccfg2); 1448 out_be32(&ug_regs->maccfg2, maccfg2);
@@ -1607,54 +1450,39 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1607 /* Set UPSMR */ 1450 /* Set UPSMR */
1608 upsmr = in_be32(&uf_regs->upsmr); 1451 upsmr = in_be32(&uf_regs->upsmr);
1609 upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM); 1452 upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM);
1610 if (rpm) 1453 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
1454 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
1455 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
1456 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1611 upsmr |= UPSMR_RPM; 1457 upsmr |= UPSMR_RPM;
1612 if (r10m) 1458 switch (ugeth->max_speed) {
1613 upsmr |= UPSMR_R10M; 1459 case SPEED_10:
1614 if (tbi) 1460 upsmr |= UPSMR_R10M;
1461 /* FALLTHROUGH */
1462 case SPEED_100:
1463 if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI)
1464 upsmr |= UPSMR_RMM;
1465 }
1466 }
1467 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
1468 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1615 upsmr |= UPSMR_TBIM; 1469 upsmr |= UPSMR_TBIM;
1616 if (rmm) 1470 }
1617 upsmr |= UPSMR_RMM;
1618 out_be32(&uf_regs->upsmr, upsmr); 1471 out_be32(&uf_regs->upsmr, upsmr);
1619 1472
1620 /* Set UTBIPAR */
1621 utbipar = in_be32(&ug_regs->utbipar);
1622 utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
1623 if (tbi)
1624 utbipar |=
1625 (ug_info->phy_address +
1626 ugeth->ug_info->uf_info.
1627 ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
1628 else
1629 utbipar |=
1630 (0x10 +
1631 ugeth->ug_info->uf_info.
1632 ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
1633 out_be32(&ug_regs->utbipar, utbipar);
1634
1635 /* Disable autonegotiation in tbi mode, because by default it 1473 /* Disable autonegotiation in tbi mode, because by default it
1636 comes up in autonegotiation mode. */ 1474 comes up in autonegotiation mode. */
1637 /* Note that this depends on proper setting in utbipar register. */ 1475 /* Note that this depends on proper setting in utbipar register. */
1638 if (tbi) { 1476 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
1477 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1639 tbiBaseAddress = in_be32(&ug_regs->utbipar); 1478 tbiBaseAddress = in_be32(&ug_regs->utbipar);
1640 tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK; 1479 tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK;
1641 tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT; 1480 tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT;
1642 value = 1481 value = ugeth->phydev->bus->read(ugeth->phydev->bus,
1643 ugeth->mii_info->mdio_read(ugeth->dev, (u8) tbiBaseAddress, 1482 (u8) tbiBaseAddress, ENET_TBI_MII_CR);
1644 ENET_TBI_MII_CR);
1645 value &= ~0x1000; /* Turn off autonegotiation */ 1483 value &= ~0x1000; /* Turn off autonegotiation */
1646 ugeth->mii_info->mdio_write(ugeth->dev, (u8) tbiBaseAddress, 1484 ugeth->phydev->bus->write(ugeth->phydev->bus,
1647 ENET_TBI_MII_CR, value); 1485 (u8) tbiBaseAddress, ENET_TBI_MII_CR, value);
1648 }
1649
1650 ret_val = init_mac_duplex_mode(1,
1651 limited_to_full_duplex,
1652 &ug_regs->maccfg2);
1653 if (ret_val != 0) {
1654 ugeth_err
1655 ("%s: half duplex not supported in requested configuration.",
1656 __FUNCTION__);
1657 return ret_val;
1658 } 1486 }
1659 1487
1660 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); 1488 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
@@ -1676,76 +1504,88 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1676 * function converts those variables into the appropriate 1504 * function converts those variables into the appropriate
1677 * register values, and can bring down the device if needed. 1505 * register values, and can bring down the device if needed.
1678 */ 1506 */
1507
1679static void adjust_link(struct net_device *dev) 1508static void adjust_link(struct net_device *dev)
1680{ 1509{
1681 struct ucc_geth_private *ugeth = netdev_priv(dev); 1510 struct ucc_geth_private *ugeth = netdev_priv(dev);
1682 struct ucc_geth *ug_regs; 1511 struct ucc_geth *ug_regs;
1683 u32 tempval; 1512 struct ucc_fast *uf_regs;
1684 struct ugeth_mii_info *mii_info = ugeth->mii_info; 1513 struct phy_device *phydev = ugeth->phydev;
1514 unsigned long flags;
1515 int new_state = 0;
1685 1516
1686 ug_regs = ugeth->ug_regs; 1517 ug_regs = ugeth->ug_regs;
1518 uf_regs = ugeth->uccf->uf_regs;
1687 1519
1688 if (mii_info->link) { 1520 spin_lock_irqsave(&ugeth->lock, flags);
1521
1522 if (phydev->link) {
1523 u32 tempval = in_be32(&ug_regs->maccfg2);
1524 u32 upsmr = in_be32(&uf_regs->upsmr);
1689 /* Now we make sure that we can be in full duplex mode. 1525 /* Now we make sure that we can be in full duplex mode.
1690 * If not, we operate in half-duplex mode. */ 1526 * If not, we operate in half-duplex mode. */
1691 if (mii_info->duplex != ugeth->oldduplex) { 1527 if (phydev->duplex != ugeth->oldduplex) {
1692 if (!(mii_info->duplex)) { 1528 new_state = 1;
1693 tempval = in_be32(&ug_regs->maccfg2); 1529 if (!(phydev->duplex))
1694 tempval &= ~(MACCFG2_FDX); 1530 tempval &= ~(MACCFG2_FDX);
1695 out_be32(&ug_regs->maccfg2, tempval); 1531 else
1696
1697 ugeth_info("%s: Half Duplex", dev->name);
1698 } else {
1699 tempval = in_be32(&ug_regs->maccfg2);
1700 tempval |= MACCFG2_FDX; 1532 tempval |= MACCFG2_FDX;
1701 out_be32(&ug_regs->maccfg2, tempval); 1533 ugeth->oldduplex = phydev->duplex;
1702
1703 ugeth_info("%s: Full Duplex", dev->name);
1704 }
1705
1706 ugeth->oldduplex = mii_info->duplex;
1707 } 1534 }
1708 1535
1709 if (mii_info->speed != ugeth->oldspeed) { 1536 if (phydev->speed != ugeth->oldspeed) {
1710 switch (mii_info->speed) { 1537 new_state = 1;
1711 case 1000: 1538 switch (phydev->speed) {
1712 ugeth->ug_info->enet_interface = ENET_1000_RGMII; 1539 case SPEED_1000:
1540 tempval = ((tempval &
1541 ~(MACCFG2_INTERFACE_MODE_MASK)) |
1542 MACCFG2_INTERFACE_MODE_BYTE);
1713 break; 1543 break;
1714 case 100: 1544 case SPEED_100:
1715 ugeth->ug_info->enet_interface = ENET_100_RGMII; 1545 case SPEED_10:
1716 break; 1546 tempval = ((tempval &
1717 case 10: 1547 ~(MACCFG2_INTERFACE_MODE_MASK)) |
1718 ugeth->ug_info->enet_interface = ENET_10_RGMII; 1548 MACCFG2_INTERFACE_MODE_NIBBLE);
1549 /* if reduced mode, re-set UPSMR.R10M */
1550 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
1551 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
1552 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
1553 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1554 if (phydev->speed == SPEED_10)
1555 upsmr |= UPSMR_R10M;
1556 else
1557 upsmr &= ~(UPSMR_R10M);
1558 }
1719 break; 1559 break;
1720 default: 1560 default:
1721 ugeth_warn 1561 if (netif_msg_link(ugeth))
1722 ("%s: Ack! Speed (%d) is not 10/100/1000!", 1562 ugeth_warn(
1723 dev->name, mii_info->speed); 1563 "%s: Ack! Speed (%d) is not 10/100/1000!",
1564 dev->name, phydev->speed);
1724 break; 1565 break;
1725 } 1566 }
1726 adjust_enet_interface(ugeth); 1567 ugeth->oldspeed = phydev->speed;
1727
1728 ugeth_info("%s: Speed %dBT", dev->name,
1729 mii_info->speed);
1730
1731 ugeth->oldspeed = mii_info->speed;
1732 } 1568 }
1733 1569
1570 out_be32(&ug_regs->maccfg2, tempval);
1571 out_be32(&uf_regs->upsmr, upsmr);
1572
1734 if (!ugeth->oldlink) { 1573 if (!ugeth->oldlink) {
1735 ugeth_info("%s: Link is up", dev->name); 1574 new_state = 1;
1736 ugeth->oldlink = 1; 1575 ugeth->oldlink = 1;
1737 netif_carrier_on(dev);
1738 netif_schedule(dev); 1576 netif_schedule(dev);
1739 } 1577 }
1740 } else { 1578 } else if (ugeth->oldlink) {
1741 if (ugeth->oldlink) { 1579 new_state = 1;
1742 ugeth_info("%s: Link is down", dev->name);
1743 ugeth->oldlink = 0; 1580 ugeth->oldlink = 0;
1744 ugeth->oldspeed = 0; 1581 ugeth->oldspeed = 0;
1745 ugeth->oldduplex = -1; 1582 ugeth->oldduplex = -1;
1746 netif_carrier_off(dev);
1747 }
1748 } 1583 }
1584
1585 if (new_state && netif_msg_link(ugeth))
1586 phy_print_status(phydev);
1587
1588 spin_unlock_irqrestore(&ugeth->lock, flags);
1749} 1589}
1750 1590
1751/* Configure the PHY for dev. 1591/* Configure the PHY for dev.
@@ -1753,102 +1593,40 @@ static void adjust_link(struct net_device *dev)
1753 */ 1593 */
1754static int init_phy(struct net_device *dev) 1594static int init_phy(struct net_device *dev)
1755{ 1595{
1756 struct ucc_geth_private *ugeth = netdev_priv(dev); 1596 struct ucc_geth_private *priv = netdev_priv(dev);
1757 struct phy_info *curphy; 1597 struct phy_device *phydev;
1758 struct ucc_mii_mng *mii_regs; 1598 char phy_id[BUS_ID_SIZE];
1759 struct ugeth_mii_info *mii_info;
1760 int err;
1761 1599
1762 mii_regs = &ugeth->ug_regs->miimng; 1600 priv->oldlink = 0;
1601 priv->oldspeed = 0;
1602 priv->oldduplex = -1;
1763 1603
1764 ugeth->oldlink = 0; 1604 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->ug_info->mdio_bus,
1765 ugeth->oldspeed = 0; 1605 priv->ug_info->phy_address);
1766 ugeth->oldduplex = -1;
1767 1606
1768 mii_info = kmalloc(sizeof(struct ugeth_mii_info), GFP_KERNEL); 1607 phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
1769 1608
1770 if (NULL == mii_info) { 1609 if (IS_ERR(phydev)) {
1771 ugeth_err("%s: Could not allocate mii_info", dev->name); 1610 printk("%s: Could not attach to PHY\n", dev->name);
1772 return -ENOMEM; 1611 return PTR_ERR(phydev);
1773 } 1612 }
1774 1613
1775 mii_info->mii_regs = mii_regs; 1614 phydev->supported &= (ADVERTISED_10baseT_Half |
1776 mii_info->speed = SPEED_1000;
1777 mii_info->duplex = DUPLEX_FULL;
1778 mii_info->pause = 0;
1779 mii_info->link = 0;
1780
1781 mii_info->advertising = (ADVERTISED_10baseT_Half |
1782 ADVERTISED_10baseT_Full | 1615 ADVERTISED_10baseT_Full |
1783 ADVERTISED_100baseT_Half | 1616 ADVERTISED_100baseT_Half |
1784 ADVERTISED_100baseT_Full | 1617 ADVERTISED_100baseT_Full);
1785 ADVERTISED_1000baseT_Full);
1786 mii_info->autoneg = 1;
1787 1618
1788 mii_info->mii_id = ugeth->ug_info->phy_address; 1619 if (priv->max_speed == SPEED_1000)
1620 phydev->supported |= ADVERTISED_1000baseT_Full;
1789 1621
1790 mii_info->dev = dev; 1622 phydev->advertising = phydev->supported;
1791 1623
1792 mii_info->mdio_read = &read_phy_reg; 1624 priv->phydev = phydev;
1793 mii_info->mdio_write = &write_phy_reg;
1794
1795 spin_lock_init(&mii_info->mdio_lock);
1796
1797 ugeth->mii_info = mii_info;
1798
1799 spin_lock_irq(&ugeth->lock);
1800
1801 /* Set this UCC to be the master of the MII managment */
1802 ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
1803
1804 if (init_mii_management_configuration(1,
1805 ugeth->ug_info->
1806 miiPreambleSupress,
1807 &mii_regs->miimcfg,
1808 &mii_regs->miimind)) {
1809 ugeth_err("%s: The MII Bus is stuck!", dev->name);
1810 err = -1;
1811 goto bus_fail;
1812 }
1813
1814 spin_unlock_irq(&ugeth->lock);
1815
1816 /* get info for this PHY */
1817 curphy = get_phy_info(ugeth->mii_info);
1818
1819 if (curphy == NULL) {
1820 ugeth_err("%s: No PHY found", dev->name);
1821 err = -1;
1822 goto no_phy;
1823 }
1824
1825 mii_info->phyinfo = curphy;
1826
1827 /* Run the commands which initialize the PHY */
1828 if (curphy->init) {
1829 err = curphy->init(ugeth->mii_info);
1830 if (err)
1831 goto phy_init_fail;
1832 }
1833 1625
1834 return 0; 1626 return 0;
1835
1836 phy_init_fail:
1837 no_phy:
1838 bus_fail:
1839 kfree(mii_info);
1840
1841 return err;
1842} 1627}
1843 1628
1844#ifdef CONFIG_UGETH_TX_ON_DEMOND
1845static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth)
1846{
1847 struct ucc_fastransmit_on_demand(ugeth->uccf);
1848 1629
1849 return 0;
1850}
1851#endif
1852 1630
1853static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) 1631static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
1854{ 1632{
@@ -2356,6 +2134,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
2356 } 2134 }
2357 for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { 2135 for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
2358 bd = ugeth->p_tx_bd_ring[i]; 2136 bd = ugeth->p_tx_bd_ring[i];
2137 if (!bd)
2138 continue;
2359 for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { 2139 for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
2360 if (ugeth->tx_skbuff[i][j]) { 2140 if (ugeth->tx_skbuff[i][j]) {
2361 dma_unmap_single(NULL, 2141 dma_unmap_single(NULL,
@@ -2487,6 +2267,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
2487static void ucc_geth_stop(struct ucc_geth_private *ugeth) 2267static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2488{ 2268{
2489 struct ucc_geth *ug_regs = ugeth->ug_regs; 2269 struct ucc_geth *ug_regs = ugeth->ug_regs;
2270 struct phy_device *phydev = ugeth->phydev;
2490 u32 tempval; 2271 u32 tempval;
2491 2272
2492 ugeth_vdbg("%s: IN", __FUNCTION__); 2273 ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2495,8 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2495 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); 2276 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
2496 2277
2497 /* Tell the kernel the link is down */ 2278 /* Tell the kernel the link is down */
2498 ugeth->mii_info->link = 0; 2279 phy_stop(phydev);
2499 adjust_link(ugeth->dev);
2500 2280
2501 /* Mask all interrupts */ 2281 /* Mask all interrupts */
2502 out_be32(ugeth->uccf->p_ucce, 0x00000000); 2282 out_be32(ugeth->uccf->p_ucce, 0x00000000);
@@ -2509,50 +2289,24 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2509 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); 2289 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
2510 out_be32(&ug_regs->maccfg1, tempval); 2290 out_be32(&ug_regs->maccfg1, tempval);
2511 2291
2512 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
2513 /* Clear any pending interrupts */
2514 mii_clear_phy_interrupt(ugeth->mii_info);
2515
2516 /* Disable PHY Interrupts */
2517 mii_configure_phy_interrupt(ugeth->mii_info,
2518 MII_INTERRUPT_DISABLED);
2519 }
2520
2521 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev); 2292 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
2522 2293
2523 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
2524 free_irq(ugeth->ug_info->phy_interrupt, ugeth->dev);
2525 } else {
2526 del_timer_sync(&ugeth->phy_info_timer);
2527 }
2528
2529 ucc_geth_memclean(ugeth); 2294 ucc_geth_memclean(ugeth);
2530} 2295}
2531 2296
2532static int ucc_geth_startup(struct ucc_geth_private *ugeth) 2297static int ucc_struct_init(struct ucc_geth_private *ugeth)
2533{ 2298{
2534 struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
2535 struct ucc_geth_init_pram *p_init_enet_pram;
2536 struct ucc_fast_private *uccf;
2537 struct ucc_geth_info *ug_info; 2299 struct ucc_geth_info *ug_info;
2538 struct ucc_fast_info *uf_info; 2300 struct ucc_fast_info *uf_info;
2539 struct ucc_fast *uf_regs; 2301 int i;
2540 struct ucc_geth *ug_regs;
2541 int ret_val = -EINVAL;
2542 u32 remoder = UCC_GETH_REMODER_INIT;
2543 u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
2544 u32 ifstat, i, j, size, l2qt, l3qt, length;
2545 u16 temoder = UCC_GETH_TEMODER_INIT;
2546 u16 test;
2547 u8 function_code = 0;
2548 u8 *bd, *endOfRing;
2549 u8 numThreadsRxNumerical, numThreadsTxNumerical;
2550
2551 ugeth_vdbg("%s: IN", __FUNCTION__);
2552 2302
2553 ug_info = ugeth->ug_info; 2303 ug_info = ugeth->ug_info;
2554 uf_info = &ug_info->uf_info; 2304 uf_info = &ug_info->uf_info;
2555 2305
2306 /* Create CQs for hash tables */
2307 INIT_LIST_HEAD(&ugeth->group_hash_q);
2308 INIT_LIST_HEAD(&ugeth->ind_hash_q);
2309
2556 if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) || 2310 if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
2557 (uf_info->bd_mem_part == MEM_PART_MURAM))) { 2311 (uf_info->bd_mem_part == MEM_PART_MURAM))) {
2558 ugeth_err("%s: Bad memory partition value.", __FUNCTION__); 2312 ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
@@ -2647,12 +2401,42 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2647 for (i = 0; i < ug_info->numQueuesTx; i++) 2401 for (i = 0; i < ug_info->numQueuesTx; i++)
2648 uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i); 2402 uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
2649 /* Initialize the general fast UCC block. */ 2403 /* Initialize the general fast UCC block. */
2650 if (ucc_fast_init(uf_info, &uccf)) { 2404 if (ucc_fast_init(uf_info, &ugeth->uccf)) {
2651 ugeth_err("%s: Failed to init uccf.", __FUNCTION__); 2405 ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
2652 ucc_geth_memclean(ugeth); 2406 ucc_geth_memclean(ugeth);
2653 return -ENOMEM; 2407 return -ENOMEM;
2654 } 2408 }
2655 ugeth->uccf = uccf; 2409
2410 ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
2411
2412 return 0;
2413}
2414
2415static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2416{
2417 struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
2418 struct ucc_geth_init_pram *p_init_enet_pram;
2419 struct ucc_fast_private *uccf;
2420 struct ucc_geth_info *ug_info;
2421 struct ucc_fast_info *uf_info;
2422 struct ucc_fast *uf_regs;
2423 struct ucc_geth *ug_regs;
2424 int ret_val = -EINVAL;
2425 u32 remoder = UCC_GETH_REMODER_INIT;
2426 u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
2427 u32 ifstat, i, j, size, l2qt, l3qt, length;
2428 u16 temoder = UCC_GETH_TEMODER_INIT;
2429 u16 test;
2430 u8 function_code = 0;
2431 u8 *bd, *endOfRing;
2432 u8 numThreadsRxNumerical, numThreadsTxNumerical;
2433
2434 ugeth_vdbg("%s: IN", __FUNCTION__);
2435 uccf = ugeth->uccf;
2436 ug_info = ugeth->ug_info;
2437 uf_info = &ug_info->uf_info;
2438 uf_regs = uccf->uf_regs;
2439 ug_regs = ugeth->ug_regs;
2656 2440
2657 switch (ug_info->numThreadsRx) { 2441 switch (ug_info->numThreadsRx) {
2658 case UCC_GETH_NUM_OF_THREADS_1: 2442 case UCC_GETH_NUM_OF_THREADS_1:
@@ -2711,10 +2495,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2711 || (ug_info->vlanOperationNonTagged != 2495 || (ug_info->vlanOperationNonTagged !=
2712 UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); 2496 UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
2713 2497
2714 uf_regs = uccf->uf_regs;
2715 ug_regs = (struct ucc_geth *) (uccf->uf_regs);
2716 ugeth->ug_regs = ug_regs;
2717
2718 init_default_reg_vals(&uf_regs->upsmr, 2498 init_default_reg_vals(&uf_regs->upsmr,
2719 &ug_regs->maccfg1, &ug_regs->maccfg2); 2499 &ug_regs->maccfg1, &ug_regs->maccfg2);
2720 2500
@@ -3177,8 +2957,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
3177 /* Size varies with number of Rx queues */ 2957 /* Size varies with number of Rx queues */
3178 ugeth->rx_irq_coalescing_tbl_offset = 2958 ugeth->rx_irq_coalescing_tbl_offset =
3179 qe_muram_alloc(ug_info->numQueuesRx * 2959 qe_muram_alloc(ug_info->numQueuesRx *
3180 sizeof(struct ucc_geth_rx_interrupt_coalescing_entry), 2960 sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
3181 UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); 2961 + 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
3182 if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { 2962 if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
3183 ugeth_err 2963 ugeth_err
3184 ("%s: Can not allocate DPRAM memory for" 2964 ("%s: Can not allocate DPRAM memory for"
@@ -3359,13 +3139,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
3359 for (j = 0; j < NUM_OF_PADDRS; j++) 3139 for (j = 0; j < NUM_OF_PADDRS; j++)
3360 ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j); 3140 ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
3361 3141
3362 /* Create CQs for hash tables */
3363 if (ug_info->maxGroupAddrInHash > 0) {
3364 INIT_LIST_HEAD(&ugeth->group_hash_q);
3365 }
3366 if (ug_info->maxIndAddrInHash > 0) {
3367 INIT_LIST_HEAD(&ugeth->ind_hash_q);
3368 }
3369 p_82xx_addr_filt = 3142 p_82xx_addr_filt =
3370 (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> 3143 (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
3371 p_rx_glbl_pram->addressfiltering; 3144 p_rx_glbl_pram->addressfiltering;
@@ -3562,6 +3335,9 @@ static void ucc_geth_timeout(struct net_device *dev)
3562static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) 3335static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
3563{ 3336{
3564 struct ucc_geth_private *ugeth = netdev_priv(dev); 3337 struct ucc_geth_private *ugeth = netdev_priv(dev);
3338#ifdef CONFIG_UGETH_TX_ON_DEMAND
3339 struct ucc_fast_private *uccf;
3340#endif
3565 u8 *bd; /* BD pointer */ 3341 u8 *bd; /* BD pointer */
3566 u32 bd_status; 3342 u32 bd_status;
3567 u8 txQ = 0; 3343 u8 txQ = 0;
@@ -3620,6 +3396,10 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
3620 out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]); 3396 out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]);
3621 } 3397 }
3622 3398
3399#ifdef CONFIG_UGETH_TX_ON_DEMAND
3400 uccf = ugeth->uccf;
3401 out_be16(uccf->p_utodr, UCC_FAST_TOD);
3402#endif
3623 spin_unlock_irq(&ugeth->lock); 3403 spin_unlock_irq(&ugeth->lock);
3624 3404
3625 return 0; 3405 return 0;
@@ -3635,7 +3415,6 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
3635 3415
3636 ugeth_vdbg("%s: IN", __FUNCTION__); 3416 ugeth_vdbg("%s: IN", __FUNCTION__);
3637 3417
3638 spin_lock(&ugeth->lock);
3639 /* collect received buffers */ 3418 /* collect received buffers */
3640 bd = ugeth->rxBd[rxQ]; 3419 bd = ugeth->rxBd[rxQ];
3641 3420
@@ -3683,7 +3462,6 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
3683 skb = get_new_skb(ugeth, bd); 3462 skb = get_new_skb(ugeth, bd);
3684 if (!skb) { 3463 if (!skb) {
3685 ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); 3464 ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
3686 spin_unlock(&ugeth->lock);
3687 ugeth->stats.rx_dropped++; 3465 ugeth->stats.rx_dropped++;
3688 break; 3466 break;
3689 } 3467 }
@@ -3704,7 +3482,6 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
3704 } 3482 }
3705 3483
3706 ugeth->rxBd[rxQ] = bd; 3484 ugeth->rxBd[rxQ] = bd;
3707 spin_unlock(&ugeth->lock);
3708 return howmany; 3485 return howmany;
3709} 3486}
3710 3487
@@ -3756,23 +3533,38 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
3756static int ucc_geth_poll(struct net_device *dev, int *budget) 3533static int ucc_geth_poll(struct net_device *dev, int *budget)
3757{ 3534{
3758 struct ucc_geth_private *ugeth = netdev_priv(dev); 3535 struct ucc_geth_private *ugeth = netdev_priv(dev);
3536 struct ucc_geth_info *ug_info;
3537 struct ucc_fast_private *uccf;
3759 int howmany; 3538 int howmany;
3760 int rx_work_limit = *budget; 3539 u8 i;
3761 u8 rxQ = 0; 3540 int rx_work_limit;
3541 register u32 uccm;
3542
3543 ug_info = ugeth->ug_info;
3762 3544
3545 rx_work_limit = *budget;
3763 if (rx_work_limit > dev->quota) 3546 if (rx_work_limit > dev->quota)
3764 rx_work_limit = dev->quota; 3547 rx_work_limit = dev->quota;
3765 3548
3766 howmany = ucc_geth_rx(ugeth, rxQ, rx_work_limit); 3549 howmany = 0;
3550
3551 for (i = 0; i < ug_info->numQueuesRx; i++) {
3552 howmany += ucc_geth_rx(ugeth, i, rx_work_limit);
3553 }
3767 3554
3768 dev->quota -= howmany; 3555 dev->quota -= howmany;
3769 rx_work_limit -= howmany; 3556 rx_work_limit -= howmany;
3770 *budget -= howmany; 3557 *budget -= howmany;
3771 3558
3772 if (rx_work_limit >= 0) 3559 if (rx_work_limit > 0) {
3773 netif_rx_complete(dev); 3560 netif_rx_complete(dev);
3561 uccf = ugeth->uccf;
3562 uccm = in_be32(uccf->p_uccm);
3563 uccm |= UCCE_RX_EVENTS;
3564 out_be32(uccf->p_uccm, uccm);
3565 }
3774 3566
3775 return (rx_work_limit < 0) ? 1 : 0; 3567 return (rx_work_limit > 0) ? 0 : 1;
3776} 3568}
3777#endif /* CONFIG_UGETH_NAPI */ 3569#endif /* CONFIG_UGETH_NAPI */
3778 3570
@@ -3782,10 +3574,13 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
3782 struct ucc_geth_private *ugeth = netdev_priv(dev); 3574 struct ucc_geth_private *ugeth = netdev_priv(dev);
3783 struct ucc_fast_private *uccf; 3575 struct ucc_fast_private *uccf;
3784 struct ucc_geth_info *ug_info; 3576 struct ucc_geth_info *ug_info;
3785 register u32 ucce = 0; 3577 register u32 ucce;
3786 register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; 3578 register u32 uccm;
3787 register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; 3579#ifndef CONFIG_UGETH_NAPI
3788 register u8 i; 3580 register u32 rx_mask;
3581#endif
3582 register u32 tx_mask;
3583 u8 i;
3789 3584
3790 ugeth_vdbg("%s: IN", __FUNCTION__); 3585 ugeth_vdbg("%s: IN", __FUNCTION__);
3791 3586
@@ -3795,174 +3590,57 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
3795 uccf = ugeth->uccf; 3590 uccf = ugeth->uccf;
3796 ug_info = ugeth->ug_info; 3591 ug_info = ugeth->ug_info;
3797 3592
3798 do { 3593 /* read and clear events */
3799 ucce |= (u32) (in_be32(uccf->p_ucce) & in_be32(uccf->p_uccm)); 3594 ucce = (u32) in_be32(uccf->p_ucce);
3800 3595 uccm = (u32) in_be32(uccf->p_uccm);
3801 /* clear event bits for next time */ 3596 ucce &= uccm;
3802 /* Side effect here is to mask ucce variable 3597 out_be32(uccf->p_ucce, ucce);
3803 for future processing below. */
3804 out_be32(uccf->p_ucce, ucce); /* Clear with ones,
3805 but only bits in UCCM */
3806
3807 /* We ignore Tx interrupts because Tx confirmation is
3808 done inside Tx routine */
3809 3598
3599 /* check for receive events that require processing */
3600 if (ucce & UCCE_RX_EVENTS) {
3601#ifdef CONFIG_UGETH_NAPI
3602 if (netif_rx_schedule_prep(dev)) {
3603 uccm &= ~UCCE_RX_EVENTS;
3604 out_be32(uccf->p_uccm, uccm);
3605 __netif_rx_schedule(dev);
3606 }
3607#else
3608 rx_mask = UCCE_RXBF_SINGLE_MASK;
3810 for (i = 0; i < ug_info->numQueuesRx; i++) { 3609 for (i = 0; i < ug_info->numQueuesRx; i++) {
3811 if (ucce & bit_mask) 3610 if (ucce & rx_mask)
3812 ucc_geth_rx(ugeth, i, 3611 ucc_geth_rx(ugeth, i, (int)ugeth->ug_info->bdRingLenRx[i]);
3813 (int)ugeth->ug_info-> 3612 ucce &= ~rx_mask;
3814 bdRingLenRx[i]); 3613 rx_mask <<= 1;
3815 ucce &= ~bit_mask;
3816 bit_mask <<= 1;
3817 } 3614 }
3615#endif /* CONFIG_UGETH_NAPI */
3616 }
3818 3617
3618 /* Tx event processing */
3619 if (ucce & UCCE_TX_EVENTS) {
3620 spin_lock(&ugeth->lock);
3621 tx_mask = UCCE_TXBF_SINGLE_MASK;
3819 for (i = 0; i < ug_info->numQueuesTx; i++) { 3622 for (i = 0; i < ug_info->numQueuesTx; i++) {
3820 if (ucce & tx_mask) 3623 if (ucce & tx_mask)
3821 ucc_geth_tx(dev, i); 3624 ucc_geth_tx(dev, i);
3822 ucce &= ~tx_mask; 3625 ucce &= ~tx_mask;
3823 tx_mask <<= 1; 3626 tx_mask <<= 1;
3824 } 3627 }
3628 spin_unlock(&ugeth->lock);
3629 }
3825 3630
3826 /* Exceptions */ 3631 /* Errors and other events */
3632 if (ucce & UCCE_OTHER) {
3827 if (ucce & UCCE_BSY) { 3633 if (ucce & UCCE_BSY) {
3828 ugeth_vdbg("Got BUSY irq!!!!");
3829 ugeth->stats.rx_errors++; 3634 ugeth->stats.rx_errors++;
3830 ucce &= ~UCCE_BSY;
3831 } 3635 }
3832 if (ucce & UCCE_OTHER) { 3636 if (ucce & UCCE_TXE) {
3833 ugeth_vdbg("Got frame with error (ucce - 0x%08x)!!!!", 3637 ugeth->stats.tx_errors++;
3834 ucce);
3835 ugeth->stats.rx_errors++;
3836 ucce &= ~ucce;
3837 } 3638 }
3838 } 3639 }
3839 while (ucce);
3840
3841 return IRQ_HANDLED;
3842}
3843
3844static irqreturn_t phy_interrupt(int irq, void *dev_id)
3845{
3846 struct net_device *dev = (struct net_device *)dev_id;
3847 struct ucc_geth_private *ugeth = netdev_priv(dev);
3848
3849 ugeth_vdbg("%s: IN", __FUNCTION__);
3850
3851 /* Clear the interrupt */
3852 mii_clear_phy_interrupt(ugeth->mii_info);
3853
3854 /* Disable PHY interrupts */
3855 mii_configure_phy_interrupt(ugeth->mii_info, MII_INTERRUPT_DISABLED);
3856
3857 /* Schedule the phy change */
3858 schedule_work(&ugeth->tq);
3859 3640
3860 return IRQ_HANDLED; 3641 return IRQ_HANDLED;
3861} 3642}
3862 3643
3863/* Scheduled by the phy_interrupt/timer to handle PHY changes */
3864static void ugeth_phy_change(struct work_struct *work)
3865{
3866 struct ucc_geth_private *ugeth =
3867 container_of(work, struct ucc_geth_private, tq);
3868 struct net_device *dev = ugeth->dev;
3869 struct ucc_geth *ug_regs;
3870 int result = 0;
3871
3872 ugeth_vdbg("%s: IN", __FUNCTION__);
3873
3874 ug_regs = ugeth->ug_regs;
3875
3876 /* Delay to give the PHY a chance to change the
3877 * register state */
3878 msleep(1);
3879
3880 /* Update the link, speed, duplex */
3881 result = ugeth->mii_info->phyinfo->read_status(ugeth->mii_info);
3882
3883 /* Adjust the known status as long as the link
3884 * isn't still coming up */
3885 if ((0 == result) || (ugeth->mii_info->link == 0))
3886 adjust_link(dev);
3887
3888 /* Reenable interrupts, if needed */
3889 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR)
3890 mii_configure_phy_interrupt(ugeth->mii_info,
3891 MII_INTERRUPT_ENABLED);
3892}
3893
3894/* Called every so often on systems that don't interrupt
3895 * the core for PHY changes */
3896static void ugeth_phy_timer(unsigned long data)
3897{
3898 struct net_device *dev = (struct net_device *)data;
3899 struct ucc_geth_private *ugeth = netdev_priv(dev);
3900
3901 schedule_work(&ugeth->tq);
3902
3903 mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
3904}
3905
3906/* Keep trying aneg for some time
3907 * If, after GFAR_AN_TIMEOUT seconds, it has not
3908 * finished, we switch to forced.
3909 * Either way, once the process has completed, we either
3910 * request the interrupt, or switch the timer over to
3911 * using ugeth_phy_timer to check status */
3912static void ugeth_phy_startup_timer(unsigned long data)
3913{
3914 struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
3915 struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev);
3916 static int secondary = UGETH_AN_TIMEOUT;
3917 int result;
3918
3919 /* Configure the Auto-negotiation */
3920 result = mii_info->phyinfo->config_aneg(mii_info);
3921
3922 /* If autonegotiation failed to start, and
3923 * we haven't timed out, reset the timer, and return */
3924 if (result && secondary--) {
3925 mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
3926 return;
3927 } else if (result) {
3928 /* Couldn't start autonegotiation.
3929 * Try switching to forced */
3930 mii_info->autoneg = 0;
3931 result = mii_info->phyinfo->config_aneg(mii_info);
3932
3933 /* Forcing failed! Give up */
3934 if (result) {
3935 ugeth_err("%s: Forcing failed!", mii_info->dev->name);
3936 return;
3937 }
3938 }
3939
3940 /* Kill the timer so it can be restarted */
3941 del_timer_sync(&ugeth->phy_info_timer);
3942
3943 /* Grab the PHY interrupt, if necessary/possible */
3944 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
3945 if (request_irq(ugeth->ug_info->phy_interrupt,
3946 phy_interrupt, IRQF_SHARED,
3947 "phy_interrupt", mii_info->dev) < 0) {
3948 ugeth_err("%s: Can't get IRQ %d (PHY)",
3949 mii_info->dev->name,
3950 ugeth->ug_info->phy_interrupt);
3951 } else {
3952 mii_configure_phy_interrupt(ugeth->mii_info,
3953 MII_INTERRUPT_ENABLED);
3954 return;
3955 }
3956 }
3957
3958 /* Start the timer again, this time in order to
3959 * handle a change in status */
3960 init_timer(&ugeth->phy_info_timer);
3961 ugeth->phy_info_timer.function = &ugeth_phy_timer;
3962 ugeth->phy_info_timer.data = (unsigned long)mii_info->dev;
3963 mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
3964}
3965
3966/* Called when something needs to use the ethernet device */ 3644/* Called when something needs to use the ethernet device */
3967/* Returns 0 for success. */ 3645/* Returns 0 for success. */
3968static int ucc_geth_open(struct net_device *dev) 3646static int ucc_geth_open(struct net_device *dev)
@@ -3979,6 +3657,12 @@ static int ucc_geth_open(struct net_device *dev)
3979 return -EINVAL; 3657 return -EINVAL;
3980 } 3658 }
3981 3659
3660 err = ucc_struct_init(ugeth);
3661 if (err) {
3662 ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
3663 return err;
3664 }
3665
3982 err = ucc_geth_startup(ugeth); 3666 err = ucc_geth_startup(ugeth);
3983 if (err) { 3667 if (err) {
3984 ugeth_err("%s: Cannot configure net device, aborting.", 3668 ugeth_err("%s: Cannot configure net device, aborting.",
@@ -4006,10 +3690,12 @@ static int ucc_geth_open(struct net_device *dev)
4006 3690
4007 err = init_phy(dev); 3691 err = init_phy(dev);
4008 if (err) { 3692 if (err) {
4009 ugeth_err("%s: Cannot initialzie PHY, aborting.", dev->name); 3693 ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
4010 return err; 3694 return err;
4011 } 3695 }
4012#ifndef CONFIG_UGETH_NAPI 3696
3697 phy_start(ugeth->phydev);
3698
4013 err = 3699 err =
4014 request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0, 3700 request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
4015 "UCC Geth", dev); 3701 "UCC Geth", dev);
@@ -4019,15 +3705,6 @@ static int ucc_geth_open(struct net_device *dev)
4019 ucc_geth_stop(ugeth); 3705 ucc_geth_stop(ugeth);
4020 return err; 3706 return err;
4021 } 3707 }
4022#endif /* CONFIG_UGETH_NAPI */
4023
4024 /* Set up the PHY change work queue */
4025 INIT_WORK(&ugeth->tq, ugeth_phy_change);
4026
4027 init_timer(&ugeth->phy_info_timer);
4028 ugeth->phy_info_timer.function = &ugeth_phy_startup_timer;
4029 ugeth->phy_info_timer.data = (unsigned long)ugeth->mii_info;
4030 mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
4031 3708
4032 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); 3709 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
4033 if (err) { 3710 if (err) {
@@ -4050,11 +3727,8 @@ static int ucc_geth_close(struct net_device *dev)
4050 3727
4051 ucc_geth_stop(ugeth); 3728 ucc_geth_stop(ugeth);
4052 3729
4053 /* Shutdown the PHY */ 3730 phy_disconnect(ugeth->phydev);
4054 if (ugeth->mii_info->phyinfo->close) 3731 ugeth->phydev = NULL;
4055 ugeth->mii_info->phyinfo->close(ugeth->mii_info);
4056
4057 kfree(ugeth->mii_info);
4058 3732
4059 netif_stop_queue(dev); 3733 netif_stop_queue(dev);
4060 3734
@@ -4063,20 +3737,53 @@ static int ucc_geth_close(struct net_device *dev)
4063 3737
4064const struct ethtool_ops ucc_geth_ethtool_ops = { }; 3738const struct ethtool_ops ucc_geth_ethtool_ops = { };
4065 3739
3740static phy_interface_t to_phy_interface(const char *interface_type)
3741{
3742 if (strcasecmp(interface_type, "mii") == 0)
3743 return PHY_INTERFACE_MODE_MII;
3744 if (strcasecmp(interface_type, "gmii") == 0)
3745 return PHY_INTERFACE_MODE_GMII;
3746 if (strcasecmp(interface_type, "tbi") == 0)
3747 return PHY_INTERFACE_MODE_TBI;
3748 if (strcasecmp(interface_type, "rmii") == 0)
3749 return PHY_INTERFACE_MODE_RMII;
3750 if (strcasecmp(interface_type, "rgmii") == 0)
3751 return PHY_INTERFACE_MODE_RGMII;
3752 if (strcasecmp(interface_type, "rgmii-id") == 0)
3753 return PHY_INTERFACE_MODE_RGMII_ID;
3754 if (strcasecmp(interface_type, "rtbi") == 0)
3755 return PHY_INTERFACE_MODE_RTBI;
3756
3757 return PHY_INTERFACE_MODE_MII;
3758}
3759
4066static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) 3760static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
4067{ 3761{
4068 struct device *device = &ofdev->dev; 3762 struct device *device = &ofdev->dev;
4069 struct device_node *np = ofdev->node; 3763 struct device_node *np = ofdev->node;
3764 struct device_node *mdio;
4070 struct net_device *dev = NULL; 3765 struct net_device *dev = NULL;
4071 struct ucc_geth_private *ugeth = NULL; 3766 struct ucc_geth_private *ugeth = NULL;
4072 struct ucc_geth_info *ug_info; 3767 struct ucc_geth_info *ug_info;
4073 struct resource res; 3768 struct resource res;
4074 struct device_node *phy; 3769 struct device_node *phy;
4075 int err, ucc_num, phy_interface; 3770 int err, ucc_num, max_speed = 0;
4076 static int mii_mng_configured = 0;
4077 const phandle *ph; 3771 const phandle *ph;
4078 const unsigned int *prop; 3772 const unsigned int *prop;
4079 const void *mac_addr; 3773 const void *mac_addr;
3774 phy_interface_t phy_interface;
3775 static const int enet_to_speed[] = {
3776 SPEED_10, SPEED_10, SPEED_10,
3777 SPEED_100, SPEED_100, SPEED_100,
3778 SPEED_1000, SPEED_1000, SPEED_1000, SPEED_1000,
3779 };
3780 static const phy_interface_t enet_to_phy_interface[] = {
3781 PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_RMII,
3782 PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_MII,
3783 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
3784 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
3785 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
3786 };
4080 3787
4081 ugeth_vdbg("%s: IN", __FUNCTION__); 3788 ugeth_vdbg("%s: IN", __FUNCTION__);
4082 3789
@@ -4087,6 +3794,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4087 3794
4088 ug_info = &ugeth_info[ucc_num]; 3795 ug_info = &ugeth_info[ucc_num];
4089 ug_info->uf_info.ucc_num = ucc_num; 3796 ug_info->uf_info.ucc_num = ucc_num;
3797
4090 prop = get_property(np, "rx-clock", NULL); 3798 prop = get_property(np, "rx-clock", NULL);
4091 ug_info->uf_info.rx_clock = *prop; 3799 ug_info->uf_info.rx_clock = *prop;
4092 prop = get_property(np, "tx-clock", NULL); 3800 prop = get_property(np, "tx-clock", NULL);
@@ -4104,13 +3812,72 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4104 if (phy == NULL) 3812 if (phy == NULL)
4105 return -ENODEV; 3813 return -ENODEV;
4106 3814
3815 /* set the PHY address */
4107 prop = get_property(phy, "reg", NULL); 3816 prop = get_property(phy, "reg", NULL);
3817 if (prop == NULL)
3818 return -1;
4108 ug_info->phy_address = *prop; 3819 ug_info->phy_address = *prop;
4109 prop = get_property(phy, "interface", NULL); 3820
4110 ug_info->enet_interface = *prop; 3821 /* get the phy interface type, or default to MII */
4111 ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0); 3822 prop = get_property(np, "interface-type", NULL);
4112 ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)? 3823 if (!prop) {
4113 0:FSL_UGETH_BRD_HAS_PHY_INTR; 3824 /* handle interface property present in old trees */
3825 prop = get_property(phy, "interface", NULL);
3826 if (prop != NULL)
3827 phy_interface = enet_to_phy_interface[*prop];
3828 else
3829 phy_interface = PHY_INTERFACE_MODE_MII;
3830 } else {
3831 phy_interface = to_phy_interface((const char *)prop);
3832 }
3833
3834 /* get speed, or derive from interface */
3835 prop = get_property(np, "max-speed", NULL);
3836 if (!prop) {
3837 /* handle interface property present in old trees */
3838 prop = get_property(phy, "interface", NULL);
3839 if (prop != NULL)
3840 max_speed = enet_to_speed[*prop];
3841 } else {
3842 max_speed = *prop;
3843 }
3844 if (!max_speed) {
3845 switch (phy_interface) {
3846 case PHY_INTERFACE_MODE_GMII:
3847 case PHY_INTERFACE_MODE_RGMII:
3848 case PHY_INTERFACE_MODE_RGMII_ID:
3849 case PHY_INTERFACE_MODE_TBI:
3850 case PHY_INTERFACE_MODE_RTBI:
3851 max_speed = SPEED_1000;
3852 break;
3853 default:
3854 max_speed = SPEED_100;
3855 break;
3856 }
3857 }
3858
3859 if (max_speed == SPEED_1000) {
3860 ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
3861 ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
3862 ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
3863 ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT;
3864 ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
3865 ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
3866 }
3867
3868 /* Set the bus id */
3869 mdio = of_get_parent(phy);
3870
3871 if (mdio == NULL)
3872 return -1;
3873
3874 err = of_address_to_resource(mdio, 0, &res);
3875 of_node_put(mdio);
3876
3877 if (err)
3878 return -1;
3879
3880 ug_info->mdio_bus = res.start;
4114 3881
4115 printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", 3882 printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
4116 ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, 3883 ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
@@ -4122,43 +3889,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4122 return -ENODEV; 3889 return -ENODEV;
4123 } 3890 }
4124 3891
4125 /* FIXME: Work around for early chip rev. */
4126 /* There's a bug in initial chip rev(s) in the RGMII ac */
4127 /* timing. */
4128 /* The following compensates by writing to the reserved */
4129 /* QE Port Output Hold Registers (CPOH1?). */
4130 prop = get_property(phy, "interface", NULL);
4131 phy_interface = *prop;
4132 if ((phy_interface == ENET_1000_RGMII) ||
4133 (phy_interface == ENET_100_RGMII) ||
4134 (phy_interface == ENET_10_RGMII)) {
4135 struct device_node *soc;
4136 phys_addr_t immrbase = -1;
4137 u32 *tmp_reg;
4138 u32 tmp_val;
4139
4140 soc = of_find_node_by_type(NULL, "soc");
4141 if (soc) {
4142 unsigned int size;
4143 const void *prop = get_property(soc, "reg", &size);
4144 immrbase = of_translate_address(soc, prop);
4145 of_node_put(soc);
4146 };
4147
4148 tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4);
4149 tmp_val = in_be32(tmp_reg);
4150 if (ucc_num == 1)
4151 out_be32(tmp_reg, tmp_val | 0x00003000);
4152 else if (ucc_num == 2)
4153 out_be32(tmp_reg, tmp_val | 0x0c000000);
4154 iounmap(tmp_reg);
4155 }
4156
4157 if (!mii_mng_configured) {
4158 ucc_set_qe_mux_mii_mng(ucc_num);
4159 mii_mng_configured = 1;
4160 }
4161
4162 /* Create an ethernet device instance */ 3892 /* Create an ethernet device instance */
4163 dev = alloc_etherdev(sizeof(*ugeth)); 3893 dev = alloc_etherdev(sizeof(*ugeth));
4164 3894
@@ -4192,6 +3922,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4192 dev->set_multicast_list = ucc_geth_set_multi; 3922 dev->set_multicast_list = ucc_geth_set_multi;
4193 dev->ethtool_ops = &ucc_geth_ethtool_ops; 3923 dev->ethtool_ops = &ucc_geth_ethtool_ops;
4194 3924
3925 ugeth->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
3926 ugeth->phy_interface = phy_interface;
3927 ugeth->max_speed = max_speed;
3928
4195 err = register_netdev(dev); 3929 err = register_netdev(dev);
4196 if (err) { 3930 if (err) {
4197 ugeth_err("%s: Cannot register net device, aborting.", 3931 ugeth_err("%s: Cannot register net device, aborting.",
@@ -4200,13 +3934,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4200 return err; 3934 return err;
4201 } 3935 }
4202 3936
4203 ugeth->ug_info = ug_info;
4204 ugeth->dev = dev;
4205
4206 mac_addr = of_get_mac_address(np); 3937 mac_addr = of_get_mac_address(np);
4207 if (mac_addr) 3938 if (mac_addr)
4208 memcpy(dev->dev_addr, mac_addr, 6); 3939 memcpy(dev->dev_addr, mac_addr, 6);
4209 3940
3941 ugeth->ug_info = ug_info;
3942 ugeth->dev = dev;
3943
4210 return 0; 3944 return 0;
4211} 3945}
4212 3946
@@ -4242,19 +3976,30 @@ static struct of_platform_driver ucc_geth_driver = {
4242 3976
4243static int __init ucc_geth_init(void) 3977static int __init ucc_geth_init(void)
4244{ 3978{
4245 int i; 3979 int i, ret;
3980
3981 ret = uec_mdio_init();
3982
3983 if (ret)
3984 return ret;
4246 3985
4247 printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); 3986 printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
4248 for (i = 0; i < 8; i++) 3987 for (i = 0; i < 8; i++)
4249 memcpy(&(ugeth_info[i]), &ugeth_primary_info, 3988 memcpy(&(ugeth_info[i]), &ugeth_primary_info,
4250 sizeof(ugeth_primary_info)); 3989 sizeof(ugeth_primary_info));
4251 3990
4252 return of_register_platform_driver(&ucc_geth_driver); 3991 ret = of_register_platform_driver(&ucc_geth_driver);
3992
3993 if (ret)
3994 uec_mdio_exit();
3995
3996 return ret;
4253} 3997}
4254 3998
4255static void __exit ucc_geth_exit(void) 3999static void __exit ucc_geth_exit(void)
4256{ 4000{
4257 of_unregister_platform_driver(&ucc_geth_driver); 4001 of_unregister_platform_driver(&ucc_geth_driver);
4002 uec_mdio_exit();
4258} 4003}
4259 4004
4260module_init(ucc_geth_init); 4005module_init(ucc_geth_init);
@@ -4262,4 +4007,5 @@ module_exit(ucc_geth_exit);
4262 4007
4263MODULE_AUTHOR("Freescale Semiconductor, Inc"); 4008MODULE_AUTHOR("Freescale Semiconductor, Inc");
4264MODULE_DESCRIPTION(DRV_DESC); 4009MODULE_DESCRIPTION(DRV_DESC);
4010MODULE_VERSION(DRV_VERSION);
4265MODULE_LICENSE("GPL"); 4011MODULE_LICENSE("GPL");
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index a66561253593..a29e1c3ca4b7 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -28,6 +28,8 @@
28#include <asm/ucc.h> 28#include <asm/ucc.h>
29#include <asm/ucc_fast.h> 29#include <asm/ucc_fast.h>
30 30
31#include "ucc_geth_mii.h"
32
31#define NUM_TX_QUEUES 8 33#define NUM_TX_QUEUES 8
32#define NUM_RX_QUEUES 8 34#define NUM_RX_QUEUES 8
33#define NUM_BDS_IN_PREFETCHED_BDS 4 35#define NUM_BDS_IN_PREFETCHED_BDS 4
@@ -36,15 +38,6 @@
36#define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 38#define ENET_INIT_PARAM_MAX_ENTRIES_RX 9
37#define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 39#define ENET_INIT_PARAM_MAX_ENTRIES_TX 8
38 40
39struct ucc_mii_mng {
40 u32 miimcfg; /* MII management configuration reg */
41 u32 miimcom; /* MII management command reg */
42 u32 miimadd; /* MII management address reg */
43 u32 miimcon; /* MII management control reg */
44 u32 miimstat; /* MII management status reg */
45 u32 miimind; /* MII management indication reg */
46} __attribute__ ((packed));
47
48struct ucc_geth { 41struct ucc_geth {
49 struct ucc_fast uccf; 42 struct ucc_fast uccf;
50 43
@@ -53,7 +46,7 @@ struct ucc_geth {
53 u32 ipgifg; /* interframe gap reg. */ 46 u32 ipgifg; /* interframe gap reg. */
54 u32 hafdup; /* half-duplex reg. */ 47 u32 hafdup; /* half-duplex reg. */
55 u8 res1[0x10]; 48 u8 res1[0x10];
56 struct ucc_mii_mng miimng; /* MII management structure */ 49 u8 miimng[0x18]; /* MII management structure moved to _mii.h */
57 u32 ifctl; /* interface control reg */ 50 u32 ifctl; /* interface control reg */
58 u32 ifstat; /* interface statux reg */ 51 u32 ifstat; /* interface statux reg */
59 u32 macstnaddr1; /* mac station address part 1 reg */ 52 u32 macstnaddr1; /* mac station address part 1 reg */
@@ -212,6 +205,9 @@ struct ucc_geth {
212#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY |\ 205#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY |\
213 UCCE_RXC | UCCE_TXC | UCCE_TXE) 206 UCCE_RXC | UCCE_TXC | UCCE_TXE)
214 207
208#define UCCE_RX_EVENTS (UCCE_RXF | UCCE_BSY)
209#define UCCE_TX_EVENTS (UCCE_TXB | UCCE_TXE)
210
215/* UCC GETH UPSMR (Protocol Specific Mode Register) */ 211/* UCC GETH UPSMR (Protocol Specific Mode Register) */
216#define UPSMR_ECM 0x04000000 /* Enable CAM 212#define UPSMR_ECM 0x04000000 /* Enable CAM
217 Miss or 213 Miss or
@@ -381,66 +377,6 @@ struct ucc_geth {
381#define UCCS_MPD 0x01 /* Magic Packet 377#define UCCS_MPD 0x01 /* Magic Packet
382 Detected */ 378 Detected */
383 379
384/* UCC GETH MIIMCFG (MII Management Configuration Register) */
385#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset
386 management */
387#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble
388 suppress */
389#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide
390 << shift */
391#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* clock divide max val
392 */
393#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000 /* divide by 2 */
394#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001 /* divide by 4 */
395#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002 /* divide by 6 */
396#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003 /* divide by 8 */
397#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004 /* divide by 10
398 */
399#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005 /* divide by 14
400 */
401#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008 /* divide by 16
402 */
403#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006 /* divide by 20
404 */
405#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007 /* divide by 28
406 */
407#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009 /* divide by 32
408 */
409#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a /* divide by 48
410 */
411#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b /* divide by 64
412 */
413#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c /* divide by 80
414 */
415#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d /* divide by
416 112 */
417#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e /* divide by
418 160 */
419#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f /* divide by
420 224 */
421
422/* UCC GETH MIIMCOM (MII Management Command Register) */
423#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */
424#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */
425
426/* UCC GETH MIIMADD (MII Management Address Register) */
427#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address
428 << shift */
429#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register
430 << shift */
431
432/* UCC GETH MIIMCON (MII Management Control Register) */
433#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control
434 << shift */
435#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status
436 << shift */
437
438/* UCC GETH MIIMIND (MII Management Indicator Register) */
439#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */
440#define MIIMIND_SCAN 0x00000002 /* Scan in
441 progress */
442#define MIIMIND_BUSY 0x00000001
443
444/* UCC GETH IFSTAT (Interface Status Register) */ 380/* UCC GETH IFSTAT (Interface Status Register) */
445#define IFSTAT_EXCESS_DEFER 0x00000200 /* Excessive 381#define IFSTAT_EXCESS_DEFER 0x00000200 /* Excessive
446 transmission 382 transmission
@@ -931,8 +867,7 @@ struct ucc_geth_hardware_statistics {
931#define UCC_GETH_SCHEDULER_ALIGNMENT 4 /* This is a guess */ 867#define UCC_GETH_SCHEDULER_ALIGNMENT 4 /* This is a guess */
932#define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */ 868#define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */
933#define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ 869#define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */
934#define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 4 /* This is a 870#define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 64
935 guess */
936#define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */ 871#define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */
937#define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */ 872#define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */
938#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This 873#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This
@@ -1009,15 +944,6 @@ struct ucc_geth_hardware_statistics {
1009 register */ 944 register */
1010#define UCC_GETH_MACCFG1_INIT 0 945#define UCC_GETH_MACCFG1_INIT 0
1011#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1) 946#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1)
1012#define UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT \
1013 (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112)
1014
1015/* Ethernet speed */
1016enum enet_speed {
1017 ENET_SPEED_10BT, /* 10 Base T */
1018 ENET_SPEED_100BT, /* 100 Base T */
1019 ENET_SPEED_1000BT /* 1000 Base T */
1020};
1021 947
1022/* Ethernet Address Type. */ 948/* Ethernet Address Type. */
1023enum enet_addr_type { 949enum enet_addr_type {
@@ -1026,22 +952,6 @@ enum enet_addr_type {
1026 ENET_ADDR_TYPE_BROADCAST 952 ENET_ADDR_TYPE_BROADCAST
1027}; 953};
1028 954
1029/* TBI / MII Set Register */
1030enum enet_tbi_mii_reg {
1031 ENET_TBI_MII_CR = 0x00, /* Control (CR ) */
1032 ENET_TBI_MII_SR = 0x01, /* Status (SR ) */
1033 ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */
1034 ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability
1035 (ANLPBPA) */
1036 ENET_TBI_MII_ANEX = 0x06, /* AN expansion (ANEX ) */
1037 ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit (ANNPT ) */
1038 ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page
1039 (ANLPANP) */
1040 ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */
1041 ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */
1042 ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */
1043};
1044
1045/* UCC GETH 82xx Ethernet Address Recognition Location */ 955/* UCC GETH 82xx Ethernet Address Recognition Location */
1046enum ucc_geth_enet_address_recognition_location { 956enum ucc_geth_enet_address_recognition_location {
1047 UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station 957 UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station
@@ -1239,8 +1149,7 @@ struct ucc_geth_info {
1239 u16 pausePeriod; 1149 u16 pausePeriod;
1240 u16 extensionField; 1150 u16 extensionField;
1241 u8 phy_address; 1151 u8 phy_address;
1242 u32 board_flags; 1152 u32 mdio_bus;
1243 u32 phy_interrupt;
1244 u8 weightfactor[NUM_TX_QUEUES]; 1153 u8 weightfactor[NUM_TX_QUEUES];
1245 u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; 1154 u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
1246 u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; 1155 u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1249,7 +1158,6 @@ struct ucc_geth_info {
1249 u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; 1158 u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
1250 u16 bdRingLenTx[NUM_TX_QUEUES]; 1159 u16 bdRingLenTx[NUM_TX_QUEUES];
1251 u16 bdRingLenRx[NUM_RX_QUEUES]; 1160 u16 bdRingLenRx[NUM_RX_QUEUES];
1252 enum enet_interface enet_interface;
1253 enum ucc_geth_num_of_station_addresses numStationAddresses; 1161 enum ucc_geth_num_of_station_addresses numStationAddresses;
1254 enum qe_fltr_largest_external_tbl_lookup_key_size 1162 enum qe_fltr_largest_external_tbl_lookup_key_size
1255 largestexternallookupkeysize; 1163 largestexternallookupkeysize;
@@ -1326,9 +1234,11 @@ struct ucc_geth_private {
1326 /* index of the first skb which hasn't been transmitted yet. */ 1234 /* index of the first skb which hasn't been transmitted yet. */
1327 u16 skb_dirtytx[NUM_TX_QUEUES]; 1235 u16 skb_dirtytx[NUM_TX_QUEUES];
1328 1236
1329 struct work_struct tq;
1330 struct timer_list phy_info_timer;
1331 struct ugeth_mii_info *mii_info; 1237 struct ugeth_mii_info *mii_info;
1238 struct phy_device *phydev;
1239 phy_interface_t phy_interface;
1240 int max_speed;
1241 uint32_t msg_enable;
1332 int oldspeed; 1242 int oldspeed;
1333 int oldduplex; 1243 int oldduplex;
1334 int oldlink; 1244 int oldlink;
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
new file mode 100644
index 000000000000..73b5a538e8f4
--- /dev/null
+++ b/drivers/net/ucc_geth_mii.c
@@ -0,0 +1,279 @@
1/*
2 * drivers/net/ucc_geth_mii.c
3 *
4 * Gianfar Ethernet Driver -- MIIM bus implementation
5 * Provides Bus interface for MIIM regs
6 *
7 * Author: Li Yang
8 *
9 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/string.h>
21#include <linux/errno.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/interrupt.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30#include <linux/spinlock.h>
31#include <linux/mm.h>
32#include <linux/module.h>
33#include <linux/platform_device.h>
34#include <asm/ocp.h>
35#include <linux/crc32.h>
36#include <linux/mii.h>
37#include <linux/phy.h>
38#include <linux/fsl_devices.h>
39
40#include <asm/of_platform.h>
41#include <asm/io.h>
42#include <asm/irq.h>
43#include <asm/uaccess.h>
44#include <asm/ucc.h>
45
46#include "ucc_geth_mii.h"
47#include "ucc_geth.h"
48
49#define DEBUG
50#ifdef DEBUG
51#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
52#else
53#define vdbg(format, arg...) do {} while(0)
54#endif
55
56#define DRV_DESC "QE UCC Ethernet Controller MII Bus"
57#define DRV_NAME "fsl-uec_mdio"
58
59/* Write value to the PHY for this device to the register at regnum, */
60/* waiting until the write is done before it returns. All PHY */
61/* configuration has to be done through the master UEC MIIM regs */
62int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
63{
64 struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
65
66 /* Setting up the MII Mangement Address Register */
67 out_be32(&regs->miimadd,
68 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
69
70 /* Setting up the MII Mangement Control Register with the value */
71 out_be32(&regs->miimcon, value);
72
73 /* Wait till MII management write is complete */
74 while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
75 cpu_relax();
76
77 return 0;
78}
79
80/* Reads from register regnum in the PHY for device dev, */
81/* returning the value. Clears miimcom first. All PHY */
82/* configuration has to be done through the TSEC1 MIIM regs */
83int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
84{
85 struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
86 u16 value;
87
88 /* Setting up the MII Mangement Address Register */
89 out_be32(&regs->miimadd,
90 (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
91
92 /* Clear miimcom, perform an MII management read cycle */
93 out_be32(&regs->miimcom, 0);
94 out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);
95
96 /* Wait till MII management write is complete */
97 while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
98 cpu_relax();
99
100 /* Read MII management status */
101 value = in_be32(&regs->miimstat);
102
103 return value;
104}
105
106/* Reset the MIIM registers, and wait for the bus to free */
107int uec_mdio_reset(struct mii_bus *bus)
108{
109 struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
110 unsigned int timeout = PHY_INIT_TIMEOUT;
111
112 spin_lock_bh(&bus->mdio_lock);
113
114 /* Reset the management interface */
115 out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
116
117 /* Setup the MII Mgmt clock speed */
118 out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);
119
120 /* Wait until the bus is free */
121 while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
122 cpu_relax();
123
124 spin_unlock_bh(&bus->mdio_lock);
125
126 if (timeout <= 0) {
127 printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
128 return -EBUSY;
129 }
130
131 return 0;
132}
133
134static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
135{
136 struct device *device = &ofdev->dev;
137 struct device_node *np = ofdev->node, *tempnp = NULL;
138 struct device_node *child = NULL;
139 struct ucc_mii_mng __iomem *regs;
140 struct mii_bus *new_bus;
141 struct resource res;
142 int k, err = 0;
143
144 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
145
146 if (NULL == new_bus)
147 return -ENOMEM;
148
149 new_bus->name = "UCC Ethernet Controller MII Bus";
150 new_bus->read = &uec_mdio_read;
151 new_bus->write = &uec_mdio_write;
152 new_bus->reset = &uec_mdio_reset;
153
154 memset(&res, 0, sizeof(res));
155
156 err = of_address_to_resource(np, 0, &res);
157 if (err)
158 goto reg_map_fail;
159
160 new_bus->id = res.start;
161
162 new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
163
164 if (NULL == new_bus->irq) {
165 err = -ENOMEM;
166 goto reg_map_fail;
167 }
168
169 for (k = 0; k < 32; k++)
170 new_bus->irq[k] = PHY_POLL;
171
172 while ((child = of_get_next_child(np, child)) != NULL) {
173 int irq = irq_of_parse_and_map(child, 0);
174 if (irq != NO_IRQ) {
175 const u32 *id = get_property(child, "reg", NULL);
176 new_bus->irq[*id] = irq;
177 }
178 }
179
180 /* Set the base address */
181 regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
182
183 if (NULL == regs) {
184 err = -ENOMEM;
185 goto ioremap_fail;
186 }
187
188 new_bus->priv = (void __force *)regs;
189
190 new_bus->dev = device;
191 dev_set_drvdata(device, new_bus);
192
193 /* Read MII management master from device tree */
194 while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
195 != NULL) {
196 struct resource tempres;
197
198 err = of_address_to_resource(tempnp, 0, &tempres);
199 if (err)
200 goto bus_register_fail;
201
202 /* if our mdio regs fall within this UCC regs range */
203 if ((res.start >= tempres.start) &&
204 (res.end <= tempres.end)) {
205 /* set this UCC to be the MII master */
206 const u32 *id = get_property(tempnp, "device-id", NULL);
207 if (id == NULL)
208 goto bus_register_fail;
209
210 ucc_set_qe_mux_mii_mng(*id - 1);
211
212 /* assign the TBI an address which won't
213 * conflict with the PHYs */
214 out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
215 break;
216 }
217 }
218
219 err = mdiobus_register(new_bus);
220 if (0 != err) {
221 printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
222 new_bus->name);
223 goto bus_register_fail;
224 }
225
226 return 0;
227
228bus_register_fail:
229 iounmap(regs);
230ioremap_fail:
231 kfree(new_bus->irq);
232reg_map_fail:
233 kfree(new_bus);
234
235 return err;
236}
237
238int uec_mdio_remove(struct of_device *ofdev)
239{
240 struct device *device = &ofdev->dev;
241 struct mii_bus *bus = dev_get_drvdata(device);
242
243 mdiobus_unregister(bus);
244
245 dev_set_drvdata(device, NULL);
246
247 iounmap((void __iomem *)bus->priv);
248 bus->priv = NULL;
249 kfree(bus);
250
251 return 0;
252}
253
254static struct of_device_id uec_mdio_match[] = {
255 {
256 .type = "mdio",
257 .compatible = "ucc_geth_phy",
258 },
259 {},
260};
261
262MODULE_DEVICE_TABLE(of, uec_mdio_match);
263
264static struct of_platform_driver uec_mdio_driver = {
265 .name = DRV_NAME,
266 .probe = uec_mdio_probe,
267 .remove = uec_mdio_remove,
268 .match_table = uec_mdio_match,
269};
270
271int __init uec_mdio_init(void)
272{
273 return of_register_platform_driver(&uec_mdio_driver);
274}
275
276void __exit uec_mdio_exit(void)
277{
278 of_unregister_platform_driver(&uec_mdio_driver);
279}
diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h
new file mode 100644
index 000000000000..98430fe0bfc6
--- /dev/null
+++ b/drivers/net/ucc_geth_mii.h
@@ -0,0 +1,100 @@
1/*
2 * drivers/net/ucc_geth_mii.h
3 *
4 * Gianfar Ethernet Driver -- MII Management Bus Implementation
5 * Driver for the MDIO bus controller in the Gianfar register space
6 *
7 * Author: Andy Fleming
8 * Maintainer: Kumar Gala
9 *
10 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18#ifndef __UEC_MII_H
19#define __UEC_MII_H
20
21/* UCC GETH MIIMCFG (MII Management Configuration Register) */
22#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset
23 management */
24#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble
25 suppress */
26#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide
27 << shift */
28#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* max clock divide */
29#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000
30#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001
31#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002
32#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003
33#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004
34#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005
35#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008
36#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006
37#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007
38#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009
39#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a
40#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b
41#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c
42#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d
43#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e
44#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f
45
46/* UCC GETH MIIMCOM (MII Management Command Register) */
47#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */
48#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */
49
50/* UCC GETH MIIMADD (MII Management Address Register) */
51#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address
52 << shift */
53#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register
54 << shift */
55
56/* UCC GETH MIIMCON (MII Management Control Register) */
57#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control
58 << shift */
59#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status
60 << shift */
61
62/* UCC GETH MIIMIND (MII Management Indicator Register) */
63#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */
64#define MIIMIND_SCAN 0x00000002 /* Scan in
65 progress */
66#define MIIMIND_BUSY 0x00000001
67
68/* Initial TBI Physical Address */
69#define UTBIPAR_INIT_TBIPA 0x1f
70
71struct ucc_mii_mng {
72 u32 miimcfg; /* MII management configuration reg */
73 u32 miimcom; /* MII management command reg */
74 u32 miimadd; /* MII management address reg */
75 u32 miimcon; /* MII management control reg */
76 u32 miimstat; /* MII management status reg */
77 u32 miimind; /* MII management indication reg */
78 u8 notcare[28]; /* Space holder */
79 u32 utbipar; /* TBI phy address reg */
80} __attribute__ ((packed));
81
82/* TBI / MII Set Register */
83enum enet_tbi_mii_reg {
84 ENET_TBI_MII_CR = 0x00, /* Control */
85 ENET_TBI_MII_SR = 0x01, /* Status */
86 ENET_TBI_MII_ANA = 0x04, /* AN advertisement */
87 ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability */
88 ENET_TBI_MII_ANEX = 0x06, /* AN expansion */
89 ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit */
90 ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page */
91 ENET_TBI_MII_EXST = 0x0F, /* Extended status */
92 ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics */
93 ENET_TBI_MII_TBICON = 0x11 /* TBI control */
94};
95
96int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
97int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
98int __init uec_mdio_init(void);
99void __exit uec_mdio_exit(void);
100#endif /* __UEC_MII_H */
diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c
deleted file mode 100644
index 9373d895b9ec..000000000000
--- a/drivers/net/ucc_geth_phy.c
+++ /dev/null
@@ -1,785 +0,0 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Author: Shlomi Gridish <gridish@freescale.com>
5 *
6 * Description:
7 * UCC GETH Driver -- PHY handling
8 *
9 * Changelog:
10 * Jun 28, 2006 Li Yang <LeoLi@freescale.com>
11 * - Rearrange code and style fixes
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/string.h>
22#include <linux/errno.h>
23#include <linux/slab.h>
24#include <linux/interrupt.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30#include <linux/spinlock.h>
31#include <linux/mm.h>
32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/crc32.h>
35#include <linux/mii.h>
36#include <linux/ethtool.h>
37
38#include <asm/io.h>
39#include <asm/irq.h>
40#include <asm/uaccess.h>
41
42#include "ucc_geth.h"
43#include "ucc_geth_phy.h"
44
45#define ugphy_printk(level, format, arg...) \
46 printk(level format "\n", ## arg)
47
48#define ugphy_dbg(format, arg...) \
49 ugphy_printk(KERN_DEBUG, format , ## arg)
50#define ugphy_err(format, arg...) \
51 ugphy_printk(KERN_ERR, format , ## arg)
52#define ugphy_info(format, arg...) \
53 ugphy_printk(KERN_INFO, format , ## arg)
54#define ugphy_warn(format, arg...) \
55 ugphy_printk(KERN_WARNING, format , ## arg)
56
57#ifdef UGETH_VERBOSE_DEBUG
58#define ugphy_vdbg ugphy_dbg
59#else
60#define ugphy_vdbg(fmt, args...) do { } while (0)
61#endif /* UGETH_VERBOSE_DEBUG */
62
63static void config_genmii_advert(struct ugeth_mii_info *mii_info);
64static void genmii_setup_forced(struct ugeth_mii_info *mii_info);
65static void genmii_restart_aneg(struct ugeth_mii_info *mii_info);
66static int gbit_config_aneg(struct ugeth_mii_info *mii_info);
67static int genmii_config_aneg(struct ugeth_mii_info *mii_info);
68static int genmii_update_link(struct ugeth_mii_info *mii_info);
69static int genmii_read_status(struct ugeth_mii_info *mii_info);
70
71static u16 ucc_geth_phy_read(struct ugeth_mii_info *mii_info, u16 regnum)
72{
73 u16 retval;
74 unsigned long flags;
75
76 ugphy_vdbg("%s: IN", __FUNCTION__);
77
78 spin_lock_irqsave(&mii_info->mdio_lock, flags);
79 retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
80 spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
81
82 return retval;
83}
84
85static void ucc_geth_phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val)
86{
87 unsigned long flags;
88
89 ugphy_vdbg("%s: IN", __FUNCTION__);
90
91 spin_lock_irqsave(&mii_info->mdio_lock, flags);
92 mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val);
93 spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
94}
95
96/* Write value to the PHY for this device to the register at regnum, */
97/* waiting until the write is done before it returns. All PHY */
98/* configuration has to be done through the TSEC1 MIIM regs */
99void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
100{
101 struct ucc_geth_private *ugeth = netdev_priv(dev);
102 struct ucc_mii_mng *mii_regs;
103 enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
104 u32 tmp_reg;
105
106 ugphy_vdbg("%s: IN", __FUNCTION__);
107
108 spin_lock_irq(&ugeth->lock);
109
110 mii_regs = ugeth->mii_info->mii_regs;
111
112 /* Set this UCC to be the master of the MII managment */
113 ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
114
115 /* Stop the MII management read cycle */
116 out_be32(&mii_regs->miimcom, 0);
117 /* Setting up the MII Mangement Address Register */
118 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
119 out_be32(&mii_regs->miimadd, tmp_reg);
120
121 /* Setting up the MII Mangement Control Register with the value */
122 out_be32(&mii_regs->miimcon, (u32) value);
123
124 /* Wait till MII management write is complete */
125 while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY)
126 cpu_relax();
127
128 spin_unlock_irq(&ugeth->lock);
129
130 udelay(10000);
131}
132
133/* Reads from register regnum in the PHY for device dev, */
134/* returning the value. Clears miimcom first. All PHY */
135/* configuration has to be done through the TSEC1 MIIM regs */
136int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
137{
138 struct ucc_geth_private *ugeth = netdev_priv(dev);
139 struct ucc_mii_mng *mii_regs;
140 enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
141 u32 tmp_reg;
142 u16 value;
143
144 ugphy_vdbg("%s: IN", __FUNCTION__);
145
146 spin_lock_irq(&ugeth->lock);
147
148 mii_regs = ugeth->mii_info->mii_regs;
149
150 /* Setting up the MII Mangement Address Register */
151 tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
152 out_be32(&mii_regs->miimadd, tmp_reg);
153
154 /* Perform an MII management read cycle */
155 out_be32(&mii_regs->miimcom, MIIMCOM_READ_CYCLE);
156
157 /* Wait till MII management write is complete */
158 while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY)
159 cpu_relax();
160
161 udelay(10000);
162
163 /* Read MII management status */
164 value = (u16) in_be32(&mii_regs->miimstat);
165 out_be32(&mii_regs->miimcom, 0);
166 if (value == 0xffff)
167 ugphy_warn("read wrong value : mii_id %d,mii_reg %d, base %08x",
168 mii_id, mii_reg, (u32) & (mii_regs->miimcfg));
169
170 spin_unlock_irq(&ugeth->lock);
171
172 return (value);
173}
174
175void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info)
176{
177 ugphy_vdbg("%s: IN", __FUNCTION__);
178
179 if (mii_info->phyinfo->ack_interrupt)
180 mii_info->phyinfo->ack_interrupt(mii_info);
181}
182
183void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info,
184 u32 interrupts)
185{
186 ugphy_vdbg("%s: IN", __FUNCTION__);
187
188 mii_info->interrupts = interrupts;
189 if (mii_info->phyinfo->config_intr)
190 mii_info->phyinfo->config_intr(mii_info);
191}
192
193/* Writes MII_ADVERTISE with the appropriate values, after
194 * sanitizing advertise to make sure only supported features
195 * are advertised
196 */
197static void config_genmii_advert(struct ugeth_mii_info *mii_info)
198{
199 u32 advertise;
200 u16 adv;
201
202 ugphy_vdbg("%s: IN", __FUNCTION__);
203
204 /* Only allow advertising what this PHY supports */
205 mii_info->advertising &= mii_info->phyinfo->features;
206 advertise = mii_info->advertising;
207
208 /* Setup standard advertisement */
209 adv = ucc_geth_phy_read(mii_info, MII_ADVERTISE);
210 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
211 if (advertise & ADVERTISED_10baseT_Half)
212 adv |= ADVERTISE_10HALF;
213 if (advertise & ADVERTISED_10baseT_Full)
214 adv |= ADVERTISE_10FULL;
215 if (advertise & ADVERTISED_100baseT_Half)
216 adv |= ADVERTISE_100HALF;
217 if (advertise & ADVERTISED_100baseT_Full)
218 adv |= ADVERTISE_100FULL;
219 ucc_geth_phy_write(mii_info, MII_ADVERTISE, adv);
220}
221
222static void genmii_setup_forced(struct ugeth_mii_info *mii_info)
223{
224 u16 ctrl;
225 u32 features = mii_info->phyinfo->features;
226
227 ugphy_vdbg("%s: IN", __FUNCTION__);
228
229 ctrl = ucc_geth_phy_read(mii_info, MII_BMCR);
230
231 ctrl &=
232 ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
233 ctrl |= BMCR_RESET;
234
235 switch (mii_info->speed) {
236 case SPEED_1000:
237 if (features & (SUPPORTED_1000baseT_Half
238 | SUPPORTED_1000baseT_Full)) {
239 ctrl |= BMCR_SPEED1000;
240 break;
241 }
242 mii_info->speed = SPEED_100;
243 case SPEED_100:
244 if (features & (SUPPORTED_100baseT_Half
245 | SUPPORTED_100baseT_Full)) {
246 ctrl |= BMCR_SPEED100;
247 break;
248 }
249 mii_info->speed = SPEED_10;
250 case SPEED_10:
251 if (features & (SUPPORTED_10baseT_Half
252 | SUPPORTED_10baseT_Full))
253 break;
254 default: /* Unsupported speed! */
255 ugphy_err("%s: Bad speed!", mii_info->dev->name);
256 break;
257 }
258
259 ucc_geth_phy_write(mii_info, MII_BMCR, ctrl);
260}
261
262/* Enable and Restart Autonegotiation */
263static void genmii_restart_aneg(struct ugeth_mii_info *mii_info)
264{
265 u16 ctl;
266
267 ugphy_vdbg("%s: IN", __FUNCTION__);
268
269 ctl = ucc_geth_phy_read(mii_info, MII_BMCR);
270 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
271 ucc_geth_phy_write(mii_info, MII_BMCR, ctl);
272}
273
274static int gbit_config_aneg(struct ugeth_mii_info *mii_info)
275{
276 u16 adv;
277 u32 advertise;
278
279 ugphy_vdbg("%s: IN", __FUNCTION__);
280
281 if (mii_info->autoneg) {
282 /* Configure the ADVERTISE register */
283 config_genmii_advert(mii_info);
284 advertise = mii_info->advertising;
285
286 adv = ucc_geth_phy_read(mii_info, MII_1000BASETCONTROL);
287 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
288 MII_1000BASETCONTROL_HALFDUPLEXCAP);
289 if (advertise & SUPPORTED_1000baseT_Half)
290 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
291 if (advertise & SUPPORTED_1000baseT_Full)
292 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
293 ucc_geth_phy_write(mii_info, MII_1000BASETCONTROL, adv);
294
295 /* Start/Restart aneg */
296 genmii_restart_aneg(mii_info);
297 } else
298 genmii_setup_forced(mii_info);
299
300 return 0;
301}
302
303static int genmii_config_aneg(struct ugeth_mii_info *mii_info)
304{
305 ugphy_vdbg("%s: IN", __FUNCTION__);
306
307 if (mii_info->autoneg) {
308 config_genmii_advert(mii_info);
309 genmii_restart_aneg(mii_info);
310 } else
311 genmii_setup_forced(mii_info);
312
313 return 0;
314}
315
316static int genmii_update_link(struct ugeth_mii_info *mii_info)
317{
318 u16 status;
319
320 ugphy_vdbg("%s: IN", __FUNCTION__);
321
322 /* Do a fake read */
323 ucc_geth_phy_read(mii_info, MII_BMSR);
324
325 /* Read link and autonegotiation status */
326 status = ucc_geth_phy_read(mii_info, MII_BMSR);
327 if ((status & BMSR_LSTATUS) == 0)
328 mii_info->link = 0;
329 else
330 mii_info->link = 1;
331
332 /* If we are autonegotiating, and not done,
333 * return an error */
334 if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
335 return -EAGAIN;
336
337 return 0;
338}
339
340static int genmii_read_status(struct ugeth_mii_info *mii_info)
341{
342 u16 status;
343 int err;
344
345 ugphy_vdbg("%s: IN", __FUNCTION__);
346
347 /* Update the link, but return if there
348 * was an error */
349 err = genmii_update_link(mii_info);
350 if (err)
351 return err;
352
353 if (mii_info->autoneg) {
354 status = ucc_geth_phy_read(mii_info, MII_LPA);
355
356 if (status & (LPA_10FULL | LPA_100FULL))
357 mii_info->duplex = DUPLEX_FULL;
358 else
359 mii_info->duplex = DUPLEX_HALF;
360 if (status & (LPA_100FULL | LPA_100HALF))
361 mii_info->speed = SPEED_100;
362 else
363 mii_info->speed = SPEED_10;
364 mii_info->pause = 0;
365 }
366 /* On non-aneg, we assume what we put in BMCR is the speed,
367 * though magic-aneg shouldn't prevent this case from occurring
368 */
369
370 return 0;
371}
372
373static int marvell_init(struct ugeth_mii_info *mii_info)
374{
375 ugphy_vdbg("%s: IN", __FUNCTION__);
376
377 ucc_geth_phy_write(mii_info, 0x14, 0x0cd2);
378 ucc_geth_phy_write(mii_info, 0x1b,
379 (ucc_geth_phy_read(mii_info, 0x1b) & ~0x000f) | 0x000b);
380 ucc_geth_phy_write(mii_info, MII_BMCR,
381 ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET);
382 msleep(4000);
383
384 return 0;
385}
386
387static int marvell_config_aneg(struct ugeth_mii_info *mii_info)
388{
389 ugphy_vdbg("%s: IN", __FUNCTION__);
390
391 /* The Marvell PHY has an errata which requires
392 * that certain registers get written in order
393 * to restart autonegotiation */
394 ucc_geth_phy_write(mii_info, MII_BMCR, BMCR_RESET);
395
396 ucc_geth_phy_write(mii_info, 0x1d, 0x1f);
397 ucc_geth_phy_write(mii_info, 0x1e, 0x200c);
398 ucc_geth_phy_write(mii_info, 0x1d, 0x5);
399 ucc_geth_phy_write(mii_info, 0x1e, 0);
400 ucc_geth_phy_write(mii_info, 0x1e, 0x100);
401
402 gbit_config_aneg(mii_info);
403
404 return 0;
405}
406
407static int marvell_read_status(struct ugeth_mii_info *mii_info)
408{
409 u16 status;
410 int err;
411
412 ugphy_vdbg("%s: IN", __FUNCTION__);
413
414 /* Update the link, but return if there
415 * was an error */
416 err = genmii_update_link(mii_info);
417 if (err)
418 return err;
419
420 /* If the link is up, read the speed and duplex */
421 /* If we aren't autonegotiating, assume speeds
422 * are as set */
423 if (mii_info->autoneg && mii_info->link) {
424 int speed;
425 status = ucc_geth_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
426
427 /* Get the duplexity */
428 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
429 mii_info->duplex = DUPLEX_FULL;
430 else
431 mii_info->duplex = DUPLEX_HALF;
432
433 /* Get the speed */
434 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
435 switch (speed) {
436 case MII_M1011_PHY_SPEC_STATUS_1000:
437 mii_info->speed = SPEED_1000;
438 break;
439 case MII_M1011_PHY_SPEC_STATUS_100:
440 mii_info->speed = SPEED_100;
441 break;
442 default:
443 mii_info->speed = SPEED_10;
444 break;
445 }
446 mii_info->pause = 0;
447 }
448
449 return 0;
450}
451
452static int marvell_ack_interrupt(struct ugeth_mii_info *mii_info)
453{
454 ugphy_vdbg("%s: IN", __FUNCTION__);
455
456 /* Clear the interrupts by reading the reg */
457 ucc_geth_phy_read(mii_info, MII_M1011_IEVENT);
458
459 return 0;
460}
461
462static int marvell_config_intr(struct ugeth_mii_info *mii_info)
463{
464 ugphy_vdbg("%s: IN", __FUNCTION__);
465
466 if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
467 ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
468 else
469 ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
470
471 return 0;
472}
473
474static int cis820x_init(struct ugeth_mii_info *mii_info)
475{
476 ugphy_vdbg("%s: IN", __FUNCTION__);
477
478 ucc_geth_phy_write(mii_info, MII_CIS8201_AUX_CONSTAT,
479 MII_CIS8201_AUXCONSTAT_INIT);
480 ucc_geth_phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT);
481
482 return 0;
483}
484
485static int cis820x_read_status(struct ugeth_mii_info *mii_info)
486{
487 u16 status;
488 int err;
489
490 ugphy_vdbg("%s: IN", __FUNCTION__);
491
492 /* Update the link, but return if there
493 * was an error */
494 err = genmii_update_link(mii_info);
495 if (err)
496 return err;
497
498 /* If the link is up, read the speed and duplex */
499 /* If we aren't autonegotiating, assume speeds
500 * are as set */
501 if (mii_info->autoneg && mii_info->link) {
502 int speed;
503
504 status = ucc_geth_phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
505 if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
506 mii_info->duplex = DUPLEX_FULL;
507 else
508 mii_info->duplex = DUPLEX_HALF;
509
510 speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
511
512 switch (speed) {
513 case MII_CIS8201_AUXCONSTAT_GBIT:
514 mii_info->speed = SPEED_1000;
515 break;
516 case MII_CIS8201_AUXCONSTAT_100:
517 mii_info->speed = SPEED_100;
518 break;
519 default:
520 mii_info->speed = SPEED_10;
521 break;
522 }
523 }
524
525 return 0;
526}
527
528static int cis820x_ack_interrupt(struct ugeth_mii_info *mii_info)
529{
530 ugphy_vdbg("%s: IN", __FUNCTION__);
531
532 ucc_geth_phy_read(mii_info, MII_CIS8201_ISTAT);
533
534 return 0;
535}
536
537static int cis820x_config_intr(struct ugeth_mii_info *mii_info)
538{
539 ugphy_vdbg("%s: IN", __FUNCTION__);
540
541 if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
542 ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
543 else
544 ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, 0);
545
546 return 0;
547}
548
549#define DM9161_DELAY 10
550
551static int dm9161_read_status(struct ugeth_mii_info *mii_info)
552{
553 u16 status;
554 int err;
555
556 ugphy_vdbg("%s: IN", __FUNCTION__);
557
558 /* Update the link, but return if there
559 * was an error */
560 err = genmii_update_link(mii_info);
561 if (err)
562 return err;
563
564 /* If the link is up, read the speed and duplex */
565 /* If we aren't autonegotiating, assume speeds
566 * are as set */
567 if (mii_info->autoneg && mii_info->link) {
568 status = ucc_geth_phy_read(mii_info, MII_DM9161_SCSR);
569 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
570 mii_info->speed = SPEED_100;
571 else
572 mii_info->speed = SPEED_10;
573
574 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
575 mii_info->duplex = DUPLEX_FULL;
576 else
577 mii_info->duplex = DUPLEX_HALF;
578 }
579
580 return 0;
581}
582
583static int dm9161_config_aneg(struct ugeth_mii_info *mii_info)
584{
585 struct dm9161_private *priv = mii_info->priv;
586
587 ugphy_vdbg("%s: IN", __FUNCTION__);
588
589 if (0 == priv->resetdone)
590 return -EAGAIN;
591
592 return 0;
593}
594
595static void dm9161_timer(unsigned long data)
596{
597 struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
598 struct dm9161_private *priv = mii_info->priv;
599 u16 status = ucc_geth_phy_read(mii_info, MII_BMSR);
600
601 ugphy_vdbg("%s: IN", __FUNCTION__);
602
603 if (status & BMSR_ANEGCOMPLETE) {
604 priv->resetdone = 1;
605 } else
606 mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
607}
608
609static int dm9161_init(struct ugeth_mii_info *mii_info)
610{
611 struct dm9161_private *priv;
612
613 ugphy_vdbg("%s: IN", __FUNCTION__);
614
615 /* Allocate the private data structure */
616 priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
617
618 if (NULL == priv)
619 return -ENOMEM;
620
621 mii_info->priv = priv;
622
623 /* Reset is not done yet */
624 priv->resetdone = 0;
625
626 ucc_geth_phy_write(mii_info, MII_BMCR,
627 ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET);
628
629 ucc_geth_phy_write(mii_info, MII_BMCR,
630 ucc_geth_phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE);
631
632 config_genmii_advert(mii_info);
633 /* Start/Restart aneg */
634 genmii_config_aneg(mii_info);
635
636 /* Start a timer for DM9161_DELAY seconds to wait
637 * for the PHY to be ready */
638 init_timer(&priv->timer);
639 priv->timer.function = &dm9161_timer;
640 priv->timer.data = (unsigned long)mii_info;
641 mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
642
643 return 0;
644}
645
646static void dm9161_close(struct ugeth_mii_info *mii_info)
647{
648 struct dm9161_private *priv = mii_info->priv;
649
650 ugphy_vdbg("%s: IN", __FUNCTION__);
651
652 del_timer_sync(&priv->timer);
653 kfree(priv);
654}
655
656static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info)
657{
658 ugphy_vdbg("%s: IN", __FUNCTION__);
659
660 /* Clear the interrupts by reading the reg */
661 ucc_geth_phy_read(mii_info, MII_DM9161_INTR);
662
663
664 return 0;
665}
666
667static int dm9161_config_intr(struct ugeth_mii_info *mii_info)
668{
669 ugphy_vdbg("%s: IN", __FUNCTION__);
670
671 if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
672 ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
673 else
674 ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
675
676 return 0;
677}
678
679/* Cicada 820x */
680static struct phy_info phy_info_cis820x = {
681 .phy_id = 0x000fc440,
682 .name = "Cicada Cis8204",
683 .phy_id_mask = 0x000fffc0,
684 .features = MII_GBIT_FEATURES,
685 .init = &cis820x_init,
686 .config_aneg = &gbit_config_aneg,
687 .read_status = &cis820x_read_status,
688 .ack_interrupt = &cis820x_ack_interrupt,
689 .config_intr = &cis820x_config_intr,
690};
691
692static struct phy_info phy_info_dm9161 = {
693 .phy_id = 0x0181b880,
694 .phy_id_mask = 0x0ffffff0,
695 .name = "Davicom DM9161E",
696 .init = dm9161_init,
697 .config_aneg = dm9161_config_aneg,
698 .read_status = dm9161_read_status,
699 .close = dm9161_close,
700};
701
702static struct phy_info phy_info_dm9161a = {
703 .phy_id = 0x0181b8a0,
704 .phy_id_mask = 0x0ffffff0,
705 .name = "Davicom DM9161A",
706 .features = MII_BASIC_FEATURES,
707 .init = dm9161_init,
708 .config_aneg = dm9161_config_aneg,
709 .read_status = dm9161_read_status,
710 .ack_interrupt = dm9161_ack_interrupt,
711 .config_intr = dm9161_config_intr,
712 .close = dm9161_close,
713};
714
715static struct phy_info phy_info_marvell = {
716 .phy_id = 0x01410c00,
717 .phy_id_mask = 0xffffff00,
718 .name = "Marvell 88E11x1",
719 .features = MII_GBIT_FEATURES,
720 .init = &marvell_init,
721 .config_aneg = &marvell_config_aneg,
722 .read_status = &marvell_read_status,
723 .ack_interrupt = &marvell_ack_interrupt,
724 .config_intr = &marvell_config_intr,
725};
726
727static struct phy_info phy_info_genmii = {
728 .phy_id = 0x00000000,
729 .phy_id_mask = 0x00000000,
730 .name = "Generic MII",
731 .features = MII_BASIC_FEATURES,
732 .config_aneg = genmii_config_aneg,
733 .read_status = genmii_read_status,
734};
735
736static struct phy_info *phy_info[] = {
737 &phy_info_cis820x,
738 &phy_info_marvell,
739 &phy_info_dm9161,
740 &phy_info_dm9161a,
741 &phy_info_genmii,
742 NULL
743};
744
745/* Use the PHY ID registers to determine what type of PHY is attached
746 * to device dev. return a struct phy_info structure describing that PHY
747 */
748struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info)
749{
750 u16 phy_reg;
751 u32 phy_ID;
752 int i;
753 struct phy_info *theInfo = NULL;
754 struct net_device *dev = mii_info->dev;
755
756 ugphy_vdbg("%s: IN", __FUNCTION__);
757
758 /* Grab the bits from PHYIR1, and put them in the upper half */
759 phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID1);
760 phy_ID = (phy_reg & 0xffff) << 16;
761
762 /* Grab the bits from PHYIR2, and put them in the lower half */
763 phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID2);
764 phy_ID |= (phy_reg & 0xffff);
765
766 /* loop through all the known PHY types, and find one that */
767 /* matches the ID we read from the PHY. */
768 for (i = 0; phy_info[i]; i++)
769 if (phy_info[i]->phy_id == (phy_ID & phy_info[i]->phy_id_mask)){
770 theInfo = phy_info[i];
771 break;
772 }
773
774 /* This shouldn't happen, as we have generic PHY support */
775 if (theInfo == NULL) {
776 ugphy_info("%s: PHY id %x is not supported!", dev->name,
777 phy_ID);
778 return NULL;
779 } else {
780 ugphy_info("%s: PHY is %s (%x)", dev->name, theInfo->name,
781 phy_ID);
782 }
783
784 return theInfo;
785}
diff --git a/drivers/net/ucc_geth_phy.h b/drivers/net/ucc_geth_phy.h
deleted file mode 100644
index f5740783670f..000000000000
--- a/drivers/net/ucc_geth_phy.h
+++ /dev/null
@@ -1,217 +0,0 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Author: Shlomi Gridish <gridish@freescale.com>
5 *
6 * Description:
7 * UCC GETH Driver -- PHY handling
8 *
9 * Changelog:
10 * Jun 28, 2006 Li Yang <LeoLi@freescale.com>
11 * - Rearrange code and style fixes
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 */
19#ifndef __UCC_GETH_PHY_H__
20#define __UCC_GETH_PHY_H__
21
22#define MII_end ((u32)-2)
23#define MII_read ((u32)-1)
24
25#define MIIMIND_BUSY 0x00000001
26#define MIIMIND_NOTVALID 0x00000004
27
28#define UGETH_AN_TIMEOUT 2000
29
30/* 1000BT control (Marvell & BCM54xx at least) */
31#define MII_1000BASETCONTROL 0x09
32#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
33#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
34
35/* Cicada Extended Control Register 1 */
36#define MII_CIS8201_EXT_CON1 0x17
37#define MII_CIS8201_EXTCON1_INIT 0x0000
38
39/* Cicada Interrupt Mask Register */
40#define MII_CIS8201_IMASK 0x19
41#define MII_CIS8201_IMASK_IEN 0x8000
42#define MII_CIS8201_IMASK_SPEED 0x4000
43#define MII_CIS8201_IMASK_LINK 0x2000
44#define MII_CIS8201_IMASK_DUPLEX 0x1000
45#define MII_CIS8201_IMASK_MASK 0xf000
46
47/* Cicada Interrupt Status Register */
48#define MII_CIS8201_ISTAT 0x1a
49#define MII_CIS8201_ISTAT_STATUS 0x8000
50#define MII_CIS8201_ISTAT_SPEED 0x4000
51#define MII_CIS8201_ISTAT_LINK 0x2000
52#define MII_CIS8201_ISTAT_DUPLEX 0x1000
53
54/* Cicada Auxiliary Control/Status Register */
55#define MII_CIS8201_AUX_CONSTAT 0x1c
56#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
57#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
58#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
59#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
60#define MII_CIS8201_AUXCONSTAT_100 0x0008
61
62/* 88E1011 PHY Status Register */
63#define MII_M1011_PHY_SPEC_STATUS 0x11
64#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
65#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
66#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
67#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
68#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
69#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400
70
71#define MII_M1011_IEVENT 0x13
72#define MII_M1011_IEVENT_CLEAR 0x0000
73
74#define MII_M1011_IMASK 0x12
75#define MII_M1011_IMASK_INIT 0x6400
76#define MII_M1011_IMASK_CLEAR 0x0000
77
78#define MII_DM9161_SCR 0x10
79#define MII_DM9161_SCR_INIT 0x0610
80
81/* DM9161 Specified Configuration and Status Register */
82#define MII_DM9161_SCSR 0x11
83#define MII_DM9161_SCSR_100F 0x8000
84#define MII_DM9161_SCSR_100H 0x4000
85#define MII_DM9161_SCSR_10F 0x2000
86#define MII_DM9161_SCSR_10H 0x1000
87
88/* DM9161 Interrupt Register */
89#define MII_DM9161_INTR 0x15
90#define MII_DM9161_INTR_PEND 0x8000
91#define MII_DM9161_INTR_DPLX_MASK 0x0800
92#define MII_DM9161_INTR_SPD_MASK 0x0400
93#define MII_DM9161_INTR_LINK_MASK 0x0200
94#define MII_DM9161_INTR_MASK 0x0100
95#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
96#define MII_DM9161_INTR_SPD_CHANGE 0x0008
97#define MII_DM9161_INTR_LINK_CHANGE 0x0004
98#define MII_DM9161_INTR_INIT 0x0000
99#define MII_DM9161_INTR_STOP \
100(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
101 | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
102
103/* DM9161 10BT Configuration/Status */
104#define MII_DM9161_10BTCSR 0x12
105#define MII_DM9161_10BTCSR_INIT 0x7800
106
107#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
108 SUPPORTED_10baseT_Full | \
109 SUPPORTED_100baseT_Half | \
110 SUPPORTED_100baseT_Full | \
111 SUPPORTED_Autoneg | \
112 SUPPORTED_TP | \
113 SUPPORTED_MII)
114
115#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
116 SUPPORTED_1000baseT_Half | \
117 SUPPORTED_1000baseT_Full)
118
119#define MII_READ_COMMAND 0x00000001
120
121#define MII_INTERRUPT_DISABLED 0x0
122#define MII_INTERRUPT_ENABLED 0x1
123/* Taken from mii_if_info and sungem_phy.h */
124struct ugeth_mii_info {
125 /* Information about the PHY type */
126 /* And management functions */
127 struct phy_info *phyinfo;
128
129 struct ucc_mii_mng *mii_regs;
130
131 /* forced speed & duplex (no autoneg)
132 * partner speed & duplex & pause (autoneg)
133 */
134 int speed;
135 int duplex;
136 int pause;
137
138 /* The most recently read link state */
139 int link;
140
141 /* Enabled Interrupts */
142 u32 interrupts;
143
144 u32 advertising;
145 int autoneg;
146 int mii_id;
147
148 /* private data pointer */
149 /* For use by PHYs to maintain extra state */
150 void *priv;
151
152 /* Provided by host chip */
153 struct net_device *dev;
154
155 /* A lock to ensure that only one thing can read/write
156 * the MDIO bus at a time */
157 spinlock_t mdio_lock;
158
159 /* Provided by ethernet driver */
160 int (*mdio_read) (struct net_device * dev, int mii_id, int reg);
161 void (*mdio_write) (struct net_device * dev, int mii_id, int reg,
162 int val);
163};
164
165/* struct phy_info: a structure which defines attributes for a PHY
166 *
167 * id will contain a number which represents the PHY. During
168 * startup, the driver will poll the PHY to find out what its
169 * UID--as defined by registers 2 and 3--is. The 32-bit result
170 * gotten from the PHY will be ANDed with phy_id_mask to
171 * discard any bits which may change based on revision numbers
172 * unimportant to functionality
173 *
174 * There are 6 commands which take a ugeth_mii_info structure.
175 * Each PHY must declare config_aneg, and read_status.
176 */
177struct phy_info {
178 u32 phy_id;
179 char *name;
180 unsigned int phy_id_mask;
181 u32 features;
182
183 /* Called to initialize the PHY */
184 int (*init) (struct ugeth_mii_info * mii_info);
185
186 /* Called to suspend the PHY for power */
187 int (*suspend) (struct ugeth_mii_info * mii_info);
188
189 /* Reconfigures autonegotiation (or disables it) */
190 int (*config_aneg) (struct ugeth_mii_info * mii_info);
191
192 /* Determines the negotiated speed and duplex */
193 int (*read_status) (struct ugeth_mii_info * mii_info);
194
195 /* Clears any pending interrupts */
196 int (*ack_interrupt) (struct ugeth_mii_info * mii_info);
197
198 /* Enables or disables interrupts */
199 int (*config_intr) (struct ugeth_mii_info * mii_info);
200
201 /* Clears up any memory if needed */
202 void (*close) (struct ugeth_mii_info * mii_info);
203};
204
205struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info);
206void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
207int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
208void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info);
209void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info,
210 u32 interrupts);
211
212struct dm9161_private {
213 struct timer_list timer;
214 int resetdone;
215};
216
217#endif /* __UCC_GETH_PHY_H__ */
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 00e0aaadabcc..9ec6cf2e510e 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -37,16 +37,16 @@
37struct hdlc_header { 37struct hdlc_header {
38 u8 address; 38 u8 address;
39 u8 control; 39 u8 control;
40 u16 protocol; 40 __be16 protocol;
41}__attribute__ ((packed)); 41}__attribute__ ((packed));
42 42
43 43
44struct cisco_packet { 44struct cisco_packet {
45 u32 type; /* code */ 45 __be32 type; /* code */
46 u32 par1; 46 __be32 par1;
47 u32 par2; 47 __be32 par2;
48 u16 rel; /* reliability */ 48 __be16 rel; /* reliability */
49 u32 time; 49 __be32 time;
50}__attribute__ ((packed)); 50}__attribute__ ((packed));
51#define CISCO_PACKET_LEN 18 51#define CISCO_PACKET_LEN 18
52#define CISCO_BIG_PACKET_LEN 20 52#define CISCO_BIG_PACKET_LEN 20
@@ -97,7 +97,7 @@ static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
97 97
98 98
99static void cisco_keepalive_send(struct net_device *dev, u32 type, 99static void cisco_keepalive_send(struct net_device *dev, u32 type,
100 u32 par1, u32 par2) 100 __be32 par1, __be32 par2)
101{ 101{
102 struct sk_buff *skb; 102 struct sk_buff *skb;
103 struct cisco_packet *data; 103 struct cisco_packet *data;
@@ -115,9 +115,9 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
115 data = (struct cisco_packet*)(skb->data + 4); 115 data = (struct cisco_packet*)(skb->data + 4);
116 116
117 data->type = htonl(type); 117 data->type = htonl(type);
118 data->par1 = htonl(par1); 118 data->par1 = par1;
119 data->par2 = htonl(par2); 119 data->par2 = par2;
120 data->rel = 0xFFFF; 120 data->rel = __constant_htons(0xFFFF);
121 /* we will need do_div here if 1000 % HZ != 0 */ 121 /* we will need do_div here if 1000 % HZ != 0 */
122 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); 122 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
123 123
@@ -193,7 +193,7 @@ static int cisco_rx(struct sk_buff *skb)
193 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ 193 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
194 in_dev = dev->ip_ptr; 194 in_dev = dev->ip_ptr;
195 addr = 0; 195 addr = 0;
196 mask = ~0; /* is the mask correct? */ 196 mask = __constant_htonl(~0); /* is the mask correct? */
197 197
198 if (in_dev != NULL) { 198 if (in_dev != NULL) {
199 struct in_ifaddr **ifap = &in_dev->ifa_list; 199 struct in_ifaddr **ifap = &in_dev->ifa_list;
@@ -245,7 +245,7 @@ static int cisco_rx(struct sk_buff *skb)
245 } /* switch(protocol) */ 245 } /* switch(protocol) */
246 246
247 printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, 247 printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name,
248 data->protocol); 248 ntohs(data->protocol));
249 dev_kfree_skb_any(skb); 249 dev_kfree_skb_any(skb);
250 return NET_RX_DROP; 250 return NET_RX_DROP;
251 251
@@ -270,8 +270,9 @@ static void cisco_timer(unsigned long arg)
270 netif_dormant_on(dev); 270 netif_dormant_on(dev);
271 } 271 }
272 272
273 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++state(hdlc)->txseq, 273 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
274 state(hdlc)->rxseq); 274 htonl(++state(hdlc)->txseq),
275 htonl(state(hdlc)->rxseq));
275 state(hdlc)->request_sent = 1; 276 state(hdlc)->request_sent = 1;
276 state(hdlc)->timer.expires = jiffies + 277 state(hdlc)->timer.expires = jiffies +
277 state(hdlc)->settings.interval * HZ; 278 state(hdlc)->settings.interval * HZ;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index aeb2789adf26..15b6e07a4382 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -288,31 +288,31 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
288 struct sk_buff *skb = *skb_p; 288 struct sk_buff *skb = *skb_p;
289 289
290 switch (skb->protocol) { 290 switch (skb->protocol) {
291 case __constant_ntohs(NLPID_CCITT_ANSI_LMI): 291 case __constant_htons(NLPID_CCITT_ANSI_LMI):
292 head_len = 4; 292 head_len = 4;
293 skb_push(skb, head_len); 293 skb_push(skb, head_len);
294 skb->data[3] = NLPID_CCITT_ANSI_LMI; 294 skb->data[3] = NLPID_CCITT_ANSI_LMI;
295 break; 295 break;
296 296
297 case __constant_ntohs(NLPID_CISCO_LMI): 297 case __constant_htons(NLPID_CISCO_LMI):
298 head_len = 4; 298 head_len = 4;
299 skb_push(skb, head_len); 299 skb_push(skb, head_len);
300 skb->data[3] = NLPID_CISCO_LMI; 300 skb->data[3] = NLPID_CISCO_LMI;
301 break; 301 break;
302 302
303 case __constant_ntohs(ETH_P_IP): 303 case __constant_htons(ETH_P_IP):
304 head_len = 4; 304 head_len = 4;
305 skb_push(skb, head_len); 305 skb_push(skb, head_len);
306 skb->data[3] = NLPID_IP; 306 skb->data[3] = NLPID_IP;
307 break; 307 break;
308 308
309 case __constant_ntohs(ETH_P_IPV6): 309 case __constant_htons(ETH_P_IPV6):
310 head_len = 4; 310 head_len = 4;
311 skb_push(skb, head_len); 311 skb_push(skb, head_len);
312 skb->data[3] = NLPID_IPV6; 312 skb->data[3] = NLPID_IPV6;
313 break; 313 break;
314 314
315 case __constant_ntohs(ETH_P_802_3): 315 case __constant_htons(ETH_P_802_3):
316 head_len = 10; 316 head_len = 10;
317 if (skb_headroom(skb) < head_len) { 317 if (skb_headroom(skb) < head_len) {
318 struct sk_buff *skb2 = skb_realloc_headroom(skb, 318 struct sk_buff *skb2 = skb_realloc_headroom(skb,
@@ -340,7 +340,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
340 skb->data[5] = FR_PAD; 340 skb->data[5] = FR_PAD;
341 skb->data[6] = FR_PAD; 341 skb->data[6] = FR_PAD;
342 skb->data[7] = FR_PAD; 342 skb->data[7] = FR_PAD;
343 *(u16*)(skb->data + 8) = skb->protocol; 343 *(__be16*)(skb->data + 8) = skb->protocol;
344 } 344 }
345 345
346 dlci_to_q922(skb->data, dlci); 346 dlci_to_q922(skb->data, dlci);
@@ -974,8 +974,8 @@ static int fr_rx(struct sk_buff *skb)
974 974
975 } else if (skb->len > 10 && data[3] == FR_PAD && 975 } else if (skb->len > 10 && data[3] == FR_PAD &&
976 data[4] == NLPID_SNAP && data[5] == FR_PAD) { 976 data[4] == NLPID_SNAP && data[5] == FR_PAD) {
977 u16 oui = ntohs(*(u16*)(data + 6)); 977 u16 oui = ntohs(*(__be16*)(data + 6));
978 u16 pid = ntohs(*(u16*)(data + 8)); 978 u16 pid = ntohs(*(__be16*)(data + 8));
979 skb_pull(skb, 10); 979 skb_pull(skb, 10);
980 980
981 switch ((((u32)oui) << 16) | pid) { 981 switch ((((u32)oui) << 16) | pid) {
@@ -1127,7 +1127,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1127 memcpy(dev->dev_addr, "\x00\x01", 2); 1127 memcpy(dev->dev_addr, "\x00\x01", 2);
1128 get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); 1128 get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
1129 } else { 1129 } else {
1130 *(u16*)dev->dev_addr = htons(dlci); 1130 *(__be16*)dev->dev_addr = htons(dlci);
1131 dlci_to_q922(dev->broadcast, dlci); 1131 dlci_to_q922(dev->broadcast, dlci);
1132 } 1132 }
1133 dev->hard_start_xmit = pvc_xmit; 1133 dev->hard_start_xmit = pvc_xmit;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4426841b2be6..c4b3dc291a5a 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -265,6 +265,19 @@ config IPW2200_DEBUG
265 265
266 If you are not sure, say N here. 266 If you are not sure, say N here.
267 267
268config LIBERTAS_USB
269 tristate "Marvell Libertas 8388 802.11a/b/g cards"
270 depends on NET_RADIO && USB
271 select FW_LOADER
272 ---help---
273 A driver for Marvell Libertas 8388 USB devices.
274
275config LIBERTAS_USB_DEBUG
276 bool "Enable full debugging output in the Libertas USB module."
277 depends on LIBERTAS_USB
278 ---help---
279 Debugging support.
280
268config AIRO 281config AIRO
269 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 282 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
270 depends on ISA_DMA_API && WLAN_80211 && (PCI || BROKEN) 283 depends on ISA_DMA_API && WLAN_80211 && (PCI || BROKEN)
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index c613af17a159..d2124602263b 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -43,3 +43,4 @@ obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
43obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o 43obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
44 44
45obj-$(CONFIG_USB_ZD1201) += zd1201.o 45obj-$(CONFIG_USB_ZD1201) += zd1201.o
46obj-$(CONFIG_LIBERTAS_USB) += libertas/
diff --git a/drivers/net/wireless/README b/drivers/net/wireless/README
deleted file mode 100644
index 0c274bf6d45e..000000000000
--- a/drivers/net/wireless/README
+++ /dev/null
@@ -1,25 +0,0 @@
1 README
2 ------
3
4 This directory is mostly for Wireless LAN drivers, in their
5various incarnations (ISA, PCI, Pcmcia...).
6 This separate directory is needed because a lot of driver work
7on different bus (typically PCI + Pcmcia) and share 95% of the
8code. This allow the code and the config options to be in one single
9place instead of scattered all over the driver tree, which is never
10100% satisfactory.
11
12 Note : if you want more info on the topic of Wireless LANs,
13you are kindly invited to have a look at the Wireless Howto :
14 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
15 Some Wireless LAN drivers, like orinoco_cs, require the use of
16Wireless Tools to be configured :
17 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
18
19 Special notes for distribution maintainers :
20 1) wvlan_cs will be discontinued soon in favor of orinoco_cs
21 2) Please add Wireless Tools support in your scripts
22
23 Have fun...
24
25 Jean
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 7fe0a61091a6..f21bbafcb728 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1145,6 +1145,7 @@ static void airo_networks_free(struct airo_info *ai);
1145struct airo_info { 1145struct airo_info {
1146 struct net_device_stats stats; 1146 struct net_device_stats stats;
1147 struct net_device *dev; 1147 struct net_device *dev;
1148 struct list_head dev_list;
1148 /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we 1149 /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we
1149 use the high bit to mark whether it is in use. */ 1150 use the high bit to mark whether it is in use. */
1150#define MAX_FIDS 6 1151#define MAX_FIDS 6
@@ -2360,6 +2361,21 @@ static int airo_change_mtu(struct net_device *dev, int new_mtu)
2360 return 0; 2361 return 0;
2361} 2362}
2362 2363
2364static LIST_HEAD(airo_devices);
2365
2366static void add_airo_dev(struct airo_info *ai)
2367{
2368 /* Upper layers already keep track of PCI devices,
2369 * so we only need to remember our non-PCI cards. */
2370 if (!ai->pci)
2371 list_add_tail(&ai->dev_list, &airo_devices);
2372}
2373
2374static void del_airo_dev(struct airo_info *ai)
2375{
2376 if (!ai->pci)
2377 list_del(&ai->dev_list);
2378}
2363 2379
2364static int airo_close(struct net_device *dev) { 2380static int airo_close(struct net_device *dev) {
2365 struct airo_info *ai = dev->priv; 2381 struct airo_info *ai = dev->priv;
@@ -2381,8 +2397,6 @@ static int airo_close(struct net_device *dev) {
2381 return 0; 2397 return 0;
2382} 2398}
2383 2399
2384static void del_airo_dev( struct net_device *dev );
2385
2386void stop_airo_card( struct net_device *dev, int freeres ) 2400void stop_airo_card( struct net_device *dev, int freeres )
2387{ 2401{
2388 struct airo_info *ai = dev->priv; 2402 struct airo_info *ai = dev->priv;
@@ -2434,14 +2448,12 @@ void stop_airo_card( struct net_device *dev, int freeres )
2434 } 2448 }
2435 } 2449 }
2436 crypto_free_cipher(ai->tfm); 2450 crypto_free_cipher(ai->tfm);
2437 del_airo_dev( dev ); 2451 del_airo_dev(ai);
2438 free_netdev( dev ); 2452 free_netdev( dev );
2439} 2453}
2440 2454
2441EXPORT_SYMBOL(stop_airo_card); 2455EXPORT_SYMBOL(stop_airo_card);
2442 2456
2443static int add_airo_dev( struct net_device *dev );
2444
2445static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) 2457static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2446{ 2458{
2447 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); 2459 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
@@ -2740,8 +2752,6 @@ static int airo_networks_allocate(struct airo_info *ai)
2740 2752
2741static void airo_networks_free(struct airo_info *ai) 2753static void airo_networks_free(struct airo_info *ai)
2742{ 2754{
2743 if (!ai->networks)
2744 return;
2745 kfree(ai->networks); 2755 kfree(ai->networks);
2746 ai->networks = NULL; 2756 ai->networks = NULL;
2747} 2757}
@@ -2816,12 +2826,10 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2816 if (IS_ERR(ai->airo_thread_task)) 2826 if (IS_ERR(ai->airo_thread_task))
2817 goto err_out_free; 2827 goto err_out_free;
2818 ai->tfm = NULL; 2828 ai->tfm = NULL;
2819 rc = add_airo_dev( dev ); 2829 add_airo_dev(ai);
2820 if (rc)
2821 goto err_out_thr;
2822 2830
2823 if (airo_networks_allocate (ai)) 2831 if (airo_networks_allocate (ai))
2824 goto err_out_unlink; 2832 goto err_out_thr;
2825 airo_networks_initialize (ai); 2833 airo_networks_initialize (ai);
2826 2834
2827 /* The Airo-specific entries in the device structure. */ 2835 /* The Airo-specific entries in the device structure. */
@@ -2937,9 +2945,8 @@ err_out_irq:
2937 free_irq(dev->irq, dev); 2945 free_irq(dev->irq, dev);
2938err_out_nets: 2946err_out_nets:
2939 airo_networks_free(ai); 2947 airo_networks_free(ai);
2940err_out_unlink:
2941 del_airo_dev(dev);
2942err_out_thr: 2948err_out_thr:
2949 del_airo_dev(ai);
2943 set_bit(JOB_DIE, &ai->jobs); 2950 set_bit(JOB_DIE, &ai->jobs);
2944 kthread_stop(ai->airo_thread_task); 2951 kthread_stop(ai->airo_thread_task);
2945err_out_free: 2952err_out_free:
@@ -5535,11 +5542,6 @@ static int proc_close( struct inode *inode, struct file *file )
5535 return 0; 5542 return 0;
5536} 5543}
5537 5544
5538static struct net_device_list {
5539 struct net_device *dev;
5540 struct net_device_list *next;
5541} *airo_devices;
5542
5543/* Since the card doesn't automatically switch to the right WEP mode, 5545/* Since the card doesn't automatically switch to the right WEP mode,
5544 we will make it do it. If the card isn't associated, every secs we 5546 we will make it do it. If the card isn't associated, every secs we
5545 will switch WEP modes to see if that will help. If the card is 5547 will switch WEP modes to see if that will help. If the card is
@@ -5582,26 +5584,6 @@ static void timer_func( struct net_device *dev ) {
5582 apriv->expires = RUN_AT(HZ*3); 5584 apriv->expires = RUN_AT(HZ*3);
5583} 5585}
5584 5586
5585static int add_airo_dev( struct net_device *dev ) {
5586 struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
5587 if ( !node )
5588 return -ENOMEM;
5589
5590 node->dev = dev;
5591 node->next = airo_devices;
5592 airo_devices = node;
5593
5594 return 0;
5595}
5596
5597static void del_airo_dev( struct net_device *dev ) {
5598 struct net_device_list **p = &airo_devices;
5599 while( *p && ( (*p)->dev != dev ) )
5600 p = &(*p)->next;
5601 if ( *p && (*p)->dev == dev )
5602 *p = (*p)->next;
5603}
5604
5605#ifdef CONFIG_PCI 5587#ifdef CONFIG_PCI
5606static int __devinit airo_pci_probe(struct pci_dev *pdev, 5588static int __devinit airo_pci_probe(struct pci_dev *pdev,
5607 const struct pci_device_id *pent) 5589 const struct pci_device_id *pent)
@@ -5625,6 +5607,10 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
5625 5607
5626static void __devexit airo_pci_remove(struct pci_dev *pdev) 5608static void __devexit airo_pci_remove(struct pci_dev *pdev)
5627{ 5609{
5610 struct net_device *dev = pci_get_drvdata(pdev);
5611
5612 airo_print_info(dev->name, "Unregistering...");
5613 stop_airo_card(dev, 1);
5628} 5614}
5629 5615
5630static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) 5616static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -5750,9 +5736,11 @@ static int __init airo_init_module( void )
5750 5736
5751static void __exit airo_cleanup_module( void ) 5737static void __exit airo_cleanup_module( void )
5752{ 5738{
5753 while( airo_devices ) { 5739 struct airo_info *ai;
5754 airo_print_info(airo_devices->dev->name, "Unregistering...\n"); 5740 while(!list_empty(&airo_devices)) {
5755 stop_airo_card( airo_devices->dev, 1 ); 5741 ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5742 airo_print_info(ai->dev->name, "Unregistering...");
5743 stop_airo_card(ai->dev, 1);
5756 } 5744 }
5757#ifdef CONFIG_PCI 5745#ifdef CONFIG_PCI
5758 pci_unregister_driver(&airo_driver); 5746 pci_unregister_driver(&airo_driver);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 95ff175d8f33..f8483c179e4c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -277,11 +277,14 @@
277#define BCM43xx_SBTMSTATELOW_REJECT 0x02 277#define BCM43xx_SBTMSTATELOW_REJECT 0x02
278#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000 278#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000
279#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000 279#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
280#define BCM43xx_SBTMSTATELOW_G_MODE_ENABLE 0x20000000
280 281
281/* sbtmstatehigh state flags */ 282/* sbtmstatehigh state flags */
282#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001 283#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001
283#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004 284#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004
284#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020 285#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020
286#define BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL 0x00010000
287#define BCM43xx_SBTMSTATEHIGH_A_PHY_AVAIL 0x00020000
285#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000 288#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000
286#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000 289#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000
287#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000 290#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
index c947025d655f..d2df6a0100a1 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
@@ -32,7 +32,7 @@
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/string.h> 34#include <linux/string.h>
35#include <linux/utsrelease.h> 35#include <linux/utsname.h>
36 36
37 37
38static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 38static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -40,7 +40,7 @@ static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *
40 struct bcm43xx_private *bcm = bcm43xx_priv(dev); 40 struct bcm43xx_private *bcm = bcm43xx_priv(dev);
41 41
42 strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 42 strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
43 strncpy(info->version, UTS_RELEASE, sizeof(info->version)); 43 strncpy(info->version, utsname()->release, sizeof(info->version));
44 strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN); 44 strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
45} 45}
46 46
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index a38e7eec0e62..5e96bca6730a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1407,7 +1407,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1407 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); 1407 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1408 } else { 1408 } else {
1409 if (connect_phy) 1409 if (connect_phy)
1410 flags |= 0x20000000; 1410 flags |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
1411 bcm43xx_phy_connect(bcm, connect_phy); 1411 bcm43xx_phy_connect(bcm, connect_phy);
1412 bcm43xx_core_enable(bcm, flags); 1412 bcm43xx_core_enable(bcm, flags);
1413 bcm43xx_write16(bcm, 0x03E6, 0x0000); 1413 bcm43xx_write16(bcm, 0x03E6, 0x0000);
@@ -3604,7 +3604,7 @@ int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3604 u32 sbtmstatelow; 3604 u32 sbtmstatelow;
3605 3605
3606 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 3606 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3607 sbtmstatelow |= 0x20000000; 3607 sbtmstatelow |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
3608 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); 3608 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3609 } 3609 }
3610 err = wireless_core_up(bcm, 1); 3610 err = wireless_core_up(bcm, 1);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 72529a440f15..b37f1e348700 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -168,16 +168,16 @@ int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect)
168 168
169 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); 169 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
170 if (connect) { 170 if (connect) {
171 if (!(flags & 0x00010000)) 171 if (!(flags & BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL))
172 return -ENODEV; 172 return -ENODEV;
173 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 173 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
174 flags |= (0x800 << 18); 174 flags |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
175 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); 175 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
176 } else { 176 } else {
177 if (!(flags & 0x00020000)) 177 if (!(flags & BCM43xx_SBTMSTATEHIGH_A_PHY_AVAIL))
178 return -ENODEV; 178 return -ENODEV;
179 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 179 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
180 flags &= ~(0x800 << 18); 180 flags &= ~BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
181 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); 181 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
182 } 182 }
183out: 183out:
@@ -300,16 +300,20 @@ static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
300 300
301 if (phy->rev > 2) { 301 if (phy->rev > 2) {
302 bcm43xx_phy_write(bcm, 0x0422, 0x287A); 302 bcm43xx_phy_write(bcm, 0x0422, 0x287A);
303 bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0x0FFF) | 0x3000); 303 bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420)
304 & 0x0FFF) | 0x3000);
304 } 305 }
305 306
306 bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080) | 0x7874); 307 bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080)
308 | 0x7874);
307 bcm43xx_phy_write(bcm, 0x048E, 0x1C00); 309 bcm43xx_phy_write(bcm, 0x048E, 0x1C00);
308 310
309 if (phy->rev == 1) { 311 if (phy->rev == 1) {
310 bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB) & 0xF0FF) | 0x0600); 312 bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB)
313 & 0xF0FF) | 0x0600);
311 bcm43xx_phy_write(bcm, 0x048B, 0x005E); 314 bcm43xx_phy_write(bcm, 0x048B, 0x005E);
312 bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xFF00) | 0x001E); 315 bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C)
316 & 0xFF00) | 0x001E);
313 bcm43xx_phy_write(bcm, 0x048D, 0x0002); 317 bcm43xx_phy_write(bcm, 0x048D, 0x0002);
314 } 318 }
315 319
@@ -335,7 +339,8 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
335 if (phy->rev == 1) { 339 if (phy->rev == 1) {
336 bcm43xx_phy_write(bcm, 0x0406, 0x4F19); 340 bcm43xx_phy_write(bcm, 0x0406, 0x4F19);
337 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, 341 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
338 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0xFC3F) | 0x0340); 342 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
343 & 0xFC3F) | 0x0340);
339 bcm43xx_phy_write(bcm, 0x042C, 0x005A); 344 bcm43xx_phy_write(bcm, 0x042C, 0x005A);
340 bcm43xx_phy_write(bcm, 0x0427, 0x001A); 345 bcm43xx_phy_write(bcm, 0x0427, 0x001A);
341 346
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
index 1f321ef42be8..73118364b552 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
@@ -48,6 +48,10 @@ void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm);
48 local_irq_restore(flags); \ 48 local_irq_restore(flags); \
49 } while (0) 49 } while (0)
50 50
51/* Card uses the loopback gain stuff */
52#define has_loopback_gain(phy) \
53 (((phy)->rev > 1) || ((phy)->connected))
54
51u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset); 55u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset);
52void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val); 56void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
53 57
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index 4025dd0089d2..6a109f4a1b71 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -1343,11 +1343,110 @@ u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm)
1343 return ret; 1343 return ret;
1344} 1344}
1345 1345
1346#define LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
1347static u16 bcm43xx_get_812_value(struct bcm43xx_private *bcm, u8 lpd)
1348{
1349 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1350 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1351 u16 loop_or = 0;
1352 u16 adj_loopback_gain = phy->loopback_gain[0];
1353 u8 loop;
1354 u16 extern_lna_control;
1355
1356 if (!phy->connected)
1357 return 0;
1358 if (!has_loopback_gain(phy)) {
1359 if (phy->rev < 7 || !(bcm->sprom.boardflags
1360 & BCM43xx_BFL_EXTLNA)) {
1361 switch (lpd) {
1362 case LPD(0, 1, 1):
1363 return 0x0FB2;
1364 case LPD(0, 0, 1):
1365 return 0x00B2;
1366 case LPD(1, 0, 1):
1367 return 0x30B2;
1368 case LPD(1, 0, 0):
1369 return 0x30B3;
1370 default:
1371 assert(0);
1372 }
1373 } else {
1374 switch (lpd) {
1375 case LPD(0, 1, 1):
1376 return 0x8FB2;
1377 case LPD(0, 0, 1):
1378 return 0x80B2;
1379 case LPD(1, 0, 1):
1380 return 0x20B2;
1381 case LPD(1, 0, 0):
1382 return 0x20B3;
1383 default:
1384 assert(0);
1385 }
1386 }
1387 } else {
1388 if (radio->revision == 8)
1389 adj_loopback_gain += 0x003E;
1390 else
1391 adj_loopback_gain += 0x0026;
1392 if (adj_loopback_gain >= 0x46) {
1393 adj_loopback_gain -= 0x46;
1394 extern_lna_control = 0x3000;
1395 } else if (adj_loopback_gain >= 0x3A) {
1396 adj_loopback_gain -= 0x3A;
1397 extern_lna_control = 0x2000;
1398 } else if (adj_loopback_gain >= 0x2E) {
1399 adj_loopback_gain -= 0x2E;
1400 extern_lna_control = 0x1000;
1401 } else {
1402 adj_loopback_gain -= 0x10;
1403 extern_lna_control = 0x0000;
1404 }
1405 for (loop = 0; loop < 16; loop++) {
1406 u16 tmp = adj_loopback_gain - 6 * loop;
1407 if (tmp < 6)
1408 break;
1409 }
1410
1411 loop_or = (loop << 8) | extern_lna_control;
1412 if (phy->rev >= 7 && bcm->sprom.boardflags
1413 & BCM43xx_BFL_EXTLNA) {
1414 if (extern_lna_control)
1415 loop_or |= 0x8000;
1416 switch (lpd) {
1417 case LPD(0, 1, 1):
1418 return 0x8F92;
1419 case LPD(0, 0, 1):
1420 return (0x8092 | loop_or);
1421 case LPD(1, 0, 1):
1422 return (0x2092 | loop_or);
1423 case LPD(1, 0, 0):
1424 return (0x2093 | loop_or);
1425 default:
1426 assert(0);
1427 }
1428 } else {
1429 switch (lpd) {
1430 case LPD(0, 1, 1):
1431 return 0x0F92;
1432 case LPD(0, 0, 1):
1433 case LPD(1, 0, 1):
1434 return (0x0092 | loop_or);
1435 case LPD(1, 0, 0):
1436 return (0x0093 | loop_or);
1437 default:
1438 assert(0);
1439 }
1440 }
1441 }
1442 return 0;
1443}
1444
1346u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm) 1445u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1347{ 1446{
1348 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 1447 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1349 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 1448 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1350 u16 backup[19] = { 0 }; 1449 u16 backup[21] = { 0 };
1351 u16 ret; 1450 u16 ret;
1352 u16 i, j; 1451 u16 i, j;
1353 u32 tmp1 = 0, tmp2 = 0; 1452 u32 tmp1 = 0, tmp2 = 0;
@@ -1373,19 +1472,36 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1373 backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS); 1472 backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS);
1374 backup[9] = bcm43xx_phy_read(bcm, 0x0802); 1473 backup[9] = bcm43xx_phy_read(bcm, 0x0802);
1375 bcm43xx_phy_write(bcm, 0x0814, 1474 bcm43xx_phy_write(bcm, 0x0814,
1376 (bcm43xx_phy_read(bcm, 0x0814) | 0x0003)); 1475 (bcm43xx_phy_read(bcm, 0x0814)
1476 | 0x0003));
1377 bcm43xx_phy_write(bcm, 0x0815, 1477 bcm43xx_phy_write(bcm, 0x0815,
1378 (bcm43xx_phy_read(bcm, 0x0815) & 0xFFFC)); 1478 (bcm43xx_phy_read(bcm, 0x0815)
1479 & 0xFFFC));
1379 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, 1480 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
1380 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF)); 1481 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
1482 & 0x7FFF));
1381 bcm43xx_phy_write(bcm, 0x0802, 1483 bcm43xx_phy_write(bcm, 0x0802,
1382 (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC)); 1484 (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC));
1383 bcm43xx_phy_write(bcm, 0x0811, 0x01B3); 1485 if (phy->rev > 1) { /* loopback gain enabled */
1384 bcm43xx_phy_write(bcm, 0x0812, 0x0FB2); 1486 backup[19] = bcm43xx_phy_read(bcm, 0x080F);
1487 backup[20] = bcm43xx_phy_read(bcm, 0x0810);
1488 if (phy->rev >= 3)
1489 bcm43xx_phy_write(bcm, 0x080F, 0xC020);
1490 else
1491 bcm43xx_phy_write(bcm, 0x080F, 0x8020);
1492 bcm43xx_phy_write(bcm, 0x0810, 0x0000);
1493 }
1494 bcm43xx_phy_write(bcm, 0x0812,
1495 bcm43xx_get_812_value(bcm, LPD(0, 1, 1)));
1496 if (phy->rev < 7 || !(bcm->sprom.boardflags
1497 & BCM43xx_BFL_EXTLNA))
1498 bcm43xx_phy_write(bcm, 0x0811, 0x01B3);
1499 else
1500 bcm43xx_phy_write(bcm, 0x0811, 0x09B3);
1385 } 1501 }
1386 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1387 (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000));
1388 } 1502 }
1503 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1504 (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000));
1389 backup[10] = bcm43xx_phy_read(bcm, 0x0035); 1505 backup[10] = bcm43xx_phy_read(bcm, 0x0035);
1390 bcm43xx_phy_write(bcm, 0x0035, 1506 bcm43xx_phy_write(bcm, 0x0035,
1391 (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F)); 1507 (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F));
@@ -1397,10 +1513,12 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1397 bcm43xx_write16(bcm, 0x03E6, 0x0122); 1513 bcm43xx_write16(bcm, 0x03E6, 0x0122);
1398 } else { 1514 } else {
1399 if (phy->analog >= 2) 1515 if (phy->analog >= 2)
1400 bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003) 1516 bcm43xx_phy_write(bcm, 0x0003,
1401 & 0xFFBF) | 0x0040); 1517 (bcm43xx_phy_read(bcm, 0x0003)
1518 & 0xFFBF) | 0x0040);
1402 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 1519 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
1403 (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000)); 1520 (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
1521 | 0x2000));
1404 } 1522 }
1405 1523
1406 ret = bcm43xx_radio_calibrationvalue(bcm); 1524 ret = bcm43xx_radio_calibrationvalue(bcm);
@@ -1408,16 +1526,25 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1408 if (phy->type == BCM43xx_PHYTYPE_B) 1526 if (phy->type == BCM43xx_PHYTYPE_B)
1409 bcm43xx_radio_write16(bcm, 0x0078, 0x0026); 1527 bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
1410 1528
1529 if (phy->connected)
1530 bcm43xx_phy_write(bcm, 0x0812,
1531 bcm43xx_get_812_value(bcm, LPD(0, 1, 1)));
1411 bcm43xx_phy_write(bcm, 0x0015, 0xBFAF); 1532 bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
1412 bcm43xx_phy_write(bcm, 0x002B, 0x1403); 1533 bcm43xx_phy_write(bcm, 0x002B, 0x1403);
1413 if (phy->connected) 1534 if (phy->connected)
1414 bcm43xx_phy_write(bcm, 0x0812, 0x00B2); 1535 bcm43xx_phy_write(bcm, 0x0812,
1536 bcm43xx_get_812_value(bcm, LPD(0, 0, 1)));
1415 bcm43xx_phy_write(bcm, 0x0015, 0xBFA0); 1537 bcm43xx_phy_write(bcm, 0x0015, 0xBFA0);
1416 bcm43xx_radio_write16(bcm, 0x0051, 1538 bcm43xx_radio_write16(bcm, 0x0051,
1417 (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004)); 1539 (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
1418 bcm43xx_radio_write16(bcm, 0x0052, 0x0000); 1540 if (radio->revision == 8)
1419 bcm43xx_radio_write16(bcm, 0x0043, 1541 bcm43xx_radio_write16(bcm, 0x0043, 0x001F);
1420 (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009); 1542 else {
1543 bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
1544 bcm43xx_radio_write16(bcm, 0x0043,
1545 (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0)
1546 | 0x0009);
1547 }
1421 bcm43xx_phy_write(bcm, 0x0058, 0x0000); 1548 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1422 1549
1423 for (i = 0; i < 16; i++) { 1550 for (i = 0; i < 16; i++) {
@@ -1425,21 +1552,25 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1425 bcm43xx_phy_write(bcm, 0x0059, 0xC810); 1552 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1426 bcm43xx_phy_write(bcm, 0x0058, 0x000D); 1553 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1427 if (phy->connected) 1554 if (phy->connected)
1428 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1555 bcm43xx_phy_write(bcm, 0x0812,
1556 bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
1429 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); 1557 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1430 udelay(10); 1558 udelay(10);
1431 if (phy->connected) 1559 if (phy->connected)
1432 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1560 bcm43xx_phy_write(bcm, 0x0812,
1561 bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
1433 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); 1562 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
1434 udelay(10); 1563 udelay(10);
1435 if (phy->connected) 1564 if (phy->connected)
1436 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1565 bcm43xx_phy_write(bcm, 0x0812,
1566 bcm43xx_get_812_value(bcm, LPD(1, 0, 0)));
1437 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); 1567 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
1438 udelay(10); 1568 udelay(20);
1439 tmp1 += bcm43xx_phy_read(bcm, 0x002D); 1569 tmp1 += bcm43xx_phy_read(bcm, 0x002D);
1440 bcm43xx_phy_write(bcm, 0x0058, 0x0000); 1570 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1441 if (phy->connected) 1571 if (phy->connected)
1442 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1572 bcm43xx_phy_write(bcm, 0x0812,
1573 bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
1443 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); 1574 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1444 } 1575 }
1445 1576
@@ -1457,21 +1588,29 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1457 bcm43xx_phy_write(bcm, 0x0059, 0xC810); 1588 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1458 bcm43xx_phy_write(bcm, 0x0058, 0x000D); 1589 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1459 if (phy->connected) 1590 if (phy->connected)
1460 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1591 bcm43xx_phy_write(bcm, 0x0812,
1592 bcm43xx_get_812_value(bcm,
1593 LPD(1, 0, 1)));
1461 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); 1594 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1462 udelay(10); 1595 udelay(10);
1463 if (phy->connected) 1596 if (phy->connected)
1464 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1597 bcm43xx_phy_write(bcm, 0x0812,
1598 bcm43xx_get_812_value(bcm,
1599 LPD(1, 0, 1)));
1465 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); 1600 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
1466 udelay(10); 1601 udelay(10);
1467 if (phy->connected) 1602 if (phy->connected)
1468 bcm43xx_phy_write(bcm, 0x0812, 0x30B3); /* 0x30B3 is not a typo */ 1603 bcm43xx_phy_write(bcm, 0x0812,
1604 bcm43xx_get_812_value(bcm,
1605 LPD(1, 0, 0)));
1469 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); 1606 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
1470 udelay(10); 1607 udelay(10);
1471 tmp2 += bcm43xx_phy_read(bcm, 0x002D); 1608 tmp2 += bcm43xx_phy_read(bcm, 0x002D);
1472 bcm43xx_phy_write(bcm, 0x0058, 0x0000); 1609 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1473 if (phy->connected) 1610 if (phy->connected)
1474 bcm43xx_phy_write(bcm, 0x0812, 0x30B2); 1611 bcm43xx_phy_write(bcm, 0x0812,
1612 bcm43xx_get_812_value(bcm,
1613 LPD(1, 0, 1)));
1475 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); 1614 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1476 } 1615 }
1477 tmp2++; 1616 tmp2++;
@@ -1497,15 +1636,20 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1497 bcm43xx_phy_write(bcm, 0x0030, backup[2]); 1636 bcm43xx_phy_write(bcm, 0x0030, backup[2]);
1498 bcm43xx_write16(bcm, 0x03EC, backup[3]); 1637 bcm43xx_write16(bcm, 0x03EC, backup[3]);
1499 } else { 1638 } else {
1500 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1501 (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) & 0x7FFF));
1502 if (phy->connected) { 1639 if (phy->connected) {
1640 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1641 (bcm43xx_read16(bcm,
1642 BCM43xx_MMIO_PHY_RADIO) & 0x7FFF));
1503 bcm43xx_phy_write(bcm, 0x0811, backup[4]); 1643 bcm43xx_phy_write(bcm, 0x0811, backup[4]);
1504 bcm43xx_phy_write(bcm, 0x0812, backup[5]); 1644 bcm43xx_phy_write(bcm, 0x0812, backup[5]);
1505 bcm43xx_phy_write(bcm, 0x0814, backup[6]); 1645 bcm43xx_phy_write(bcm, 0x0814, backup[6]);
1506 bcm43xx_phy_write(bcm, 0x0815, backup[7]); 1646 bcm43xx_phy_write(bcm, 0x0815, backup[7]);
1507 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]); 1647 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]);
1508 bcm43xx_phy_write(bcm, 0x0802, backup[9]); 1648 bcm43xx_phy_write(bcm, 0x0802, backup[9]);
1649 if (phy->rev > 1) {
1650 bcm43xx_phy_write(bcm, 0x080F, backup[19]);
1651 bcm43xx_phy_write(bcm, 0x0810, backup[20]);
1652 }
1509 } 1653 }
1510 } 1654 }
1511 if (i >= 15) 1655 if (i >= 15)
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 4ca8a27b8c55..5b3abd54d0e5 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Intersil Prism2 driver with Host AP (software access point) support 2 * Intersil Prism2 driver with Host AP (software access point) support
3 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 3 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
4 * <jkmaline@cc.hut.fi> 4 * <j@w1.fi>
5 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> 5 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
6 * 6 *
7 * This file is to be included into hostap.c when S/W AP functionality is 7 * This file is to be included into hostap.c when S/W AP functionality is
8 * compiled. 8 * compiled.
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index 01624005d808..b31e6a05f23c 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -368,9 +368,9 @@ enum {
368 368
369#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024 369#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
370#define PRISM2_HOSTAPD_RID_HDR_LEN \ 370#define PRISM2_HOSTAPD_RID_HDR_LEN \
371((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data)) 371offsetof(struct prism2_hostapd_param, u.rid.data)
372#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ 372#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
373((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data)) 373offsetof(struct prism2_hostapd_param, u.generic_elem.data)
374 374
375/* Maximum length for algorithm names (-1 for nul termination) used in ioctl() 375/* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
376 */ 376 */
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 8d8f4b9b8b07..ee1532b62e42 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -22,7 +22,7 @@
22#include "hostap_wlan.h" 22#include "hostap_wlan.h"
23 23
24 24
25static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 25static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
26static dev_info_t dev_info = "hostap_cs"; 26static dev_info_t dev_info = "hostap_cs";
27 27
28MODULE_AUTHOR("Jouni Malinen"); 28MODULE_AUTHOR("Jouni Malinen");
@@ -838,6 +838,8 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
838 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), 838 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
839 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), 839 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
840 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x0002), 840 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x0002),
841 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0xd601, 0x0005, "ADLINK 345 CF",
842 0x2d858104),
841 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL", 843 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL",
842 0x74c5e40d), 844 0x74c5e40d),
843 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil", 845 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",
@@ -848,6 +850,11 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
848 "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P", 850 "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P",
849 "Eval-RevA", 851 "Eval-RevA",
850 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e), 852 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e),
853 /* D-Link DWL-650 Rev. P1; manfid 0x000b, 0x7110 */
854 PCMCIA_DEVICE_PROD_ID1234(
855 "D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10",
856 "A3",
857 0x1a424a1c, 0x6ea57632, 0xdd97a26b, 0x56b21f52),
851 PCMCIA_DEVICE_PROD_ID123( 858 PCMCIA_DEVICE_PROD_ID123(
852 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", 859 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
853 0xe6ec52ce, 0x08649af2, 0x4b74baa0), 860 0xe6ec52ce, 0x08649af2, 0x4b74baa0),
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index fb01fb95a9f0..959887b70ca7 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3,8 +3,8 @@
3 * Intersil Prism2/2.5/3. 3 * Intersil Prism2/2.5/3.
4 * 4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi> 6 * <j@w1.fi>
7 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 1f9edd91565d..4743426cf6ad 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -3,8 +3,8 @@
3 * Intersil Prism2/2.5/3 - hostap.o module, common routines 3 * Intersil Prism2/2.5/3 - hostap.o module, common routines
4 * 4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi> 6 * <j@w1.fi>
7 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index c4f6020baa9e..db4899ed4bb1 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -20,7 +20,7 @@
20#include "hostap_wlan.h" 20#include "hostap_wlan.h"
21 21
22 22
23static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 23static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
24static char *dev_info = "hostap_pci"; 24static char *dev_info = "hostap_pci";
25 25
26 26
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index e235e0647897..f0fd5ecdb24d 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -23,7 +23,7 @@
23#include "hostap_wlan.h" 23#include "hostap_wlan.h"
24 24
25 25
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 26static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
27static char *dev_info = "hostap_plx"; 27static char *dev_info = "hostap_plx";
28 28
29 29
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 9137a4dd02eb..d51daf87450f 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -28,8 +28,8 @@
28 28
29 Portions of this file are based on the Host AP project, 29 Portions of this file are based on the Host AP project,
30 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 30 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
31 <jkmaline@cc.hut.fi> 31 <j@w1.fi>
32 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 32 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
33 33
34 Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and 34 Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and
35 ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c 35 ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 4839a45098cb..7cb2052a55a5 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1847,6 +1847,52 @@ static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1847static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, 1847static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1848 show_net_stats, store_net_stats); 1848 show_net_stats, store_net_stats);
1849 1849
1850static ssize_t show_channels(struct device *d,
1851 struct device_attribute *attr,
1852 char *buf)
1853{
1854 struct ipw_priv *priv = dev_get_drvdata(d);
1855 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
1856 int len = 0, i;
1857
1858 len = sprintf(&buf[len],
1859 "Displaying %d channels in 2.4Ghz band "
1860 "(802.11bg):\n", geo->bg_channels);
1861
1862 for (i = 0; i < geo->bg_channels; i++) {
1863 len += sprintf(&buf[len], "%d: BSS%s%s, %s, Band %s.\n",
1864 geo->bg[i].channel,
1865 geo->bg[i].flags & IEEE80211_CH_RADAR_DETECT ?
1866 " (radar spectrum)" : "",
1867 ((geo->bg[i].flags & IEEE80211_CH_NO_IBSS) ||
1868 (geo->bg[i].flags & IEEE80211_CH_RADAR_DETECT))
1869 ? "" : ", IBSS",
1870 geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY ?
1871 "passive only" : "active/passive",
1872 geo->bg[i].flags & IEEE80211_CH_B_ONLY ?
1873 "B" : "B/G");
1874 }
1875
1876 len += sprintf(&buf[len],
1877 "Displaying %d channels in 5.2Ghz band "
1878 "(802.11a):\n", geo->a_channels);
1879 for (i = 0; i < geo->a_channels; i++) {
1880 len += sprintf(&buf[len], "%d: BSS%s%s, %s.\n",
1881 geo->a[i].channel,
1882 geo->a[i].flags & IEEE80211_CH_RADAR_DETECT ?
1883 " (radar spectrum)" : "",
1884 ((geo->a[i].flags & IEEE80211_CH_NO_IBSS) ||
1885 (geo->a[i].flags & IEEE80211_CH_RADAR_DETECT))
1886 ? "" : ", IBSS",
1887 geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY ?
1888 "passive only" : "active/passive");
1889 }
1890
1891 return len;
1892}
1893
1894static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
1895
1850static void notify_wx_assoc_event(struct ipw_priv *priv) 1896static void notify_wx_assoc_event(struct ipw_priv *priv)
1851{ 1897{
1852 union iwreq_data wrqu; 1898 union iwreq_data wrqu;
@@ -11383,6 +11429,7 @@ static struct attribute *ipw_sysfs_entries[] = {
11383 &dev_attr_led.attr, 11429 &dev_attr_led.attr,
11384 &dev_attr_speed_scan.attr, 11430 &dev_attr_speed_scan.attr,
11385 &dev_attr_net_stats.attr, 11431 &dev_attr_net_stats.attr,
11432 &dev_attr_channels.attr,
11386#ifdef CONFIG_IPW2200_PROMISCUOUS 11433#ifdef CONFIG_IPW2200_PROMISCUOUS
11387 &dev_attr_rtap_iface.attr, 11434 &dev_attr_rtap_iface.attr,
11388 &dev_attr_rtap_filter.attr, 11435 &dev_attr_rtap_filter.attr,
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
new file mode 100644
index 000000000000..e0ecc4d483bb
--- /dev/null
+++ b/drivers/net/wireless/libertas/11d.c
@@ -0,0 +1,754 @@
1/**
2 * This file contains functions for 802.11D.
3 */
4#include <linux/ctype.h>
5#include <linux/kernel.h>
6#include <linux/wireless.h>
7
8#include "host.h"
9#include "decl.h"
10#include "11d.h"
11#include "dev.h"
12#include "wext.h"
13
14#define TX_PWR_DEFAULT 10
15
16static struct region_code_mapping region_code_mapping[] = {
17 {"US ", 0x10}, /* US FCC */
18 {"CA ", 0x10}, /* IC Canada */
19 {"SG ", 0x10}, /* Singapore */
20 {"EU ", 0x30}, /* ETSI */
21 {"AU ", 0x30}, /* Australia */
22 {"KR ", 0x30}, /* Republic Of Korea */
23 {"ES ", 0x31}, /* Spain */
24 {"FR ", 0x32}, /* France */
25 {"JP ", 0x40}, /* Japan */
26};
27
28/* Following 2 structure defines the supported channels */
29static struct chan_freq_power channel_freq_power_UN_BG[] = {
30 {1, 2412, TX_PWR_DEFAULT},
31 {2, 2417, TX_PWR_DEFAULT},
32 {3, 2422, TX_PWR_DEFAULT},
33 {4, 2427, TX_PWR_DEFAULT},
34 {5, 2432, TX_PWR_DEFAULT},
35 {6, 2437, TX_PWR_DEFAULT},
36 {7, 2442, TX_PWR_DEFAULT},
37 {8, 2447, TX_PWR_DEFAULT},
38 {9, 2452, TX_PWR_DEFAULT},
39 {10, 2457, TX_PWR_DEFAULT},
40 {11, 2462, TX_PWR_DEFAULT},
41 {12, 2467, TX_PWR_DEFAULT},
42 {13, 2472, TX_PWR_DEFAULT},
43 {14, 2484, TX_PWR_DEFAULT}
44};
45
46static u8 wlan_region_2_code(u8 * region)
47{
48 u8 i;
49 u8 size = sizeof(region_code_mapping)/
50 sizeof(struct region_code_mapping);
51
52 for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++)
53 region[i] = toupper(region[i]);
54
55 for (i = 0; i < size; i++) {
56 if (!memcmp(region, region_code_mapping[i].region,
57 COUNTRY_CODE_LEN))
58 return (region_code_mapping[i].code);
59 }
60
61 /* default is US */
62 return (region_code_mapping[0].code);
63}
64
65static u8 *wlan_code_2_region(u8 code)
66{
67 u8 i;
68 u8 size = sizeof(region_code_mapping)
69 / sizeof(struct region_code_mapping);
70 for (i = 0; i < size; i++) {
71 if (region_code_mapping[i].code == code)
72 return (region_code_mapping[i].region);
73 }
74 /* default is US */
75 return (region_code_mapping[0].region);
76}
77
78/**
79 * @brief This function finds the nrchan-th chan after the firstchan
80 * @param band band
81 * @param firstchan first channel number
82 * @param nrchan number of channels
83 * @return the nrchan-th chan number
84*/
85static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
86/*find the nrchan-th chan after the firstchan*/
87{
88 u8 i;
89 struct chan_freq_power *cfp;
90 u8 cfp_no;
91
92 cfp = channel_freq_power_UN_BG;
93 cfp_no = sizeof(channel_freq_power_UN_BG) /
94 sizeof(struct chan_freq_power);
95
96 for (i = 0; i < cfp_no; i++) {
97 if ((cfp + i)->channel == firstchan) {
98 lbs_pr_debug(1, "firstchan found\n");
99 break;
100 }
101 }
102
103 if (i < cfp_no) {
104 /*if beyond the boundary */
105 if (i + nrchan < cfp_no) {
106 *chan = (cfp + i + nrchan)->channel;
107 return 1;
108 }
109 }
110
111 return 0;
112}
113
114/**
115 * @brief This function Checks if chan txpwr is learned from AP/IBSS
116 * @param chan chan number
117 * @param parsed_region_chan pointer to parsed_region_chan_11d
118 * @return TRUE; FALSE
119*/
120static u8 wlan_channel_known_11d(u8 chan,
121 struct parsed_region_chan_11d * parsed_region_chan)
122{
123 struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr;
124 u8 nr_chan = parsed_region_chan->nr_chan;
125 u8 i = 0;
126
127 lbs_dbg_hex("11D:parsed_region_chan:", (char *)chanpwr,
128 sizeof(struct chan_power_11d) * nr_chan);
129
130 for (i = 0; i < nr_chan; i++) {
131 if (chan == chanpwr[i].chan) {
132 lbs_pr_debug(1, "11D: Found Chan:%d\n", chan);
133 return 1;
134 }
135 }
136
137 lbs_pr_debug(1, "11D: Not Find Chan:%d\n", chan);
138 return 0;
139}
140
141u32 libertas_chan_2_freq(u8 chan, u8 band)
142{
143 struct chan_freq_power *cf;
144 u16 cnt;
145 u16 i;
146 u32 freq = 0;
147
148 cf = channel_freq_power_UN_BG;
149 cnt =
150 sizeof(channel_freq_power_UN_BG) /
151 sizeof(struct chan_freq_power);
152
153 for (i = 0; i < cnt; i++) {
154 if (chan == cf[i].channel)
155 freq = cf[i].freq;
156 }
157
158 return freq;
159}
160
161static int generate_domain_info_11d(struct parsed_region_chan_11d
162 *parsed_region_chan,
163 struct wlan_802_11d_domain_reg * domaininfo)
164{
165 u8 nr_subband = 0;
166
167 u8 nr_chan = parsed_region_chan->nr_chan;
168 u8 nr_parsedchan = 0;
169
170 u8 firstchan = 0, nextchan = 0, maxpwr = 0;
171
172 u8 i, flag = 0;
173
174 memcpy(domaininfo->countrycode, parsed_region_chan->countrycode,
175 COUNTRY_CODE_LEN);
176
177 lbs_pr_debug(1, "11D:nrchan=%d\n", nr_chan);
178 lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan,
179 sizeof(struct parsed_region_chan_11d));
180
181 for (i = 0; i < nr_chan; i++) {
182 if (!flag) {
183 flag = 1;
184 nextchan = firstchan =
185 parsed_region_chan->chanpwr[i].chan;
186 maxpwr = parsed_region_chan->chanpwr[i].pwr;
187 nr_parsedchan = 1;
188 continue;
189 }
190
191 if (parsed_region_chan->chanpwr[i].chan == nextchan + 1 &&
192 parsed_region_chan->chanpwr[i].pwr == maxpwr) {
193 nextchan++;
194 nr_parsedchan++;
195 } else {
196 domaininfo->subband[nr_subband].firstchan = firstchan;
197 domaininfo->subband[nr_subband].nrchan =
198 nr_parsedchan;
199 domaininfo->subband[nr_subband].maxtxpwr = maxpwr;
200 nr_subband++;
201 nextchan = firstchan =
202 parsed_region_chan->chanpwr[i].chan;
203 maxpwr = parsed_region_chan->chanpwr[i].pwr;
204 }
205 }
206
207 if (flag) {
208 domaininfo->subband[nr_subband].firstchan = firstchan;
209 domaininfo->subband[nr_subband].nrchan = nr_parsedchan;
210 domaininfo->subband[nr_subband].maxtxpwr = maxpwr;
211 nr_subband++;
212 }
213 domaininfo->nr_subband = nr_subband;
214
215 lbs_pr_debug(1, "nr_subband=%x\n", domaininfo->nr_subband);
216 lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo,
217 COUNTRY_CODE_LEN + 1 +
218 sizeof(struct ieeetypes_subbandset) * nr_subband);
219 return 0;
220}
221
222/**
223 * @brief This function generates parsed_region_chan from Domain Info learned from AP/IBSS
224 * @param region_chan pointer to struct region_channel
225 * @param *parsed_region_chan pointer to parsed_region_chan_11d
226 * @return N/A
227*/
228static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_chan,
229 struct parsed_region_chan_11d *
230 parsed_region_chan)
231{
232 u8 i;
233 struct chan_freq_power *cfp;
234
235 if (region_chan == NULL) {
236 lbs_pr_debug(1, "11D: region_chan is NULL\n");
237 return;
238 }
239
240 cfp = region_chan->CFP;
241 if (cfp == NULL) {
242 lbs_pr_debug(1, "11D: cfp equal NULL \n");
243 return;
244 }
245
246 parsed_region_chan->band = region_chan->band;
247 parsed_region_chan->region = region_chan->region;
248 memcpy(parsed_region_chan->countrycode,
249 wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
250
251 lbs_pr_debug(1, "11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
252 parsed_region_chan->band);
253
254 for (i = 0; i < region_chan->nrcfp; i++, cfp++) {
255 parsed_region_chan->chanpwr[i].chan = cfp->channel;
256 parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower;
257 lbs_pr_debug(1, "11D: Chan[%d] Pwr[%d]\n",
258 parsed_region_chan->chanpwr[i].chan,
259 parsed_region_chan->chanpwr[i].pwr);
260 }
261 parsed_region_chan->nr_chan = region_chan->nrcfp;
262
263 lbs_pr_debug(1, "11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
264
265 return;
266}
267
268/**
269 * @brief generate parsed_region_chan from Domain Info learned from AP/IBSS
270 * @param region region ID
271 * @param band band
272 * @param chan chan
273 * @return TRUE;FALSE
274*/
275static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
276{
277 struct chan_freq_power *cfp;
278 int cfp_no;
279 u8 idx;
280
281 ENTER();
282
283 cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
284 if (cfp == NULL)
285 return 0;
286
287 for (idx = 0; idx < cfp_no; idx++) {
288 if (chan == (cfp + idx)->channel) {
289 /* If Mrvl Chip Supported? */
290 if ((cfp + idx)->unsupported) {
291 return 0;
292 } else {
293 return 1;
294 }
295 }
296 }
297
298 /*chan is not in the region table */
299 LEAVE();
300 return 0;
301}
302
303/**
304 * @brief This function checks if chan txpwr is learned from AP/IBSS
305 * @param chan chan number
306 * @param parsed_region_chan pointer to parsed_region_chan_11d
307 * @return 0
308*/
309static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
310 countryinfo,
311 u8 band,
312 struct parsed_region_chan_11d *
313 parsed_region_chan)
314{
315 u8 nr_subband, nrchan;
316 u8 lastchan, firstchan;
317 u8 region;
318 u8 curchan = 0;
319
320 u8 idx = 0; /*chan index in parsed_region_chan */
321
322 u8 j, i;
323
324 ENTER();
325
326 /*validation Rules:
327 1. valid region Code
328 2. First Chan increment
329 3. channel range no overlap
330 4. channel is valid?
331 5. channel is supported by region?
332 6. Others
333 */
334
335 lbs_dbg_hex("CountryInfo:", (u8 *) countryinfo, 30);
336
337 if ((*(countryinfo->countrycode)) == 0
338 || (countryinfo->len <= COUNTRY_CODE_LEN)) {
339 /* No region Info or Wrong region info: treat as No 11D info */
340 LEAVE();
341 return 0;
342 }
343
344 /*Step1: check region_code */
345 parsed_region_chan->region = region =
346 wlan_region_2_code(countryinfo->countrycode);
347
348 lbs_pr_debug(1, "regioncode=%x\n", (u8) parsed_region_chan->region);
349 lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode,
350 COUNTRY_CODE_LEN);
351
352 parsed_region_chan->band = band;
353
354 memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
355 COUNTRY_CODE_LEN);
356
357 nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) /
358 sizeof(struct ieeetypes_subbandset);
359
360 for (j = 0, lastchan = 0; j < nr_subband; j++) {
361
362 if (countryinfo->subband[j].firstchan <= lastchan) {
363 /*Step2&3. Check First Chan Num increment and no overlap */
364 lbs_pr_debug(1, "11D: Chan[%d>%d] Overlap\n",
365 countryinfo->subband[j].firstchan, lastchan);
366 continue;
367 }
368
369 firstchan = countryinfo->subband[j].firstchan;
370 nrchan = countryinfo->subband[j].nrchan;
371
372 for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) {
373 /*step4: channel is supported? */
374
375 if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) {
376 /* Chan is not found in UN table */
377 lbs_pr_debug(1, "chan is not supported: %d \n", i);
378 break;
379 }
380
381 lastchan = curchan;
382
383 if (wlan_region_chan_supported_11d
384 (region, band, curchan)) {
385 /*step5: Check if curchan is supported by mrvl in region */
386 parsed_region_chan->chanpwr[idx].chan = curchan;
387 parsed_region_chan->chanpwr[idx].pwr =
388 countryinfo->subband[j].maxtxpwr;
389 idx++;
390 } else {
391 /*not supported and ignore the chan */
392 lbs_pr_debug(1,
393 "11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n",
394 i, curchan, region, band);
395 }
396 }
397
398 /*Step6: Add other checking if any */
399
400 }
401
402 parsed_region_chan->nr_chan = idx;
403
404 lbs_pr_debug(1, "nrchan=%x\n", parsed_region_chan->nr_chan);
405 lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan,
406 2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx);
407
408 LEAVE();
409 return 0;
410}
411
412/**
413 * @brief This function calculates the scan type for channels
414 * @param chan chan number
415 * @param parsed_region_chan pointer to parsed_region_chan_11d
416 * @return PASSIVE if chan is unknown; ACTIVE if chan is known
417*/
418u8 libertas_get_scan_type_11d(u8 chan,
419 struct parsed_region_chan_11d * parsed_region_chan)
420{
421 u8 scan_type = cmd_scan_type_passive;
422
423 ENTER();
424
425 if (wlan_channel_known_11d(chan, parsed_region_chan)) {
426 lbs_pr_debug(1, "11D: Found and do Active Scan\n");
427 scan_type = cmd_scan_type_active;
428 } else {
429 lbs_pr_debug(1, "11D: Not Find and do Passive Scan\n");
430 }
431
432 LEAVE();
433 return scan_type;
434
435}
436
437void libertas_init_11d(wlan_private * priv)
438{
439 priv->adapter->enable11d = 0;
440 memset(&(priv->adapter->parsed_region_chan), 0,
441 sizeof(struct parsed_region_chan_11d));
442 return;
443}
444
445static int wlan_enable_11d(wlan_private * priv, u8 flag)
446{
447 int ret;
448
449 priv->adapter->enable11d = flag;
450
451 /* send cmd to FW to enable/disable 11D function in FW */
452 ret = libertas_prepare_and_send_command(priv,
453 cmd_802_11_snmp_mib,
454 cmd_act_set,
455 cmd_option_waitforrsp,
456 OID_802_11D_ENABLE,
457 &priv->adapter->enable11d);
458 if (ret)
459 lbs_pr_debug(1, "11D: Fail to enable 11D \n");
460
461 return 0;
462}
463
464/**
465 * @brief This function sets DOMAIN INFO to FW
466 * @param priv pointer to wlan_private
467 * @return 0; -1
468*/
469static int set_domain_info_11d(wlan_private * priv)
470{
471 int ret;
472
473 if (!priv->adapter->enable11d) {
474 lbs_pr_debug(1, "11D: dnld domain Info with 11d disabled\n");
475 return 0;
476 }
477
478 ret = libertas_prepare_and_send_command(priv, cmd_802_11d_domain_info,
479 cmd_act_set,
480 cmd_option_waitforrsp, 0, NULL);
481 if (ret)
482 lbs_pr_debug(1, "11D: Fail to dnld domain Info\n");
483
484 return ret;
485}
486
487/**
488 * @brief This function setups scan channels
489 * @param priv pointer to wlan_private
490 * @param band band
491 * @return 0
492*/
493int libertas_set_universaltable(wlan_private * priv, u8 band)
494{
495 wlan_adapter *adapter = priv->adapter;
496 u16 size = sizeof(struct chan_freq_power);
497 u16 i = 0;
498
499 memset(adapter->universal_channel, 0,
500 sizeof(adapter->universal_channel));
501
502 adapter->universal_channel[i].nrcfp =
503 sizeof(channel_freq_power_UN_BG) / size;
504 lbs_pr_debug(1, "11D: BG-band nrcfp=%d\n",
505 adapter->universal_channel[i].nrcfp);
506
507 adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
508 adapter->universal_channel[i].valid = 1;
509 adapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
510 adapter->universal_channel[i].band = band;
511 i++;
512
513 return 0;
514}
515
516/**
517 * @brief This function implements command CMD_802_11D_DOMAIN_INFO
518 * @param priv pointer to wlan_private
519 * @param cmd pointer to cmd buffer
520 * @param cmdno cmd ID
521 * @param cmdOption cmd action
522 * @return 0
523*/
524int libertas_cmd_802_11d_domain_info(wlan_private * priv,
525 struct cmd_ds_command *cmd, u16 cmdno,
526 u16 cmdoption)
527{
528 struct cmd_ds_802_11d_domain_info *pdomaininfo =
529 &cmd->params.domaininfo;
530 struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
531 wlan_adapter *adapter = priv->adapter;
532 u8 nr_subband = adapter->domainreg.nr_subband;
533
534 ENTER();
535
536 lbs_pr_debug(1, "nr_subband=%x\n", nr_subband);
537
538 cmd->command = cpu_to_le16(cmdno);
539 pdomaininfo->action = cpu_to_le16(cmdoption);
540 if (cmdoption == cmd_act_get) {
541 cmd->size =
542 cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
543 lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd,
544 (int)(cmd->size));
545 LEAVE();
546 return 0;
547 }
548
549 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
550 memcpy(domain->countrycode, adapter->domainreg.countrycode,
551 sizeof(domain->countrycode));
552
553 domain->header.len =
554 cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) +
555 sizeof(domain->countrycode));
556
557 if (nr_subband) {
558 memcpy(domain->subband, adapter->domainreg.subband,
559 nr_subband * sizeof(struct ieeetypes_subbandset));
560
561 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
562 domain->header.len +
563 sizeof(struct mrvlietypesheader) +
564 S_DS_GEN);
565 } else {
566 cmd->size =
567 cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
568 }
569
570 lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, (int)(cmd->size));
571
572 LEAVE();
573
574 return 0;
575}
576
577/**
578 * @brief This function implements private cmd: enable/disable 11D
579 * @param priv pointer to wlan_private
580 * @param wrq pointer to user data
581 * @return 0 or -1
582 */
583int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
584{
585 int data = 0;
586 int *val;
587
588 ENTER();
589 data = SUBCMD_DATA(wrq);
590
591 lbs_pr_debug(1, "enable 11D: %s\n",
592 (data == 1) ? "enable" : "Disable");
593
594 wlan_enable_11d(priv, data);
595 val = (int *)wrq->u.name;
596 *val = priv->adapter->enable11d;
597
598 LEAVE();
599 return 0;
600}
601
602/**
603 * @brief This function parses countryinfo from AP and download country info to FW
604 * @param priv pointer to wlan_private
605 * @param resp pointer to command response buffer
606 * @return 0; -1
607 */
608int libertas_ret_802_11d_domain_info(wlan_private * priv,
609 struct cmd_ds_command *resp)
610{
611 struct cmd_ds_802_11d_domain_info
612 *domaininfo = &resp->params.domaininforesp;
613 struct mrvlietypes_domainparamset *domain = &domaininfo->domain;
614 u16 action = le16_to_cpu(domaininfo->action);
615 s16 ret = 0;
616 u8 nr_subband = 0;
617
618 ENTER();
619
620 lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp,
621 (int)le16_to_cpu(resp->size));
622
623 nr_subband = (domain->header.len - 3) / sizeof(struct ieeetypes_subbandset);
624 /* countrycode 3 bytes */
625
626 lbs_pr_debug(1, "11D Domain Info Resp: nr_subband=%d\n", nr_subband);
627
628 if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) {
629 lbs_pr_debug(1, "Invalid Numrer of Subband returned!!\n");
630 return -1;
631 }
632
633 switch (action) {
634 case cmd_act_set: /*Proc Set action */
635 break;
636
637 case cmd_act_get:
638 break;
639 default:
640 lbs_pr_debug(1, "Invalid action:%d\n", domaininfo->action);
641 ret = -1;
642 break;
643 }
644
645 LEAVE();
646 return ret;
647}
648
649/**
650 * @brief This function parses countryinfo from AP and download country info to FW
651 * @param priv pointer to wlan_private
652 * @return 0; -1
653 */
654int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
655{
656 int ret;
657 wlan_adapter *adapter = priv->adapter;
658
659 ENTER();
660 if (priv->adapter->enable11d) {
661 memset(&adapter->parsed_region_chan, 0,
662 sizeof(struct parsed_region_chan_11d));
663 ret = parse_domain_info_11d(&adapter->pattemptedbssdesc->
664 countryinfo, 0,
665 &adapter->parsed_region_chan);
666
667 if (ret == -1) {
668 lbs_pr_debug(1, "11D: Err Parse domain_info from AP..\n");
669 LEAVE();
670 return ret;
671 }
672
673 memset(&adapter->domainreg, 0,
674 sizeof(struct wlan_802_11d_domain_reg));
675 generate_domain_info_11d(&adapter->parsed_region_chan,
676 &adapter->domainreg);
677
678 ret = set_domain_info_11d(priv);
679
680 if (ret) {
681 lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
682 LEAVE();
683 return ret;
684 }
685 }
686 LEAVE();
687 return 0;
688}
689
690/**
691 * @brief This function generates 11D info from user specified regioncode and download to FW
692 * @param priv pointer to wlan_private
693 * @return 0; -1
694 */
695int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
696{
697 int ret;
698 wlan_adapter *adapter = priv->adapter;
699 struct region_channel *region_chan;
700 u8 j;
701
702 ENTER();
703 lbs_pr_debug(1, "11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
704
705 if (priv->adapter->enable11d) {
706 /* update parsed_region_chan_11; dnld domaininf to FW */
707
708 for (j = 0; j < sizeof(adapter->region_channel) /
709 sizeof(adapter->region_channel[0]); j++) {
710 region_chan = &adapter->region_channel[j];
711
712 lbs_pr_debug(1, "11D:[%d] region_chan->band[%d]\n", j,
713 region_chan->band);
714
715 if (!region_chan || !region_chan->valid
716 || !region_chan->CFP)
717 continue;
718 if (region_chan->band != adapter->curbssparams.band)
719 continue;
720 break;
721 }
722
723 if (j >= sizeof(adapter->region_channel) /
724 sizeof(adapter->region_channel[0])) {
725 lbs_pr_debug(1, "11D:region_chan not found. band[%d]\n",
726 adapter->curbssparams.band);
727 LEAVE();
728 return -1;
729 }
730
731 memset(&adapter->parsed_region_chan, 0,
732 sizeof(struct parsed_region_chan_11d));
733 wlan_generate_parsed_region_chan_11d(region_chan,
734 &adapter->
735 parsed_region_chan);
736
737 memset(&adapter->domainreg, 0,
738 sizeof(struct wlan_802_11d_domain_reg));
739 generate_domain_info_11d(&adapter->parsed_region_chan,
740 &adapter->domainreg);
741
742 ret = set_domain_info_11d(priv);
743
744 if (ret) {
745 lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
746 LEAVE();
747 return ret;
748 }
749
750 }
751
752 LEAVE();
753 return 0;
754}
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
new file mode 100644
index 000000000000..db2ebea9f231
--- /dev/null
+++ b/drivers/net/wireless/libertas/11d.h
@@ -0,0 +1,105 @@
1/**
2 * This header file contains data structures and
3 * function declarations of 802.11d
4 */
5#ifndef _WLAN_11D_
6#define _WLAN_11D_
7
8#include "types.h"
9#include "defs.h"
10
11#define UNIVERSAL_REGION_CODE 0xff
12
13/** (Beaconsize(256)-5(IEId,len,contrystr(3))/3(FirstChan,NoOfChan,MaxPwr)
14 */
15#define MRVDRV_MAX_SUBBAND_802_11D 83
16
17#define COUNTRY_CODE_LEN 3
18#define MAX_NO_OF_CHAN 40
19
20struct cmd_ds_command;
21
22/** Data structure for Country IE*/
23struct ieeetypes_subbandset {
24 u8 firstchan;
25 u8 nrchan;
26 u8 maxtxpwr;
27} __attribute__ ((packed));
28
29struct ieeetypes_countryinfoset {
30 u8 element_id;
31 u8 len;
32 u8 countrycode[COUNTRY_CODE_LEN];
33 struct ieeetypes_subbandset subband[1];
34};
35
36struct ieeetypes_countryinfofullset {
37 u8 element_id;
38 u8 len;
39 u8 countrycode[COUNTRY_CODE_LEN];
40 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
41} __attribute__ ((packed));
42
43struct mrvlietypes_domainparamset {
44 struct mrvlietypesheader header;
45 u8 countrycode[COUNTRY_CODE_LEN];
46 struct ieeetypes_subbandset subband[1];
47} __attribute__ ((packed));
48
49struct cmd_ds_802_11d_domain_info {
50 u16 action;
51 struct mrvlietypes_domainparamset domain;
52} __attribute__ ((packed));
53
54/** domain regulatory information */
55struct wlan_802_11d_domain_reg {
56 /** country Code*/
57 u8 countrycode[COUNTRY_CODE_LEN];
58 /** No. of subband*/
59 u8 nr_subband;
60 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
61};
62
63struct chan_power_11d {
64 u8 chan;
65 u8 pwr;
66} __attribute__ ((packed));
67
68struct parsed_region_chan_11d {
69 u8 band;
70 u8 region;
71 s8 countrycode[COUNTRY_CODE_LEN];
72 struct chan_power_11d chanpwr[MAX_NO_OF_CHAN];
73 u8 nr_chan;
74} __attribute__ ((packed));
75
76struct region_code_mapping {
77 u8 region[COUNTRY_CODE_LEN];
78 u8 code;
79};
80
81u8 libertas_get_scan_type_11d(u8 chan,
82 struct parsed_region_chan_11d *parsed_region_chan);
83
84u32 libertas_chan_2_freq(u8 chan, u8 band);
85
86enum state_11d libertas_get_state_11d(wlan_private * priv);
87
88void libertas_init_11d(wlan_private * priv);
89
90int libertas_set_universaltable(wlan_private * priv, u8 band);
91
92int libertas_cmd_802_11d_domain_info(wlan_private * priv,
93 struct cmd_ds_command *cmd, u16 cmdno,
94 u16 cmdOption);
95
96int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
97
98int libertas_ret_802_11d_domain_info(wlan_private * priv,
99 struct cmd_ds_command *resp);
100
101int libertas_parse_dnld_countryinfo_11d(wlan_private * priv);
102
103int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
104
105#endif /* _WLAN_11D_ */
diff --git a/drivers/net/wireless/libertas/LICENSE b/drivers/net/wireless/libertas/LICENSE
new file mode 100644
index 000000000000..8862742213b9
--- /dev/null
+++ b/drivers/net/wireless/libertas/LICENSE
@@ -0,0 +1,16 @@
1 Copyright (c) 2003-2006, Marvell International Ltd.
2 All Rights Reserved
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of version 2 of the GNU General Public License as
6 published by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc., 59
15 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
new file mode 100644
index 000000000000..19c935071d8e
--- /dev/null
+++ b/drivers/net/wireless/libertas/Makefile
@@ -0,0 +1,21 @@
1# EXTRA_CFLAGS += -Wpacked
2
3usb8xxx-objs := main.o fw.o wext.o \
4 rx.o tx.o cmd.o \
5 cmdresp.o scan.o \
6 join.o 11d.o \
7 ioctl.o debugfs.o \
8 ethtool.o assoc.o
9
10ifeq ($(CONFIG_LIBERTAS_USB_DEBUG), y)
11EXTRA_CFLAGS += -DDEBUG -DPROC_DEBUG
12endif
13
14
15# This is needed to support the newer boot2 bootloader (v >= 3104)
16EXTRA_CFLAGS += -DSUPPORT_BOOT_COMMAND
17usb8xxx-objs += if_bootcmd.o
18usb8xxx-objs += if_usb.o
19
20obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
21
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
new file mode 100644
index 000000000000..688da4c784b1
--- /dev/null
+++ b/drivers/net/wireless/libertas/README
@@ -0,0 +1,1044 @@
1================================================================================
2 README for USB8388
3
4 (c) Copyright © 2003-2006, Marvell International Ltd.
5 All Rights Reserved
6
7 This software file (the "File") is distributed by Marvell International
8 Ltd. under the terms of the GNU General Public License Version 2, June 1991
9 (the "License"). You may use, redistribute and/or modify this File in
10 accordance with the terms and conditions of the License, a copy of which
11 is available along with the File in the license.txt file or by writing to
12 the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
14
15 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17 ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18 this warranty disclaimer.
19================================================================================
20
21=====================
22DRIVER LOADING
23=====================
24
25 o. Copy the firmware image (e.g. usb8388.bin) to /lib/firmware/
26
27 o. Load driver by using the following command:
28
29 insmod usb8388.ko [fw_name=usb8388.bin]
30
31=====================
32IWPRIV COMMAND
33=====================
34
35NAME
36 This manual describes the usage of private commands used in Marvell WLAN
37 Linux Driver. All the commands available in Wlanconfig will not be available
38 in the iwpriv.
39
40SYNOPSIS
41 iwpriv <ethX> <command> [sub-command] ...
42
43 iwpriv ethX version
44 iwpriv ethX scantype [sub-command]
45 iwpriv ethX getSNR <n>
46 iwpriv ethX getNF <n>
47 iwpriv ethX getRSSI <n>
48 iwpriv ethX setrxant <n>
49 iwpriv ethX getrxant
50 iwpriv ethX settxant <n>
51 iwpriv ethX gettxant
52 iwpriv ethX authalgs <n>
53 iwpriv ethX pre-TBTT <n>
54 iwpriv ethX 8021xauthalgs <n>
55 iwpriv ethX encryptionmode <n>
56 iwpriv ethX setregioncode <n>
57 iwpriv ethX getregioncode
58 iwpriv ethX setbcnavg <n>
59 iwpriv ethX getbcnavg
60 iwpriv ethX setdataavg <n>
61 iwpriv ethX setlisteninter <n>
62 iwpriv ethX getlisteninter
63 iwpriv ethX setmultipledtim <n>
64 iwpriv ethX getmultipledtim
65 iwpriv ethX atimwindow <n>
66 iwpriv ethX deauth
67 iwpriv ethX adhocstop
68 iwpriv ethX radioon
69 iwpriv ethX radiooff
70 iwpriv ethX reasso-on
71 iwpriv ethX reasso-off
72 iwpriv ethX scanmode [sub-command]
73 iwpriv ethX setwpaie <n>
74 iwpriv ethX wlanidle-off
75 iwpriv ethX wlanidle-on
76 iwpriv ethX getcis
77 iwpriv ethX getlog
78 iwpriv ethX getadhocstatus
79 iwpriv ethX adhocgrate <n>
80
81Version 4 Command:
82 iwpriv ethX inactvityto <n>
83 iwpriv ethX sleeppd <n>
84 iwpriv ethX enable11d <n>
85 iwpriv ethX tpccfg <n>
86 iwpriv ethX powercfg <n>
87 iwpriv ethX setafc <n>
88 iwpriv ethX getafc
89
90Version 5 Command:
91 iwpriv ethX ledgpio <n>
92 iwpriv ethX scanprobes <n>
93 iwpriv ethX lolisteninter <n>
94 iwpriv ethX rateadapt <n> <m>
95 iwpriv ethX txcontrol <n>
96 iwpriv ethX psnullinterval <n>
97 iwpriv ethX prescan <n>
98 iwpriv ethX getrxinfo
99 iwpriv ethX gettxrate
100 iwpriv ethX beaconinterval
101
102BT Commands:
103 The blinding table (BT) contains a list of mac addresses that should be
104 ignored by the firmware. It is primarily used for debugging and
105 testing networks. It can be edited and inspected with the following
106 commands:
107
108 iwpriv ethX bt_reset
109 iwpriv ethX bt_add <mac_address>
110 iwpriv ethX bt_del <mac_address>
111 iwpriv ethX bt_list <id>
112
113FWT Commands:
114 The forwarding table (FWT) is a feature used to manage mesh network
115 routing in the firmware. The FWT is essentially a routing table that
116 associates a destination mac address (da) with a next hop receiver
117 address (ra). The FWT can be inspected and edited with the following
118 iwpriv commands, which are described in greater detail below.
119 Eventually, the table will be automatically maintained by a custom
120 routing protocol.
121
122 NOTE: FWT commands replace the previous DFT commands. What were the DFT
123 commands?, you might ask. They were an earlier API to the firmware that
124 implemented a simple MAC-layer forwarding mechanism. In the unlikely
125 event that you were using these commands, you must migrate to the new
126 FWT commands which can be used to achieve the same functionality.
127
128 iwpriv ethX fwt_add [parameters]
129 iwpriv ethX fwt_del [parameters]
130 iwpriv ethX fwt_lookup [parameters]
131 iwpriv ethX fwt_list [parameters]
132 iwpriv ethX fwt_list_route [parameters]
133 iwpriv ethX fwt_list_neigh [parameters]
134 iwpriv ethX fwt_reset [parameters]
135 iwpriv ethX fwt_cleanup
136 iwpriv ethX fwt_time
137
138MESH Commands:
139
140 The MESH commands are used to configure various features of the mesh
141 routing protocol. The following commands are supported:
142
143 iwpriv ethX mesh_get_ttl
144 iwpriv ethX mesh_set_ttl ttl
145
146DESCRIPTION
147 Those commands are used to send additional commands to the Marvell WLAN
148 card via the Linux device driver.
149
150 The ethX parameter specifies the network device that is to be used to
151 perform this command on. it could be eth0, eth1 etc.
152
153version
154 This is used to get the current version of the driver and the firmware.
155
156scantype
157 This command is used to set the scan type to be used by the driver in
158 the scan command. This setting will not be used while performing a scan
159 for a specific SSID, as it is always done with scan type being active.
160
161 where the sub-commands are: -
162 active -- to set the scan type to active
163 passive -- to set the scan type to passive
164 get -- to get the scan type set in the driver
165
166getSNR
167 This command gets the average and non average value of Signal to Noise
168 Ratio of Beacon and Data.
169
170 where value is:-
171 0 -- Beacon non-average.
172 1 -- Beacon average.
173 2 -- Data non-average.
174 3 -- Data average.
175
176 If no value is given, all four values are returned in the order mentioned
177 above.
178
179 Note: This command is available only when STA is connected.
180
181getRSSI
182 This command gets the average and non average value os Receive Signal
183 Strength of Beacon and Data.
184
185 where value is:-
186 0 -- Beacon non-average.
187 1 -- Beacon average.
188 2 -- Data non-average.
189 3 -- Data average.
190
191 Note: This command is available only when STA is connected.
192
193getNF
194 This command gets the average and non average value of Noise Floor of
195 Beacon and Data.
196
197 where value is:-
198 0 -- Beacon non-average.
199 1 -- Beacon average.
200 2 -- Data non-average.
201 3 -- Data average.
202
203 Note: This command is available only when STA is connected.
204
205setrxant
206 This command is used to set the mode for Rx antenna.
207
208 The options that can be sent are:-
209 1 -- Antenna 1.
210 2 -- Antenna 2.
211 0xFFFF -- Diversity.
212
213 Usage:
214 iwpriv ethX setrxant 0x01: select Antenna 1.
215
216getrxant
217 This command is used to get the mode for Rx antenna.
218
219
220settxant
221 This command is used to set the mode for Tx antenna.
222 The options that can be sent are:-
223 1 -- Antenna 1.
224 2 -- Antenna 2.
225 0xFFFF -- Diversity.
226 Usage:
227 iwpriv ethX settxant 0x01: select Antenna 1.
228
229gettxant
230 This command is used to get the mode for Tx antenna.
231
232authalgs
233 This command is used by the WPA supplicant to set the authentication
234 algorithms in the station.
235
2368021xauthalgs
237 This command is used by the WPA supplicant to set the 8021.x authentication algorithm type
238 station.
239
240 where values can be:-
241 1 -- None
242 2 -- LEAP
243 4 -- TLS
244 8 -- TTLs
245 16 -- MD5
246
247
248encryptionmode
249 This command is used by the WPA supplicant to set the encryption algorithm.
250
251 where values can be:-
252 0 -- NONE
253 1 -- WEP40
254 2 -- TKIP
255 3 -- CCMP
256 4 -- WEP104
257
258pre-TBTT
259 This command is used to set pre-TBTT time period where value is in microseconds.
260
261setregioncode
262 This command is used to set the region code in the station.
263 where value is 'region code' for various regions like
264 USA FCC, Canada IC, Spain, France, Europe ETSI, Japan ...
265
266 Usage:
267 iwpriv ethX setregioncode 0x10: set region code to USA (0x10).
268
269getregioncode
270 This command is used to get the region code information set in the
271 station.
272
273setbcnavg
274 Set the weighting factor for calculating RSSI.
275
276getbcnavg
277 Get weighting factor for calculating RSSI.
278
279setdataavg
280 Set the weighting factor for calculating SNR.
281
282setlisteninter
283 This command is used to set the listen interval in the
284 station.
285
286 where the value ranges between 1 - 255
287
288getlisteninter
289 This command is used to get the listen interval value set in the
290 station.
291
292setmultipledtim
293 This command is used to set the multiple dtim value in the
294 station.
295 where the value is 1,2,3,4,5,0xfffe
296 0xfffe means the firmware will use listen interval in association
297 command for waking up
298
299getmultipledtim
300 This command is used to get the multiple dtim value set in the station.
301
302atimwindow
303 This command is used to set the atim value in the
304 station.
305
306 where the value ranges between 0 - 50
307
308deauth
309 This command is used to send the de-authentication to the AP with which
310 the station is associated. This command is valid only when
311 station is in Infrastructure mode.
312
313 Note: This command is available only when STA is connected.
314
315adhocstop
316 This command is used to stop beacon transmission from the station and
317 go into idle state in ad-hoc mode.
318
319 Note: This command is available only when STA is connected.
320
321radioon
322 This command is used to turn on the RF antenna.
323
324radiooff
325 This command is sued to turn off the RF antenna.
326
327scanmode
328 This command is used to set the station to scan for either IBSS
329 networks or BSS networks or both BSS and IBSS networks. This
330 command can be used with sub commands,
331
332 where the value for
333 bss -- Scan All the BSS networks.
334 ibss -- Scan All the IBSS networks.
335 any -- Scan both BSS and IBSS networks.
336
337
338
339setwpaie
340 This command is used by WPA supplicant to send the WPA-IE to the driver.
341
342wlanidle-off
343 This command is used to get into idle state.
344
345 Note: This command is available only when STA is connected.
346
347wlanidle-on
348 This command is used to get off the idle state.
349
350 Note: This command is available only when STA is connected.
351
352
353getlog
354 This command is used to get the 802.11 statistics available in the
355 station.
356
357 Note: This command is available only when STA is connected.
358
359getadhocstatus
360 This command is used to get the ad-hoc Network Status.
361
362 The various status codes are:
363 AdhocStarted
364 AdhocJoined
365 AdhocIdle
366 InfraMode
367 AutoUnknownMode
368
369 Note: This command is available only when STA is connected.
370
371adhocgrate
372 This command is used to enable(1) g_rate, Disable(0) g_rate
373 and request(2) the status which g_rate is disabled/enabled,
374 for Ad-hoc creator.
375
376 where value is:-
377 0 -- Disabled
378 1 -- Enabled
379 2 -- Get
380
381ledgpio
382 This command is used to set/get LEDs.
383
384 iwpriv ethX ledgpio <LEDs>
385 will set the corresponding LED for the GPIO Line.
386
387 iwpriv ethX ledgpio
388 will give u which LEDs are Enabled.
389
390 Usage:
391 iwpriv eth1 ledgpio 1 0 2 1 3 4
392 will enable
393 LED 1 -> GPIO 0
394 LED 2 -> GPIO 1
395 LED 3 -> GPIO 4
396
397 iwpriv eth1 ledgpio
398 shows LED information in the format as mentioned above.
399
400 Note: LED0 is invalid
401 Note: Maximum Number of LEDs are 16.
402
403inactivityto
404 This command is used by the host to set/get the inactivity timeout value,
405 which specifies when WLAN device is put to sleep.
406
407 Usage:
408 iwpriv ethX inactivityto [<timeout>]
409
410 where the parameter are:
411 timeout: timeout value in milliseconds.
412
413 Example:
414 iwpriv eth1 inactivityto
415 "get the timeout value"
416
417 iwpriv eth1 inactivityto X
418 "set timeout value to X ms"
419
420
421sleeppd
422 This command is used to configure the sleep period of the WLAN device.
423
424 Usage:
425 iwpriv ethX sleeppd [<sleep period>]
426
427 where the parameter are:
428 Period: sleep period in milliseconds. Range 10~60.
429
430 Example:
431 iwpriv eth1 sleeppd 10
432 "set period as 10 ms"
433 iwpriv eth1 sleeppd
434 "get the sleep period configuration"
435
436enable11d
437 This command is used to control 11d
438 where value is:-
439 1 -- Enabled
440 0 -- Disabled
441 2 -- Get
442
443
444
445
446tpccfg
447 Enables or disables automatic transmit power control.
448
449 The first parameter turns this feature on (1) or off (0). When turning
450 on, the user must also supply four more parameters in the following
451 order:
452 -UseSNR (Use SNR (in addition to PER) for TPC algorithm),
453 -P0 (P0 power level for TPC),
454 -P1 (P1 power level for TPC),
455 -P2 (P2 power level for TPC).
456
457 Usage:
458 iwpriv ethX tpccfg: Get current configuration
459 iwpriv ethX tpccfg 0: disable auto TPC
460 iwpriv ethX tpccfg 0x01 0x00 0x05 0x0a 0x0d: enable auto TPC; do not use SNR;
461 P0=0x05; P1=0x0a; P2=0x0d;
462 iwpriv ethX tpccfg 0x01 0x01 0x05 0x0a 0x0d: enable auto TPC; use SNR;
463 P0=0x05; P1=0x0a; P2=0x0d.
464
465powercfg
466 Enables or disables power adaptation.
467
468 The first parameter turns this feature on (1) or off (0). When turning
469 on, the user must also supply three more parameters in the following
470 order:
471 -P0 (P0 power level for Power Adaptation),
472 -P1 (P1 power level for Power Adaptation),
473 -P2 (P2 power level for Power Adaptation).
474
475 Usage:
476 iwpriv ethX powercfg: Get current configuration
477 iwpriv ethX powercfg 0: disable power adaptation
478 iwpriv ethX powercfg 1 0x0d 0x0f 0x12: enable power adaptation;
479 P0=0x0d; P1=0x0f; P2=0x12.
480
481getafc
482 This command returns automatic frequency control parameters. It returns
483 three integers:
484 -P0: automatic is on (1), or off (0),
485 -P1: current timing offset in PPM (part per million), and
486 -P2: current frequency offset in PPM.
487
488setafc
489 Set automatic frequency control options.
490
491 The first parameter turns automatic on (1) or off (0).
492 The user must supply two more parameters in either case, in the following
493 order:
494
495 When auto is on:
496
497 -P0 (automatic adjustment frequency threshold in PPM),
498 -P1 (automatic adjustment period in beacon period),
499
500 When auto is off:
501
502 -P0 (manual adjustment timing offset in PPM), and
503 -P1 (manual adjustment frequency offset in PPM).
504
505 Usage:
506 iwpriv ethX setafc 0 10 10: manual adjustment, both timing and frequcncy
507 offset are 10 PPM.
508
509 iwpriv ethX setafc 1 10 10 enable afc, automatic adjustment,
510 frequency threshold 10 PPM, for every 10 beacon periods.
511
512
513
514scanprobes
515 This command sets number of probe requests per channel.
516
517 Usage:
518 iwpriv ethX scanprobes 3 (set scan probes to 3)
519 iwpriv ethX scanprobes (get scan probes)
520
521lolisteninter
522 This command sets the value of listen interval.
523
524 Usage:
525 iwpriv ethX lolisteninter 234 (set the lolisteninter to 234)
526 iwpriv ethX lolisteninter (get the lolisteninter value)
527
528rateadapt
529 This command sets the data rates bitmap.
530 Where <n>
531 0: Disable auto rate adapt
532 1: Enable auto rate adapt
533
534 <m>
535 data rate bitmap
536 Bit Data rate
537 0 1 Mbps
538 1 2 Mbps
539 2 5.5 Mbps
540 3 11 Mbps
541 4 Reserved
542 5 6 Mbps
543 6 9 Mbps
544 7 12 Mbps
545 8 18 Mbps
546 9 24 Mbps
547 10 36 Mbps
548 11 48 Mbps
549 12 54 Mbps
550 12-15 Reserved
551
552 Usage:
553 iwpriv ethX rateadapt
554 read the currect data rate setting
555 iwpriv ethX rateadapt 1 0x07
556 enable auto data rate adapt and
557 data rates are 1Mbps, 2Mbsp and 5.5Mbps
558
559
560txcontrol
561 This command is used to set the Tx rate, ack policy, and retry limit on a per packet basis.
562
563 Where value <n> is:
564 if bit[4] == 1:
565 bit[3:0] -- 0 1 2 3 4 5 6 7 8 9 10 11 12 13-16
566 Data Rate(Mbps) -- 1 2 5.5 11 Rsv 6 9 12 18 24 36 48 54 Rsv
567
568 bit[12:8]
569 if bit[12] == 1, bit[11:8] specifies the Tx retry limit.
570
571 bit[14:13] specifies per packet ack policy:
572 bit[14:13]
573 1 0 use immediate ack policy for this packet
574 1 1 use no ack policy for this packet
575 0 x use the per-packet ack policy setting
576
577 Usage:
578 iwpriv ethX txcontrol 0x7513
579 Use no-ack policy, 5 retires for Tx, 11Mbps rate
580
581
582
583psnullinterval
584 This command is used to set/request NULL package interval for Power Save
585 under infrastructure mode.
586
587 where value is:-
588 -1 -- Disabled
589 n>0 -- Set interval as n (seconds)
590
591prescan
592 This command is used to enable (1)/disable(0) auto prescan before assoicate to the ap
593
594 where value is:-
595 0 -- Disabled
596 1 -- Enabled
597 2 -- Get
598
599getrxinfo
600 This command gets non average value of Signal to Noise Ratio of Data and rate index.
601
602 The following table shows RateIndex and Rate
603
604 RateIndex Data rate
605 0 1 Mbps
606 1 2 Mbps
607 2 5.5 Mbps
608 3 11 Mbps
609 4 Reserved
610 5 6 Mbps
611 6 9 Mbps
612 7 12 Mbps
613 8 18 Mbps
614 9 24 Mbps
615 10 36 Mbps
616 11 48 Mbps
617 12 54 Mbps
618 13-15 Reserved
619
620gettxrate
621 This command gets current Tx rate index of the first packet associated with Rate Adaptation.
622
623 The following table shows RateIndex and Rate
624
625 RateIndex Data rate
626 0 1 Mbps
627 1 2 Mbps
628 2 5.5 Mbps
629 3 11 Mbps
630 4 Reserved
631 5 6 Mbps
632 6 9 Mbps
633 7 12 Mbps
634 8 18 Mbps
635 9 24 Mbps
636 10 36 Mbps
637 11 48 Mbps
638 12 54 Mbps
639 13-15 Reserved
640
641bcninterval
642 This command is used to sets beacon interval in adhoc mode when an argument is given, and gets current adhoc
643 beacon interval when no argument is given. The valid beacon interval is between 20 - 1000,
644 default beacon interval is 100.
645
646 Usage:
647 iwpriv ethX bcninterval 100 (set adhoc beacon interval to 100)
648 iwpriv ethX bcninterval (get adhoc beacon interval)
649
650fwt_add
651 This command is used to insert an entry into the FWT table. The list of
652 parameters must follow the following structure:
653
654 iwpriv ethX fwt_add da ra [metric dir ssn dsn hopcount ttl expiration sleepmode snr]
655
656 The parameters between brackets are optional, but they must appear in
657 the order specified. For example, if you want to specify the metric,
658 you must also specify the dir, ssn, and dsn but you need not specify the
659 hopcount, expiration, sleepmode, or snr. Any unspecified parameters
660 will be assigned the defaults specified below.
661
662 The different parameters are:-
663 da -- DA MAC address in the form 00:11:22:33:44:55
664 ra -- RA MAC address in the form 00:11:22:33:44:55
665 metric -- route metric (cost: smaller-metric routes are
666 preferred, default is 0)
667 dir -- direction (1 for direct, 0 for reverse,
668 default is 1)
669 ssn -- Source Sequence Number (time at the RA for
670 reverse routes. Default is 0)
671 dsn -- Destination Sequence Number (time at the DA
672 for direct routes. Default is 0)
673 hopcount -- hop count (currently unused, default is 0)
674 ttl -- TTL (Only used in reverse entries)
675 expiration -- entry expiration (in ticks, where a tick is
676 1024us, or ~ 1ms. Use 0 for an indefinite
677 entry, default is 0)
678 sleepmode -- RA's sleep mode (currently unused, default is
679 0)
680 snr -- SNR in the link to RA (currently unused,
681 default is 0)
682
683 The command does not return anything.
684
685fwt_del
686 This command is used to remove an entry to the FWT table. The list of
687 parameters must follow the following structure:
688
689 iwpriv ethX fwt_del da ra [dir]
690
691 where the different parameters are:-
692 da -- DA MAC address (in the form "00:11:22:33:44:55")
693 ra -- RA MAC address (in the form "00:11:22:33:44:55")
694 dir -- direction (1 for direct, 0 for reverse,
695 default is 1)
696
697 The command does not return anything.
698
699fwt_lookup
700 This command is used to get the best route in the FWT table to a given
701 host. The only parameter is the MAC address of the host that is being
702 looked for.
703
704 iwpriv ethX fwt_lookup da
705
706 where:-
707 da -- DA MAC address (in the form "00:11:22:33:44:55")
708
709 The command returns an output string identical to the one returned by
710 fwt_list described below.
711
712
713fwt_list
714 This command is used to list a route from the FWT table. The only
715 parameter is the index into the table. If you want to list all the
716 routes in a table, start with index=0, and keep listing until you get a
717 "(null)" string. Note that the indicies may change as the fwt is
718 updated. It is expected that most users will not use fwt_list directly,
719 but that a utility similar to the traditional route command will be used
720 to invoke fwt_list over and over.
721
722 iwpriv ethX fwt_list index
723
724 The output is a string of the following form:
725
726 da ra metric dir ssn dsn hopcount ttl expiration sleepmode snr
727
728 where the different fields are:-
729 da -- DA MAC address (in the form "00:11:22:33:44:55")
730 ra -- RA MAC address (in the form "00:11:22:33:44:55")
731 metric -- route metric (cost: smaller-metric routes are preferred)
732 dir -- direction (1 for direct, 0 for reverse)
733 ssn -- Source Sequence Number (time at the RA for reverse routes)
734 dsn -- Destination Sequence Number (time at the DA for direct routes)
735 hopcount -- hop count (currently unused)
736 ttl -- TTL (only used in reverse entries)
737 expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
738 sleepmode -- RA's sleep mode (currently unused)
739 snr -- SNR in the link to RA (currently unused)
740
741fwt_list_route
742 This command is used to list a route from the FWT table. The only
743 parameter is the route ID. If you want to list all the routes in a
744 table, start with rid=0, and keep incrementing rid until you get a
745 "(null)" string. This function is similar to fwt_list. The only
746 difference is the output format. Also note that this command is meant
747 for debugging. It is expected that users will use fwt_lookup and
748 fwt_list. One important reason for this is that the route id may change
749 as the route table is altered.
750
751 iwpriv ethX fwt_list_route rid
752
753 The output is a string of the following form:
754
755 da metric dir nid ssn dsn hopcount ttl expiration
756
757 where the different fields are:-
758 da -- DA MAC address (in the form "00:11:22:33:44:55")
759 metric -- route metric (cost: smaller-metric routes are preferred)
760 dir -- direction (1 for direct, 0 for reverse)
761 nid -- Next-hop (neighbor) host ID (nid)
762 ssn -- Source Sequence Number (time at the RA for reverse routes)
763 dsn -- Destination Sequence Number (time at the DA for direct routes)
764 hopcount -- hop count (currently unused)
765 ttl -- TTL count (only used in reverse entries)
766 expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
767
768fwt_list_neigh
769 This command is used to list a neighbor from the FWT table. The only
770 parameter is the neighbor ID. If you want to list all the neighbors in a
771 table, start with nid=0, and keep incrementing nid until you get a
772 "(null)" string. Note that the nid from a fwt_list_route command can be
773 used as an input to this command. Also note that this command is meant
774 mostly for debugging. It is expected that users will use fwt_lookup.
775 One important reason for this is that the neighbor id may change as the
776 neighbor table is altered.
777
778 iwpriv ethX fwt_list_neigh nid
779
780 The output is a string of the following form:
781
782 ra sleepmode snr references
783
784 where the different fields are:-
785 ra -- RA MAC address (in the form "00:11:22:33:44:55")
786 sleepmode -- RA's sleep mode (currently unused)
787 snr -- SNR in the link to RA (currently unused)
788 references -- RA's reference counter
789
790fwt_reset
791 This command is used to reset the FWT table, getting rid of all the
792 entries. There are no input parameters.
793
794 iwpriv ethX fwt_reset
795
796 The command does not return anything.
797
798fwt_cleanup
799 This command is used to perform user-based garbage recollection. The
800 FWT table is checked, and all the entries that are expired or invalid
801 are cleaned. Note that this is exported to the driver for debugging
802 purposes, as garbage collection is also fired by the firmware when in
803 space problems. There are no input parameters.
804
805 iwpriv ethX fwt_cleanup
806
807 The command does returns the number of invalid/expired routes deleted.
808
809fwt_time
810 This command returns a card's internal time representation. It is this
811 time that is used to represent the expiration times of FWT entries. The
812 number is not consistent from card to card; it is simply a timer count.
813 The fwt_time command is used to inspect the timer so that expiration
814 times reported by fwt_list can be properly interpreted.
815
816 iwpriv ethX fwt_time
817
818mesh_get_ttl
819
820 The mesh ttl is the number of hops a mesh packet can traverse before it
821 is dropped. This parameter is used to prevent infinite loops in the
822 mesh network. The value returned by this function is the ttl assigned
823 to all mesh packets. Currently there is no way to control the ttl on a
824 per packet or per socket basis.
825
826 iwpriv ethX mesh_get_ttl
827
828mesh_set_ttl ttl
829
830 Set the ttl. The argument must be between 0 and 255.
831
832 iwpriv ethX mesh_set_ttl <ttl>
833
834=========================
835ETHTOOL
836=========================
837
838
839Use the -i option to retrieve version information from the driver.
840
841# ethtool -i eth0
842driver: libertas
843version: COMM-USB8388-318.p4
844firmware-version: 5.110.7
845bus-info:
846
847Use the -e option to read the EEPROM contents of the card.
848
849 Usage:
850 ethtool -e ethX [raw on|off] [offset N] [length N]
851
852 -e retrieves and prints an EEPROM dump for the specified ethernet
853 device. When raw is enabled, then it dumps the raw EEPROM data
854 to stdout. The length and offset parameters allow dumping cer-
855 tain portions of the EEPROM. Default is to dump the entire EEP-
856 ROM.
857
858# ethtool -e eth0 offset 0 length 16
859Offset Values
860------ ------
8610x0000 38 33 30 58 00 00 34 f4 00 00 10 00 00 c4 17 00
862
863========================
864DEBUGFS COMMANDS
865========================
866
867those commands are used via debugfs interface
868
869===========
870rdmac
871rdbbp
872rdrf
873 These commands are used to read the MAC, BBP and RF registers from the
874 card. These commands take one parameter that specifies the offset
875 location that is to be read. This parameter must be specified in
876 hexadecimal (its possible to preceed preceding the number with a "0x").
877
878 Path: /debugfs/libertas_wireless/ethX/registers/
879
880 Usage:
881 echo "0xa123" > rdmac ; cat rdmac
882 echo "0xa123" > rdbbp ; cat rdbbp
883 echo "0xa123" > rdrf ; cat rdrf
884wrmac
885wrbbp
886wrrf
887 These commands are used to write the MAC, BBP and RF registers in the
888 card. These commands take two parameters that specify the offset
889 location and the value that is to be written. This parameters must
890 be specified in hexadecimal (its possible to preceed the number
891 with a "0x").
892
893 Usage:
894 echo "0xa123 0xaa" > wrmac
895 echo "0xa123 0xaa" > wrbbp
896 echo "0xa123 0xaa" > wrrf
897
898sleepparams
899 This command is used to set the sleepclock configurations
900
901 Path: /debugfs/libertas_wireless/ethX/
902
903 Usage:
904 cat sleepparams: reads the current sleepclock configuration
905
906 echo "p1 p2 p3 p4 p5 p6" > sleepparams: writes the sleepclock configuration.
907
908 where:
909 p1 is Sleep clock error in ppm (0-65535)
910 p2 is Wakeup offset in usec (0-65535)
911 p3 is Clock stabilization time in usec (0-65535)
912 p4 is Control periodic calibration (0-2)
913 p5 is Control the use of external sleep clock (0-2)
914 p6 is reserved for debug (0-65535)
915
916subscribed_events
917
918 The subscribed_events directory contains the interface for the
919 subscribed events API.
920
921 Path: /debugfs/libertas_wireless/ethX/subscribed_events/
922
923 Each event is represented by a filename. Each filename consists of the
924 following three fields:
925 Value Frequency Subscribed
926
927 To read the current values for a given event, do:
928 cat event
929 To set the current values, do:
930 echo "60 2 1" > event
931
932 Frequency field specifies the reporting frequency for this event.
933 If it is set to 0, then the event is reported only once, and then
934 automatically unsubscribed. If it is set to 1, then the event is
935 reported every time it occurs. If it is set to N, then the event is
936 reported every Nth time it occurs.
937
938 beacon_missed
939 Value field specifies the number of consecutive missing beacons which
940 triggers the LINK_LOSS event. This event is generated only once after
941 which the firmware resets its state. At initialization, the LINK_LOSS
942 event is subscribed by default. The default value of MissedBeacons is
943 60.
944
945 failure_count
946 Value field specifies the consecutive failure count threshold which
947 triggers the generation of the MAX_FAIL event. Once this event is
948 generated, the consecutive failure count is reset to 0.
949 At initialization, the MAX_FAIL event is NOT subscribed by
950 default.
951
952 high_rssi
953 This event is generated when the average received RSSI in beacons goes
954 above a threshold, specified by Value.
955
956 low_rssi
957 This event is generated when the average received RSSI in beacons goes
958 below a threshold, specified by Value.
959
960 high_snr
961 This event is generated when the average received SNR in beacons goes
962 above a threshold, specified by Value.
963
964 low_snr
965 This event is generated when the average received SNR in beacons goes
966 below a threshold, specified by Value.
967
968extscan
969 This command is used to do a specific scan.
970
971 Path: /debugfs/libertas_wireless/ethX/
972
973 Usage: echo "SSID" > extscan
974
975 Example:
976 echo "LINKSYS-AP" > extscan
977
978 To see the results of use getscantable command.
979
980getscantable
981
982 Display the current contents of the driver scan table (ie. get the
983 scan results).
984
985 Path: /debugfs/libertas_wireless/ethX/
986
987 Usage:
988 cat getscantable
989
990setuserscan
991 Initiate a customized scan and retrieve the results
992
993
994 Path: /debugfs/libertas_wireless/ethX/
995
996 Usage:
997 echo "[ARGS]" > setuserscan
998
999 where [ARGS]:
1000
1001 chan=[chan#][band][mode] where band is [a,b,g] and mode is
1002 blank for active or 'p' for passive
1003 bssid=xx:xx:xx:xx:xx:xx specify a BSSID filter for the scan
1004 ssid="[SSID]" specify a SSID filter for the scan
1005 keep=[0 or 1] keep the previous scan results (1), discard (0)
1006 dur=[scan time] time to scan for each channel in milliseconds
1007 probes=[#] number of probe requests to send on each chan
1008 type=[1,2,3] BSS type: 1 (Infra), 2(Adhoc), 3(Any)
1009
1010 Any combination of the above arguments can be supplied on the command line.
1011 If the chan token is absent, a full channel scan will be completed by
1012 the driver. If the dur or probes tokens are absent, the driver default
1013 setting will be used. The bssid and ssid fields, if blank,
1014 will produce an unfiltered scan. The type field will default to 3 (Any)
1015 and the keep field will default to 0 (Discard).
1016
1017 Examples:
1018 1) Perform an active scan on channels 1, 6, and 11 in the 'g' band:
1019 echo "chan=1g,6g,11g" > setuserscan
1020
1021 2) Perform a passive scan on channel 11 for 20 ms:
1022 echo "chan=11gp dur=20" > setuserscan
1023
1024 3) Perform an active scan on channels 1, 6, and 11; and a passive scan on
1025 channel 36 in the 'a' band:
1026
1027 echo "chan=1g,6g,11g,36ap" > setuserscan
1028
1029 4) Perform an active scan on channel 6 and 36 for a specific SSID:
1030 echo "chan=6g,36a ssid="TestAP"" > setuserscan
1031
1032 5) Scan all available channels (B/G, A bands) for a specific BSSID, keep
1033 the current scan table intact, update existing or append new scan data:
1034 echo "bssid=00:50:43:20:12:82 keep=1" > setuserscan
1035
1036 6) Scan channel 6, for all infrastructure networks, sending two probe
1037 requests. Keep the previous scan table intact. Update any duplicate
1038 BSSID/SSID matches with the new scan data:
1039 echo "chan=6g type=1 probes=2 keep=1" > setuserscan
1040
1041 All entries in the scan table (not just the new scan data when keep=1)
1042 will be displayed upon completion by use of the getscantable ioctl.
1043
1044==============================================================================
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
new file mode 100644
index 000000000000..b55c7f57aca8
--- /dev/null
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -0,0 +1,588 @@
1/* Copyright (C) 2006, Red Hat, Inc. */
2
3#include <linux/bitops.h>
4#include <net/ieee80211.h>
5
6#include "assoc.h"
7#include "join.h"
8#include "decl.h"
9#include "hostcmd.h"
10#include "host.h"
11
12
13static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
14static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
15
16static int assoc_helper_essid(wlan_private *priv,
17 struct assoc_request * assoc_req)
18{
19 wlan_adapter *adapter = priv->adapter;
20 int ret = 0;
21 int i;
22
23 ENTER();
24
25 lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
26 if (assoc_req->mode == wlan802_11infrastructure) {
27 if (adapter->prescan) {
28 libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
29 }
30
31 i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
32 NULL, wlan802_11infrastructure);
33 if (i >= 0) {
34 lbs_pr_debug(1,
35 "SSID found in scan list ... associating...\n");
36
37 ret = wlan_associate(priv, &adapter->scantable[i]);
38 if (ret == 0) {
39 memcpy(&assoc_req->bssid,
40 &adapter->scantable[i].macaddress,
41 ETH_ALEN);
42 }
43 } else {
44 lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
45 assoc_req->ssid.ssid);
46 }
47 } else if (assoc_req->mode == wlan802_11ibss) {
48 /* Scan for the network, do not save previous results. Stale
49 * scan data will cause us to join a non-existant adhoc network
50 */
51 libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0);
52
53 /* Search for the requested SSID in the scan table */
54 i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
55 wlan802_11ibss);
56 if (i >= 0) {
57 lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
58 libertas_join_adhoc_network(priv, &adapter->scantable[i]);
59 } else {
60 /* else send START command */
61 lbs_pr_debug(1, "SSID not found in list, so creating adhoc"
62 " with SSID '%s'\n", assoc_req->ssid.ssid);
63 libertas_start_adhoc_network(priv, &assoc_req->ssid);
64 }
65 memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN);
66 }
67
68 LEAVE();
69 return ret;
70}
71
72
73static int assoc_helper_bssid(wlan_private *priv,
74 struct assoc_request * assoc_req)
75{
76 wlan_adapter *adapter = priv->adapter;
77 int i, ret = 0;
78
79 ENTER();
80
81 lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n",
82 MAC_ARG(assoc_req->bssid));
83
84 /* Search for index position in list for requested MAC */
85 i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid,
86 assoc_req->mode);
87 if (i < 0) {
88 lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, "
89 "cannot associate.\n", MAC_ARG(assoc_req->bssid));
90 goto out;
91 }
92
93 if (assoc_req->mode == wlan802_11infrastructure) {
94 ret = wlan_associate(priv, &adapter->scantable[i]);
95 lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
96 } else if (assoc_req->mode == wlan802_11ibss) {
97 libertas_join_adhoc_network(priv, &adapter->scantable[i]);
98 }
99 memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
100 sizeof(struct WLAN_802_11_SSID));
101
102out:
103 LEAVE();
104 return ret;
105}
106
107
108static int assoc_helper_associate(wlan_private *priv,
109 struct assoc_request * assoc_req)
110{
111 int ret = 0, done = 0;
112
113 /* If we're given and 'any' BSSID, try associating based on SSID */
114
115 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
116 if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN)
117 && memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) {
118 ret = assoc_helper_bssid(priv, assoc_req);
119 done = 1;
120 if (ret) {
121 lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
122 }
123 }
124 }
125
126 if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
127 ret = assoc_helper_essid(priv, assoc_req);
128 if (ret) {
129 lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
130 }
131 }
132
133 return ret;
134}
135
136
137static int assoc_helper_mode(wlan_private *priv,
138 struct assoc_request * assoc_req)
139{
140 wlan_adapter *adapter = priv->adapter;
141 int ret = 0;
142
143 ENTER();
144
145 if (assoc_req->mode == adapter->inframode) {
146 LEAVE();
147 return 0;
148 }
149
150 if (assoc_req->mode == wlan802_11infrastructure) {
151 if (adapter->psstate != PS_STATE_FULL_POWER)
152 libertas_ps_wakeup(priv, cmd_option_waitforrsp);
153 adapter->psmode = wlan802_11powermodecam;
154 }
155
156 adapter->inframode = assoc_req->mode;
157 ret = libertas_prepare_and_send_command(priv,
158 cmd_802_11_snmp_mib,
159 0, cmd_option_waitforrsp,
160 OID_802_11_INFRASTRUCTURE_MODE,
161 (void *) assoc_req->mode);
162
163 LEAVE();
164 return ret;
165}
166
167
168static int assoc_helper_wep_keys(wlan_private *priv,
169 struct assoc_request * assoc_req)
170{
171 wlan_adapter *adapter = priv->adapter;
172 int i;
173 int ret = 0;
174
175 ENTER();
176
177 /* Set or remove WEP keys */
178 if ( assoc_req->wep_keys[0].len
179 || assoc_req->wep_keys[1].len
180 || assoc_req->wep_keys[2].len
181 || assoc_req->wep_keys[3].len) {
182 ret = libertas_prepare_and_send_command(priv,
183 cmd_802_11_set_wep,
184 cmd_act_add,
185 cmd_option_waitforrsp,
186 0, assoc_req);
187 } else {
188 ret = libertas_prepare_and_send_command(priv,
189 cmd_802_11_set_wep,
190 cmd_act_remove,
191 cmd_option_waitforrsp,
192 0, NULL);
193 }
194
195 if (ret)
196 goto out;
197
198 /* enable/disable the MAC's WEP packet filter */
199 if (assoc_req->secinfo.WEPstatus == wlan802_11WEPenabled)
200 adapter->currentpacketfilter |= cmd_act_mac_wep_enable;
201 else
202 adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable;
203 ret = libertas_set_mac_packet_filter(priv);
204 if (ret)
205 goto out;
206
207 mutex_lock(&adapter->lock);
208
209 /* Copy WEP keys into adapter wep key fields */
210 for (i = 0; i < 4; i++) {
211 memcpy(&adapter->wep_keys[i], &assoc_req->wep_keys[i],
212 sizeof(struct WLAN_802_11_KEY));
213 }
214 adapter->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
215
216 mutex_unlock(&adapter->lock);
217
218out:
219 LEAVE();
220 return ret;
221}
222
223static int assoc_helper_secinfo(wlan_private *priv,
224 struct assoc_request * assoc_req)
225{
226 wlan_adapter *adapter = priv->adapter;
227 int ret = 0;
228
229 ENTER();
230
231 memcpy(&adapter->secinfo, &assoc_req->secinfo,
232 sizeof(struct wlan_802_11_security));
233
234 ret = libertas_set_mac_packet_filter(priv);
235
236 LEAVE();
237 return ret;
238}
239
240
241static int assoc_helper_wpa_keys(wlan_private *priv,
242 struct assoc_request * assoc_req)
243{
244 int ret = 0;
245
246 ENTER();
247
248 /* enable/Disable RSN */
249 ret = libertas_prepare_and_send_command(priv,
250 cmd_802_11_enable_rsn,
251 cmd_act_set,
252 cmd_option_waitforrsp,
253 0, assoc_req);
254 if (ret)
255 goto out;
256
257 ret = libertas_prepare_and_send_command(priv,
258 cmd_802_11_key_material,
259 cmd_act_set,
260 cmd_option_waitforrsp,
261 0, assoc_req);
262
263out:
264 LEAVE();
265 return ret;
266}
267
268
269static int assoc_helper_wpa_ie(wlan_private *priv,
270 struct assoc_request * assoc_req)
271{
272 wlan_adapter *adapter = priv->adapter;
273 int ret = 0;
274
275 ENTER();
276
277 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
278 memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
279 adapter->wpa_ie_len = assoc_req->wpa_ie_len;
280 } else {
281 memset(&adapter->wpa_ie, 0, MAX_WPA_IE_LEN);
282 adapter->wpa_ie_len = 0;
283 }
284
285 LEAVE();
286 return ret;
287}
288
289
290static int should_deauth_infrastructure(wlan_adapter *adapter,
291 struct assoc_request * assoc_req)
292{
293 if (adapter->connect_status != libertas_connected)
294 return 0;
295
296 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
297 lbs_pr_debug(1, "Deauthenticating due to new SSID in "
298 " configuration request.\n");
299 return 1;
300 }
301
302 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
303 if (adapter->secinfo.authmode !=
304 assoc_req->secinfo.authmode) {
305 lbs_pr_debug(1, "Deauthenticating due to updated security "
306 "info in configuration request.\n");
307 return 1;
308 }
309 }
310
311 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
312 lbs_pr_debug(1, "Deauthenticating due to new BSSID in "
313 " configuration request.\n");
314 return 1;
315 }
316
317 /* FIXME: deal with 'auto' mode somehow */
318 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
319 if (assoc_req->mode != wlan802_11infrastructure)
320 return 1;
321 }
322
323 return 0;
324}
325
326
327static int should_stop_adhoc(wlan_adapter *adapter,
328 struct assoc_request * assoc_req)
329{
330 if (adapter->connect_status != libertas_connected)
331 return 0;
332
333 if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
334 return 1;
335 if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
336 sizeof(struct WLAN_802_11_SSID)))
337 return 1;
338
339 /* FIXME: deal with 'auto' mode somehow */
340 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
341 if (assoc_req->mode != wlan802_11ibss)
342 return 1;
343 }
344
345 return 0;
346}
347
348
349void wlan_association_worker(struct work_struct *work)
350{
351 wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
352 wlan_adapter *adapter = priv->adapter;
353 struct assoc_request * assoc_req = NULL;
354 int ret = 0;
355 int find_any_ssid = 0;
356
357 ENTER();
358
359 mutex_lock(&adapter->lock);
360 assoc_req = adapter->assoc_req;
361 adapter->assoc_req = NULL;
362 mutex_unlock(&adapter->lock);
363
364 if (!assoc_req) {
365 LEAVE();
366 return;
367 }
368
369 lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n",
370 assoc_req->flags);
371
372 /* If 'any' SSID was specified, find an SSID to associate with */
373 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
374 && !assoc_req->ssid.ssidlength)
375 find_any_ssid = 1;
376
377 /* But don't use 'any' SSID if there's a valid locked BSSID to use */
378 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
379 if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN)
380 && memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN))
381 find_any_ssid = 0;
382 }
383
384 if (find_any_ssid) {
385 enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
386
387 ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
388 assoc_req->mode, &new_mode);
389 if (ret) {
390 lbs_pr_debug(1, "Could not find best network\n");
391 ret = -ENETUNREACH;
392 goto out;
393 }
394
395 /* Ensure we switch to the mode of the AP */
396 if (assoc_req->mode == wlan802_11autounknown) {
397 set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
398 assoc_req->mode = new_mode;
399 }
400 }
401
402 /*
403 * Check if the attributes being changing require deauthentication
404 * from the currently associated infrastructure access point.
405 */
406 if (adapter->inframode == wlan802_11infrastructure) {
407 if (should_deauth_infrastructure(adapter, assoc_req)) {
408 ret = libertas_send_deauthentication(priv);
409 if (ret) {
410 lbs_pr_debug(1, "Deauthentication due to new "
411 "configuration request failed: %d\n",
412 ret);
413 }
414 }
415 } else if (adapter->inframode == wlan802_11ibss) {
416 if (should_stop_adhoc(adapter, assoc_req)) {
417 ret = libertas_stop_adhoc_network(priv);
418 if (ret) {
419 lbs_pr_debug(1, "Teardown of AdHoc network due to "
420 "new configuration request failed: %d\n",
421 ret);
422 }
423
424 }
425 }
426
427 /* Send the various configuration bits to the firmware */
428 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
429 ret = assoc_helper_mode(priv, assoc_req);
430 if (ret) {
431lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
432 goto out;
433 }
434 }
435
436 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
437 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
438 ret = assoc_helper_wep_keys(priv, assoc_req);
439 if (ret) {
440lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
441 goto out;
442 }
443 }
444
445 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
446 ret = assoc_helper_secinfo(priv, assoc_req);
447 if (ret) {
448lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
449 goto out;
450 }
451 }
452
453 if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
454 ret = assoc_helper_wpa_ie(priv, assoc_req);
455 if (ret) {
456lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
457 goto out;
458 }
459 }
460
461 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)
462 || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
463 ret = assoc_helper_wpa_keys(priv, assoc_req);
464 if (ret) {
465lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
466 goto out;
467 }
468 }
469
470 /* SSID/BSSID should be the _last_ config option set, because they
471 * trigger the association attempt.
472 */
473 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)
474 || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
475 int success = 1;
476
477 ret = assoc_helper_associate(priv, assoc_req);
478 if (ret) {
479 lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n",
480 ret);
481 success = 0;
482 }
483
484 if (adapter->connect_status != libertas_connected) {
485 lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, "
486 "not connected.\n");
487 success = 0;
488 }
489
490 if (success) {
491 lbs_pr_debug(1, "ASSOC: association attempt successful. "
492 "Associated to '%s' (" MAC_FMT ")\n",
493 assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid));
494 libertas_prepare_and_send_command(priv,
495 cmd_802_11_rssi,
496 0, cmd_option_waitforrsp, 0, NULL);
497
498 libertas_prepare_and_send_command(priv,
499 cmd_802_11_get_log,
500 0, cmd_option_waitforrsp, 0, NULL);
501 } else {
502
503 ret = -1;
504 }
505 }
506
507out:
508 if (ret) {
509 lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n",
510 ret);
511 }
512 kfree(assoc_req);
513 LEAVE();
514}
515
516
517/*
518 * Caller MUST hold any necessary locks
519 */
520struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
521{
522 struct assoc_request * assoc_req;
523
524 if (!adapter->assoc_req) {
525 adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL);
526 if (!adapter->assoc_req) {
527 lbs_pr_info("Not enough memory to allocate association"
528 " request!\n");
529 return NULL;
530 }
531 }
532
533 /* Copy current configuration attributes to the association request,
534 * but don't overwrite any that are already set.
535 */
536 assoc_req = adapter->assoc_req;
537 if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
538 memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid,
539 adapter->curbssparams.ssid.ssidlength);
540 }
541
542 if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
543 assoc_req->channel = adapter->curbssparams.channel;
544
545 if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
546 assoc_req->mode = adapter->inframode;
547
548 if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
549 memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
550 ETH_ALEN);
551 }
552
553 if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) {
554 int i;
555 for (i = 0; i < 4; i++) {
556 memcpy(&assoc_req->wep_keys[i], &adapter->wep_keys[i],
557 sizeof(struct WLAN_802_11_KEY));
558 }
559 }
560
561 if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags))
562 assoc_req->wep_tx_keyidx = adapter->wep_tx_keyidx;
563
564 if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
565 memcpy(&assoc_req->wpa_mcast_key, &adapter->wpa_mcast_key,
566 sizeof(struct WLAN_802_11_KEY));
567 }
568
569 if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
570 memcpy(&assoc_req->wpa_unicast_key, &adapter->wpa_unicast_key,
571 sizeof(struct WLAN_802_11_KEY));
572 }
573
574 if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
575 memcpy(&assoc_req->secinfo, &adapter->secinfo,
576 sizeof(struct wlan_802_11_security));
577 }
578
579 if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
580 memcpy(&assoc_req->wpa_ie, &adapter->wpa_ie,
581 MAX_WPA_IE_LEN);
582 assoc_req->wpa_ie_len = adapter->wpa_ie_len;
583 }
584
585 return assoc_req;
586}
587
588
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
new file mode 100644
index 000000000000..2ffd82d99b34
--- /dev/null
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -0,0 +1,30 @@
1/* Copyright (C) 2006, Red Hat, Inc. */
2
3#ifndef _WLAN_ASSOC_H_
4#define _WLAN_ASSOC_H_
5
6#include "dev.h"
7
8void wlan_association_worker(struct work_struct *work);
9
10struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
11
12#define ASSOC_DELAY (HZ / 2)
13static inline void wlan_postpone_association_work(wlan_private *priv)
14{
15 if (priv->adapter->surpriseremoved)
16 return;
17 cancel_delayed_work(&priv->assoc_work);
18 queue_delayed_work(priv->assoc_thread, &priv->assoc_work, ASSOC_DELAY);
19}
20
21static inline void wlan_cancel_association_work(wlan_private *priv)
22{
23 cancel_delayed_work(&priv->assoc_work);
24 if (priv->adapter->assoc_req) {
25 kfree(priv->adapter->assoc_req);
26 priv->adapter->assoc_req = NULL;
27 }
28}
29
30#endif /* _WLAN_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
new file mode 100644
index 000000000000..bfdac58b5c06
--- /dev/null
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -0,0 +1,1958 @@
1/**
2 * This file contains the handling of command.
3 * It prepares command and sends it to firmware when it is ready.
4 */
5
6#include <net/iw_handler.h>
7#include "host.h"
8#include "hostcmd.h"
9#include "sbi.h"
10#include "decl.h"
11#include "defs.h"
12#include "dev.h"
13#include "join.h"
14#include "wext.h"
15
16static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
17
18static u16 commands_allowed_in_ps[] = {
19 cmd_802_11_rssi,
20};
21
22/**
23 * @brief This function checks if the commans is allowed
24 * in PS mode not.
25 *
26 * @param command the command ID
27 * @return TRUE or FALSE
28 */
29static u8 is_command_allowed_in_ps(u16 command)
30{
31 int count = sizeof(commands_allowed_in_ps)
32 / sizeof(commands_allowed_in_ps[0]);
33 int i;
34
35 for (i = 0; i < count; i++) {
36 if (command == cpu_to_le16(commands_allowed_in_ps[i]))
37 return 1;
38 }
39
40 return 0;
41}
42
43static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd)
44{
45 struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
46
47 ENTER();
48
49 cmd->command = cpu_to_le16(cmd_get_hw_spec);
50 cmd->size =
51 cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
52 memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN);
53
54 LEAVE();
55 return 0;
56}
57
58static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
59 struct cmd_ds_command *cmd,
60 u16 cmd_action)
61{
62 struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
63 u16 action = cmd_action;
64 wlan_adapter *adapter = priv->adapter;
65
66 ENTER();
67
68 cmd->command = cpu_to_le16(cmd_802_11_ps_mode);
69 cmd->size =
70 cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
71 S_DS_GEN);
72 psm->action = cpu_to_le16(cmd_action);
73 psm->multipledtim = 0;
74 switch (action) {
75 case cmd_subcmd_enter_ps:
76 lbs_pr_debug(1, "PS command:" "SubCode- Enter PS\n");
77 lbs_pr_debug(1, "locallisteninterval = %d\n",
78 adapter->locallisteninterval);
79
80 psm->locallisteninterval =
81 cpu_to_le16(adapter->locallisteninterval);
82 psm->nullpktinterval =
83 cpu_to_le16(adapter->nullpktinterval);
84 psm->multipledtim =
85 cpu_to_le16(priv->adapter->multipledtim);
86 break;
87
88 case cmd_subcmd_exit_ps:
89 lbs_pr_debug(1, "PS command:" "SubCode- Exit PS\n");
90 break;
91
92 case cmd_subcmd_sleep_confirmed:
93 lbs_pr_debug(1, "PS command: SubCode- sleep confirm\n");
94 break;
95
96 default:
97 break;
98 }
99
100 LEAVE();
101 return 0;
102}
103
104static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
105 struct cmd_ds_command *cmd,
106 u16 cmd_action, void *pdata_buf)
107{
108 u16 *timeout = pdata_buf;
109
110 cmd->command = cpu_to_le16(cmd_802_11_inactivity_timeout);
111 cmd->size =
112 cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout)
113 + S_DS_GEN);
114
115 cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action);
116
117 if (cmd_action)
118 cmd->params.inactivity_timeout.timeout =
119 cpu_to_le16(*timeout);
120 else
121 cmd->params.inactivity_timeout.timeout = 0;
122
123 return 0;
124}
125
126static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
127 struct cmd_ds_command *cmd,
128 u16 cmd_action)
129{
130 wlan_adapter *adapter = priv->adapter;
131 struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
132
133 ENTER();
134
135 cmd->size =
136 cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
137 S_DS_GEN);
138 cmd->command = cpu_to_le16(cmd_802_11_sleep_params);
139
140 if (cmd_action == cmd_act_get) {
141 memset(&adapter->sp, 0, sizeof(struct sleep_params));
142 memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params));
143 sp->action = cpu_to_le16(cmd_action);
144 } else if (cmd_action == cmd_act_set) {
145 sp->action = cpu_to_le16(cmd_action);
146 sp->error = cpu_to_le16(adapter->sp.sp_error);
147 sp->offset = cpu_to_le16(adapter->sp.sp_offset);
148 sp->stabletime = cpu_to_le16(adapter->sp.sp_stabletime);
149 sp->calcontrol = (u8) adapter->sp.sp_calcontrol;
150 sp->externalsleepclk = (u8) adapter->sp.sp_extsleepclk;
151 sp->reserved = cpu_to_le16(adapter->sp.sp_reserved);
152 }
153
154 LEAVE();
155 return 0;
156}
157
158static int wlan_cmd_802_11_set_wep(wlan_private * priv,
159 struct cmd_ds_command *cmd,
160 u32 cmd_act,
161 void * pdata_buf)
162{
163 struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep;
164 wlan_adapter *adapter = priv->adapter;
165 int ret = 0;
166 struct assoc_request * assoc_req = pdata_buf;
167
168 ENTER();
169
170 cmd->command = cpu_to_le16(cmd_802_11_set_wep);
171 cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_set_wep))
172 + S_DS_GEN);
173
174 if (cmd_act == cmd_act_add) {
175 int i;
176
177 if (!assoc_req) {
178 lbs_pr_debug(1, "Invalid association request!");
179 ret = -1;
180 goto done;
181 }
182
183 wep->action = cpu_to_le16(cmd_act_add);
184
185 /* default tx key index */
186 wep->keyindex = cpu_to_le16((u16)
187 (assoc_req->wep_tx_keyidx &
188 (u32)cmd_WEP_KEY_INDEX_MASK));
189
190 lbs_pr_debug(1, "Tx key Index: %u\n", wep->keyindex);
191
192 /* Copy key types and material to host command structure */
193 for (i = 0; i < 4; i++) {
194 struct WLAN_802_11_KEY * pkey = &assoc_req->wep_keys[i];
195
196 switch (pkey->len) {
197 case KEY_LEN_WEP_40:
198 wep->keytype[i] = cmd_type_wep_40_bit;
199 memmove(&wep->keymaterial[i], pkey->key,
200 pkey->len);
201 break;
202 case KEY_LEN_WEP_104:
203 wep->keytype[i] = cmd_type_wep_104_bit;
204 memmove(&wep->keymaterial[i], pkey->key,
205 pkey->len);
206 break;
207 case 0:
208 break;
209 default:
210 lbs_pr_debug(1, "Invalid WEP key %d length of %d\n",
211 i, pkey->len);
212 ret = -1;
213 goto done;
214 break;
215 }
216 }
217 } else if (cmd_act == cmd_act_remove) {
218 /* ACT_REMOVE clears _all_ WEP keys */
219 wep->action = cpu_to_le16(cmd_act_remove);
220
221 /* default tx key index */
222 wep->keyindex = cpu_to_le16((u16)
223 (adapter->wep_tx_keyidx &
224 (u32)cmd_WEP_KEY_INDEX_MASK));
225 }
226
227 ret = 0;
228
229done:
230 LEAVE();
231 return ret;
232}
233
234static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
235 struct cmd_ds_command *cmd,
236 u16 cmd_action)
237{
238 struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
239 wlan_adapter *adapter = priv->adapter;
240
241 cmd->command = cpu_to_le16(cmd_802_11_enable_rsn);
242 cmd->size =
243 cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) +
244 S_DS_GEN);
245 penableRSN->action = cpu_to_le16(cmd_action);
246 if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
247 penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
248 } else {
249 penableRSN->enable = cpu_to_le16(cmd_disable_rsn);
250 }
251
252 return 0;
253}
254
255
256static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
257 struct WLAN_802_11_KEY * pkey)
258{
259 pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
260
261 if (pkey->flags & KEY_INFO_WPA_ENABLED) {
262 pkeyparamset->keyinfo = cpu_to_le16(KEY_INFO_WPA_ENABLED);
263 } else {
264 pkeyparamset->keyinfo = cpu_to_le16(!KEY_INFO_WPA_ENABLED);
265 }
266
267 if (pkey->flags & KEY_INFO_WPA_UNICAST) {
268 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
269 } else if (pkey->flags & KEY_INFO_WPA_MCAST) {
270 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
271 }
272
273 pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
274 pkeyparamset->keylen = cpu_to_le16(pkey->len);
275 memcpy(pkeyparamset->key, pkey->key, pkey->len);
276 pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid)
277 + sizeof(pkeyparamset->keyinfo)
278 + sizeof(pkeyparamset->keylen)
279 + sizeof(pkeyparamset->key));
280}
281
282static int wlan_cmd_802_11_key_material(wlan_private * priv,
283 struct cmd_ds_command *cmd,
284 u16 cmd_action,
285 u32 cmd_oid, void *pdata_buf)
286{
287 wlan_adapter *adapter = priv->adapter;
288 struct cmd_ds_802_11_key_material *pkeymaterial =
289 &cmd->params.keymaterial;
290 int ret = 0;
291 int index = 0;
292
293 ENTER();
294
295 cmd->command = cpu_to_le16(cmd_802_11_key_material);
296 pkeymaterial->action = cpu_to_le16(cmd_action);
297
298 if (cmd_action == cmd_act_get) {
299 cmd->size = cpu_to_le16( S_DS_GEN
300 + sizeof (pkeymaterial->action));
301 ret = 0;
302 goto done;
303 }
304
305 memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet));
306
307 if (adapter->wpa_unicast_key.len) {
308 set_one_wpa_key(&pkeymaterial->keyParamSet[index],
309 &adapter->wpa_unicast_key);
310 index++;
311 }
312
313 if (adapter->wpa_mcast_key.len) {
314 set_one_wpa_key(&pkeymaterial->keyParamSet[index],
315 &adapter->wpa_mcast_key);
316 index++;
317 }
318
319 cmd->size = cpu_to_le16( S_DS_GEN
320 + sizeof (pkeymaterial->action)
321 + index * sizeof(struct MrvlIEtype_keyParamSet));
322
323 ret = 0;
324
325done:
326 LEAVE();
327 return ret;
328}
329
330static int wlan_cmd_802_11_reset(wlan_private * priv,
331 struct cmd_ds_command *cmd, int cmd_action)
332{
333 struct cmd_ds_802_11_reset *reset = &cmd->params.reset;
334
335 cmd->command = cpu_to_le16(cmd_802_11_reset);
336 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
337 reset->action = cpu_to_le16(cmd_action);
338
339 return 0;
340}
341
342static int wlan_cmd_802_11_get_log(wlan_private * priv,
343 struct cmd_ds_command *cmd)
344{
345 cmd->command = cpu_to_le16(cmd_802_11_get_log);
346 cmd->size =
347 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN);
348
349 return 0;
350}
351
352static int wlan_cmd_802_11_get_stat(wlan_private * priv,
353 struct cmd_ds_command *cmd)
354{
355 cmd->command = cpu_to_le16(cmd_802_11_get_stat);
356 cmd->size =
357 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) +
358 S_DS_GEN);
359
360 return 0;
361}
362
363static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
364 struct cmd_ds_command *cmd,
365 int cmd_action,
366 int cmd_oid, void *pdata_buf)
367{
368 struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib;
369 wlan_adapter *adapter = priv->adapter;
370 u8 ucTemp;
371
372 ENTER();
373
374 lbs_pr_debug(1, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
375
376 cmd->command = cpu_to_le16(cmd_802_11_snmp_mib);
377 cmd->size =
378 cpu_to_le16(sizeof(struct cmd_ds_802_11_snmp_mib) +
379 S_DS_GEN);
380
381 switch (cmd_oid) {
382 case OID_802_11_INFRASTRUCTURE_MODE:
383 {
384 enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode =
385 (enum WLAN_802_11_NETWORK_INFRASTRUCTURE) pdata_buf;
386 pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
387 pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i);
388 pSNMPMIB->bufsize = sizeof(u8);
389 if (mode == wlan802_11infrastructure)
390 ucTemp = SNMP_MIB_VALUE_INFRA;
391 else
392 ucTemp = SNMP_MIB_VALUE_ADHOC;
393
394 memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
395
396 break;
397 }
398
399 case OID_802_11D_ENABLE:
400 {
401 u32 ulTemp;
402
403 pSNMPMIB->oid = cpu_to_le16((u16) dot11d_i);
404
405 if (cmd_action == cmd_act_set) {
406 pSNMPMIB->querytype = cmd_act_set;
407 pSNMPMIB->bufsize = sizeof(u16);
408 ulTemp = *(u32 *)pdata_buf;
409 *((unsigned short *)(pSNMPMIB->value)) =
410 cpu_to_le16((u16) ulTemp);
411 }
412 break;
413 }
414
415 case OID_802_11_FRAGMENTATION_THRESHOLD:
416 {
417 u32 ulTemp;
418
419 pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i);
420
421 if (cmd_action == cmd_act_get) {
422 pSNMPMIB->querytype =
423 cpu_to_le16(cmd_act_get);
424 } else if (cmd_action == cmd_act_set) {
425 pSNMPMIB->querytype =
426 cpu_to_le16(cmd_act_set);
427 pSNMPMIB->bufsize =
428 cpu_to_le16(sizeof(u16));
429 ulTemp = *((u32 *) pdata_buf);
430 *((unsigned short *)(pSNMPMIB->value)) =
431 cpu_to_le16((u16) ulTemp);
432
433 }
434
435 break;
436 }
437
438 case OID_802_11_RTS_THRESHOLD:
439 {
440
441 u32 ulTemp;
442 pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i);
443
444 if (cmd_action == cmd_act_get) {
445 pSNMPMIB->querytype =
446 cpu_to_le16(cmd_act_get);
447 } else if (cmd_action == cmd_act_set) {
448 pSNMPMIB->querytype =
449 cpu_to_le16(cmd_act_set);
450 pSNMPMIB->bufsize =
451 cpu_to_le16(sizeof(u16));
452 ulTemp = *((u32 *)
453 pdata_buf);
454 *(unsigned short *)(pSNMPMIB->value) =
455 cpu_to_le16((u16) ulTemp);
456
457 }
458 break;
459 }
460 case OID_802_11_TX_RETRYCOUNT:
461 pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i);
462
463 if (cmd_action == cmd_act_get) {
464 pSNMPMIB->querytype =
465 cpu_to_le16(cmd_act_get);
466 } else if (cmd_action == cmd_act_set) {
467 pSNMPMIB->querytype =
468 cpu_to_le16(cmd_act_set);
469 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
470 *((unsigned short *)(pSNMPMIB->value)) =
471 cpu_to_le16((u16) adapter->txretrycount);
472 }
473
474 break;
475 default:
476 break;
477 }
478
479 lbs_pr_debug(1,
480 "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
481 cmd->command, cmd->size, cmd->seqnum, cmd->result);
482
483 lbs_pr_debug(1,
484 "SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n",
485 pSNMPMIB->querytype, pSNMPMIB->oid, pSNMPMIB->bufsize,
486 *(u16 *) pSNMPMIB->value);
487
488 LEAVE();
489 return 0;
490}
491
492static int wlan_cmd_802_11_radio_control(wlan_private * priv,
493 struct cmd_ds_command *cmd,
494 int cmd_action)
495{
496 wlan_adapter *adapter = priv->adapter;
497 struct cmd_ds_802_11_radio_control *pradiocontrol =
498 &cmd->params.radio;
499
500 ENTER();
501
502 cmd->size =
503 cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) +
504 S_DS_GEN);
505 cmd->command = cpu_to_le16(cmd_802_11_radio_control);
506
507 pradiocontrol->action = cpu_to_le16(cmd_action);
508
509 switch (adapter->preamble) {
510 case cmd_type_short_preamble:
511 pradiocontrol->control = cpu_to_le16(SET_SHORT_PREAMBLE);
512 break;
513
514 case cmd_type_long_preamble:
515 pradiocontrol->control = cpu_to_le16(SET_LONG_PREAMBLE);
516 break;
517
518 case cmd_type_auto_preamble:
519 default:
520 pradiocontrol->control = cpu_to_le16(SET_AUTO_PREAMBLE);
521 break;
522 }
523
524 if (adapter->radioon)
525 pradiocontrol->control |= cpu_to_le16(TURN_ON_RF);
526 else
527 pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF);
528
529 LEAVE();
530 return 0;
531}
532
533static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
534 struct cmd_ds_command *cmd,
535 u16 cmd_action, void *pdata_buf)
536{
537
538 struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp;
539
540 ENTER();
541
542 cmd->size =
543 cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) +
544 S_DS_GEN);
545 cmd->command = cpu_to_le16(cmd_802_11_rf_tx_power);
546 prtp->action = cmd_action;
547
548 lbs_pr_debug(1, "RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", cmd->size,
549 cmd->command, prtp->action);
550
551 switch (cmd_action) {
552 case cmd_act_tx_power_opt_get:
553 prtp->action = cpu_to_le16(cmd_act_get);
554 prtp->currentlevel = 0;
555 break;
556
557 case cmd_act_tx_power_opt_set_high:
558 prtp->action = cpu_to_le16(cmd_act_set);
559 prtp->currentlevel =
560 cpu_to_le16(cmd_act_tx_power_index_high);
561 break;
562
563 case cmd_act_tx_power_opt_set_mid:
564 prtp->action = cpu_to_le16(cmd_act_set);
565 prtp->currentlevel =
566 cpu_to_le16(cmd_act_tx_power_index_mid);
567 break;
568
569 case cmd_act_tx_power_opt_set_low:
570 prtp->action = cpu_to_le16(cmd_act_set);
571 prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
572 break;
573 }
574 LEAVE();
575 return 0;
576}
577
578static int wlan_cmd_802_11_rf_antenna(wlan_private * priv,
579 struct cmd_ds_command *cmd,
580 u16 cmd_action, void *pdata_buf)
581{
582 struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant;
583
584 cmd->command = cpu_to_le16(cmd_802_11_rf_antenna);
585 cmd->size =
586 cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
587 S_DS_GEN);
588
589 rant->action = cpu_to_le16(cmd_action);
590 if ((cmd_action == cmd_act_set_rx) ||
591 (cmd_action == cmd_act_set_tx)) {
592 rant->antennamode =
593 cpu_to_le16((u16) (*(u32 *) pdata_buf));
594 }
595
596 return 0;
597}
598
599static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
600 struct cmd_ds_command *cmd,
601 u16 cmd_action)
602{
603 struct cmd_ds_802_11_rate_adapt_rateset
604 *rateadapt = &cmd->params.rateset;
605 wlan_adapter *adapter = priv->adapter;
606
607 cmd->size =
608 cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset)
609 + S_DS_GEN);
610 cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset);
611
612 ENTER();
613
614 rateadapt->action = cmd_action;
615 rateadapt->enablehwauto = adapter->enablehwauto;
616 rateadapt->bitmap = adapter->ratebitmap;
617
618 LEAVE();
619 return 0;
620}
621
622static int wlan_cmd_802_11_data_rate(wlan_private * priv,
623 struct cmd_ds_command *cmd,
624 u16 cmd_action)
625{
626 struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
627 wlan_adapter *adapter = priv->adapter;
628 u16 action = cmd_action;
629
630 ENTER();
631
632 cmd->size =
633 cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
634 S_DS_GEN);
635
636 cmd->command = cpu_to_le16(cmd_802_11_data_rate);
637
638 memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate));
639
640 pdatarate->action = cpu_to_le16(cmd_action);
641
642 if (action == cmd_act_set_tx_fix_rate) {
643 pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate);
644 lbs_pr_debug(1, "Setting FW for fixed rate 0x%02X\n",
645 adapter->datarate);
646 } else if (action == cmd_act_set_tx_auto) {
647 lbs_pr_debug(1, "Setting FW for AUTO rate\n");
648 }
649
650 LEAVE();
651 return 0;
652}
653
654static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
655 struct cmd_ds_command *cmd,
656 u16 cmd_action)
657{
658 struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
659 wlan_adapter *adapter = priv->adapter;
660
661 cmd->size =
662 cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
663 S_DS_GEN);
664 cmd->command = cpu_to_le16(cmd_mac_multicast_adr);
665
666 pMCastAdr->action = cpu_to_le16(cmd_action);
667 pMCastAdr->nr_of_adrs =
668 cpu_to_le16((u16) adapter->nr_of_multicastmacaddr);
669 memcpy(pMCastAdr->maclist, adapter->multicastlist,
670 adapter->nr_of_multicastmacaddr * ETH_ALEN);
671
672 return 0;
673}
674
675static int wlan_cmd_802_11_rf_channel(wlan_private * priv,
676 struct cmd_ds_command *cmd,
677 int option, void *pdata_buf)
678{
679 struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel;
680
681 cmd->command = cpu_to_le16(cmd_802_11_rf_channel);
682 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel)
683 + S_DS_GEN);
684
685 if (option == cmd_opt_802_11_rf_channel_set) {
686 rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf));
687 }
688
689 rfchan->action = cpu_to_le16(option);
690
691 return 0;
692}
693
694static int wlan_cmd_802_11_rssi(wlan_private * priv,
695 struct cmd_ds_command *cmd)
696{
697 wlan_adapter *adapter = priv->adapter;
698
699 cmd->command = cpu_to_le16(cmd_802_11_rssi);
700 cmd->size =
701 cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
702 cmd->params.rssi.N = priv->adapter->bcn_avg_factor;
703
704 /* reset Beacon SNR/NF/RSSI values */
705 adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
706 adapter->SNR[TYPE_BEACON][TYPE_AVG] = 0;
707 adapter->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
708 adapter->NF[TYPE_BEACON][TYPE_AVG] = 0;
709 adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
710 adapter->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
711
712 return 0;
713}
714
715static int wlan_cmd_reg_access(wlan_private * priv,
716 struct cmd_ds_command *cmdptr,
717 u8 cmd_action, void *pdata_buf)
718{
719 struct wlan_offset_value *offval;
720
721 ENTER();
722
723 offval = (struct wlan_offset_value *)pdata_buf;
724
725 switch (cmdptr->command) {
726 case cmd_mac_reg_access:
727 {
728 struct cmd_ds_mac_reg_access *macreg;
729
730 cmdptr->size =
731 cpu_to_le16(sizeof
732 (struct cmd_ds_mac_reg_access)
733 + S_DS_GEN);
734 macreg =
735 (struct cmd_ds_mac_reg_access *)&cmdptr->params.
736 macreg;
737
738 macreg->action = cpu_to_le16(cmd_action);
739 macreg->offset = cpu_to_le16((u16) offval->offset);
740 macreg->value = cpu_to_le32(offval->value);
741
742 break;
743 }
744
745 case cmd_bbp_reg_access:
746 {
747 struct cmd_ds_bbp_reg_access *bbpreg;
748
749 cmdptr->size =
750 cpu_to_le16(sizeof
751 (struct cmd_ds_bbp_reg_access)
752 + S_DS_GEN);
753 bbpreg =
754 (struct cmd_ds_bbp_reg_access *)&cmdptr->params.
755 bbpreg;
756
757 bbpreg->action = cpu_to_le16(cmd_action);
758 bbpreg->offset = cpu_to_le16((u16) offval->offset);
759 bbpreg->value = (u8) offval->value;
760
761 break;
762 }
763
764 case cmd_rf_reg_access:
765 {
766 struct cmd_ds_rf_reg_access *rfreg;
767
768 cmdptr->size =
769 cpu_to_le16(sizeof
770 (struct cmd_ds_rf_reg_access) +
771 S_DS_GEN);
772 rfreg =
773 (struct cmd_ds_rf_reg_access *)&cmdptr->params.
774 rfreg;
775
776 rfreg->action = cpu_to_le16(cmd_action);
777 rfreg->offset = cpu_to_le16((u16) offval->offset);
778 rfreg->value = (u8) offval->value;
779
780 break;
781 }
782
783 default:
784 break;
785 }
786
787 LEAVE();
788 return 0;
789}
790
791static int wlan_cmd_802_11_mac_address(wlan_private * priv,
792 struct cmd_ds_command *cmd,
793 u16 cmd_action)
794{
795 wlan_adapter *adapter = priv->adapter;
796
797 cmd->command = cpu_to_le16(cmd_802_11_mac_address);
798 cmd->size =
799 cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
800 S_DS_GEN);
801 cmd->result = 0;
802
803 cmd->params.macadd.action = cpu_to_le16(cmd_action);
804
805 if (cmd_action == cmd_act_set) {
806 memcpy(cmd->params.macadd.macadd,
807 adapter->current_addr, ETH_ALEN);
808 lbs_dbg_hex("SET_CMD: MAC ADDRESS-", adapter->current_addr, 6);
809 }
810
811 return 0;
812}
813
814static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
815 struct cmd_ds_command *cmd,
816 int cmd_action, void *pdata_buf)
817{
818 struct wlan_ioctl_regrdwr *ea = pdata_buf;
819
820 ENTER();
821
822 cmd->command = cpu_to_le16(cmd_802_11_eeprom_access);
823 cmd->size =
824 cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
825 S_DS_GEN);
826 cmd->result = 0;
827
828 cmd->params.rdeeprom.action = cpu_to_le16(ea->action);
829 cmd->params.rdeeprom.offset = cpu_to_le16(ea->offset);
830 cmd->params.rdeeprom.bytecount = cpu_to_le16(ea->NOB);
831 cmd->params.rdeeprom.value = 0;
832
833 return 0;
834}
835
836static int wlan_cmd_bt_access(wlan_private * priv,
837 struct cmd_ds_command *cmd,
838 u16 cmd_action, void *pdata_buf)
839{
840 struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
841 lbs_pr_debug(1, "BT CMD(%d)\n", cmd_action);
842
843 cmd->command = cpu_to_le16(cmd_bt_access);
844 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access)
845 + S_DS_GEN);
846 cmd->result = 0;
847 bt_access->action = cpu_to_le16(cmd_action);
848
849 switch (cmd_action) {
850 case cmd_act_bt_access_add:
851 memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
852 lbs_dbg_hex("BT_ADD: blinded mac address-", bt_access->addr1, 6);
853 break;
854 case cmd_act_bt_access_del:
855 memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
856 lbs_dbg_hex("BT_DEL: blinded mac address-", bt_access->addr1, 6);
857 break;
858 case cmd_act_bt_access_list:
859 bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
860 break;
861 case cmd_act_bt_access_reset:
862 break;
863 default:
864 break;
865 }
866 return 0;
867}
868
869static int wlan_cmd_fwt_access(wlan_private * priv,
870 struct cmd_ds_command *cmd,
871 u16 cmd_action, void *pdata_buf)
872{
873 struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
874 lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
875
876 cmd->command = cpu_to_le16(cmd_fwt_access);
877 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)
878 + S_DS_GEN);
879 cmd->result = 0;
880
881 if (pdata_buf)
882 memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
883 else
884 memset(fwt_access, 0, sizeof(*fwt_access));
885
886 fwt_access->action = cpu_to_le16(cmd_action);
887
888 return 0;
889}
890
891static int wlan_cmd_mesh_access(wlan_private * priv,
892 struct cmd_ds_command *cmd,
893 u16 cmd_action, void *pdata_buf)
894{
895 struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
896 lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
897
898 cmd->command = cpu_to_le16(cmd_mesh_access);
899 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access)
900 + S_DS_GEN);
901 cmd->result = 0;
902
903 if (pdata_buf)
904 memcpy(mesh_access, pdata_buf, sizeof(*mesh_access));
905 else
906 memset(mesh_access, 0, sizeof(*mesh_access));
907
908 mesh_access->action = cpu_to_le16(cmd_action);
909
910 return 0;
911}
912
913void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
914{
915 unsigned long flags;
916 struct cmd_ds_command *cmdptr;
917
918 ENTER();
919
920 if (!cmdnode) {
921 lbs_pr_debug(1, "QUEUE_CMD: cmdnode is NULL\n");
922 goto done;
923 }
924
925 cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
926 if (!cmdptr) {
927 lbs_pr_debug(1, "QUEUE_CMD: cmdptr is NULL\n");
928 goto done;
929 }
930
931 /* Exit_PS command needs to be queued in the header always. */
932 if (cmdptr->command == cmd_802_11_ps_mode) {
933 struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
934 if (psm->action == cmd_subcmd_exit_ps) {
935 if (adapter->psstate != PS_STATE_FULL_POWER)
936 addtail = 0;
937 }
938 }
939
940 spin_lock_irqsave(&adapter->driver_lock, flags);
941
942 if (addtail)
943 list_add_tail((struct list_head *)cmdnode,
944 &adapter->cmdpendingq);
945 else
946 list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
947
948 spin_unlock_irqrestore(&adapter->driver_lock, flags);
949
950 lbs_pr_debug(1, "QUEUE_CMD: Inserted node=0x%x, cmd=0x%x in cmdpendingq\n",
951 (u32) cmdnode,
952 ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
953
954done:
955 LEAVE();
956 return;
957}
958
959/*
960 * TODO: Fix the issue when DownloadcommandToStation is being called the
961 * second time when the command timesout. All the cmdptr->xxx are in little
962 * endian and therefore all the comparissions will fail.
963 * For now - we are not performing the endian conversion the second time - but
964 * for PS and DEEP_SLEEP we need to worry
965 */
966static int DownloadcommandToStation(wlan_private * priv,
967 struct cmd_ctrl_node *cmdnode)
968{
969 unsigned long flags;
970 struct cmd_ds_command *cmdptr;
971 wlan_adapter *adapter = priv->adapter;
972 int ret = 0;
973 u16 cmdsize;
974 u16 command;
975
976 ENTER();
977
978 if (!adapter || !cmdnode) {
979 lbs_pr_debug(1, "DNLD_CMD: adapter = %#x, cmdnode = %#x\n",
980 (int)adapter, (int)cmdnode);
981 if (cmdnode) {
982 spin_lock_irqsave(&adapter->driver_lock, flags);
983 __libertas_cleanup_and_insert_cmd(priv, cmdnode);
984 spin_unlock_irqrestore(&adapter->driver_lock, flags);
985 }
986 ret = -1;
987 goto done;
988 }
989
990 cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
991
992
993 spin_lock_irqsave(&adapter->driver_lock, flags);
994 if (!cmdptr || !cmdptr->size) {
995 lbs_pr_debug(1, "DNLD_CMD: cmdptr is Null or cmd size is Zero, "
996 "Not sending\n");
997 __libertas_cleanup_and_insert_cmd(priv, cmdnode);
998 spin_unlock_irqrestore(&adapter->driver_lock, flags);
999 ret = -1;
1000 goto done;
1001 }
1002
1003 adapter->cur_cmd = cmdnode;
1004 adapter->cur_cmd_retcode = 0;
1005 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1006 lbs_pr_debug(1, "DNLD_CMD:: Before download, size of cmd = %d\n",
1007 cmdptr->size);
1008
1009 cmdsize = cmdptr->size;
1010
1011 command = cpu_to_le16(cmdptr->command);
1012
1013 cmdnode->cmdwaitqwoken = 0;
1014 cmdsize = cpu_to_le16(cmdsize);
1015
1016 ret = libertas_sbi_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
1017
1018 if (ret != 0) {
1019 lbs_pr_debug(1, "DNLD_CMD: Host to Card failed\n");
1020 spin_lock_irqsave(&adapter->driver_lock, flags);
1021 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
1022 adapter->cur_cmd = NULL;
1023 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1024 ret = -1;
1025 goto done;
1026 }
1027
1028 lbs_pr_debug(1, "DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
1029 lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize);
1030
1031 /* Setup the timer after transmit command */
1032 if (command == cmd_802_11_scan
1033 || command == cmd_802_11_authenticate
1034 || command == cmd_802_11_associate)
1035 mod_timer(&adapter->command_timer, jiffies + (10*HZ));
1036 else
1037 mod_timer(&adapter->command_timer, jiffies + (5*HZ));
1038
1039 ret = 0;
1040
1041 done:
1042 LEAVE();
1043 return ret;
1044}
1045
1046static int wlan_cmd_mac_control(wlan_private * priv,
1047 struct cmd_ds_command *cmd)
1048{
1049 struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
1050
1051 ENTER();
1052
1053 cmd->command = cpu_to_le16(cmd_mac_control);
1054 cmd->size =
1055 cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
1056 mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);
1057
1058 lbs_pr_debug(1, "wlan_cmd_mac_control(): action=0x%X size=%d\n",
1059 mac->action, cmd->size);
1060
1061 LEAVE();
1062 return 0;
1063}
1064
1065/**
1066 * This function inserts command node to cmdfreeq
1067 * after cleans it. Requires adapter->driver_lock held.
1068 */
1069void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
1070{
1071 wlan_adapter *adapter = priv->adapter;
1072
1073 if (!ptempcmd)
1074 goto done;
1075
1076 cleanup_cmdnode(ptempcmd);
1077 list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq);
1078done:
1079 return;
1080}
1081
1082void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
1083{
1084 unsigned long flags;
1085
1086 spin_lock_irqsave(&priv->adapter->driver_lock, flags);
1087 __libertas_cleanup_and_insert_cmd(priv, ptempcmd);
1088 spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
1089}
1090
1091int libertas_set_radio_control(wlan_private * priv)
1092{
1093 int ret = 0;
1094
1095 ENTER();
1096
1097 ret = libertas_prepare_and_send_command(priv,
1098 cmd_802_11_radio_control,
1099 cmd_act_set,
1100 cmd_option_waitforrsp, 0, NULL);
1101
1102 lbs_pr_debug(1, "RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
1103 priv->adapter->radioon, priv->adapter->preamble);
1104
1105 LEAVE();
1106 return ret;
1107}
1108
1109int libertas_set_mac_packet_filter(wlan_private * priv)
1110{
1111 int ret = 0;
1112
1113 ENTER();
1114
1115 lbs_pr_debug(1, "libertas_set_mac_packet_filter value = %x\n",
1116 priv->adapter->currentpacketfilter);
1117
1118 /* Send MAC control command to station */
1119 ret = libertas_prepare_and_send_command(priv,
1120 cmd_mac_control, 0, 0, 0, NULL);
1121
1122 LEAVE();
1123 return ret;
1124}
1125
1126/**
1127 * @brief This function prepare the command before send to firmware.
1128 *
1129 * @param priv A pointer to wlan_private structure
1130 * @param cmd_no command number
1131 * @param cmd_action command action: GET or SET
1132 * @param wait_option wait option: wait response or not
1133 * @param cmd_oid cmd oid: treated as sub command
1134 * @param pdata_buf A pointer to informaion buffer
1135 * @return 0 or -1
1136 */
1137int libertas_prepare_and_send_command(wlan_private * priv,
1138 u16 cmd_no,
1139 u16 cmd_action,
1140 u16 wait_option, u32 cmd_oid, void *pdata_buf)
1141{
1142 int ret = 0;
1143 wlan_adapter *adapter = priv->adapter;
1144 struct cmd_ctrl_node *cmdnode;
1145 struct cmd_ds_command *cmdptr;
1146 unsigned long flags;
1147
1148 ENTER();
1149
1150 if (!adapter) {
1151 lbs_pr_debug(1, "PREP_CMD: adapter is Null\n");
1152 ret = -1;
1153 goto done;
1154 }
1155
1156 if (adapter->surpriseremoved) {
1157 lbs_pr_debug(1, "PREP_CMD: Card is Removed\n");
1158 ret = -1;
1159 goto done;
1160 }
1161
1162 cmdnode = libertas_get_free_cmd_ctrl_node(priv);
1163
1164 if (cmdnode == NULL) {
1165 lbs_pr_debug(1, "PREP_CMD: No free cmdnode\n");
1166
1167 /* Wake up main thread to execute next command */
1168 wake_up_interruptible(&priv->mainthread.waitq);
1169 ret = -1;
1170 goto done;
1171 }
1172
1173 libertas_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf);
1174
1175 cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
1176
1177 lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr =0x%x, command=0x%X\n",
1178 (u32) cmdptr, cmd_no);
1179
1180 if (!cmdptr) {
1181 lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
1182 libertas_cleanup_and_insert_cmd(priv, cmdnode);
1183 ret = -1;
1184 goto done;
1185 }
1186
1187 /* Set sequence number, command and INT option */
1188 adapter->seqnum++;
1189 cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
1190
1191 cmdptr->command = cmd_no;
1192 cmdptr->result = 0;
1193
1194 switch (cmd_no) {
1195 case cmd_get_hw_spec:
1196 ret = wlan_cmd_hw_spec(priv, cmdptr);
1197 break;
1198 case cmd_802_11_ps_mode:
1199 ret = wlan_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
1200 break;
1201
1202 case cmd_802_11_scan:
1203 ret = libertas_cmd_80211_scan(priv, cmdptr, pdata_buf);
1204 break;
1205
1206 case cmd_mac_control:
1207 ret = wlan_cmd_mac_control(priv, cmdptr);
1208 break;
1209
1210 case cmd_802_11_associate:
1211 case cmd_802_11_reassociate:
1212 ret = libertas_cmd_80211_associate(priv, cmdptr, pdata_buf);
1213 break;
1214
1215 case cmd_802_11_deauthenticate:
1216 ret = libertas_cmd_80211_deauthenticate(priv, cmdptr);
1217 break;
1218
1219 case cmd_802_11_set_wep:
1220 ret = wlan_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf);
1221 break;
1222
1223 case cmd_802_11_ad_hoc_start:
1224 ret = libertas_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
1225 break;
1226 case cmd_code_dnld:
1227 break;
1228
1229 case cmd_802_11_reset:
1230 ret = wlan_cmd_802_11_reset(priv, cmdptr, cmd_action);
1231 break;
1232
1233 case cmd_802_11_get_log:
1234 ret = wlan_cmd_802_11_get_log(priv, cmdptr);
1235 break;
1236
1237 case cmd_802_11_authenticate:
1238 ret = libertas_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1239 break;
1240
1241 case cmd_802_11_get_stat:
1242 ret = wlan_cmd_802_11_get_stat(priv, cmdptr);
1243 break;
1244
1245 case cmd_802_11_snmp_mib:
1246 ret = wlan_cmd_802_11_snmp_mib(priv, cmdptr,
1247 cmd_action, cmd_oid, pdata_buf);
1248 break;
1249
1250 case cmd_mac_reg_access:
1251 case cmd_bbp_reg_access:
1252 case cmd_rf_reg_access:
1253 ret = wlan_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
1254 break;
1255
1256 case cmd_802_11_rf_channel:
1257 ret = wlan_cmd_802_11_rf_channel(priv, cmdptr,
1258 cmd_action, pdata_buf);
1259 break;
1260
1261 case cmd_802_11_rf_tx_power:
1262 ret = wlan_cmd_802_11_rf_tx_power(priv, cmdptr,
1263 cmd_action, pdata_buf);
1264 break;
1265
1266 case cmd_802_11_radio_control:
1267 ret = wlan_cmd_802_11_radio_control(priv, cmdptr, cmd_action);
1268 break;
1269
1270 case cmd_802_11_rf_antenna:
1271 ret = wlan_cmd_802_11_rf_antenna(priv, cmdptr,
1272 cmd_action, pdata_buf);
1273 break;
1274
1275 case cmd_802_11_data_rate:
1276 ret = wlan_cmd_802_11_data_rate(priv, cmdptr, cmd_action);
1277 break;
1278 case cmd_802_11_rate_adapt_rateset:
1279 ret = wlan_cmd_802_11_rate_adapt_rateset(priv,
1280 cmdptr, cmd_action);
1281 break;
1282
1283 case cmd_mac_multicast_adr:
1284 ret = wlan_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
1285 break;
1286
1287 case cmd_802_11_ad_hoc_join:
1288 ret = libertas_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
1289 break;
1290
1291 case cmd_802_11_rssi:
1292 ret = wlan_cmd_802_11_rssi(priv, cmdptr);
1293 break;
1294
1295 case cmd_802_11_ad_hoc_stop:
1296 ret = libertas_cmd_80211_ad_hoc_stop(priv, cmdptr);
1297 break;
1298
1299 case cmd_802_11_enable_rsn:
1300 ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action);
1301 break;
1302
1303 case cmd_802_11_key_material:
1304 ret = wlan_cmd_802_11_key_material(priv, cmdptr,
1305 cmd_action, cmd_oid,
1306 pdata_buf);
1307 break;
1308
1309 case cmd_802_11_pairwise_tsc:
1310 break;
1311 case cmd_802_11_group_tsc:
1312 break;
1313
1314 case cmd_802_11_mac_address:
1315 ret = wlan_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
1316 break;
1317
1318 case cmd_802_11_eeprom_access:
1319 ret = wlan_cmd_802_11_eeprom_access(priv, cmdptr,
1320 cmd_action, pdata_buf);
1321 break;
1322
1323 case cmd_802_11_set_afc:
1324 case cmd_802_11_get_afc:
1325
1326 cmdptr->command = cpu_to_le16(cmd_no);
1327 cmdptr->size =
1328 cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
1329 S_DS_GEN);
1330
1331 memmove(&cmdptr->params.afc,
1332 pdata_buf, sizeof(struct cmd_ds_802_11_afc));
1333
1334 ret = 0;
1335 goto done;
1336
1337 case cmd_802_11d_domain_info:
1338 ret = libertas_cmd_802_11d_domain_info(priv, cmdptr,
1339 cmd_no, cmd_action);
1340 break;
1341
1342 case cmd_802_11_sleep_params:
1343 ret = wlan_cmd_802_11_sleep_params(priv, cmdptr, cmd_action);
1344 break;
1345 case cmd_802_11_inactivity_timeout:
1346 ret = wlan_cmd_802_11_inactivity_timeout(priv, cmdptr,
1347 cmd_action, pdata_buf);
1348 libertas_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf);
1349 break;
1350
1351 case cmd_802_11_tpc_cfg:
1352 cmdptr->command = cpu_to_le16(cmd_802_11_tpc_cfg);
1353 cmdptr->size =
1354 cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
1355 S_DS_GEN);
1356
1357 memmove(&cmdptr->params.tpccfg,
1358 pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg));
1359
1360 ret = 0;
1361 break;
1362 case cmd_802_11_led_gpio_ctrl:
1363 {
1364 struct mrvlietypes_ledgpio *gpio =
1365 (struct mrvlietypes_ledgpio*)
1366 cmdptr->params.ledgpio.data;
1367
1368 memmove(&cmdptr->params.ledgpio,
1369 pdata_buf,
1370 sizeof(struct cmd_ds_802_11_led_ctrl));
1371
1372 cmdptr->command =
1373 cpu_to_le16(cmd_802_11_led_gpio_ctrl);
1374
1375#define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
1376 cmdptr->size =
1377 cpu_to_le16(gpio->header.len + S_DS_GEN +
1378 ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
1379 gpio->header.len = cpu_to_le16(gpio->header.len);
1380
1381 ret = 0;
1382 break;
1383 }
1384 case cmd_802_11_pwr_cfg:
1385 cmdptr->command = cpu_to_le16(cmd_802_11_pwr_cfg);
1386 cmdptr->size =
1387 cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) +
1388 S_DS_GEN);
1389 memmove(&cmdptr->params.pwrcfg, pdata_buf,
1390 sizeof(struct cmd_ds_802_11_pwr_cfg));
1391
1392 ret = 0;
1393 break;
1394 case cmd_bt_access:
1395 ret = wlan_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
1396 break;
1397
1398 case cmd_fwt_access:
1399 ret = wlan_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
1400 break;
1401
1402 case cmd_mesh_access:
1403 ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
1404 break;
1405
1406 case cmd_get_tsf:
1407 cmdptr->command = cpu_to_le16(cmd_get_tsf);
1408 cmdptr->size =
1409 cpu_to_le16(sizeof(struct cmd_ds_get_tsf)
1410 + S_DS_GEN);
1411 ret = 0;
1412 break;
1413 case cmd_802_11_tx_rate_query:
1414 cmdptr->command =
1415 cpu_to_le16(cmd_802_11_tx_rate_query);
1416 cmdptr->size =
1417 cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
1418 S_DS_GEN);
1419 adapter->txrate = 0;
1420 ret = 0;
1421 break;
1422 default:
1423 lbs_pr_debug(1, "PREP_CMD: unknown command- %#x\n", cmd_no);
1424 ret = -1;
1425 break;
1426 }
1427
1428 /* return error, since the command preparation failed */
1429 if (ret != 0) {
1430 lbs_pr_debug(1, "PREP_CMD: command preparation failed\n");
1431 libertas_cleanup_and_insert_cmd(priv, cmdnode);
1432 ret = -1;
1433 goto done;
1434 }
1435
1436 cmdnode->cmdwaitqwoken = 0;
1437
1438 libertas_queue_cmd(adapter, cmdnode, 1);
1439 adapter->nr_cmd_pending++;
1440 wake_up_interruptible(&priv->mainthread.waitq);
1441
1442 if (wait_option & cmd_option_waitforrsp) {
1443 lbs_pr_debug(1, "PREP_CMD: Wait for CMD response\n");
1444 might_sleep();
1445 wait_event_interruptible(cmdnode->cmdwait_q,
1446 cmdnode->cmdwaitqwoken);
1447 }
1448
1449 spin_lock_irqsave(&adapter->driver_lock, flags);
1450 if (adapter->cur_cmd_retcode) {
1451 lbs_pr_debug(1, "PREP_CMD: command failed with return code=%d\n",
1452 adapter->cur_cmd_retcode);
1453 adapter->cur_cmd_retcode = 0;
1454 ret = -1;
1455 }
1456 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1457
1458done:
1459 LEAVE();
1460 return ret;
1461}
1462
1463/**
1464 * @brief This function allocates the command buffer and link
1465 * it to command free queue.
1466 *
1467 * @param priv A pointer to wlan_private structure
1468 * @return 0 or -1
1469 */
1470int libertas_allocate_cmd_buffer(wlan_private * priv)
1471{
1472 int ret = 0;
1473 u32 ulbufsize;
1474 u32 i;
1475 struct cmd_ctrl_node *tempcmd_array;
1476 u8 *ptempvirtualaddr;
1477 wlan_adapter *adapter = priv->adapter;
1478
1479 ENTER();
1480
1481 /* Allocate and initialize cmdCtrlNode */
1482 ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
1483
1484 if (!(tempcmd_array = kmalloc(ulbufsize, GFP_KERNEL))) {
1485 lbs_pr_debug(1,
1486 "ALLOC_CMD_BUF: failed to allocate tempcmd_array\n");
1487 ret = -1;
1488 goto done;
1489 }
1490
1491 adapter->cmd_array = tempcmd_array;
1492 memset(adapter->cmd_array, 0, ulbufsize);
1493
1494 /* Allocate and initialize command buffers */
1495 ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
1496 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
1497 if (!(ptempvirtualaddr = kmalloc(ulbufsize, GFP_KERNEL))) {
1498 lbs_pr_debug(1,
1499 "ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n");
1500 ret = -1;
1501 goto done;
1502 }
1503
1504 memset(ptempvirtualaddr, 0, ulbufsize);
1505
1506 /* Update command buffer virtual */
1507 tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
1508 }
1509
1510 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
1511 init_waitqueue_head(&tempcmd_array[i].cmdwait_q);
1512 libertas_cleanup_and_insert_cmd(priv, &tempcmd_array[i]);
1513 }
1514
1515 ret = 0;
1516 done:
1517 LEAVE();
1518 return ret;
1519}
1520
1521/**
1522 * @brief This function frees the command buffer.
1523 *
1524 * @param priv A pointer to wlan_private structure
1525 * @return 0 or -1
1526 */
1527int libertas_free_cmd_buffer(wlan_private * priv)
1528{
1529 u32 ulbufsize;
1530 unsigned int i;
1531 struct cmd_ctrl_node *tempcmd_array;
1532 wlan_adapter *adapter = priv->adapter;
1533
1534 ENTER();
1535
1536 /* need to check if cmd array is allocated or not */
1537 if (adapter->cmd_array == NULL) {
1538 lbs_pr_debug(1, "FREE_CMD_BUF: cmd_array is Null\n");
1539 goto done;
1540 }
1541
1542 tempcmd_array = adapter->cmd_array;
1543
1544 /* Release shared memory buffers */
1545 ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
1546 for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
1547 if (tempcmd_array[i].bufvirtualaddr) {
1548 lbs_pr_debug(1, "Free all the array\n");
1549 kfree(tempcmd_array[i].bufvirtualaddr);
1550 tempcmd_array[i].bufvirtualaddr = NULL;
1551 }
1552 }
1553
1554 /* Release cmd_ctrl_node */
1555 if (adapter->cmd_array) {
1556 lbs_pr_debug(1, "Free cmd_array\n");
1557 kfree(adapter->cmd_array);
1558 adapter->cmd_array = NULL;
1559 }
1560
1561done:
1562 LEAVE();
1563 return 0;
1564}
1565
1566/**
1567 * @brief This function gets a free command node if available in
1568 * command free queue.
1569 *
1570 * @param priv A pointer to wlan_private structure
1571 * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
1572 */
1573struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
1574{
1575 struct cmd_ctrl_node *tempnode;
1576 wlan_adapter *adapter = priv->adapter;
1577 unsigned long flags;
1578
1579 if (!adapter)
1580 return NULL;
1581
1582 spin_lock_irqsave(&adapter->driver_lock, flags);
1583
1584 if (!list_empty(&adapter->cmdfreeq)) {
1585 tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
1586 list_del((struct list_head *)tempnode);
1587 } else {
1588 lbs_pr_debug(1, "GET_CMD_NODE: cmd_ctrl_node is not available\n");
1589 tempnode = NULL;
1590 }
1591
1592 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1593
1594 if (tempnode) {
1595 lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode available\n");
1596 lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode Address = %p\n",
1597 tempnode);
1598 cleanup_cmdnode(tempnode);
1599 }
1600
1601 return tempnode;
1602}
1603
1604/**
1605 * @brief This function cleans command node.
1606 *
1607 * @param ptempnode A pointer to cmdCtrlNode structure
1608 * @return n/a
1609 */
1610static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
1611{
1612 if (!ptempnode)
1613 return;
1614 ptempnode->cmdwaitqwoken = 1;
1615 wake_up_interruptible(&ptempnode->cmdwait_q);
1616 ptempnode->status = 0;
1617 ptempnode->cmd_oid = (u32) 0;
1618 ptempnode->wait_option = 0;
1619 ptempnode->pdata_buf = NULL;
1620
1621 if (ptempnode->bufvirtualaddr != NULL)
1622 memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
1623 return;
1624}
1625
1626/**
1627 * @brief This function initializes the command node.
1628 *
1629 * @param priv A pointer to wlan_private structure
1630 * @param ptempnode A pointer to cmd_ctrl_node structure
1631 * @param cmd_oid cmd oid: treated as sub command
1632 * @param wait_option wait option: wait response or not
1633 * @param pdata_buf A pointer to informaion buffer
1634 * @return 0 or -1
1635 */
1636void libertas_set_cmd_ctrl_node(wlan_private * priv,
1637 struct cmd_ctrl_node *ptempnode,
1638 u32 cmd_oid, u16 wait_option, void *pdata_buf)
1639{
1640 ENTER();
1641
1642 if (!ptempnode)
1643 return;
1644
1645 ptempnode->cmd_oid = cmd_oid;
1646 ptempnode->wait_option = wait_option;
1647 ptempnode->pdata_buf = pdata_buf;
1648
1649 LEAVE();
1650}
1651
1652/**
1653 * @brief This function executes next command in command
1654 * pending queue. It will put fimware back to PS mode
1655 * if applicable.
1656 *
1657 * @param priv A pointer to wlan_private structure
1658 * @return 0 or -1
1659 */
1660int libertas_execute_next_command(wlan_private * priv)
1661{
1662 wlan_adapter *adapter = priv->adapter;
1663 struct cmd_ctrl_node *cmdnode = NULL;
1664 struct cmd_ds_command *cmdptr;
1665 unsigned long flags;
1666 int ret = 0;
1667
1668 lbs_pr_debug(1, "libertas_execute_next_command\n");
1669
1670 spin_lock_irqsave(&adapter->driver_lock, flags);
1671
1672 if (adapter->cur_cmd) {
1673 lbs_pr_alert( "EXEC_NEXT_CMD: there is command in processing!\n");
1674 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1675 ret = -1;
1676 goto done;
1677 }
1678
1679 if (!list_empty(&adapter->cmdpendingq)) {
1680 cmdnode = (struct cmd_ctrl_node *)
1681 adapter->cmdpendingq.next;
1682 }
1683
1684 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1685
1686 if (cmdnode) {
1687 lbs_pr_debug(1,
1688 "EXEC_NEXT_CMD: Got next command from cmdpendingq\n");
1689 cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
1690
1691 if (is_command_allowed_in_ps(cmdptr->command)) {
1692 if ((adapter->psstate == PS_STATE_SLEEP)
1693 || (adapter->psstate == PS_STATE_PRE_SLEEP)
1694 ) {
1695 lbs_pr_debug(1,
1696 "EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n",
1697 cmdptr->command, adapter->psstate);
1698 ret = -1;
1699 goto done;
1700 }
1701 lbs_pr_debug(1, "EXEC_NEXT_CMD: OK to send command "
1702 "0x%x in psstate %d\n",
1703 cmdptr->command, adapter->psstate);
1704 } else if (adapter->psstate != PS_STATE_FULL_POWER) {
1705 /*
1706 * 1. Non-PS command:
1707 * Queue it. set needtowakeup to TRUE if current state
1708 * is SLEEP, otherwise call libertas_ps_wakeup to send Exit_PS.
1709 * 2. PS command but not Exit_PS:
1710 * Ignore it.
1711 * 3. PS command Exit_PS:
1712 * Set needtowakeup to TRUE if current state is SLEEP,
1713 * otherwise send this command down to firmware
1714 * immediately.
1715 */
1716 if (cmdptr->command !=
1717 cpu_to_le16(cmd_802_11_ps_mode)) {
1718 /* Prepare to send Exit PS,
1719 * this non PS command will be sent later */
1720 if ((adapter->psstate == PS_STATE_SLEEP)
1721 || (adapter->psstate == PS_STATE_PRE_SLEEP)
1722 ) {
1723 /* w/ new scheme, it will not reach here.
1724 since it is blocked in main_thread. */
1725 adapter->needtowakeup = 1;
1726 } else
1727 libertas_ps_wakeup(priv, 0);
1728
1729 ret = 0;
1730 goto done;
1731 } else {
1732 /*
1733 * PS command. Ignore it if it is not Exit_PS.
1734 * otherwise send it down immediately.
1735 */
1736 struct cmd_ds_802_11_ps_mode *psm =
1737 &cmdptr->params.psmode;
1738
1739 lbs_pr_debug(1,
1740 "EXEC_NEXT_CMD: PS cmd- action=0x%x\n",
1741 psm->action);
1742 if (psm->action !=
1743 cpu_to_le16(cmd_subcmd_exit_ps)) {
1744 lbs_pr_debug(1,
1745 "EXEC_NEXT_CMD: Ignore Enter PS cmd\n");
1746 list_del((struct list_head *)cmdnode);
1747 libertas_cleanup_and_insert_cmd(priv, cmdnode);
1748
1749 ret = 0;
1750 goto done;
1751 }
1752
1753 if ((adapter->psstate == PS_STATE_SLEEP)
1754 || (adapter->psstate == PS_STATE_PRE_SLEEP)
1755 ) {
1756 lbs_pr_debug(1,
1757 "EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n");
1758 list_del((struct list_head *)cmdnode);
1759 libertas_cleanup_and_insert_cmd(priv, cmdnode);
1760 adapter->needtowakeup = 1;
1761
1762 ret = 0;
1763 goto done;
1764 }
1765
1766 lbs_pr_debug(1,
1767 "EXEC_NEXT_CMD: Sending Exit_PS down...\n");
1768 }
1769 }
1770 list_del((struct list_head *)cmdnode);
1771 lbs_pr_debug(1, "EXEC_NEXT_CMD: Sending 0x%04X command\n",
1772 cmdptr->command);
1773 DownloadcommandToStation(priv, cmdnode);
1774 } else {
1775 /*
1776 * check if in power save mode, if yes, put the device back
1777 * to PS mode
1778 */
1779 if ((adapter->psmode != wlan802_11powermodecam) &&
1780 (adapter->psstate == PS_STATE_FULL_POWER) &&
1781 (adapter->connect_status == libertas_connected)) {
1782 if (adapter->secinfo.WPAenabled
1783 || adapter->secinfo.WPA2enabled) {
1784 /* check for valid WPA group keys */
1785 if (adapter->wpa_mcast_key.len
1786 || adapter->wpa_unicast_key.len) {
1787 lbs_pr_debug(1,
1788 "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1789 " go back to PS_SLEEP");
1790 libertas_ps_sleep(priv, 0);
1791 }
1792 } else {
1793 lbs_pr_debug(1,
1794 "EXEC_NEXT_CMD: command PendQ is empty,"
1795 " go back to PS_SLEEP");
1796 libertas_ps_sleep(priv, 0);
1797 }
1798 }
1799 }
1800
1801 ret = 0;
1802done:
1803 return ret;
1804}
1805
1806void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
1807{
1808 union iwreq_data iwrq;
1809 u8 buf[50];
1810
1811 ENTER();
1812
1813 memset(&iwrq, 0, sizeof(union iwreq_data));
1814 memset(buf, 0, sizeof(buf));
1815
1816 snprintf(buf, sizeof(buf) - 1, "%s", str);
1817
1818 iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
1819
1820 /* Send Event to upper layer */
1821 lbs_pr_debug(1, "Event Indication string = %s\n",
1822 (char *)buf);
1823 lbs_pr_debug(1, "Event Indication String length = %d\n", iwrq.data.length);
1824
1825 lbs_pr_debug(1, "Sending wireless event IWEVCUSTOM for %s\n", str);
1826 wireless_send_event(priv->wlan_dev.netdev, IWEVCUSTOM, &iwrq, buf);
1827
1828 LEAVE();
1829 return;
1830}
1831
1832static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
1833{
1834 unsigned long flags;
1835 wlan_adapter *adapter = priv->adapter;
1836 int ret = 0;
1837
1838 ENTER();
1839
1840 lbs_pr_debug(1, "SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
1841 size);
1842
1843 lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size);
1844
1845 ret = libertas_sbi_host_to_card(priv, MVMS_CMD, cmdptr, size);
1846 priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
1847
1848 spin_lock_irqsave(&adapter->driver_lock, flags);
1849 if (adapter->intcounter || adapter->currenttxskb)
1850 lbs_pr_debug(1, "SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
1851 adapter->intcounter, adapter->currenttxskb);
1852 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1853
1854 if (ret) {
1855 lbs_pr_alert(
1856 "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");
1857 } else {
1858 spin_lock_irqsave(&adapter->driver_lock, flags);
1859 if (!adapter->intcounter) {
1860 adapter->psstate = PS_STATE_SLEEP;
1861 } else {
1862 lbs_pr_debug(1, "SEND_SLEEPC_CMD: After sent,IntC=%d\n",
1863 adapter->intcounter);
1864 }
1865 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1866
1867 lbs_pr_debug(1, "SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
1868 lbs_pr_debug(1, "+");
1869 }
1870
1871 LEAVE();
1872 return ret;
1873}
1874
1875void libertas_ps_sleep(wlan_private * priv, int wait_option)
1876{
1877
1878 ENTER();
1879
1880 /*
1881 * PS is currently supported only in Infrastructure mode
1882 * Remove this check if it is to be supported in IBSS mode also
1883 */
1884
1885 libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
1886 cmd_subcmd_enter_ps, wait_option, 0, NULL);
1887
1888 LEAVE();
1889 return;
1890}
1891
1892/**
1893 * @brief This function sends Eixt_PS command to firmware.
1894 *
1895 * @param priv A pointer to wlan_private structure
1896 * @param wait_option wait response or not
1897 * @return n/a
1898 */
1899void libertas_ps_wakeup(wlan_private * priv, int wait_option)
1900{
1901 enum WLAN_802_11_POWER_MODE Localpsmode;
1902
1903 ENTER();
1904
1905 Localpsmode = wlan802_11powermodecam;
1906
1907 lbs_pr_debug(1, "Exit_PS: Localpsmode = %d\n", Localpsmode);
1908
1909 libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
1910 cmd_subcmd_exit_ps,
1911 wait_option, 0, &Localpsmode);
1912
1913 LEAVE();
1914 return;
1915}
1916
1917/**
1918 * @brief This function checks condition and prepares to
1919 * send sleep confirm command to firmware if ok.
1920 *
1921 * @param priv A pointer to wlan_private structure
1922 * @param psmode Power Saving mode
1923 * @return n/a
1924 */
1925void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
1926{
1927 unsigned long flags =0;
1928 wlan_adapter *adapter = priv->adapter;
1929 u8 allowed = 1;
1930
1931 ENTER();
1932
1933 if (priv->wlan_dev.dnld_sent) {
1934 allowed = 0;
1935 lbs_pr_debug(1, "D");
1936 }
1937
1938 spin_lock_irqsave(&adapter->driver_lock, flags);
1939 if (adapter->cur_cmd) {
1940 allowed = 0;
1941 lbs_pr_debug(1, "C");
1942 }
1943 if (adapter->intcounter > 0) {
1944 allowed = 0;
1945 lbs_pr_debug(1, "I%d", adapter->intcounter);
1946 }
1947 spin_unlock_irqrestore(&adapter->driver_lock, flags);
1948
1949 if (allowed) {
1950 lbs_pr_debug(1, "Sending libertas_ps_confirm_sleep\n");
1951 sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,
1952 sizeof(struct PS_CMD_ConfirmSleep));
1953 } else {
1954 lbs_pr_debug(1, "Sleep Confirm has been delayed\n");
1955 }
1956
1957 LEAVE();
1958}
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
new file mode 100644
index 000000000000..cdb012c7e9cf
--- /dev/null
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -0,0 +1,1031 @@
1/**
2 * This file contains the handling of command
3 * responses as well as events generated by firmware.
4 */
5#include <linux/delay.h>
6#include <linux/if_arp.h>
7#include <linux/netdevice.h>
8
9#include <net/iw_handler.h>
10
11#include "host.h"
12#include "sbi.h"
13#include "decl.h"
14#include "defs.h"
15#include "dev.h"
16#include "join.h"
17#include "wext.h"
18
19/**
20 * @brief This function handles disconnect event. it
21 * reports disconnect to upper layer, clean tx/rx packets,
22 * reset link state etc.
23 *
24 * @param priv A pointer to wlan_private structure
25 * @return n/a
26 */
27void libertas_mac_event_disconnected(wlan_private * priv)
28{
29 wlan_adapter *adapter = priv->adapter;
30 union iwreq_data wrqu;
31
32 if (adapter->connect_status != libertas_connected)
33 return;
34
35 lbs_pr_debug(1, "Handles disconnect event.\n");
36
37 memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
38 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
39
40 /*
41 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
42 * It causes problem in the Supplicant
43 */
44
45 msleep_interruptible(1000);
46 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
47
48 /* Free Tx and Rx packets */
49 kfree_skb(priv->adapter->currenttxskb);
50 priv->adapter->currenttxskb = NULL;
51
52 /* report disconnect to upper layer */
53 netif_stop_queue(priv->wlan_dev.netdev);
54 netif_carrier_off(priv->wlan_dev.netdev);
55
56 /* reset SNR/NF/RSSI values */
57 memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
58 memset(adapter->NF, 0x00, sizeof(adapter->NF));
59 memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI));
60 memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
61 memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
62 adapter->nextSNRNF = 0;
63 adapter->numSNRNF = 0;
64 adapter->rxpd_rate = 0;
65 lbs_pr_debug(1, "Current SSID=%s, ssid length=%u\n",
66 adapter->curbssparams.ssid.ssid,
67 adapter->curbssparams.ssid.ssidlength);
68 lbs_pr_debug(1, "Previous SSID=%s, ssid length=%u\n",
69 adapter->previousssid.ssid, adapter->previousssid.ssidlength);
70
71 /* reset internal flags */
72 adapter->secinfo.WPAenabled = 0;
73 adapter->secinfo.WPA2enabled = 0;
74 adapter->wpa_ie_len = 0;
75 adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
76 adapter->secinfo.Encryptionmode = CIPHER_NONE;
77
78 adapter->connect_status = libertas_disconnected;
79
80 /*
81 * memorize the previous SSID and BSSID
82 * it could be used for re-assoc
83 */
84 memcpy(&adapter->previousssid,
85 &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID));
86 memcpy(adapter->previousbssid,
87 adapter->curbssparams.bssid, ETH_ALEN);
88
89 /* need to erase the current SSID and BSSID info */
90 adapter->pattemptedbssdesc = NULL;
91 memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
92
93 if (adapter->psstate != PS_STATE_FULL_POWER) {
94 /* make firmware to exit PS mode */
95 lbs_pr_debug(1, "Disconnected, so exit PS mode.\n");
96 libertas_ps_wakeup(priv, 0);
97 }
98}
99
100/**
101 * @brief This function handles MIC failure event.
102 *
103 * @param priv A pointer to wlan_private structure
104 * @para event the event id
105 * @return n/a
106 */
107static void handle_mic_failureevent(wlan_private * priv, u32 event)
108{
109 char buf[50];
110
111 memset(buf, 0, sizeof(buf));
112
113 sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
114
115 if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) {
116 strcat(buf, "unicast ");
117 } else {
118 strcat(buf, "multicast ");
119 }
120
121 libertas_send_iwevcustom_event(priv, buf);
122}
123
124static int wlan_ret_reg_access(wlan_private * priv,
125 u16 type, struct cmd_ds_command *resp)
126{
127 wlan_adapter *adapter = priv->adapter;
128
129 ENTER();
130
131 switch (type) {
132 case cmd_ret_mac_reg_access:
133 {
134 struct cmd_ds_mac_reg_access *reg;
135
136 reg =
137 (struct cmd_ds_mac_reg_access *)&resp->params.
138 macreg;
139
140 adapter->offsetvalue.offset = reg->offset;
141 adapter->offsetvalue.value = reg->value;
142 break;
143 }
144
145 case cmd_ret_bbp_reg_access:
146 {
147 struct cmd_ds_bbp_reg_access *reg;
148 reg =
149 (struct cmd_ds_bbp_reg_access *)&resp->params.
150 bbpreg;
151
152 adapter->offsetvalue.offset = reg->offset;
153 adapter->offsetvalue.value = reg->value;
154 break;
155 }
156
157 case cmd_ret_rf_reg_access:
158 {
159 struct cmd_ds_rf_reg_access *reg;
160 reg =
161 (struct cmd_ds_rf_reg_access *)&resp->params.
162 rfreg;
163
164 adapter->offsetvalue.offset = reg->offset;
165 adapter->offsetvalue.value = reg->value;
166 break;
167 }
168
169 default:
170 LEAVE();
171 return -1;
172 }
173
174 LEAVE();
175 return 0;
176}
177
178static int wlan_ret_get_hw_spec(wlan_private * priv,
179 struct cmd_ds_command *resp)
180{
181 u32 i;
182 struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec;
183 wlan_adapter *adapter = priv->adapter;
184 int ret = 0;
185
186 ENTER();
187
188 adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
189
190 adapter->fwreleasenumber = hwspec->fwreleasenumber;
191
192 lbs_pr_debug(1, "GET_HW_SPEC: FWReleaseVersion- 0x%X\n",
193 adapter->fwreleasenumber);
194 lbs_pr_debug(1, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
195 hwspec->permanentaddr[0], hwspec->permanentaddr[1],
196 hwspec->permanentaddr[2], hwspec->permanentaddr[3],
197 hwspec->permanentaddr[4], hwspec->permanentaddr[5]);
198 lbs_pr_debug(1, "GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
199 hwspec->hwifversion, hwspec->version);
200
201 adapter->regioncode = le16_to_cpu(hwspec->regioncode);
202
203 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
204 /* use the region code to search for the index */
205 if (adapter->regioncode == libertas_region_code_to_index[i]) {
206 adapter->regiontableindex = (u16) i;
207 break;
208 }
209 }
210
211 /* if it's unidentified region code, use the default (USA) */
212 if (i >= MRVDRV_MAX_REGION_CODE) {
213 adapter->regioncode = 0x10;
214 adapter->regiontableindex = 0;
215 lbs_pr_info(
216 "unidentified region code, use the default (USA)\n");
217 }
218
219 if (adapter->current_addr[0] == 0xff) {
220 memmove(adapter->current_addr, hwspec->permanentaddr,
221 ETH_ALEN);
222 }
223
224 memcpy(priv->wlan_dev.netdev->dev_addr, adapter->current_addr, ETH_ALEN);
225 memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
226
227 if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
228 ret = -1;
229 goto done;
230 }
231
232 if (libertas_set_universaltable(priv, 0)) {
233 ret = -1;
234 goto done;
235 }
236
237 done:
238 LEAVE();
239 return ret;
240}
241
242static int wlan_ret_802_11_sleep_params(wlan_private * priv,
243 struct cmd_ds_command *resp)
244{
245 struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
246 wlan_adapter *adapter = priv->adapter;
247
248 ENTER();
249
250 lbs_pr_debug(1, "error=%x offset=%x stabletime=%x calcontrol=%x\n"
251 " extsleepclk=%x\n", sp->error, sp->offset,
252 sp->stabletime, sp->calcontrol, sp->externalsleepclk);
253 adapter->sp.sp_error = le16_to_cpu(sp->error);
254 adapter->sp.sp_offset = le16_to_cpu(sp->offset);
255 adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
256 adapter->sp.sp_calcontrol = le16_to_cpu(sp->calcontrol);
257 adapter->sp.sp_extsleepclk = le16_to_cpu(sp->externalsleepclk);
258 adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
259
260 LEAVE();
261 return 0;
262}
263
264static int wlan_ret_802_11_stat(wlan_private * priv,
265 struct cmd_ds_command *resp)
266{
267/* currently adapter->wlan802_11Stat is unused
268
269 struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
270 wlan_adapter *adapter = priv->adapter;
271
272 // TODO Convert it to Big endian befor copy
273 memcpy(&adapter->wlan802_11Stat,
274 p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
275*/
276 return 0;
277}
278
279static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
280 struct cmd_ds_command *resp)
281{
282 struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
283 u16 oid = le16_to_cpu(smib->oid);
284 u16 querytype = le16_to_cpu(smib->querytype);
285
286 ENTER();
287
288 lbs_pr_debug(1, "SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
289 querytype);
290 lbs_pr_debug(1, "SNMP_RESP: Buf size = %x\n",
291 le16_to_cpu(smib->bufsize));
292
293 if (querytype == cmd_act_get) {
294 switch (oid) {
295 case fragthresh_i:
296 priv->adapter->fragthsd =
297 le16_to_cpu(*
298 ((unsigned short *)(smib->value)));
299 lbs_pr_debug(1, "SNMP_RESP: fragthsd =%u\n",
300 priv->adapter->fragthsd);
301 break;
302 case rtsthresh_i:
303 priv->adapter->rtsthsd =
304 le16_to_cpu(*
305 ((unsigned short *)(smib->value)));
306 lbs_pr_debug(1, "SNMP_RESP: rtsthsd =%u\n",
307 priv->adapter->rtsthsd);
308 break;
309 case short_retrylim_i:
310 priv->adapter->txretrycount =
311 le16_to_cpu(*
312 ((unsigned short *)(smib->value)));
313 lbs_pr_debug(1, "SNMP_RESP: txretrycount =%u\n",
314 priv->adapter->rtsthsd);
315 break;
316 default:
317 break;
318 }
319 }
320
321 LEAVE();
322 return 0;
323}
324
325static int wlan_ret_802_11_key_material(wlan_private * priv,
326 struct cmd_ds_command *resp)
327{
328 struct cmd_ds_802_11_key_material *pkeymaterial =
329 &resp->params.keymaterial;
330 wlan_adapter *adapter = priv->adapter;
331 u16 action = le16_to_cpu(pkeymaterial->action);
332
333 ENTER();
334
335 /* Copy the returned key to driver private data */
336 if (action == cmd_act_get) {
337 u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet;
338 u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size));
339
340 while (buf_ptr < resp_end) {
341 struct MrvlIEtype_keyParamSet * pkeyparamset =
342 (struct MrvlIEtype_keyParamSet *) buf_ptr;
343 struct WLAN_802_11_KEY * pkey;
344 u16 key_info = le16_to_cpu(pkeyparamset->keyinfo);
345 u16 param_set_len = le16_to_cpu(pkeyparamset->length);
346 u8 * end;
347 u16 key_len = le16_to_cpu(pkeyparamset->keylen);
348
349 end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type)
350 + sizeof (pkeyparamset->length)
351 + param_set_len;
352 /* Make sure we don't access past the end of the IEs */
353 if (end > resp_end)
354 break;
355
356 if (key_info & KEY_INFO_WPA_UNICAST)
357 pkey = &adapter->wpa_unicast_key;
358 else if (key_info & KEY_INFO_WPA_MCAST)
359 pkey = &adapter->wpa_mcast_key;
360 else
361 break;
362
363 /* Copy returned key into driver */
364 memset(pkey, 0, sizeof(struct WLAN_802_11_KEY));
365 if (key_len > sizeof(pkey->key))
366 break;
367 pkey->type = le16_to_cpu(pkeyparamset->keytypeid);
368 pkey->flags = le16_to_cpu(pkeyparamset->keyinfo);
369 pkey->len = le16_to_cpu(pkeyparamset->keylen);
370 memcpy(pkey->key, pkeyparamset->key, pkey->len);
371
372 buf_ptr = end + 1;
373 }
374 }
375
376 LEAVE();
377 return 0;
378}
379
380static int wlan_ret_802_11_mac_address(wlan_private * priv,
381 struct cmd_ds_command *resp)
382{
383 struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
384 wlan_adapter *adapter = priv->adapter;
385
386 ENTER();
387
388 memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
389
390 LEAVE();
391 return 0;
392}
393
394static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
395 struct cmd_ds_command *resp)
396{
397 struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
398 wlan_adapter *adapter = priv->adapter;
399
400 ENTER();
401
402 adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
403
404 lbs_pr_debug(1, "Current TxPower Level = %d\n", adapter->txpowerlevel);
405
406 LEAVE();
407 return 0;
408}
409
410static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
411 struct cmd_ds_command *resp)
412{
413 struct cmd_ds_802_11_rf_antenna *pAntenna = &resp->params.rant;
414 wlan_adapter *adapter = priv->adapter;
415 u16 action = le16_to_cpu(pAntenna->action);
416
417 if (action == cmd_act_get_rx)
418 adapter->rxantennamode =
419 le16_to_cpu(pAntenna->antennamode);
420
421 if (action == cmd_act_get_tx)
422 adapter->txantennamode =
423 le16_to_cpu(pAntenna->antennamode);
424
425 lbs_pr_debug(1, "RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
426 action, le16_to_cpu(pAntenna->antennamode));
427
428 return 0;
429}
430
431static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
432 struct cmd_ds_command *resp)
433{
434 struct cmd_ds_802_11_rate_adapt_rateset *rates =
435 &resp->params.rateset;
436 wlan_adapter *adapter = priv->adapter;
437
438 ENTER();
439
440 if (rates->action == cmd_act_get) {
441 adapter->enablehwauto = rates->enablehwauto;
442 adapter->ratebitmap = rates->bitmap;
443 }
444
445 LEAVE();
446
447 return 0;
448}
449
450static int wlan_ret_802_11_data_rate(wlan_private * priv,
451 struct cmd_ds_command *resp)
452{
453 struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
454 wlan_adapter *adapter = priv->adapter;
455 u8 dot11datarate;
456
457 ENTER();
458
459 lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
460 (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate));
461
462 dot11datarate = pdatarate->datarate[0];
463 if (pdatarate->action == cmd_act_get_tx_rate) {
464 memcpy(adapter->libertas_supported_rates, pdatarate->datarate,
465 sizeof(adapter->libertas_supported_rates));
466 }
467 adapter->datarate = libertas_index_to_data_rate(dot11datarate);
468
469 LEAVE();
470 return 0;
471}
472
473static int wlan_ret_802_11_rf_channel(wlan_private * priv,
474 struct cmd_ds_command *resp)
475{
476 struct cmd_ds_802_11_rf_channel *rfchannel =
477 &resp->params.rfchannel;
478 wlan_adapter *adapter = priv->adapter;
479 u16 action = le16_to_cpu(rfchannel->action);
480 u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
481
482 ENTER();
483
484 if (action == cmd_opt_802_11_rf_channel_get
485 && adapter->curbssparams.channel != newchannel) {
486 lbs_pr_debug(1, "channel Switch: %d to %d\n",
487 adapter->curbssparams.channel, newchannel);
488
489 /* Update the channel again */
490 adapter->curbssparams.channel = newchannel;
491 }
492
493 LEAVE();
494 return 0;
495}
496
497static int wlan_ret_802_11_rssi(wlan_private * priv,
498 struct cmd_ds_command *resp)
499{
500 struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
501 wlan_adapter *adapter = priv->adapter;
502
503 /* store the non average value */
504 adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
505 adapter->NF[TYPE_BEACON][TYPE_NOAVG] =
506 le16_to_cpu(rssirsp->noisefloor);
507
508 adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
509 adapter->NF[TYPE_BEACON][TYPE_AVG] =
510 le16_to_cpu(rssirsp->avgnoisefloor);
511
512 adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
513 CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
514 adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
515
516 adapter->RSSI[TYPE_BEACON][TYPE_AVG] =
517 CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
518 adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
519
520 lbs_pr_debug(1, "Beacon RSSI value = 0x%x\n",
521 adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
522
523 return 0;
524}
525
526static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
527 struct cmd_ds_command *resp)
528{
529 wlan_adapter *adapter = priv->adapter;
530 struct wlan_ioctl_regrdwr *pbuf;
531 pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
532
533 lbs_pr_debug(1, "eeprom read len=%x\n",
534 le16_to_cpu(resp->params.rdeeprom.bytecount));
535 if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
536 pbuf->NOB = 0;
537 lbs_pr_debug(1, "eeprom read return length is too big\n");
538 return -1;
539 }
540 pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
541 if (pbuf->NOB > 0) {
542
543 memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value,
544 le16_to_cpu(resp->params.rdeeprom.bytecount));
545 lbs_dbg_hex("adapter", (char *)&pbuf->value,
546 le16_to_cpu(resp->params.rdeeprom.bytecount));
547 }
548 return 0;
549}
550
551static int wlan_ret_get_log(wlan_private * priv,
552 struct cmd_ds_command *resp)
553{
554 struct cmd_ds_802_11_get_log *logmessage =
555 (struct cmd_ds_802_11_get_log *)&resp->params.glog;
556 wlan_adapter *adapter = priv->adapter;
557
558 ENTER();
559
560 /* TODO Convert it to Big Endian before copy */
561 memcpy(&adapter->logmsg, logmessage,
562 sizeof(struct cmd_ds_802_11_get_log));
563
564 LEAVE();
565 return 0;
566}
567
568static inline int handle_cmd_response(u16 respcmd,
569 struct cmd_ds_command *resp,
570 wlan_private *priv)
571{
572 int ret = 0;
573 unsigned long flags;
574 wlan_adapter *adapter = priv->adapter;
575
576 switch (respcmd) {
577 case cmd_ret_mac_reg_access:
578 case cmd_ret_bbp_reg_access:
579 case cmd_ret_rf_reg_access:
580 ret = wlan_ret_reg_access(priv, respcmd, resp);
581 break;
582
583 case cmd_ret_hw_spec_info:
584 ret = wlan_ret_get_hw_spec(priv, resp);
585 break;
586
587 case cmd_ret_802_11_scan:
588 ret = libertas_ret_80211_scan(priv, resp);
589 break;
590
591 case cmd_ret_802_11_get_log:
592 ret = wlan_ret_get_log(priv, resp);
593 break;
594
595 case cmd_ret_802_11_associate:
596 case cmd_ret_802_11_reassociate:
597 ret = libertas_ret_80211_associate(priv, resp);
598 break;
599
600 case cmd_ret_802_11_disassociate:
601 case cmd_ret_802_11_deauthenticate:
602 ret = libertas_ret_80211_disassociate(priv, resp);
603 break;
604
605 case cmd_ret_802_11_ad_hoc_start:
606 case cmd_ret_802_11_ad_hoc_join:
607 ret = libertas_ret_80211_ad_hoc_start(priv, resp);
608 break;
609
610 case cmd_ret_802_11_stat:
611 ret = wlan_ret_802_11_stat(priv, resp);
612 break;
613
614 case cmd_ret_802_11_snmp_mib:
615 ret = wlan_ret_802_11_snmp_mib(priv, resp);
616 break;
617
618 case cmd_ret_802_11_rf_tx_power:
619 ret = wlan_ret_802_11_rf_tx_power(priv, resp);
620 break;
621
622 case cmd_ret_802_11_set_afc:
623 case cmd_ret_802_11_get_afc:
624 spin_lock_irqsave(&adapter->driver_lock, flags);
625 memmove(adapter->cur_cmd->pdata_buf,
626 &resp->params.afc,
627 sizeof(struct cmd_ds_802_11_afc));
628 spin_unlock_irqrestore(&adapter->driver_lock, flags);
629
630 break;
631 case cmd_ret_802_11_rf_antenna:
632 ret = wlan_ret_802_11_rf_antenna(priv, resp);
633 break;
634
635 case cmd_ret_mac_multicast_adr:
636 case cmd_ret_mac_control:
637 case cmd_ret_802_11_set_wep:
638 case cmd_ret_802_11_reset:
639 case cmd_ret_802_11_authenticate:
640 case cmd_ret_802_11_radio_control:
641 case cmd_ret_802_11_beacon_stop:
642 case cmd_ret_802_11_enable_rsn:
643 break;
644
645 case cmd_ret_802_11_data_rate:
646 ret = wlan_ret_802_11_data_rate(priv, resp);
647 break;
648 case cmd_ret_802_11_rate_adapt_rateset:
649 ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp);
650 break;
651 case cmd_ret_802_11_rf_channel:
652 ret = wlan_ret_802_11_rf_channel(priv, resp);
653 break;
654
655 case cmd_ret_802_11_rssi:
656 ret = wlan_ret_802_11_rssi(priv, resp);
657 break;
658
659 case cmd_ret_802_11_mac_address:
660 ret = wlan_ret_802_11_mac_address(priv, resp);
661 break;
662
663 case cmd_ret_802_11_ad_hoc_stop:
664 ret = libertas_ret_80211_ad_hoc_stop(priv, resp);
665 break;
666
667 case cmd_ret_802_11_key_material:
668 lbs_pr_debug(1, "CMD_RESP: KEY_MATERIAL command response\n");
669 ret = wlan_ret_802_11_key_material(priv, resp);
670 break;
671
672 case cmd_ret_802_11_eeprom_access:
673 ret = wlan_ret_802_11_eeprom_access(priv, resp);
674 break;
675
676 case cmd_ret_802_11d_domain_info:
677 ret = libertas_ret_802_11d_domain_info(priv, resp);
678 break;
679
680 case cmd_ret_802_11_sleep_params:
681 ret = wlan_ret_802_11_sleep_params(priv, resp);
682 break;
683 case cmd_ret_802_11_inactivity_timeout:
684 spin_lock_irqsave(&adapter->driver_lock, flags);
685 *((u16 *) adapter->cur_cmd->pdata_buf) =
686 le16_to_cpu(resp->params.inactivity_timeout.timeout);
687 spin_unlock_irqrestore(&adapter->driver_lock, flags);
688 break;
689
690 case cmd_ret_802_11_tpc_cfg:
691 spin_lock_irqsave(&adapter->driver_lock, flags);
692 memmove(adapter->cur_cmd->pdata_buf,
693 &resp->params.tpccfg,
694 sizeof(struct cmd_ds_802_11_tpc_cfg));
695 spin_unlock_irqrestore(&adapter->driver_lock, flags);
696 break;
697 case cmd_ret_802_11_led_gpio_ctrl:
698 spin_lock_irqsave(&adapter->driver_lock, flags);
699 memmove(adapter->cur_cmd->pdata_buf,
700 &resp->params.ledgpio,
701 sizeof(struct cmd_ds_802_11_led_ctrl));
702 spin_unlock_irqrestore(&adapter->driver_lock, flags);
703 break;
704 case cmd_ret_802_11_pwr_cfg:
705 spin_lock_irqsave(&adapter->driver_lock, flags);
706 memmove(adapter->cur_cmd->pdata_buf,
707 &resp->params.pwrcfg,
708 sizeof(struct cmd_ds_802_11_pwr_cfg));
709 spin_unlock_irqrestore(&adapter->driver_lock, flags);
710
711 break;
712
713 case cmd_ret_get_tsf:
714 spin_lock_irqsave(&adapter->driver_lock, flags);
715 memcpy(priv->adapter->cur_cmd->pdata_buf,
716 &resp->params.gettsf.tsfvalue, sizeof(u64));
717 spin_unlock_irqrestore(&adapter->driver_lock, flags);
718 break;
719 case cmd_ret_bt_access:
720 spin_lock_irqsave(&adapter->driver_lock, flags);
721 if (adapter->cur_cmd->pdata_buf)
722 memcpy(adapter->cur_cmd->pdata_buf,
723 &resp->params.bt.addr1, 2 * ETH_ALEN);
724 spin_unlock_irqrestore(&adapter->driver_lock, flags);
725 break;
726 case cmd_ret_fwt_access:
727 spin_lock_irqsave(&adapter->driver_lock, flags);
728 if (adapter->cur_cmd->pdata_buf)
729 memcpy(adapter->cur_cmd->pdata_buf,
730 &resp->params.fwt,
731 sizeof(resp->params.fwt));
732 spin_unlock_irqrestore(&adapter->driver_lock, flags);
733 break;
734 case cmd_ret_mesh_access:
735 if (adapter->cur_cmd->pdata_buf)
736 memcpy(adapter->cur_cmd->pdata_buf,
737 &resp->params.mesh,
738 sizeof(resp->params.mesh));
739 break;
740 case cmd_rte_802_11_tx_rate_query:
741 priv->adapter->txrate = resp->params.txrate.txrate;
742 break;
743 default:
744 lbs_pr_debug(1, "CMD_RESP: Unknown command response %#x\n",
745 resp->command);
746 break;
747 }
748 return ret;
749}
750
751int libertas_process_rx_command(wlan_private * priv)
752{
753 u16 respcmd;
754 struct cmd_ds_command *resp;
755 wlan_adapter *adapter = priv->adapter;
756 int ret = 0;
757 ulong flags;
758 u16 result;
759
760 ENTER();
761
762 lbs_pr_debug(1, "CMD_RESP: @ %lu\n", jiffies);
763
764 /* Now we got response from FW, cancel the command timer */
765 del_timer(&adapter->command_timer);
766
767 mutex_lock(&adapter->lock);
768 spin_lock_irqsave(&adapter->driver_lock, flags);
769
770 if (!adapter->cur_cmd) {
771 lbs_pr_debug(1, "CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
772 ret = -1;
773 spin_unlock_irqrestore(&adapter->driver_lock, flags);
774 goto done;
775 }
776 resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
777
778 lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr,
779 priv->wlan_dev.upld_len);
780
781 respcmd = le16_to_cpu(resp->command);
782
783 result = le16_to_cpu(resp->result);
784
785 lbs_pr_debug(1, "CMD_RESP: %x result: %d length: %d\n", respcmd,
786 result, priv->wlan_dev.upld_len);
787
788 if (!(respcmd & 0x8000)) {
789 lbs_pr_debug(1, "Invalid response to command!");
790 adapter->cur_cmd_retcode = -1;
791 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
792 adapter->nr_cmd_pending--;
793 adapter->cur_cmd = NULL;
794 spin_unlock_irqrestore(&adapter->driver_lock, flags);
795 ret = -1;
796 goto done;
797 }
798
799 /* Store the response code to cur_cmd_retcode. */
800 adapter->cur_cmd_retcode = le16_to_cpu(resp->result);
801
802 if (respcmd == cmd_ret_802_11_ps_mode) {
803 struct cmd_ds_802_11_ps_mode *psmode;
804
805 psmode = &resp->params.psmode;
806 lbs_pr_debug(1,
807 "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
808 resp->result, psmode->action);
809 psmode->action = cpu_to_le16(psmode->action);
810
811 if (result) {
812 lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
813 resp->result);
814 if (adapter->inframode == wlan802_11ibss) {
815 /*
816 * We should not re-try enter-ps command in
817 * ad-hoc mode. It takes place in
818 * libertas_execute_next_command().
819 */
820 if (psmode->action == cmd_subcmd_enter_ps)
821 adapter->psmode =
822 wlan802_11powermodecam;
823 }
824 } else if (psmode->action == cmd_subcmd_enter_ps) {
825 adapter->needtowakeup = 0;
826 adapter->psstate = PS_STATE_AWAKE;
827
828 lbs_pr_debug(1, "CMD_RESP: Enter_PS command response\n");
829 if (adapter->connect_status != libertas_connected) {
830 /*
831 * When Deauth Event received before Enter_PS command
832 * response, We need to wake up the firmware.
833 */
834 lbs_pr_debug(1,
835 "Disconnected, Going to invoke libertas_ps_wakeup\n");
836
837 mutex_unlock(&adapter->lock);
838 spin_unlock_irqrestore(&adapter->driver_lock, flags);
839 libertas_ps_wakeup(priv, 0);
840 mutex_lock(&adapter->lock);
841 spin_lock_irqsave(&adapter->driver_lock, flags);
842 }
843 } else if (psmode->action == cmd_subcmd_exit_ps) {
844 adapter->needtowakeup = 0;
845 adapter->psstate = PS_STATE_FULL_POWER;
846 lbs_pr_debug(1, "CMD_RESP: Exit_PS command response\n");
847 } else {
848 lbs_pr_debug(1, "CMD_RESP: PS- action=0x%X\n",
849 psmode->action);
850 }
851
852 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
853 adapter->nr_cmd_pending--;
854 adapter->cur_cmd = NULL;
855 spin_unlock_irqrestore(&adapter->driver_lock, flags);
856
857 ret = 0;
858 goto done;
859 }
860
861 if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) {
862 /* Copy the response back to response buffer */
863 memcpy(adapter->cur_cmd->pdata_buf, resp, resp->size);
864
865 adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD;
866 }
867
868 /* If the command is not successful, cleanup and return failure */
869 if ((result != 0 || !(respcmd & 0x8000))) {
870 lbs_pr_debug(1, "CMD_RESP: command reply %#x result=%#x\n",
871 resp->command, resp->result);
872 /*
873 * Handling errors here
874 */
875 switch (respcmd) {
876 case cmd_ret_hw_spec_info:
877 case cmd_ret_802_11_reset:
878 lbs_pr_debug(1, "CMD_RESP: Reset command failed\n");
879 break;
880
881 }
882
883 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
884 adapter->nr_cmd_pending--;
885 adapter->cur_cmd = NULL;
886 spin_unlock_irqrestore(&adapter->driver_lock, flags);
887
888 ret = -1;
889 goto done;
890 }
891
892 spin_unlock_irqrestore(&adapter->driver_lock, flags);
893
894 ret = handle_cmd_response(respcmd, resp, priv);
895
896 spin_lock_irqsave(&adapter->driver_lock, flags);
897 if (adapter->cur_cmd) {
898 /* Clean up and Put current command back to cmdfreeq */
899 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
900 adapter->nr_cmd_pending--;
901 WARN_ON(adapter->nr_cmd_pending > 128);
902 adapter->cur_cmd = NULL;
903 }
904 spin_unlock_irqrestore(&adapter->driver_lock, flags);
905
906done:
907 mutex_unlock(&adapter->lock);
908 LEAVE();
909 return ret;
910}
911
912int libertas_process_event(wlan_private * priv)
913{
914 int ret = 0;
915 wlan_adapter *adapter = priv->adapter;
916 u32 eventcause;
917
918 spin_lock_irq(&adapter->driver_lock);
919 eventcause = adapter->eventcause;
920 spin_unlock_irq(&adapter->driver_lock);
921
922 ENTER();
923
924 lbs_pr_debug(1, "EVENT Cause %x\n", eventcause);
925
926 switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
927 case MACREG_INT_CODE_LINK_SENSED:
928 lbs_pr_debug(1, "EVENT: MACREG_INT_CODE_LINK_SENSED\n");
929 break;
930
931 case MACREG_INT_CODE_DEAUTHENTICATED:
932 lbs_pr_debug(1, "EVENT: Deauthenticated\n");
933 libertas_mac_event_disconnected(priv);
934 break;
935
936 case MACREG_INT_CODE_DISASSOCIATED:
937 lbs_pr_debug(1, "EVENT: Disassociated\n");
938 libertas_mac_event_disconnected(priv);
939 break;
940
941 case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
942 lbs_pr_debug(1, "EVENT: Link lost\n");
943 libertas_mac_event_disconnected(priv);
944 break;
945
946 case MACREG_INT_CODE_PS_SLEEP:
947 lbs_pr_debug(1, "EVENT: SLEEP\n");
948 lbs_pr_debug(1, "_");
949
950 /* handle unexpected PS SLEEP event */
951 if (adapter->psstate == PS_STATE_FULL_POWER) {
952 lbs_pr_debug(1,
953 "EVENT: In FULL POWER mode - ignore PS SLEEP\n");
954 break;
955 }
956 adapter->psstate = PS_STATE_PRE_SLEEP;
957
958 libertas_ps_confirm_sleep(priv, (u16) adapter->psmode);
959
960 break;
961
962 case MACREG_INT_CODE_PS_AWAKE:
963 lbs_pr_debug(1, "EVENT: AWAKE \n");
964 lbs_pr_debug(1, "|");
965
966 /* handle unexpected PS AWAKE event */
967 if (adapter->psstate == PS_STATE_FULL_POWER) {
968 lbs_pr_debug(1,
969 "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
970 break;
971 }
972
973 adapter->psstate = PS_STATE_AWAKE;
974
975 if (adapter->needtowakeup) {
976 /*
977 * wait for the command processing to finish
978 * before resuming sending
979 * adapter->needtowakeup will be set to FALSE
980 * in libertas_ps_wakeup()
981 */
982 lbs_pr_debug(1, "Waking up...\n");
983 libertas_ps_wakeup(priv, 0);
984 }
985 break;
986
987 case MACREG_INT_CODE_MIC_ERR_UNICAST:
988 lbs_pr_debug(1, "EVENT: UNICAST MIC ERROR\n");
989 handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
990 break;
991
992 case MACREG_INT_CODE_MIC_ERR_MULTICAST:
993 lbs_pr_debug(1, "EVENT: MULTICAST MIC ERROR\n");
994 handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
995 break;
996 case MACREG_INT_CODE_MIB_CHANGED:
997 case MACREG_INT_CODE_INIT_DONE:
998 break;
999
1000 case MACREG_INT_CODE_ADHOC_BCN_LOST:
1001 lbs_pr_debug(1, "EVENT: HWAC - ADHOC BCN LOST\n");
1002 break;
1003
1004 case MACREG_INT_CODE_RSSI_LOW:
1005 lbs_pr_alert( "EVENT: RSSI_LOW\n");
1006 break;
1007 case MACREG_INT_CODE_SNR_LOW:
1008 lbs_pr_alert( "EVENT: SNR_LOW\n");
1009 break;
1010 case MACREG_INT_CODE_MAX_FAIL:
1011 lbs_pr_alert( "EVENT: MAX_FAIL\n");
1012 break;
1013 case MACREG_INT_CODE_RSSI_HIGH:
1014 lbs_pr_alert( "EVENT: RSSI_HIGH\n");
1015 break;
1016 case MACREG_INT_CODE_SNR_HIGH:
1017 lbs_pr_alert( "EVENT: SNR_HIGH\n");
1018 break;
1019
1020 default:
1021 lbs_pr_alert( "EVENT: unknown event id: %#x\n",
1022 eventcause >> SBI_EVENT_CAUSE_SHIFT);
1023 break;
1024 }
1025
1026 spin_lock_irq(&adapter->driver_lock);
1027 adapter->eventcause = 0;
1028 spin_unlock_irq(&adapter->driver_lock);
1029 LEAVE();
1030 return ret;
1031}
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
new file mode 100644
index 000000000000..51dfd202f558
--- /dev/null
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -0,0 +1,1935 @@
1#include <linux/module.h>
2#include <linux/dcache.h>
3#include <linux/debugfs.h>
4#include <linux/delay.h>
5#include <linux/mm.h>
6#include <net/iw_handler.h>
7#include "dev.h"
8#include "decl.h"
9#include "host.h"
10
11static struct dentry *libertas_dir = NULL;
12static char *szStates[] = {
13 "Connected",
14 "Disconnected"
15};
16
17void libertas_debug_init(wlan_private * priv, struct net_device *dev);
18
19static int open_file_generic(struct inode *inode, struct file *file)
20{
21 file->private_data = inode->i_private;
22 return 0;
23}
24
25static ssize_t write_file_dummy(struct file *file, const char __user *buf,
26 size_t count, loff_t *ppos)
27{
28 return -EINVAL;
29}
30
31static const size_t len = PAGE_SIZE;
32
33static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
34 size_t count, loff_t *ppos)
35{
36 wlan_private *priv = file->private_data;
37 size_t pos = 0;
38 unsigned long addr = get_zeroed_page(GFP_KERNEL);
39 char *buf = (char *)addr;
40 ssize_t res;
41
42 pos += snprintf(buf+pos, len-pos, "state = %s\n",
43 szStates[priv->adapter->connect_status]);
44 pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
45 (u32) priv->adapter->regioncode);
46
47 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
48
49 free_page(addr);
50 return res;
51}
52
53
54static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
55 size_t count, loff_t *ppos)
56{
57 wlan_private *priv = file->private_data;
58 size_t pos = 0;
59 int numscansdone = 0, res;
60 unsigned long addr = get_zeroed_page(GFP_KERNEL);
61 char *buf = (char *)addr;
62
63 pos += snprintf(buf+pos, len-pos,
64 "---------------------------------------");
65 pos += snprintf(buf+pos, len-pos,
66 "---------------------------------------\n");
67 pos += snprintf(buf+pos, len-pos,
68 "# | ch | ss | bssid | cap | TSF | Qual | SSID \n");
69 pos += snprintf(buf+pos, len-pos,
70 "---------------------------------------");
71 pos += snprintf(buf+pos, len-pos,
72 "---------------------------------------\n");
73
74 while (numscansdone < priv->adapter->numinscantable) {
75 struct bss_descriptor *pbssinfo;
76 u16 cap;
77
78 pbssinfo = &priv->adapter->scantable[numscansdone];
79 memcpy(&cap, &pbssinfo->cap, sizeof(cap));
80 pos += snprintf(buf+pos, len-pos,
81 "%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |",
82 numscansdone, pbssinfo->channel, pbssinfo->rssi,
83 pbssinfo->macaddress[0], pbssinfo->macaddress[1],
84 pbssinfo->macaddress[2], pbssinfo->macaddress[3],
85 pbssinfo->macaddress[4], pbssinfo->macaddress[5]);
86 pos += snprintf(buf+pos, len-pos, " %04x-", cap);
87 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
88 pbssinfo->cap.ibss ? 'A' : 'I',
89 pbssinfo->cap.privacy ? 'P' : ' ',
90 pbssinfo->cap.spectrummgmt ? 'S' : ' ');
91 pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf);
92 pos += snprintf(buf+pos, len-pos, " %d |",
93 SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi));
94
95 pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid);
96
97 numscansdone++;
98 }
99
100 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
101
102 free_page(addr);
103 return res;
104}
105
106static ssize_t libertas_sleepparams_write(struct file *file,
107 const char __user *user_buf, size_t count,
108 loff_t *ppos)
109{
110 wlan_private *priv = file->private_data;
111 ssize_t buf_size, res;
112 int p1, p2, p3, p4, p5, p6;
113 struct sleep_params sp;
114 unsigned long addr = get_zeroed_page(GFP_KERNEL);
115 char *buf = (char *)addr;
116
117 buf_size = min(count, len - 1);
118 if (copy_from_user(buf, user_buf, buf_size)) {
119 res = -EFAULT;
120 goto out_unlock;
121 }
122 res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
123 if (res != 6) {
124 res = -EFAULT;
125 goto out_unlock;
126 }
127 sp.sp_error = p1;
128 sp.sp_offset = p2;
129 sp.sp_stabletime = p3;
130 sp.sp_calcontrol = p4;
131 sp.sp_extsleepclk = p5;
132 sp.sp_reserved = p6;
133
134 memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
135
136 res = libertas_prepare_and_send_command(priv,
137 cmd_802_11_sleep_params,
138 cmd_act_set,
139 cmd_option_waitforrsp, 0, NULL);
140
141 if (!res)
142 res = count;
143 else
144 res = -EINVAL;
145
146out_unlock:
147 free_page(addr);
148 return res;
149}
150
151static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
152 size_t count, loff_t *ppos)
153{
154 wlan_private *priv = file->private_data;
155 wlan_adapter *adapter = priv->adapter;
156 ssize_t res;
157 size_t pos = 0;
158 unsigned long addr = get_zeroed_page(GFP_KERNEL);
159 char *buf = (char *)addr;
160
161 res = libertas_prepare_and_send_command(priv,
162 cmd_802_11_sleep_params,
163 cmd_act_get,
164 cmd_option_waitforrsp, 0, NULL);
165 if (res) {
166 res = -EFAULT;
167 goto out_unlock;
168 }
169
170 pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
171 adapter->sp.sp_offset, adapter->sp.sp_stabletime,
172 adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
173 adapter->sp.sp_reserved);
174
175 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
176
177out_unlock:
178 free_page(addr);
179 return res;
180}
181
182static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
183 size_t count, loff_t *ppos)
184{
185 wlan_private *priv = file->private_data;
186 ssize_t res, buf_size;
187 struct WLAN_802_11_SSID extscan_ssid;
188 union iwreq_data wrqu;
189 unsigned long addr = get_zeroed_page(GFP_KERNEL);
190 char *buf = (char *)addr;
191
192 buf_size = min(count, len - 1);
193 if (copy_from_user(buf, userbuf, buf_size)) {
194 res = -EFAULT;
195 goto out_unlock;
196 }
197
198 memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
199 extscan_ssid.ssidlength = strlen(buf)-1;
200
201 libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
202
203 memset(&wrqu, 0, sizeof(union iwreq_data));
204 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
205
206out_unlock:
207 free_page(addr);
208 return count;
209}
210
211static int libertas_parse_chan(char *buf, size_t count,
212 struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
213{
214 char *start, *end, *hold, *str;
215 int i = 0;
216
217 start = strstr(buf, "chan=");
218 if (!start)
219 return -EINVAL;
220 start += 5;
221 end = strstr(start, " ");
222 if (!end)
223 end = buf + count;
224 hold = kzalloc((end - start)+1, GFP_KERNEL);
225 if (!hold)
226 return -ENOMEM;
227 strncpy(hold, start, end - start);
228 hold[(end-start)+1] = '\0';
229 while(hold && (str = strsep(&hold, ","))) {
230 int chan;
231 char band, passive = 0;
232 sscanf(str, "%d%c%c", &chan, &band, &passive);
233 scan_cfg->chanlist[i].channumber = chan;
234 scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
235 if (band == 'b' || band == 'g')
236 scan_cfg->chanlist[i].radiotype = 0;
237 else if (band == 'a')
238 scan_cfg->chanlist[i].radiotype = 1;
239
240 scan_cfg->chanlist[i].scantime = dur;
241 i++;
242 }
243
244 kfree(hold);
245 return i;
246}
247
248static void libertas_parse_bssid(char *buf, size_t count,
249 struct wlan_ioctl_user_scan_cfg *scan_cfg)
250{
251 char *hold;
252 unsigned int mac[ETH_ALEN];
253 int i;
254
255 hold = strstr(buf, "bssid=");
256 if (!hold)
257 return;
258 hold += 6;
259 sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
260 mac+4, mac+5);
261 for(i=0;i<ETH_ALEN;i++)
262 scan_cfg->specificBSSID[i] = mac[i];
263}
264
265static void libertas_parse_ssid(char *buf, size_t count,
266 struct wlan_ioctl_user_scan_cfg *scan_cfg)
267{
268 char *hold, *end;
269 ssize_t size;
270
271 hold = strstr(buf, "ssid=");
272 if (!hold)
273 return;
274 hold += 5;
275 end = strstr(hold, " ");
276 if (!end)
277 end = buf + count - 1;
278
279 size = min(IW_ESSID_MAX_SIZE, end - hold);
280 strncpy(scan_cfg->specificSSID, hold, size);
281
282 return;
283}
284
285static void libertas_parse_keep(char *buf, size_t count,
286 struct wlan_ioctl_user_scan_cfg *scan_cfg)
287{
288 char *hold;
289 int val;
290
291 hold = strstr(buf, "keep=");
292 if (!hold)
293 return;
294 hold += 5;
295 sscanf(hold, "%d", &val);
296
297 if (val != 0)
298 val = 1;
299
300 scan_cfg->keeppreviousscan = val;
301 return;
302}
303
304static int libertas_parse_dur(char *buf, size_t count,
305 struct wlan_ioctl_user_scan_cfg *scan_cfg)
306{
307 char *hold;
308 int val;
309
310 hold = strstr(buf, "dur=");
311 if (!hold)
312 return 0;
313 hold += 4;
314 sscanf(hold, "%d", &val);
315
316 return val;
317}
318
319static void libertas_parse_probes(char *buf, size_t count,
320 struct wlan_ioctl_user_scan_cfg *scan_cfg)
321{
322 char *hold;
323 int val;
324
325 hold = strstr(buf, "probes=");
326 if (!hold)
327 return;
328 hold += 7;
329 sscanf(hold, "%d", &val);
330
331 scan_cfg->numprobes = val;
332
333 return;
334}
335
336static void libertas_parse_type(char *buf, size_t count,
337 struct wlan_ioctl_user_scan_cfg *scan_cfg)
338{
339 char *hold;
340 int val;
341
342 hold = strstr(buf, "type=");
343 if (!hold)
344 return;
345 hold += 5;
346 sscanf(hold, "%d", &val);
347
348 /* type=1,2 or 3 */
349 if (val < 1 || val > 3)
350 return;
351
352 scan_cfg->bsstype = val;
353
354 return;
355}
356
357static ssize_t libertas_setuserscan(struct file *file,
358 const char __user *userbuf,
359 size_t count, loff_t *ppos)
360{
361 wlan_private *priv = file->private_data;
362 ssize_t res, buf_size;
363 struct wlan_ioctl_user_scan_cfg *scan_cfg;
364 union iwreq_data wrqu;
365 int dur;
366 unsigned long addr = get_zeroed_page(GFP_KERNEL);
367 char *buf = (char *)addr;
368
369 scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
370 if (!scan_cfg)
371 return -ENOMEM;
372
373 buf_size = min(count, len - 1);
374 if (copy_from_user(buf, userbuf, buf_size)) {
375 res = -EFAULT;
376 goto out_unlock;
377 }
378
379 scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
380
381 dur = libertas_parse_dur(buf, count, scan_cfg);
382 libertas_parse_chan(buf, count, scan_cfg, dur);
383 libertas_parse_bssid(buf, count, scan_cfg);
384 libertas_parse_ssid(buf, count, scan_cfg);
385 libertas_parse_keep(buf, count, scan_cfg);
386 libertas_parse_probes(buf, count, scan_cfg);
387 libertas_parse_type(buf, count, scan_cfg);
388
389 wlan_scan_networks(priv, scan_cfg);
390 wait_event_interruptible(priv->adapter->cmd_pending,
391 !priv->adapter->nr_cmd_pending);
392
393 memset(&wrqu, 0x00, sizeof(union iwreq_data));
394 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
395
396out_unlock:
397 free_page(addr);
398 kfree(scan_cfg);
399 return count;
400}
401
402static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
403 struct cmd_ctrl_node **cmdnode,
404 struct cmd_ds_command **cmd)
405{
406 u16 wait_option = cmd_option_waitforrsp;
407
408 if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
409 lbs_pr_debug(1, "failed libertas_get_free_cmd_ctrl_node\n");
410 return -ENOMEM;
411 }
412 if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
413 lbs_pr_debug(1, "failed to allocate response buffer!\n");
414 return -ENOMEM;
415 }
416 libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
417 init_waitqueue_head(&(*cmdnode)->cmdwait_q);
418 (*cmdnode)->pdata_buf = *response_buf;
419 (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
420 (*cmdnode)->cmdwaitqwoken = 0;
421 *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
422 (*cmd)->command = cmd_802_11_subscribe_event;
423 (*cmd)->seqnum = ++priv->adapter->seqnum;
424 (*cmd)->result = 0;
425 return 0;
426}
427
428static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
429 size_t count, loff_t *ppos)
430{
431 wlan_private *priv = file->private_data;
432 wlan_adapter *adapter = priv->adapter;
433 struct cmd_ctrl_node *pcmdnode;
434 struct cmd_ds_command *pcmdptr;
435 struct cmd_ds_802_11_subscribe_event *event;
436 void *response_buf;
437 int res, cmd_len;
438 ssize_t pos = 0;
439 unsigned long addr = get_zeroed_page(GFP_KERNEL);
440 char *buf = (char *)addr;
441
442 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
443 if (res < 0) {
444 free_page(addr);
445 return res;
446 }
447
448 event = &pcmdptr->params.subscribe_event;
449 event->action = cmd_act_get;
450 pcmdptr->size =
451 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
452 libertas_queue_cmd(adapter, pcmdnode, 1);
453 wake_up_interruptible(&priv->mainthread.waitq);
454
455 /* Sleep until response is generated by FW */
456 wait_event_interruptible(pcmdnode->cmdwait_q,
457 pcmdnode->cmdwaitqwoken);
458
459 pcmdptr = response_buf;
460 if (pcmdptr->result) {
461 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
462 pcmdptr->result);
463 kfree(response_buf);
464 free_page(addr);
465 return 0;
466 }
467
468 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
469 lbs_pr_err("command response incorrect!\n");
470 kfree(response_buf);
471 free_page(addr);
472 return 0;
473 }
474
475 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
476 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
477 while (cmd_len < pcmdptr->size) {
478 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
479 switch(header->type) {
480 struct mrvlietypes_rssithreshold *Lowrssi;
481 case TLV_TYPE_RSSI_LOW:
482 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
483 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
484 Lowrssi->rssivalue,
485 Lowrssi->rssifreq,
486 (event->events & 0x0001)?1:0);
487 default:
488 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
489 break;
490 }
491 }
492
493 kfree(response_buf);
494 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
495 free_page(addr);
496 return res;
497}
498
499static u16 libertas_get_events_bitmap(wlan_private *priv)
500{
501 wlan_adapter *adapter = priv->adapter;
502 struct cmd_ctrl_node *pcmdnode;
503 struct cmd_ds_command *pcmdptr;
504 struct cmd_ds_802_11_subscribe_event *event;
505 void *response_buf;
506 int res;
507 u16 event_bitmap;
508
509 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
510 if (res < 0)
511 return res;
512
513 event = &pcmdptr->params.subscribe_event;
514 event->action = cmd_act_get;
515 pcmdptr->size =
516 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
517 libertas_queue_cmd(adapter, pcmdnode, 1);
518 wake_up_interruptible(&priv->mainthread.waitq);
519
520 /* Sleep until response is generated by FW */
521 wait_event_interruptible(pcmdnode->cmdwait_q,
522 pcmdnode->cmdwaitqwoken);
523
524 pcmdptr = response_buf;
525
526 if (pcmdptr->result) {
527 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
528 pcmdptr->result);
529 kfree(response_buf);
530 return 0;
531 }
532
533 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
534 lbs_pr_err("command response incorrect!\n");
535 kfree(response_buf);
536 return 0;
537 }
538
539 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
540 event_bitmap = event->events;
541 kfree(response_buf);
542 return event_bitmap;
543}
544
545static ssize_t libertas_lowrssi_write(struct file *file,
546 const char __user *userbuf,
547 size_t count, loff_t *ppos)
548{
549 wlan_private *priv = file->private_data;
550 wlan_adapter *adapter = priv->adapter;
551 ssize_t res, buf_size;
552 int value, freq, subscribed, cmd_len;
553 struct cmd_ctrl_node *pcmdnode;
554 struct cmd_ds_command *pcmdptr;
555 struct cmd_ds_802_11_subscribe_event *event;
556 struct mrvlietypes_rssithreshold *rssi_threshold;
557 void *response_buf;
558 u16 event_bitmap;
559 u8 *ptr;
560 unsigned long addr = get_zeroed_page(GFP_KERNEL);
561 char *buf = (char *)addr;
562
563 buf_size = min(count, len - 1);
564 if (copy_from_user(buf, userbuf, buf_size)) {
565 res = -EFAULT;
566 goto out_unlock;
567 }
568 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
569 if (res != 3) {
570 res = -EFAULT;
571 goto out_unlock;
572 }
573
574 event_bitmap = libertas_get_events_bitmap(priv);
575
576 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
577 if (res < 0)
578 goto out_unlock;
579
580 event = &pcmdptr->params.subscribe_event;
581 event->action = cmd_act_set;
582 pcmdptr->size = cpu_to_le16(S_DS_GEN +
583 sizeof(struct cmd_ds_802_11_subscribe_event) +
584 sizeof(struct mrvlietypes_rssithreshold));
585
586 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
587 ptr = (u8*) pcmdptr+cmd_len;
588 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
589 rssi_threshold->header.type = cpu_to_le16(0x0104);
590 rssi_threshold->header.len = 2;
591 rssi_threshold->rssivalue = cpu_to_le16(value);
592 rssi_threshold->rssifreq = cpu_to_le16(freq);
593 event_bitmap |= subscribed ? 0x0001 : 0x0;
594 event->events = event_bitmap;
595
596 libertas_queue_cmd(adapter, pcmdnode, 1);
597 wake_up_interruptible(&priv->mainthread.waitq);
598
599 /* Sleep until response is generated by FW */
600 wait_event_interruptible(pcmdnode->cmdwait_q,
601 pcmdnode->cmdwaitqwoken);
602
603 pcmdptr = response_buf;
604
605 if (pcmdptr->result) {
606 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
607 pcmdptr->result);
608 kfree(response_buf);
609 free_page(addr);
610 return 0;
611 }
612
613 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
614 lbs_pr_err("command response incorrect!\n");
615 kfree(response_buf);
616 free_page(addr);
617 return 0;
618 }
619
620 res = count;
621out_unlock:
622 free_page(addr);
623 return res;
624}
625
626static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
627 size_t count, loff_t *ppos)
628{
629 wlan_private *priv = file->private_data;
630 wlan_adapter *adapter = priv->adapter;
631 struct cmd_ctrl_node *pcmdnode;
632 struct cmd_ds_command *pcmdptr;
633 struct cmd_ds_802_11_subscribe_event *event;
634 void *response_buf;
635 int res, cmd_len;
636 ssize_t pos = 0;
637 unsigned long addr = get_zeroed_page(GFP_KERNEL);
638 char *buf = (char *)addr;
639
640 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
641 if (res < 0) {
642 free_page(addr);
643 return res;
644 }
645
646 event = &pcmdptr->params.subscribe_event;
647 event->action = cmd_act_get;
648 pcmdptr->size =
649 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
650 libertas_queue_cmd(adapter, pcmdnode, 1);
651 wake_up_interruptible(&priv->mainthread.waitq);
652
653 /* Sleep until response is generated by FW */
654 wait_event_interruptible(pcmdnode->cmdwait_q,
655 pcmdnode->cmdwaitqwoken);
656
657 pcmdptr = response_buf;
658
659 if (pcmdptr->result) {
660 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
661 pcmdptr->result);
662 kfree(response_buf);
663 free_page(addr);
664 return 0;
665 }
666
667 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
668 lbs_pr_err("command response incorrect!\n");
669 kfree(response_buf);
670 free_page(addr);
671 return 0;
672 }
673
674 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
675 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
676 while (cmd_len < pcmdptr->size) {
677 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
678 switch(header->type) {
679 struct mrvlietypes_snrthreshold *LowSnr;
680 case TLV_TYPE_SNR_LOW:
681 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
682 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
683 LowSnr->snrvalue,
684 LowSnr->snrfreq,
685 (event->events & 0x0002)?1:0);
686 default:
687 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
688 break;
689 }
690 }
691
692 kfree(response_buf);
693
694 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
695 free_page(addr);
696 return res;
697}
698
699static ssize_t libertas_lowsnr_write(struct file *file,
700 const char __user *userbuf,
701 size_t count, loff_t *ppos)
702{
703 wlan_private *priv = file->private_data;
704 wlan_adapter *adapter = priv->adapter;
705 ssize_t res, buf_size;
706 int value, freq, subscribed, cmd_len;
707 struct cmd_ctrl_node *pcmdnode;
708 struct cmd_ds_command *pcmdptr;
709 struct cmd_ds_802_11_subscribe_event *event;
710 struct mrvlietypes_snrthreshold *snr_threshold;
711 void *response_buf;
712 u16 event_bitmap;
713 u8 *ptr;
714 unsigned long addr = get_zeroed_page(GFP_KERNEL);
715 char *buf = (char *)addr;
716
717 buf_size = min(count, len - 1);
718 if (copy_from_user(buf, userbuf, buf_size)) {
719 res = -EFAULT;
720 goto out_unlock;
721 }
722 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
723 if (res != 3) {
724 res = -EFAULT;
725 goto out_unlock;
726 }
727
728 event_bitmap = libertas_get_events_bitmap(priv);
729
730 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
731 if (res < 0)
732 goto out_unlock;
733
734 event = &pcmdptr->params.subscribe_event;
735 event->action = cmd_act_set;
736 pcmdptr->size = cpu_to_le16(S_DS_GEN +
737 sizeof(struct cmd_ds_802_11_subscribe_event) +
738 sizeof(struct mrvlietypes_snrthreshold));
739 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
740 ptr = (u8*) pcmdptr+cmd_len;
741 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
742 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
743 snr_threshold->header.len = 2;
744 snr_threshold->snrvalue = cpu_to_le16(value);
745 snr_threshold->snrfreq = cpu_to_le16(freq);
746 event_bitmap |= subscribed ? 0x0002 : 0x0;
747 event->events = event_bitmap;
748
749 libertas_queue_cmd(adapter, pcmdnode, 1);
750 wake_up_interruptible(&priv->mainthread.waitq);
751
752 /* Sleep until response is generated by FW */
753 wait_event_interruptible(pcmdnode->cmdwait_q,
754 pcmdnode->cmdwaitqwoken);
755
756 pcmdptr = response_buf;
757
758 if (pcmdptr->result) {
759 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
760 pcmdptr->result);
761 kfree(response_buf);
762 free_page(addr);
763 return 0;
764 }
765
766 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
767 lbs_pr_err("command response incorrect!\n");
768 kfree(response_buf);
769 free_page(addr);
770 return 0;
771 }
772
773 res = count;
774
775out_unlock:
776 free_page(addr);
777 return res;
778}
779
780static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
781 size_t count, loff_t *ppos)
782{
783 wlan_private *priv = file->private_data;
784 wlan_adapter *adapter = priv->adapter;
785 struct cmd_ctrl_node *pcmdnode;
786 struct cmd_ds_command *pcmdptr;
787 struct cmd_ds_802_11_subscribe_event *event;
788 void *response_buf;
789 int res, cmd_len;
790 ssize_t pos = 0;
791 unsigned long addr = get_zeroed_page(GFP_KERNEL);
792 char *buf = (char *)addr;
793
794 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
795 if (res < 0) {
796 free_page(addr);
797 return res;
798 }
799
800 event = &pcmdptr->params.subscribe_event;
801 event->action = cmd_act_get;
802 pcmdptr->size =
803 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
804 libertas_queue_cmd(adapter, pcmdnode, 1);
805 wake_up_interruptible(&priv->mainthread.waitq);
806
807 /* Sleep until response is generated by FW */
808 wait_event_interruptible(pcmdnode->cmdwait_q,
809 pcmdnode->cmdwaitqwoken);
810
811 pcmdptr = response_buf;
812
813 if (pcmdptr->result) {
814 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
815 pcmdptr->result);
816 kfree(response_buf);
817 free_page(addr);
818 return 0;
819 }
820
821 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
822 lbs_pr_err("command response incorrect!\n");
823 kfree(response_buf);
824 free_page(addr);
825 return 0;
826 }
827
828 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
829 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
830 while (cmd_len < pcmdptr->size) {
831 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
832 switch(header->type) {
833 struct mrvlietypes_failurecount *failcount;
834 case TLV_TYPE_FAILCOUNT:
835 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
836 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
837 failcount->failvalue,
838 failcount->Failfreq,
839 (event->events & 0x0004)?1:0);
840 default:
841 cmd_len += sizeof(struct mrvlietypes_failurecount);
842 break;
843 }
844 }
845
846 kfree(response_buf);
847 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
848 free_page(addr);
849 return res;
850}
851
852static ssize_t libertas_failcount_write(struct file *file,
853 const char __user *userbuf,
854 size_t count, loff_t *ppos)
855{
856 wlan_private *priv = file->private_data;
857 wlan_adapter *adapter = priv->adapter;
858 ssize_t res, buf_size;
859 int value, freq, subscribed, cmd_len;
860 struct cmd_ctrl_node *pcmdnode;
861 struct cmd_ds_command *pcmdptr;
862 struct cmd_ds_802_11_subscribe_event *event;
863 struct mrvlietypes_failurecount *failcount;
864 void *response_buf;
865 u16 event_bitmap;
866 u8 *ptr;
867 unsigned long addr = get_zeroed_page(GFP_KERNEL);
868 char *buf = (char *)addr;
869
870 buf_size = min(count, len - 1);
871 if (copy_from_user(buf, userbuf, buf_size)) {
872 res = -EFAULT;
873 goto out_unlock;
874 }
875 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
876 if (res != 3) {
877 res = -EFAULT;
878 goto out_unlock;
879 }
880
881 event_bitmap = libertas_get_events_bitmap(priv);
882
883 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
884 if (res < 0)
885 goto out_unlock;
886
887 event = &pcmdptr->params.subscribe_event;
888 event->action = cmd_act_set;
889 pcmdptr->size = cpu_to_le16(S_DS_GEN +
890 sizeof(struct cmd_ds_802_11_subscribe_event) +
891 sizeof(struct mrvlietypes_failurecount));
892 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
893 ptr = (u8*) pcmdptr+cmd_len;
894 failcount = (struct mrvlietypes_failurecount *)(ptr);
895 failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
896 failcount->header.len = 2;
897 failcount->failvalue = cpu_to_le16(value);
898 failcount->Failfreq = cpu_to_le16(freq);
899 event_bitmap |= subscribed ? 0x0004 : 0x0;
900 event->events = event_bitmap;
901
902 libertas_queue_cmd(adapter, pcmdnode, 1);
903 wake_up_interruptible(&priv->mainthread.waitq);
904
905 /* Sleep until response is generated by FW */
906 wait_event_interruptible(pcmdnode->cmdwait_q,
907 pcmdnode->cmdwaitqwoken);
908
909 pcmdptr = (struct cmd_ds_command *)response_buf;
910
911 if (pcmdptr->result) {
912 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
913 pcmdptr->result);
914 kfree(response_buf);
915 free_page(addr);
916 return 0;
917 }
918
919 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
920 lbs_pr_err("command response incorrect!\n");
921 kfree(response_buf);
922 free_page(addr);
923 return 0;
924 }
925
926 res = count;
927out_unlock:
928 free_page(addr);
929 return res;
930}
931
932static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
933 size_t count, loff_t *ppos)
934{
935 wlan_private *priv = file->private_data;
936 wlan_adapter *adapter = priv->adapter;
937 struct cmd_ctrl_node *pcmdnode;
938 struct cmd_ds_command *pcmdptr;
939 struct cmd_ds_802_11_subscribe_event *event;
940 void *response_buf;
941 int res, cmd_len;
942 ssize_t pos = 0;
943 unsigned long addr = get_zeroed_page(GFP_KERNEL);
944 char *buf = (char *)addr;
945
946 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
947 if (res < 0) {
948 free_page(addr);
949 return res;
950 }
951
952 event = &pcmdptr->params.subscribe_event;
953 event->action = cmd_act_get;
954 pcmdptr->size =
955 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
956 libertas_queue_cmd(adapter, pcmdnode, 1);
957 wake_up_interruptible(&priv->mainthread.waitq);
958
959 /* Sleep until response is generated by FW */
960 wait_event_interruptible(pcmdnode->cmdwait_q,
961 pcmdnode->cmdwaitqwoken);
962
963 pcmdptr = response_buf;
964
965 if (pcmdptr->result) {
966 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
967 pcmdptr->result);
968 free_page(addr);
969 kfree(response_buf);
970 return 0;
971 }
972
973 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
974 lbs_pr_err("command response incorrect!\n");
975 free_page(addr);
976 kfree(response_buf);
977 return 0;
978 }
979
980 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
981 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
982 while (cmd_len < pcmdptr->size) {
983 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
984 switch(header->type) {
985 struct mrvlietypes_beaconsmissed *bcnmiss;
986 case TLV_TYPE_BCNMISS:
987 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
988 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
989 bcnmiss->beaconmissed,
990 (event->events & 0x0008)?1:0);
991 default:
992 cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
993 break;
994 }
995 }
996
997 kfree(response_buf);
998
999 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1000 free_page(addr);
1001 return res;
1002}
1003
1004static ssize_t libertas_bcnmiss_write(struct file *file,
1005 const char __user *userbuf,
1006 size_t count, loff_t *ppos)
1007{
1008 wlan_private *priv = file->private_data;
1009 wlan_adapter *adapter = priv->adapter;
1010 ssize_t res, buf_size;
1011 int value, freq, subscribed, cmd_len;
1012 struct cmd_ctrl_node *pcmdnode;
1013 struct cmd_ds_command *pcmdptr;
1014 struct cmd_ds_802_11_subscribe_event *event;
1015 struct mrvlietypes_beaconsmissed *bcnmiss;
1016 void *response_buf;
1017 u16 event_bitmap;
1018 u8 *ptr;
1019 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1020 char *buf = (char *)addr;
1021
1022 buf_size = min(count, len - 1);
1023 if (copy_from_user(buf, userbuf, buf_size)) {
1024 res = -EFAULT;
1025 goto out_unlock;
1026 }
1027 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1028 if (res != 3) {
1029 res = -EFAULT;
1030 goto out_unlock;
1031 }
1032
1033 event_bitmap = libertas_get_events_bitmap(priv);
1034
1035 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1036 if (res < 0)
1037 goto out_unlock;
1038
1039 event = &pcmdptr->params.subscribe_event;
1040 event->action = cmd_act_set;
1041 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1042 sizeof(struct cmd_ds_802_11_subscribe_event) +
1043 sizeof(struct mrvlietypes_beaconsmissed));
1044 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1045 ptr = (u8*) pcmdptr+cmd_len;
1046 bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1047 bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1048 bcnmiss->header.len = 2;
1049 bcnmiss->beaconmissed = cpu_to_le16(value);
1050 event_bitmap |= subscribed ? 0x0008 : 0x0;
1051 event->events = event_bitmap;
1052
1053 libertas_queue_cmd(adapter, pcmdnode, 1);
1054 wake_up_interruptible(&priv->mainthread.waitq);
1055
1056 /* Sleep until response is generated by FW */
1057 wait_event_interruptible(pcmdnode->cmdwait_q,
1058 pcmdnode->cmdwaitqwoken);
1059
1060 pcmdptr = response_buf;
1061
1062 if (pcmdptr->result) {
1063 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1064 pcmdptr->result);
1065 kfree(response_buf);
1066 free_page(addr);
1067 return 0;
1068 }
1069
1070 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1071 lbs_pr_err("command response incorrect!\n");
1072 free_page(addr);
1073 kfree(response_buf);
1074 return 0;
1075 }
1076
1077 res = count;
1078out_unlock:
1079 free_page(addr);
1080 return res;
1081}
1082
1083static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1084 size_t count, loff_t *ppos)
1085{
1086 wlan_private *priv = file->private_data;
1087 wlan_adapter *adapter = priv->adapter;
1088 struct cmd_ctrl_node *pcmdnode;
1089 struct cmd_ds_command *pcmdptr;
1090 struct cmd_ds_802_11_subscribe_event *event;
1091 void *response_buf;
1092 int res, cmd_len;
1093 ssize_t pos = 0;
1094 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1095 char *buf = (char *)addr;
1096
1097 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1098 if (res < 0) {
1099 free_page(addr);
1100 return res;
1101 }
1102
1103 event = &pcmdptr->params.subscribe_event;
1104 event->action = cmd_act_get;
1105 pcmdptr->size =
1106 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1107 libertas_queue_cmd(adapter, pcmdnode, 1);
1108 wake_up_interruptible(&priv->mainthread.waitq);
1109
1110 /* Sleep until response is generated by FW */
1111 wait_event_interruptible(pcmdnode->cmdwait_q,
1112 pcmdnode->cmdwaitqwoken);
1113
1114 pcmdptr = response_buf;
1115
1116 if (pcmdptr->result) {
1117 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1118 pcmdptr->result);
1119 kfree(response_buf);
1120 free_page(addr);
1121 return 0;
1122 }
1123
1124 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1125 lbs_pr_err("command response incorrect!\n");
1126 kfree(response_buf);
1127 free_page(addr);
1128 return 0;
1129 }
1130
1131 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1132 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1133 while (cmd_len < pcmdptr->size) {
1134 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1135 switch(header->type) {
1136 struct mrvlietypes_rssithreshold *Highrssi;
1137 case TLV_TYPE_RSSI_HIGH:
1138 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1139 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1140 Highrssi->rssivalue,
1141 Highrssi->rssifreq,
1142 (event->events & 0x0010)?1:0);
1143 default:
1144 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1145 break;
1146 }
1147 }
1148
1149 kfree(response_buf);
1150
1151 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1152 free_page(addr);
1153 return res;
1154}
1155
1156static ssize_t libertas_highrssi_write(struct file *file,
1157 const char __user *userbuf,
1158 size_t count, loff_t *ppos)
1159{
1160 wlan_private *priv = file->private_data;
1161 wlan_adapter *adapter = priv->adapter;
1162 ssize_t res, buf_size;
1163 int value, freq, subscribed, cmd_len;
1164 struct cmd_ctrl_node *pcmdnode;
1165 struct cmd_ds_command *pcmdptr;
1166 struct cmd_ds_802_11_subscribe_event *event;
1167 struct mrvlietypes_rssithreshold *rssi_threshold;
1168 void *response_buf;
1169 u16 event_bitmap;
1170 u8 *ptr;
1171 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1172 char *buf = (char *)addr;
1173
1174 buf_size = min(count, len - 1);
1175 if (copy_from_user(buf, userbuf, buf_size)) {
1176 res = -EFAULT;
1177 goto out_unlock;
1178 }
1179 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1180 if (res != 3) {
1181 res = -EFAULT;
1182 goto out_unlock;
1183 }
1184
1185 event_bitmap = libertas_get_events_bitmap(priv);
1186
1187 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1188 if (res < 0)
1189 goto out_unlock;
1190
1191 event = &pcmdptr->params.subscribe_event;
1192 event->action = cmd_act_set;
1193 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1194 sizeof(struct cmd_ds_802_11_subscribe_event) +
1195 sizeof(struct mrvlietypes_rssithreshold));
1196 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1197 ptr = (u8*) pcmdptr+cmd_len;
1198 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1199 rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1200 rssi_threshold->header.len = 2;
1201 rssi_threshold->rssivalue = cpu_to_le16(value);
1202 rssi_threshold->rssifreq = cpu_to_le16(freq);
1203 event_bitmap |= subscribed ? 0x0010 : 0x0;
1204 event->events = event_bitmap;
1205
1206 libertas_queue_cmd(adapter, pcmdnode, 1);
1207 wake_up_interruptible(&priv->mainthread.waitq);
1208
1209 /* Sleep until response is generated by FW */
1210 wait_event_interruptible(pcmdnode->cmdwait_q,
1211 pcmdnode->cmdwaitqwoken);
1212
1213 pcmdptr = response_buf;
1214
1215 if (pcmdptr->result) {
1216 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1217 pcmdptr->result);
1218 kfree(response_buf);
1219 return 0;
1220 }
1221
1222 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1223 lbs_pr_err("command response incorrect!\n");
1224 kfree(response_buf);
1225 return 0;
1226 }
1227
1228 res = count;
1229out_unlock:
1230 free_page(addr);
1231 return res;
1232}
1233
1234static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1235 size_t count, loff_t *ppos)
1236{
1237 wlan_private *priv = file->private_data;
1238 wlan_adapter *adapter = priv->adapter;
1239 struct cmd_ctrl_node *pcmdnode;
1240 struct cmd_ds_command *pcmdptr;
1241 struct cmd_ds_802_11_subscribe_event *event;
1242 void *response_buf;
1243 int res, cmd_len;
1244 ssize_t pos = 0;
1245 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1246 char *buf = (char *)addr;
1247
1248 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1249 if (res < 0) {
1250 free_page(addr);
1251 return res;
1252 }
1253
1254 event = &pcmdptr->params.subscribe_event;
1255 event->action = cmd_act_get;
1256 pcmdptr->size =
1257 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1258 libertas_queue_cmd(adapter, pcmdnode, 1);
1259 wake_up_interruptible(&priv->mainthread.waitq);
1260
1261 /* Sleep until response is generated by FW */
1262 wait_event_interruptible(pcmdnode->cmdwait_q,
1263 pcmdnode->cmdwaitqwoken);
1264
1265 pcmdptr = response_buf;
1266
1267 if (pcmdptr->result) {
1268 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1269 pcmdptr->result);
1270 kfree(response_buf);
1271 free_page(addr);
1272 return 0;
1273 }
1274
1275 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1276 lbs_pr_err("command response incorrect!\n");
1277 kfree(response_buf);
1278 free_page(addr);
1279 return 0;
1280 }
1281
1282 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1283 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1284 while (cmd_len < pcmdptr->size) {
1285 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1286 switch(header->type) {
1287 struct mrvlietypes_snrthreshold *HighSnr;
1288 case TLV_TYPE_SNR_HIGH:
1289 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1290 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1291 HighSnr->snrvalue,
1292 HighSnr->snrfreq,
1293 (event->events & 0x0020)?1:0);
1294 default:
1295 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1296 break;
1297 }
1298 }
1299
1300 kfree(response_buf);
1301
1302 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1303 free_page(addr);
1304 return res;
1305}
1306
1307static ssize_t libertas_highsnr_write(struct file *file,
1308 const char __user *userbuf,
1309 size_t count, loff_t *ppos)
1310{
1311 wlan_private *priv = file->private_data;
1312 wlan_adapter *adapter = priv->adapter;
1313 ssize_t res, buf_size;
1314 int value, freq, subscribed, cmd_len;
1315 struct cmd_ctrl_node *pcmdnode;
1316 struct cmd_ds_command *pcmdptr;
1317 struct cmd_ds_802_11_subscribe_event *event;
1318 struct mrvlietypes_snrthreshold *snr_threshold;
1319 void *response_buf;
1320 u16 event_bitmap;
1321 u8 *ptr;
1322 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1323 char *buf = (char *)addr;
1324
1325 buf_size = min(count, len - 1);
1326 if (copy_from_user(buf, userbuf, buf_size)) {
1327 res = -EFAULT;
1328 goto out_unlock;
1329 }
1330 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1331 if (res != 3) {
1332 res = -EFAULT;
1333 goto out_unlock;
1334 }
1335
1336 event_bitmap = libertas_get_events_bitmap(priv);
1337
1338 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1339 if (res < 0)
1340 goto out_unlock;
1341
1342 event = &pcmdptr->params.subscribe_event;
1343 event->action = cmd_act_set;
1344 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1345 sizeof(struct cmd_ds_802_11_subscribe_event) +
1346 sizeof(struct mrvlietypes_snrthreshold));
1347 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1348 ptr = (u8*) pcmdptr+cmd_len;
1349 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1350 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1351 snr_threshold->header.len = 2;
1352 snr_threshold->snrvalue = cpu_to_le16(value);
1353 snr_threshold->snrfreq = cpu_to_le16(freq);
1354 event_bitmap |= subscribed ? 0x0020 : 0x0;
1355 event->events = event_bitmap;
1356
1357 libertas_queue_cmd(adapter, pcmdnode, 1);
1358 wake_up_interruptible(&priv->mainthread.waitq);
1359
1360 /* Sleep until response is generated by FW */
1361 wait_event_interruptible(pcmdnode->cmdwait_q,
1362 pcmdnode->cmdwaitqwoken);
1363
1364 pcmdptr = response_buf;
1365
1366 if (pcmdptr->result) {
1367 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1368 pcmdptr->result);
1369 kfree(response_buf);
1370 free_page(addr);
1371 return 0;
1372 }
1373
1374 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1375 lbs_pr_err("command response incorrect!\n");
1376 kfree(response_buf);
1377 free_page(addr);
1378 return 0;
1379 }
1380
1381 res = count;
1382out_unlock:
1383 free_page(addr);
1384 return res;
1385}
1386
1387static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1388 size_t count, loff_t *ppos)
1389{
1390 wlan_private *priv = file->private_data;
1391 wlan_adapter *adapter = priv->adapter;
1392 struct wlan_offset_value offval;
1393 ssize_t pos = 0;
1394 int ret;
1395 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1396 char *buf = (char *)addr;
1397
1398 offval.offset = priv->mac_offset;
1399 offval.value = 0;
1400
1401 ret = libertas_prepare_and_send_command(priv,
1402 cmd_mac_reg_access, 0,
1403 cmd_option_waitforrsp, 0, &offval);
1404 mdelay(10);
1405 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1406 priv->mac_offset, adapter->offsetvalue.value);
1407
1408 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1409 free_page(addr);
1410 return ret;
1411}
1412
1413static ssize_t libertas_rdmac_write(struct file *file,
1414 const char __user *userbuf,
1415 size_t count, loff_t *ppos)
1416{
1417 wlan_private *priv = file->private_data;
1418 ssize_t res, buf_size;
1419 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1420 char *buf = (char *)addr;
1421
1422 buf_size = min(count, len - 1);
1423 if (copy_from_user(buf, userbuf, buf_size)) {
1424 res = -EFAULT;
1425 goto out_unlock;
1426 }
1427 priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1428 res = count;
1429out_unlock:
1430 free_page(addr);
1431 return res;
1432}
1433
1434static ssize_t libertas_wrmac_write(struct file *file,
1435 const char __user *userbuf,
1436 size_t count, loff_t *ppos)
1437{
1438
1439 wlan_private *priv = file->private_data;
1440 ssize_t res, buf_size;
1441 u32 offset, value;
1442 struct wlan_offset_value offval;
1443 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1444 char *buf = (char *)addr;
1445
1446 buf_size = min(count, len - 1);
1447 if (copy_from_user(buf, userbuf, buf_size)) {
1448 res = -EFAULT;
1449 goto out_unlock;
1450 }
1451 res = sscanf(buf, "%x %x", &offset, &value);
1452 if (res != 2) {
1453 res = -EFAULT;
1454 goto out_unlock;
1455 }
1456
1457 offval.offset = offset;
1458 offval.value = value;
1459 res = libertas_prepare_and_send_command(priv,
1460 cmd_mac_reg_access, 1,
1461 cmd_option_waitforrsp, 0, &offval);
1462 mdelay(10);
1463
1464 res = count;
1465out_unlock:
1466 free_page(addr);
1467 return res;
1468}
1469
1470static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1471 size_t count, loff_t *ppos)
1472{
1473 wlan_private *priv = file->private_data;
1474 wlan_adapter *adapter = priv->adapter;
1475 struct wlan_offset_value offval;
1476 ssize_t pos = 0;
1477 int ret;
1478 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1479 char *buf = (char *)addr;
1480
1481 offval.offset = priv->bbp_offset;
1482 offval.value = 0;
1483
1484 ret = libertas_prepare_and_send_command(priv,
1485 cmd_bbp_reg_access, 0,
1486 cmd_option_waitforrsp, 0, &offval);
1487 mdelay(10);
1488 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1489 priv->bbp_offset, adapter->offsetvalue.value);
1490
1491 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1492 free_page(addr);
1493
1494 return ret;
1495}
1496
1497static ssize_t libertas_rdbbp_write(struct file *file,
1498 const char __user *userbuf,
1499 size_t count, loff_t *ppos)
1500{
1501 wlan_private *priv = file->private_data;
1502 ssize_t res, buf_size;
1503 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1504 char *buf = (char *)addr;
1505
1506 buf_size = min(count, len - 1);
1507 if (copy_from_user(buf, userbuf, buf_size)) {
1508 res = -EFAULT;
1509 goto out_unlock;
1510 }
1511 priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1512 res = count;
1513out_unlock:
1514 free_page(addr);
1515 return res;
1516}
1517
1518static ssize_t libertas_wrbbp_write(struct file *file,
1519 const char __user *userbuf,
1520 size_t count, loff_t *ppos)
1521{
1522
1523 wlan_private *priv = file->private_data;
1524 ssize_t res, buf_size;
1525 u32 offset, value;
1526 struct wlan_offset_value offval;
1527 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1528 char *buf = (char *)addr;
1529
1530 buf_size = min(count, len - 1);
1531 if (copy_from_user(buf, userbuf, buf_size)) {
1532 res = -EFAULT;
1533 goto out_unlock;
1534 }
1535 res = sscanf(buf, "%x %x", &offset, &value);
1536 if (res != 2) {
1537 res = -EFAULT;
1538 goto out_unlock;
1539 }
1540
1541 offval.offset = offset;
1542 offval.value = value;
1543 res = libertas_prepare_and_send_command(priv,
1544 cmd_bbp_reg_access, 1,
1545 cmd_option_waitforrsp, 0, &offval);
1546 mdelay(10);
1547
1548 res = count;
1549out_unlock:
1550 free_page(addr);
1551 return res;
1552}
1553
1554static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1555 size_t count, loff_t *ppos)
1556{
1557 wlan_private *priv = file->private_data;
1558 wlan_adapter *adapter = priv->adapter;
1559 struct wlan_offset_value offval;
1560 ssize_t pos = 0;
1561 int ret;
1562 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1563 char *buf = (char *)addr;
1564
1565 offval.offset = priv->rf_offset;
1566 offval.value = 0;
1567
1568 ret = libertas_prepare_and_send_command(priv,
1569 cmd_rf_reg_access, 0,
1570 cmd_option_waitforrsp, 0, &offval);
1571 mdelay(10);
1572 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1573 priv->rf_offset, adapter->offsetvalue.value);
1574
1575 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1576 free_page(addr);
1577
1578 return ret;
1579}
1580
1581static ssize_t libertas_rdrf_write(struct file *file,
1582 const char __user *userbuf,
1583 size_t count, loff_t *ppos)
1584{
1585 wlan_private *priv = file->private_data;
1586 ssize_t res, buf_size;
1587 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1588 char *buf = (char *)addr;
1589
1590 buf_size = min(count, len - 1);
1591 if (copy_from_user(buf, userbuf, buf_size)) {
1592 res = -EFAULT;
1593 goto out_unlock;
1594 }
1595 priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1596 res = count;
1597out_unlock:
1598 free_page(addr);
1599 return res;
1600}
1601
1602static ssize_t libertas_wrrf_write(struct file *file,
1603 const char __user *userbuf,
1604 size_t count, loff_t *ppos)
1605{
1606
1607 wlan_private *priv = file->private_data;
1608 ssize_t res, buf_size;
1609 u32 offset, value;
1610 struct wlan_offset_value offval;
1611 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1612 char *buf = (char *)addr;
1613
1614 buf_size = min(count, len - 1);
1615 if (copy_from_user(buf, userbuf, buf_size)) {
1616 res = -EFAULT;
1617 goto out_unlock;
1618 }
1619 res = sscanf(buf, "%x %x", &offset, &value);
1620 if (res != 2) {
1621 res = -EFAULT;
1622 goto out_unlock;
1623 }
1624
1625 offval.offset = offset;
1626 offval.value = value;
1627 res = libertas_prepare_and_send_command(priv,
1628 cmd_rf_reg_access, 1,
1629 cmd_option_waitforrsp, 0, &offval);
1630 mdelay(10);
1631
1632 res = count;
1633out_unlock:
1634 free_page(addr);
1635 return res;
1636}
1637
1638#define FOPS(fread, fwrite) { \
1639 .owner = THIS_MODULE, \
1640 .open = open_file_generic, \
1641 .read = (fread), \
1642 .write = (fwrite), \
1643}
1644
1645struct libertas_debugfs_files {
1646 char *name;
1647 int perm;
1648 struct file_operations fops;
1649};
1650
1651struct libertas_debugfs_files debugfs_files[] = {
1652 { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1653 { "getscantable", 0444, FOPS(libertas_getscantable,
1654 write_file_dummy), },
1655 { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1656 libertas_sleepparams_write), },
1657 { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1658 { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1659};
1660
1661struct libertas_debugfs_files debugfs_events_files[] = {
1662 {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1663 libertas_lowrssi_write), },
1664 {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1665 libertas_lowsnr_write), },
1666 {"failure_count", 0644, FOPS(libertas_failcount_read,
1667 libertas_failcount_write), },
1668 {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1669 libertas_bcnmiss_write), },
1670 {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1671 libertas_highrssi_write), },
1672 {"high_snr", 0644, FOPS(libertas_highsnr_read,
1673 libertas_highsnr_write), },
1674};
1675
1676struct libertas_debugfs_files debugfs_regs_files[] = {
1677 {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1678 {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1679 {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1680 {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1681 {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1682 {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1683};
1684
1685void libertas_debugfs_init(void)
1686{
1687 if (!libertas_dir)
1688 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1689
1690 return;
1691}
1692
1693void libertas_debugfs_remove(void)
1694{
1695 if (libertas_dir)
1696 debugfs_remove(libertas_dir);
1697 return;
1698}
1699
1700void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1701{
1702 int i;
1703 struct libertas_debugfs_files *files;
1704 if (!libertas_dir)
1705 goto exit;
1706
1707 priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1708 if (!priv->debugfs_dir)
1709 goto exit;
1710
1711 for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1712 files = &debugfs_files[i];
1713 priv->debugfs_files[i] = debugfs_create_file(files->name,
1714 files->perm,
1715 priv->debugfs_dir,
1716 priv,
1717 &files->fops);
1718 }
1719
1720 priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1721 if (!priv->events_dir)
1722 goto exit;
1723
1724 for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1725 files = &debugfs_events_files[i];
1726 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1727 files->perm,
1728 priv->events_dir,
1729 priv,
1730 &files->fops);
1731 }
1732
1733 priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1734 if (!priv->regs_dir)
1735 goto exit;
1736
1737 for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1738 files = &debugfs_regs_files[i];
1739 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1740 files->perm,
1741 priv->regs_dir,
1742 priv,
1743 &files->fops);
1744 }
1745
1746#ifdef PROC_DEBUG
1747 libertas_debug_init(priv, dev);
1748#endif
1749exit:
1750 return;
1751}
1752
1753void libertas_debugfs_remove_one(wlan_private *priv)
1754{
1755 int i;
1756
1757 for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1758 debugfs_remove(priv->debugfs_regs_files[i]);
1759
1760 debugfs_remove(priv->regs_dir);
1761
1762 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1763 debugfs_remove(priv->debugfs_events_files[i]);
1764
1765 debugfs_remove(priv->events_dir);
1766#ifdef PROC_DEBUG
1767 debugfs_remove(priv->debugfs_debug);
1768#endif
1769 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1770 debugfs_remove(priv->debugfs_files[i]);
1771}
1772
1773/* debug entry */
1774
1775#define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
1776#define item_addr(n) (offsetof(wlan_adapter, n))
1777
1778struct debug_data {
1779 char name[32];
1780 u32 size;
1781 u32 addr;
1782};
1783
1784/* To debug any member of wlan_adapter, simply add one line here.
1785 */
1786static struct debug_data items[] = {
1787 {"intcounter", item_size(intcounter), item_addr(intcounter)},
1788 {"psmode", item_size(psmode), item_addr(psmode)},
1789 {"psstate", item_size(psstate), item_addr(psstate)},
1790};
1791
1792static int num_of_items = ARRAY_SIZE(items);
1793
1794/**
1795 * @brief proc read function
1796 *
1797 * @param page pointer to buffer
1798 * @param s read data starting position
1799 * @param off offset
1800 * @param cnt counter
1801 * @param eof end of file flag
1802 * @param data data to output
1803 * @return number of output data
1804 */
1805static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1806 size_t count, loff_t *ppos)
1807{
1808 int val = 0;
1809 size_t pos = 0;
1810 ssize_t res;
1811 char *p;
1812 int i;
1813 struct debug_data *d;
1814 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1815 char *buf = (char *)addr;
1816
1817 p = buf;
1818
1819 d = (struct debug_data *)file->private_data;
1820
1821 for (i = 0; i < num_of_items; i++) {
1822 if (d[i].size == 1)
1823 val = *((u8 *) d[i].addr);
1824 else if (d[i].size == 2)
1825 val = *((u16 *) d[i].addr);
1826 else if (d[i].size == 4)
1827 val = *((u32 *) d[i].addr);
1828
1829 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1830 }
1831
1832 res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1833
1834 free_page(addr);
1835 return res;
1836}
1837
1838/**
1839 * @brief proc write function
1840 *
1841 * @param f file pointer
1842 * @param buf pointer to data buffer
1843 * @param cnt data number to write
1844 * @param data data to write
1845 * @return number of data
1846 */
1847static int wlan_debugfs_write(struct file *f, const char __user *buf,
1848 size_t cnt, loff_t *ppos)
1849{
1850 int r, i;
1851 char *pdata;
1852 char *p;
1853 char *p0;
1854 char *p1;
1855 char *p2;
1856 struct debug_data *d = (struct debug_data *)f->private_data;
1857
1858 pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1859 if (pdata == NULL)
1860 return 0;
1861
1862 if (copy_from_user(pdata, buf, cnt)) {
1863 lbs_pr_debug(1, "Copy from user failed\n");
1864 kfree(pdata);
1865 return 0;
1866 }
1867
1868 p0 = pdata;
1869 for (i = 0; i < num_of_items; i++) {
1870 do {
1871 p = strstr(p0, d[i].name);
1872 if (p == NULL)
1873 break;
1874 p1 = strchr(p, '\n');
1875 if (p1 == NULL)
1876 break;
1877 p0 = p1++;
1878 p2 = strchr(p, '=');
1879 if (!p2)
1880 break;
1881 p2++;
1882 r = simple_strtoul(p2, NULL, 0);
1883 if (d[i].size == 1)
1884 *((u8 *) d[i].addr) = (u8) r;
1885 else if (d[i].size == 2)
1886 *((u16 *) d[i].addr) = (u16) r;
1887 else if (d[i].size == 4)
1888 *((u32 *) d[i].addr) = (u32) r;
1889 break;
1890 } while (1);
1891 }
1892 kfree(pdata);
1893
1894 return cnt;
1895}
1896
1897static struct file_operations libertas_debug_fops = {
1898 .owner = THIS_MODULE,
1899 .open = open_file_generic,
1900 .write = wlan_debugfs_write,
1901 .read = wlan_debugfs_read,
1902};
1903
1904/**
1905 * @brief create debug proc file
1906 *
1907 * @param priv pointer wlan_private
1908 * @param dev pointer net_device
1909 * @return N/A
1910 */
1911void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1912{
1913 int i;
1914
1915 if (!priv->debugfs_dir)
1916 return;
1917
1918 for (i = 0; i < num_of_items; i++)
1919 items[i].addr += (u32) priv->adapter;
1920
1921 priv->debugfs_debug = debugfs_create_file("debug", 0644,
1922 priv->debugfs_dir, &items[0],
1923 &libertas_debug_fops);
1924}
1925
1926/**
1927 * @brief remove proc file
1928 *
1929 * @param priv pointer wlan_private
1930 * @return N/A
1931 */
1932void libertas_debug_remove(wlan_private * priv)
1933{
1934 debugfs_remove(priv->debugfs_debug);
1935}
diff --git a/drivers/net/wireless/libertas/debugfs.h b/drivers/net/wireless/libertas/debugfs.h
new file mode 100644
index 000000000000..880a11b95d26
--- /dev/null
+++ b/drivers/net/wireless/libertas/debugfs.h
@@ -0,0 +1,6 @@
1void libertas_debugfs_init(void);
2void libertas_debugfs_remove(void);
3
4void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev);
5void libertas_debugfs_remove_one(wlan_private *priv);
6
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
new file mode 100644
index 000000000000..606bdd002be7
--- /dev/null
+++ b/drivers/net/wireless/libertas/decl.h
@@ -0,0 +1,83 @@
1/**
2 * This file contains declaration referring to
3 * functions defined in other source files
4 */
5
6#ifndef _WLAN_DECL_H_
7#define _WLAN_DECL_H_
8
9#include "defs.h"
10
11/** Function Prototype Declaration */
12struct wlan_private;
13struct sk_buff;
14struct net_device;
15
16extern char *libertas_fw_name;
17
18void libertas_free_adapter(wlan_private * priv);
19int libertas_set_mac_packet_filter(wlan_private * priv);
20
21int libertas_send_null_packet(wlan_private * priv, u8 pwr_mgmt);
22void libertas_send_tx_feedback(wlan_private * priv);
23u8 libertas_check_last_packet_indication(wlan_private * priv);
24
25int libertas_free_cmd_buffer(wlan_private * priv);
26struct cmd_ctrl_node;
27struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv);
28
29void libertas_set_cmd_ctrl_node(wlan_private * priv,
30 struct cmd_ctrl_node *ptempnode,
31 u32 cmd_oid, u16 wait_option, void *pdata_buf);
32
33int libertas_prepare_and_send_command(wlan_private * priv,
34 u16 cmd_no,
35 u16 cmd_action,
36 u16 wait_option, u32 cmd_oid, void *pdata_buf);
37
38void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail);
39
40int libertas_allocate_cmd_buffer(wlan_private * priv);
41int libertas_execute_next_command(wlan_private * priv);
42int libertas_process_event(wlan_private * priv);
43void libertas_interrupt(struct net_device *);
44int libertas_set_radio_control(wlan_private * priv);
45u32 libertas_index_to_data_rate(u8 index);
46u8 libertas_data_rate_to_index(u32 rate);
47void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
48
49int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
50
51/** The proc fs interface */
52int libertas_process_rx_command(wlan_private * priv);
53int libertas_process_tx(wlan_private * priv, struct sk_buff *skb);
54void libertas_cleanup_and_insert_cmd(wlan_private * priv,
55 struct cmd_ctrl_node *ptempcmd);
56void __libertas_cleanup_and_insert_cmd(wlan_private * priv,
57 struct cmd_ctrl_node *ptempcmd);
58
59int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band);
60
61int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *);
62
63void libertas_ps_sleep(wlan_private * priv, int wait_option);
64void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode);
65void libertas_ps_wakeup(wlan_private * priv, int wait_option);
66
67void libertas_tx_runqueue(wlan_private *priv);
68
69extern struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
70 wlan_adapter * adapter, u8 band, u16 channel);
71
72extern void libertas_mac_event_disconnected(wlan_private * priv);
73
74void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
75
76int reset_device(wlan_private *priv);
77/* main.c */
78extern struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
79 int *cfp_no);
80wlan_private *wlan_add_card(void *card);
81int wlan_remove_card(void *card);
82
83#endif /* _WLAN_DECL_H_ */
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
new file mode 100644
index 000000000000..fb1478c1b87d
--- /dev/null
+++ b/drivers/net/wireless/libertas/defs.h
@@ -0,0 +1,369 @@
1/**
2 * This header file contains global constant/enum definitions,
3 * global variable declaration.
4 */
5#ifndef _WLAN_DEFS_H_
6#define _WLAN_DEFS_H_
7
8#include <linux/spinlock.h>
9
10extern unsigned int libertas_debug;
11
12#define DRV_NAME "usb8xxx"
13
14#define lbs_pr_info(format, args...) \
15 printk(KERN_INFO DRV_NAME": " format, ## args)
16#define lbs_pr_err(format, args...) \
17 printk(KERN_ERR DRV_NAME": " format, ## args)
18#define lbs_pr_alert(format, args...) \
19 printk(KERN_ALERT DRV_NAME": " format, ## args)
20
21#ifdef DEBUG
22#define lbs_pr_debug(level, format, args...) \
23 do { if (libertas_debug >= level) \
24 printk(KERN_INFO DRV_NAME": " format, ##args); } while (0)
25#define lbs_dev_dbg(level, device, format, args...) \
26 lbs_pr_debug(level, "%s: " format, \
27 (device)->bus_id , ## args)
28
29static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
30{
31 int i = 0;
32
33 if (!libertas_debug)
34 return;
35
36 printk(KERN_DEBUG "%s: ", prompt);
37 for (i = 1; i <= len; i++) {
38 printk(KERN_DEBUG "%02x ", (u8) * buf);
39 buf++;
40 }
41 printk("\n");
42}
43#else
44#define lbs_pr_debug(level, format, args...) do {} while (0)
45#define lbs_dev_dbg(level, device, format, args...) do {} while (0)
46#define lbs_dbg_hex(x,y,z) do {} while (0)
47#endif
48
49#define ENTER() lbs_pr_debug(1, "Enter: %s, %s:%i\n", \
50 __FUNCTION__, __FILE__, __LINE__)
51#define LEAVE() lbs_pr_debug(1, "Leave: %s, %s:%i\n", \
52 __FUNCTION__, __FILE__, __LINE__)
53
54/** Buffer Constants */
55
56/* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
57* addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
58* driver has more local TxPDs. Each TxPD on the host memory is associated
59* with a Tx control node. The driver maintains 8 RxPD descriptors for
60* station firmware to store Rx packet information.
61*
62* Current version of MAC has a 32x6 multicast address buffer.
63*
64* 802.11b can have up to 14 channels, the driver keeps the
65* BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
66*/
67
68#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
69#define MRVDRV_NUM_OF_CMD_BUFFER 10
70#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
71#define MRVDRV_MAX_CHANNEL_SIZE 14
72#define MRVDRV_MAX_BSSID_LIST 64
73#define MRVDRV_ASSOCIATION_TIME_OUT 255
74#define MRVDRV_SNAP_HEADER_LEN 8
75
76#define WLAN_UPLD_SIZE 2312
77#define DEV_NAME_LEN 32
78
79/** Misc constants */
80/* This section defines 802.11 specific contants */
81
82#define MRVDRV_MAX_BSS_DESCRIPTS 16
83#define MRVDRV_MAX_REGION_CODE 6
84
85#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe
86#define MRVDRV_MIN_MULTIPLE_DTIM 1
87#define MRVDRV_MAX_MULTIPLE_DTIM 5
88#define MRVDRV_DEFAULT_MULTIPLE_DTIM 1
89
90#define MRVDRV_DEFAULT_LISTEN_INTERVAL 10
91
92#define MRVDRV_CHANNELS_PER_SCAN 4
93#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
94
95#define MRVDRV_DEBUG_RX_PATH 0x00000001
96#define MRVDRV_DEBUG_TX_PATH 0x00000002
97
98#define MRVDRV_MIN_BEACON_INTERVAL 20
99#define MRVDRV_MAX_BEACON_INTERVAL 1000
100#define MRVDRV_BEACON_INTERVAL 100
101
102/** TxPD status */
103
104/* Station firmware use TxPD status field to report final Tx transmit
105* result, Bit masks are used to present combined situations.
106*/
107
108#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
109#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
110
111/** Tx mesh flag */
112/* Currently we are using normal WDS flag as mesh flag.
113 * TODO: change to proper mesh flag when MAC understands it.
114 */
115#define TxPD_CONTROL_WDS_FRAME (1<<17)
116#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
117
118/** RxPD status */
119
120#define MRVDRV_RXPD_STATUS_OK 0x0001
121
122/** RxPD status - Received packet types */
123/** Rx mesh flag */
124/* Currently we are using normal WDS flag as mesh flag.
125 * TODO: change to proper mesh flag when MAC understands it.
126 */
127#define RxPD_CONTROL_WDS_FRAME (0x40)
128#define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME
129
130/** RSSI-related defines */
131/* RSSI constants are used to implement 802.11 RSSI threshold
132* indication. if the Rx packet signal got too weak for 5 consecutive
133* times, miniport driver (driver) will report this event to wrapper
134*/
135
136#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)
137
138/** RTS/FRAG related defines */
139#define MRVDRV_RTS_MIN_VALUE 0
140#define MRVDRV_RTS_MAX_VALUE 2347
141#define MRVDRV_FRAG_MIN_VALUE 256
142#define MRVDRV_FRAG_MAX_VALUE 2346
143
144/* This is for firmware specific length */
145#define EXTRA_LEN 36
146
147#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
148 (ETH_FRAME_LEN + sizeof(struct txpd) + EXTRA_LEN)
149
150#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
151 (ETH_FRAME_LEN + sizeof(struct rxpd) \
152 + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
153
154#define CMD_F_HOSTCMD (1 << 0)
155#define FW_CAPINFO_WPA (1 << 0)
156
157/** WPA key LENGTH*/
158#define MRVL_MAX_KEY_WPA_KEY_LENGTH 32
159
160#define KEY_LEN_WPA_AES 16
161#define KEY_LEN_WPA_TKIP 32
162#define KEY_LEN_WEP_104 13
163#define KEY_LEN_WEP_40 5
164
165#define RF_ANTENNA_1 0x1
166#define RF_ANTENNA_2 0x2
167#define RF_ANTENNA_AUTO 0xFFFF
168
169#define BAND_B (0x01)
170#define BAND_G (0x02)
171#define ALL_802_11_BANDS (BAND_B | BAND_G)
172
173/** MACRO DEFINITIONS */
174#define CAL_NF(NF) ((s32)(-(s32)(NF)))
175#define CAL_RSSI(SNR, NF) ((s32)((s32)(SNR) + CAL_NF(NF)))
176#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
177
178#define DEFAULT_BCN_AVG_FACTOR 8
179#define DEFAULT_DATA_AVG_FACTOR 8
180#define AVG_SCALE 100
181#define CAL_AVG_SNR_NF(AVG, SNRNF, N) \
182 (((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \
183 ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \
184 AVG_SCALE)) / N))
185
186#define B_SUPPORTED_RATES 8
187#define G_SUPPORTED_RATES 14
188
189#define WLAN_SUPPORTED_RATES 14
190
191#define MAX_LEDS 8
192
193#define IS_MESH_FRAME(x) (x->cb[6])
194#define SET_MESH_FRAME(x) (x->cb[6]=1)
195#define UNSET_MESH_FRAME(x) (x->cb[6]=0)
196
197/** Global Variable Declaration */
198typedef struct _wlan_private wlan_private;
199typedef struct _wlan_adapter wlan_adapter;
200extern const char libertas_driver_version[];
201extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE];
202
203extern u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES];
204
205extern u8 libertas_supported_rates[G_SUPPORTED_RATES];
206
207extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES];
208
209extern u8 libertas_adhoc_rates_b[4];
210
211/** ENUM definition*/
212/** SNRNF_TYPE */
213enum SNRNF_TYPE {
214 TYPE_BEACON = 0,
215 TYPE_RXPD,
216 MAX_TYPE_B
217};
218
219/** SNRNF_DATA*/
220enum SNRNF_DATA {
221 TYPE_NOAVG = 0,
222 TYPE_AVG,
223 MAX_TYPE_AVG
224};
225
226/** WLAN_802_11_AUTH_ALG*/
227enum WLAN_802_11_AUTH_ALG {
228 AUTH_ALG_OPEN_SYSTEM = 1,
229 AUTH_ALG_SHARED_KEY = 2,
230 AUTH_ALG_NETWORK_EAP = 8,
231};
232
233/** WLAN_802_1X_AUTH_ALG */
234enum WLAN_802_1X_AUTH_ALG {
235 WLAN_1X_AUTH_ALG_NONE = 1,
236 WLAN_1X_AUTH_ALG_LEAP = 2,
237 WLAN_1X_AUTH_ALG_TLS = 4,
238 WLAN_1X_AUTH_ALG_TTLS = 8,
239 WLAN_1X_AUTH_ALG_MD5 = 16,
240};
241
242/** WLAN_802_11_ENCRYPTION_MODE */
243enum WLAN_802_11_ENCRYPTION_MODE {
244 CIPHER_NONE,
245 CIPHER_WEP40,
246 CIPHER_TKIP,
247 CIPHER_CCMP,
248 CIPHER_WEP104,
249};
250
251/** WLAN_802_11_POWER_MODE */
252enum WLAN_802_11_POWER_MODE {
253 wlan802_11powermodecam,
254 wlan802_11powermodemax_psp,
255 wlan802_11Powermodefast_psp,
256 /*not a real mode, defined as an upper bound */
257 wlan802_11powemodemax
258};
259
260/** PS_STATE */
261enum PS_STATE {
262 PS_STATE_FULL_POWER,
263 PS_STATE_AWAKE,
264 PS_STATE_PRE_SLEEP,
265 PS_STATE_SLEEP
266};
267
268/** DNLD_STATE */
269enum DNLD_STATE {
270 DNLD_RES_RECEIVED,
271 DNLD_DATA_SENT,
272 DNLD_CMD_SENT
273};
274
275/** WLAN_MEDIA_STATE */
276enum WLAN_MEDIA_STATE {
277 libertas_connected,
278 libertas_disconnected
279};
280
281/** WLAN_802_11_PRIVACY_FILTER */
282enum WLAN_802_11_PRIVACY_FILTER {
283 wlan802_11privfilteracceptall,
284 wlan802_11privfilter8021xWEP
285};
286
287/** mv_ms_type */
288enum mv_ms_type {
289 MVMS_DAT = 0,
290 MVMS_CMD = 1,
291 MVMS_TXDONE = 2,
292 MVMS_EVENT
293};
294
295/** WLAN_802_11_NETWORK_INFRASTRUCTURE */
296enum WLAN_802_11_NETWORK_INFRASTRUCTURE {
297 wlan802_11ibss,
298 wlan802_11infrastructure,
299 wlan802_11autounknown,
300 /*defined as upper bound */
301 wlan802_11infrastructuremax
302};
303
304/** WLAN_802_11_AUTHENTICATION_MODE */
305enum WLAN_802_11_AUTHENTICATION_MODE {
306 wlan802_11authmodeopen = 0x00,
307 wlan802_11authmodeshared = 0x01,
308 wlan802_11authmodenetworkEAP = 0x80,
309};
310
311/** WLAN_802_11_WEP_STATUS */
312enum WLAN_802_11_WEP_STATUS {
313 wlan802_11WEPenabled,
314 wlan802_11WEPdisabled,
315};
316
317/** SNMP_MIB_INDEX_e */
318enum SNMP_MIB_INDEX_e {
319 desired_bsstype_i = 0,
320 op_rateset_i,
321 bcnperiod_i,
322 dtimperiod_i,
323 assocrsp_timeout_i,
324 rtsthresh_i,
325 short_retrylim_i,
326 long_retrylim_i,
327 fragthresh_i,
328 dot11d_i,
329 dot11h_i,
330 manufid_i,
331 prodID_i,
332 manuf_oui_i,
333 manuf_name_i,
334 manuf_prodname_i,
335 manuf_prodver_i,
336};
337
338/** KEY_TYPE_ID */
339enum KEY_TYPE_ID {
340 KEY_TYPE_ID_WEP = 0,
341 KEY_TYPE_ID_TKIP,
342 KEY_TYPE_ID_AES
343};
344
345/** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
346enum KEY_INFO_WPA {
347 KEY_INFO_WPA_MCAST = 0x01,
348 KEY_INFO_WPA_UNICAST = 0x02,
349 KEY_INFO_WPA_ENABLED = 0x04
350};
351
352/** SNMP_MIB_VALUE_e */
353enum SNMP_MIB_VALUE_e {
354 SNMP_MIB_VALUE_INFRA = 1,
355 SNMP_MIB_VALUE_ADHOC
356};
357
358/* Default values for fwt commands. */
359#define FWT_DEFAULT_METRIC 0
360#define FWT_DEFAULT_DIR 1
361#define FWT_DEFAULT_SSN 0xffffffff
362#define FWT_DEFAULT_DSN 0
363#define FWT_DEFAULT_HOPCOUNT 0
364#define FWT_DEFAULT_TTL 0
365#define FWT_DEFAULT_EXPIRATION 0
366#define FWT_DEFAULT_SLEEPMODE 0
367#define FWT_DEFAULT_SNR 0
368
369#endif /* _WLAN_DEFS_H_ */
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
new file mode 100644
index 000000000000..b1f876f9693b
--- /dev/null
+++ b/drivers/net/wireless/libertas/dev.h
@@ -0,0 +1,403 @@
1/**
2 * This file contains definitions and data structures specific
3 * to Marvell 802.11 NIC. It contains the Device Information
4 * structure wlan_adapter.
5 */
6#ifndef _WLAN_DEV_H_
7#define _WLAN_DEV_H_
8
9#include <linux/netdevice.h>
10#include <linux/wireless.h>
11#include <linux/ethtool.h>
12#include <linux/debugfs.h>
13
14#include "defs.h"
15#include "scan.h"
16#include "thread.h"
17
18extern struct ethtool_ops libertas_ethtool_ops;
19
20#define MAX_BSSID_PER_CHANNEL 16
21
22#define NR_TX_QUEUE 3
23
24/* For the extended Scan */
25#define MAX_EXTENDED_SCAN_BSSID_LIST MAX_BSSID_PER_CHANNEL * \
26 MRVDRV_MAX_CHANNEL_SIZE + 1
27
28#define MAX_REGION_CHANNEL_NUM 2
29
30/** Chan-freq-TxPower mapping table*/
31struct chan_freq_power {
32 /** channel Number */
33 u16 channel;
34 /** frequency of this channel */
35 u32 freq;
36 /** Max allowed Tx power level */
37 u16 maxtxpower;
38 /** TRUE:channel unsupported; FLASE:supported*/
39 u8 unsupported;
40};
41
42/** region-band mapping table*/
43struct region_channel {
44 /** TRUE if this entry is valid */
45 u8 valid;
46 /** region code for US, Japan ... */
47 u8 region;
48 /** band B/G/A, used for BAND_CONFIG cmd */
49 u8 band;
50 /** Actual No. of elements in the array below */
51 u8 nrcfp;
52 /** chan-freq-txpower mapping table*/
53 struct chan_freq_power *CFP;
54};
55
56struct wlan_802_11_security {
57 u8 WPAenabled;
58 u8 WPA2enabled;
59 enum WLAN_802_11_WEP_STATUS WEPstatus;
60 enum WLAN_802_11_AUTHENTICATION_MODE authmode;
61 enum WLAN_802_1X_AUTH_ALG auth1xalg;
62 enum WLAN_802_11_ENCRYPTION_MODE Encryptionmode;
63};
64
65/** Current Basic Service Set State Structure */
66struct current_bss_params {
67 struct bss_descriptor bssdescriptor;
68 /** bssid */
69 u8 bssid[ETH_ALEN];
70 /** ssid */
71 struct WLAN_802_11_SSID ssid;
72
73 /** band */
74 u8 band;
75 /** channel */
76 u8 channel;
77 /** number of rates supported */
78 int numofrates;
79 /** supported rates*/
80 u8 datarates[WLAN_SUPPORTED_RATES];
81};
82
83/** sleep_params */
84struct sleep_params {
85 u16 sp_error;
86 u16 sp_offset;
87 u16 sp_stabletime;
88 u8 sp_calcontrol;
89 u8 sp_extsleepclk;
90 u16 sp_reserved;
91};
92
93/** Data structure for the Marvell WLAN device */
94typedef struct _wlan_dev {
95 /** device name */
96 char name[DEV_NAME_LEN];
97 /** card pointer */
98 void *card;
99 /** IO port */
100 u32 ioport;
101 /** Upload received */
102 u32 upld_rcv;
103 /** Upload type */
104 u32 upld_typ;
105 /** Upload length */
106 u32 upld_len;
107 /** netdev pointer */
108 struct net_device *netdev;
109 /* Upload buffer */
110 u8 upld_buf[WLAN_UPLD_SIZE];
111 /* Download sent:
112 bit0 1/0=data_sent/data_tx_done,
113 bit1 1/0=cmd_sent/cmd_tx_done,
114 all other bits reserved 0 */
115 u8 dnld_sent;
116} wlan_dev_t, *pwlan_dev_t;
117
118/* Mesh statistics */
119struct wlan_mesh_stats {
120 u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
121 u32 fwd_unicast_cnt; /* Fwd: Unicast counter */
122 u32 fwd_drop_ttl; /* Fwd: TTL zero */
123 u32 fwd_drop_rbt; /* Fwd: Recently Broadcasted */
124 u32 fwd_drop_noroute; /* Fwd: No route to Destination */
125 u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
126 u32 drop_blind; /* Rx: Dropped by blinding table */
127};
128
129/** Private structure for the MV device */
130struct _wlan_private {
131 int open;
132 int mesh_open;
133 int infra_open;
134
135 wlan_adapter *adapter;
136 wlan_dev_t wlan_dev;
137
138 struct net_device_stats stats;
139 struct net_device *mesh_dev ; /* Virtual device */
140
141 struct iw_statistics wstats;
142 struct wlan_mesh_stats mstats;
143 struct dentry *debugfs_dir;
144 struct dentry *debugfs_debug;
145 struct dentry *debugfs_files[6];
146
147 struct dentry *events_dir;
148 struct dentry *debugfs_events_files[6];
149
150 struct dentry *regs_dir;
151 struct dentry *debugfs_regs_files[6];
152
153 u32 mac_offset;
154 u32 bbp_offset;
155 u32 rf_offset;
156
157 const struct firmware *firmware;
158 struct device *hotplug_device;
159
160 /** thread to service interrupts */
161 struct wlan_thread mainthread;
162
163 struct delayed_work assoc_work;
164 struct workqueue_struct *assoc_thread;
165};
166
167/** Association request
168 *
169 * Encapsulates all the options that describe a specific assocation request
170 * or configuration of the wireless card's radio, mode, and security settings.
171 */
172struct assoc_request {
173#define ASSOC_FLAG_SSID 1
174#define ASSOC_FLAG_CHANNEL 2
175#define ASSOC_FLAG_MODE 3
176#define ASSOC_FLAG_BSSID 4
177#define ASSOC_FLAG_WEP_KEYS 5
178#define ASSOC_FLAG_WEP_TX_KEYIDX 6
179#define ASSOC_FLAG_WPA_MCAST_KEY 7
180#define ASSOC_FLAG_WPA_UCAST_KEY 8
181#define ASSOC_FLAG_SECINFO 9
182#define ASSOC_FLAG_WPA_IE 10
183 unsigned long flags;
184
185 struct WLAN_802_11_SSID ssid;
186 u8 channel;
187 enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode;
188 u8 bssid[ETH_ALEN];
189
190 /** WEP keys */
191 struct WLAN_802_11_KEY wep_keys[4];
192 u16 wep_tx_keyidx;
193
194 /** WPA keys */
195 struct WLAN_802_11_KEY wpa_mcast_key;
196 struct WLAN_802_11_KEY wpa_unicast_key;
197
198 struct wlan_802_11_security secinfo;
199
200 /** WPA Information Elements*/
201#define MAX_WPA_IE_LEN 64
202 u8 wpa_ie[MAX_WPA_IE_LEN];
203 u8 wpa_ie_len;
204};
205
206/** Wlan adapter data structure*/
207struct _wlan_adapter {
208 /** STATUS variables */
209 u32 fwreleasenumber;
210 u32 fwcapinfo;
211 /* protected with big lock */
212
213 struct mutex lock;
214
215 u8 tmptxbuf[WLAN_UPLD_SIZE];
216 /* protected by hard_start_xmit serialization */
217
218 /** command-related variables */
219 u16 seqnum;
220 /* protected by big lock */
221
222 struct cmd_ctrl_node *cmd_array;
223 /** Current command */
224 struct cmd_ctrl_node *cur_cmd;
225 int cur_cmd_retcode;
226 /** command Queues */
227 /** Free command buffers */
228 struct list_head cmdfreeq;
229 /** Pending command buffers */
230 struct list_head cmdpendingq;
231
232 wait_queue_head_t cmd_pending;
233 u8 nr_cmd_pending;
234 /* command related variables protected by adapter->driver_lock */
235
236 /** Async and Sync Event variables */
237 u32 intcounter;
238 u32 eventcause;
239 u8 nodename[16]; /* nickname */
240
241 /** spin locks */
242 spinlock_t driver_lock;
243
244 /** Timers */
245 struct timer_list command_timer;
246
247 /* TX queue used in PS mode */
248 spinlock_t txqueue_lock;
249 struct sk_buff *tx_queue_ps[NR_TX_QUEUE];
250 unsigned int tx_queue_idx;
251
252 u8 hisregcpy;
253
254 /** current ssid/bssid related parameters*/
255 struct current_bss_params curbssparams;
256
257 enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
258
259 struct bss_descriptor *pattemptedbssdesc;
260
261 struct WLAN_802_11_SSID previousssid;
262 u8 previousbssid[ETH_ALEN];
263
264 struct bss_descriptor *scantable;
265 u32 numinscantable;
266
267 u8 scantype;
268 u32 scanmode;
269
270 u16 beaconperiod;
271 u8 adhoccreate;
272
273 /** capability Info used in Association, start, join */
274 struct ieeetypes_capinfo capinfo;
275
276 /** MAC address information */
277 u8 current_addr[ETH_ALEN];
278 u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
279 u32 nr_of_multicastmacaddr;
280
281 /** 802.11 statistics */
282// struct cmd_DS_802_11_GET_STAT wlan802_11Stat;
283
284 u16 enablehwauto;
285 u16 ratebitmap;
286 /** control G rates */
287 u8 adhoc_grate_enabled;
288
289 u32 txantenna;
290 u32 rxantenna;
291
292 u8 adhocchannel;
293 u32 fragthsd;
294 u32 rtsthsd;
295
296 u32 datarate;
297 u8 is_datarate_auto;
298
299 u16 listeninterval;
300 u16 prescan;
301 u8 txretrycount;
302
303 /** Tx-related variables (for single packet tx) */
304 struct sk_buff *currenttxskb;
305 u16 TxLockFlag;
306
307 /** NIC Operation characteristics */
308 u16 currentpacketfilter;
309 u32 connect_status;
310 u16 regioncode;
311 u16 regiontableindex;
312 u16 txpowerlevel;
313
314 /** POWER MANAGEMENT AND PnP SUPPORT */
315 u8 surpriseremoved;
316 u16 atimwindow;
317
318 u16 psmode; /* Wlan802_11PowermodeCAM=disable
319 Wlan802_11PowermodeMAX_PSP=enable */
320 u16 multipledtim;
321 u32 psstate;
322 u8 needtowakeup;
323
324 struct PS_CMD_ConfirmSleep libertas_ps_confirm_sleep;
325 u16 locallisteninterval;
326 u16 nullpktinterval;
327
328 struct assoc_request * assoc_req;
329
330 /** Encryption parameter */
331 struct wlan_802_11_security secinfo;
332
333 /** WEP keys */
334 struct WLAN_802_11_KEY wep_keys[4];
335 u16 wep_tx_keyidx;
336
337 /** WPA keys */
338 struct WLAN_802_11_KEY wpa_mcast_key;
339 struct WLAN_802_11_KEY wpa_unicast_key;
340
341 /** WPA Information Elements*/
342#define MAX_WPA_IE_LEN 64
343 u8 wpa_ie[MAX_WPA_IE_LEN];
344 u8 wpa_ie_len;
345
346 u16 rxantennamode;
347 u16 txantennamode;
348
349 /** Requested Signal Strength*/
350 u16 bcn_avg_factor;
351 u16 data_avg_factor;
352 u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
353 u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
354 u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
355 u8 rawSNR[DEFAULT_DATA_AVG_FACTOR];
356 u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
357 u16 nextSNRNF;
358 u16 numSNRNF;
359 u16 rxpd_rate;
360
361 u8 radioon;
362 u32 preamble;
363
364 /** Multi bands Parameter*/
365 u8 libertas_supported_rates[G_SUPPORTED_RATES];
366
367 /** Blue Tooth Co-existence Arbitration */
368
369 /** sleep_params */
370 struct sleep_params sp;
371
372 /** RF calibration data */
373
374#define MAX_REGION_CHANNEL_NUM 2
375 /** region channel data */
376 struct region_channel region_channel[MAX_REGION_CHANNEL_NUM];
377
378 struct region_channel universal_channel[MAX_REGION_CHANNEL_NUM];
379
380 /** 11D and Domain Regulatory Data */
381 struct wlan_802_11d_domain_reg domainreg;
382 struct parsed_region_chan_11d parsed_region_chan;
383
384 /** FSM variable for 11d support */
385 u32 enable11d;
386
387 /** MISCELLANEOUS */
388 u8 *prdeeprom;
389 struct wlan_offset_value offsetvalue;
390
391 struct cmd_ds_802_11_get_log logmsg;
392 u16 scanprobes;
393
394 u32 pkttxctrl;
395
396 u16 txrate;
397 u32 linkmode;
398 u32 radiomode;
399 u32 debugmode;
400 u8 fw_ready;
401};
402
403#endif /* _WLAN_DEV_H_ */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
new file mode 100644
index 000000000000..0064de542963
--- /dev/null
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -0,0 +1,184 @@
1
2#include <linux/netdevice.h>
3#include <linux/ethtool.h>
4#include <linux/delay.h>
5
6#include "host.h"
7#include "sbi.h"
8#include "decl.h"
9#include "defs.h"
10#include "dev.h"
11#include "join.h"
12#include "wext.h"
13static const char * mesh_stat_strings[]= {
14 "drop_duplicate_bcast",
15 "drop_ttl_zero",
16 "drop_no_fwd_route",
17 "drop_no_buffers",
18 "fwded_unicast_cnt",
19 "fwded_bcast_cnt",
20 "drop_blind_table"
21};
22
23static void libertas_ethtool_get_drvinfo(struct net_device *dev,
24 struct ethtool_drvinfo *info)
25{
26 wlan_private *priv = (wlan_private *) dev->priv;
27 char fwver[32];
28
29 libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1);
30
31 strcpy(info->driver, "libertas");
32 strcpy(info->version, libertas_driver_version);
33 strcpy(info->fw_version, fwver);
34}
35
36/* All 8388 parts have 16KiB EEPROM size at the time of writing.
37 * In case that changes this needs fixing.
38 */
39#define LIBERTAS_EEPROM_LEN 16384
40
41static int libertas_ethtool_get_eeprom_len(struct net_device *dev)
42{
43 return LIBERTAS_EEPROM_LEN;
44}
45
46static int libertas_ethtool_get_eeprom(struct net_device *dev,
47 struct ethtool_eeprom *eeprom, u8 * bytes)
48{
49 wlan_private *priv = (wlan_private *) dev->priv;
50 wlan_adapter *adapter = priv->adapter;
51 struct wlan_ioctl_regrdwr regctrl;
52 char *ptr;
53 int ret;
54
55 regctrl.action = 0;
56 regctrl.offset = eeprom->offset;
57 regctrl.NOB = eeprom->len;
58
59 if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN)
60 return -EINVAL;
61
62// mutex_lock(&priv->mutex);
63
64 adapter->prdeeprom =
65 (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
66 if (!adapter->prdeeprom)
67 return -ENOMEM;
68 memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
69
70 /* +14 is for action, offset, and NOB in
71 * response */
72 lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n",
73 regctrl.action, regctrl.offset, regctrl.NOB);
74
75 ret = libertas_prepare_and_send_command(priv,
76 cmd_802_11_eeprom_access,
77 regctrl.action,
78 cmd_option_waitforrsp, 0,
79 &regctrl);
80
81 if (ret) {
82 if (adapter->prdeeprom)
83 kfree(adapter->prdeeprom);
84 LEAVE();
85 return ret;
86 }
87
88 mdelay(10);
89
90 ptr = (char *)adapter->prdeeprom;
91
92 /* skip the command header, but include the "value" u32 variable */
93 ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4;
94
95 /*
96 * Return the result back to the user
97 */
98 memcpy(bytes, ptr, eeprom->len);
99
100 if (adapter->prdeeprom)
101 kfree(adapter->prdeeprom);
102// mutex_unlock(&priv->mutex);
103
104 return 0;
105}
106
107static void libertas_ethtool_get_stats(struct net_device * dev,
108 struct ethtool_stats * stats, u64 * data)
109{
110 wlan_private *priv = dev->priv;
111
112 ENTER();
113
114 stats->cmd = ETHTOOL_GSTATS;
115 BUG_ON(stats->n_stats != MESH_STATS_NUM);
116
117 data[0] = priv->mstats.fwd_drop_rbt;
118 data[1] = priv->mstats.fwd_drop_ttl;
119 data[2] = priv->mstats.fwd_drop_noroute;
120 data[3] = priv->mstats.fwd_drop_nobuf;
121 data[4] = priv->mstats.fwd_unicast_cnt;
122 data[5] = priv->mstats.fwd_bcast_cnt;
123 data[6] = priv->mstats.drop_blind;
124
125 LEAVE();
126}
127
128static int libertas_ethtool_get_stats_count(struct net_device * dev)
129{
130 int ret;
131 wlan_private *priv = dev->priv;
132 struct cmd_ds_mesh_access mesh_access;
133
134 ENTER();
135 /* Get Mesh Statistics */
136 ret = libertas_prepare_and_send_command(priv,
137 cmd_mesh_access, cmd_act_mesh_get_stats,
138 cmd_option_waitforrsp, 0, &mesh_access);
139
140 if (ret) {
141 LEAVE();
142 return 0;
143 }
144
145 priv->mstats.fwd_drop_rbt = mesh_access.data[0];
146 priv->mstats.fwd_drop_ttl = mesh_access.data[1];
147 priv->mstats.fwd_drop_noroute = mesh_access.data[2];
148 priv->mstats.fwd_drop_nobuf = mesh_access.data[3];
149 priv->mstats.fwd_unicast_cnt = mesh_access.data[4];
150 priv->mstats.fwd_bcast_cnt = mesh_access.data[5];
151 priv->mstats.drop_blind = mesh_access.data[6];
152
153 LEAVE();
154 return MESH_STATS_NUM;
155}
156
157static void libertas_ethtool_get_strings (struct net_device * dev,
158 u32 stringset,
159 u8 * s)
160{
161 int i;
162
163 ENTER();
164 switch (stringset) {
165 case ETH_SS_STATS:
166 for (i=0; i < MESH_STATS_NUM; i++) {
167 memcpy(s + i * ETH_GSTRING_LEN,
168 mesh_stat_strings[i],
169 ETH_GSTRING_LEN);
170 }
171 break;
172 }
173 LEAVE();
174}
175
176struct ethtool_ops libertas_ethtool_ops = {
177 .get_drvinfo = libertas_ethtool_get_drvinfo,
178 .get_eeprom = libertas_ethtool_get_eeprom,
179 .get_eeprom_len = libertas_ethtool_get_eeprom_len,
180 .get_stats_count = libertas_ethtool_get_stats_count,
181 .get_ethtool_stats = libertas_ethtool_get_stats,
182 .get_strings = libertas_ethtool_get_strings,
183};
184
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
new file mode 100644
index 000000000000..b194a4570791
--- /dev/null
+++ b/drivers/net/wireless/libertas/fw.c
@@ -0,0 +1,361 @@
1/**
2 * This file contains the initialization for FW and HW
3 */
4#include <linux/module.h>
5#include <linux/moduleparam.h>
6
7#include <linux/vmalloc.h>
8#include <linux/firmware.h>
9#include <linux/version.h>
10
11#include "host.h"
12#include "sbi.h"
13#include "defs.h"
14#include "decl.h"
15#include "dev.h"
16#include "fw.h"
17#include "wext.h"
18#include "if_usb.h"
19
20char *libertas_fw_name = NULL;
21module_param_named(fw_name, libertas_fw_name, charp, 0644);
22
23unsigned int libertas_debug = 0;
24module_param(libertas_debug, int, 0);
25
26/**
27 * @brief This function checks the validity of Boot2/FW image.
28 *
29 * @param data pointer to image
30 * len image length
31 * @return 0 or -1
32 */
33static int check_fwfile_format(u8 *data, u32 totlen)
34{
35 u8 bincmd, exit;
36 u32 blksize, offset, len;
37 int ret;
38
39 ret = 1;
40 exit = len = 0;
41
42 do {
43 bincmd = *data;
44 blksize = *(u32*)(data + offsetof(struct fwheader, datalength));
45 switch (bincmd) {
46 case FW_HAS_DATA_TO_RECV:
47 offset = sizeof(struct fwheader) + blksize;
48 data += offset;
49 len += offset;
50 if (len >= totlen)
51 exit = 1;
52 break;
53 case FW_HAS_LAST_BLOCK:
54 exit = 1;
55 ret = 0;
56 break;
57 default:
58 exit = 1;
59 break;
60 }
61 } while (!exit);
62
63 if (ret)
64 lbs_pr_err("bin file format check FAIL...\n");
65 else
66 lbs_pr_debug(1, "bin file format check PASS...\n");
67
68 return ret;
69}
70
71/**
72 * @brief This function downloads firmware image, gets
73 * HW spec from firmware and set basic parameters to
74 * firmware.
75 *
76 * @param priv A pointer to wlan_private structure
77 * @return 0 or -1
78 */
79static int wlan_setup_station_hw(wlan_private * priv)
80{
81 int ret = -1;
82 wlan_adapter *adapter = priv->adapter;
83
84 ENTER();
85
86 if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
87 priv->hotplug_device)) < 0) {
88 lbs_pr_err("request_firmware() failed, error code = %#x\n",
89 ret);
90 lbs_pr_err("%s not found in /lib/firmware\n", libertas_fw_name);
91 goto done;
92 }
93
94 if(check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
95 release_firmware(priv->firmware);
96 goto done;
97 }
98
99 ret = libertas_sbi_prog_firmware(priv);
100
101 release_firmware(priv->firmware);
102
103 if (ret) {
104 lbs_pr_debug(1, "Bootloader in invalid state!\n");
105 ret = -1;
106 goto done;
107 }
108
109 /*
110 * Read MAC address from HW
111 */
112 memset(adapter->current_addr, 0xff, ETH_ALEN);
113
114 ret = libertas_prepare_and_send_command(priv, cmd_get_hw_spec,
115 0, cmd_option_waitforrsp, 0, NULL);
116
117 if (ret) {
118 ret = -1;
119 goto done;
120 }
121
122 libertas_set_mac_packet_filter(priv);
123
124 /* Get the supported Data rates */
125 ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
126 cmd_act_get_tx_rate,
127 cmd_option_waitforrsp, 0, NULL);
128
129 if (ret) {
130 ret = -1;
131 goto done;
132 }
133
134 ret = 0;
135done:
136 LEAVE();
137
138 return (ret);
139}
140
141static int wlan_allocate_adapter(wlan_private * priv)
142{
143 u32 ulbufsize;
144 wlan_adapter *adapter = priv->adapter;
145
146 struct bss_descriptor *ptempscantable;
147
148 /* Allocate buffer to store the BSSID list */
149 ulbufsize = sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST;
150 if (!(ptempscantable = kmalloc(ulbufsize, GFP_KERNEL))) {
151 libertas_free_adapter(priv);
152 return -1;
153 }
154
155 adapter->scantable = ptempscantable;
156 memset(adapter->scantable, 0, ulbufsize);
157
158 /* Allocate the command buffers */
159 libertas_allocate_cmd_buffer(priv);
160
161 memset(&adapter->libertas_ps_confirm_sleep, 0, sizeof(struct PS_CMD_ConfirmSleep));
162 adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);
163 adapter->libertas_ps_confirm_sleep.command =
164 cpu_to_le16(cmd_802_11_ps_mode);
165 adapter->libertas_ps_confirm_sleep.size =
166 cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
167 adapter->libertas_ps_confirm_sleep.result = 0;
168 adapter->libertas_ps_confirm_sleep.action =
169 cpu_to_le16(cmd_subcmd_sleep_confirmed);
170
171 return 0;
172}
173
174static void wlan_init_adapter(wlan_private * priv)
175{
176 wlan_adapter *adapter = priv->adapter;
177 int i;
178
179 adapter->scanprobes = 0;
180
181 adapter->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
182 adapter->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
183
184 /* ATIM params */
185 adapter->atimwindow = 0;
186
187 adapter->connect_status = libertas_disconnected;
188 memset(adapter->current_addr, 0xff, ETH_ALEN);
189
190 /* scan type */
191 adapter->scantype = cmd_scan_type_active;
192
193 /* scan mode */
194 adapter->scanmode = cmd_bss_type_any;
195
196 /* 802.11 specific */
197 adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
198 for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
199 i++)
200 memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
201 adapter->wep_tx_keyidx = 0;
202 adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
203 adapter->secinfo.authmode = wlan802_11authmodeopen;
204 adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
205 adapter->secinfo.Encryptionmode = CIPHER_NONE;
206 adapter->inframode = wlan802_11infrastructure;
207
208 adapter->assoc_req = NULL;
209
210 adapter->numinscantable = 0;
211 adapter->pattemptedbssdesc = NULL;
212 mutex_init(&adapter->lock);
213
214 adapter->prescan = 1;
215
216 memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
217
218 /* PnP and power profile */
219 adapter->surpriseremoved = 0;
220
221 adapter->currentpacketfilter =
222 cmd_act_mac_rx_on | cmd_act_mac_tx_on;
223
224 adapter->radioon = RADIO_ON;
225 adapter->txantenna = RF_ANTENNA_2;
226 adapter->rxantenna = RF_ANTENNA_AUTO;
227
228 adapter->is_datarate_auto = 1;
229 adapter->beaconperiod = MRVDRV_BEACON_INTERVAL;
230
231 // set default value of capinfo.
232#define SHORT_PREAMBLE_ALLOWED 1
233 memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
234 adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
235
236 adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
237
238 adapter->psmode = wlan802_11powermodecam;
239 adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
240
241 adapter->listeninterval = MRVDRV_DEFAULT_LISTEN_INTERVAL;
242
243 adapter->psstate = PS_STATE_FULL_POWER;
244 adapter->needtowakeup = 0;
245 adapter->locallisteninterval = 0; /* default value in firmware will be used */
246
247 adapter->datarate = 0; // Initially indicate the rate as auto
248
249 adapter->adhoc_grate_enabled = 0;
250
251 adapter->intcounter = 0;
252
253 adapter->currenttxskb = NULL;
254 adapter->pkttxctrl = 0;
255
256 memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
257 adapter->tx_queue_idx = 0;
258 spin_lock_init(&adapter->txqueue_lock);
259
260 return;
261}
262
263static void command_timer_fn(unsigned long data);
264
265int libertas_init_fw(wlan_private * priv)
266{
267 int ret = -1;
268 wlan_adapter *adapter = priv->adapter;
269
270 ENTER();
271
272 /* Allocate adapter structure */
273 if ((ret = wlan_allocate_adapter(priv)) != 0)
274 goto done;
275
276 /* init adapter structure */
277 wlan_init_adapter(priv);
278
279 /* init timer etc. */
280 setup_timer(&adapter->command_timer, command_timer_fn,
281 (unsigned long)priv);
282
283 /* download fimrware etc. */
284 if ((ret = wlan_setup_station_hw(priv)) != 0) {
285 del_timer_sync(&adapter->command_timer);
286 goto done;
287 }
288
289 /* init 802.11d */
290 libertas_init_11d(priv);
291
292 ret = 0;
293done:
294 LEAVE();
295 return ret;
296}
297
298void libertas_free_adapter(wlan_private * priv)
299{
300 wlan_adapter *adapter = priv->adapter;
301
302 if (!adapter) {
303 lbs_pr_debug(1, "Why double free adapter?:)\n");
304 return;
305 }
306
307 lbs_pr_debug(1, "Free command buffer\n");
308 libertas_free_cmd_buffer(priv);
309
310 lbs_pr_debug(1, "Free commandTimer\n");
311 del_timer(&adapter->command_timer);
312
313 lbs_pr_debug(1, "Free scantable\n");
314 if (adapter->scantable) {
315 kfree(adapter->scantable);
316 adapter->scantable = NULL;
317 }
318
319 lbs_pr_debug(1, "Free adapter\n");
320
321 /* Free the adapter object itself */
322 kfree(adapter);
323 priv->adapter = NULL;
324}
325
326/**
327 * This function handles the timeout of command sending.
328 * It will re-send the same command again.
329 */
330static void command_timer_fn(unsigned long data)
331{
332 wlan_private *priv = (wlan_private *)data;
333 wlan_adapter *adapter = priv->adapter;
334 struct cmd_ctrl_node *ptempnode;
335 struct cmd_ds_command *cmd;
336 unsigned long flags;
337
338 ptempnode = adapter->cur_cmd;
339 cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
340
341 lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command);
342
343 if (!adapter->fw_ready)
344 return;
345
346 if (ptempnode == NULL) {
347 lbs_pr_debug(1, "PTempnode Empty\n");
348 return;
349 }
350
351 spin_lock_irqsave(&adapter->driver_lock, flags);
352 adapter->cur_cmd = NULL;
353 spin_unlock_irqrestore(&adapter->driver_lock, flags);
354
355 lbs_pr_debug(1, "Re-sending same command as it timeout...!\n");
356 libertas_queue_cmd(adapter, ptempnode, 0);
357
358 wake_up_interruptible(&priv->mainthread.waitq);
359
360 return;
361}
diff --git a/drivers/net/wireless/libertas/fw.h b/drivers/net/wireless/libertas/fw.h
new file mode 100644
index 000000000000..1f9ae267a9e0
--- /dev/null
+++ b/drivers/net/wireless/libertas/fw.h
@@ -0,0 +1,13 @@
1/**
2 * This header file contains FW interface related definitions.
3 */
4#ifndef _WLAN_FW_H_
5#define _WLAN_FW_H_
6
7#ifndef DEV_NAME_LEN
8#define DEV_NAME_LEN 32
9#endif
10
11int libertas_init_fw(wlan_private * priv);
12
13#endif /* _WLAN_FW_H_ */
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
new file mode 100644
index 000000000000..c0faaecaf5be
--- /dev/null
+++ b/drivers/net/wireless/libertas/host.h
@@ -0,0 +1,338 @@
1/**
2 * This file contains definitions of WLAN commands.
3 */
4
5#ifndef _HOST_H_
6#define _HOST_H_
7
8/** PUBLIC DEFINITIONS */
9#define DEFAULT_AD_HOC_CHANNEL 6
10#define DEFAULT_AD_HOC_CHANNEL_A 36
11
12/** IEEE 802.11 oids */
13#define OID_802_11_SSID 0x00008002
14#define OID_802_11_INFRASTRUCTURE_MODE 0x00008008
15#define OID_802_11_FRAGMENTATION_THRESHOLD 0x00008009
16#define OID_802_11_RTS_THRESHOLD 0x0000800A
17#define OID_802_11_TX_ANTENNA_SELECTED 0x0000800D
18#define OID_802_11_SUPPORTED_RATES 0x0000800E
19#define OID_802_11_STATISTICS 0x00008012
20#define OID_802_11_TX_RETRYCOUNT 0x0000801D
21#define OID_802_11D_ENABLE 0x00008020
22
23#define cmd_option_waitforrsp 0x0002
24
25/** Host command ID */
26#define cmd_code_dnld 0x0002
27#define cmd_get_hw_spec 0x0003
28#define cmd_eeprom_update 0x0004
29#define cmd_802_11_reset 0x0005
30#define cmd_802_11_scan 0x0006
31#define cmd_802_11_get_log 0x000b
32#define cmd_mac_multicast_adr 0x0010
33#define cmd_802_11_authenticate 0x0011
34#define cmd_802_11_eeprom_access 0x0059
35#define cmd_802_11_associate 0x0050
36#define cmd_802_11_set_wep 0x0013
37#define cmd_802_11_get_stat 0x0014
38#define cmd_802_3_get_stat 0x0015
39#define cmd_802_11_snmp_mib 0x0016
40#define cmd_mac_reg_map 0x0017
41#define cmd_bbp_reg_map 0x0018
42#define cmd_mac_reg_access 0x0019
43#define cmd_bbp_reg_access 0x001a
44#define cmd_rf_reg_access 0x001b
45#define cmd_802_11_radio_control 0x001c
46#define cmd_802_11_rf_channel 0x001d
47#define cmd_802_11_rf_tx_power 0x001e
48#define cmd_802_11_rssi 0x001f
49#define cmd_802_11_rf_antenna 0x0020
50
51#define cmd_802_11_ps_mode 0x0021
52
53#define cmd_802_11_data_rate 0x0022
54#define cmd_rf_reg_map 0x0023
55#define cmd_802_11_deauthenticate 0x0024
56#define cmd_802_11_reassociate 0x0025
57#define cmd_802_11_disassociate 0x0026
58#define cmd_mac_control 0x0028
59#define cmd_802_11_ad_hoc_start 0x002b
60#define cmd_802_11_ad_hoc_join 0x002c
61
62#define cmd_802_11_query_tkip_reply_cntrs 0x002e
63#define cmd_802_11_enable_rsn 0x002f
64#define cmd_802_11_pairwise_tsc 0x0036
65#define cmd_802_11_group_tsc 0x0037
66#define cmd_802_11_key_material 0x005e
67
68#define cmd_802_11_set_afc 0x003c
69#define cmd_802_11_get_afc 0x003d
70
71#define cmd_802_11_ad_hoc_stop 0x0040
72
73#define cmd_802_11_beacon_stop 0x0049
74
75#define cmd_802_11_mac_address 0x004D
76#define cmd_802_11_eeprom_access 0x0059
77
78#define cmd_802_11_band_config 0x0058
79
80#define cmd_802_11d_domain_info 0x005b
81
82#define cmd_802_11_sleep_params 0x0066
83
84#define cmd_802_11_inactivity_timeout 0x0067
85
86#define cmd_802_11_tpc_cfg 0x0072
87#define cmd_802_11_pwr_cfg 0x0073
88
89#define cmd_802_11_led_gpio_ctrl 0x004e
90
91#define cmd_802_11_subscribe_event 0x0075
92
93#define cmd_802_11_rate_adapt_rateset 0x0076
94
95#define cmd_802_11_tx_rate_query 0x007f
96
97#define cmd_get_tsf 0x0080
98
99#define cmd_bt_access 0x0087
100#define cmd_ret_bt_access 0x8087
101
102#define cmd_fwt_access 0x0088
103#define cmd_ret_fwt_access 0x8088
104
105#define cmd_mesh_access 0x0090
106#define cmd_ret_mesh_access 0x8090
107
108/* For the IEEE Power Save */
109#define cmd_subcmd_enter_ps 0x0030
110#define cmd_subcmd_exit_ps 0x0031
111#define cmd_subcmd_sleep_confirmed 0x0034
112#define cmd_subcmd_full_powerdown 0x0035
113#define cmd_subcmd_full_powerup 0x0036
114
115/* command RET code, MSB is set to 1 */
116#define cmd_ret_hw_spec_info 0x8003
117#define cmd_ret_eeprom_update 0x8004
118#define cmd_ret_802_11_reset 0x8005
119#define cmd_ret_802_11_scan 0x8006
120#define cmd_ret_802_11_get_log 0x800b
121#define cmd_ret_mac_control 0x8028
122#define cmd_ret_mac_multicast_adr 0x8010
123#define cmd_ret_802_11_authenticate 0x8011
124#define cmd_ret_802_11_deauthenticate 0x8024
125#define cmd_ret_802_11_associate 0x8012
126#define cmd_ret_802_11_reassociate 0x8025
127#define cmd_ret_802_11_disassociate 0x8026
128#define cmd_ret_802_11_set_wep 0x8013
129#define cmd_ret_802_11_stat 0x8014
130#define cmd_ret_802_3_stat 0x8015
131#define cmd_ret_802_11_snmp_mib 0x8016
132#define cmd_ret_mac_reg_map 0x8017
133#define cmd_ret_bbp_reg_map 0x8018
134#define cmd_ret_rf_reg_map 0x8023
135#define cmd_ret_mac_reg_access 0x8019
136#define cmd_ret_bbp_reg_access 0x801a
137#define cmd_ret_rf_reg_access 0x801b
138#define cmd_ret_802_11_radio_control 0x801c
139#define cmd_ret_802_11_rf_channel 0x801d
140#define cmd_ret_802_11_rssi 0x801f
141#define cmd_ret_802_11_rf_tx_power 0x801e
142#define cmd_ret_802_11_rf_antenna 0x8020
143#define cmd_ret_802_11_ps_mode 0x8021
144#define cmd_ret_802_11_data_rate 0x8022
145
146#define cmd_ret_802_11_ad_hoc_start 0x802B
147#define cmd_ret_802_11_ad_hoc_join 0x802C
148
149#define cmd_ret_802_11_query_tkip_reply_cntrs 0x802e
150#define cmd_ret_802_11_enable_rsn 0x802f
151#define cmd_ret_802_11_pairwise_tsc 0x8036
152#define cmd_ret_802_11_group_tsc 0x8037
153#define cmd_ret_802_11_key_material 0x805e
154
155#define cmd_enable_rsn 0x0001
156#define cmd_disable_rsn 0x0000
157
158#define cmd_act_set 0x0001
159#define cmd_act_get 0x0000
160
161#define cmd_act_get_AES (cmd_act_get + 2)
162#define cmd_act_set_AES (cmd_act_set + 2)
163#define cmd_act_remove_aes (cmd_act_set + 3)
164
165#define cmd_ret_802_11_set_afc 0x803c
166#define cmd_ret_802_11_get_afc 0x803d
167
168#define cmd_ret_802_11_ad_hoc_stop 0x8040
169
170#define cmd_ret_802_11_beacon_stop 0x8049
171
172#define cmd_ret_802_11_mac_address 0x804D
173#define cmd_ret_802_11_eeprom_access 0x8059
174
175#define cmd_ret_802_11_band_config 0x8058
176
177#define cmd_ret_802_11_sleep_params 0x8066
178
179#define cmd_ret_802_11_inactivity_timeout 0x8067
180
181#define cmd_ret_802_11d_domain_info (0x8000 | \
182 cmd_802_11d_domain_info)
183
184#define cmd_ret_802_11_tpc_cfg (cmd_802_11_tpc_cfg | 0x8000)
185#define cmd_ret_802_11_pwr_cfg (cmd_802_11_pwr_cfg | 0x8000)
186
187#define cmd_ret_802_11_led_gpio_ctrl 0x804e
188
189#define cmd_ret_802_11_subscribe_event (cmd_802_11_subscribe_event | 0x8000)
190
191#define cmd_ret_802_11_rate_adapt_rateset (cmd_802_11_rate_adapt_rateset | 0x8000)
192
193#define cmd_rte_802_11_tx_rate_query (cmd_802_11_tx_rate_query | 0x8000)
194
195#define cmd_ret_get_tsf 0x8080
196
197/* Define action or option for cmd_802_11_set_wep */
198#define cmd_act_add 0x0002
199#define cmd_act_remove 0x0004
200#define cmd_act_use_default 0x0008
201
202#define cmd_type_wep_40_bit 0x0001
203#define cmd_type_wep_104_bit 0x0002
204
205#define cmd_NUM_OF_WEP_KEYS 4
206
207#define cmd_WEP_KEY_INDEX_MASK 0x3fff
208
209/* Define action or option for cmd_802_11_reset */
210#define cmd_act_halt 0x0003
211
212/* Define action or option for cmd_802_11_scan */
213#define cmd_bss_type_bss 0x0001
214#define cmd_bss_type_ibss 0x0002
215#define cmd_bss_type_any 0x0003
216
217/* Define action or option for cmd_802_11_scan */
218#define cmd_scan_type_active 0x0000
219#define cmd_scan_type_passive 0x0001
220
221#define cmd_scan_radio_type_bg 0
222
223#define cmd_scan_probe_delay_time 0
224
225/* Define action or option for cmd_mac_control */
226#define cmd_act_mac_rx_on 0x0001
227#define cmd_act_mac_tx_on 0x0002
228#define cmd_act_mac_loopback_on 0x0004
229#define cmd_act_mac_wep_enable 0x0008
230#define cmd_act_mac_int_enable 0x0010
231#define cmd_act_mac_multicast_enable 0x0020
232#define cmd_act_mac_broadcast_enable 0x0040
233#define cmd_act_mac_promiscuous_enable 0x0080
234#define cmd_act_mac_all_multicast_enable 0x0100
235#define cmd_act_mac_strict_protection_enable 0x0400
236
237/* Define action or option for cmd_802_11_radio_control */
238#define cmd_type_auto_preamble 0x0001
239#define cmd_type_short_preamble 0x0002
240#define cmd_type_long_preamble 0x0003
241
242#define TURN_ON_RF 0x01
243#define RADIO_ON 0x01
244#define RADIO_OFF 0x00
245
246#define SET_AUTO_PREAMBLE 0x05
247#define SET_SHORT_PREAMBLE 0x03
248#define SET_LONG_PREAMBLE 0x01
249
250/* Define action or option for CMD_802_11_RF_CHANNEL */
251#define cmd_opt_802_11_rf_channel_get 0x00
252#define cmd_opt_802_11_rf_channel_set 0x01
253
254/* Define action or option for cmd_802_11_rf_tx_power */
255#define cmd_act_tx_power_opt_get 0x0000
256#define cmd_act_tx_power_opt_set_high 0x8007
257#define cmd_act_tx_power_opt_set_mid 0x8004
258#define cmd_act_tx_power_opt_set_low 0x8000
259
260#define cmd_act_tx_power_index_high 0x0007
261#define cmd_act_tx_power_index_mid 0x0004
262#define cmd_act_tx_power_index_low 0x0000
263
264/* Define action or option for cmd_802_11_data_rate */
265#define cmd_act_set_tx_auto 0x0000
266#define cmd_act_set_tx_fix_rate 0x0001
267#define cmd_act_get_tx_rate 0x0002
268
269#define cmd_act_set_rx 0x0001
270#define cmd_act_set_tx 0x0002
271#define cmd_act_set_both 0x0003
272#define cmd_act_get_rx 0x0004
273#define cmd_act_get_tx 0x0008
274#define cmd_act_get_both 0x000c
275
276/* Define action or option for cmd_802_11_ps_mode */
277#define cmd_type_cam 0x0000
278#define cmd_type_max_psp 0x0001
279#define cmd_type_fast_psp 0x0002
280
281/* Define action or option for cmd_bt_access */
282enum cmd_bt_access_opts {
283 /* The bt commands start at 5 instead of 1 because the old dft commands
284 * are mapped to 1-4. These old commands are no longer maintained and
285 * should not be called.
286 */
287 cmd_act_bt_access_add = 5,
288 cmd_act_bt_access_del,
289 cmd_act_bt_access_list,
290 cmd_act_bt_access_reset
291};
292
293/* Define action or option for cmd_fwt_access */
294enum cmd_fwt_access_opts {
295 cmd_act_fwt_access_add = 1,
296 cmd_act_fwt_access_del,
297 cmd_act_fwt_access_lookup,
298 cmd_act_fwt_access_list,
299 cmd_act_fwt_access_list_route,
300 cmd_act_fwt_access_list_neighbor,
301 cmd_act_fwt_access_reset,
302 cmd_act_fwt_access_cleanup,
303 cmd_act_fwt_access_time,
304};
305
306/* Define action or option for cmd_mesh_access */
307enum cmd_mesh_access_opts {
308 cmd_act_mesh_get_ttl = 1,
309 cmd_act_mesh_set_ttl,
310 cmd_act_mesh_get_stats,
311 cmd_act_mesh_get_mpp,
312 cmd_act_mesh_set_mpp,
313};
314
315/** Card Event definition */
316#define MACREG_INT_CODE_TX_PPA_FREE 0x00000000
317#define MACREG_INT_CODE_TX_DMA_DONE 0x00000001
318#define MACREG_INT_CODE_LINK_LOSE_W_SCAN 0x00000002
319#define MACREG_INT_CODE_LINK_LOSE_NO_SCAN 0x00000003
320#define MACREG_INT_CODE_LINK_SENSED 0x00000004
321#define MACREG_INT_CODE_CMD_FINISHED 0x00000005
322#define MACREG_INT_CODE_MIB_CHANGED 0x00000006
323#define MACREG_INT_CODE_INIT_DONE 0x00000007
324#define MACREG_INT_CODE_DEAUTHENTICATED 0x00000008
325#define MACREG_INT_CODE_DISASSOCIATED 0x00000009
326#define MACREG_INT_CODE_PS_AWAKE 0x0000000a
327#define MACREG_INT_CODE_PS_SLEEP 0x0000000b
328#define MACREG_INT_CODE_MIC_ERR_MULTICAST 0x0000000d
329#define MACREG_INT_CODE_MIC_ERR_UNICAST 0x0000000e
330#define MACREG_INT_CODE_WM_AWAKE 0x0000000f
331#define MACREG_INT_CODE_ADHOC_BCN_LOST 0x00000011
332#define MACREG_INT_CODE_RSSI_LOW 0x00000019
333#define MACREG_INT_CODE_SNR_LOW 0x0000001a
334#define MACREG_INT_CODE_MAX_FAIL 0x0000001b
335#define MACREG_INT_CODE_RSSI_HIGH 0x0000001c
336#define MACREG_INT_CODE_SNR_HIGH 0x0000001d
337
338#endif /* _HOST_H_ */
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
new file mode 100644
index 000000000000..f239e5d2435b
--- /dev/null
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -0,0 +1,693 @@
1/*
2 * This file contains the function prototypes, data structure
3 * and defines for all the host/station commands
4 */
5#ifndef __HOSTCMD__H
6#define __HOSTCMD__H
7
8#include <linux/wireless.h>
9#include "11d.h"
10#include "types.h"
11
12/* 802.11-related definitions */
13
14/* TxPD descriptor */
15struct txpd {
16 /* Current Tx packet status */
17 u32 tx_status;
18 /* Tx control */
19 u32 tx_control;
20 u32 tx_packet_location;
21 /* Tx packet length */
22 u16 tx_packet_length;
23 /* First 2 byte of destination MAC address */
24 u8 tx_dest_addr_high[2];
25 /* Last 4 byte of destination MAC address */
26 u8 tx_dest_addr_low[4];
27 /* Pkt Priority */
28 u8 priority;
29 /* Pkt Trasnit Power control */
30 u8 powermgmt;
31 /* Amount of time the packet has been queued in the driver (units = 2ms) */
32 u8 pktdelay_2ms;
33 /* reserved */
34 u8 reserved1;
35};
36
37/* RxPD Descriptor */
38struct rxpd {
39 /* Current Rx packet status */
40 u16 status;
41
42 /* SNR */
43 u8 snr;
44
45 /* Tx control */
46 u8 rx_control;
47
48 /* Pkt length */
49 u16 pkt_len;
50
51 /* Noise Floor */
52 u8 nf;
53
54 /* Rx Packet Rate */
55 u8 rx_rate;
56
57 /* Pkt addr */
58 u32 pkt_ptr;
59
60 /* Next Rx RxPD addr */
61 u32 next_rxpd_ptr;
62
63 /* Pkt Priority */
64 u8 priority;
65 u8 reserved[3];
66};
67
68struct cmd_ctrl_node {
69 /* CMD link list */
70 struct list_head list;
71 u32 status;
72 /* CMD ID */
73 u32 cmd_oid;
74 /*CMD wait option: wait for finish or no wait */
75 u16 wait_option;
76 /* command parameter */
77 void *pdata_buf;
78 /*command data */
79 u8 *bufvirtualaddr;
80 u16 cmdflags;
81 /* wait queue */
82 u16 cmdwaitqwoken;
83 wait_queue_head_t cmdwait_q;
84};
85
86/* WLAN_802_11_KEY
87 *
88 * Generic structure to hold all key types. key type (WEP40, WEP104, TKIP, AES)
89 * is determined from the keylength field.
90 */
91struct WLAN_802_11_KEY {
92 u32 len;
93 u32 flags; /* KEY_INFO_* from wlan_defs.h */
94 u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH];
95 u16 type; /* KEY_TYPE_* from wlan_defs.h */
96};
97
98struct IE_WPA {
99 u8 elementid;
100 u8 len;
101 u8 oui[4];
102 u16 version;
103};
104
105struct WLAN_802_11_SSID {
106 /* SSID length */
107 u32 ssidlength;
108
109 /* SSID information field */
110 u8 ssid[IW_ESSID_MAX_SIZE];
111};
112
113struct WPA_SUPPLICANT {
114 u8 wpa_ie[256];
115 u8 wpa_ie_len;
116};
117
118/* wlan_offset_value */
119struct wlan_offset_value {
120 u32 offset;
121 u32 value;
122};
123
124struct WLAN_802_11_FIXED_IEs {
125 u8 timestamp[8];
126 u16 beaconinterval;
127 u16 capabilities;
128};
129
130struct WLAN_802_11_VARIABLE_IEs {
131 u8 elementid;
132 u8 length;
133 u8 data[1];
134};
135
136/* Define general data structure */
137/* cmd_DS_GEN */
138struct cmd_ds_gen {
139 u16 command;
140 u16 size;
141 u16 seqnum;
142 u16 result;
143};
144
145#define S_DS_GEN sizeof(struct cmd_ds_gen)
146/*
147 * Define data structure for cmd_get_hw_spec
148 * This structure defines the response for the GET_HW_SPEC command
149 */
150struct cmd_ds_get_hw_spec {
151 /* HW Interface version number */
152 u16 hwifversion;
153 /* HW version number */
154 u16 version;
155 /* Max number of TxPD FW can handle */
156 u16 nr_txpd;
157 /* Max no of Multicast address */
158 u16 nr_mcast_adr;
159 /* MAC address */
160 u8 permanentaddr[6];
161
162 /* region Code */
163 u16 regioncode;
164
165 /* Number of antenna used */
166 u16 nr_antenna;
167
168 /* FW release number, example 0x1234=1.2.3.4 */
169 u32 fwreleasenumber;
170
171 /* Base Address of TxPD queue */
172 u32 wcb_base;
173 /* Read Pointer of RxPd queue */
174 u32 rxpd_rdptr;
175
176 /* Write Pointer of RxPd queue */
177 u32 rxpd_wrptr;
178
179 /*FW/HW capability */
180 u32 fwcapinfo;
181} __attribute__ ((packed));
182
183struct cmd_ds_802_11_reset {
184 u16 action;
185};
186
187struct cmd_ds_802_11_subscribe_event {
188 u16 action;
189 u16 events;
190};
191
192/*
193 * This scan handle Country Information IE(802.11d compliant)
194 * Define data structure for cmd_802_11_scan
195 */
196struct cmd_ds_802_11_scan {
197 u8 bsstype;
198 u8 BSSID[ETH_ALEN];
199 u8 tlvbuffer[1];
200#if 0
201 mrvlietypes_ssidparamset_t ssidParamSet;
202 mrvlietypes_chanlistparamset_t ChanListParamSet;
203 mrvlietypes_ratesparamset_t OpRateSet;
204#endif
205};
206
207struct cmd_ds_802_11_scan_rsp {
208 u16 bssdescriptsize;
209 u8 nr_sets;
210 u8 bssdesc_and_tlvbuffer[1];
211};
212
213struct cmd_ds_802_11_get_log {
214 u32 mcasttxframe;
215 u32 failed;
216 u32 retry;
217 u32 multiretry;
218 u32 framedup;
219 u32 rtssuccess;
220 u32 rtsfailure;
221 u32 ackfailure;
222 u32 rxfrag;
223 u32 mcastrxframe;
224 u32 fcserror;
225 u32 txframe;
226 u32 wepundecryptable;
227};
228
229struct cmd_ds_mac_control {
230 u16 action;
231 u16 reserved;
232};
233
234struct cmd_ds_mac_multicast_adr {
235 u16 action;
236 u16 nr_of_adrs;
237 u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
238};
239
240struct cmd_ds_802_11_authenticate {
241 u8 macaddr[ETH_ALEN];
242 u8 authtype;
243 u8 reserved[10];
244};
245
246struct cmd_ds_802_11_deauthenticate {
247 u8 macaddr[6];
248 u16 reasoncode;
249};
250
251struct cmd_ds_802_11_associate {
252 u8 peerstaaddr[6];
253 struct ieeetypes_capinfo capinfo;
254 u16 listeninterval;
255 u16 bcnperiod;
256 u8 dtimperiod;
257
258#if 0
259 mrvlietypes_ssidparamset_t ssidParamSet;
260 mrvlietypes_phyparamset_t phyparamset;
261 mrvlietypes_ssparamset_t ssparamset;
262 mrvlietypes_ratesparamset_t ratesParamSet;
263#endif
264} __attribute__ ((packed));
265
266struct cmd_ds_802_11_disassociate {
267 u8 destmacaddr[6];
268 u16 reasoncode;
269};
270
271struct cmd_ds_802_11_associate_rsp {
272 struct ieeetypes_assocrsp assocRsp;
273};
274
275struct cmd_ds_802_11_ad_hoc_result {
276 u8 PAD[3];
277 u8 BSSID[ETH_ALEN];
278};
279
280struct cmd_ds_802_11_set_wep {
281 /* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
282 u16 action;
283
284 /* key Index selected for Tx */
285 u16 keyindex;
286
287 /* 40, 128bit or TXWEP */
288 u8 keytype[4];
289 u8 keymaterial[4][16];
290};
291
292struct cmd_ds_802_3_get_stat {
293 u32 xmitok;
294 u32 rcvok;
295 u32 xmiterror;
296 u32 rcverror;
297 u32 rcvnobuffer;
298 u32 rcvcrcerror;
299};
300
301struct cmd_ds_802_11_get_stat {
302 u32 txfragmentcnt;
303 u32 mcasttxframecnt;
304 u32 failedcnt;
305 u32 retrycnt;
306 u32 Multipleretrycnt;
307 u32 rtssuccesscnt;
308 u32 rtsfailurecnt;
309 u32 ackfailurecnt;
310 u32 frameduplicatecnt;
311 u32 rxfragmentcnt;
312 u32 mcastrxframecnt;
313 u32 fcserrorcnt;
314 u32 bcasttxframecnt;
315 u32 bcastrxframecnt;
316 u32 txbeacon;
317 u32 rxbeacon;
318 u32 wepundecryptable;
319};
320
321struct cmd_ds_802_11_snmp_mib {
322 u16 querytype;
323 u16 oid;
324 u16 bufsize;
325 u8 value[128];
326};
327
328struct cmd_ds_mac_reg_map {
329 u16 buffersize;
330 u8 regmap[128];
331 u16 reserved;
332};
333
334struct cmd_ds_bbp_reg_map {
335 u16 buffersize;
336 u8 regmap[128];
337 u16 reserved;
338};
339
340struct cmd_ds_rf_reg_map {
341 u16 buffersize;
342 u8 regmap[64];
343 u16 reserved;
344};
345
346struct cmd_ds_mac_reg_access {
347 u16 action;
348 u16 offset;
349 u32 value;
350};
351
352struct cmd_ds_bbp_reg_access {
353 u16 action;
354 u16 offset;
355 u8 value;
356 u8 reserved[3];
357};
358
359struct cmd_ds_rf_reg_access {
360 u16 action;
361 u16 offset;
362 u8 value;
363 u8 reserved[3];
364};
365
366struct cmd_ds_802_11_radio_control {
367 u16 action;
368 u16 control;
369};
370
371struct cmd_ds_802_11_sleep_params {
372 /* ACT_GET/ACT_SET */
373 u16 action;
374
375 /* Sleep clock error in ppm */
376 u16 error;
377
378 /* Wakeup offset in usec */
379 u16 offset;
380
381 /* Clock stabilization time in usec */
382 u16 stabletime;
383
384 /* control periodic calibration */
385 u8 calcontrol;
386
387 /* control the use of external sleep clock */
388 u8 externalsleepclk;
389
390 /* reserved field, should be set to zero */
391 u16 reserved;
392};
393
394struct cmd_ds_802_11_inactivity_timeout {
395 /* ACT_GET/ACT_SET */
396 u16 action;
397
398 /* Inactivity timeout in msec */
399 u16 timeout;
400};
401
402struct cmd_ds_802_11_rf_channel {
403 u16 action;
404 u16 currentchannel;
405 u16 rftype;
406 u16 reserved;
407 u8 channellist[32];
408};
409
410struct cmd_ds_802_11_rssi {
411 /* weighting factor */
412 u16 N;
413
414 u16 reserved_0;
415 u16 reserved_1;
416 u16 reserved_2;
417};
418
419struct cmd_ds_802_11_rssi_rsp {
420 u16 SNR;
421 u16 noisefloor;
422 u16 avgSNR;
423 u16 avgnoisefloor;
424};
425
426struct cmd_ds_802_11_mac_address {
427 u16 action;
428 u8 macadd[ETH_ALEN];
429};
430
431struct cmd_ds_802_11_rf_tx_power {
432 u16 action;
433 u16 currentlevel;
434};
435
436struct cmd_ds_802_11_rf_antenna {
437 u16 action;
438
439 /* Number of antennas or 0xffff(diversity) */
440 u16 antennamode;
441
442};
443
444struct cmd_ds_802_11_ps_mode {
445 u16 action;
446 u16 nullpktinterval;
447 u16 multipledtim;
448 u16 reserved;
449 u16 locallisteninterval;
450};
451
452struct PS_CMD_ConfirmSleep {
453 u16 command;
454 u16 size;
455 u16 seqnum;
456 u16 result;
457
458 u16 action;
459 u16 reserved1;
460 u16 multipledtim;
461 u16 reserved;
462 u16 locallisteninterval;
463};
464
465struct cmd_ds_802_11_data_rate {
466 u16 action;
467 u16 reserverd;
468 u8 datarate[G_SUPPORTED_RATES];
469};
470
471struct cmd_ds_802_11_rate_adapt_rateset {
472 u16 action;
473 u16 enablehwauto;
474 u16 bitmap;
475};
476
477struct cmd_ds_802_11_ad_hoc_start {
478 u8 SSID[IW_ESSID_MAX_SIZE];
479 u8 bsstype;
480 u16 beaconperiod;
481 u8 dtimperiod;
482 union IEEEtypes_ssparamset ssparamset;
483 union ieeetypes_phyparamset phyparamset;
484 u16 probedelay;
485 struct ieeetypes_capinfo cap;
486 u8 datarate[G_SUPPORTED_RATES];
487 u8 tlv_memory_size_pad[100];
488} __attribute__ ((packed));
489
490struct adhoc_bssdesc {
491 u8 BSSID[6];
492 u8 SSID[32];
493 u8 bsstype;
494 u16 beaconperiod;
495 u8 dtimperiod;
496 u8 timestamp[8];
497 u8 localtime[8];
498 union ieeetypes_phyparamset phyparamset;
499 union IEEEtypes_ssparamset ssparamset;
500 struct ieeetypes_capinfo cap;
501 u8 datarates[G_SUPPORTED_RATES];
502
503 /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
504 * Adhoc join command and will cause a binary layout mismatch with
505 * the firmware
506 */
507} __attribute__ ((packed));
508
509struct cmd_ds_802_11_ad_hoc_join {
510 struct adhoc_bssdesc bssdescriptor;
511 u16 failtimeout;
512 u16 probedelay;
513
514} __attribute__ ((packed));
515
516struct cmd_ds_802_11_enable_rsn {
517 u16 action;
518 u16 enable;
519};
520
521struct MrvlIEtype_keyParamSet {
522 /* type ID */
523 u16 type;
524
525 /* length of Payload */
526 u16 length;
527
528 /* type of key: WEP=0, TKIP=1, AES=2 */
529 u16 keytypeid;
530
531 /* key control Info specific to a keytypeid */
532 u16 keyinfo;
533
534 /* length of key */
535 u16 keylen;
536
537 /* key material of size keylen */
538 u8 key[32];
539};
540
541struct cmd_ds_802_11_key_material {
542 u16 action;
543 struct MrvlIEtype_keyParamSet keyParamSet[2];
544} __attribute__ ((packed));
545
546struct cmd_ds_802_11_eeprom_access {
547 u16 action;
548
549 /* multiple 4 */
550 u16 offset;
551 u16 bytecount;
552 u8 value;
553} __attribute__ ((packed));
554
555struct cmd_ds_802_11_tpc_cfg {
556 u16 action;
557 u8 enable;
558 s8 P0;
559 s8 P1;
560 s8 P2;
561 u8 usesnr;
562} __attribute__ ((packed));
563
564struct cmd_ds_802_11_led_ctrl {
565 u16 action;
566 u16 numled;
567 u8 data[256];
568} __attribute__ ((packed));
569
570struct cmd_ds_802_11_pwr_cfg {
571 u16 action;
572 u8 enable;
573 s8 PA_P0;
574 s8 PA_P1;
575 s8 PA_P2;
576} __attribute__ ((packed));
577
578struct cmd_ds_802_11_afc {
579 u16 afc_auto;
580 union {
581 struct {
582 u16 threshold;
583 u16 period;
584 };
585 struct {
586 s16 timing_offset;
587 s16 carrier_offset;
588 };
589 };
590} __attribute__ ((packed));
591
592struct cmd_tx_rate_query {
593 u16 txrate;
594} __attribute__ ((packed));
595
596struct cmd_ds_get_tsf {
597 __le64 tsfvalue;
598} __attribute__ ((packed));
599
600struct cmd_ds_bt_access {
601 u16 action;
602 u32 id;
603 u8 addr1[ETH_ALEN];
604 u8 addr2[ETH_ALEN];
605} __attribute__ ((packed));
606
607struct cmd_ds_fwt_access {
608 u16 action;
609 u32 id;
610 u8 da[ETH_ALEN];
611 u8 dir;
612 u8 ra[ETH_ALEN];
613 u32 ssn;
614 u32 dsn;
615 u32 metric;
616 u8 hopcount;
617 u8 ttl;
618 u32 expiration;
619 u8 sleepmode;
620 u32 snr;
621 u32 references;
622} __attribute__ ((packed));
623
624#define MESH_STATS_NUM 7
625struct cmd_ds_mesh_access {
626 u16 action;
627 u32 data[MESH_STATS_NUM + 1]; /* last position reserved */
628} __attribute__ ((packed));
629
630struct cmd_ds_command {
631 /* command header */
632 u16 command;
633 u16 size;
634 u16 seqnum;
635 u16 result;
636
637 /* command Body */
638 union {
639 struct cmd_ds_get_hw_spec hwspec;
640 struct cmd_ds_802_11_ps_mode psmode;
641 struct cmd_ds_802_11_scan scan;
642 struct cmd_ds_802_11_scan_rsp scanresp;
643 struct cmd_ds_mac_control macctrl;
644 struct cmd_ds_802_11_associate associate;
645 struct cmd_ds_802_11_deauthenticate deauth;
646 struct cmd_ds_802_11_set_wep wep;
647 struct cmd_ds_802_11_ad_hoc_start ads;
648 struct cmd_ds_802_11_reset reset;
649 struct cmd_ds_802_11_ad_hoc_result result;
650 struct cmd_ds_802_11_get_log glog;
651 struct cmd_ds_802_11_authenticate auth;
652 struct cmd_ds_802_11_get_stat gstat;
653 struct cmd_ds_802_3_get_stat gstat_8023;
654 struct cmd_ds_802_11_snmp_mib smib;
655 struct cmd_ds_802_11_rf_tx_power txp;
656 struct cmd_ds_802_11_rf_antenna rant;
657 struct cmd_ds_802_11_data_rate drate;
658 struct cmd_ds_802_11_rate_adapt_rateset rateset;
659 struct cmd_ds_mac_multicast_adr madr;
660 struct cmd_ds_802_11_ad_hoc_join adj;
661 struct cmd_ds_802_11_radio_control radio;
662 struct cmd_ds_802_11_rf_channel rfchannel;
663 struct cmd_ds_802_11_rssi rssi;
664 struct cmd_ds_802_11_rssi_rsp rssirsp;
665 struct cmd_ds_802_11_disassociate dassociate;
666 struct cmd_ds_802_11_mac_address macadd;
667 struct cmd_ds_802_11_enable_rsn enbrsn;
668 struct cmd_ds_802_11_key_material keymaterial;
669 struct cmd_ds_mac_reg_access macreg;
670 struct cmd_ds_bbp_reg_access bbpreg;
671 struct cmd_ds_rf_reg_access rfreg;
672 struct cmd_ds_802_11_eeprom_access rdeeprom;
673
674 struct cmd_ds_802_11d_domain_info domaininfo;
675 struct cmd_ds_802_11d_domain_info domaininforesp;
676
677 struct cmd_ds_802_11_sleep_params sleep_params;
678 struct cmd_ds_802_11_inactivity_timeout inactivity_timeout;
679 struct cmd_ds_802_11_tpc_cfg tpccfg;
680 struct cmd_ds_802_11_pwr_cfg pwrcfg;
681 struct cmd_ds_802_11_afc afc;
682 struct cmd_ds_802_11_led_ctrl ledgpio;
683
684 struct cmd_tx_rate_query txrate;
685 struct cmd_ds_bt_access bt;
686 struct cmd_ds_fwt_access fwt;
687 struct cmd_ds_mesh_access mesh;
688 struct cmd_ds_get_tsf gettsf;
689 struct cmd_ds_802_11_subscribe_event subscribe_event;
690 } params;
691} __attribute__ ((packed));
692
693#endif
diff --git a/drivers/net/wireless/libertas/if_bootcmd.c b/drivers/net/wireless/libertas/if_bootcmd.c
new file mode 100644
index 000000000000..567000c3e87b
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_bootcmd.c
@@ -0,0 +1,38 @@
1/**
2 * This file contains functions used in USB Boot command
3 * and Boot2/FW update
4 */
5
6#include <linux/delay.h>
7#include <linux/firmware.h>
8#include <linux/netdevice.h>
9#include <linux/usb.h>
10
11#include "defs.h"
12#include "dev.h"
13#include "if_usb.h"
14
15/**
16 * @brief This function issues Boot command to the Boot2 code
17 * @param ivalue 1:Boot from FW by USB-Download
18 * 2:Boot from FW in EEPROM
19 * @return 0
20 */
21int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
22{
23 struct usb_card_rec *cardp = priv->wlan_dev.card;
24 struct bootcmdstr sbootcmd;
25 int i;
26
27 /* Prepare command */
28 sbootcmd.u32magicnumber = BOOT_CMD_MAGIC_NUMBER;
29 sbootcmd.u8cmd_tag = ivalue;
30 for (i=0; i<11; i++)
31 sbootcmd.au8dumy[i]=0x00;
32 memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
33
34 /* Issue command */
35 usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
36
37 return 0;
38}
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
new file mode 100644
index 000000000000..695fb6a66ffe
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -0,0 +1,952 @@
1/**
2 * This file contains functions used in USB interface module.
3 */
4#include <linux/delay.h>
5#include <linux/firmware.h>
6#include <linux/netdevice.h>
7#include <linux/usb.h>
8
9#include "host.h"
10#include "sbi.h"
11#include "decl.h"
12#include "defs.h"
13#include "dev.h"
14#include "if_usb.h"
15
16#define MESSAGE_HEADER_LEN 4
17
18static const char usbdriver_name[] = "usb8xxx";
19
20static struct usb_device_id if_usb_table[] = {
21 /* Enter the device signature inside */
22 {
23 USB_DEVICE(USB8388_VID_1, USB8388_PID_1),
24 },
25 {
26 USB_DEVICE(USB8388_VID_2, USB8388_PID_2),
27 },
28 {} /* Terminating entry */
29};
30
31MODULE_DEVICE_TABLE(usb, if_usb_table);
32
33static void if_usb_receive(struct urb *urb);
34static void if_usb_receive_fwload(struct urb *urb);
35
36/**
37 * @brief call back function to handle the status of the URB
38 * @param urb pointer to urb structure
39 * @return N/A
40 */
41static void if_usb_write_bulk_callback(struct urb *urb)
42{
43 wlan_private *priv = (wlan_private *) (urb->context);
44 wlan_adapter *adapter = priv->adapter;
45 struct net_device *dev = priv->wlan_dev.netdev;
46
47 /* handle the transmission complete validations */
48
49 if (urb->status != 0) {
50 /* print the failure status number for debug */
51 lbs_pr_info("URB in failure status\n");
52 } else {
53 lbs_dev_dbg(2, &urb->dev->dev, "URB status is successfull\n");
54 lbs_dev_dbg(2, &urb->dev->dev, "Actual length transmitted %d\n",
55 urb->actual_length);
56 priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
57 /* Wake main thread if commands are pending */
58 if (!adapter->cur_cmd)
59 wake_up_interruptible(&priv->mainthread.waitq);
60 if ((adapter->connect_status == libertas_connected))
61 netif_wake_queue(dev);
62 }
63
64 return;
65}
66
67/**
68 * @brief free tx/rx urb, skb and rx buffer
69 * @param cardp pointer usb_card_rec
70 * @return N/A
71 */
72void if_usb_free(struct usb_card_rec *cardp)
73{
74 ENTER();
75
76 /* Unlink tx & rx urb */
77 usb_kill_urb(cardp->tx_urb);
78 usb_kill_urb(cardp->rx_urb);
79
80 usb_free_urb(cardp->tx_urb);
81 cardp->tx_urb = NULL;
82
83 usb_free_urb(cardp->rx_urb);
84 cardp->rx_urb = NULL;
85
86 kfree(cardp->bulk_out_buffer);
87 cardp->bulk_out_buffer = NULL;
88
89 LEAVE();
90 return;
91}
92
93/**
94 * @brief sets the configuration values
95 * @param ifnum interface number
96 * @param id pointer to usb_device_id
97 * @return 0 on success, error code on failure
98 */
99static int if_usb_probe(struct usb_interface *intf,
100 const struct usb_device_id *id)
101{
102 struct usb_device *udev;
103 struct usb_host_interface *iface_desc;
104 struct usb_endpoint_descriptor *endpoint;
105 wlan_private *pwlanpriv;
106 struct usb_card_rec *usb_cardp;
107 int i;
108
109 udev = interface_to_usbdev(intf);
110
111 usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
112 if (!usb_cardp) {
113 lbs_pr_err("Out of memory allocating private data.\n");
114 goto error;
115 }
116
117 usb_cardp->udev = udev;
118 iface_desc = intf->cur_altsetting;
119
120 lbs_dev_dbg(1, &udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
121 " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
122 udev->descriptor.bcdUSB,
123 udev->descriptor.bDeviceClass,
124 udev->descriptor.bDeviceSubClass,
125 udev->descriptor.bDeviceProtocol);
126
127 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
128 endpoint = &iface_desc->endpoint[i].desc;
129 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
130 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
131 USB_ENDPOINT_XFER_BULK)) {
132 /* we found a bulk in endpoint */
133 lbs_dev_dbg(1, &udev->dev, "Bulk in size is %d\n",
134 endpoint->wMaxPacketSize);
135 if (!
136 (usb_cardp->rx_urb =
137 usb_alloc_urb(0, GFP_KERNEL))) {
138 lbs_dev_dbg(1, &udev->dev,
139 "Rx URB allocation failed\n");
140 goto dealloc;
141 }
142 usb_cardp->rx_urb_recall = 0;
143
144 usb_cardp->bulk_in_size =
145 endpoint->wMaxPacketSize;
146 usb_cardp->bulk_in_endpointAddr =
147 (endpoint->
148 bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
149 lbs_dev_dbg(1, &udev->dev, "in_endpoint = %d\n",
150 endpoint->bEndpointAddress);
151 }
152
153 if (((endpoint->
154 bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
155 USB_DIR_OUT)
156 && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
157 USB_ENDPOINT_XFER_BULK)) {
158 /* We found bulk out endpoint */
159 if (!
160 (usb_cardp->tx_urb =
161 usb_alloc_urb(0, GFP_KERNEL))) {
162 lbs_dev_dbg(1,&udev->dev,
163 "Tx URB allocation failed\n");
164 goto dealloc;
165 }
166
167 usb_cardp->bulk_out_size =
168 endpoint->wMaxPacketSize;
169 lbs_dev_dbg(1, &udev->dev,
170 "Bulk out size is %d\n",
171 endpoint->wMaxPacketSize);
172 usb_cardp->bulk_out_endpointAddr =
173 endpoint->bEndpointAddress;
174 lbs_dev_dbg(1, &udev->dev, "out_endpoint = %d\n",
175 endpoint->bEndpointAddress);
176 usb_cardp->bulk_out_buffer =
177 kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
178 GFP_KERNEL);
179
180 if (!usb_cardp->bulk_out_buffer) {
181 lbs_dev_dbg(1, &udev->dev,
182 "Could not allocate buffer\n");
183 goto dealloc;
184 }
185 }
186 }
187
188
189 /* At this point wlan_add_card() will be called. Don't worry
190 * about keeping pwlanpriv around since it will be set on our
191 * usb device data in -> add() -> libertas_sbi_register_dev().
192 */
193 if (!(pwlanpriv = wlan_add_card(usb_cardp)))
194 goto dealloc;
195
196 usb_get_dev(udev);
197 usb_set_intfdata(intf, usb_cardp);
198
199 /*
200 * return card structure, which can be got back in the
201 * diconnect function as the ptr
202 * argument.
203 */
204 return 0;
205
206dealloc:
207 if_usb_free(usb_cardp);
208
209error:
210 return -ENOMEM;
211}
212
213/**
214 * @brief free resource and cleanup
215 * @param udev pointer to usb_device
216 * @param ptr pointer to usb_cardp
217 * @return N/A
218 */
219static void if_usb_disconnect(struct usb_interface *intf)
220{
221 struct usb_card_rec *cardp = usb_get_intfdata(intf);
222 wlan_private *priv = (wlan_private *) cardp->priv;
223 wlan_adapter *adapter = NULL;
224
225 adapter = priv->adapter;
226
227 /*
228 * Update Surprise removed to TRUE
229 */
230 adapter->surpriseremoved = 1;
231
232 /* card is removed and we can call wlan_remove_card */
233 lbs_dev_dbg(1, &cardp->udev->dev, "call remove card\n");
234 wlan_remove_card(cardp);
235
236 /* Unlink and free urb */
237 if_usb_free(cardp);
238
239 usb_set_intfdata(intf, NULL);
240 usb_put_dev(interface_to_usbdev(intf));
241
242 return;
243}
244
245/**
246 * @brief This function download FW
247 * @param priv pointer to wlan_private
248 * @return 0
249 */
250static int if_prog_firmware(wlan_private * priv)
251{
252 struct usb_card_rec *cardp = priv->wlan_dev.card;
253 struct FWData *fwdata;
254 struct fwheader *fwheader;
255 u8 *firmware = priv->firmware->data;
256
257 fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
258
259 if (!fwdata)
260 return -1;
261
262 fwheader = &fwdata->fwheader;
263
264 if (!cardp->CRC_OK) {
265 cardp->totalbytes = cardp->fwlastblksent;
266 cardp->fwseqnum = cardp->lastseqnum - 1;
267 }
268
269 lbs_dev_dbg(2, &cardp->udev->dev, "totalbytes = %d\n",
270 cardp->totalbytes);
271
272 memcpy(fwheader, &firmware[cardp->totalbytes],
273 sizeof(struct fwheader));
274
275 cardp->fwlastblksent = cardp->totalbytes;
276 cardp->totalbytes += sizeof(struct fwheader);
277
278 lbs_dev_dbg(2, &cardp->udev->dev,"Copy Data\n");
279 memcpy(fwdata->data, &firmware[cardp->totalbytes],
280 fwdata->fwheader.datalength);
281
282 lbs_dev_dbg(2, &cardp->udev->dev,
283 "Data length = %d\n", fwdata->fwheader.datalength);
284
285 cardp->fwseqnum = cardp->fwseqnum + 1;
286
287 fwdata->seqnum = cardp->fwseqnum;
288 cardp->lastseqnum = fwdata->seqnum;
289 cardp->totalbytes += fwdata->fwheader.datalength;
290
291 if (fwheader->dnldcmd == FW_HAS_DATA_TO_RECV) {
292 lbs_dev_dbg(2, &cardp->udev->dev, "There is data to follow\n");
293 lbs_dev_dbg(2, &cardp->udev->dev,
294 "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
295 cardp->totalbytes);
296 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
297 usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
298
299 } else if (fwdata->fwheader.dnldcmd == FW_HAS_LAST_BLOCK) {
300 lbs_dev_dbg(2, &cardp->udev->dev,
301 "Host has finished FW downloading\n");
302 lbs_dev_dbg(2, &cardp->udev->dev,
303 "Donwloading FW JUMP BLOCK\n");
304 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
305 usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
306 cardp->fwfinalblk = 1;
307 }
308
309 lbs_dev_dbg(2, &cardp->udev->dev,
310 "The firmware download is done size is %d\n",
311 cardp->totalbytes);
312
313 kfree(fwdata);
314
315 return 0;
316}
317
318static int libertas_do_reset(wlan_private *priv)
319{
320 int ret;
321 struct usb_card_rec *cardp = priv->wlan_dev.card;
322
323 ret = usb_reset_device(cardp->udev);
324 if (!ret) {
325 msleep(10);
326 reset_device(priv);
327 msleep(10);
328 }
329 return ret;
330}
331
332/**
333 * @brief This function transfer the data to the device.
334 * @param priv pointer to wlan_private
335 * @param payload pointer to payload data
336 * @param nb data length
337 * @return 0 or -1
338 */
339int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
340{
341 /* pointer to card structure */
342 struct usb_card_rec *cardp = priv->wlan_dev.card;
343 int ret = -1;
344
345 /* check if device is removed */
346 if (priv->adapter->surpriseremoved) {
347 lbs_dev_dbg(1, &cardp->udev->dev, "Device removed\n");
348 goto tx_ret;
349 }
350
351 usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
352 usb_sndbulkpipe(cardp->udev,
353 cardp->bulk_out_endpointAddr),
354 payload, nb, if_usb_write_bulk_callback, priv);
355
356 cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
357
358 if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
359 /* transfer failed */
360 lbs_dev_dbg(1, &cardp->udev->dev, "usb_submit_urb failed\n");
361 ret = -1;
362 } else {
363 lbs_dev_dbg(2, &cardp->udev->dev, "usb_submit_urb success\n");
364 ret = 0;
365 }
366
367tx_ret:
368 return ret;
369}
370
371static int __if_usb_submit_rx_urb(wlan_private * priv,
372 void (*callbackfn)
373 (struct urb *urb))
374{
375 struct usb_card_rec *cardp = priv->wlan_dev.card;
376 struct sk_buff *skb;
377 struct read_cb_info *rinfo = &cardp->rinfo;
378 int ret = -1;
379
380 if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
381 lbs_pr_err("No free skb\n");
382 goto rx_ret;
383 }
384
385 rinfo->skb = skb;
386
387 /* Fill the receive configuration URB and initialise the Rx call back */
388 usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
389 usb_rcvbulkpipe(cardp->udev,
390 cardp->bulk_in_endpointAddr),
391 skb->tail + IPFIELD_ALIGN_OFFSET,
392 MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
393 rinfo);
394
395 cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
396
397 lbs_dev_dbg(2, &cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
398 if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
399 /* handle failure conditions */
400 lbs_dev_dbg(1, &cardp->udev->dev, "Submit Rx URB failed\n");
401 ret = -1;
402 } else {
403 lbs_dev_dbg(2, &cardp->udev->dev, "Submit Rx URB success\n");
404 ret = 0;
405 }
406
407rx_ret:
408 return ret;
409}
410
411static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv)
412{
413 return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload);
414}
415
416static inline int if_usb_submit_rx_urb(wlan_private * priv)
417{
418 return __if_usb_submit_rx_urb(priv, &if_usb_receive);
419}
420
421static void if_usb_receive_fwload(struct urb *urb)
422{
423 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
424 wlan_private *priv = rinfo->priv;
425 struct sk_buff *skb = rinfo->skb;
426 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
427 struct fwsyncheader *syncfwheader;
428 struct bootcmdrespStr bootcmdresp;
429
430 if (urb->status) {
431 lbs_dev_dbg(1, &cardp->udev->dev,
432 "URB status is failed during fw load\n");
433 kfree_skb(skb);
434 return;
435 }
436
437 if (cardp->bootcmdresp == 0) {
438 memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
439 sizeof(bootcmdresp));
440 if (cardp->udev->descriptor.bcdDevice < 0x3106) {
441 kfree_skb(skb);
442 if_usb_submit_rx_urb_fwload(priv);
443 cardp->bootcmdresp = 1;
444 lbs_dev_dbg(1, &cardp->udev->dev,
445 "Received valid boot command response\n");
446 return;
447 }
448 if (bootcmdresp.u32magicnumber != BOOT_CMD_MAGIC_NUMBER) {
449 lbs_pr_info(
450 "boot cmd response wrong magic number (0x%x)\n",
451 bootcmdresp.u32magicnumber);
452 } else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
453 lbs_pr_info(
454 "boot cmd response cmd_tag error (%d)\n",
455 bootcmdresp.u8cmd_tag);
456 } else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
457 lbs_pr_info(
458 "boot cmd response result error (%d)\n",
459 bootcmdresp.u8result);
460 } else {
461 cardp->bootcmdresp = 1;
462 lbs_dev_dbg(1, &cardp->udev->dev,
463 "Received valid boot command response\n");
464 }
465 kfree_skb(skb);
466 if_usb_submit_rx_urb_fwload(priv);
467 return;
468 }
469
470 syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
471 if (!syncfwheader) {
472 lbs_dev_dbg(1, &cardp->udev->dev, "Failure to allocate syncfwheader\n");
473 kfree_skb(skb);
474 return;
475 }
476
477 memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
478 sizeof(struct fwsyncheader));
479
480 if (!syncfwheader->cmd) {
481 lbs_dev_dbg(2, &cardp->udev->dev,
482 "FW received Blk with correct CRC\n");
483 lbs_dev_dbg(2, &cardp->udev->dev,
484 "FW received Blk seqnum = %d\n",
485 syncfwheader->seqnum);
486 cardp->CRC_OK = 1;
487 } else {
488 lbs_dev_dbg(1, &cardp->udev->dev,
489 "FW received Blk with CRC error\n");
490 cardp->CRC_OK = 0;
491 }
492
493 kfree_skb(skb);
494
495 if (cardp->fwfinalblk) {
496 cardp->fwdnldover = 1;
497 goto exit;
498 }
499
500 if_prog_firmware(priv);
501
502 if_usb_submit_rx_urb_fwload(priv);
503exit:
504 kfree(syncfwheader);
505
506 return;
507
508}
509
510#define MRVDRV_MIN_PKT_LEN 30
511
512static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
513 struct usb_card_rec *cardp,
514 wlan_private *priv)
515{
516 if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
517 MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
518 lbs_dev_dbg(1, &cardp->udev->dev,
519 "Packet length is Invalid\n");
520 kfree_skb(skb);
521 return;
522 }
523
524 skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
525 skb_put(skb, recvlength);
526 skb_pull(skb, MESSAGE_HEADER_LEN);
527 libertas_process_rxed_packet(priv, skb);
528 priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
529}
530
531static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
532 struct sk_buff *skb,
533 struct usb_card_rec *cardp,
534 wlan_private *priv)
535{
536 u8 *cmdbuf;
537 if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
538 lbs_dev_dbg(1, &cardp->udev->dev,
539 "The receive buffer is too large\n");
540 kfree_skb(skb);
541 return;
542 }
543
544 if (!in_interrupt())
545 BUG();
546
547 spin_lock(&priv->adapter->driver_lock);
548 /* take care of cur_cmd = NULL case by reading the
549 * data to clear the interrupt */
550 if (!priv->adapter->cur_cmd) {
551 cmdbuf = priv->wlan_dev.upld_buf;
552 priv->adapter->hisregcpy &= ~his_cmdupldrdy;
553 } else
554 cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
555
556 cardp->usb_int_cause |= his_cmdupldrdy;
557 priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
558 memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
559 priv->wlan_dev.upld_len);
560
561 kfree_skb(skb);
562 libertas_interrupt(priv->wlan_dev.netdev);
563 spin_unlock(&priv->adapter->driver_lock);
564
565 lbs_dev_dbg(1, &cardp->udev->dev,
566 "Wake up main thread to handle cmd response\n");
567
568 return;
569}
570
571/**
572 * @brief This function reads of the packet into the upload buff,
573 * wake up the main thread and initialise the Rx callack.
574 *
575 * @param urb pointer to struct urb
576 * @return N/A
577 */
578static void if_usb_receive(struct urb *urb)
579{
580 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
581 wlan_private *priv = rinfo->priv;
582 struct sk_buff *skb = rinfo->skb;
583 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
584
585 int recvlength = urb->actual_length;
586 u8 *recvbuff = NULL;
587 u32 recvtype;
588
589 ENTER();
590
591 if (recvlength) {
592 if (urb->status) {
593 lbs_dev_dbg(1, &cardp->udev->dev,
594 "URB status is failed\n");
595 kfree_skb(skb);
596 goto setup_for_next;
597 }
598
599 recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
600 memcpy(&recvtype, recvbuff, sizeof(u32));
601 lbs_dev_dbg(1, &cardp->udev->dev,
602 "Recv length = 0x%x\n", recvlength);
603 lbs_dev_dbg(1, &cardp->udev->dev,
604 "Receive type = 0x%X\n", recvtype);
605 recvtype = le32_to_cpu(recvtype);
606 lbs_dev_dbg(1, &cardp->udev->dev,
607 "Receive type after = 0x%X\n", recvtype);
608 } else if (urb->status)
609 goto rx_exit;
610
611
612 switch (recvtype) {
613 case CMD_TYPE_DATA:
614 process_cmdtypedata(recvlength, skb, cardp, priv);
615 break;
616
617 case CMD_TYPE_REQUEST:
618 process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
619 break;
620
621 case CMD_TYPE_INDICATION:
622 /* Event cause handling */
623 spin_lock(&priv->adapter->driver_lock);
624 cardp->usb_event_cause = *(u32 *) (recvbuff + MESSAGE_HEADER_LEN);
625 lbs_dev_dbg(1, &cardp->udev->dev,"**EVENT** 0x%X\n",
626 cardp->usb_event_cause);
627 if (cardp->usb_event_cause & 0xffff0000) {
628 libertas_send_tx_feedback(priv);
629 break;
630 }
631 cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
632 cardp->usb_int_cause |= his_cardevent;
633 kfree_skb(skb);
634 libertas_interrupt(priv->wlan_dev.netdev);
635 spin_unlock(&priv->adapter->driver_lock);
636 goto rx_exit;
637 default:
638 kfree_skb(skb);
639 break;
640 }
641
642setup_for_next:
643 if_usb_submit_rx_urb(priv);
644rx_exit:
645 LEAVE();
646 return;
647}
648
649/**
650 * @brief This function downloads data to FW
651 * @param priv pointer to wlan_private structure
652 * @param type type of data
653 * @param buf pointer to data buffer
654 * @param len number of bytes
655 * @return 0 or -1
656 */
657int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
658{
659 int ret = -1;
660 u32 tmp;
661 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
662
663 lbs_dev_dbg(1, &cardp->udev->dev,"*** type = %u\n", type);
664 lbs_dev_dbg(1, &cardp->udev->dev,"size after = %d\n", nb);
665
666 if (type == MVMS_CMD) {
667 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
668 priv->wlan_dev.dnld_sent = DNLD_CMD_SENT;
669 memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
670 MESSAGE_HEADER_LEN);
671
672 } else {
673 tmp = cpu_to_le32(CMD_TYPE_DATA);
674 priv->wlan_dev.dnld_sent = DNLD_DATA_SENT;
675 memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
676 MESSAGE_HEADER_LEN);
677 }
678
679 memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
680
681 ret =
682 usb_tx_block(priv, cardp->bulk_out_buffer, nb + MESSAGE_HEADER_LEN);
683
684 return ret;
685}
686
687/* called with adapter->driver_lock held */
688int libertas_sbi_get_int_status(wlan_private * priv, u8 * ireg)
689{
690 struct usb_card_rec *cardp = priv->wlan_dev.card;
691
692 *ireg = cardp->usb_int_cause;
693 cardp->usb_int_cause = 0;
694
695 lbs_dev_dbg(1, &cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
696
697 return 0;
698}
699
700int libertas_sbi_read_event_cause(wlan_private * priv)
701{
702 struct usb_card_rec *cardp = priv->wlan_dev.card;
703 priv->adapter->eventcause = cardp->usb_event_cause;
704 /* Re-submit rx urb here to avoid event lost issue */
705 if_usb_submit_rx_urb(priv);
706 return 0;
707}
708
709int reset_device(wlan_private *priv)
710{
711 int ret;
712
713 ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
714 cmd_act_halt, 0, 0, NULL);
715 msleep_interruptible(10);
716
717 return ret;
718}
719
720int libertas_sbi_unregister_dev(wlan_private * priv)
721{
722 int ret = 0;
723
724 /* Need to send a Reset command to device before USB resources freed
725 * and wlan_remove_card() called, then device can handle FW download
726 * again.
727 */
728 if (priv)
729 reset_device(priv);
730
731 return ret;
732}
733
734
735/**
736 * @brief This function register usb device and initialize parameter
737 * @param priv pointer to wlan_private
738 * @return 0 or -1
739 */
740int libertas_sbi_register_dev(wlan_private * priv)
741{
742
743 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
744 ENTER();
745
746 cardp->priv = priv;
747 cardp->eth_dev = priv->wlan_dev.netdev;
748 priv->hotplug_device = &(cardp->udev->dev);
749
750 SET_NETDEV_DEV(cardp->eth_dev, &(cardp->udev->dev));
751
752 lbs_dev_dbg(1, &cardp->udev->dev, "udev pointer is at %p\n",
753 cardp->udev);
754
755 LEAVE();
756 return 0;
757}
758
759
760
761int libertas_sbi_prog_firmware(wlan_private * priv)
762{
763 struct usb_card_rec *cardp = priv->wlan_dev.card;
764 int i = 0;
765 static int reset_count = 10;
766
767 ENTER();
768
769 cardp->rinfo.priv = priv;
770
771restart:
772 if (if_usb_submit_rx_urb_fwload(priv) < 0) {
773 lbs_dev_dbg(1, &cardp->udev->dev, "URB submission is failed\n");
774 LEAVE();
775 return -1;
776 }
777
778#ifdef SUPPORT_BOOT_COMMAND
779 cardp->bootcmdresp = 0;
780 do {
781 int j = 0;
782 i++;
783 /* Issue Boot command = 1, Boot from Download-FW */
784 if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB);
785 /* wait for command response */
786 do {
787 j++;
788 msleep_interruptible(100);
789 } while (cardp->bootcmdresp == 0 && j < 10);
790 } while (cardp->bootcmdresp == 0 && i < 5);
791
792 if (cardp->bootcmdresp == 0) {
793 if (--reset_count >= 0) {
794 libertas_do_reset(priv);
795 goto restart;
796 }
797 return -1;
798 }
799#endif
800
801 i = 0;
802 priv->adapter->fw_ready = 0;
803
804 cardp->totalbytes = 0;
805 cardp->fwlastblksent = 0;
806 cardp->CRC_OK = 1;
807 cardp->fwdnldover = 0;
808 cardp->fwseqnum = -1;
809 cardp->totalbytes = 0;
810 cardp->fwfinalblk = 0;
811
812 if_prog_firmware(priv);
813
814 do {
815 lbs_dev_dbg(1, &cardp->udev->dev,"Wlan sched timeout\n");
816 i++;
817 msleep_interruptible(100);
818 if (priv->adapter->surpriseremoved || i >= 20)
819 break;
820 } while (!cardp->fwdnldover);
821
822 if (!cardp->fwdnldover) {
823 lbs_pr_info("failed to load fw, resetting device!\n");
824 if (--reset_count >= 0) {
825 libertas_do_reset(priv);
826 goto restart;
827 }
828
829 lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
830 LEAVE();
831 return -1;
832 }
833
834 if_usb_submit_rx_urb(priv);
835
836 /* Delay 200 ms to waiting for the FW ready */
837 msleep_interruptible(200);
838
839 priv->adapter->fw_ready = 1;
840
841 LEAVE();
842 return 0;
843}
844
845/**
846 * @brief Given a usb_card_rec return its wlan_private
847 * @param card pointer to a usb_card_rec
848 * @return pointer to wlan_private
849 */
850wlan_private *libertas_sbi_get_priv(void *card)
851{
852 struct usb_card_rec *cardp = card;
853 return cardp->priv;
854}
855
856#ifdef ENABLE_PM
857int libertas_sbi_suspend(wlan_private * priv)
858{
859 return 0;
860}
861
862int libertas_sbi_resume(wlan_private * priv)
863{
864 return 0;
865}
866#endif
867
868#ifdef CONFIG_PM
869static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
870{
871 struct usb_card_rec *cardp = usb_get_intfdata(intf);
872 wlan_private *priv = cardp->priv;
873
874 ENTER();
875
876 if (priv->adapter->psstate != PS_STATE_FULL_POWER)
877 return -1;
878
879 netif_device_detach(cardp->eth_dev);
880
881 /* Unlink tx & rx urb */
882 usb_kill_urb(cardp->tx_urb);
883 usb_kill_urb(cardp->rx_urb);
884
885 cardp->rx_urb_recall = 1;
886
887 LEAVE();
888 return 0;
889}
890
891static int if_usb_resume(struct usb_interface *intf)
892{
893 struct usb_card_rec *cardp = usb_get_intfdata(intf);
894
895 ENTER();
896
897 cardp->rx_urb_recall = 0;
898
899 if_usb_submit_rx_urb(cardp->priv);
900
901 netif_device_attach(cardp->eth_dev);
902
903 LEAVE();
904 return 0;
905}
906#else
907#define if_usb_suspend NULL
908#define if_usb_resume NULL
909#endif
910
911static struct usb_driver if_usb_driver = {
912 /* driver name */
913 .name = usbdriver_name,
914 /* probe function name */
915 .probe = if_usb_probe,
916 /* disconnect function name */
917 .disconnect = if_usb_disconnect,
918 /* device signature table */
919 .id_table = if_usb_table,
920 .suspend = if_usb_suspend,
921 .resume = if_usb_resume,
922};
923
924/**
925 * @brief This function registers driver.
926 * @param add pointer to add_card callback function
927 * @param remove pointer to remove card callback function
928 * @param arg pointer to call back function parameter
929 * @return dummy success variable
930 */
931int libertas_sbi_register(void)
932{
933 /*
934 * API registers the Marvell USB driver
935 * to the USB system
936 */
937 usb_register(&if_usb_driver);
938
939 /* Return success to wlan layer */
940 return 0;
941}
942
943/**
944 * @brief This function removes usb driver.
945 * @return N/A
946 */
947void libertas_sbi_unregister(void)
948{
949 /* API unregisters the driver from USB subsystem */
950 usb_deregister(&if_usb_driver);
951 return;
952}
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
new file mode 100644
index 000000000000..785116720bc6
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -0,0 +1,109 @@
1/**
2 * This file contains definition for USB interface.
3 */
4#define CMD_TYPE_REQUEST 0xF00DFACE
5#define CMD_TYPE_DATA 0xBEADC0DE
6#define CMD_TYPE_INDICATION 0xBEEFFACE
7
8#define IPFIELD_ALIGN_OFFSET 2
9
10#define USB8388_VID_1 0x1286
11#define USB8388_PID_1 0x2001
12#define USB8388_VID_2 0x05a3
13#define USB8388_PID_2 0x8388
14
15#ifdef SUPPORT_BOOT_COMMAND
16#define BOOT_CMD_FW_BY_USB 0x01
17#define BOOT_CMD_FW_IN_EEPROM 0x02
18#define BOOT_CMD_UPDATE_BOOT2 0x03
19#define BOOT_CMD_UPDATE_FW 0x04
20#define BOOT_CMD_MAGIC_NUMBER 0x4C56524D /* M=>0x4D,R=>0x52,V=>0x56,L=>0x4C */
21
22struct bootcmdstr
23{
24 u32 u32magicnumber;
25 u8 u8cmd_tag;
26 u8 au8dumy[11];
27};
28
29#define BOOT_CMD_RESP_OK 0x0001
30#define BOOT_CMD_RESP_FAIL 0x0000
31
32struct bootcmdrespStr
33{
34 u32 u32magicnumber;
35 u8 u8cmd_tag;
36 u8 u8result;
37 u8 au8dumy[2];
38};
39#endif /* SUPPORT_BOOT_COMMAND */
40
41/* read callback private data */
42struct read_cb_info {
43 wlan_private *priv;
44 struct sk_buff *skb;
45};
46
47/** USB card description structure*/
48struct usb_card_rec {
49 struct net_device *eth_dev;
50 struct usb_device *udev;
51 struct urb *rx_urb, *tx_urb;
52 void *priv;
53 struct read_cb_info rinfo;
54
55 int bulk_in_size;
56 u8 bulk_in_endpointAddr;
57
58 u8 *bulk_out_buffer;
59 int bulk_out_size;
60 u8 bulk_out_endpointAddr;
61
62 u8 CRC_OK;
63 u32 fwseqnum;
64 u32 lastseqnum;
65 u32 totalbytes;
66 u32 fwlastblksent;
67 u8 fwdnldover;
68 u8 fwfinalblk;
69
70 u32 usb_event_cause;
71 u8 usb_int_cause;
72
73 u8 rx_urb_recall;
74
75 u8 bootcmdresp;
76};
77
78/** fwheader */
79struct fwheader {
80 u32 dnldcmd;
81 u32 baseaddr;
82 u32 datalength;
83 u32 CRC;
84};
85
86#define FW_MAX_DATA_BLK_SIZE 600
87/** FWData */
88struct FWData {
89 struct fwheader fwheader;
90 u32 seqnum;
91 u8 data[FW_MAX_DATA_BLK_SIZE];
92};
93
94/** fwsyncheader */
95struct fwsyncheader {
96 u32 cmd;
97 u32 seqnum;
98};
99
100#define FW_HAS_DATA_TO_RECV 0x00000001
101#define FW_HAS_LAST_BLOCK 0x00000004
102
103#define FW_DATA_XMIT_SIZE \
104 sizeof(struct fwheader) + fwdata->fwheader.datalength + sizeof(u32)
105
106int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
107void if_usb_free(struct usb_card_rec *cardp);
108int if_usb_issue_boot_command(wlan_private *priv, int ivalue);
109
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
new file mode 100644
index 000000000000..82b39642423a
--- /dev/null
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -0,0 +1,2500 @@
1/**
2 * This file contains ioctl functions
3 */
4
5#include <linux/ctype.h>
6#include <linux/delay.h>
7#include <linux/if.h>
8#include <linux/if_arp.h>
9#include <linux/wireless.h>
10
11#include <net/iw_handler.h>
12#include <net/ieee80211.h>
13
14#include "host.h"
15#include "radiotap.h"
16#include "decl.h"
17#include "defs.h"
18#include "dev.h"
19#include "join.h"
20#include "wext.h"
21
22#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \
23 IW_ESSID_MAX_SIZE + \
24 IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \
25 IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \
26 IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */
27
28#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
29
30static int setrxantenna(wlan_private * priv, int mode)
31{
32 int ret = 0;
33 wlan_adapter *adapter = priv->adapter;
34
35 if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2
36 && mode != RF_ANTENNA_AUTO) {
37 return -EINVAL;
38 }
39
40 adapter->rxantennamode = mode;
41
42 lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode);
43
44 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
45 cmd_act_set_rx,
46 cmd_option_waitforrsp, 0,
47 &adapter->rxantennamode);
48 return ret;
49}
50
51static int settxantenna(wlan_private * priv, int mode)
52{
53 int ret = 0;
54 wlan_adapter *adapter = priv->adapter;
55
56 if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2)
57 && (mode != RF_ANTENNA_AUTO)) {
58 return -EINVAL;
59 }
60
61 adapter->txantennamode = mode;
62
63 lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode);
64
65 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
66 cmd_act_set_tx,
67 cmd_option_waitforrsp, 0,
68 &adapter->txantennamode);
69
70 return ret;
71}
72
73static int getrxantenna(wlan_private * priv, char *buf)
74{
75 int ret = 0;
76 wlan_adapter *adapter = priv->adapter;
77
78 // clear it, so we will know if the value
79 // returned below is correct or not.
80 adapter->rxantennamode = 0;
81
82 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
83 cmd_act_get_rx,
84 cmd_option_waitforrsp, 0, NULL);
85
86 if (ret) {
87 LEAVE();
88 return ret;
89 }
90
91 lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode);
92
93 return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1;
94}
95
96static int gettxantenna(wlan_private * priv, char *buf)
97{
98 int ret = 0;
99 wlan_adapter *adapter = priv->adapter;
100
101 // clear it, so we will know if the value
102 // returned below is correct or not.
103 adapter->txantennamode = 0;
104
105 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
106 cmd_act_get_tx,
107 cmd_option_waitforrsp, 0, NULL);
108
109 if (ret) {
110 LEAVE();
111 return ret;
112 }
113
114 lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode);
115
116 return sprintf(buf, "0x%04x", adapter->txantennamode) + 1;
117}
118
119static int wlan_set_region(wlan_private * priv, u16 region_code)
120{
121 int i;
122
123 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
124 // use the region code to search for the index
125 if (region_code == libertas_region_code_to_index[i]) {
126 priv->adapter->regiontableindex = (u16) i;
127 priv->adapter->regioncode = region_code;
128 break;
129 }
130 }
131
132 // if it's unidentified region code
133 if (i >= MRVDRV_MAX_REGION_CODE) {
134 lbs_pr_debug(1, "region Code not identified\n");
135 LEAVE();
136 return -1;
137 }
138
139 if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
140 LEAVE();
141 return -EINVAL;
142 }
143
144 return 0;
145}
146
147/**
148 * @brief Get/Set Firmware wakeup method
149 *
150 * @param priv A pointer to wlan_private structure
151 * @param wrq A pointer to user data
152 * @return 0--success, otherwise fail
153 */
154static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq)
155{
156 wlan_adapter *adapter = priv->adapter;
157 int data;
158 ENTER();
159
160 if ((int)wrq->u.data.length == 0) {
161 if (copy_to_user
162 (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) {
163 lbs_pr_alert("copy_to_user failed!\n");
164 return -EFAULT;
165 }
166 } else {
167 if ((int)wrq->u.data.length > 1) {
168 lbs_pr_alert("ioctl too many args!\n");
169 return -EFAULT;
170 }
171 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
172 lbs_pr_alert("Copy from user failed\n");
173 return -EFAULT;
174 }
175
176 adapter->pkttxctrl = (u32) data;
177 }
178
179 wrq->u.data.length = 1;
180
181 LEAVE();
182 return 0;
183}
184
185/**
186 * @brief Get/Set NULL Package generation interval
187 *
188 * @param priv A pointer to wlan_private structure
189 * @param wrq A pointer to user data
190 * @return 0--success, otherwise fail
191 */
192static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq)
193{
194 wlan_adapter *adapter = priv->adapter;
195 int data;
196 ENTER();
197
198 if ((int)wrq->u.data.length == 0) {
199 data = adapter->nullpktinterval;
200
201 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
202 lbs_pr_alert( "copy_to_user failed!\n");
203 return -EFAULT;
204 }
205 } else {
206 if ((int)wrq->u.data.length > 1) {
207 lbs_pr_alert( "ioctl too many args!\n");
208 return -EFAULT;
209 }
210 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
211 lbs_pr_debug(1, "Copy from user failed\n");
212 return -EFAULT;
213 }
214
215 adapter->nullpktinterval = data;
216 }
217
218 wrq->u.data.length = 1;
219
220 LEAVE();
221 return 0;
222}
223
224static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq)
225{
226 wlan_adapter *adapter = priv->adapter;
227 int data[2];
228 ENTER();
229 data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
230 data[1] = adapter->rxpd_rate;
231 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
232 lbs_pr_debug(1, "Copy to user failed\n");
233 return -EFAULT;
234 }
235 wrq->u.data.length = 2;
236 LEAVE();
237 return 0;
238}
239
240static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq)
241{
242 int ret = 0;
243 wlan_adapter *adapter = priv->adapter;
244 int data[4];
245
246 ENTER();
247 memset(data, 0, sizeof(data));
248 if (wrq->u.data.length) {
249 if (copy_from_user(data, wrq->u.data.pointer,
250 min_t(size_t, wrq->u.data.length, 4) * sizeof(int)))
251 return -EFAULT;
252 }
253 if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) {
254 if (adapter->connect_status == libertas_connected) {
255 ret = libertas_prepare_and_send_command(priv,
256 cmd_802_11_rssi,
257 0,
258 cmd_option_waitforrsp,
259 0, NULL);
260
261 if (ret) {
262 LEAVE();
263 return ret;
264 }
265 }
266 }
267
268 if (wrq->u.data.length == 0) {
269 data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
270 data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
271 data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
272 data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
273 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4))
274 return -EFAULT;
275 wrq->u.data.length = 4;
276 } else if (data[0] == 0) {
277 data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
278 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
279 return -EFAULT;
280 wrq->u.data.length = 1;
281 } else if (data[0] == 1) {
282 data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
283 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
284 return -EFAULT;
285 wrq->u.data.length = 1;
286 } else if (data[0] == 2) {
287 data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
288 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
289 return -EFAULT;
290 wrq->u.data.length = 1;
291 } else if (data[0] == 3) {
292 data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
293 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
294 return -EFAULT;
295 wrq->u.data.length = 1;
296 } else
297 return -ENOTSUPP;
298
299 LEAVE();
300 return 0;
301}
302
303static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq)
304{
305 int data;
306 wlan_adapter *adapter = priv->adapter;
307
308 if (wrq->u.data.length > 0) {
309 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int)))
310 return -EFAULT;
311
312 lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data);
313 if ((data > MRVDRV_MAX_BEACON_INTERVAL)
314 || (data < MRVDRV_MIN_BEACON_INTERVAL))
315 return -ENOTSUPP;
316 adapter->beaconperiod = data;
317 }
318 data = adapter->beaconperiod;
319 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int)))
320 return -EFAULT;
321
322 wrq->u.data.length = 1;
323
324 return 0;
325}
326
327static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq)
328{
329 int ret = 0;
330 wlan_adapter *adapter = priv->adapter;
331 int temp;
332 int data = 0;
333 int *val;
334
335 ENTER();
336 data = SUBCMD_DATA(wrq);
337 if ((data == 0) || (data == 1)) {
338 ret = libertas_prepare_and_send_command(priv,
339 cmd_802_11_rssi,
340 0, cmd_option_waitforrsp,
341 0, NULL);
342 if (ret) {
343 LEAVE();
344 return ret;
345 }
346 }
347
348 switch (data) {
349 case 0:
350
351 temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
352 adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
353 break;
354 case 1:
355 temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG],
356 adapter->NF[TYPE_BEACON][TYPE_AVG]);
357 break;
358 case 2:
359 temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
360 adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
361 break;
362 case 3:
363 temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
364 adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
365 break;
366 default:
367 return -ENOTSUPP;
368 }
369 val = (int *)wrq->u.name;
370 *val = temp;
371
372 LEAVE();
373 return 0;
374}
375
376static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq)
377{
378 int ret = 0;
379 wlan_adapter *adapter = priv->adapter;
380 int temp;
381 int data = 0;
382 int *val;
383
384 data = SUBCMD_DATA(wrq);
385 if ((data == 0) || (data == 1)) {
386 ret = libertas_prepare_and_send_command(priv,
387 cmd_802_11_rssi,
388 0, cmd_option_waitforrsp,
389 0, NULL);
390
391 if (ret) {
392 LEAVE();
393 return ret;
394 }
395 }
396
397 switch (data) {
398 case 0:
399 temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG];
400 break;
401 case 1:
402 temp = adapter->NF[TYPE_BEACON][TYPE_AVG];
403 break;
404 case 2:
405 temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG];
406 break;
407 case 3:
408 temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
409 break;
410 default:
411 return -ENOTSUPP;
412 }
413
414 temp = CAL_NF(temp);
415
416 lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp);
417 val = (int *)wrq->u.name;
418 *val = temp;
419 return 0;
420}
421
422static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req)
423{
424 wlan_adapter *adapter = priv->adapter;
425 int *pdata;
426 struct iwreq *wrq = (struct iwreq *)req;
427 int ret = 0;
428 adapter->txrate = 0;
429 lbs_pr_debug(1, "wlan_get_txrate_ioctl\n");
430 ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query,
431 cmd_act_get, cmd_option_waitforrsp,
432 0, NULL);
433 if (ret)
434 return ret;
435
436 pdata = (int *)wrq->u.name;
437 *pdata = (int)adapter->txrate;
438 return 0;
439}
440
441static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq)
442{
443 char status[64];
444 wlan_adapter *adapter = priv->adapter;
445
446 memset(status, 0, sizeof(status));
447
448 switch (adapter->inframode) {
449 case wlan802_11ibss:
450 if (adapter->connect_status == libertas_connected) {
451 if (adapter->adhoccreate)
452 memcpy(&status, "AdhocStarted", sizeof(status));
453 else
454 memcpy(&status, "AdhocJoined", sizeof(status));
455 } else {
456 memcpy(&status, "AdhocIdle", sizeof(status));
457 }
458 break;
459 case wlan802_11infrastructure:
460 memcpy(&status, "Inframode", sizeof(status));
461 break;
462 default:
463 memcpy(&status, "AutoUnknownmode", sizeof(status));
464 break;
465 }
466
467 lbs_pr_debug(1, "status = %s\n", status);
468 wrq->u.data.length = strlen(status) + 1;
469
470 if (wrq->u.data.pointer) {
471 if (copy_to_user(wrq->u.data.pointer,
472 &status, wrq->u.data.length))
473 return -EFAULT;
474 }
475
476 LEAVE();
477 return 0;
478}
479
480/**
481 * @brief Set/Get WPA IE
482 * @param priv A pointer to wlan_private structure
483 * @param req A pointer to ifreq structure
484 * @return 0 --success, otherwise fail
485 */
486static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req)
487{
488 struct iwreq *wrq = (struct iwreq *)req;
489 wlan_adapter *adapter = priv->adapter;
490 int ret = 0;
491
492 ENTER();
493
494 if (wrq->u.data.length) {
495 if (wrq->u.data.length > sizeof(adapter->wpa_ie)) {
496 lbs_pr_debug(1, "failed to copy WPA IE, too big \n");
497 return -EFAULT;
498 }
499 if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer,
500 wrq->u.data.length)) {
501 lbs_pr_debug(1, "failed to copy WPA IE \n");
502 return -EFAULT;
503 }
504 adapter->wpa_ie_len = wrq->u.data.length;
505 lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len,
506 adapter->wpa_ie[0]);
507 lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len);
508 if (adapter->wpa_ie[0] == WPA_IE)
509 adapter->secinfo.WPAenabled = 1;
510 else if (adapter->wpa_ie[0] == WPA2_IE)
511 adapter->secinfo.WPA2enabled = 1;
512 else {
513 adapter->secinfo.WPAenabled = 0;
514 adapter->secinfo.WPA2enabled = 0;
515 }
516 } else {
517 memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie));
518 adapter->wpa_ie_len = wrq->u.data.length;
519 lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n",
520 adapter->wpa_ie_len, adapter->wpa_ie[0]);
521 adapter->secinfo.WPAenabled = 0;
522 adapter->secinfo.WPA2enabled = 0;
523 }
524
525 // enable/disable RSN in firmware if WPA is enabled/disabled
526 // depending on variable adapter->secinfo.WPAenabled is set or not
527 ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn,
528 cmd_act_set, cmd_option_waitforrsp,
529 0, NULL);
530
531 LEAVE();
532 return ret;
533}
534
535/**
536 * @brief Set Auto prescan
537 * @param priv A pointer to wlan_private structure
538 * @param wrq A pointer to iwreq structure
539 * @return 0 --success, otherwise fail
540 */
541static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq)
542{
543 int data;
544 wlan_adapter *adapter = priv->adapter;
545 int *val;
546
547 data = SUBCMD_DATA(wrq);
548 lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data);
549 adapter->prescan = data;
550
551 val = (int *)wrq->u.name;
552 *val = data;
553 return 0;
554}
555
556static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req)
557{
558 struct iwreq *wrq = (struct iwreq *)req;
559 u32 mdtim;
560 int idata;
561 int ret = -EINVAL;
562
563 ENTER();
564
565 idata = SUBCMD_DATA(wrq);
566 mdtim = (u32) idata;
567 if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM)
568 && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM))
569 || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) {
570 priv->adapter->multipledtim = mdtim;
571 ret = 0;
572 }
573 if (ret)
574 lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n");
575
576 LEAVE();
577 return ret;
578}
579
580/**
581 * @brief Set authentication mode
582 * @param priv A pointer to wlan_private structure
583 * @param req A pointer to ifreq structure
584 * @return 0 --success, otherwise fail
585 */
586static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req)
587{
588 int alg;
589 struct iwreq *wrq = (struct iwreq *)req;
590 wlan_adapter *adapter = priv->adapter;
591
592 if (wrq->u.data.flags == 0) {
593 //from iwpriv subcmd
594 alg = SUBCMD_DATA(wrq);
595 } else {
596 //from wpa_supplicant subcmd
597 if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) {
598 lbs_pr_debug(1, "Copy from user failed\n");
599 return -EFAULT;
600 }
601 }
602
603 lbs_pr_debug(1, "auth alg is %#x\n", alg);
604
605 switch (alg) {
606 case AUTH_ALG_SHARED_KEY:
607 adapter->secinfo.authmode = wlan802_11authmodeshared;
608 break;
609 case AUTH_ALG_NETWORK_EAP:
610 adapter->secinfo.authmode =
611 wlan802_11authmodenetworkEAP;
612 break;
613 case AUTH_ALG_OPEN_SYSTEM:
614 default:
615 adapter->secinfo.authmode = wlan802_11authmodeopen;
616 break;
617 }
618 return 0;
619}
620
621/**
622 * @brief Set 802.1x authentication mode
623 * @param priv A pointer to wlan_private structure
624 * @param req A pointer to ifreq structure
625 * @return 0 --success, otherwise fail
626 */
627static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req)
628{
629 int alg;
630 struct iwreq *wrq = (struct iwreq *)req;
631
632 if (wrq->u.data.flags == 0) {
633 //from iwpriv subcmd
634 alg = SUBCMD_DATA(wrq);
635 } else {
636 //from wpa_supplicant subcmd
637 if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) {
638 lbs_pr_debug(1, "Copy from user failed\n");
639 return -EFAULT;
640 }
641 }
642 lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg);
643 priv->adapter->secinfo.auth1xalg = alg;
644 return 0;
645}
646
647static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
648{
649 int mode;
650 struct iwreq *wrq = (struct iwreq *)req;
651
652 ENTER();
653
654 if (wrq->u.data.flags == 0) {
655 //from iwpriv subcmd
656 mode = SUBCMD_DATA(wrq);
657 } else {
658 //from wpa_supplicant subcmd
659 if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
660 lbs_pr_debug(1, "Copy from user failed\n");
661 return -EFAULT;
662 }
663 }
664 lbs_pr_debug(1, "encryption mode is %#x\n", mode);
665 priv->adapter->secinfo.Encryptionmode = mode;
666
667 LEAVE();
668 return 0;
669}
670
671static void adjust_mtu(wlan_private * priv)
672{
673 int mtu_increment = 0;
674
675 if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
676 mtu_increment += sizeof(struct ieee80211_hdr_4addr);
677
678 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
679 mtu_increment += max(sizeof(struct tx_radiotap_hdr),
680 sizeof(struct rx_radiotap_hdr));
681 priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
682 - sizeof(struct ethhdr)
683 + mtu_increment;
684}
685
686/**
687 * @brief Set Link-Layer Layer mode
688 * @param priv A pointer to wlan_private structure
689 * @param req A pointer to ifreq structure
690 * @return 0 --success, otherwise fail
691 */
692static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
693{
694 int mode;
695
696 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
697
698 switch (mode) {
699 case WLAN_LINKMODE_802_3:
700 priv->adapter->linkmode = mode;
701 break;
702 case WLAN_LINKMODE_802_11:
703 priv->adapter->linkmode = mode;
704 break;
705 default:
706 lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
707 mode);
708 return -EINVAL;
709 break;
710 }
711 lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
712
713 adjust_mtu(priv);
714
715 return 0;
716}
717
718/**
719 * @brief Set Radio header mode
720 * @param priv A pointer to wlan_private structure
721 * @param req A pointer to ifreq structure
722 * @return 0 --success, otherwise fail
723 */
724static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
725{
726 int mode;
727
728 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
729
730 switch (mode) {
731 case WLAN_RADIOMODE_NONE:
732 priv->adapter->radiomode = mode;
733 break;
734 case WLAN_RADIOMODE_RADIOTAP:
735 priv->adapter->radiomode = mode;
736 break;
737 default:
738 lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
739 mode);
740 return -EINVAL;
741 }
742 lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
743
744 adjust_mtu(priv);
745 return 0;
746}
747
748/**
749 * @brief Set Debug header mode
750 * @param priv A pointer to wlan_private structure
751 * @param req A pointer to ifreq structure
752 * @return 0 --success, otherwise fail
753 */
754static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
755{
756 priv->adapter->debugmode = (int)((struct ifreq *)
757 ((u8 *) req + 4))->ifr_data;
758 return 0;
759}
760
761static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
762 struct ifreq *req)
763{
764 int len;
765 char buf[8];
766 struct iwreq *wrq = (struct iwreq *)req;
767
768 lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
769 len = getrxantenna(priv, buf);
770
771 wrq->u.data.length = len;
772 if (wrq->u.data.pointer) {
773 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
774 lbs_pr_debug(1, "CopyToUser failed\n");
775 return -EFAULT;
776 }
777 }
778
779 return 0;
780}
781
782static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
783 struct ifreq *req)
784{
785 int len;
786 char buf[8];
787 struct iwreq *wrq = (struct iwreq *)req;
788
789 lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
790 len = gettxantenna(priv, buf);
791
792 wrq->u.data.length = len;
793 if (wrq->u.data.pointer) {
794 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
795 lbs_pr_debug(1, "CopyToUser failed\n");
796 return -EFAULT;
797 }
798 }
799 return 0;
800}
801
802/**
803 * @brief Get the MAC TSF value from the firmware
804 *
805 * @param priv A pointer to wlan_private structure
806 * @param wrq A pointer to iwreq structure containing buffer
807 * space to store a TSF value retrieved from the firmware
808 *
809 * @return 0 if successful; IOCTL error code otherwise
810 */
811static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
812{
813 u64 tsfval;
814 int ret;
815
816 ret = libertas_prepare_and_send_command(priv,
817 cmd_get_tsf,
818 0, cmd_option_waitforrsp, 0, &tsfval);
819
820 lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
821
822 if (ret != 0) {
823 lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
824 ret = -EFAULT;
825 } else {
826 if (copy_to_user(wrq->u.data.pointer,
827 &tsfval,
828 min_t(size_t, wrq->u.data.length,
829 sizeof(tsfval))) != 0) {
830
831 lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
832 ret = -EFAULT;
833 } else {
834 ret = 0;
835 }
836 }
837 return ret;
838}
839
840/**
841 * @brief Get/Set adapt rate
842 * @param priv A pointer to wlan_private structure
843 * @param wrq A pointer to iwreq structure
844 * @return 0 --success, otherwise fail
845 */
846static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
847{
848 int ret;
849 wlan_adapter *adapter = priv->adapter;
850 int data[2];
851
852 memset(data, 0, sizeof(data));
853 if (!wrq->u.data.length) {
854 lbs_pr_debug(1, "Get ADAPT RATE SET\n");
855 ret = libertas_prepare_and_send_command(priv,
856 cmd_802_11_rate_adapt_rateset,
857 cmd_act_get,
858 cmd_option_waitforrsp, 0, NULL);
859 data[0] = adapter->enablehwauto;
860 data[1] = adapter->ratebitmap;
861 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
862 lbs_pr_debug(1, "Copy to user failed\n");
863 return -EFAULT;
864 }
865#define GET_TWO_INT 2
866 wrq->u.data.length = GET_TWO_INT;
867 } else {
868 lbs_pr_debug(1, "Set ADAPT RATE SET\n");
869 if (wrq->u.data.length > 2)
870 return -EINVAL;
871 if (copy_from_user
872 (data, wrq->u.data.pointer,
873 sizeof(int) * wrq->u.data.length)) {
874 lbs_pr_debug(1, "Copy from user failed\n");
875 return -EFAULT;
876 }
877
878 adapter->enablehwauto = data[0];
879 adapter->ratebitmap = data[1];
880 ret = libertas_prepare_and_send_command(priv,
881 cmd_802_11_rate_adapt_rateset,
882 cmd_act_set,
883 cmd_option_waitforrsp, 0, NULL);
884 }
885 return ret;
886}
887
888/**
889 * @brief Get/Set inactivity timeout
890 * @param priv A pointer to wlan_private structure
891 * @param wrq A pointer to iwreq structure
892 * @return 0 --success, otherwise fail
893 */
894static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
895{
896 int ret;
897 int data = 0;
898 u16 timeout = 0;
899
900 ENTER();
901 if (wrq->u.data.length > 1)
902 return -ENOTSUPP;
903
904 if (wrq->u.data.length == 0) {
905 /* Get */
906 ret = libertas_prepare_and_send_command(priv,
907 cmd_802_11_inactivity_timeout,
908 cmd_act_get,
909 cmd_option_waitforrsp, 0,
910 &timeout);
911 data = timeout;
912 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
913 lbs_pr_debug(1, "Copy to user failed\n");
914 return -EFAULT;
915 }
916 } else {
917 /* Set */
918 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
919 lbs_pr_debug(1, "Copy from user failed\n");
920 return -EFAULT;
921 }
922
923 timeout = data;
924 ret = libertas_prepare_and_send_command(priv,
925 cmd_802_11_inactivity_timeout,
926 cmd_act_set,
927 cmd_option_waitforrsp, 0,
928 &timeout);
929 }
930
931 wrq->u.data.length = 1;
932
933 LEAVE();
934 return ret;
935}
936
937static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
938{
939 int ret;
940 char buf[GETLOG_BUFSIZE - 1];
941 wlan_adapter *adapter = priv->adapter;
942
943 lbs_pr_debug(1, " GET STATS\n");
944
945 ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
946 0, cmd_option_waitforrsp, 0, NULL);
947
948 if (ret) {
949 return ret;
950 }
951
952 if (wrq->u.data.pointer) {
953 sprintf(buf, "\n mcasttxframe %u failed %u retry %u "
954 "multiretry %u framedup %u "
955 "rtssuccess %u rtsfailure %u ackfailure %u\n"
956 "rxfrag %u mcastrxframe %u fcserror %u "
957 "txframe %u wepundecryptable %u ",
958 adapter->logmsg.mcasttxframe,
959 adapter->logmsg.failed,
960 adapter->logmsg.retry,
961 adapter->logmsg.multiretry,
962 adapter->logmsg.framedup,
963 adapter->logmsg.rtssuccess,
964 adapter->logmsg.rtsfailure,
965 adapter->logmsg.ackfailure,
966 adapter->logmsg.rxfrag,
967 adapter->logmsg.mcastrxframe,
968 adapter->logmsg.fcserror,
969 adapter->logmsg.txframe,
970 adapter->logmsg.wepundecryptable);
971 wrq->u.data.length = strlen(buf) + 1;
972 if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
973 lbs_pr_debug(1, "Copy to user failed\n");
974 return -EFAULT;
975 }
976 }
977
978 return 0;
979}
980
981static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
982{
983 u8 buf[12];
984 u8 *option[] = { "active", "passive", "get", };
985 int i, max_options = (sizeof(option) / sizeof(option[0]));
986 int ret = 0;
987 wlan_adapter *adapter = priv->adapter;
988
989 if (priv->adapter->enable11d) {
990 lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
991 return -EFAULT;
992 }
993
994 memset(buf, 0, sizeof(buf));
995
996 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
997 wrq->u.data.length)))
998 return -EFAULT;
999
1000 lbs_pr_debug(1, "Scan type Option = %s\n", buf);
1001
1002 buf[sizeof(buf) - 1] = '\0';
1003
1004 for (i = 0; i < max_options; i++) {
1005 if (!strcmp(buf, option[i]))
1006 break;
1007 }
1008
1009 switch (i) {
1010 case 0:
1011 adapter->scantype = cmd_scan_type_active;
1012 break;
1013 case 1:
1014 adapter->scantype = cmd_scan_type_passive;
1015 break;
1016 case 2:
1017 wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
1018
1019 if (copy_to_user(wrq->u.data.pointer,
1020 option[adapter->scantype],
1021 wrq->u.data.length)) {
1022 lbs_pr_debug(1, "Copy to user failed\n");
1023 ret = -EFAULT;
1024 }
1025
1026 break;
1027 default:
1028 lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
1029 ret = -EINVAL;
1030 break;
1031 }
1032
1033 return ret;
1034}
1035
1036static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
1037{
1038 wlan_adapter *adapter = priv->adapter;
1039 u8 buf[12];
1040 u8 *option[] = { "bss", "ibss", "any", "get" };
1041 int i, max_options = (sizeof(option) / sizeof(option[0]));
1042 int ret = 0;
1043
1044 ENTER();
1045
1046 memset(buf, 0, sizeof(buf));
1047
1048 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
1049 wrq->u.data.length))) {
1050 lbs_pr_debug(1, "Copy from user failed\n");
1051 return -EFAULT;
1052 }
1053
1054 lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
1055
1056 buf[sizeof(buf) - 1] = '\0';
1057
1058 for (i = 0; i < max_options; i++) {
1059 if (!strcmp(buf, option[i]))
1060 break;
1061 }
1062
1063 switch (i) {
1064
1065 case 0:
1066 adapter->scanmode = cmd_bss_type_bss;
1067 break;
1068 case 1:
1069 adapter->scanmode = cmd_bss_type_ibss;
1070 break;
1071 case 2:
1072 adapter->scanmode = cmd_bss_type_any;
1073 break;
1074 case 3:
1075
1076 wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
1077
1078 lbs_pr_debug(1, "Get Scan mode Option = %s\n",
1079 option[adapter->scanmode - 1]);
1080
1081 lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
1082
1083 if (copy_to_user(wrq->u.data.pointer,
1084 option[adapter->scanmode - 1],
1085 wrq->u.data.length)) {
1086 lbs_pr_debug(1, "Copy to user failed\n");
1087 ret = -EFAULT;
1088 }
1089 lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
1090 (char *)wrq->u.data.pointer);
1091
1092 break;
1093
1094 default:
1095 lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
1096 ret = -EINVAL;
1097 break;
1098 }
1099
1100 LEAVE();
1101 return ret;
1102}
1103
1104/**
1105 * @brief Get/Set Adhoc G Rate
1106 *
1107 * @param priv A pointer to wlan_private structure
1108 * @param wrq A pointer to user data
1109 * @return 0--success, otherwise fail
1110 */
1111static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
1112{
1113 wlan_adapter *adapter = priv->adapter;
1114 int data, data1;
1115 int *val;
1116
1117 ENTER();
1118
1119 data1 = SUBCMD_DATA(wrq);
1120 switch (data1) {
1121 case 0:
1122 adapter->adhoc_grate_enabled = 0;
1123 break;
1124 case 1:
1125 adapter->adhoc_grate_enabled = 1;
1126 break;
1127 case 2:
1128 break;
1129 default:
1130 return -EINVAL;
1131 }
1132 data = adapter->adhoc_grate_enabled;
1133 val = (int *)wrq->u.name;
1134 *val = data;
1135 LEAVE();
1136 return 0;
1137}
1138
1139static inline int hex2int(char c)
1140{
1141 if (c >= '0' && c <= '9')
1142 return (c - '0');
1143 if (c >= 'a' && c <= 'f')
1144 return (c - 'a' + 10);
1145 if (c >= 'A' && c <= 'F')
1146 return (c - 'A' + 10);
1147 return -1;
1148}
1149
1150/* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx")
1151 into binary format (6 bytes).
1152
1153 This function expects that each byte is represented with 2 characters
1154 (e.g., 11:2:11:11:11:11 is invalid)
1155
1156 */
1157static char *eth_str2addr(char *ethstr, u8 * addr)
1158{
1159 int i, val, val2;
1160 char *pos = ethstr;
1161
1162 /* get rid of initial blanks */
1163 while (*pos == ' ' || *pos == '\t')
1164 ++pos;
1165
1166 for (i = 0; i < 6; i++) {
1167 val = hex2int(*pos++);
1168 if (val < 0)
1169 return NULL;
1170 val2 = hex2int(*pos++);
1171 if (val2 < 0)
1172 return NULL;
1173 addr[i] = (val * 16 + val2) & 0xff;
1174
1175 if (i < 5 && *pos++ != ':')
1176 return NULL;
1177 }
1178 return pos;
1179}
1180
1181/* this writes xx:xx:xx:xx:xx:xx into ethstr
1182 (ethstr must have space for 18 chars) */
1183static int eth_addr2str(u8 * addr, char *ethstr)
1184{
1185 int i;
1186 char *pos = ethstr;
1187
1188 for (i = 0; i < 6; i++) {
1189 sprintf(pos, "%02x", addr[i] & 0xff);
1190 pos += 2;
1191 if (i < 5)
1192 *pos++ = ':';
1193 }
1194 return 17;
1195}
1196
1197/**
1198 * @brief Add an entry to the BT table
1199 * @param priv A pointer to wlan_private structure
1200 * @param req A pointer to ifreq structure
1201 * @return 0 --success, otherwise fail
1202 */
1203static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
1204{
1205 struct iwreq *wrq = (struct iwreq *)req;
1206 char ethaddrs_str[18];
1207 char *pos;
1208 u8 ethaddr[ETH_ALEN];
1209
1210 ENTER();
1211 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1212 sizeof(ethaddrs_str)))
1213 return -EFAULT;
1214
1215 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1216 lbs_pr_info("BT_ADD: Invalid MAC address\n");
1217 return -EINVAL;
1218 }
1219
1220 lbs_pr_debug(1, "BT: adding %s\n", ethaddrs_str);
1221 LEAVE();
1222 return (libertas_prepare_and_send_command(priv, cmd_bt_access,
1223 cmd_act_bt_access_add,
1224 cmd_option_waitforrsp, 0, ethaddr));
1225}
1226
1227/**
1228 * @brief Delete an entry from the BT table
1229 * @param priv A pointer to wlan_private structure
1230 * @param req A pointer to ifreq structure
1231 * @return 0 --success, otherwise fail
1232 */
1233static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
1234{
1235 struct iwreq *wrq = (struct iwreq *)req;
1236 char ethaddrs_str[18];
1237 u8 ethaddr[ETH_ALEN];
1238 char *pos;
1239
1240 ENTER();
1241 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1242 sizeof(ethaddrs_str)))
1243 return -EFAULT;
1244
1245 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1246 lbs_pr_info("Invalid MAC address\n");
1247 return -EINVAL;
1248 }
1249
1250 lbs_pr_debug(1, "BT: deleting %s\n", ethaddrs_str);
1251
1252 return (libertas_prepare_and_send_command(priv,
1253 cmd_bt_access,
1254 cmd_act_bt_access_del,
1255 cmd_option_waitforrsp, 0, ethaddr));
1256 LEAVE();
1257 return 0;
1258}
1259
1260/**
1261 * @brief Reset all entries from the BT table
1262 * @param priv A pointer to wlan_private structure
1263 * @return 0 --success, otherwise fail
1264 */
1265static int wlan_bt_reset_ioctl(wlan_private * priv)
1266{
1267 ENTER();
1268
1269 lbs_pr_alert( "BT: resetting\n");
1270
1271 return (libertas_prepare_and_send_command(priv,
1272 cmd_bt_access,
1273 cmd_act_bt_access_reset,
1274 cmd_option_waitforrsp, 0, NULL));
1275
1276 LEAVE();
1277 return 0;
1278}
1279
1280/**
1281 * @brief List an entry from the BT table
1282 * @param priv A pointer to wlan_private structure
1283 * @param req A pointer to ifreq structure
1284 * @return 0 --success, otherwise fail
1285 */
1286static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
1287{
1288 int pos;
1289 char *addr1;
1290 struct iwreq *wrq = (struct iwreq *)req;
1291 /* used to pass id and store the bt entry returned by the FW */
1292 union {
1293 int id;
1294 char addr1addr2[2 * ETH_ALEN];
1295 } param;
1296 static char outstr[64];
1297 char *pbuf = outstr;
1298 int ret;
1299
1300 ENTER();
1301
1302 if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
1303 lbs_pr_debug(1, "Copy from user failed\n");
1304 return -1;
1305 }
1306 param.id = simple_strtoul(outstr, NULL, 10);
1307 pos = sprintf(pbuf, "%d: ", param.id);
1308 pbuf += pos;
1309
1310 ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
1311 cmd_act_bt_access_list,
1312 cmd_option_waitforrsp, 0,
1313 (char *)&param);
1314
1315 if (ret == 0) {
1316 addr1 = param.addr1addr2;
1317
1318 pos = sprintf(pbuf, "ignoring traffic from ");
1319 pbuf += pos;
1320 pos = eth_addr2str(addr1, pbuf);
1321 pbuf += pos;
1322 } else {
1323 sprintf(pbuf, "(null)");
1324 pbuf += pos;
1325 }
1326
1327 wrq->u.data.length = strlen(outstr);
1328 if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
1329 wrq->u.data.length)) {
1330 lbs_pr_debug(1, "BT_LIST: Copy to user failed!\n");
1331 return -EFAULT;
1332 }
1333
1334 LEAVE();
1335 return 0;
1336}
1337
1338/**
1339 * @brief Find the next parameter in an input string
1340 * @param ptr A pointer to the input parameter string
1341 * @return A pointer to the next parameter, or 0 if no parameters left.
1342 */
1343static char * next_param(char * ptr)
1344{
1345 if (!ptr) return NULL;
1346 while (*ptr == ' ' || *ptr == '\t') ++ptr;
1347 return (*ptr == '\0') ? NULL : ptr;
1348}
1349
1350/**
1351 * @brief Add an entry to the FWT table
1352 * @param priv A pointer to wlan_private structure
1353 * @param req A pointer to ifreq structure
1354 * @return 0 --success, otherwise fail
1355 */
1356static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
1357{
1358 struct iwreq *wrq = (struct iwreq *)req;
1359 char in_str[128];
1360 static struct cmd_ds_fwt_access fwt_access;
1361 char *ptr;
1362
1363 ENTER();
1364 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1365 return -EFAULT;
1366
1367 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1368 lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n");
1369 return -EINVAL;
1370 }
1371
1372 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1373 lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n");
1374 return -EINVAL;
1375 }
1376
1377 if ((ptr = next_param(ptr)))
1378 fwt_access.metric =
1379 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1380 else
1381 fwt_access.metric = FWT_DEFAULT_METRIC;
1382
1383 if ((ptr = next_param(ptr)))
1384 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1385 else
1386 fwt_access.dir = FWT_DEFAULT_DIR;
1387
1388 if ((ptr = next_param(ptr)))
1389 fwt_access.ssn =
1390 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1391 else
1392 fwt_access.ssn = FWT_DEFAULT_SSN;
1393
1394 if ((ptr = next_param(ptr)))
1395 fwt_access.dsn =
1396 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1397 else
1398 fwt_access.dsn = FWT_DEFAULT_DSN;
1399
1400 if ((ptr = next_param(ptr)))
1401 fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
1402 else
1403 fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT;
1404
1405 if ((ptr = next_param(ptr)))
1406 fwt_access.ttl = simple_strtoul(ptr, &ptr, 10);
1407 else
1408 fwt_access.ttl = FWT_DEFAULT_TTL;
1409
1410 if ((ptr = next_param(ptr)))
1411 fwt_access.expiration =
1412 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1413 else
1414 fwt_access.expiration = FWT_DEFAULT_EXPIRATION;
1415
1416 if ((ptr = next_param(ptr)))
1417 fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
1418 else
1419 fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE;
1420
1421 if ((ptr = next_param(ptr)))
1422 fwt_access.snr =
1423 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1424 else
1425 fwt_access.snr = FWT_DEFAULT_SNR;
1426
1427#ifdef DEBUG
1428 {
1429 char ethaddr1_str[18], ethaddr2_str[18];
1430 eth_addr2str(fwt_access.da, ethaddr1_str);
1431 eth_addr2str(fwt_access.ra, ethaddr2_str);
1432 lbs_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
1433 fwt_access.dir, ethaddr2_str);
1434 lbs_pr_debug(1, "FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
1435 fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
1436 fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
1437 fwt_access.sleepmode, fwt_access.snr);
1438 }
1439#endif
1440
1441 LEAVE();
1442 return (libertas_prepare_and_send_command(priv, cmd_fwt_access,
1443 cmd_act_fwt_access_add,
1444 cmd_option_waitforrsp, 0,
1445 (void *)&fwt_access));
1446}
1447
1448/**
1449 * @brief Delete an entry from the FWT table
1450 * @param priv A pointer to wlan_private structure
1451 * @param req A pointer to ifreq structure
1452 * @return 0 --success, otherwise fail
1453 */
1454static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
1455{
1456 struct iwreq *wrq = (struct iwreq *)req;
1457 char in_str[64];
1458 static struct cmd_ds_fwt_access fwt_access;
1459 char *ptr;
1460
1461 ENTER();
1462 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1463 return -EFAULT;
1464
1465 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1466 lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n");
1467 return -EINVAL;
1468 }
1469
1470 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1471 lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n");
1472 return -EINVAL;
1473 }
1474
1475 if ((ptr = next_param(ptr)))
1476 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1477 else
1478 fwt_access.dir = FWT_DEFAULT_DIR;
1479
1480#ifdef DEBUG
1481 {
1482 char ethaddr1_str[18], ethaddr2_str[18];
1483 lbs_pr_debug(1, "FWT_DEL: line is %s\n", in_str);
1484 eth_addr2str(fwt_access.da, ethaddr1_str);
1485 eth_addr2str(fwt_access.ra, ethaddr2_str);
1486 lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
1487 ethaddr2_str, fwt_access.dir);
1488 }
1489#endif
1490
1491 LEAVE();
1492 return (libertas_prepare_and_send_command(priv,
1493 cmd_fwt_access,
1494 cmd_act_fwt_access_del,
1495 cmd_option_waitforrsp, 0,
1496 (void *)&fwt_access));
1497}
1498
1499
1500/**
1501 * @brief Print route parameters
1502 * @param fwt_access struct cmd_ds_fwt_access with route info
1503 * @param buf destination buffer for route info
1504 */
1505static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
1506{
1507 buf += sprintf(buf, " ");
1508 buf += eth_addr2str(fwt_access.da, buf);
1509 buf += sprintf(buf, " ");
1510 buf += eth_addr2str(fwt_access.ra, buf);
1511 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
1512 buf += sprintf(buf, " %u", fwt_access.dir);
1513 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
1514 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
1515 buf += sprintf(buf, " %u", fwt_access.hopcount);
1516 buf += sprintf(buf, " %u", fwt_access.ttl);
1517 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
1518 buf += sprintf(buf, " %u", fwt_access.sleepmode);
1519 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.snr));
1520}
1521
1522/**
1523 * @brief Lookup an entry in the FWT table
1524 * @param priv A pointer to wlan_private structure
1525 * @param req A pointer to ifreq structure
1526 * @return 0 --success, otherwise fail
1527 */
1528static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
1529{
1530 struct iwreq *wrq = (struct iwreq *)req;
1531 char in_str[64];
1532 char *ptr;
1533 static struct cmd_ds_fwt_access fwt_access;
1534 static char out_str[128];
1535 int ret;
1536
1537 ENTER();
1538 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1539 return -EFAULT;
1540
1541 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1542 lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n");
1543 return -EINVAL;
1544 }
1545
1546#ifdef DEBUG
1547 {
1548 char ethaddr1_str[18];
1549 lbs_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str);
1550 eth_addr2str(fwt_access.da, ethaddr1_str);
1551 lbs_pr_debug(1, "FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
1552 }
1553#endif
1554
1555 ret = libertas_prepare_and_send_command(priv,
1556 cmd_fwt_access,
1557 cmd_act_fwt_access_lookup,
1558 cmd_option_waitforrsp, 0,
1559 (void *)&fwt_access);
1560
1561 if (ret == 0)
1562 print_route(fwt_access, out_str);
1563 else
1564 sprintf(out_str, "(null)");
1565
1566 wrq->u.data.length = strlen(out_str);
1567 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1568 wrq->u.data.length)) {
1569 lbs_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n");
1570 return -EFAULT;
1571 }
1572
1573 LEAVE();
1574 return 0;
1575}
1576
1577/**
1578 * @brief Reset all entries from the FWT table
1579 * @param priv A pointer to wlan_private structure
1580 * @return 0 --success, otherwise fail
1581 */
1582static int wlan_fwt_reset_ioctl(wlan_private * priv)
1583{
1584 lbs_pr_debug(1, "FWT: resetting\n");
1585
1586 return (libertas_prepare_and_send_command(priv,
1587 cmd_fwt_access,
1588 cmd_act_fwt_access_reset,
1589 cmd_option_waitforrsp, 0, NULL));
1590}
1591
1592/**
1593 * @brief List an entry from the FWT table
1594 * @param priv A pointer to wlan_private structure
1595 * @param req A pointer to ifreq structure
1596 * @return 0 --success, otherwise fail
1597 */
1598static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
1599{
1600 struct iwreq *wrq = (struct iwreq *)req;
1601 char in_str[8];
1602 static struct cmd_ds_fwt_access fwt_access;
1603 char *ptr = in_str;
1604 static char out_str[128];
1605 char *pbuf = out_str;
1606 int ret;
1607
1608 ENTER();
1609 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1610 return -EFAULT;
1611
1612 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1613
1614#ifdef DEBUG
1615 {
1616 lbs_pr_debug(1, "FWT_LIST: line is %s\n", in_str);
1617 lbs_pr_debug(1, "FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
1618 }
1619#endif
1620
1621 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1622 cmd_act_fwt_access_list,
1623 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1624
1625 if (ret == 0)
1626 print_route(fwt_access, pbuf);
1627 else
1628 pbuf += sprintf(pbuf, " (null)");
1629
1630 wrq->u.data.length = strlen(out_str);
1631 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1632 wrq->u.data.length)) {
1633 lbs_pr_debug(1, "FWT_LIST: Copy to user failed!\n");
1634 return -EFAULT;
1635 }
1636
1637 LEAVE();
1638 return 0;
1639}
1640
1641/**
1642 * @brief List an entry from the FRT table
1643 * @param priv A pointer to wlan_private structure
1644 * @param req A pointer to ifreq structure
1645 * @return 0 --success, otherwise fail
1646 */
1647static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
1648{
1649 struct iwreq *wrq = (struct iwreq *)req;
1650 char in_str[64];
1651 static struct cmd_ds_fwt_access fwt_access;
1652 char *ptr = in_str;
1653 static char out_str[128];
1654 char *pbuf = out_str;
1655 int ret;
1656
1657 ENTER();
1658 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1659 return -EFAULT;
1660
1661 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1662
1663#ifdef DEBUG
1664 {
1665 lbs_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str);
1666 lbs_pr_debug(1, "FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
1667 }
1668#endif
1669
1670 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1671 cmd_act_fwt_access_list_route,
1672 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1673
1674 if (ret == 0) {
1675 pbuf += sprintf(pbuf, " ");
1676 pbuf += eth_addr2str(fwt_access.da, pbuf);
1677 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric));
1678 pbuf += sprintf(pbuf, " %u", fwt_access.dir);
1679 /* note that the firmware returns the nid in the id field */
1680 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id));
1681 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn));
1682 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn));
1683 pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount);
1684 pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl);
1685 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration));
1686 } else
1687 pbuf += sprintf(pbuf, " (null)");
1688
1689 wrq->u.data.length = strlen(out_str);
1690 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1691 wrq->u.data.length)) {
1692 lbs_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n");
1693 return -EFAULT;
1694 }
1695
1696 LEAVE();
1697 return 0;
1698}
1699
1700/**
1701 * @brief List an entry from the FNT table
1702 * @param priv A pointer to wlan_private structure
1703 * @param req A pointer to ifreq structure
1704 * @return 0 --success, otherwise fail
1705 */
1706static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
1707{
1708 struct iwreq *wrq = (struct iwreq *)req;
1709 char in_str[8];
1710 static struct cmd_ds_fwt_access fwt_access;
1711 char *ptr = in_str;
1712 static char out_str[128];
1713 char *pbuf = out_str;
1714 int ret;
1715
1716 ENTER();
1717 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1718 return -EFAULT;
1719
1720 memset(&fwt_access, 0, sizeof(fwt_access));
1721 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1722
1723#ifdef DEBUG
1724 {
1725 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str);
1726 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
1727 }
1728#endif
1729
1730 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1731 cmd_act_fwt_access_list_neighbor,
1732 cmd_option_waitforrsp, 0,
1733 (void *)&fwt_access);
1734
1735 if (ret == 0) {
1736 pbuf += sprintf(pbuf, " ra ");
1737 pbuf += eth_addr2str(fwt_access.ra, pbuf);
1738 pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode);
1739 pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr));
1740 pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references));
1741 } else
1742 pbuf += sprintf(pbuf, " (null)");
1743
1744 wrq->u.data.length = strlen(out_str);
1745 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1746 wrq->u.data.length)) {
1747 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n");
1748 return -EFAULT;
1749 }
1750
1751 LEAVE();
1752 return 0;
1753}
1754
1755/**
1756 * @brief Cleans up the route (FRT) and neighbor (FNT) tables
1757 * (Garbage Collection)
1758 * @param priv A pointer to wlan_private structure
1759 * @param req A pointer to ifreq structure
1760 * @return 0 --success, otherwise fail
1761 */
1762static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
1763{
1764 static struct cmd_ds_fwt_access fwt_access;
1765 int ret;
1766
1767 ENTER();
1768
1769 lbs_pr_debug(1, "FWT: cleaning up\n");
1770
1771 memset(&fwt_access, 0, sizeof(fwt_access));
1772
1773 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1774 cmd_act_fwt_access_cleanup,
1775 cmd_option_waitforrsp, 0,
1776 (void *)&fwt_access);
1777
1778 if (ret == 0)
1779 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1780 else
1781 return -EFAULT;
1782
1783 LEAVE();
1784 return 0;
1785}
1786
1787/**
1788 * @brief Gets firmware internal time (debug purposes)
1789 * @param priv A pointer to wlan_private structure
1790 * @param req A pointer to ifreq structure
1791 * @return 0 --success, otherwise fail
1792 */
1793static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
1794{
1795 static struct cmd_ds_fwt_access fwt_access;
1796 int ret;
1797
1798 ENTER();
1799
1800 lbs_pr_debug(1, "FWT: getting time\n");
1801
1802 memset(&fwt_access, 0, sizeof(fwt_access));
1803
1804 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1805 cmd_act_fwt_access_time,
1806 cmd_option_waitforrsp, 0,
1807 (void *)&fwt_access);
1808
1809 if (ret == 0)
1810 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1811 else
1812 return -EFAULT;
1813
1814 LEAVE();
1815 return 0;
1816}
1817
1818/**
1819 * @brief Gets mesh ttl from firmware
1820 * @param priv A pointer to wlan_private structure
1821 * @param req A pointer to ifreq structure
1822 * @return 0 --success, otherwise fail
1823 */
1824static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
1825{
1826 struct cmd_ds_mesh_access mesh_access;
1827 int ret;
1828
1829 ENTER();
1830
1831 memset(&mesh_access, 0, sizeof(mesh_access));
1832
1833 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1834 cmd_act_mesh_get_ttl,
1835 cmd_option_waitforrsp, 0,
1836 (void *)&mesh_access);
1837
1838 if (ret == 0) {
1839 req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
1840 }
1841 else
1842 return -EFAULT;
1843
1844 LEAVE();
1845 return 0;
1846}
1847
1848/**
1849 * @brief Gets mesh ttl from firmware
1850 * @param priv A pointer to wlan_private structure
1851 * @param ttl New ttl value
1852 * @return 0 --success, otherwise fail
1853 */
1854static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
1855{
1856 struct cmd_ds_mesh_access mesh_access;
1857 int ret;
1858
1859 ENTER();
1860
1861 if( (ttl > 0xff) || (ttl < 0) )
1862 return -EINVAL;
1863
1864 memset(&mesh_access, 0, sizeof(mesh_access));
1865 mesh_access.data[0] = ttl;
1866
1867 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1868 cmd_act_mesh_set_ttl,
1869 cmd_option_waitforrsp, 0,
1870 (void *)&mesh_access);
1871
1872 if (ret != 0)
1873 ret = -EFAULT;
1874
1875 LEAVE();
1876 return ret;
1877}
1878
1879/**
1880 * @brief ioctl function - entry point
1881 *
1882 * @param dev A pointer to net_device structure
1883 * @param req A pointer to ifreq structure
1884 * @param cmd command
1885 * @return 0--success, otherwise fail
1886 */
1887int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
1888{
1889 int subcmd = 0;
1890 int idata = 0;
1891 int *pdata;
1892 int ret = 0;
1893 wlan_private *priv = dev->priv;
1894 wlan_adapter *adapter = priv->adapter;
1895 struct iwreq *wrq = (struct iwreq *)req;
1896
1897 ENTER();
1898
1899 lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
1900 switch (cmd) {
1901 case WLANSCAN_TYPE:
1902 lbs_pr_debug(1, "Scan type Ioctl\n");
1903 ret = wlan_scan_type_ioctl(priv, wrq);
1904 break;
1905
1906 case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
1907 switch (wrq->u.data.flags) {
1908 case WLANDEAUTH:
1909 lbs_pr_debug(1, "Deauth\n");
1910 libertas_send_deauth(priv);
1911 break;
1912
1913 case WLANADHOCSTOP:
1914 lbs_pr_debug(1, "Adhoc stop\n");
1915 ret = libertas_do_adhocstop_ioctl(priv);
1916 break;
1917
1918 case WLANRADIOON:
1919 wlan_radio_ioctl(priv, 1);
1920 break;
1921
1922 case WLANRADIOOFF:
1923 wlan_radio_ioctl(priv, 0);
1924 break;
1925 case WLANWLANIDLEON:
1926 libertas_idle_on(priv);
1927 break;
1928 case WLANWLANIDLEOFF:
1929 libertas_idle_off(priv);
1930 break;
1931 case WLAN_SUBCMD_BT_RESET: /* bt_reset */
1932 wlan_bt_reset_ioctl(priv);
1933 break;
1934 case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */
1935 wlan_fwt_reset_ioctl(priv);
1936 break;
1937 } /* End of switch */
1938 break;
1939
1940 case WLANSETWPAIE:
1941 ret = wlan_setwpaie_ioctl(priv, req);
1942 break;
1943 case WLAN_SETINT_GETINT:
1944 /* The first 4 bytes of req->ifr_data is sub-ioctl number
1945 * after 4 bytes sits the payload.
1946 */
1947 subcmd = (int)req->ifr_data; //from iwpriv subcmd
1948 switch (subcmd) {
1949 case WLANNF:
1950 ret = wlan_get_nf(priv, wrq);
1951 break;
1952 case WLANRSSI:
1953 ret = wlan_get_rssi(priv, wrq);
1954 break;
1955 case WLANENABLE11D:
1956 ret = libertas_cmd_enable_11d(priv, wrq);
1957 break;
1958 case WLANADHOCGRATE:
1959 ret = wlan_do_set_grate_ioctl(priv, wrq);
1960 break;
1961 case WLAN_SUBCMD_SET_PRESCAN:
1962 ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
1963 break;
1964 }
1965 break;
1966
1967 case WLAN_SETONEINT_GETONEINT:
1968 switch (wrq->u.data.flags) {
1969 case WLAN_BEACON_INTERVAL:
1970 ret = wlan_beacon_interval(priv, wrq);
1971 break;
1972
1973 case WLAN_LISTENINTRVL:
1974 if (!wrq->u.data.length) {
1975 int data;
1976 lbs_pr_debug(1, "Get locallisteninterval value\n");
1977#define GET_ONE_INT 1
1978 data = adapter->locallisteninterval;
1979 if (copy_to_user(wrq->u.data.pointer,
1980 &data, sizeof(int))) {
1981 lbs_pr_debug(1, "Copy to user failed\n");
1982 return -EFAULT;
1983 }
1984
1985 wrq->u.data.length = GET_ONE_INT;
1986 } else {
1987 int data;
1988 if (copy_from_user
1989 (&data, wrq->u.data.pointer, sizeof(int))) {
1990 lbs_pr_debug(1, "Copy from user failed\n");
1991 return -EFAULT;
1992 }
1993
1994 lbs_pr_debug(1, "Set locallisteninterval = %d\n",
1995 data);
1996#define MAX_U16_VAL 65535
1997 if (data > MAX_U16_VAL) {
1998 lbs_pr_debug(1, "Exceeds U16 value\n");
1999 return -EINVAL;
2000 }
2001 adapter->locallisteninterval = data;
2002 }
2003 break;
2004 case WLAN_TXCONTROL:
2005 ret = wlan_txcontrol(priv, wrq); //adds for txcontrol ioctl
2006 break;
2007
2008 case WLAN_NULLPKTINTERVAL:
2009 ret = wlan_null_pkt_interval(priv, wrq);
2010 break;
2011
2012 default:
2013 ret = -EOPNOTSUPP;
2014 break;
2015 }
2016 break;
2017
2018 case WLAN_SETONEINT_GETNONE:
2019 /* The first 4 bytes of req->ifr_data is sub-ioctl number
2020 * after 4 bytes sits the payload.
2021 */
2022 subcmd = wrq->u.data.flags; //from wpa_supplicant subcmd
2023
2024 if (!subcmd)
2025 subcmd = (int)req->ifr_data; //from iwpriv subcmd
2026
2027 switch (subcmd) {
2028 case WLAN_SUBCMD_SETRXANTENNA: /* SETRXANTENNA */
2029 idata = SUBCMD_DATA(wrq);
2030 ret = setrxantenna(priv, idata);
2031 break;
2032 case WLAN_SUBCMD_SETTXANTENNA: /* SETTXANTENNA */
2033 idata = SUBCMD_DATA(wrq);
2034 ret = settxantenna(priv, idata);
2035 break;
2036 case WLAN_SET_ATIM_WINDOW:
2037 adapter->atimwindow = SUBCMD_DATA(wrq);
2038 adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
2039 break;
2040 case WLANSETBCNAVG:
2041 adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
2042 if (adapter->bcn_avg_factor == 0)
2043 adapter->bcn_avg_factor =
2044 DEFAULT_BCN_AVG_FACTOR;
2045 if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
2046 adapter->bcn_avg_factor =
2047 DEFAULT_BCN_AVG_FACTOR;
2048 break;
2049 case WLANSETDATAAVG:
2050 adapter->data_avg_factor = SUBCMD_DATA(wrq);
2051 if (adapter->data_avg_factor == 0)
2052 adapter->data_avg_factor =
2053 DEFAULT_DATA_AVG_FACTOR;
2054 if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
2055 adapter->data_avg_factor =
2056 DEFAULT_DATA_AVG_FACTOR;
2057 break;
2058 case WLANSETREGION:
2059 idata = SUBCMD_DATA(wrq);
2060 ret = wlan_set_region(priv, (u16) idata);
2061 break;
2062
2063 case WLAN_SET_LISTEN_INTERVAL:
2064 idata = SUBCMD_DATA(wrq);
2065 adapter->listeninterval = (u16) idata;
2066 break;
2067
2068 case WLAN_SET_MULTIPLE_DTIM:
2069 ret = wlan_set_multiple_dtim_ioctl(priv, req);
2070 break;
2071
2072 case WLANSETAUTHALG:
2073 ret = wlan_setauthalg_ioctl(priv, req);
2074 break;
2075
2076 case WLANSET8021XAUTHALG:
2077 ret = wlan_set8021xauthalg_ioctl(priv, req);
2078 break;
2079
2080 case WLANSETENCRYPTIONMODE:
2081 ret = wlan_setencryptionmode_ioctl(priv, req);
2082 break;
2083
2084 case WLAN_SET_LINKMODE:
2085 ret = wlan_set_linkmode_ioctl(priv, req);
2086 break;
2087
2088 case WLAN_SET_RADIOMODE:
2089 ret = wlan_set_radiomode_ioctl(priv, req);
2090 break;
2091
2092 case WLAN_SET_DEBUGMODE:
2093 ret = wlan_set_debugmode_ioctl(priv, req);
2094 break;
2095
2096 case WLAN_SUBCMD_MESH_SET_TTL:
2097 idata = SUBCMD_DATA(wrq);
2098 ret = wlan_mesh_set_ttl_ioctl(priv, idata);
2099 break;
2100
2101 default:
2102 ret = -EOPNOTSUPP;
2103 break;
2104 }
2105
2106 break;
2107
2108 case WLAN_SETNONE_GETTWELVE_CHAR: /* Get Antenna settings */
2109 /*
2110 * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
2111 * in flags of iwreq structure, otherwise it will be in
2112 * mode member of iwreq structure.
2113 */
2114 switch ((int)wrq->u.data.flags) {
2115 case WLAN_SUBCMD_GETRXANTENNA: /* Get Rx Antenna */
2116 ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
2117 break;
2118
2119 case WLAN_SUBCMD_GETTXANTENNA: /* Get Tx Antenna */
2120 ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
2121 break;
2122
2123 case WLAN_GET_TSF:
2124 ret = wlan_get_tsf_ioctl(priv, wrq);
2125 break;
2126 }
2127 break;
2128
2129 case WLAN_SET128CHAR_GET128CHAR:
2130 switch ((int)wrq->u.data.flags) {
2131
2132 case WLANSCAN_MODE:
2133 lbs_pr_debug(1, "Scan mode Ioctl\n");
2134 ret = wlan_scan_mode_ioctl(priv, wrq);
2135 break;
2136
2137 case WLAN_GET_ADHOC_STATUS:
2138 ret = wlan_get_adhoc_status_ioctl(priv, wrq);
2139 break;
2140 case WLAN_SUBCMD_BT_ADD:
2141 ret = wlan_bt_add_ioctl(priv, req);
2142 break;
2143 case WLAN_SUBCMD_BT_DEL:
2144 ret = wlan_bt_del_ioctl(priv, req);
2145 break;
2146 case WLAN_SUBCMD_BT_LIST:
2147 ret = wlan_bt_list_ioctl(priv, req);
2148 break;
2149 case WLAN_SUBCMD_FWT_ADD:
2150 ret = wlan_fwt_add_ioctl(priv, req);
2151 break;
2152 case WLAN_SUBCMD_FWT_DEL:
2153 ret = wlan_fwt_del_ioctl(priv, req);
2154 break;
2155 case WLAN_SUBCMD_FWT_LOOKUP:
2156 ret = wlan_fwt_lookup_ioctl(priv, req);
2157 break;
2158 case WLAN_SUBCMD_FWT_LIST_NEIGHBOR:
2159 ret = wlan_fwt_list_neighbor_ioctl(priv, req);
2160 break;
2161 case WLAN_SUBCMD_FWT_LIST:
2162 ret = wlan_fwt_list_ioctl(priv, req);
2163 break;
2164 case WLAN_SUBCMD_FWT_LIST_ROUTE:
2165 ret = wlan_fwt_list_route_ioctl(priv, req);
2166 break;
2167 }
2168 break;
2169
2170 case WLAN_SETNONE_GETONEINT:
2171 switch ((int)req->ifr_data) {
2172 case WLANGETBCNAVG:
2173 pdata = (int *)wrq->u.name;
2174 *pdata = (int)adapter->bcn_avg_factor;
2175 break;
2176
2177 case WLANGETREGION:
2178 pdata = (int *)wrq->u.name;
2179 *pdata = (int)adapter->regioncode;
2180 break;
2181
2182 case WLAN_GET_LISTEN_INTERVAL:
2183 pdata = (int *)wrq->u.name;
2184 *pdata = (int)adapter->listeninterval;
2185 break;
2186
2187 case WLAN_GET_LINKMODE:
2188 req->ifr_data = (char *)((u32) adapter->linkmode);
2189 break;
2190
2191 case WLAN_GET_RADIOMODE:
2192 req->ifr_data = (char *)((u32) adapter->radiomode);
2193 break;
2194
2195 case WLAN_GET_DEBUGMODE:
2196 req->ifr_data = (char *)((u32) adapter->debugmode);
2197 break;
2198
2199 case WLAN_GET_MULTIPLE_DTIM:
2200 pdata = (int *)wrq->u.name;
2201 *pdata = (int)adapter->multipledtim;
2202 break;
2203 case WLAN_GET_TX_RATE:
2204 ret = wlan_get_txrate_ioctl(priv, req);
2205 break;
2206 case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */
2207 ret = wlan_fwt_cleanup_ioctl(priv, req);
2208 break;
2209
2210 case WLAN_SUBCMD_FWT_TIME: /* fwt_time */
2211 ret = wlan_fwt_time_ioctl(priv, req);
2212 break;
2213
2214 case WLAN_SUBCMD_MESH_GET_TTL:
2215 ret = wlan_mesh_get_ttl_ioctl(priv, req);
2216 break;
2217
2218 default:
2219 ret = -EOPNOTSUPP;
2220
2221 }
2222
2223 break;
2224
2225 case WLANGETLOG:
2226 ret = wlan_do_getlog_ioctl(priv, wrq);
2227 break;
2228
2229 case WLAN_SET_GET_SIXTEEN_INT:
2230 switch ((int)wrq->u.data.flags) {
2231 case WLAN_TPCCFG:
2232 {
2233 int data[5];
2234 struct cmd_ds_802_11_tpc_cfg cfg;
2235 memset(&cfg, 0, sizeof(cfg));
2236 if ((wrq->u.data.length > 1)
2237 && (wrq->u.data.length != 5))
2238 return -1;
2239
2240 if (wrq->u.data.length == 0) {
2241 cfg.action =
2242 cpu_to_le16
2243 (cmd_act_get);
2244 } else {
2245 if (copy_from_user
2246 (data, wrq->u.data.pointer,
2247 sizeof(int) * 5)) {
2248 lbs_pr_debug(1,
2249 "Copy from user failed\n");
2250 return -EFAULT;
2251 }
2252
2253 cfg.action =
2254 cpu_to_le16
2255 (cmd_act_set);
2256 cfg.enable = data[0];
2257 cfg.usesnr = data[1];
2258 cfg.P0 = data[2];
2259 cfg.P1 = data[3];
2260 cfg.P2 = data[4];
2261 }
2262
2263 ret =
2264 libertas_prepare_and_send_command(priv,
2265 cmd_802_11_tpc_cfg,
2266 0,
2267 cmd_option_waitforrsp,
2268 0, (void *)&cfg);
2269
2270 data[0] = cfg.enable;
2271 data[1] = cfg.usesnr;
2272 data[2] = cfg.P0;
2273 data[3] = cfg.P1;
2274 data[4] = cfg.P2;
2275 if (copy_to_user
2276 (wrq->u.data.pointer, data,
2277 sizeof(int) * 5)) {
2278 lbs_pr_debug(1, "Copy to user failed\n");
2279 return -EFAULT;
2280 }
2281
2282 wrq->u.data.length = 5;
2283 }
2284 break;
2285
2286 case WLAN_POWERCFG:
2287 {
2288 int data[4];
2289 struct cmd_ds_802_11_pwr_cfg cfg;
2290 memset(&cfg, 0, sizeof(cfg));
2291 if ((wrq->u.data.length > 1)
2292 && (wrq->u.data.length != 4))
2293 return -1;
2294 if (wrq->u.data.length == 0) {
2295 cfg.action =
2296 cpu_to_le16
2297 (cmd_act_get);
2298 } else {
2299 if (copy_from_user
2300 (data, wrq->u.data.pointer,
2301 sizeof(int) * 4)) {
2302 lbs_pr_debug(1,
2303 "Copy from user failed\n");
2304 return -EFAULT;
2305 }
2306
2307 cfg.action =
2308 cpu_to_le16
2309 (cmd_act_set);
2310 cfg.enable = data[0];
2311 cfg.PA_P0 = data[1];
2312 cfg.PA_P1 = data[2];
2313 cfg.PA_P2 = data[3];
2314 }
2315 ret =
2316 libertas_prepare_and_send_command(priv,
2317 cmd_802_11_pwr_cfg,
2318 0,
2319 cmd_option_waitforrsp,
2320 0, (void *)&cfg);
2321 data[0] = cfg.enable;
2322 data[1] = cfg.PA_P0;
2323 data[2] = cfg.PA_P1;
2324 data[3] = cfg.PA_P2;
2325 if (copy_to_user
2326 (wrq->u.data.pointer, data,
2327 sizeof(int) * 4)) {
2328 lbs_pr_debug(1, "Copy to user failed\n");
2329 return -EFAULT;
2330 }
2331
2332 wrq->u.data.length = 4;
2333 }
2334 break;
2335 case WLAN_AUTO_FREQ_SET:
2336 {
2337 int data[3];
2338 struct cmd_ds_802_11_afc afc;
2339 memset(&afc, 0, sizeof(afc));
2340 if (wrq->u.data.length != 3)
2341 return -1;
2342 if (copy_from_user
2343 (data, wrq->u.data.pointer,
2344 sizeof(int) * 3)) {
2345 lbs_pr_debug(1, "Copy from user failed\n");
2346 return -EFAULT;
2347 }
2348 afc.afc_auto = data[0];
2349
2350 if (afc.afc_auto != 0) {
2351 afc.threshold = data[1];
2352 afc.period = data[2];
2353 } else {
2354 afc.timing_offset = data[1];
2355 afc.carrier_offset = data[2];
2356 }
2357 ret =
2358 libertas_prepare_and_send_command(priv,
2359 cmd_802_11_set_afc,
2360 0,
2361 cmd_option_waitforrsp,
2362 0, (void *)&afc);
2363 }
2364 break;
2365 case WLAN_AUTO_FREQ_GET:
2366 {
2367 int data[3];
2368 struct cmd_ds_802_11_afc afc;
2369 memset(&afc, 0, sizeof(afc));
2370 ret =
2371 libertas_prepare_and_send_command(priv,
2372 cmd_802_11_get_afc,
2373 0,
2374 cmd_option_waitforrsp,
2375 0, (void *)&afc);
2376 data[0] = afc.afc_auto;
2377 data[1] = afc.timing_offset;
2378 data[2] = afc.carrier_offset;
2379 if (copy_to_user
2380 (wrq->u.data.pointer, data,
2381 sizeof(int) * 3)) {
2382 lbs_pr_debug(1, "Copy to user failed\n");
2383 return -EFAULT;
2384 }
2385
2386 wrq->u.data.length = 3;
2387 }
2388 break;
2389 case WLAN_SCANPROBES:
2390 {
2391 int data;
2392 if (wrq->u.data.length > 0) {
2393 if (copy_from_user
2394 (&data, wrq->u.data.pointer,
2395 sizeof(int))) {
2396 lbs_pr_debug(1,
2397 "Copy from user failed\n");
2398 return -EFAULT;
2399 }
2400
2401 adapter->scanprobes = data;
2402 } else {
2403 data = adapter->scanprobes;
2404 if (copy_to_user
2405 (wrq->u.data.pointer, &data,
2406 sizeof(int))) {
2407 lbs_pr_debug(1,
2408 "Copy to user failed\n");
2409 return -EFAULT;
2410 }
2411 }
2412 wrq->u.data.length = 1;
2413 }
2414 break;
2415 case WLAN_LED_GPIO_CTRL:
2416 {
2417 int i;
2418 int data[16];
2419
2420 struct cmd_ds_802_11_led_ctrl ctrl;
2421 struct mrvlietypes_ledgpio *gpio =
2422 (struct mrvlietypes_ledgpio *) ctrl.data;
2423
2424 memset(&ctrl, 0, sizeof(ctrl));
2425 if (wrq->u.data.length > MAX_LEDS * 2)
2426 return -ENOTSUPP;
2427 if ((wrq->u.data.length % 2) != 0)
2428 return -ENOTSUPP;
2429 if (wrq->u.data.length == 0) {
2430 ctrl.action =
2431 cpu_to_le16
2432 (cmd_act_get);
2433 } else {
2434 if (copy_from_user
2435 (data, wrq->u.data.pointer,
2436 sizeof(int) *
2437 wrq->u.data.length)) {
2438 lbs_pr_debug(1,
2439 "Copy from user failed\n");
2440 return -EFAULT;
2441 }
2442
2443 ctrl.action =
2444 cpu_to_le16
2445 (cmd_act_set);
2446 ctrl.numled = cpu_to_le16(0);
2447 gpio->header.type =
2448 cpu_to_le16(TLV_TYPE_LED_GPIO);
2449 gpio->header.len = wrq->u.data.length;
2450 for (i = 0; i < wrq->u.data.length;
2451 i += 2) {
2452 gpio->ledpin[i / 2].led =
2453 data[i];
2454 gpio->ledpin[i / 2].pin =
2455 data[i + 1];
2456 }
2457 }
2458 ret =
2459 libertas_prepare_and_send_command(priv,
2460 cmd_802_11_led_gpio_ctrl,
2461 0,
2462 cmd_option_waitforrsp,
2463 0, (void *)&ctrl);
2464 for (i = 0; i < gpio->header.len; i += 2) {
2465 data[i] = gpio->ledpin[i / 2].led;
2466 data[i + 1] = gpio->ledpin[i / 2].pin;
2467 }
2468 if (copy_to_user(wrq->u.data.pointer, data,
2469 sizeof(int) *
2470 gpio->header.len)) {
2471 lbs_pr_debug(1, "Copy to user failed\n");
2472 return -EFAULT;
2473 }
2474
2475 wrq->u.data.length = gpio->header.len;
2476 }
2477 break;
2478 case WLAN_ADAPT_RATESET:
2479 ret = wlan_adapt_rateset(priv, wrq);
2480 break;
2481 case WLAN_INACTIVITY_TIMEOUT:
2482 ret = wlan_inactivity_timeout(priv, wrq);
2483 break;
2484 case WLANSNR:
2485 ret = wlan_get_snr(priv, wrq);
2486 break;
2487 case WLAN_GET_RXINFO:
2488 ret = wlan_get_rxinfo(priv, wrq);
2489 }
2490 break;
2491
2492 default:
2493 ret = -EINVAL;
2494 break;
2495 }
2496 LEAVE();
2497 return ret;
2498}
2499
2500
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
new file mode 100644
index 000000000000..11682cbe752b
--- /dev/null
+++ b/drivers/net/wireless/libertas/join.c
@@ -0,0 +1,1055 @@
1/**
2 * Functions implementing wlan infrastructure and adhoc join routines,
3 * IOCTL handlers as well as command preperation and response routines
4 * for sending adhoc start, adhoc join, and association commands
5 * to the firmware.
6 */
7#include <linux/netdevice.h>
8#include <linux/if_arp.h>
9#include <linux/wireless.h>
10
11#include <net/iw_handler.h>
12
13#include "host.h"
14#include "decl.h"
15#include "join.h"
16#include "dev.h"
17
18/**
19 * @brief This function finds out the common rates between rate1 and rate2.
20 *
21 * It will fill common rates in rate1 as output if found.
22 *
23 * NOTE: Setting the MSB of the basic rates need to be taken
24 * care, either before or after calling this function
25 *
26 * @param adapter A pointer to wlan_adapter structure
27 * @param rate1 the buffer which keeps input and output
28 * @param rate1_size the size of rate1 buffer
29 * @param rate2 the buffer which keeps rate2
30 * @param rate2_size the size of rate2 buffer.
31 *
32 * @return 0 or -1
33 */
34static int get_common_rates(wlan_adapter * adapter, u8 * rate1,
35 int rate1_size, u8 * rate2, int rate2_size)
36{
37 u8 *ptr = rate1;
38 int ret = 0;
39 u8 tmp[30];
40 int i;
41
42 memset(&tmp, 0, sizeof(tmp));
43 memcpy(&tmp, rate1, min_t(size_t, rate1_size, sizeof(tmp)));
44 memset(rate1, 0, rate1_size);
45
46 /* Mask the top bit of the original values */
47 for (i = 0; tmp[i] && i < sizeof(tmp); i++)
48 tmp[i] &= 0x7F;
49
50 for (i = 0; rate2[i] && i < rate2_size; i++) {
51 /* Check for Card Rate in tmp, excluding the top bit */
52 if (strchr(tmp, rate2[i] & 0x7F)) {
53 /* values match, so copy the Card Rate to rate1 */
54 *rate1++ = rate2[i];
55 }
56 }
57
58 lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp));
59 lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size);
60 lbs_dbg_hex("Common rates:", ptr, rate1_size);
61 lbs_pr_debug(1, "Tx datarate is set to 0x%X\n", adapter->datarate);
62
63 if (!adapter->is_datarate_auto) {
64 while (*ptr) {
65 if ((*ptr & 0x7f) == adapter->datarate) {
66 ret = 0;
67 goto done;
68 }
69 ptr++;
70 }
71 lbs_pr_alert( "Previously set fixed data rate %#x isn't "
72 "compatible with the network.\n", adapter->datarate);
73
74 ret = -1;
75 goto done;
76 }
77
78 ret = 0;
79done:
80 return ret;
81}
82
83int libertas_send_deauth(wlan_private * priv)
84{
85 wlan_adapter *adapter = priv->adapter;
86 int ret = 0;
87
88 if (adapter->inframode == wlan802_11infrastructure &&
89 adapter->connect_status == libertas_connected)
90 ret = libertas_send_deauthentication(priv);
91 else
92 ret = -ENOTSUPP;
93
94 return ret;
95}
96
97int libertas_do_adhocstop_ioctl(wlan_private * priv)
98{
99 wlan_adapter *adapter = priv->adapter;
100 int ret = 0;
101
102 if (adapter->inframode == wlan802_11ibss &&
103 adapter->connect_status == libertas_connected)
104 ret = libertas_stop_adhoc_network(priv);
105 else
106 ret = -ENOTSUPP;
107
108 return ret;
109}
110
111/**
112 * @brief Associate to a specific BSS discovered in a scan
113 *
114 * @param priv A pointer to wlan_private structure
115 * @param pbssdesc Pointer to the BSS descriptor to associate with.
116 *
117 * @return 0-success, otherwise fail
118 */
119int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
120{
121 wlan_adapter *adapter = priv->adapter;
122 int ret;
123
124 ENTER();
125
126 ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate,
127 0, cmd_option_waitforrsp,
128 0, pbssdesc->macaddress);
129
130 if (ret) {
131 LEAVE();
132 return ret;
133 }
134
135 /* set preamble to firmware */
136 if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble)
137 adapter->preamble = cmd_type_short_preamble;
138 else
139 adapter->preamble = cmd_type_long_preamble;
140
141 libertas_set_radio_control(priv);
142
143 ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate,
144 0, cmd_option_waitforrsp, 0, pbssdesc);
145
146 LEAVE();
147 return ret;
148}
149
150/**
151 * @brief Start an Adhoc Network
152 *
153 * @param priv A pointer to wlan_private structure
154 * @param adhocssid The ssid of the Adhoc Network
155 * @return 0--success, -1--fail
156 */
157int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid)
158{
159 wlan_adapter *adapter = priv->adapter;
160 int ret = 0;
161
162 adapter->adhoccreate = 1;
163
164 if (!adapter->capinfo.shortpreamble) {
165 lbs_pr_debug(1, "AdhocStart: Long preamble\n");
166 adapter->preamble = cmd_type_long_preamble;
167 } else {
168 lbs_pr_debug(1, "AdhocStart: Short preamble\n");
169 adapter->preamble = cmd_type_short_preamble;
170 }
171
172 libertas_set_radio_control(priv);
173
174 lbs_pr_debug(1, "Adhoc channel = %d\n", adapter->adhocchannel);
175 lbs_pr_debug(1, "curbssparams.channel = %d\n",
176 adapter->curbssparams.channel);
177 lbs_pr_debug(1, "curbssparams.band = %d\n", adapter->curbssparams.band);
178
179 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start,
180 0, cmd_option_waitforrsp, 0, adhocssid);
181
182 return ret;
183}
184
185/**
186 * @brief Join an adhoc network found in a previous scan
187 *
188 * @param priv A pointer to wlan_private structure
189 * @param pbssdesc Pointer to a BSS descriptor found in a previous scan
190 * to attempt to join
191 *
192 * @return 0--success, -1--fail
193 */
194int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc)
195{
196 wlan_adapter *adapter = priv->adapter;
197 int ret = 0;
198
199 lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid =%s\n",
200 adapter->curbssparams.ssid.ssid);
201 lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid_len =%u\n",
202 adapter->curbssparams.ssid.ssidlength);
203 lbs_pr_debug(1, "libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid);
204 lbs_pr_debug(1, "libertas_join_adhoc_network: ssid len =%u\n",
205 pbssdesc->ssid.ssidlength);
206
207 /* check if the requested SSID is already joined */
208 if (adapter->curbssparams.ssid.ssidlength
209 && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
210 && (adapter->curbssparams.bssdescriptor.inframode ==
211 wlan802_11ibss)) {
212
213 lbs_pr_debug(1,
214 "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
215 "not attempting to re-join");
216
217 return -1;
218 }
219
220 /*Use shortpreamble only when both creator and card supports
221 short preamble */
222 if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
223 lbs_pr_debug(1, "AdhocJoin: Long preamble\n");
224 adapter->preamble = cmd_type_long_preamble;
225 } else {
226 lbs_pr_debug(1, "AdhocJoin: Short preamble\n");
227 adapter->preamble = cmd_type_short_preamble;
228 }
229
230 libertas_set_radio_control(priv);
231
232 lbs_pr_debug(1, "curbssparams.channel = %d\n",
233 adapter->curbssparams.channel);
234 lbs_pr_debug(1, "curbssparams.band = %c\n", adapter->curbssparams.band);
235
236 adapter->adhoccreate = 0;
237
238 ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join,
239 0, cmd_option_waitforrsp,
240 OID_802_11_SSID, pbssdesc);
241
242 return ret;
243}
244
245int libertas_stop_adhoc_network(wlan_private * priv)
246{
247 return libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_stop,
248 0, cmd_option_waitforrsp, 0, NULL);
249}
250
251/**
252 * @brief Send Deauthentication Request
253 *
254 * @param priv A pointer to wlan_private structure
255 * @return 0--success, -1--fail
256 */
257int libertas_send_deauthentication(wlan_private * priv)
258{
259 return libertas_prepare_and_send_command(priv, cmd_802_11_deauthenticate,
260 0, cmd_option_waitforrsp, 0, NULL);
261}
262
263/**
264 * @brief Set Idle Off
265 *
266 * @param priv A pointer to wlan_private structure
267 * @return 0 --success, otherwise fail
268 */
269int libertas_idle_off(wlan_private * priv)
270{
271 wlan_adapter *adapter = priv->adapter;
272 int ret = 0;
273 const u8 zeromac[] = { 0, 0, 0, 0, 0, 0 };
274 int i;
275
276 ENTER();
277
278 if (adapter->connect_status == libertas_disconnected) {
279 if (adapter->inframode == wlan802_11infrastructure) {
280 if (memcmp(adapter->previousbssid, zeromac,
281 sizeof(zeromac)) != 0) {
282
283 lbs_pr_debug(1, "Previous SSID = %s\n",
284 adapter->previousssid.ssid);
285 lbs_pr_debug(1, "Previous BSSID = "
286 "%02x:%02x:%02x:%02x:%02x:%02x:\n",
287 adapter->previousbssid[0],
288 adapter->previousbssid[1],
289 adapter->previousbssid[2],
290 adapter->previousbssid[3],
291 adapter->previousbssid[4],
292 adapter->previousbssid[5]);
293
294 i = libertas_find_SSID_in_list(adapter,
295 &adapter->previousssid,
296 adapter->previousbssid,
297 adapter->inframode);
298
299 if (i < 0) {
300 libertas_send_specific_BSSID_scan(priv,
301 adapter->
302 previousbssid,
303 1);
304 i = libertas_find_SSID_in_list(adapter,
305 &adapter->
306 previousssid,
307 adapter->
308 previousbssid,
309 adapter->
310 inframode);
311 }
312
313 if (i < 0) {
314 /* If the BSSID could not be found, try just the SSID */
315 i = libertas_find_SSID_in_list(adapter,
316 &adapter->
317 previousssid, NULL,
318 adapter->
319 inframode);
320 }
321
322 if (i < 0) {
323 libertas_send_specific_SSID_scan(priv,
324 &adapter->
325 previousssid,
326 1);
327 i = libertas_find_SSID_in_list(adapter,
328 &adapter->
329 previousssid, NULL,
330 adapter->
331 inframode);
332 }
333
334 if (i >= 0) {
335 ret =
336 wlan_associate(priv,
337 &adapter->
338 scantable[i]);
339 }
340 }
341 } else if (adapter->inframode == wlan802_11ibss) {
342 ret = libertas_prepare_and_send_command(priv,
343 cmd_802_11_ad_hoc_start,
344 0,
345 cmd_option_waitforrsp,
346 0, &adapter->previousssid);
347 }
348 }
349 /* else it is connected */
350
351 lbs_pr_debug(1, "\nwlanidle is off");
352 LEAVE();
353 return ret;
354}
355
356/**
357 * @brief Set Idle On
358 *
359 * @param priv A pointer to wlan_private structure
360 * @return 0 --success, otherwise fail
361 */
362int libertas_idle_on(wlan_private * priv)
363{
364 wlan_adapter *adapter = priv->adapter;
365 int ret = 0;
366
367 if (adapter->connect_status == libertas_connected) {
368 if (adapter->inframode == wlan802_11infrastructure) {
369 lbs_pr_debug(1, "Previous SSID = %s\n",
370 adapter->previousssid.ssid);
371 memmove(&adapter->previousssid,
372 &adapter->curbssparams.ssid,
373 sizeof(struct WLAN_802_11_SSID));
374 libertas_send_deauth(priv);
375
376 } else if (adapter->inframode == wlan802_11ibss) {
377 ret = libertas_stop_adhoc_network(priv);
378 }
379
380 }
381
382 lbs_pr_debug(1, "\nwlanidle is on");
383
384 return ret;
385}
386
387/**
388 * @brief This function prepares command of authenticate.
389 *
390 * @param priv A pointer to wlan_private structure
391 * @param cmd A pointer to cmd_ds_command structure
392 * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
393 *
394 * @return 0 or -1
395 */
396int libertas_cmd_80211_authenticate(wlan_private * priv,
397 struct cmd_ds_command *cmd,
398 void *pdata_buf)
399{
400 wlan_adapter *adapter = priv->adapter;
401 struct cmd_ds_802_11_authenticate *pauthenticate =
402 &cmd->params.auth;
403 u8 *bssid = pdata_buf;
404
405 cmd->command = cpu_to_le16(cmd_802_11_authenticate);
406 cmd->size =
407 cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
408 + S_DS_GEN);
409
410 pauthenticate->authtype = adapter->secinfo.authmode;
411 memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
412
413 lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
414 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
415
416 return 0;
417}
418
419int libertas_cmd_80211_deauthenticate(wlan_private * priv,
420 struct cmd_ds_command *cmd)
421{
422 wlan_adapter *adapter = priv->adapter;
423 struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
424
425 ENTER();
426
427 cmd->command = cpu_to_le16(cmd_802_11_deauthenticate);
428 cmd->size =
429 cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
430 S_DS_GEN);
431
432 /* set AP MAC address */
433 memmove(dauth->macaddr, adapter->curbssparams.bssid,
434 ETH_ALEN);
435
436 /* Reason code 3 = Station is leaving */
437#define REASON_CODE_STA_LEAVING 3
438 dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING);
439
440 LEAVE();
441 return 0;
442}
443
444int libertas_cmd_80211_associate(wlan_private * priv,
445 struct cmd_ds_command *cmd, void *pdata_buf)
446{
447 wlan_adapter *adapter = priv->adapter;
448 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
449 int ret = 0;
450 struct bss_descriptor *pbssdesc;
451 u8 *card_rates;
452 u8 *pos;
453 int card_rates_size;
454 u16 tmpcap;
455 struct mrvlietypes_ssidparamset *ssid;
456 struct mrvlietypes_phyparamset *phy;
457 struct mrvlietypes_ssparamset *ss;
458 struct mrvlietypes_ratesparamset *rates;
459 struct mrvlietypes_rsnparamset *rsn;
460
461 ENTER();
462
463 pbssdesc = pdata_buf;
464 pos = (u8 *) passo;
465
466 if (!adapter) {
467 ret = -1;
468 goto done;
469 }
470
471 cmd->command = cpu_to_le16(cmd_802_11_associate);
472
473 /* Save so we know which BSS Desc to use in the response handler */
474 adapter->pattemptedbssdesc = pbssdesc;
475
476 memcpy(passo->peerstaaddr,
477 pbssdesc->macaddress, sizeof(passo->peerstaaddr));
478 pos += sizeof(passo->peerstaaddr);
479
480 /* set the listen interval */
481 passo->listeninterval = adapter->listeninterval;
482
483 pos += sizeof(passo->capinfo);
484 pos += sizeof(passo->listeninterval);
485 pos += sizeof(passo->bcnperiod);
486 pos += sizeof(passo->dtimperiod);
487
488 ssid = (struct mrvlietypes_ssidparamset *) pos;
489 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
490 ssid->header.len = pbssdesc->ssid.ssidlength;
491 memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len);
492 pos += sizeof(ssid->header) + ssid->header.len;
493 ssid->header.len = cpu_to_le16(ssid->header.len);
494
495 phy = (struct mrvlietypes_phyparamset *) pos;
496 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
497 phy->header.len = sizeof(phy->fh_ds.dsparamset);
498 memcpy(&phy->fh_ds.dsparamset,
499 &pbssdesc->phyparamset.dsparamset.currentchan,
500 sizeof(phy->fh_ds.dsparamset));
501 pos += sizeof(phy->header) + phy->header.len;
502 phy->header.len = cpu_to_le16(phy->header.len);
503
504 ss = (struct mrvlietypes_ssparamset *) pos;
505 ss->header.type = cpu_to_le16(TLV_TYPE_CF);
506 ss->header.len = sizeof(ss->cf_ibss.cfparamset);
507 pos += sizeof(ss->header) + ss->header.len;
508 ss->header.len = cpu_to_le16(ss->header.len);
509
510 rates = (struct mrvlietypes_ratesparamset *) pos;
511 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
512
513 memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES);
514
515 card_rates = libertas_supported_rates;
516 card_rates_size = sizeof(libertas_supported_rates);
517
518 if (get_common_rates(adapter, rates->rates, WLAN_SUPPORTED_RATES,
519 card_rates, card_rates_size)) {
520 ret = -1;
521 goto done;
522 }
523
524 rates->header.len = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
525 adapter->curbssparams.numofrates = rates->header.len;
526
527 pos += sizeof(rates->header) + rates->header.len;
528 rates->header.len = cpu_to_le16(rates->header.len);
529
530 if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
531 rsn = (struct mrvlietypes_rsnparamset *) pos;
532 rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */
533 rsn->header.type = cpu_to_le16(rsn->header.type);
534 rsn->header.len = (u16) adapter->wpa_ie[1];
535 memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len);
536 lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn,
537 sizeof(rsn->header) + rsn->header.len);
538 pos += sizeof(rsn->header) + rsn->header.len;
539 rsn->header.len = cpu_to_le16(rsn->header.len);
540 }
541
542 /* update curbssparams */
543 adapter->curbssparams.channel =
544 (pbssdesc->phyparamset.dsparamset.currentchan);
545
546 /* Copy the infra. association rates into Current BSS state structure */
547 memcpy(&adapter->curbssparams.datarates, &rates->rates,
548 min_t(size_t, sizeof(adapter->curbssparams.datarates), rates->header.len));
549
550 lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
551
552 /* set IBSS field */
553 if (pbssdesc->inframode == wlan802_11infrastructure) {
554#define CAPINFO_ESS_MODE 1
555 passo->capinfo.ess = CAPINFO_ESS_MODE;
556 }
557
558 if (libertas_parse_dnld_countryinfo_11d(priv)) {
559 ret = -1;
560 goto done;
561 }
562
563 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
564
565 /* set the capability info at last */
566 memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo));
567 tmpcap &= CAPINFO_MASK;
568 lbs_pr_debug(1, "ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
569 tmpcap, CAPINFO_MASK);
570 tmpcap = cpu_to_le16(tmpcap);
571 memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo));
572
573 done:
574 LEAVE();
575 return ret;
576}
577
578int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
579 struct cmd_ds_command *cmd, void *pssid)
580{
581 wlan_adapter *adapter = priv->adapter;
582 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
583 int ret = 0;
584 int cmdappendsize = 0;
585 int i;
586 u16 tmpcap;
587 struct bss_descriptor *pbssdesc;
588 struct WLAN_802_11_SSID *ssid = pssid;
589
590 ENTER();
591
592 if (!adapter) {
593 ret = -1;
594 goto done;
595 }
596
597 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start);
598
599 pbssdesc = &adapter->curbssparams.bssdescriptor;
600 adapter->pattemptedbssdesc = pbssdesc;
601
602 /*
603 * Fill in the parameters for 2 data structures:
604 * 1. cmd_ds_802_11_ad_hoc_start command
605 * 2. adapter->scantable[i]
606 *
607 * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
608 * probe delay, and cap info.
609 *
610 * Firmware will fill up beacon period, DTIM, Basic rates
611 * and operational rates.
612 */
613
614 memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE);
615
616 memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength);
617
618 lbs_pr_debug(1, "ADHOC_S_CMD: SSID = %s\n", adhs->SSID);
619
620 memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE);
621 memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength);
622
623 pbssdesc->ssid.ssidlength = ssid->ssidlength;
624
625 /* set the BSS type */
626 adhs->bsstype = cmd_bss_type_ibss;
627 pbssdesc->inframode = wlan802_11ibss;
628 adhs->beaconperiod = adapter->beaconperiod;
629
630 /* set Physical param set */
631#define DS_PARA_IE_ID 3
632#define DS_PARA_IE_LEN 1
633
634 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
635 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
636
637 WARN_ON(!adapter->adhocchannel);
638
639 lbs_pr_debug(1, "ADHOC_S_CMD: Creating ADHOC on channel %d\n",
640 adapter->adhocchannel);
641
642 adapter->curbssparams.channel = adapter->adhocchannel;
643
644 pbssdesc->channel = adapter->adhocchannel;
645 adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel;
646
647 memcpy(&pbssdesc->phyparamset,
648 &adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
649
650 /* set IBSS param set */
651#define IBSS_PARA_IE_ID 6
652#define IBSS_PARA_IE_LEN 2
653
654 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
655 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
656 adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow;
657 memcpy(&pbssdesc->ssparamset,
658 &adhs->ssparamset, sizeof(union IEEEtypes_ssparamset));
659
660 /* set capability info */
661 adhs->cap.ess = 0;
662 adhs->cap.ibss = 1;
663 pbssdesc->cap.ibss = 1;
664
665 /* probedelay */
666 adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
667
668 /* set up privacy in adapter->scantable[i] */
669 if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
670
671#define AD_HOC_CAP_PRIVACY_ON 1
672 lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus set, privacy to WEP\n");
673 pbssdesc->privacy = wlan802_11privfilter8021xWEP;
674 adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
675 } else {
676 lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus NOT set, Setting "
677 "privacy to ACCEPT ALL\n");
678 pbssdesc->privacy = wlan802_11privfilteracceptall;
679 }
680
681 memset(adhs->datarate, 0, sizeof(adhs->datarate));
682
683 if (adapter->adhoc_grate_enabled) {
684 memcpy(adhs->datarate, libertas_adhoc_rates_g,
685 min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_g)));
686 } else {
687 memcpy(adhs->datarate, libertas_adhoc_rates_b,
688 min(sizeof(adhs->datarate), sizeof(libertas_adhoc_rates_b)));
689 }
690
691 /* Find the last non zero */
692 for (i = 0; i < sizeof(adhs->datarate) && adhs->datarate[i]; i++) ;
693
694 adapter->curbssparams.numofrates = i;
695
696 /* Copy the ad-hoc creating rates into Current BSS state structure */
697 memcpy(&adapter->curbssparams.datarates,
698 &adhs->datarate, adapter->curbssparams.numofrates);
699
700 lbs_pr_debug(1, "ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
701 adhs->datarate[0], adhs->datarate[1],
702 adhs->datarate[2], adhs->datarate[3]);
703
704 lbs_pr_debug(1, "ADHOC_S_CMD: AD HOC Start command is ready\n");
705
706 if (libertas_create_dnld_countryinfo_11d(priv)) {
707 lbs_pr_debug(1, "ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
708 ret = -1;
709 goto done;
710 }
711
712 cmd->size =
713 cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start)
714 + S_DS_GEN + cmdappendsize);
715
716 memcpy(&tmpcap, &adhs->cap, sizeof(u16));
717 tmpcap = cpu_to_le16(tmpcap);
718 memcpy(&adhs->cap, &tmpcap, sizeof(u16));
719
720 ret = 0;
721done:
722 LEAVE();
723 return ret;
724}
725
726int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
727 struct cmd_ds_command *cmd)
728{
729 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_stop);
730 cmd->size = cpu_to_le16(S_DS_GEN);
731
732 return 0;
733}
734
735int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
736 struct cmd_ds_command *cmd, void *pdata_buf)
737{
738 wlan_adapter *adapter = priv->adapter;
739 struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj;
740 struct bss_descriptor *pbssdesc = pdata_buf;
741 int cmdappendsize = 0;
742 int ret = 0;
743 u8 *card_rates;
744 int card_rates_size;
745 u16 tmpcap;
746 int i;
747
748 ENTER();
749
750 adapter->pattemptedbssdesc = pbssdesc;
751
752 cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join);
753
754 padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss;
755
756 padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod;
757
758 memcpy(&padhocjoin->bssdescriptor.BSSID,
759 &pbssdesc->macaddress, ETH_ALEN);
760
761 memcpy(&padhocjoin->bssdescriptor.SSID,
762 &pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength);
763
764 memcpy(&padhocjoin->bssdescriptor.phyparamset,
765 &pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset));
766
767 memcpy(&padhocjoin->bssdescriptor.ssparamset,
768 &pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset));
769
770 memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo));
771 tmpcap &= CAPINFO_MASK;
772
773 lbs_pr_debug(1, "ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
774 tmpcap, CAPINFO_MASK);
775 memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap,
776 sizeof(struct ieeetypes_capinfo));
777
778 /* information on BSSID descriptor passed to FW */
779 lbs_pr_debug(1,
780 "ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n",
781 padhocjoin->bssdescriptor.BSSID[0],
782 padhocjoin->bssdescriptor.BSSID[1],
783 padhocjoin->bssdescriptor.BSSID[2],
784 padhocjoin->bssdescriptor.BSSID[3],
785 padhocjoin->bssdescriptor.BSSID[4],
786 padhocjoin->bssdescriptor.BSSID[5],
787 padhocjoin->bssdescriptor.SSID);
788
789 lbs_pr_debug(1, "ADHOC_J_CMD: Data Rate = %x\n",
790 (u32) padhocjoin->bssdescriptor.datarates);
791
792 /* failtimeout */
793 padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
794
795 /* probedelay */
796 padhocjoin->probedelay =
797 cpu_to_le16(cmd_scan_probe_delay_time);
798
799 /* Copy Data rates from the rates recorded in scan response */
800 memset(padhocjoin->bssdescriptor.datarates, 0,
801 sizeof(padhocjoin->bssdescriptor.datarates));
802 memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates,
803 min(sizeof(padhocjoin->bssdescriptor.datarates),
804 sizeof(pbssdesc->datarates)));
805
806 card_rates = libertas_supported_rates;
807 card_rates_size = sizeof(libertas_supported_rates);
808
809 adapter->curbssparams.channel = pbssdesc->channel;
810
811 if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates,
812 sizeof(padhocjoin->bssdescriptor.datarates),
813 card_rates, card_rates_size)) {
814 lbs_pr_debug(1, "ADHOC_J_CMD: get_common_rates returns error.\n");
815 ret = -1;
816 goto done;
817 }
818
819 /* Find the last non zero */
820 for (i = 0; i < sizeof(padhocjoin->bssdescriptor.datarates)
821 && padhocjoin->bssdescriptor.datarates[i]; i++) ;
822
823 adapter->curbssparams.numofrates = i;
824
825 /*
826 * Copy the adhoc joining rates to Current BSS State structure
827 */
828 memcpy(adapter->curbssparams.datarates,
829 padhocjoin->bssdescriptor.datarates,
830 adapter->curbssparams.numofrates);
831
832 padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
833 cpu_to_le16(pbssdesc->atimwindow);
834
835 if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
836 padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
837 }
838
839 if (adapter->psmode == wlan802_11powermodemax_psp) {
840 /* wake up first */
841 enum WLAN_802_11_POWER_MODE Localpsmode;
842
843 Localpsmode = wlan802_11powermodecam;
844 ret = libertas_prepare_and_send_command(priv,
845 cmd_802_11_ps_mode,
846 cmd_act_set,
847 0, 0, &Localpsmode);
848
849 if (ret) {
850 ret = -1;
851 goto done;
852 }
853 }
854
855 if (libertas_parse_dnld_countryinfo_11d(priv)) {
856 ret = -1;
857 goto done;
858 }
859
860 cmd->size =
861 cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join)
862 + S_DS_GEN + cmdappendsize);
863
864 memcpy(&tmpcap, &padhocjoin->bssdescriptor.cap,
865 sizeof(struct ieeetypes_capinfo));
866 tmpcap = cpu_to_le16(tmpcap);
867
868 memcpy(&padhocjoin->bssdescriptor.cap,
869 &tmpcap, sizeof(struct ieeetypes_capinfo));
870
871 done:
872 LEAVE();
873 return ret;
874}
875
876int libertas_ret_80211_associate(wlan_private * priv,
877 struct cmd_ds_command *resp)
878{
879 wlan_adapter *adapter = priv->adapter;
880 int ret = 0;
881 union iwreq_data wrqu;
882 struct ieeetypes_assocrsp *passocrsp;
883 struct bss_descriptor *pbssdesc;
884
885 ENTER();
886
887 passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
888
889 if (passocrsp->statuscode) {
890
891 libertas_mac_event_disconnected(priv);
892
893 lbs_pr_debug(1,
894 "ASSOC_RESP: Association failed, status code = %d\n",
895 passocrsp->statuscode);
896
897 ret = -1;
898 goto done;
899 }
900
901 lbs_dbg_hex("ASSOC_RESP:", (void *)&resp->params,
902 le16_to_cpu(resp->size) - S_DS_GEN);
903
904 /* Send a Media Connected event, according to the Spec */
905 adapter->connect_status = libertas_connected;
906
907 /* Set the attempted BSSID Index to current */
908 pbssdesc = adapter->pattemptedbssdesc;
909
910 lbs_pr_debug(1, "ASSOC_RESP: %s\n", pbssdesc->ssid.ssid);
911
912 /* Set the new SSID to current SSID */
913 memcpy(&adapter->curbssparams.ssid,
914 &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
915
916 /* Set the new BSSID (AP's MAC address) to current BSSID */
917 memcpy(adapter->curbssparams.bssid,
918 pbssdesc->macaddress, ETH_ALEN);
919
920 /* Make a copy of current BSSID descriptor */
921 memcpy(&adapter->curbssparams.bssdescriptor,
922 pbssdesc, sizeof(struct bss_descriptor));
923
924 lbs_pr_debug(1, "ASSOC_RESP: currentpacketfilter is %x\n",
925 adapter->currentpacketfilter);
926
927 adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
928 adapter->NF[TYPE_RXPD][TYPE_AVG] = 0;
929
930 memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
931 memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
932 adapter->nextSNRNF = 0;
933 adapter->numSNRNF = 0;
934
935 netif_carrier_on(priv->wlan_dev.netdev);
936 netif_wake_queue(priv->wlan_dev.netdev);
937
938 lbs_pr_debug(1, "ASSOC_RESP: Associated \n");
939
940 memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
941 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
942 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
943
944 done:
945 LEAVE();
946 return ret;
947}
948
949int libertas_ret_80211_disassociate(wlan_private * priv,
950 struct cmd_ds_command *resp)
951{
952 ENTER();
953
954 libertas_mac_event_disconnected(priv);
955
956 LEAVE();
957 return 0;
958}
959
960int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
961 struct cmd_ds_command *resp)
962{
963 wlan_adapter *adapter = priv->adapter;
964 int ret = 0;
965 u16 command = le16_to_cpu(resp->command);
966 u16 result = le16_to_cpu(resp->result);
967 struct cmd_ds_802_11_ad_hoc_result *padhocresult;
968 union iwreq_data wrqu;
969 struct bss_descriptor *pbssdesc;
970
971 ENTER();
972
973 padhocresult = &resp->params.result;
974
975 lbs_pr_debug(1, "ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size));
976 lbs_pr_debug(1, "ADHOC_S_RESP: command = %x\n", command);
977 lbs_pr_debug(1, "ADHOC_S_RESP: result = %x\n", result);
978
979 pbssdesc = adapter->pattemptedbssdesc;
980
981 /*
982 * Join result code 0 --> SUCCESS
983 */
984 if (result) {
985 lbs_pr_debug(1, "ADHOC_RESP failed\n");
986 if (adapter->connect_status == libertas_connected) {
987 libertas_mac_event_disconnected(priv);
988 }
989
990 memset(&adapter->curbssparams.bssdescriptor,
991 0x00, sizeof(adapter->curbssparams.bssdescriptor));
992
993 LEAVE();
994 return -1;
995 }
996
997 /*
998 * Now the join cmd should be successful
999 * If BSSID has changed use SSID to compare instead of BSSID
1000 */
1001 lbs_pr_debug(1, "ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid);
1002
1003 /* Send a Media Connected event, according to the Spec */
1004 adapter->connect_status = libertas_connected;
1005
1006 if (command == cmd_ret_802_11_ad_hoc_start) {
1007 /* Update the created network descriptor with the new BSSID */
1008 memcpy(pbssdesc->macaddress,
1009 padhocresult->BSSID, ETH_ALEN);
1010 } else {
1011
1012 /* Make a copy of current BSSID descriptor, only needed for join since
1013 * the current descriptor is already being used for adhoc start
1014 */
1015 memmove(&adapter->curbssparams.bssdescriptor,
1016 pbssdesc, sizeof(struct bss_descriptor));
1017 }
1018
1019 /* Set the BSSID from the joined/started descriptor */
1020 memcpy(&adapter->curbssparams.bssid,
1021 pbssdesc->macaddress, ETH_ALEN);
1022
1023 /* Set the new SSID to current SSID */
1024 memcpy(&adapter->curbssparams.ssid,
1025 &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
1026
1027 netif_carrier_on(priv->wlan_dev.netdev);
1028 netif_wake_queue(priv->wlan_dev.netdev);
1029
1030 memset(&wrqu, 0, sizeof(wrqu));
1031 memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
1032 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1033 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
1034
1035 lbs_pr_debug(1, "ADHOC_RESP: - Joined/Started Ad Hoc\n");
1036 lbs_pr_debug(1, "ADHOC_RESP: channel = %d\n", adapter->adhocchannel);
1037 lbs_pr_debug(1, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
1038 padhocresult->BSSID[0], padhocresult->BSSID[1],
1039 padhocresult->BSSID[2], padhocresult->BSSID[3],
1040 padhocresult->BSSID[4], padhocresult->BSSID[5]);
1041
1042 LEAVE();
1043 return ret;
1044}
1045
1046int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
1047 struct cmd_ds_command *resp)
1048{
1049 ENTER();
1050
1051 libertas_mac_event_disconnected(priv);
1052
1053 LEAVE();
1054 return 0;
1055}
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
new file mode 100644
index 000000000000..8efa2455af9a
--- /dev/null
+++ b/drivers/net/wireless/libertas/join.h
@@ -0,0 +1,64 @@
1/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
2/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
3
4/**
5 * Interface for the wlan infrastructure and adhoc join routines
6 *
7 * Driver interface functions and type declarations for the join module
8 * implemented in wlan_join.c. Process all start/join requests for
9 * both adhoc and infrastructure networks
10 */
11#ifndef _WLAN_JOIN_H
12#define _WLAN_JOIN_H
13
14#include "defs.h"
15
16struct cmd_ds_command;
17extern int libertas_cmd_80211_authenticate(wlan_private * priv,
18 struct cmd_ds_command *cmd,
19 void *pdata_buf);
20extern int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
21 struct cmd_ds_command *cmd,
22 void *pdata_buf);
23extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
24 struct cmd_ds_command *cmd);
25extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
26 struct cmd_ds_command *cmd,
27 void *pssid);
28extern int libertas_cmd_80211_deauthenticate(wlan_private * priv,
29 struct cmd_ds_command *cmd);
30extern int libertas_cmd_80211_associate(wlan_private * priv,
31 struct cmd_ds_command *cmd,
32 void *pdata_buf);
33
34extern int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
35 struct cmd_ds_command *resp);
36extern int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
37 struct cmd_ds_command *resp);
38extern int libertas_ret_80211_disassociate(wlan_private * priv,
39 struct cmd_ds_command *resp);
40extern int libertas_ret_80211_associate(wlan_private * priv,
41 struct cmd_ds_command *resp);
42
43extern int libertas_idle_on(wlan_private * priv);
44extern int libertas_idle_off(wlan_private * priv);
45
46extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
47extern int libertas_reassociation_thread(void *data);
48
49struct WLAN_802_11_SSID;
50struct bss_descriptor;
51
52extern int libertas_start_adhoc_network(wlan_private * priv,
53 struct WLAN_802_11_SSID *adhocssid);
54extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc);
55extern int libertas_stop_adhoc_network(wlan_private * priv);
56
57extern int libertas_send_deauthentication(wlan_private * priv);
58extern int libertas_send_deauth(wlan_private * priv);
59
60extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
61
62int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc);
63
64#endif
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
new file mode 100644
index 000000000000..dcbf102a057e
--- /dev/null
+++ b/drivers/net/wireless/libertas/main.c
@@ -0,0 +1,1258 @@
1/**
2 * This file contains the major functions in WLAN
3 * driver. It includes init, exit, open, close and main
4 * thread etc..
5 */
6
7#include <linux/delay.h>
8#include <linux/freezer.h>
9#include <linux/etherdevice.h>
10#include <linux/netdevice.h>
11#include <linux/if_arp.h>
12
13#include <net/iw_handler.h>
14
15#include "host.h"
16#include "sbi.h"
17#include "decl.h"
18#include "dev.h"
19#include "fw.h"
20#include "wext.h"
21#include "debugfs.h"
22#include "assoc.h"
23
24#ifdef ENABLE_PM
25static struct pm_dev *wlan_pm_dev = NULL;
26#endif
27
28#define WLAN_TX_PWR_DEFAULT 20 /*100mW */
29#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */
30#define WLAN_TX_PWR_JP_DEFAULT 16 /*50mW */
31#define WLAN_TX_PWR_FR_DEFAULT 20 /*100mW */
32#define WLAN_TX_PWR_EMEA_DEFAULT 20 /*100mW */
33
34/* Format { channel, frequency (MHz), maxtxpower } */
35/* band: 'B/G', region: USA FCC/Canada IC */
36static struct chan_freq_power channel_freq_power_US_BG[] = {
37 {1, 2412, WLAN_TX_PWR_US_DEFAULT},
38 {2, 2417, WLAN_TX_PWR_US_DEFAULT},
39 {3, 2422, WLAN_TX_PWR_US_DEFAULT},
40 {4, 2427, WLAN_TX_PWR_US_DEFAULT},
41 {5, 2432, WLAN_TX_PWR_US_DEFAULT},
42 {6, 2437, WLAN_TX_PWR_US_DEFAULT},
43 {7, 2442, WLAN_TX_PWR_US_DEFAULT},
44 {8, 2447, WLAN_TX_PWR_US_DEFAULT},
45 {9, 2452, WLAN_TX_PWR_US_DEFAULT},
46 {10, 2457, WLAN_TX_PWR_US_DEFAULT},
47 {11, 2462, WLAN_TX_PWR_US_DEFAULT}
48};
49
50/* band: 'B/G', region: Europe ETSI */
51static struct chan_freq_power channel_freq_power_EU_BG[] = {
52 {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
53 {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
54 {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
55 {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
56 {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
57 {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
58 {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
59 {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
60 {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
61 {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
62 {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
63 {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
64 {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
65};
66
67/* band: 'B/G', region: Spain */
68static struct chan_freq_power channel_freq_power_SPN_BG[] = {
69 {10, 2457, WLAN_TX_PWR_DEFAULT},
70 {11, 2462, WLAN_TX_PWR_DEFAULT}
71};
72
73/* band: 'B/G', region: France */
74static struct chan_freq_power channel_freq_power_FR_BG[] = {
75 {10, 2457, WLAN_TX_PWR_FR_DEFAULT},
76 {11, 2462, WLAN_TX_PWR_FR_DEFAULT},
77 {12, 2467, WLAN_TX_PWR_FR_DEFAULT},
78 {13, 2472, WLAN_TX_PWR_FR_DEFAULT}
79};
80
81/* band: 'B/G', region: Japan */
82static struct chan_freq_power channel_freq_power_JPN_BG[] = {
83 {1, 2412, WLAN_TX_PWR_JP_DEFAULT},
84 {2, 2417, WLAN_TX_PWR_JP_DEFAULT},
85 {3, 2422, WLAN_TX_PWR_JP_DEFAULT},
86 {4, 2427, WLAN_TX_PWR_JP_DEFAULT},
87 {5, 2432, WLAN_TX_PWR_JP_DEFAULT},
88 {6, 2437, WLAN_TX_PWR_JP_DEFAULT},
89 {7, 2442, WLAN_TX_PWR_JP_DEFAULT},
90 {8, 2447, WLAN_TX_PWR_JP_DEFAULT},
91 {9, 2452, WLAN_TX_PWR_JP_DEFAULT},
92 {10, 2457, WLAN_TX_PWR_JP_DEFAULT},
93 {11, 2462, WLAN_TX_PWR_JP_DEFAULT},
94 {12, 2467, WLAN_TX_PWR_JP_DEFAULT},
95 {13, 2472, WLAN_TX_PWR_JP_DEFAULT},
96 {14, 2484, WLAN_TX_PWR_JP_DEFAULT}
97};
98
99/**
100 * the structure for channel, frequency and power
101 */
102struct region_cfp_table {
103 u8 region;
104 struct chan_freq_power *cfp_BG;
105 int cfp_no_BG;
106};
107
108/**
109 * the structure for the mapping between region and CFP
110 */
111static struct region_cfp_table region_cfp_table[] = {
112 {0x10, /*US FCC */
113 channel_freq_power_US_BG,
114 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
115 }
116 ,
117 {0x20, /*CANADA IC */
118 channel_freq_power_US_BG,
119 sizeof(channel_freq_power_US_BG) / sizeof(struct chan_freq_power),
120 }
121 ,
122 {0x30, /*EU*/ channel_freq_power_EU_BG,
123 sizeof(channel_freq_power_EU_BG) / sizeof(struct chan_freq_power),
124 }
125 ,
126 {0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
127 sizeof(channel_freq_power_SPN_BG) / sizeof(struct chan_freq_power),
128 }
129 ,
130 {0x32, /*FRANCE*/ channel_freq_power_FR_BG,
131 sizeof(channel_freq_power_FR_BG) / sizeof(struct chan_freq_power),
132 }
133 ,
134 {0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
135 sizeof(channel_freq_power_JPN_BG) / sizeof(struct chan_freq_power),
136 }
137 ,
138/*Add new region here */
139};
140
141/**
142 * the rates supported by the card
143 */
144u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
145 { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
146 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
147};
148
149/**
150 * the rates supported
151 */
152u8 libertas_supported_rates[G_SUPPORTED_RATES] =
153 { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
1540 };
155
156/**
157 * the rates supported for ad-hoc G mode
158 */
159u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] =
160 { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
1610 };
162
163/**
164 * the rates supported for ad-hoc B mode
165 */
166u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 };
167
168/**
169 * the global variable of a pointer to wlan_private
170 * structure variable
171 */
172static wlan_private *wlanpriv = NULL;
173
174#define MAX_DEVS 5
175static struct net_device *libertas_devs[MAX_DEVS];
176static int libertas_found = 0;
177
178/**
179 * the table to keep region code
180 */
181u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
182 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
183
184static u8 *default_fw_name = "usb8388.bin";
185
186/**
187 * Attributes exported through sysfs
188 */
189
190/**
191 * @brief Get function for sysfs attribute libertas_mpp
192 */
193static ssize_t libertas_mpp_get(struct device * dev,
194 struct device_attribute *attr, char * buf) {
195 struct cmd_ds_mesh_access mesh_access;
196
197 memset(&mesh_access, 0, sizeof(mesh_access));
198 libertas_prepare_and_send_command(to_net_dev(dev)->priv,
199 cmd_mesh_access,
200 cmd_act_mesh_get_mpp,
201 cmd_option_waitforrsp, 0, (void *)&mesh_access);
202
203 return snprintf(buf, 3, "%d\n", mesh_access.data[0]);
204}
205
206/**
207 * @brief Set function for sysfs attribute libertas_mpp
208 */
209static ssize_t libertas_mpp_set(struct device * dev,
210 struct device_attribute *attr, const char * buf, size_t count) {
211 struct cmd_ds_mesh_access mesh_access;
212
213
214 memset(&mesh_access, 0, sizeof(mesh_access));
215 sscanf(buf, "%d", &(mesh_access.data[0]));
216 libertas_prepare_and_send_command((to_net_dev(dev))->priv,
217 cmd_mesh_access,
218 cmd_act_mesh_set_mpp,
219 cmd_option_waitforrsp, 0, (void *)&mesh_access);
220 return strlen(buf);
221}
222
223/**
224 * libertas_mpp attribute to be exported per mshX interface
225 * through sysfs (/sys/class/net/mshX/libertas-mpp)
226 */
227static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get,
228 libertas_mpp_set );
229
230/**
231 * @brief Check if the device can be open and wait if necessary.
232 *
233 * @param dev A pointer to net_device structure
234 * @return 0
235 *
236 * For USB adapter, on some systems the device open handler will be
237 * called before FW ready. Use the following flag check and wait
238 * function to work around the issue.
239 *
240 */
241static int pre_open_check(struct net_device *dev) {
242 wlan_private *priv = (wlan_private *) dev->priv;
243 wlan_adapter *adapter = priv->adapter;
244 int i = 0;
245
246 while (!adapter->fw_ready && i < 20) {
247 i++;
248 msleep_interruptible(100);
249 }
250 if (!adapter->fw_ready) {
251 lbs_pr_info("FW not ready, pre_open_check() return failure\n");
252 LEAVE();
253 return -1;
254 }
255
256 return 0;
257}
258
259/**
260 * @brief This function opens the device
261 *
262 * @param dev A pointer to net_device structure
263 * @return 0
264 */
265static int wlan_dev_open(struct net_device *dev)
266{
267 wlan_private *priv = (wlan_private *) dev->priv;
268 wlan_adapter *adapter = priv->adapter;
269
270 ENTER();
271
272
273 priv->open = 1;
274
275 if (adapter->connect_status == libertas_connected) {
276 netif_carrier_on(priv->wlan_dev.netdev);
277 } else
278 netif_carrier_off(priv->wlan_dev.netdev);
279
280 LEAVE();
281 return 0;
282}
283/**
284 * @brief This function opens the mshX interface
285 *
286 * @param dev A pointer to net_device structure
287 * @return 0
288 */
289static int mesh_open(struct net_device *dev)
290{
291 wlan_private *priv = (wlan_private *) dev->priv ;
292
293 if(pre_open_check(dev) == -1)
294 return -1;
295 priv->mesh_open = 1 ;
296 netif_start_queue(priv->mesh_dev);
297 if (priv->infra_open == 0)
298 return wlan_dev_open(priv->wlan_dev.netdev) ;
299 return 0;
300}
301
302/**
303 * @brief This function opens the ethX interface
304 *
305 * @param dev A pointer to net_device structure
306 * @return 0
307 */
308static int wlan_open(struct net_device *dev)
309{
310 wlan_private *priv = (wlan_private *) dev->priv ;
311
312 if(pre_open_check(dev) == -1)
313 return -1;
314 priv->infra_open = 1 ;
315 netif_wake_queue(priv->wlan_dev.netdev);
316 if (priv->open == 0)
317 return wlan_dev_open(priv->wlan_dev.netdev) ;
318 return 0;
319}
320
321static int wlan_dev_close(struct net_device *dev)
322{
323 wlan_private *priv = dev->priv;
324
325 ENTER();
326
327 netif_carrier_off(priv->wlan_dev.netdev);
328 priv->open = 0;
329
330 LEAVE();
331 return 0;
332}
333
334/**
335 * @brief This function closes the mshX interface
336 *
337 * @param dev A pointer to net_device structure
338 * @return 0
339 */
340static int mesh_close(struct net_device *dev)
341{
342 wlan_private *priv = (wlan_private *) (dev->priv);
343
344 priv->mesh_open = 0;
345 netif_stop_queue(priv->mesh_dev);
346 if (priv->infra_open == 0)
347 return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
348 else
349 return 0;
350}
351
352/**
353 * @brief This function closes the ethX interface
354 *
355 * @param dev A pointer to net_device structure
356 * @return 0
357 */
358static int wlan_close(struct net_device *dev) {
359 wlan_private *priv = (wlan_private *) dev->priv;
360
361 netif_stop_queue(priv->wlan_dev.netdev);
362 priv->infra_open = 0;
363 if (priv->mesh_open == 0)
364 return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
365 else
366 return 0;
367}
368
369
370#ifdef ENABLE_PM
371
372/**
373 * @brief This function is a callback function. it is called by
374 * kernel to enter or exit power saving mode.
375 *
376 * @param pmdev A pointer to pm_dev
377 * @param pmreq pm_request_t
378 * @param pmdata A pointer to pmdata
379 * @return 0 or -1
380 */
381static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq,
382 void *pmdata)
383{
384 wlan_private *priv = wlanpriv;
385 wlan_adapter *adapter = priv->adapter;
386 struct net_device *dev = priv->wlan_dev.netdev;
387
388 lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq);
389
390 switch (pmreq) {
391 case PM_SUSPEND:
392 lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");
393
394 /* in associated mode */
395 if (adapter->connect_status == libertas_connected) {
396 if ((adapter->psstate != PS_STATE_SLEEP)
397 ) {
398 lbs_pr_debug(1,
399 "wlan_pm_callback: can't enter sleep mode\n");
400 return -1;
401 } else {
402
403 /*
404 * Detach the network interface
405 * if the network is running
406 */
407 if (netif_running(dev)) {
408 netif_device_detach(dev);
409 lbs_pr_debug(1,
410 "netif_device_detach().\n");
411 }
412 libertas_sbi_suspend(priv);
413 }
414 break;
415 }
416
417 /* in non associated mode */
418
419 /*
420 * Detach the network interface
421 * if the network is running
422 */
423 if (netif_running(dev))
424 netif_device_detach(dev);
425
426 /*
427 * Storing and restoring of the regs be taken care
428 * at the driver rest will be done at wlan driver
429 * this makes driver independent of the card
430 */
431
432 libertas_sbi_suspend(priv);
433
434 break;
435
436 case PM_RESUME:
437 /* in associated mode */
438 if (adapter->connect_status == libertas_connected) {
439 {
440 /*
441 * Bring the inteface up first
442 * This case should not happen still ...
443 */
444 libertas_sbi_resume(priv);
445
446 /*
447 * Attach the network interface
448 * if the network is running
449 */
450 if (netif_running(dev)) {
451 netif_device_attach(dev);
452 lbs_pr_debug(1,
453 "after netif_device_attach().\n");
454 }
455 lbs_pr_debug(1,
456 "After netif attach, in associated mode.\n");
457 }
458 break;
459 }
460
461 /* in non associated mode */
462
463 /*
464 * Bring the inteface up first
465 * This case should not happen still ...
466 */
467
468 libertas_sbi_resume(priv);
469
470 if (netif_running(dev))
471 netif_device_attach(dev);
472
473 lbs_pr_debug(1, "after netif attach, in NON associated mode.\n");
474 break;
475 }
476
477 return 0;
478}
479#endif /* ENABLE_PM */
480
481static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
482{
483 int ret = 0;
484 wlan_private *priv = dev->priv;
485
486 ENTER();
487
488 if (priv->wlan_dev.dnld_sent || priv->adapter->TxLockFlag) {
489 priv->stats.tx_dropped++;
490 goto done;
491 }
492
493 netif_stop_queue(priv->wlan_dev.netdev);
494
495 if (libertas_process_tx(priv, skb) == 0)
496 dev->trans_start = jiffies;
497done:
498 LEAVE();
499 return ret;
500}
501
502/**
503 * @brief Mark mesh packets and handover them to wlan_hard_start_xmit
504 *
505 */
506static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
507{
508 wlan_private *priv = dev->priv;
509 ENTER();
510 SET_MESH_FRAME(skb);
511 LEAVE();
512
513 return wlan_hard_start_xmit(skb, priv->wlan_dev.netdev);
514}
515
516/**
517 * @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
518 *
519 */
520static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) {
521 ENTER();
522 UNSET_MESH_FRAME(skb);
523 LEAVE();
524 return wlan_hard_start_xmit(skb, dev);
525}
526
527static void wlan_tx_timeout(struct net_device *dev)
528{
529 wlan_private *priv = (wlan_private *) dev->priv;
530
531 ENTER();
532
533 lbs_pr_err("tx watch dog timeout!\n");
534
535 priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
536 dev->trans_start = jiffies;
537
538 if (priv->adapter->currenttxskb) {
539 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
540 /* If we are here, we have not received feedback from
541 the previous packet. Assume TX_FAIL and move on. */
542 priv->adapter->eventcause = 0x01000000;
543 libertas_send_tx_feedback(priv);
544 } else
545 wake_up_interruptible(&priv->mainthread.waitq);
546 } else if (priv->adapter->connect_status == libertas_connected)
547 netif_wake_queue(priv->wlan_dev.netdev);
548
549 LEAVE();
550}
551
552/**
553 * @brief This function returns the network statistics
554 *
555 * @param dev A pointer to wlan_private structure
556 * @return A pointer to net_device_stats structure
557 */
558static struct net_device_stats *wlan_get_stats(struct net_device *dev)
559{
560 wlan_private *priv = (wlan_private *) dev->priv;
561
562 return &priv->stats;
563}
564
565static int wlan_set_mac_address(struct net_device *dev, void *addr)
566{
567 int ret = 0;
568 wlan_private *priv = (wlan_private *) dev->priv;
569 wlan_adapter *adapter = priv->adapter;
570 struct sockaddr *phwaddr = addr;
571
572 ENTER();
573
574 memset(adapter->current_addr, 0, ETH_ALEN);
575
576 /* dev->dev_addr is 8 bytes */
577 lbs_dbg_hex("dev->dev_addr:", dev->dev_addr, ETH_ALEN);
578
579 lbs_dbg_hex("addr:", phwaddr->sa_data, ETH_ALEN);
580 memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN);
581
582 ret = libertas_prepare_and_send_command(priv, cmd_802_11_mac_address,
583 cmd_act_set,
584 cmd_option_waitforrsp, 0, NULL);
585
586 if (ret) {
587 lbs_pr_debug(1, "set mac address failed.\n");
588 ret = -1;
589 goto done;
590 }
591
592 lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN);
593 memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
594 memcpy(((wlan_private *) dev->priv)->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
595
596done:
597 LEAVE();
598 return ret;
599}
600
601static int wlan_copy_multicast_address(wlan_adapter * adapter,
602 struct net_device *dev)
603{
604 int i = 0;
605 struct dev_mc_list *mcptr = dev->mc_list;
606
607 for (i = 0; i < dev->mc_count; i++) {
608 memcpy(&adapter->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
609 mcptr = mcptr->next;
610 }
611
612 return i;
613
614}
615
616static void wlan_set_multicast_list(struct net_device *dev)
617{
618 wlan_private *priv = dev->priv;
619 wlan_adapter *adapter = priv->adapter;
620 int oldpacketfilter;
621
622 ENTER();
623
624 oldpacketfilter = adapter->currentpacketfilter;
625
626 if (dev->flags & IFF_PROMISC) {
627 lbs_pr_debug(1, "enable Promiscuous mode\n");
628 adapter->currentpacketfilter |=
629 cmd_act_mac_promiscuous_enable;
630 adapter->currentpacketfilter &=
631 ~(cmd_act_mac_all_multicast_enable |
632 cmd_act_mac_multicast_enable);
633 } else {
634 /* Multicast */
635 adapter->currentpacketfilter &=
636 ~cmd_act_mac_promiscuous_enable;
637
638 if (dev->flags & IFF_ALLMULTI || dev->mc_count >
639 MRVDRV_MAX_MULTICAST_LIST_SIZE) {
640 lbs_pr_debug(1, "Enabling All Multicast!\n");
641 adapter->currentpacketfilter |=
642 cmd_act_mac_all_multicast_enable;
643 adapter->currentpacketfilter &=
644 ~cmd_act_mac_multicast_enable;
645 } else {
646 adapter->currentpacketfilter &=
647 ~cmd_act_mac_all_multicast_enable;
648
649 if (!dev->mc_count) {
650 lbs_pr_debug(1, "No multicast addresses - "
651 "disabling multicast!\n");
652 adapter->currentpacketfilter &=
653 ~cmd_act_mac_multicast_enable;
654 } else {
655 int i;
656
657 adapter->currentpacketfilter |=
658 cmd_act_mac_multicast_enable;
659
660 adapter->nr_of_multicastmacaddr =
661 wlan_copy_multicast_address(adapter, dev);
662
663 lbs_pr_debug(1, "Multicast addresses: %d\n",
664 dev->mc_count);
665
666 for (i = 0; i < dev->mc_count; i++) {
667 lbs_pr_debug(1, "Multicast address %d:"
668 "%x %x %x %x %x %x\n", i,
669 adapter->multicastlist[i][0],
670 adapter->multicastlist[i][1],
671 adapter->multicastlist[i][2],
672 adapter->multicastlist[i][3],
673 adapter->multicastlist[i][4],
674 adapter->multicastlist[i][5]);
675 }
676 /* set multicast addresses to firmware */
677 libertas_prepare_and_send_command(priv,
678 cmd_mac_multicast_adr,
679 cmd_act_set, 0, 0,
680 NULL);
681 }
682 }
683 }
684
685 if (adapter->currentpacketfilter != oldpacketfilter) {
686 libertas_set_mac_packet_filter(priv);
687 }
688
689 LEAVE();
690}
691
692/**
693 * @brief This function hanldes the major job in WLAN driver.
694 * it handles the event generated by firmware, rx data received
695 * from firmware and tx data sent from kernel.
696 *
697 * @param data A pointer to wlan_thread structure
698 * @return 0
699 */
700static int wlan_service_main_thread(void *data)
701{
702 struct wlan_thread *thread = data;
703 wlan_private *priv = thread->priv;
704 wlan_adapter *adapter = priv->adapter;
705 wait_queue_t wait;
706 u8 ireg = 0;
707
708 ENTER();
709
710 wlan_activate_thread(thread);
711
712 init_waitqueue_entry(&wait, current);
713
714 for (;;) {
715 lbs_pr_debug(1, "main-thread 111: intcounter=%d "
716 "currenttxskb=%p dnld_sent=%d\n",
717 adapter->intcounter,
718 adapter->currenttxskb, priv->wlan_dev.dnld_sent);
719
720 add_wait_queue(&thread->waitq, &wait);
721 set_current_state(TASK_INTERRUPTIBLE);
722 spin_lock_irq(&adapter->driver_lock);
723 if ((adapter->psstate == PS_STATE_SLEEP) ||
724 (!adapter->intcounter
725 && (priv->wlan_dev.dnld_sent || adapter->cur_cmd ||
726 list_empty(&adapter->cmdpendingq)))) {
727 lbs_pr_debug(1,
728 "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
729 adapter->connect_status, adapter->intcounter,
730 adapter->psmode, adapter->psstate);
731 spin_unlock_irq(&adapter->driver_lock);
732 schedule();
733 } else
734 spin_unlock_irq(&adapter->driver_lock);
735
736
737 lbs_pr_debug(1,
738 "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
739 "dnld_sent=%d\n", adapter->intcounter,
740 adapter->currenttxskb, priv->wlan_dev.dnld_sent);
741
742 set_current_state(TASK_RUNNING);
743 remove_wait_queue(&thread->waitq, &wait);
744 try_to_freeze();
745
746 lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p "
747 "dnld_sent=%d\n",
748 adapter->intcounter,
749 adapter->currenttxskb, priv->wlan_dev.dnld_sent);
750
751 if (kthread_should_stop()
752 || adapter->surpriseremoved) {
753 lbs_pr_debug(1,
754 "main-thread: break from main thread: surpriseremoved=0x%x\n",
755 adapter->surpriseremoved);
756 break;
757 }
758
759
760 spin_lock_irq(&adapter->driver_lock);
761 if (adapter->intcounter) {
762 u8 int_status;
763 adapter->intcounter = 0;
764 int_status = libertas_sbi_get_int_status(priv, &ireg);
765
766 if (int_status) {
767 lbs_pr_debug(1,
768 "main-thread: reading HOST_INT_STATUS_REG failed\n");
769 spin_unlock_irq(&adapter->driver_lock);
770 continue;
771 }
772 adapter->hisregcpy |= ireg;
773 }
774
775 lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p "
776 "dnld_sent=%d\n",
777 adapter->intcounter,
778 adapter->currenttxskb, priv->wlan_dev.dnld_sent);
779
780 /* command response? */
781 if (adapter->hisregcpy & his_cmdupldrdy) {
782 lbs_pr_debug(1, "main-thread: cmd response ready.\n");
783
784 adapter->hisregcpy &= ~his_cmdupldrdy;
785 spin_unlock_irq(&adapter->driver_lock);
786 libertas_process_rx_command(priv);
787 spin_lock_irq(&adapter->driver_lock);
788 }
789
790 /* Any Card Event */
791 if (adapter->hisregcpy & his_cardevent) {
792 lbs_pr_debug(1, "main-thread: Card Event Activity.\n");
793
794 adapter->hisregcpy &= ~his_cardevent;
795
796 if (libertas_sbi_read_event_cause(priv)) {
797 lbs_pr_alert(
798 "main-thread: libertas_sbi_read_event_cause failed.\n");
799 spin_unlock_irq(&adapter->driver_lock);
800 continue;
801 }
802 spin_unlock_irq(&adapter->driver_lock);
803 libertas_process_event(priv);
804 } else
805 spin_unlock_irq(&adapter->driver_lock);
806
807 /* Check if we need to confirm Sleep Request received previously */
808 if (adapter->psstate == PS_STATE_PRE_SLEEP) {
809 if (!priv->wlan_dev.dnld_sent && !adapter->cur_cmd) {
810 if (adapter->connect_status ==
811 libertas_connected) {
812 lbs_pr_debug(1,
813 "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
814 "dnld_sent=%d cur_cmd=%p, confirm now\n",
815 adapter->intcounter,
816 adapter->currenttxskb,
817 priv->wlan_dev.dnld_sent,
818 adapter->cur_cmd);
819
820 libertas_ps_confirm_sleep(priv,
821 (u16) adapter->psmode);
822 } else {
823 /* workaround for firmware sending
824 * deauth/linkloss event immediately
825 * after sleep request, remove this
826 * after firmware fixes it
827 */
828 adapter->psstate = PS_STATE_AWAKE;
829 lbs_pr_alert(
830 "main-thread: ignore PS_SleepConfirm in non-connected state\n");
831 }
832 }
833 }
834
835 /* The PS state is changed during processing of Sleep Request
836 * event above
837 */
838 if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
839 (priv->adapter->psstate == PS_STATE_PRE_SLEEP))
840 continue;
841
842 /* Execute the next command */
843 if (!priv->wlan_dev.dnld_sent && !priv->adapter->cur_cmd)
844 libertas_execute_next_command(priv);
845
846 /* Wake-up command waiters which can't sleep in
847 * libertas_prepare_and_send_command
848 */
849 if (!adapter->nr_cmd_pending)
850 wake_up_all(&adapter->cmd_pending);
851
852 libertas_tx_runqueue(priv);
853 }
854
855 del_timer(&adapter->command_timer);
856 adapter->nr_cmd_pending = 0;
857 wake_up_all(&adapter->cmd_pending);
858 wlan_deactivate_thread(thread);
859
860 LEAVE();
861 return 0;
862}
863
864/**
865 * @brief This function adds the card. it will probe the
866 * card, allocate the wlan_priv and initialize the device.
867 *
868 * @param card A pointer to card
869 * @return A pointer to wlan_private structure
870 */
871wlan_private *wlan_add_card(void *card)
872{
873 struct net_device *dev = NULL;
874 struct net_device *mesh_dev = NULL;
875 wlan_private *priv = NULL;
876
877 ENTER();
878
879 /* Allocate an Ethernet device and register it */
880 if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
881 lbs_pr_alert( "Init ethernet device failed!\n");
882 return NULL;
883 }
884
885 priv = dev->priv;
886
887 /* allocate buffer for wlan_adapter */
888 if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
889 lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n");
890 goto err_kmalloc;
891 }
892
893 /* Allocate a virtual mesh device */
894 if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
895 lbs_pr_debug(1, "Init ethernet device failed!\n");
896 return NULL;
897 }
898
899 /* Both intervaces share the priv structure */
900 mesh_dev->priv = priv;
901
902 /* init wlan_adapter */
903 memset(priv->adapter, 0, sizeof(wlan_adapter));
904
905 priv->wlan_dev.netdev = dev;
906 priv->wlan_dev.card = card;
907 priv->mesh_open = 0;
908 priv->infra_open = 0;
909 priv->mesh_dev = mesh_dev;
910 wlanpriv = priv;
911
912 SET_MODULE_OWNER(dev);
913 SET_MODULE_OWNER(mesh_dev);
914
915 /* Setup the OS Interface to our functions */
916 dev->open = wlan_open;
917 dev->hard_start_xmit = wlan_pre_start_xmit;
918 dev->stop = wlan_close;
919 dev->do_ioctl = libertas_do_ioctl;
920 dev->set_mac_address = wlan_set_mac_address;
921 mesh_dev->open = mesh_open;
922 mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
923 mesh_dev->stop = mesh_close;
924 mesh_dev->do_ioctl = libertas_do_ioctl;
925 memcpy(mesh_dev->dev_addr, wlanpriv->wlan_dev.netdev->dev_addr,
926 sizeof(wlanpriv->wlan_dev.netdev->dev_addr));
927
928#define WLAN_WATCHDOG_TIMEOUT (5 * HZ)
929
930 dev->tx_timeout = wlan_tx_timeout;
931 dev->get_stats = wlan_get_stats;
932 dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT;
933 dev->ethtool_ops = &libertas_ethtool_ops;
934 mesh_dev->get_stats = wlan_get_stats;
935 mesh_dev->ethtool_ops = &libertas_ethtool_ops;
936
937#ifdef WIRELESS_EXT
938 dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
939 mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
940#endif
941#define NETIF_F_DYNALLOC 16
942 dev->features |= NETIF_F_DYNALLOC;
943 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
944 dev->set_multicast_list = wlan_set_multicast_list;
945
946 INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
947 INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
948
949 spin_lock_init(&priv->adapter->driver_lock);
950 init_waitqueue_head(&priv->adapter->cmd_pending);
951 priv->adapter->nr_cmd_pending = 0;
952
953 lbs_pr_debug(1, "Starting kthread...\n");
954 priv->mainthread.priv = priv;
955 wlan_create_thread(wlan_service_main_thread,
956 &priv->mainthread, "wlan_main_service");
957
958 priv->assoc_thread =
959 create_singlethread_workqueue("libertas_assoc");
960 INIT_DELAYED_WORK(&priv->assoc_work, wlan_association_worker);
961
962 /*
963 * Register the device. Fillup the private data structure with
964 * relevant information from the card and request for the required
965 * IRQ.
966 */
967 if (libertas_sbi_register_dev(priv) < 0) {
968 lbs_pr_info("failed to register wlan device!\n");
969 goto err_registerdev;
970 }
971
972 /* init FW and HW */
973 if (libertas_init_fw(priv)) {
974 lbs_pr_debug(1, "Firmware Init failed\n");
975 goto err_registerdev;
976 }
977
978 if (register_netdev(dev)) {
979 lbs_pr_err("Cannot register network device!\n");
980 goto err_init_fw;
981 }
982
983 /* Register virtual mesh interface */
984 if (register_netdev(mesh_dev)) {
985 lbs_pr_info("Cannot register mesh virtual interface!\n");
986 goto err_init_fw;
987 }
988
989 lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev->name);
990
991 libertas_debugfs_init_one(priv, dev);
992
993 if (libertas_found == MAX_DEVS)
994 goto err_init_fw;
995 libertas_devs[libertas_found] = dev;
996 libertas_found++;
997#ifdef ENABLE_PM
998 if (!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback)))
999 lbs_pr_alert( "failed to register PM callback\n");
1000#endif
1001 if (device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp))
1002 goto err_create_file;
1003
1004 LEAVE();
1005 return priv;
1006
1007err_create_file:
1008 device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
1009err_init_fw:
1010 libertas_sbi_unregister_dev(priv);
1011err_registerdev:
1012 destroy_workqueue(priv->assoc_thread);
1013 /* Stop the thread servicing the interrupts */
1014 wake_up_interruptible(&priv->mainthread.waitq);
1015 wlan_terminate_thread(&priv->mainthread);
1016 kfree(priv->adapter);
1017err_kmalloc:
1018 free_netdev(dev);
1019 free_netdev(mesh_dev);
1020 wlanpriv = NULL;
1021
1022 LEAVE();
1023 return NULL;
1024}
1025
1026static void wake_pending_cmdnodes(wlan_private *priv)
1027{
1028 struct cmd_ctrl_node *cmdnode;
1029 unsigned long flags;
1030
1031 spin_lock_irqsave(&priv->adapter->driver_lock, flags);
1032 list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
1033 cmdnode->cmdwaitqwoken = 1;
1034 wake_up_interruptible(&cmdnode->cmdwait_q);
1035 }
1036 spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
1037}
1038
1039
1040int wlan_remove_card(void *card)
1041{
1042 wlan_private *priv = libertas_sbi_get_priv(card);
1043 wlan_adapter *adapter;
1044 struct net_device *dev;
1045 struct net_device *mesh_dev;
1046 union iwreq_data wrqu;
1047 int i;
1048
1049 ENTER();
1050
1051 if (!priv) {
1052 LEAVE();
1053 return 0;
1054 }
1055
1056 adapter = priv->adapter;
1057
1058 if (!adapter) {
1059 LEAVE();
1060 return 0;
1061 }
1062
1063 dev = priv->wlan_dev.netdev;
1064 mesh_dev = priv->mesh_dev;
1065
1066 netif_stop_queue(mesh_dev);
1067 netif_stop_queue(priv->wlan_dev.netdev);
1068 netif_carrier_off(priv->wlan_dev.netdev);
1069
1070 wake_pending_cmdnodes(priv);
1071
1072 device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
1073 unregister_netdev(mesh_dev);
1074 unregister_netdev(dev);
1075
1076 cancel_delayed_work(&priv->assoc_work);
1077 destroy_workqueue(priv->assoc_thread);
1078
1079 if (adapter->psmode == wlan802_11powermodemax_psp) {
1080 adapter->psmode = wlan802_11powermodecam;
1081 libertas_ps_wakeup(priv, cmd_option_waitforrsp);
1082 }
1083
1084 memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
1085 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1086 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
1087
1088#ifdef ENABLE_PM
1089 pm_unregister(wlan_pm_dev);
1090#endif
1091
1092 adapter->surpriseremoved = 1;
1093
1094 /* Stop the thread servicing the interrupts */
1095 wlan_terminate_thread(&priv->mainthread);
1096
1097 libertas_debugfs_remove_one(priv);
1098
1099 lbs_pr_debug(1, "Free adapter\n");
1100 libertas_free_adapter(priv);
1101
1102 for (i = 0; i<libertas_found; i++) {
1103 if (libertas_devs[i]==priv->wlan_dev.netdev) {
1104 libertas_devs[i] = libertas_devs[--libertas_found];
1105 libertas_devs[libertas_found] = NULL ;
1106 break ;
1107 }
1108 }
1109
1110 lbs_pr_debug(1, "Unregister finish\n");
1111
1112 priv->wlan_dev.netdev = NULL;
1113 priv->mesh_dev = NULL ;
1114 free_netdev(mesh_dev);
1115 free_netdev(dev);
1116 wlanpriv = NULL;
1117
1118 LEAVE();
1119 return 0;
1120}
1121
1122/**
1123 * @brief This function finds the CFP in
1124 * region_cfp_table based on region and band parameter.
1125 *
1126 * @param region The region code
1127 * @param band The band
1128 * @param cfp_no A pointer to CFP number
1129 * @return A pointer to CFP
1130 */
1131struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
1132{
1133 int i, end;
1134
1135 ENTER();
1136
1137 end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
1138
1139 for (i = 0; i < end ; i++) {
1140 lbs_pr_debug(1, "region_cfp_table[i].region=%d\n",
1141 region_cfp_table[i].region);
1142 if (region_cfp_table[i].region == region) {
1143 *cfp_no = region_cfp_table[i].cfp_no_BG;
1144 LEAVE();
1145 return region_cfp_table[i].cfp_BG;
1146 }
1147 }
1148
1149 LEAVE();
1150 return NULL;
1151}
1152
1153int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
1154{
1155 wlan_adapter *adapter = priv->adapter;
1156 int i = 0;
1157
1158 struct chan_freq_power *cfp;
1159 int cfp_no;
1160
1161 ENTER();
1162
1163 memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
1164
1165 {
1166 cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
1167 if (cfp != NULL) {
1168 adapter->region_channel[i].nrcfp = cfp_no;
1169 adapter->region_channel[i].CFP = cfp;
1170 } else {
1171 lbs_pr_debug(1, "wrong region code %#x in band B-G\n",
1172 region);
1173 return -1;
1174 }
1175 adapter->region_channel[i].valid = 1;
1176 adapter->region_channel[i].region = region;
1177 adapter->region_channel[i].band = band;
1178 i++;
1179 }
1180 LEAVE();
1181 return 0;
1182}
1183
1184/**
1185 * @brief This function handles the interrupt. it will change PS
1186 * state if applicable. it will wake up main_thread to handle
1187 * the interrupt event as well.
1188 *
1189 * @param dev A pointer to net_device structure
1190 * @return n/a
1191 */
1192void libertas_interrupt(struct net_device *dev)
1193{
1194 wlan_private *priv = dev->priv;
1195
1196 ENTER();
1197
1198 lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n",
1199 priv->adapter->intcounter);
1200
1201 priv->adapter->intcounter++;
1202
1203 if (priv->adapter->psstate == PS_STATE_SLEEP) {
1204 priv->adapter->psstate = PS_STATE_AWAKE;
1205 netif_wake_queue(dev);
1206 }
1207
1208 wake_up_interruptible(&priv->mainthread.waitq);
1209
1210 LEAVE();
1211}
1212
1213static int wlan_init_module(void)
1214{
1215 int ret = 0;
1216
1217 ENTER();
1218
1219 if (libertas_fw_name == NULL) {
1220 libertas_fw_name = default_fw_name;
1221 }
1222
1223 libertas_debugfs_init();
1224
1225 if (libertas_sbi_register()) {
1226 ret = -1;
1227 libertas_debugfs_remove();
1228 goto done;
1229 }
1230
1231done:
1232 LEAVE();
1233 return ret;
1234}
1235
1236static void wlan_cleanup_module(void)
1237{
1238 int i;
1239
1240 ENTER();
1241
1242 for (i = 0; i<libertas_found; i++) {
1243 wlan_private *priv = libertas_devs[i]->priv;
1244 reset_device(priv);
1245 }
1246
1247 libertas_sbi_unregister();
1248 libertas_debugfs_remove();
1249
1250 LEAVE();
1251}
1252
1253module_init(wlan_init_module);
1254module_exit(wlan_cleanup_module);
1255
1256MODULE_DESCRIPTION("M-WLAN Driver");
1257MODULE_AUTHOR("Marvell International Ltd.");
1258MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h
new file mode 100644
index 000000000000..5d118f40cfbc
--- /dev/null
+++ b/drivers/net/wireless/libertas/radiotap.h
@@ -0,0 +1,57 @@
1#include <net/ieee80211_radiotap.h>
2
3struct tx_radiotap_hdr {
4 struct ieee80211_radiotap_header hdr;
5 u8 rate;
6 u8 txpower;
7 u8 rts_retries;
8 u8 data_retries;
9#if 0
10 u8 pad[IEEE80211_RADIOTAP_HDRLEN - 12];
11#endif
12} __attribute__ ((packed));
13
14#define TX_RADIOTAP_PRESENT ( \
15 (1 << IEEE80211_RADIOTAP_RATE) | \
16 (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
17 (1 << IEEE80211_RADIOTAP_RTS_RETRIES) | \
18 (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | \
19 0)
20
21#define IEEE80211_FC_VERSION_MASK 0x0003
22#define IEEE80211_FC_TYPE_MASK 0x000c
23#define IEEE80211_FC_TYPE_MGT 0x0000
24#define IEEE80211_FC_TYPE_CTL 0x0004
25#define IEEE80211_FC_TYPE_DATA 0x0008
26#define IEEE80211_FC_SUBTYPE_MASK 0x00f0
27#define IEEE80211_FC_TOFROMDS_MASK 0x0300
28#define IEEE80211_FC_TODS_MASK 0x0100
29#define IEEE80211_FC_FROMDS_MASK 0x0200
30#define IEEE80211_FC_NODS 0x0000
31#define IEEE80211_FC_TODS 0x0100
32#define IEEE80211_FC_FROMDS 0x0200
33#define IEEE80211_FC_DSTODS 0x0300
34
35struct rx_radiotap_hdr {
36 struct ieee80211_radiotap_header hdr;
37 u8 flags;
38 u8 rate;
39 u16 chan_freq;
40 u16 chan_flags;
41 u8 antenna;
42 u8 antsignal;
43 u16 rx_flags;
44#if 0
45 u8 pad[IEEE80211_RADIOTAP_HDRLEN - 18];
46#endif
47} __attribute__ ((packed));
48
49#define RX_RADIOTAP_PRESENT ( \
50 (1 << IEEE80211_RADIOTAP_FLAGS) | \
51 (1 << IEEE80211_RADIOTAP_RATE) | \
52 (1 << IEEE80211_RADIOTAP_CHANNEL) | \
53 (1 << IEEE80211_RADIOTAP_ANTENNA) | \
54 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\
55 (1 << IEEE80211_RADIOTAP_RX_FLAGS) | \
56 0)
57
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
new file mode 100644
index 000000000000..7e3f78f092dc
--- /dev/null
+++ b/drivers/net/wireless/libertas/rx.c
@@ -0,0 +1,459 @@
1/**
2 * This file contains the handling of RX in wlan driver.
3 */
4#include <linux/etherdevice.h>
5#include <linux/types.h>
6
7#include "hostcmd.h"
8#include "radiotap.h"
9#include "decl.h"
10#include "dev.h"
11#include "wext.h"
12
13struct eth803hdr {
14 u8 dest_addr[6];
15 u8 src_addr[6];
16 u16 h803_len;
17} __attribute__ ((packed));
18
19struct rfc1042hdr {
20 u8 llc_dsap;
21 u8 llc_ssap;
22 u8 llc_ctrl;
23 u8 snap_oui[3];
24 u16 snap_type;
25} __attribute__ ((packed));
26
27struct rxpackethdr {
28 struct rxpd rx_pd;
29 struct eth803hdr eth803_hdr;
30 struct rfc1042hdr rfc1042_hdr;
31} __attribute__ ((packed));
32
33struct rx80211packethdr {
34 struct rxpd rx_pd;
35 void *eth80211_hdr;
36} __attribute__ ((packed));
37
38static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb);
39
40/**
41 * @brief This function computes the avgSNR .
42 *
43 * @param priv A pointer to wlan_private structure
44 * @return avgSNR
45 */
46static u8 wlan_getavgsnr(wlan_private * priv)
47{
48 u8 i;
49 u16 temp = 0;
50 wlan_adapter *adapter = priv->adapter;
51 if (adapter->numSNRNF == 0)
52 return 0;
53 for (i = 0; i < adapter->numSNRNF; i++)
54 temp += adapter->rawSNR[i];
55 return (u8) (temp / adapter->numSNRNF);
56
57}
58
59/**
60 * @brief This function computes the AvgNF
61 *
62 * @param priv A pointer to wlan_private structure
63 * @return AvgNF
64 */
65static u8 wlan_getavgnf(wlan_private * priv)
66{
67 u8 i;
68 u16 temp = 0;
69 wlan_adapter *adapter = priv->adapter;
70 if (adapter->numSNRNF == 0)
71 return 0;
72 for (i = 0; i < adapter->numSNRNF; i++)
73 temp += adapter->rawNF[i];
74 return (u8) (temp / adapter->numSNRNF);
75
76}
77
78/**
79 * @brief This function save the raw SNR/NF to our internel buffer
80 *
81 * @param priv A pointer to wlan_private structure
82 * @param prxpd A pointer to rxpd structure of received packet
83 * @return n/a
84 */
85static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd)
86{
87 wlan_adapter *adapter = priv->adapter;
88 if (adapter->numSNRNF < adapter->data_avg_factor)
89 adapter->numSNRNF++;
90 adapter->rawSNR[adapter->nextSNRNF] = p_rx_pd->snr;
91 adapter->rawNF[adapter->nextSNRNF] = p_rx_pd->nf;
92 adapter->nextSNRNF++;
93 if (adapter->nextSNRNF >= adapter->data_avg_factor)
94 adapter->nextSNRNF = 0;
95 return;
96}
97
98/**
99 * @brief This function computes the RSSI in received packet.
100 *
101 * @param priv A pointer to wlan_private structure
102 * @param prxpd A pointer to rxpd structure of received packet
103 * @return n/a
104 */
105static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
106{
107 wlan_adapter *adapter = priv->adapter;
108
109 ENTER();
110
111 lbs_pr_debug(1, "rxpd: SNR = %d, NF = %d\n", p_rx_pd->snr, p_rx_pd->nf);
112 lbs_pr_debug(1, "Before computing SNR: SNR- avg = %d, NF-avg = %d\n",
113 adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
114 adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
115
116 adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
117 adapter->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
118 wlan_save_rawSNRNF(priv, p_rx_pd);
119
120 adapter->rxpd_rate = p_rx_pd->rx_rate;
121
122 adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE;
123 adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE;
124 lbs_pr_debug(1, "After computing SNR: SNR-avg = %d, NF-avg = %d\n",
125 adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
126 adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
127
128 adapter->RSSI[TYPE_RXPD][TYPE_NOAVG] =
129 CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
130 adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
131
132 adapter->RSSI[TYPE_RXPD][TYPE_AVG] =
133 CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
134 adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
135
136 LEAVE();
137}
138
139int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
140{
141 lbs_pr_debug(1, "skb->data=%p\n", skb->data);
142
143 if(IS_MESH_FRAME(skb))
144 skb->dev = priv->mesh_dev;
145 else
146 skb->dev = priv->wlan_dev.netdev;
147 skb->protocol = eth_type_trans(skb, priv->wlan_dev.netdev);
148 skb->ip_summed = CHECKSUM_UNNECESSARY;
149
150 netif_rx(skb);
151
152 return 0;
153}
154
155/**
156 * @brief This function processes received packet and forwards it
157 * to kernel/upper layer
158 *
159 * @param priv A pointer to wlan_private
160 * @param skb A pointer to skb which includes the received packet
161 * @return 0 or -1
162 */
163int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
164{
165 wlan_adapter *adapter = priv->adapter;
166 int ret = 0;
167
168 struct rxpackethdr *p_rx_pkt;
169 struct rxpd *p_rx_pd;
170
171 int hdrchop;
172 struct ethhdr *p_ethhdr;
173
174 const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
175
176 ENTER();
177
178 if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH)
179 lbs_dbg_hex("RX packet: ", skb->data,
180 min_t(unsigned int, skb->len, 100));
181
182 if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
183 return process_rxed_802_11_packet(priv, skb);
184
185 p_rx_pkt = (struct rxpackethdr *) skb->data;
186 p_rx_pd = &p_rx_pkt->rx_pd;
187 if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
188 SET_MESH_FRAME(skb);
189 else
190 UNSET_MESH_FRAME(skb);
191
192 lbs_dbg_hex("RX Data: Before chop rxpd", skb->data,
193 min_t(unsigned int, skb->len, 100));
194
195 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
196 lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
197 priv->stats.rx_length_errors++;
198 ret = 0;
199 goto done;
200 }
201
202 /*
203 * Check rxpd status and update 802.3 stat,
204 */
205 if (!(p_rx_pd->status & MRVDRV_RXPD_STATUS_OK)) {
206 lbs_pr_debug(1, "RX error: frame received with bad status\n");
207 lbs_pr_alert("rxpd Not OK\n");
208 priv->stats.rx_errors++;
209 ret = 0;
210 goto done;
211 }
212
213 lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
214 skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
215
216 lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
217 sizeof(p_rx_pkt->eth803_hdr.dest_addr));
218 lbs_dbg_hex("RX Data: Src", p_rx_pkt->eth803_hdr.src_addr,
219 sizeof(p_rx_pkt->eth803_hdr.src_addr));
220
221 if (memcmp(&p_rx_pkt->rfc1042_hdr,
222 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
223 /*
224 * Replace the 803 header and rfc1042 header (llc/snap) with an
225 * EthernetII header, keep the src/dst and snap_type (ethertype)
226 *
227 * The firmware only passes up SNAP frames converting
228 * all RX Data from 802.11 to 802.2/LLC/SNAP frames.
229 *
230 * To create the Ethernet II, just move the src, dst address right
231 * before the snap_type.
232 */
233 p_ethhdr = (struct ethhdr *)
234 ((u8 *) & p_rx_pkt->eth803_hdr
235 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr)
236 - sizeof(p_rx_pkt->eth803_hdr.dest_addr)
237 - sizeof(p_rx_pkt->eth803_hdr.src_addr)
238 - sizeof(p_rx_pkt->rfc1042_hdr.snap_type));
239
240 memcpy(p_ethhdr->h_source, p_rx_pkt->eth803_hdr.src_addr,
241 sizeof(p_ethhdr->h_source));
242 memcpy(p_ethhdr->h_dest, p_rx_pkt->eth803_hdr.dest_addr,
243 sizeof(p_ethhdr->h_dest));
244
245 /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
246 * that was removed
247 */
248 hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
249 } else {
250 lbs_dbg_hex("RX Data: LLC/SNAP",
251 (u8 *) & p_rx_pkt->rfc1042_hdr,
252 sizeof(p_rx_pkt->rfc1042_hdr));
253
254 /* Chop off the rxpd */
255 hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
256 }
257
258 /* Chop off the leading header bytes so the skb points to the start of
259 * either the reconstructed EthII frame or the 802.2/llc/snap frame
260 */
261 skb_pull(skb, hdrchop);
262
263 /* Take the data rate from the rxpd structure
264 * only if the rate is auto
265 */
266 if (adapter->is_datarate_auto)
267 adapter->datarate = libertas_index_to_data_rate(p_rx_pd->rx_rate);
268
269 wlan_compute_rssi(priv, p_rx_pd);
270
271 lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
272 if (libertas_upload_rx_packet(priv, skb)) {
273 lbs_pr_debug(1, "RX error: libertas_upload_rx_packet"
274 " returns failure\n");
275 ret = -1;
276 goto done;
277 }
278 priv->stats.rx_bytes += skb->len;
279 priv->stats.rx_packets++;
280
281 ret = 0;
282done:
283 LEAVE();
284
285 return ret;
286}
287
288/**
289 * @brief This function converts Tx/Rx rates from the Marvell WLAN format
290 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
291 *
292 * @param rate Input rate
293 * @return Output Rate (0 if invalid)
294 */
295static u8 convert_mv_rate_to_radiotap(u8 rate)
296{
297 switch (rate) {
298 case 0: /* 1 Mbps */
299 return 2;
300 case 1: /* 2 Mbps */
301 return 4;
302 case 2: /* 5.5 Mbps */
303 return 11;
304 case 3: /* 11 Mbps */
305 return 22;
306 case 4: /* 6 Mbps */
307 return 12;
308 case 5: /* 9 Mbps */
309 return 18;
310 case 6: /* 12 Mbps */
311 return 24;
312 case 7: /* 18 Mbps */
313 return 36;
314 case 8: /* 24 Mbps */
315 return 48;
316 case 9: /* 36 Mbps */
317 return 72;
318 case 10: /* 48 Mbps */
319 return 96;
320 case 11: /* 54 Mbps */
321 return 108;
322 }
323 lbs_pr_alert( "Invalid Marvell WLAN rate (%i)\n", rate);
324 return 0;
325}
326
327/**
328 * @brief This function processes a received 802.11 packet and forwards it
329 * to kernel/upper layer
330 *
331 * @param priv A pointer to wlan_private
332 * @param skb A pointer to skb which includes the received packet
333 * @return 0 or -1
334 */
335static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
336{
337 wlan_adapter *adapter = priv->adapter;
338 int ret = 0;
339
340 struct rx80211packethdr *p_rx_pkt;
341 struct rxpd *prxpd;
342 struct rx_radiotap_hdr radiotap_hdr;
343 struct rx_radiotap_hdr *pradiotap_hdr;
344
345 ENTER();
346
347 p_rx_pkt = (struct rx80211packethdr *) skb->data;
348 prxpd = &p_rx_pkt->rx_pd;
349
350 // lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
351
352 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
353 lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
354 priv->stats.rx_length_errors++;
355 ret = 0;
356 goto done;
357 }
358
359 /*
360 * Check rxpd status and update 802.3 stat,
361 */
362 if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK)) {
363 //lbs_pr_debug(1, "RX error: frame received with bad status\n");
364 priv->stats.rx_errors++;
365 }
366
367 lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
368 skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
369
370 /* create the exported radio header */
371 switch (priv->adapter->radiomode) {
372 case WLAN_RADIOMODE_NONE:
373 /* no radio header */
374 /* chop the rxpd */
375 skb_pull(skb, sizeof(struct rxpd));
376 break;
377
378 case WLAN_RADIOMODE_RADIOTAP:
379 /* radiotap header */
380 radiotap_hdr.hdr.it_version = 0;
381 /* XXX must check this value for pad */
382 radiotap_hdr.hdr.it_pad = 0;
383 radiotap_hdr.hdr.it_len = sizeof(struct rx_radiotap_hdr);
384 radiotap_hdr.hdr.it_present = RX_RADIOTAP_PRESENT;
385 /* unknown values */
386 radiotap_hdr.flags = 0;
387 radiotap_hdr.chan_freq = 0;
388 radiotap_hdr.chan_flags = 0;
389 radiotap_hdr.antenna = 0;
390 /* known values */
391 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
392 /* XXX must check no carryout */
393 radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
394 radiotap_hdr.rx_flags = 0;
395 if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK))
396 radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
397 //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
398
399 // lbs_dbg_hex1("RX radiomode packet BEF: ", skb->data, min(skb->len, 100));
400
401 /* chop the rxpd */
402 skb_pull(skb, sizeof(struct rxpd));
403
404 /* add space for the new radio header */
405 if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
406 pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
407 GFP_ATOMIC)) {
408 lbs_pr_alert( "%s: couldn't pskb_expand_head\n",
409 __func__);
410 }
411
412 pradiotap_hdr =
413 (struct rx_radiotap_hdr *)skb_push(skb,
414 sizeof(struct
415 rx_radiotap_hdr));
416 memcpy(pradiotap_hdr, &radiotap_hdr,
417 sizeof(struct rx_radiotap_hdr));
418 //lbs_dbg_hex1("RX radiomode packet AFT: ", skb->data, min(skb->len, 100));
419 break;
420
421 default:
422 /* unknown header */
423 lbs_pr_alert( "Unknown radiomode (%i)\n",
424 priv->adapter->radiomode);
425 /* don't export any header */
426 /* chop the rxpd */
427 skb_pull(skb, sizeof(struct rxpd));
428 break;
429 }
430
431 /* Take the data rate from the rxpd structure
432 * only if the rate is auto
433 */
434 if (adapter->is_datarate_auto) {
435 adapter->datarate = libertas_index_to_data_rate(prxpd->rx_rate);
436 }
437
438 wlan_compute_rssi(priv, prxpd);
439
440 lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
441
442 if (libertas_upload_rx_packet(priv, skb)) {
443 lbs_pr_debug(1, "RX error: libertas_upload_rx_packet "
444 "returns failure\n");
445 ret = -1;
446 goto done;
447 }
448
449 priv->stats.rx_bytes += skb->len;
450 priv->stats.rx_packets++;
451
452 ret = 0;
453done:
454 LEAVE();
455
456 skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
457
458 return (ret);
459}
diff --git a/drivers/net/wireless/libertas/sbi.h b/drivers/net/wireless/libertas/sbi.h
new file mode 100644
index 000000000000..59d3a59ccef0
--- /dev/null
+++ b/drivers/net/wireless/libertas/sbi.h
@@ -0,0 +1,40 @@
1/**
2 * This file contains IF layer definitions.
3 */
4
5#ifndef _SBI_H_
6#define _SBI_H_
7
8#include <linux/interrupt.h>
9
10#include "defs.h"
11
12/** INT status Bit Definition*/
13#define his_cmddnldrdy 0x01
14#define his_cardevent 0x02
15#define his_cmdupldrdy 0x04
16
17#ifndef DEV_NAME_LEN
18#define DEV_NAME_LEN 32
19#endif
20
21#define SBI_EVENT_CAUSE_SHIFT 3
22
23/* Probe and Check if the card is present*/
24int libertas_sbi_register_dev(wlan_private * priv);
25int libertas_sbi_unregister_dev(wlan_private *);
26int libertas_sbi_get_int_status(wlan_private * priv, u8 *);
27int libertas_sbi_register(void);
28void libertas_sbi_unregister(void);
29int libertas_sbi_prog_firmware(wlan_private *);
30
31int libertas_sbi_read_event_cause(wlan_private *);
32int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
33wlan_private *libertas_sbi_get_priv(void *card);
34
35#ifdef ENABLE_PM
36int libertas_sbi_suspend(wlan_private *);
37int libertas_sbi_resume(wlan_private *);
38#endif
39
40#endif /* _SBI_H */
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
new file mode 100644
index 000000000000..e18706238951
--- /dev/null
+++ b/drivers/net/wireless/libertas/scan.c
@@ -0,0 +1,2044 @@
1/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
2/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
3
4/**
5 * Functions implementing wlan scan IOCTL and firmware command APIs
6 *
7 * IOCTL handlers as well as command preperation and response routines
8 * for sending scan commands to the firmware.
9 */
10#include <linux/ctype.h>
11#include <linux/if.h>
12#include <linux/netdevice.h>
13#include <linux/wireless.h>
14
15#include <net/ieee80211.h>
16#include <net/iw_handler.h>
17
18#include "host.h"
19#include "decl.h"
20#include "dev.h"
21#include "scan.h"
22
23//! Approximate amount of data needed to pass a scan result back to iwlist
24#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \
25 + IW_ESSID_MAX_SIZE \
26 + IW_EV_UINT_LEN \
27 + IW_EV_FREQ_LEN \
28 + IW_EV_QUAL_LEN \
29 + IW_ESSID_MAX_SIZE \
30 + IW_EV_PARAM_LEN \
31 + 40) /* 40 for WPAIE */
32
33//! Memory needed to store a max sized channel List TLV for a firmware scan
34#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvlietypesheader) \
35 + (MRVDRV_MAX_CHANNELS_PER_SCAN \
36 * sizeof(struct chanscanparamset)))
37
38//! Memory needed to store a max number/size SSID TLV for a firmware scan
39#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset))
40
41//! Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max
42#define MAX_SCAN_CFG_ALLOC (sizeof(struct wlan_scan_cmd_config) \
43 + sizeof(struct mrvlietypes_numprobes) \
44 + CHAN_TLV_MAX_SIZE \
45 + SSID_TLV_MAX_SIZE)
46
47//! The maximum number of channels the firmware can scan per command
48#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
49
50/**
51 * @brief Number of channels to scan per firmware scan command issuance.
52 *
53 * Number restricted to prevent hitting the limit on the amount of scan data
54 * returned in a single firmware scan command.
55 */
56#define MRVDRV_CHANNELS_PER_SCAN_CMD 4
57
58//! Scan time specified in the channel TLV for each channel for passive scans
59#define MRVDRV_PASSIVE_SCAN_CHAN_TIME 100
60
61//! Scan time specified in the channel TLV for each channel for active scans
62#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
63
64//! Macro to enable/disable SSID checking before storing a scan table
65#ifdef DISCARD_BAD_SSID
66#define CHECK_SSID_IS_VALID(x) ssid_valid(&bssidEntry.ssid)
67#else
68#define CHECK_SSID_IS_VALID(x) 1
69#endif
70
71/**
72 * @brief Check if a scanned network compatible with the driver settings
73 *
74 * WEP WPA WPA2 ad-hoc encrypt Network
75 * enabled enabled enabled AES mode privacy WPA WPA2 Compatible
76 * 0 0 0 0 NONE 0 0 0 yes No security
77 * 1 0 0 0 NONE 1 0 0 yes Static WEP
78 * 0 1 0 0 x 1x 1 x yes WPA
79 * 0 0 1 0 x 1x x 1 yes WPA2
80 * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES
81 * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP
82 *
83 *
84 * @param adapter A pointer to wlan_adapter
85 * @param index Index in scantable to check against current driver settings
86 * @param mode Network mode: Infrastructure or IBSS
87 *
88 * @return Index in scantable, or error code if negative
89 */
90static int is_network_compatible(wlan_adapter * adapter, int index, int mode)
91{
92 ENTER();
93
94 if (adapter->scantable[index].inframode == mode) {
95 if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
96 && !adapter->secinfo.WPAenabled
97 && !adapter->secinfo.WPA2enabled
98 && adapter->scantable[index].wpa_supplicant.wpa_ie[0] !=
99 WPA_IE
100 && adapter->scantable[index].wpa2_supplicant.wpa_ie[0] !=
101 WPA2_IE && adapter->secinfo.Encryptionmode == CIPHER_NONE
102 && !adapter->scantable[index].privacy) {
103 /* no security */
104 LEAVE();
105 return index;
106 } else if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled
107 && !adapter->secinfo.WPAenabled
108 && !adapter->secinfo.WPA2enabled
109 && adapter->scantable[index].privacy) {
110 /* static WEP enabled */
111 LEAVE();
112 return index;
113 } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
114 && adapter->secinfo.WPAenabled
115 && !adapter->secinfo.WPA2enabled
116 && (adapter->scantable[index].wpa_supplicant.
117 wpa_ie[0]
118 == WPA_IE)
119 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
120 && adapter->scantable[index].privacy */
121 ) {
122 /* WPA enabled */
123 lbs_pr_debug(1,
124 "is_network_compatible() WPA: index=%d wpa_ie=%#x "
125 "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
126 "privacy=%#x\n", index,
127 adapter->scantable[index].wpa_supplicant.
128 wpa_ie[0],
129 adapter->scantable[index].wpa2_supplicant.
130 wpa_ie[0],
131 (adapter->secinfo.WEPstatus ==
132 wlan802_11WEPenabled) ? "e" : "d",
133 (adapter->secinfo.WPAenabled) ? "e" : "d",
134 (adapter->secinfo.WPA2enabled) ? "e" : "d",
135 adapter->secinfo.Encryptionmode,
136 adapter->scantable[index].privacy);
137 LEAVE();
138 return index;
139 } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
140 && !adapter->secinfo.WPAenabled
141 && adapter->secinfo.WPA2enabled
142 && (adapter->scantable[index].wpa2_supplicant.
143 wpa_ie[0]
144 == WPA2_IE)
145 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
146 && adapter->scantable[index].privacy */
147 ) {
148 /* WPA2 enabled */
149 lbs_pr_debug(1,
150 "is_network_compatible() WPA2: index=%d wpa_ie=%#x "
151 "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
152 "privacy=%#x\n", index,
153 adapter->scantable[index].wpa_supplicant.
154 wpa_ie[0],
155 adapter->scantable[index].wpa2_supplicant.
156 wpa_ie[0],
157 (adapter->secinfo.WEPstatus ==
158 wlan802_11WEPenabled) ? "e" : "d",
159 (adapter->secinfo.WPAenabled) ? "e" : "d",
160 (adapter->secinfo.WPA2enabled) ? "e" : "d",
161 adapter->secinfo.Encryptionmode,
162 adapter->scantable[index].privacy);
163 LEAVE();
164 return index;
165 } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
166 && !adapter->secinfo.WPAenabled
167 && !adapter->secinfo.WPA2enabled
168 && (adapter->scantable[index].wpa_supplicant.
169 wpa_ie[0]
170 != WPA_IE)
171 && (adapter->scantable[index].wpa2_supplicant.
172 wpa_ie[0]
173 != WPA2_IE)
174 && adapter->secinfo.Encryptionmode != CIPHER_NONE
175 && adapter->scantable[index].privacy) {
176 /* dynamic WEP enabled */
177 lbs_pr_debug(1,
178 "is_network_compatible() dynamic WEP: index=%d "
179 "wpa_ie=%#x wpa2_ie=%#x Encmode=%#x privacy=%#x\n",
180 index,
181 adapter->scantable[index].wpa_supplicant.
182 wpa_ie[0],
183 adapter->scantable[index].wpa2_supplicant.
184 wpa_ie[0], adapter->secinfo.Encryptionmode,
185 adapter->scantable[index].privacy);
186 LEAVE();
187 return index;
188 }
189
190 /* security doesn't match */
191 lbs_pr_debug(1,
192 "is_network_compatible() FAILED: index=%d wpa_ie=%#x "
193 "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x privacy=%#x\n",
194 index,
195 adapter->scantable[index].wpa_supplicant.wpa_ie[0],
196 adapter->scantable[index].wpa2_supplicant.wpa_ie[0],
197 (adapter->secinfo.WEPstatus ==
198 wlan802_11WEPenabled) ? "e" : "d",
199 (adapter->secinfo.WPAenabled) ? "e" : "d",
200 (adapter->secinfo.WPA2enabled) ? "e" : "d",
201 adapter->secinfo.Encryptionmode,
202 adapter->scantable[index].privacy);
203 LEAVE();
204 return -ECONNREFUSED;
205 }
206
207 /* mode doesn't match */
208 LEAVE();
209 return -ENETUNREACH;
210}
211
212/**
213 * @brief This function validates a SSID as being able to be printed
214 *
215 * @param pssid SSID structure to validate
216 *
217 * @return TRUE or FALSE
218 */
219static u8 ssid_valid(struct WLAN_802_11_SSID *pssid)
220{
221 int ssididx;
222
223 for (ssididx = 0; ssididx < pssid->ssidlength; ssididx++) {
224 if (!isprint(pssid->ssid[ssididx])) {
225 return 0;
226 }
227 }
228
229 return 1;
230}
231
232/**
233 * @brief Post process the scan table after a new scan command has completed
234 *
235 * Inspect each entry of the scan table and try to find an entry that
236 * matches our current associated/joined network from the scan. If
237 * one is found, update the stored copy of the bssdescriptor for our
238 * current network.
239 *
240 * Debug dump the current scan table contents if compiled accordingly.
241 *
242 * @param priv A pointer to wlan_private structure
243 *
244 * @return void
245 */
246static void wlan_scan_process_results(wlan_private * priv)
247{
248 wlan_adapter *adapter = priv->adapter;
249 int foundcurrent;
250 int i;
251
252 foundcurrent = 0;
253
254 if (adapter->connect_status == libertas_connected) {
255 /* try to find the current BSSID in the new scan list */
256 for (i = 0; i < adapter->numinscantable; i++) {
257 if (!libertas_SSID_cmp(&adapter->scantable[i].ssid,
258 &adapter->curbssparams.ssid) &&
259 !memcmp(adapter->curbssparams.bssid,
260 adapter->scantable[i].macaddress,
261 ETH_ALEN)) {
262 foundcurrent = 1;
263 }
264 }
265
266 if (foundcurrent) {
267 /* Make a copy of current BSSID descriptor */
268 memcpy(&adapter->curbssparams.bssdescriptor,
269 &adapter->scantable[i],
270 sizeof(adapter->curbssparams.bssdescriptor));
271 }
272 }
273
274 for (i = 0; i < adapter->numinscantable; i++) {
275 lbs_pr_debug(1, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "
276 "RSSI[%03d], SSID[%s]\n",
277 i,
278 adapter->scantable[i].macaddress[0],
279 adapter->scantable[i].macaddress[1],
280 adapter->scantable[i].macaddress[2],
281 adapter->scantable[i].macaddress[3],
282 adapter->scantable[i].macaddress[4],
283 adapter->scantable[i].macaddress[5],
284 (s32) adapter->scantable[i].rssi,
285 adapter->scantable[i].ssid.ssid);
286 }
287}
288
289/**
290 * @brief Create a channel list for the driver to scan based on region info
291 *
292 * Use the driver region/band information to construct a comprehensive list
293 * of channels to scan. This routine is used for any scan that is not
294 * provided a specific channel list to scan.
295 *
296 * @param priv A pointer to wlan_private structure
297 * @param scanchanlist Output parameter: resulting channel list to scan
298 * @param filteredscan Flag indicating whether or not a BSSID or SSID filter
299 * is being sent in the command to firmware. Used to
300 * increase the number of channels sent in a scan
301 * command and to disable the firmware channel scan
302 * filter.
303 *
304 * @return void
305 */
306static void wlan_scan_create_channel_list(wlan_private * priv,
307 struct chanscanparamset * scanchanlist,
308 u8 filteredscan)
309{
310
311 wlan_adapter *adapter = priv->adapter;
312 struct region_channel *scanregion;
313 struct chan_freq_power *cfp;
314 int rgnidx;
315 int chanidx;
316 int nextchan;
317 u8 scantype;
318
319 chanidx = 0;
320
321 /* Set the default scan type to the user specified type, will later
322 * be changed to passive on a per channel basis if restricted by
323 * regulatory requirements (11d or 11h)
324 */
325 scantype = adapter->scantype;
326
327 for (rgnidx = 0; rgnidx < ARRAY_SIZE(adapter->region_channel); rgnidx++) {
328 if (priv->adapter->enable11d &&
329 adapter->connect_status != libertas_connected) {
330 /* Scan all the supported chan for the first scan */
331 if (!adapter->universal_channel[rgnidx].valid)
332 continue;
333 scanregion = &adapter->universal_channel[rgnidx];
334
335 /* clear the parsed_region_chan for the first scan */
336 memset(&adapter->parsed_region_chan, 0x00,
337 sizeof(adapter->parsed_region_chan));
338 } else {
339 if (!adapter->region_channel[rgnidx].valid)
340 continue;
341 scanregion = &adapter->region_channel[rgnidx];
342 }
343
344 for (nextchan = 0;
345 nextchan < scanregion->nrcfp; nextchan++, chanidx++) {
346
347 cfp = scanregion->CFP + nextchan;
348
349 if (priv->adapter->enable11d) {
350 scantype =
351 libertas_get_scan_type_11d(cfp->channel,
352 &adapter->
353 parsed_region_chan);
354 }
355
356 switch (scanregion->band) {
357 case BAND_B:
358 case BAND_G:
359 default:
360 scanchanlist[chanidx].radiotype =
361 cmd_scan_radio_type_bg;
362 break;
363 }
364
365 if (scantype == cmd_scan_type_passive) {
366 scanchanlist[chanidx].maxscantime =
367 cpu_to_le16
368 (MRVDRV_PASSIVE_SCAN_CHAN_TIME);
369 scanchanlist[chanidx].chanscanmode.passivescan =
370 1;
371 } else {
372 scanchanlist[chanidx].maxscantime =
373 cpu_to_le16
374 (MRVDRV_ACTIVE_SCAN_CHAN_TIME);
375 scanchanlist[chanidx].chanscanmode.passivescan =
376 0;
377 }
378
379 scanchanlist[chanidx].channumber = cfp->channel;
380
381 if (filteredscan) {
382 scanchanlist[chanidx].chanscanmode.
383 disablechanfilt = 1;
384 }
385 }
386 }
387}
388
389/**
390 * @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds
391 *
392 * Application layer or other functions can invoke wlan_scan_networks
393 * with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct.
394 * This structure is used as the basis of one or many wlan_scan_cmd_config
395 * commands that are sent to the command processing module and sent to
396 * firmware.
397 *
398 * Create a wlan_scan_cmd_config based on the following user supplied
399 * parameters (if present):
400 * - SSID filter
401 * - BSSID filter
402 * - Number of Probes to be sent
403 * - channel list
404 *
405 * If the SSID or BSSID filter is not present, disable/clear the filter.
406 * If the number of probes is not set, use the adapter default setting
407 * Qualify the channel
408 *
409 * @param priv A pointer to wlan_private structure
410 * @param puserscanin NULL or pointer to scan configuration parameters
411 * @param ppchantlvout Output parameter: Pointer to the start of the
412 * channel TLV portion of the output scan config
413 * @param pscanchanlist Output parameter: Pointer to the resulting channel
414 * list to scan
415 * @param pmaxchanperscan Output parameter: Number of channels to scan for
416 * each issuance of the firmware scan command
417 * @param pfilteredscan Output parameter: Flag indicating whether or not
418 * a BSSID or SSID filter is being sent in the
419 * command to firmware. Used to increase the number
420 * of channels sent in a scan command and to
421 * disable the firmware channel scan filter.
422 * @param pscancurrentonly Output parameter: Flag indicating whether or not
423 * we are only scanning our current active channel
424 *
425 * @return resulting scan configuration
426 */
427static struct wlan_scan_cmd_config *
428wlan_scan_setup_scan_config(wlan_private * priv,
429 const struct wlan_ioctl_user_scan_cfg * puserscanin,
430 struct mrvlietypes_chanlistparamset ** ppchantlvout,
431 struct chanscanparamset * pscanchanlist,
432 int *pmaxchanperscan,
433 u8 * pfilteredscan,
434 u8 * pscancurrentonly)
435{
436 wlan_adapter *adapter = priv->adapter;
437 const u8 zeromac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
438 struct mrvlietypes_numprobes *pnumprobestlv;
439 struct mrvlietypes_ssidparamset *pssidtlv;
440 struct wlan_scan_cmd_config * pscancfgout = NULL;
441 u8 *ptlvpos;
442 u16 numprobes;
443 u16 ssidlen;
444 int chanidx;
445 int scantype;
446 int scandur;
447 int channel;
448 int radiotype;
449
450 pscancfgout = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
451 if (pscancfgout == NULL)
452 goto out;
453
454 /* The tlvbufferlen is calculated for each scan command. The TLVs added
455 * in this routine will be preserved since the routine that sends
456 * the command will append channelTLVs at *ppchantlvout. The difference
457 * between the *ppchantlvout and the tlvbuffer start will be used
458 * to calculate the size of anything we add in this routine.
459 */
460 pscancfgout->tlvbufferlen = 0;
461
462 /* Running tlv pointer. Assigned to ppchantlvout at end of function
463 * so later routines know where channels can be added to the command buf
464 */
465 ptlvpos = pscancfgout->tlvbuffer;
466
467 /*
468 * Set the initial scan paramters for progressive scanning. If a specific
469 * BSSID or SSID is used, the number of channels in the scan command
470 * will be increased to the absolute maximum
471 */
472 *pmaxchanperscan = MRVDRV_CHANNELS_PER_SCAN_CMD;
473
474 /* Initialize the scan as un-filtered by firmware, set to TRUE below if
475 * a SSID or BSSID filter is sent in the command
476 */
477 *pfilteredscan = 0;
478
479 /* Initialize the scan as not being only on the current channel. If
480 * the channel list is customized, only contains one channel, and
481 * is the active channel, this is set true and data flow is not halted.
482 */
483 *pscancurrentonly = 0;
484
485 if (puserscanin) {
486
487 /* Set the bss type scan filter, use adapter setting if unset */
488 pscancfgout->bsstype =
489 (puserscanin->bsstype ? puserscanin->bsstype : adapter->
490 scanmode);
491
492 /* Set the number of probes to send, use adapter setting if unset */
493 numprobes = (puserscanin->numprobes ? puserscanin->numprobes :
494 adapter->scanprobes);
495
496 /*
497 * Set the BSSID filter to the incoming configuration,
498 * if non-zero. If not set, it will remain disabled (all zeros).
499 */
500 memcpy(pscancfgout->specificBSSID,
501 puserscanin->specificBSSID,
502 sizeof(pscancfgout->specificBSSID));
503
504 ssidlen = strlen(puserscanin->specificSSID);
505
506 if (ssidlen) {
507 pssidtlv =
508 (struct mrvlietypes_ssidparamset *) pscancfgout->
509 tlvbuffer;
510 pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
511 pssidtlv->header.len = cpu_to_le16(ssidlen);
512 memcpy(pssidtlv->ssid, puserscanin->specificSSID,
513 ssidlen);
514 ptlvpos += sizeof(pssidtlv->header) + ssidlen;
515 }
516
517 /*
518 * The default number of channels sent in the command is low to
519 * ensure the response buffer from the firmware does not truncate
520 * scan results. That is not an issue with an SSID or BSSID
521 * filter applied to the scan results in the firmware.
522 */
523 if (ssidlen || (memcmp(pscancfgout->specificBSSID,
524 &zeromac, sizeof(zeromac)) != 0)) {
525 *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
526 *pfilteredscan = 1;
527 }
528 } else {
529 pscancfgout->bsstype = adapter->scanmode;
530 numprobes = adapter->scanprobes;
531 }
532
533 /* If the input config or adapter has the number of Probes set, add tlv */
534 if (numprobes) {
535 pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
536 pnumprobestlv->header.type =
537 cpu_to_le16(TLV_TYPE_NUMPROBES);
538 pnumprobestlv->header.len = sizeof(pnumprobestlv->numprobes);
539 pnumprobestlv->numprobes = cpu_to_le16(numprobes);
540
541 ptlvpos +=
542 sizeof(pnumprobestlv->header) + pnumprobestlv->header.len;
543
544 pnumprobestlv->header.len =
545 cpu_to_le16(pnumprobestlv->header.len);
546 }
547
548 /*
549 * Set the output for the channel TLV to the address in the tlv buffer
550 * past any TLVs that were added in this fuction (SSID, numprobes).
551 * channel TLVs will be added past this for each scan command, preserving
552 * the TLVs that were previously added.
553 */
554 *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos;
555
556 if (puserscanin && puserscanin->chanlist[0].channumber) {
557
558 lbs_pr_debug(1, "Scan: Using supplied channel list\n");
559
560 for (chanidx = 0;
561 chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX
562 && puserscanin->chanlist[chanidx].channumber; chanidx++) {
563
564 channel = puserscanin->chanlist[chanidx].channumber;
565 (pscanchanlist + chanidx)->channumber = channel;
566
567 radiotype = puserscanin->chanlist[chanidx].radiotype;
568 (pscanchanlist + chanidx)->radiotype = radiotype;
569
570 scantype = puserscanin->chanlist[chanidx].scantype;
571
572 if (scantype == cmd_scan_type_passive) {
573 (pscanchanlist +
574 chanidx)->chanscanmode.passivescan = 1;
575 } else {
576 (pscanchanlist +
577 chanidx)->chanscanmode.passivescan = 0;
578 }
579
580 if (puserscanin->chanlist[chanidx].scantime) {
581 scandur =
582 puserscanin->chanlist[chanidx].scantime;
583 } else {
584 if (scantype == cmd_scan_type_passive) {
585 scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
586 } else {
587 scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
588 }
589 }
590
591 (pscanchanlist + chanidx)->minscantime =
592 cpu_to_le16(scandur);
593 (pscanchanlist + chanidx)->maxscantime =
594 cpu_to_le16(scandur);
595 }
596
597 /* Check if we are only scanning the current channel */
598 if ((chanidx == 1) && (puserscanin->chanlist[0].channumber
599 ==
600 priv->adapter->curbssparams.channel)) {
601 *pscancurrentonly = 1;
602 lbs_pr_debug(1, "Scan: Scanning current channel only");
603 }
604
605 } else {
606 lbs_pr_debug(1, "Scan: Creating full region channel list\n");
607 wlan_scan_create_channel_list(priv, pscanchanlist,
608 *pfilteredscan);
609 }
610
611out:
612 return pscancfgout;
613}
614
615/**
616 * @brief Construct and send multiple scan config commands to the firmware
617 *
618 * Previous routines have created a wlan_scan_cmd_config with any requested
619 * TLVs. This function splits the channel TLV into maxchanperscan lists
620 * and sends the portion of the channel TLV along with the other TLVs
621 * to the wlan_cmd routines for execution in the firmware.
622 *
623 * @param priv A pointer to wlan_private structure
624 * @param maxchanperscan Maximum number channels to be included in each
625 * scan command sent to firmware
626 * @param filteredscan Flag indicating whether or not a BSSID or SSID
627 * filter is being used for the firmware command
628 * scan command sent to firmware
629 * @param pscancfgout Scan configuration used for this scan.
630 * @param pchantlvout Pointer in the pscancfgout where the channel TLV
631 * should start. This is past any other TLVs that
632 * must be sent down in each firmware command.
633 * @param pscanchanlist List of channels to scan in maxchanperscan segments
634 *
635 * @return 0 or error return otherwise
636 */
637static int wlan_scan_channel_list(wlan_private * priv,
638 int maxchanperscan,
639 u8 filteredscan,
640 struct wlan_scan_cmd_config * pscancfgout,
641 struct mrvlietypes_chanlistparamset * pchantlvout,
642 struct chanscanparamset * pscanchanlist)
643{
644 struct chanscanparamset *ptmpchan;
645 struct chanscanparamset *pstartchan;
646 u8 scanband;
647 int doneearly;
648 int tlvidx;
649 int ret = 0;
650
651 ENTER();
652
653 if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) {
654 lbs_pr_debug(1, "Scan: Null detect: %p, %p, %p\n",
655 pscancfgout, pchantlvout, pscanchanlist);
656 return -1;
657 }
658
659 pchantlvout->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
660
661 /* Set the temp channel struct pointer to the start of the desired list */
662 ptmpchan = pscanchanlist;
663
664 /* Loop through the desired channel list, sending a new firmware scan
665 * commands for each maxchanperscan channels (or for 1,6,11 individually
666 * if configured accordingly)
667 */
668 while (ptmpchan->channumber) {
669
670 tlvidx = 0;
671 pchantlvout->header.len = 0;
672 scanband = ptmpchan->radiotype;
673 pstartchan = ptmpchan;
674 doneearly = 0;
675
676 /* Construct the channel TLV for the scan command. Continue to
677 * insert channel TLVs until:
678 * - the tlvidx hits the maximum configured per scan command
679 * - the next channel to insert is 0 (end of desired channel list)
680 * - doneearly is set (controlling individual scanning of 1,6,11)
681 */
682 while (tlvidx < maxchanperscan && ptmpchan->channumber
683 && !doneearly) {
684
685 lbs_pr_debug(1,
686 "Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n",
687 ptmpchan->channumber, ptmpchan->radiotype,
688 ptmpchan->chanscanmode.passivescan,
689 ptmpchan->chanscanmode.disablechanfilt,
690 ptmpchan->maxscantime);
691
692 /* Copy the current channel TLV to the command being prepared */
693 memcpy(pchantlvout->chanscanparam + tlvidx,
694 ptmpchan, sizeof(pchantlvout->chanscanparam));
695
696 /* Increment the TLV header length by the size appended */
697 pchantlvout->header.len +=
698 sizeof(pchantlvout->chanscanparam);
699
700 /*
701 * The tlv buffer length is set to the number of bytes of the
702 * between the channel tlv pointer and the start of the
703 * tlv buffer. This compensates for any TLVs that were appended
704 * before the channel list.
705 */
706 pscancfgout->tlvbufferlen = ((u8 *) pchantlvout
707 - pscancfgout->tlvbuffer);
708
709 /* Add the size of the channel tlv header and the data length */
710 pscancfgout->tlvbufferlen +=
711 (sizeof(pchantlvout->header)
712 + pchantlvout->header.len);
713
714 /* Increment the index to the channel tlv we are constructing */
715 tlvidx++;
716
717 doneearly = 0;
718
719 /* Stop the loop if the *current* channel is in the 1,6,11 set
720 * and we are not filtering on a BSSID or SSID.
721 */
722 if (!filteredscan && (ptmpchan->channumber == 1
723 || ptmpchan->channumber == 6
724 || ptmpchan->channumber == 11)) {
725 doneearly = 1;
726 }
727
728 /* Increment the tmp pointer to the next channel to be scanned */
729 ptmpchan++;
730
731 /* Stop the loop if the *next* channel is in the 1,6,11 set.
732 * This will cause it to be the only channel scanned on the next
733 * interation
734 */
735 if (!filteredscan && (ptmpchan->channumber == 1
736 || ptmpchan->channumber == 6
737 || ptmpchan->channumber == 11)) {
738 doneearly = 1;
739 }
740 }
741
742 /* Send the scan command to the firmware with the specified cfg */
743 ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0,
744 0, 0, pscancfgout);
745 }
746
747 LEAVE();
748 return ret;
749}
750
751/**
752 * @brief Internal function used to start a scan based on an input config
753 *
754 * Use the input user scan configuration information when provided in
755 * order to send the appropriate scan commands to firmware to populate or
756 * update the internal driver scan table
757 *
758 * @param priv A pointer to wlan_private structure
759 * @param puserscanin Pointer to the input configuration for the requested
760 * scan.
761 *
762 * @return 0 or < 0 if error
763 */
764int wlan_scan_networks(wlan_private * priv,
765 const struct wlan_ioctl_user_scan_cfg * puserscanin)
766{
767 wlan_adapter *adapter = priv->adapter;
768 struct mrvlietypes_chanlistparamset *pchantlvout;
769 struct chanscanparamset * scan_chan_list = NULL;
770 struct wlan_scan_cmd_config * scan_cfg = NULL;
771 u8 keeppreviousscan;
772 u8 filteredscan;
773 u8 scancurrentchanonly;
774 int maxchanperscan;
775 int ret;
776
777 ENTER();
778
779 scan_chan_list = kzalloc(sizeof(struct chanscanparamset) *
780 WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
781 if (scan_chan_list == NULL) {
782 ret = -ENOMEM;
783 goto out;
784 }
785
786 scan_cfg = wlan_scan_setup_scan_config(priv,
787 puserscanin,
788 &pchantlvout,
789 scan_chan_list,
790 &maxchanperscan,
791 &filteredscan,
792 &scancurrentchanonly);
793 if (scan_cfg == NULL) {
794 ret = -ENOMEM;
795 goto out;
796 }
797
798 keeppreviousscan = 0;
799
800 if (puserscanin) {
801 keeppreviousscan = puserscanin->keeppreviousscan;
802 }
803
804 if (!keeppreviousscan) {
805 memset(adapter->scantable, 0x00,
806 sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST);
807 adapter->numinscantable = 0;
808 }
809
810 /* Keep the data path active if we are only scanning our current channel */
811 if (!scancurrentchanonly) {
812 netif_stop_queue(priv->wlan_dev.netdev);
813 netif_carrier_off(priv->wlan_dev.netdev);
814 }
815
816 ret = wlan_scan_channel_list(priv,
817 maxchanperscan,
818 filteredscan,
819 scan_cfg,
820 pchantlvout,
821 scan_chan_list);
822
823 /* Process the resulting scan table:
824 * - Remove any bad ssids
825 * - Update our current BSS information from scan data
826 */
827 wlan_scan_process_results(priv);
828
829 if (priv->adapter->connect_status == libertas_connected) {
830 netif_carrier_on(priv->wlan_dev.netdev);
831 netif_wake_queue(priv->wlan_dev.netdev);
832 }
833
834out:
835 if (scan_cfg)
836 kfree(scan_cfg);
837
838 if (scan_chan_list)
839 kfree(scan_chan_list);
840
841 LEAVE();
842 return ret;
843}
844
845/**
846 * @brief Inspect the scan response buffer for pointers to expected TLVs
847 *
848 * TLVs can be included at the end of the scan response BSS information.
849 * Parse the data in the buffer for pointers to TLVs that can potentially
850 * be passed back in the response
851 *
852 * @param ptlv Pointer to the start of the TLV buffer to parse
853 * @param tlvbufsize size of the TLV buffer
854 * @param ptsftlv Output parameter: Pointer to the TSF TLV if found
855 *
856 * @return void
857 */
858static
859void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
860 int tlvbufsize,
861 struct mrvlietypes_tsftimestamp ** ptsftlv)
862{
863 struct mrvlietypes_data *pcurrenttlv;
864 int tlvbufleft;
865 u16 tlvtype;
866 u16 tlvlen;
867
868 pcurrenttlv = ptlv;
869 tlvbufleft = tlvbufsize;
870 *ptsftlv = NULL;
871
872 lbs_pr_debug(1, "SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
873 lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize);
874
875 while (tlvbufleft >= sizeof(struct mrvlietypesheader)) {
876 tlvtype = le16_to_cpu(pcurrenttlv->header.type);
877 tlvlen = le16_to_cpu(pcurrenttlv->header.len);
878
879 switch (tlvtype) {
880 case TLV_TYPE_TSFTIMESTAMP:
881 *ptsftlv = (struct mrvlietypes_tsftimestamp *) pcurrenttlv;
882 break;
883
884 default:
885 lbs_pr_debug(1, "SCAN_RESP: Unhandled TLV = %d\n",
886 tlvtype);
887 /* Give up, this seems corrupted */
888 return;
889 } /* switch */
890
891 tlvbufleft -= (sizeof(ptlv->header) + tlvlen);
892 pcurrenttlv =
893 (struct mrvlietypes_data *) (pcurrenttlv->Data + tlvlen);
894 } /* while */
895}
896
897/**
898 * @brief Interpret a BSS scan response returned from the firmware
899 *
900 * Parse the various fixed fields and IEs passed back for a a BSS probe
901 * response or beacon from the scan command. Record information as needed
902 * in the scan table struct bss_descriptor for that entry.
903 *
904 * @param pBSSIDEntry Output parameter: Pointer to the BSS Entry
905 *
906 * @return 0 or -1
907 */
908static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
909 u8 ** pbeaconinfo, int *bytesleft)
910{
911 enum ieeetypes_elementid elemID;
912 struct ieeetypes_fhparamset *pFH;
913 struct ieeetypes_dsparamset *pDS;
914 struct ieeetypes_cfparamset *pCF;
915 struct ieeetypes_ibssparamset *pibss;
916 struct ieeetypes_capinfo *pcap;
917 struct WLAN_802_11_FIXED_IEs fixedie;
918 u8 *pcurrentptr;
919 u8 *pRate;
920 u8 elemlen;
921 u8 bytestocopy;
922 u8 ratesize;
923 u16 beaconsize;
924 u8 founddatarateie;
925 int bytesleftforcurrentbeacon;
926
927 struct WPA_SUPPLICANT *pwpa_supplicant;
928 struct WPA_SUPPLICANT *pwpa2_supplicant;
929 struct IE_WPA *pIe;
930 const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
931
932 struct ieeetypes_countryinfoset *pcountryinfo;
933
934 ENTER();
935
936 founddatarateie = 0;
937 ratesize = 0;
938 beaconsize = 0;
939
940 if (*bytesleft >= sizeof(beaconsize)) {
941 /* Extract & convert beacon size from the command buffer */
942 memcpy(&beaconsize, *pbeaconinfo, sizeof(beaconsize));
943 beaconsize = le16_to_cpu(beaconsize);
944 *bytesleft -= sizeof(beaconsize);
945 *pbeaconinfo += sizeof(beaconsize);
946 }
947
948 if (beaconsize == 0 || beaconsize > *bytesleft) {
949
950 *pbeaconinfo += *bytesleft;
951 *bytesleft = 0;
952
953 return -1;
954 }
955
956 /* Initialize the current working beacon pointer for this BSS iteration */
957 pcurrentptr = *pbeaconinfo;
958
959 /* Advance the return beacon pointer past the current beacon */
960 *pbeaconinfo += beaconsize;
961 *bytesleft -= beaconsize;
962
963 bytesleftforcurrentbeacon = beaconsize;
964
965 pwpa_supplicant = &pBSSEntry->wpa_supplicant;
966 pwpa2_supplicant = &pBSSEntry->wpa2_supplicant;
967
968 memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
969 lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
970 pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
971 pBSSEntry->macaddress[2], pBSSEntry->macaddress[3],
972 pBSSEntry->macaddress[4], pBSSEntry->macaddress[5]);
973
974 pcurrentptr += ETH_ALEN;
975 bytesleftforcurrentbeacon -= ETH_ALEN;
976
977 if (bytesleftforcurrentbeacon < 12) {
978 lbs_pr_debug(1, "InterpretIE: Not enough bytes left\n");
979 return -1;
980 }
981
982 /*
983 * next 4 fields are RSSI, time stamp, beacon interval,
984 * and capability information
985 */
986
987 /* RSSI is 1 byte long */
988 pBSSEntry->rssi = le32_to_cpu((long)(*pcurrentptr));
989 lbs_pr_debug(1, "InterpretIE: RSSI=%02X\n", *pcurrentptr);
990 pcurrentptr += 1;
991 bytesleftforcurrentbeacon -= 1;
992
993 /* time stamp is 8 bytes long */
994 memcpy(fixedie.timestamp, pcurrentptr, 8);
995 memcpy(pBSSEntry->timestamp, pcurrentptr, 8);
996 pcurrentptr += 8;
997 bytesleftforcurrentbeacon -= 8;
998
999 /* beacon interval is 2 bytes long */
1000 memcpy(&fixedie.beaconinterval, pcurrentptr, 2);
1001 pBSSEntry->beaconperiod = le16_to_cpu(fixedie.beaconinterval);
1002 pcurrentptr += 2;
1003 bytesleftforcurrentbeacon -= 2;
1004
1005 /* capability information is 2 bytes long */
1006 memcpy(&fixedie.capabilities, pcurrentptr, 2);
1007 lbs_pr_debug(1, "InterpretIE: fixedie.capabilities=0x%X\n",
1008 fixedie.capabilities);
1009 fixedie.capabilities = le16_to_cpu(fixedie.capabilities);
1010 pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities;
1011 memcpy(&pBSSEntry->cap, pcap, sizeof(struct ieeetypes_capinfo));
1012 pcurrentptr += 2;
1013 bytesleftforcurrentbeacon -= 2;
1014
1015 /* rest of the current buffer are IE's */
1016 lbs_pr_debug(1, "InterpretIE: IElength for this AP = %d\n",
1017 bytesleftforcurrentbeacon);
1018
1019 lbs_dbg_hex("InterpretIE: IE info", (u8 *) pcurrentptr,
1020 bytesleftforcurrentbeacon);
1021
1022 if (pcap->privacy) {
1023 lbs_pr_debug(1, "InterpretIE: AP WEP enabled\n");
1024 pBSSEntry->privacy = wlan802_11privfilter8021xWEP;
1025 } else {
1026 pBSSEntry->privacy = wlan802_11privfilteracceptall;
1027 }
1028
1029 if (pcap->ibss == 1) {
1030 pBSSEntry->inframode = wlan802_11ibss;
1031 } else {
1032 pBSSEntry->inframode = wlan802_11infrastructure;
1033 }
1034
1035 /* process variable IE */
1036 while (bytesleftforcurrentbeacon >= 2) {
1037 elemID = (enum ieeetypes_elementid) (*((u8 *) pcurrentptr));
1038 elemlen = *((u8 *) pcurrentptr + 1);
1039
1040 if (bytesleftforcurrentbeacon < elemlen) {
1041 lbs_pr_debug(1, "InterpretIE: error in processing IE, "
1042 "bytes left < IE length\n");
1043 bytesleftforcurrentbeacon = 0;
1044 continue;
1045 }
1046
1047 switch (elemID) {
1048
1049 case SSID:
1050 pBSSEntry->ssid.ssidlength = elemlen;
1051 memcpy(pBSSEntry->ssid.ssid, (pcurrentptr + 2),
1052 elemlen);
1053 lbs_pr_debug(1, "ssid: %32s", pBSSEntry->ssid.ssid);
1054 break;
1055
1056 case SUPPORTED_RATES:
1057 memcpy(pBSSEntry->datarates, (pcurrentptr + 2),
1058 elemlen);
1059 memmove(pBSSEntry->libertas_supported_rates, (pcurrentptr + 2),
1060 elemlen);
1061 ratesize = elemlen;
1062 founddatarateie = 1;
1063 break;
1064
1065 case EXTRA_IE:
1066 lbs_pr_debug(1, "InterpretIE: EXTRA_IE Found!\n");
1067 pBSSEntry->extra_ie = 1;
1068 break;
1069
1070 case FH_PARAM_SET:
1071 pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
1072 memmove(&pBSSEntry->phyparamset.fhparamset, pFH,
1073 sizeof(struct ieeetypes_fhparamset));
1074 pBSSEntry->phyparamset.fhparamset.dwelltime
1075 =
1076 le16_to_cpu(pBSSEntry->phyparamset.fhparamset.
1077 dwelltime);
1078 break;
1079
1080 case DS_PARAM_SET:
1081 pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
1082
1083 pBSSEntry->channel = pDS->currentchan;
1084
1085 memcpy(&pBSSEntry->phyparamset.dsparamset, pDS,
1086 sizeof(struct ieeetypes_dsparamset));
1087 break;
1088
1089 case CF_PARAM_SET:
1090 pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
1091
1092 memcpy(&pBSSEntry->ssparamset.cfparamset, pCF,
1093 sizeof(struct ieeetypes_cfparamset));
1094 break;
1095
1096 case IBSS_PARAM_SET:
1097 pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
1098 pBSSEntry->atimwindow =
1099 le32_to_cpu(pibss->atimwindow);
1100
1101 memmove(&pBSSEntry->ssparamset.ibssparamset, pibss,
1102 sizeof(struct ieeetypes_ibssparamset));
1103
1104 pBSSEntry->ssparamset.ibssparamset.atimwindow
1105 =
1106 le16_to_cpu(pBSSEntry->ssparamset.ibssparamset.
1107 atimwindow);
1108 break;
1109
1110 /* Handle Country Info IE */
1111 case COUNTRY_INFO:
1112 pcountryinfo =
1113 (struct ieeetypes_countryinfoset *) pcurrentptr;
1114
1115 if (pcountryinfo->len <
1116 sizeof(pcountryinfo->countrycode)
1117 || pcountryinfo->len > 254) {
1118 lbs_pr_debug(1, "InterpretIE: 11D- Err "
1119 "CountryInfo len =%d min=%d max=254\n",
1120 pcountryinfo->len,
1121 sizeof(pcountryinfo->countrycode));
1122 LEAVE();
1123 return -1;
1124 }
1125
1126 memcpy(&pBSSEntry->countryinfo,
1127 pcountryinfo, pcountryinfo->len + 2);
1128 lbs_dbg_hex("InterpretIE: 11D- CountryInfo:",
1129 (u8 *) pcountryinfo,
1130 (u32) (pcountryinfo->len + 2));
1131 break;
1132
1133 case EXTENDED_SUPPORTED_RATES:
1134 /*
1135 * only process extended supported rate
1136 * if data rate is already found.
1137 * data rate IE should come before
1138 * extended supported rate IE
1139 */
1140 if (founddatarateie) {
1141 if ((elemlen + ratesize) > WLAN_SUPPORTED_RATES) {
1142 bytestocopy =
1143 (WLAN_SUPPORTED_RATES - ratesize);
1144 } else {
1145 bytestocopy = elemlen;
1146 }
1147
1148 pRate = (u8 *) pBSSEntry->datarates;
1149 pRate += ratesize;
1150 memmove(pRate, (pcurrentptr + 2), bytestocopy);
1151
1152 pRate = (u8 *) pBSSEntry->libertas_supported_rates;
1153
1154 pRate += ratesize;
1155 memmove(pRate, (pcurrentptr + 2), bytestocopy);
1156 }
1157 break;
1158
1159 case VENDOR_SPECIFIC_221:
1160#define IE_ID_LEN_FIELDS_BYTES 2
1161 pIe = (struct IE_WPA *)pcurrentptr;
1162
1163 if (!memcmp(pIe->oui, oui01, sizeof(oui01))) {
1164 pwpa_supplicant->wpa_ie_len
1165 = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
1166 sizeof(pwpa_supplicant->wpa_ie));
1167 memcpy(pwpa_supplicant->wpa_ie,
1168 pcurrentptr,
1169 pwpa_supplicant->wpa_ie_len);
1170 lbs_dbg_hex("InterpretIE: Resp WPA_IE",
1171 pwpa_supplicant->wpa_ie, elemlen);
1172 }
1173 break;
1174 case WPA2_IE:
1175 pIe = (struct IE_WPA *)pcurrentptr;
1176 pwpa2_supplicant->wpa_ie_len
1177 = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
1178 sizeof(pwpa2_supplicant->wpa_ie));
1179 memcpy(pwpa2_supplicant->wpa_ie,
1180 pcurrentptr, pwpa2_supplicant->wpa_ie_len);
1181
1182 lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
1183 pwpa2_supplicant->wpa_ie, elemlen);
1184 break;
1185 case TIM:
1186 break;
1187
1188 case CHALLENGE_TEXT:
1189 break;
1190 }
1191
1192 pcurrentptr += elemlen + 2;
1193
1194 /* need to account for IE ID and IE len */
1195 bytesleftforcurrentbeacon -= (elemlen + 2);
1196
1197 } /* while (bytesleftforcurrentbeacon > 2) */
1198
1199 return 0;
1200}
1201
1202/**
1203 * @brief Compare two SSIDs
1204 *
1205 * @param ssid1 A pointer to ssid to compare
1206 * @param ssid2 A pointer to ssid to compare
1207 *
1208 * @return 0--ssid is same, otherwise is different
1209 */
1210int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2)
1211{
1212 if (!ssid1 || !ssid2)
1213 return -1;
1214
1215 if (ssid1->ssidlength != ssid2->ssidlength)
1216 return -1;
1217
1218 return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssidlength);
1219}
1220
1221/**
1222 * @brief This function finds a specific compatible BSSID in the scan list
1223 *
1224 * @param adapter A pointer to wlan_adapter
1225 * @param bssid BSSID to find in the scan list
1226 * @param mode Network mode: Infrastructure or IBSS
1227 *
1228 * @return index in BSSID list, or error return code (< 0)
1229 */
1230int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
1231{
1232 int ret = -ENETUNREACH;
1233 int i;
1234
1235 if (!bssid)
1236 return -EFAULT;
1237
1238 lbs_pr_debug(1, "FindBSSID: Num of BSSIDs = %d\n",
1239 adapter->numinscantable);
1240
1241 /* Look through the scan table for a compatible match. The ret return
1242 * variable will be equal to the index in the scan table (greater
1243 * than zero) if the network is compatible. The loop will continue
1244 * past a matched bssid that is not compatible in case there is an
1245 * AP with multiple SSIDs assigned to the same BSSID
1246 */
1247 for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
1248 if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
1249 switch (mode) {
1250 case wlan802_11infrastructure:
1251 case wlan802_11ibss:
1252 ret = is_network_compatible(adapter, i, mode);
1253 break;
1254 default:
1255 ret = i;
1256 break;
1257 }
1258 }
1259 }
1260
1261 return ret;
1262}
1263
1264/**
1265 * @brief This function finds ssid in ssid list.
1266 *
1267 * @param adapter A pointer to wlan_adapter
1268 * @param ssid SSID to find in the list
1269 * @param bssid BSSID to qualify the SSID selection (if provided)
1270 * @param mode Network mode: Infrastructure or IBSS
1271 *
1272 * @return index in BSSID list
1273 */
1274int libertas_find_SSID_in_list(wlan_adapter * adapter,
1275 struct WLAN_802_11_SSID *ssid, u8 * bssid, int mode)
1276{
1277 int net = -ENETUNREACH;
1278 u8 bestrssi = 0;
1279 int i;
1280 int j;
1281
1282 lbs_pr_debug(1, "Num of Entries in Table = %d\n", adapter->numinscantable);
1283
1284 for (i = 0; i < adapter->numinscantable; i++) {
1285 if (!libertas_SSID_cmp(&adapter->scantable[i].ssid, ssid) &&
1286 (!bssid ||
1287 !memcmp(adapter->scantable[i].
1288 macaddress, bssid, ETH_ALEN))) {
1289 switch (mode) {
1290 case wlan802_11infrastructure:
1291 case wlan802_11ibss:
1292 j = is_network_compatible(adapter, i, mode);
1293
1294 if (j >= 0) {
1295 if (bssid) {
1296 return i;
1297 }
1298
1299 if (SCAN_RSSI
1300 (adapter->scantable[i].rssi)
1301 > bestrssi) {
1302 bestrssi =
1303 SCAN_RSSI(adapter->
1304 scantable[i].
1305 rssi);
1306 net = i;
1307 }
1308 } else {
1309 if (net == -ENETUNREACH) {
1310 net = j;
1311 }
1312 }
1313 break;
1314 case wlan802_11autounknown:
1315 default:
1316 if (SCAN_RSSI(adapter->scantable[i].rssi)
1317 > bestrssi) {
1318 bestrssi =
1319 SCAN_RSSI(adapter->scantable[i].
1320 rssi);
1321 net = i;
1322 }
1323 break;
1324 }
1325 }
1326 }
1327
1328 return net;
1329}
1330
1331/**
1332 * @brief This function finds the best SSID in the Scan List
1333 *
1334 * Search the scan table for the best SSID that also matches the current
1335 * adapter network preference (infrastructure or adhoc)
1336 *
1337 * @param adapter A pointer to wlan_adapter
1338 *
1339 * @return index in BSSID list
1340 */
1341int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
1342 enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode)
1343{
1344 int bestnet = -ENETUNREACH;
1345 u8 bestrssi = 0;
1346 int i;
1347
1348 ENTER();
1349
1350 lbs_pr_debug(1, "Num of BSSIDs = %d\n", adapter->numinscantable);
1351
1352 for (i = 0; i < adapter->numinscantable; i++) {
1353 switch (mode) {
1354 case wlan802_11infrastructure:
1355 case wlan802_11ibss:
1356 if (is_network_compatible(adapter, i, mode) >= 0) {
1357 if (SCAN_RSSI(adapter->scantable[i].rssi) >
1358 bestrssi) {
1359 bestrssi =
1360 SCAN_RSSI(adapter->scantable[i].
1361 rssi);
1362 bestnet = i;
1363 }
1364 }
1365 break;
1366 case wlan802_11autounknown:
1367 default:
1368 if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
1369 bestrssi =
1370 SCAN_RSSI(adapter->scantable[i].rssi);
1371 bestnet = i;
1372 }
1373 break;
1374 }
1375 }
1376
1377 LEAVE();
1378 return bestnet;
1379}
1380
1381/**
1382 * @brief Find the AP with specific ssid in the scan list
1383 *
1384 * @param priv A pointer to wlan_private structure
1385 * @param pSSID A pointer to AP's ssid
1386 *
1387 * @return 0--success, otherwise--fail
1388 */
1389int libertas_find_best_network_SSID(wlan_private * priv,
1390 struct WLAN_802_11_SSID *pSSID,
1391 enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
1392 enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode)
1393{
1394 wlan_adapter *adapter = priv->adapter;
1395 int ret = 0;
1396 struct bss_descriptor *preqbssid;
1397 int i;
1398
1399 ENTER();
1400
1401 memset(pSSID, 0, sizeof(struct WLAN_802_11_SSID));
1402
1403 wlan_scan_networks(priv, NULL);
1404 if (adapter->surpriseremoved)
1405 return -1;
1406 wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
1407
1408 i = libertas_find_best_SSID_in_list(adapter, preferred_mode);
1409 if (i < 0) {
1410 ret = -1;
1411 goto out;
1412 }
1413
1414 preqbssid = &adapter->scantable[i];
1415 memcpy(pSSID, &preqbssid->ssid,
1416 sizeof(struct WLAN_802_11_SSID));
1417 *out_mode = preqbssid->inframode;
1418
1419 if (!pSSID->ssidlength) {
1420 ret = -1;
1421 }
1422
1423out:
1424 LEAVE();
1425 return ret;
1426}
1427
1428/**
1429 * @brief Scan Network
1430 *
1431 * @param dev A pointer to net_device structure
1432 * @param info A pointer to iw_request_info structure
1433 * @param vwrq A pointer to iw_param structure
1434 * @param extra A pointer to extra data buf
1435 *
1436 * @return 0 --success, otherwise fail
1437 */
1438int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
1439 struct iw_param *vwrq, char *extra)
1440{
1441 wlan_private *priv = dev->priv;
1442 wlan_adapter *adapter = priv->adapter;
1443 union iwreq_data wrqu;
1444
1445 ENTER();
1446
1447 if (!wlan_scan_networks(priv, NULL)) {
1448 memset(&wrqu, 0, sizeof(union iwreq_data));
1449 wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu,
1450 NULL);
1451 }
1452
1453 if (adapter->surpriseremoved)
1454 return -1;
1455
1456 LEAVE();
1457 return 0;
1458}
1459
1460/**
1461 * @brief Send a scan command for all available channels filtered on a spec
1462 *
1463 * @param priv A pointer to wlan_private structure
1464 * @param prequestedssid A pointer to AP's ssid
1465 * @param keeppreviousscan Flag used to save/clear scan table before scan
1466 *
1467 * @return 0-success, otherwise fail
1468 */
1469int libertas_send_specific_SSID_scan(wlan_private * priv,
1470 struct WLAN_802_11_SSID *prequestedssid,
1471 u8 keeppreviousscan)
1472{
1473 wlan_adapter *adapter = priv->adapter;
1474 struct wlan_ioctl_user_scan_cfg scancfg;
1475
1476 ENTER();
1477
1478 if (prequestedssid == NULL) {
1479 return -1;
1480 }
1481
1482 memset(&scancfg, 0x00, sizeof(scancfg));
1483
1484 memcpy(scancfg.specificSSID, prequestedssid->ssid,
1485 prequestedssid->ssidlength);
1486 scancfg.keeppreviousscan = keeppreviousscan;
1487
1488 wlan_scan_networks(priv, &scancfg);
1489 if (adapter->surpriseremoved)
1490 return -1;
1491 wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
1492
1493 LEAVE();
1494 return 0;
1495}
1496
1497/**
1498 * @brief scan an AP with specific BSSID
1499 *
1500 * @param priv A pointer to wlan_private structure
1501 * @param bssid A pointer to AP's bssid
1502 * @param keeppreviousscan Flag used to save/clear scan table before scan
1503 *
1504 * @return 0-success, otherwise fail
1505 */
1506int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppreviousscan)
1507{
1508 struct wlan_ioctl_user_scan_cfg scancfg;
1509
1510 ENTER();
1511
1512 if (bssid == NULL) {
1513 return -1;
1514 }
1515
1516 memset(&scancfg, 0x00, sizeof(scancfg));
1517 memcpy(scancfg.specificBSSID, bssid, sizeof(scancfg.specificBSSID));
1518 scancfg.keeppreviousscan = keeppreviousscan;
1519
1520 wlan_scan_networks(priv, &scancfg);
1521 if (priv->adapter->surpriseremoved)
1522 return -1;
1523 wait_event_interruptible(priv->adapter->cmd_pending,
1524 !priv->adapter->nr_cmd_pending);
1525
1526 LEAVE();
1527 return 0;
1528}
1529
1530/**
1531 * @brief Retrieve the scan table entries via wireless tools IOCTL call
1532 *
1533 * @param dev A pointer to net_device structure
1534 * @param info A pointer to iw_request_info structure
1535 * @param dwrq A pointer to iw_point structure
1536 * @param extra A pointer to extra data buf
1537 *
1538 * @return 0 --success, otherwise fail
1539 */
1540int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
1541 struct iw_point *dwrq, char *extra)
1542{
1543 wlan_private *priv = dev->priv;
1544 wlan_adapter *adapter = priv->adapter;
1545 int ret = 0;
1546 char *current_ev = extra;
1547 char *end_buf = extra + IW_SCAN_MAX_DATA;
1548 struct chan_freq_power *cfp;
1549 struct bss_descriptor *pscantable;
1550 char *current_val; /* For rates */
1551 struct iw_event iwe; /* Temporary buffer */
1552 int i;
1553 int j;
1554 int rate;
1555#define PERFECT_RSSI ((u8)50)
1556#define WORST_RSSI ((u8)0)
1557#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI))
1558 u8 rssi;
1559
1560 u8 buf[16 + 256 * 2];
1561 u8 *ptr;
1562
1563 ENTER();
1564
1565 /*
1566 * if there's either commands in the queue or one being
1567 * processed return -EAGAIN for iwlist to retry later.
1568 */
1569 if (adapter->nr_cmd_pending)
1570 return -EAGAIN;
1571
1572 if (adapter->connect_status == libertas_connected)
1573 lbs_pr_debug(1, "Current ssid: %32s\n",
1574 adapter->curbssparams.ssid.ssid);
1575
1576 lbs_pr_debug(1, "Scan: Get: numinscantable = %d\n",
1577 adapter->numinscantable);
1578
1579 /* The old API using SIOCGIWAPLIST had a hard limit of IW_MAX_AP.
1580 * The new API using SIOCGIWSCAN is only limited by buffer size
1581 * WE-14 -> WE-16 the buffer is limited to IW_SCAN_MAX_DATA bytes
1582 * which is 4096.
1583 */
1584 for (i = 0; i < adapter->numinscantable; i++) {
1585 if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
1586 lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
1587 "MAX_SCAN_CELL_SIZE=%d\n",
1588 i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
1589 break;
1590 }
1591
1592 pscantable = &adapter->scantable[i];
1593
1594 lbs_pr_debug(1, "i=%d ssid: %32s\n", i, pscantable->ssid.ssid);
1595
1596 cfp =
1597 libertas_find_cfp_by_band_and_channel(adapter, 0,
1598 pscantable->channel);
1599 if (!cfp) {
1600 lbs_pr_debug(1, "Invalid channel number %d\n",
1601 pscantable->channel);
1602 continue;
1603 }
1604
1605 if (!ssid_valid(&adapter->scantable[i].ssid)) {
1606 continue;
1607 }
1608
1609 /* First entry *MUST* be the AP MAC address */
1610 iwe.cmd = SIOCGIWAP;
1611 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1612 memcpy(iwe.u.ap_addr.sa_data,
1613 &adapter->scantable[i].macaddress, ETH_ALEN);
1614
1615 iwe.len = IW_EV_ADDR_LEN;
1616 current_ev =
1617 iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
1618
1619 //Add the ESSID
1620 iwe.u.data.length = adapter->scantable[i].ssid.ssidlength;
1621
1622 if (iwe.u.data.length > 32) {
1623 iwe.u.data.length = 32;
1624 }
1625
1626 iwe.cmd = SIOCGIWESSID;
1627 iwe.u.data.flags = 1;
1628 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1629 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1630 adapter->scantable[i].ssid.
1631 ssid);
1632
1633 //Add mode
1634 iwe.cmd = SIOCGIWMODE;
1635 iwe.u.mode = adapter->scantable[i].inframode + 1;
1636 iwe.len = IW_EV_UINT_LEN;
1637 current_ev =
1638 iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
1639
1640 //frequency
1641 iwe.cmd = SIOCGIWFREQ;
1642 iwe.u.freq.m = (long)cfp->freq * 100000;
1643 iwe.u.freq.e = 1;
1644 iwe.len = IW_EV_FREQ_LEN;
1645 current_ev =
1646 iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
1647
1648 /* Add quality statistics */
1649 iwe.cmd = IWEVQUAL;
1650 iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
1651 iwe.u.qual.level = SCAN_RSSI(adapter->scantable[i].rssi);
1652
1653 rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
1654 iwe.u.qual.qual =
1655 (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) *
1656 (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) /
1657 (RSSI_DIFF * RSSI_DIFF);
1658 if (iwe.u.qual.qual > 100)
1659 iwe.u.qual.qual = 100;
1660 else if (iwe.u.qual.qual < 1)
1661 iwe.u.qual.qual = 0;
1662
1663 if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
1664 iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
1665 } else {
1666 iwe.u.qual.noise =
1667 CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
1668 }
1669 if ((adapter->inframode == wlan802_11ibss) &&
1670 !libertas_SSID_cmp(&adapter->curbssparams.ssid,
1671 &adapter->scantable[i].ssid)
1672 && adapter->adhoccreate) {
1673 ret = libertas_prepare_and_send_command(priv,
1674 cmd_802_11_rssi,
1675 0,
1676 cmd_option_waitforrsp,
1677 0, NULL);
1678
1679 if (!ret) {
1680 iwe.u.qual.level =
1681 CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] /
1682 AVG_SCALE,
1683 adapter->NF[TYPE_RXPD][TYPE_AVG] /
1684 AVG_SCALE);
1685 }
1686 }
1687 iwe.len = IW_EV_QUAL_LEN;
1688 current_ev =
1689 iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
1690
1691 /* Add encryption capability */
1692 iwe.cmd = SIOCGIWENCODE;
1693 if (adapter->scantable[i].privacy) {
1694 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1695 } else {
1696 iwe.u.data.flags = IW_ENCODE_DISABLED;
1697 }
1698 iwe.u.data.length = 0;
1699 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1700 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1701 adapter->scantable->ssid.
1702 ssid);
1703
1704 current_val = current_ev + IW_EV_LCP_LEN;
1705
1706 iwe.cmd = SIOCGIWRATE;
1707
1708 iwe.u.bitrate.fixed = 0;
1709 iwe.u.bitrate.disabled = 0;
1710 iwe.u.bitrate.value = 0;
1711
1712 /* Bit rate given in 500 kb/s units (+ 0x80) */
1713 for (j = 0; j < sizeof(adapter->scantable[i].libertas_supported_rates);
1714 j++) {
1715 if (adapter->scantable[i].libertas_supported_rates[j] == 0) {
1716 break;
1717 }
1718 rate =
1719 (adapter->scantable[i].libertas_supported_rates[j] & 0x7F) *
1720 500000;
1721 if (rate > iwe.u.bitrate.value) {
1722 iwe.u.bitrate.value = rate;
1723 }
1724
1725 iwe.u.bitrate.value =
1726 (adapter->scantable[i].libertas_supported_rates[j]
1727 & 0x7f) * 500000;
1728 iwe.len = IW_EV_PARAM_LEN;
1729 current_ev =
1730 iwe_stream_add_value(current_ev, current_val,
1731 end_buf, &iwe, iwe.len);
1732
1733 }
1734 if ((adapter->scantable[i].inframode == wlan802_11ibss)
1735 && !libertas_SSID_cmp(&adapter->curbssparams.ssid,
1736 &adapter->scantable[i].ssid)
1737 && adapter->adhoccreate) {
1738 iwe.u.bitrate.value = 22 * 500000;
1739 }
1740 iwe.len = IW_EV_PARAM_LEN;
1741 current_ev =
1742 iwe_stream_add_value(current_ev, current_val, end_buf, &iwe,
1743 iwe.len);
1744
1745 /* Add new value to event */
1746 current_val = current_ev + IW_EV_LCP_LEN;
1747
1748 if (adapter->scantable[i].wpa2_supplicant.wpa_ie[0] == WPA2_IE) {
1749 memset(&iwe, 0, sizeof(iwe));
1750 memset(buf, 0, sizeof(buf));
1751 memcpy(buf, adapter->scantable[i].
1752 wpa2_supplicant.wpa_ie,
1753 adapter->scantable[i].wpa2_supplicant.
1754 wpa_ie_len);
1755 iwe.cmd = IWEVGENIE;
1756 iwe.u.data.length = adapter->scantable[i].
1757 wpa2_supplicant.wpa_ie_len;
1758 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1759 current_ev = iwe_stream_add_point(current_ev, end_buf,
1760 &iwe, buf);
1761 }
1762 if (adapter->scantable[i].wpa_supplicant.wpa_ie[0] == WPA_IE) {
1763 memset(&iwe, 0, sizeof(iwe));
1764 memset(buf, 0, sizeof(buf));
1765 memcpy(buf, adapter->scantable[i].
1766 wpa_supplicant.wpa_ie,
1767 adapter->scantable[i].wpa_supplicant.
1768 wpa_ie_len);
1769 iwe.cmd = IWEVGENIE;
1770 iwe.u.data.length = adapter->scantable[i].
1771 wpa_supplicant.wpa_ie_len;
1772 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1773 current_ev = iwe_stream_add_point(current_ev, end_buf,
1774 &iwe, buf);
1775 }
1776
1777
1778 if (adapter->scantable[i].extra_ie != 0) {
1779 memset(&iwe, 0, sizeof(iwe));
1780 memset(buf, 0, sizeof(buf));
1781 ptr = buf;
1782 ptr += sprintf(ptr, "extra_ie");
1783 iwe.u.data.length = strlen(buf);
1784
1785 lbs_pr_debug(1, "iwe.u.data.length %d\n",
1786 iwe.u.data.length);
1787 lbs_pr_debug(1, "BUF: %s \n", buf);
1788
1789 iwe.cmd = IWEVCUSTOM;
1790 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1791 current_ev =
1792 iwe_stream_add_point(current_ev, end_buf, &iwe,
1793 buf);
1794 }
1795
1796 current_val = current_ev + IW_EV_LCP_LEN;
1797
1798 /*
1799 * Check if we added any event
1800 */
1801 if ((current_val - current_ev) > IW_EV_LCP_LEN)
1802 current_ev = current_val;
1803 }
1804
1805 dwrq->length = (current_ev - extra);
1806 dwrq->flags = 0;
1807
1808 LEAVE();
1809 return 0;
1810}
1811
1812/**
1813 * @brief Prepare a scan command to be sent to the firmware
1814 *
1815 * Use the wlan_scan_cmd_config sent to the command processing module in
1816 * the libertas_prepare_and_send_command to configure a cmd_ds_802_11_scan command
1817 * struct to send to firmware.
1818 *
1819 * The fixed fields specifying the BSS type and BSSID filters as well as a
1820 * variable number/length of TLVs are sent in the command to firmware.
1821 *
1822 * @param priv A pointer to wlan_private structure
1823 * @param cmd A pointer to cmd_ds_command structure to be sent to
1824 * firmware with the cmd_DS_801_11_SCAN structure
1825 * @param pdata_buf Void pointer cast of a wlan_scan_cmd_config struct used
1826 * to set the fields/TLVs for the command sent to firmware
1827 *
1828 * @return 0 or -1
1829 *
1830 * @sa wlan_scan_create_channel_list
1831 */
1832int libertas_cmd_80211_scan(wlan_private * priv,
1833 struct cmd_ds_command *cmd, void *pdata_buf)
1834{
1835 struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
1836 struct wlan_scan_cmd_config *pscancfg;
1837
1838 ENTER();
1839
1840 pscancfg = pdata_buf;
1841
1842 /* Set fixed field variables in scan command */
1843 pscan->bsstype = pscancfg->bsstype;
1844 memcpy(pscan->BSSID, pscancfg->specificBSSID, sizeof(pscan->BSSID));
1845 memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
1846
1847 cmd->command = cpu_to_le16(cmd_802_11_scan);
1848
1849 /* size is equal to the sizeof(fixed portions) + the TLV len + header */
1850 cmd->size = cpu_to_le16(sizeof(pscan->bsstype)
1851 + sizeof(pscan->BSSID)
1852 + pscancfg->tlvbufferlen + S_DS_GEN);
1853
1854 lbs_pr_debug(1, "SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
1855 cmd->command, cmd->size, cmd->seqnum);
1856 LEAVE();
1857 return 0;
1858}
1859
1860/**
1861 * @brief This function handles the command response of scan
1862 *
1863 * The response buffer for the scan command has the following
1864 * memory layout:
1865 *
1866 * .-----------------------------------------------------------.
1867 * | header (4 * sizeof(u16)): Standard command response hdr |
1868 * .-----------------------------------------------------------.
1869 * | bufsize (u16) : sizeof the BSS Description data |
1870 * .-----------------------------------------------------------.
1871 * | NumOfSet (u8) : Number of BSS Descs returned |
1872 * .-----------------------------------------------------------.
1873 * | BSSDescription data (variable, size given in bufsize) |
1874 * .-----------------------------------------------------------.
1875 * | TLV data (variable, size calculated using header->size, |
1876 * | bufsize and sizeof the fixed fields above) |
1877 * .-----------------------------------------------------------.
1878 *
1879 * @param priv A pointer to wlan_private structure
1880 * @param resp A pointer to cmd_ds_command
1881 *
1882 * @return 0 or -1
1883 */
1884int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
1885{
1886 wlan_adapter *adapter = priv->adapter;
1887 struct cmd_ds_802_11_scan_rsp *pscan;
1888 struct bss_descriptor newbssentry;
1889 struct mrvlietypes_data *ptlv;
1890 struct mrvlietypes_tsftimestamp *ptsftlv;
1891 u8 *pbssinfo;
1892 u16 scanrespsize;
1893 int bytesleft;
1894 int numintable;
1895 int bssIdx;
1896 int idx;
1897 int tlvbufsize;
1898 u64 tsfval;
1899
1900 ENTER();
1901
1902 pscan = &resp->params.scanresp;
1903
1904 if (pscan->nr_sets > MRVDRV_MAX_BSSID_LIST) {
1905 lbs_pr_debug(1,
1906 "SCAN_RESP: Invalid number of AP returned (%d)!!\n",
1907 pscan->nr_sets);
1908 LEAVE();
1909 return -1;
1910 }
1911
1912 bytesleft = le16_to_cpu(pscan->bssdescriptsize);
1913 lbs_pr_debug(1, "SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1914
1915 scanrespsize = le16_to_cpu(resp->size);
1916 lbs_pr_debug(1, "SCAN_RESP: returned %d AP before parsing\n",
1917 pscan->nr_sets);
1918
1919 numintable = adapter->numinscantable;
1920 pbssinfo = pscan->bssdesc_and_tlvbuffer;
1921
1922 /* The size of the TLV buffer is equal to the entire command response
1923 * size (scanrespsize) minus the fixed fields (sizeof()'s), the
1924 * BSS Descriptions (bssdescriptsize as bytesLef) and the command
1925 * response header (S_DS_GEN)
1926 */
1927 tlvbufsize = scanrespsize - (bytesleft + sizeof(pscan->bssdescriptsize)
1928 + sizeof(pscan->nr_sets)
1929 + S_DS_GEN);
1930
1931 ptlv = (struct mrvlietypes_data *) (pscan->bssdesc_and_tlvbuffer + bytesleft);
1932
1933 /* Search the TLV buffer space in the scan response for any valid TLVs */
1934 wlan_ret_802_11_scan_get_tlv_ptrs(ptlv, tlvbufsize, &ptsftlv);
1935
1936 /*
1937 * Process each scan response returned (pscan->nr_sets). Save
1938 * the information in the newbssentry and then insert into the
1939 * driver scan table either as an update to an existing entry
1940 * or as an addition at the end of the table
1941 */
1942 for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) {
1943 /* Zero out the newbssentry we are about to store info in */
1944 memset(&newbssentry, 0x00, sizeof(newbssentry));
1945
1946 /* Process the data fields and IEs returned for this BSS */
1947 if ((InterpretBSSDescriptionWithIE(&newbssentry,
1948 &pbssinfo,
1949 &bytesleft) ==
1950 0)
1951 && CHECK_SSID_IS_VALID(&newbssentry.ssid)) {
1952
1953 lbs_pr_debug(1,
1954 "SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
1955 newbssentry.macaddress[0],
1956 newbssentry.macaddress[1],
1957 newbssentry.macaddress[2],
1958 newbssentry.macaddress[3],
1959 newbssentry.macaddress[4],
1960 newbssentry.macaddress[5]);
1961
1962 /*
1963 * Search the scan table for the same bssid
1964 */
1965 for (bssIdx = 0; bssIdx < numintable; bssIdx++) {
1966 if (memcmp(newbssentry.macaddress,
1967 adapter->scantable[bssIdx].
1968 macaddress,
1969 sizeof(newbssentry.macaddress)) ==
1970 0) {
1971 /*
1972 * If the SSID matches as well, it is a duplicate of
1973 * this entry. Keep the bssIdx set to this
1974 * entry so we replace the old contents in the table
1975 */
1976 if ((newbssentry.ssid.ssidlength ==
1977 adapter->scantable[bssIdx].ssid.
1978 ssidlength)
1979 &&
1980 (memcmp
1981 (newbssentry.ssid.ssid,
1982 adapter->scantable[bssIdx].ssid.
1983 ssid,
1984 newbssentry.ssid.ssidlength) ==
1985 0)) {
1986 lbs_pr_debug(1,
1987 "SCAN_RESP: Duplicate of index: %d\n",
1988 bssIdx);
1989 break;
1990 }
1991 }
1992 }
1993 /*
1994 * If the bssIdx is equal to the number of entries in the table,
1995 * the new entry was not a duplicate; append it to the scan
1996 * table
1997 */
1998 if (bssIdx == numintable) {
1999 /* Range check the bssIdx, keep it limited to the last entry */
2000 if (bssIdx == MRVDRV_MAX_BSSID_LIST) {
2001 bssIdx--;
2002 } else {
2003 numintable++;
2004 }
2005 }
2006
2007 /*
2008 * If the TSF TLV was appended to the scan results, save the
2009 * this entries TSF value in the networktsf field. The
2010 * networktsf is the firmware's TSF value at the time the
2011 * beacon or probe response was received.
2012 */
2013 if (ptsftlv) {
2014 memcpy(&tsfval, &ptsftlv->tsftable[idx],
2015 sizeof(tsfval));
2016 tsfval = le64_to_cpu(tsfval);
2017
2018 memcpy(&newbssentry.networktsf,
2019 &tsfval, sizeof(newbssentry.networktsf));
2020 }
2021
2022 /* Copy the locally created newbssentry to the scan table */
2023 memcpy(&adapter->scantable[bssIdx],
2024 &newbssentry,
2025 sizeof(adapter->scantable[bssIdx]));
2026
2027 } else {
2028
2029 /* error parsing/interpreting the scan response, skipped */
2030 lbs_pr_debug(1, "SCAN_RESP: "
2031 "InterpretBSSDescriptionWithIE returned ERROR\n");
2032 }
2033 }
2034
2035 lbs_pr_debug(1, "SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
2036 pscan->nr_sets, numintable - adapter->numinscantable,
2037 numintable);
2038
2039 /* Update the total number of BSSIDs in the scan table */
2040 adapter->numinscantable = numintable;
2041
2042 LEAVE();
2043 return 0;
2044}
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
new file mode 100644
index 000000000000..d93aa7fa44fd
--- /dev/null
+++ b/drivers/net/wireless/libertas/scan.h
@@ -0,0 +1,216 @@
1/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
2/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
3
4/**
5 * Interface for the wlan network scan routines
6 *
7 * Driver interface functions and type declarations for the scan module
8 * implemented in wlan_scan.c.
9 */
10#ifndef _WLAN_SCAN_H
11#define _WLAN_SCAN_H
12
13#include "hostcmd.h"
14
15/**
16 * @brief Maximum number of channels that can be sent in a setuserscan ioctl
17 *
18 * @sa wlan_ioctl_user_scan_cfg
19 */
20#define WLAN_IOCTL_USER_SCAN_CHAN_MAX 50
21
22//! Infrastructure BSS scan type in wlan_scan_cmd_config
23#define WLAN_SCAN_BSS_TYPE_BSS 1
24
25//! Adhoc BSS scan type in wlan_scan_cmd_config
26#define WLAN_SCAN_BSS_TYPE_IBSS 2
27
28//! Adhoc or Infrastructure BSS scan type in wlan_scan_cmd_config, no filter
29#define WLAN_SCAN_BSS_TYPE_ANY 3
30
31/**
32 * @brief Structure used internally in the wlan driver to configure a scan.
33 *
34 * Sent to the command processing module to configure the firmware
35 * scan command prepared by libertas_cmd_80211_scan.
36 *
37 * @sa wlan_scan_networks
38 *
39 */
40struct wlan_scan_cmd_config {
41 /**
42 * @brief BSS type to be sent in the firmware command
43 *
44 * Field can be used to restrict the types of networks returned in the
45 * scan. valid settings are:
46 *
47 * - WLAN_SCAN_BSS_TYPE_BSS (infrastructure)
48 * - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
49 * - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
50 */
51 u8 bsstype;
52
53 /**
54 * @brief Specific BSSID used to filter scan results in the firmware
55 */
56 u8 specificBSSID[ETH_ALEN];
57
58 /**
59 * @brief length of TLVs sent in command starting at tlvBuffer
60 */
61 int tlvbufferlen;
62
63 /**
64 * @brief SSID TLV(s) and ChanList TLVs to be sent in the firmware command
65 *
66 * @sa TLV_TYPE_CHANLIST, mrvlietypes_chanlistparamset_t
67 * @sa TLV_TYPE_SSID, mrvlietypes_ssidparamset_t
68 */
69 u8 tlvbuffer[1]; //!< SSID TLV(s) and ChanList TLVs are stored here
70};
71
72/**
73 * @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg
74 *
75 * Multiple instances of this structure are included in the IOCTL command
76 * to configure a instance of a scan on the specific channel.
77 */
78struct wlan_ioctl_user_scan_chan {
79 u8 channumber; //!< channel Number to scan
80 u8 radiotype; //!< Radio type: 'B/G' band = 0, 'A' band = 1
81 u8 scantype; //!< Scan type: Active = 0, Passive = 1
82 u16 scantime; //!< Scan duration in milliseconds; if 0 default used
83};
84
85/**
86 * @brief IOCTL input structure to configure an immediate scan cmd to firmware
87 *
88 * Used in the setuserscan (WLAN_SET_USER_SCAN) private ioctl. Specifies
89 * a number of parameters to be used in general for the scan as well
90 * as a channel list (wlan_ioctl_user_scan_chan) for each scan period
91 * desired.
92 *
93 * @sa libertas_set_user_scan_ioctl
94 */
95struct wlan_ioctl_user_scan_cfg {
96
97 /**
98 * @brief Flag set to keep the previous scan table intact
99 *
100 * If set, the scan results will accumulate, replacing any previous
101 * matched entries for a BSS with the new scan data
102 */
103 u8 keeppreviousscan; //!< Do not erase the existing scan results
104
105 /**
106 * @brief BSS type to be sent in the firmware command
107 *
108 * Field can be used to restrict the types of networks returned in the
109 * scan. valid settings are:
110 *
111 * - WLAN_SCAN_BSS_TYPE_BSS (infrastructure)
112 * - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
113 * - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
114 */
115 u8 bsstype;
116
117 /**
118 * @brief Configure the number of probe requests for active chan scans
119 */
120 u8 numprobes;
121
122 /**
123 * @brief BSSID filter sent in the firmware command to limit the results
124 */
125 u8 specificBSSID[ETH_ALEN];
126
127 /**
128 * @brief SSID filter sent in the firmware command to limit the results
129 */
130 char specificSSID[IW_ESSID_MAX_SIZE + 1];
131
132 /**
133 * @brief Variable number (fixed maximum) of channels to scan up
134 */
135 struct wlan_ioctl_user_scan_chan chanlist[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
136};
137
138/**
139 * @brief Structure used to store information for each beacon/probe response
140 */
141struct bss_descriptor {
142 u8 macaddress[ETH_ALEN];
143
144 struct WLAN_802_11_SSID ssid;
145
146 /* WEP encryption requirement */
147 u32 privacy;
148
149 /* receive signal strength in dBm */
150 long rssi;
151
152 u32 channel;
153
154 u16 beaconperiod;
155
156 u32 atimwindow;
157
158 enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
159 u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
160
161 int extra_ie;
162
163 u8 timestamp[8]; //!< TSF value included in the beacon/probe response
164 union ieeetypes_phyparamset phyparamset;
165 union IEEEtypes_ssparamset ssparamset;
166 struct ieeetypes_capinfo cap;
167 u8 datarates[WLAN_SUPPORTED_RATES];
168
169 __le64 networktsf; //!< TSF timestamp from the current firmware TSF
170
171 struct ieeetypes_countryinfofullset countryinfo;
172
173 struct WPA_SUPPLICANT wpa_supplicant;
174 struct WPA_SUPPLICANT wpa2_supplicant;
175
176};
177
178extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
179 struct WLAN_802_11_SSID *ssid2);
180extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
181 u8 * bssid, int mode);
182int libertas_find_best_SSID_in_list(wlan_adapter * adapter, enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode);
183extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode);
184
185int libertas_find_best_network_SSID(wlan_private * priv,
186 struct WLAN_802_11_SSID *pSSID,
187 enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
188 enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode);
189
190extern int libertas_send_specific_SSID_scan(wlan_private * priv,
191 struct WLAN_802_11_SSID *prequestedssid,
192 u8 keeppreviousscan);
193extern int libertas_send_specific_BSSID_scan(wlan_private * priv,
194 u8 * bssid, u8 keeppreviousscan);
195
196extern int libertas_cmd_80211_scan(wlan_private * priv,
197 struct cmd_ds_command *cmd,
198 void *pdata_buf);
199
200extern int libertas_ret_80211_scan(wlan_private * priv,
201 struct cmd_ds_command *resp);
202
203int wlan_scan_networks(wlan_private * priv,
204 const struct wlan_ioctl_user_scan_cfg * puserscanin);
205
206struct ifreq;
207
208struct iw_point;
209struct iw_param;
210struct iw_request_info;
211extern int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
212 struct iw_point *dwrq, char *extra);
213extern int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
214 struct iw_param *vwrq, char *extra);
215
216#endif /* _WLAN_SCAN_H */
diff --git a/drivers/net/wireless/libertas/thread.h b/drivers/net/wireless/libertas/thread.h
new file mode 100644
index 000000000000..207b8a6cc33d
--- /dev/null
+++ b/drivers/net/wireless/libertas/thread.h
@@ -0,0 +1,52 @@
1#ifndef __WLAN_THREAD_H_
2#define __WLAN_THREAD_H_
3
4#include <linux/kthread.h>
5
6struct wlan_thread {
7 struct task_struct *task;
8 wait_queue_head_t waitq;
9 pid_t pid;
10 void *priv;
11};
12
13static inline void wlan_activate_thread(struct wlan_thread * thr)
14{
15 /** Record the thread pid */
16 thr->pid = current->pid;
17
18 /** Initialize the wait queue */
19 init_waitqueue_head(&thr->waitq);
20}
21
22static inline void wlan_deactivate_thread(struct wlan_thread * thr)
23{
24 ENTER();
25
26 thr->pid = 0;
27
28 LEAVE();
29}
30
31static inline void wlan_create_thread(int (*wlanfunc) (void *),
32 struct wlan_thread * thr, char *name)
33{
34 thr->task = kthread_run(wlanfunc, thr, "%s", name);
35}
36
37static inline int wlan_terminate_thread(struct wlan_thread * thr)
38{
39 ENTER();
40
41 /* Check if the thread is active or not */
42 if (!thr->pid) {
43 printk(KERN_ERR "Thread does not exist\n");
44 return -1;
45 }
46 kthread_stop(thr->task);
47
48 LEAVE();
49 return 0;
50}
51
52#endif
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
new file mode 100644
index 000000000000..82d06223043e
--- /dev/null
+++ b/drivers/net/wireless/libertas/tx.c
@@ -0,0 +1,285 @@
1/**
2 * This file contains the handling of TX in wlan driver.
3 */
4#include <linux/netdevice.h>
5
6#include "hostcmd.h"
7#include "radiotap.h"
8#include "sbi.h"
9#include "decl.h"
10#include "defs.h"
11#include "dev.h"
12#include "wext.h"
13
14/**
15 * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
16 * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
17 *
18 * @param rate Input rate
19 * @return Output Rate (0 if invalid)
20 */
21static u32 convert_radiotap_rate_to_mv(u8 rate)
22{
23 switch (rate) {
24 case 2: /* 1 Mbps */
25 return 0 | (1 << 4);
26 case 4: /* 2 Mbps */
27 return 1 | (1 << 4);
28 case 11: /* 5.5 Mbps */
29 return 2 | (1 << 4);
30 case 22: /* 11 Mbps */
31 return 3 | (1 << 4);
32 case 12: /* 6 Mbps */
33 return 4 | (1 << 4);
34 case 18: /* 9 Mbps */
35 return 5 | (1 << 4);
36 case 24: /* 12 Mbps */
37 return 6 | (1 << 4);
38 case 36: /* 18 Mbps */
39 return 7 | (1 << 4);
40 case 48: /* 24 Mbps */
41 return 8 | (1 << 4);
42 case 72: /* 36 Mbps */
43 return 9 | (1 << 4);
44 case 96: /* 48 Mbps */
45 return 10 | (1 << 4);
46 case 108: /* 54 Mbps */
47 return 11 | (1 << 4);
48 }
49 return 0;
50}
51
52/**
53 * @brief This function processes a single packet and sends
54 * to IF layer
55 *
56 * @param priv A pointer to wlan_private structure
57 * @param skb A pointer to skb which includes TX packet
58 * @return 0 or -1
59 */
60static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
61{
62 wlan_adapter *adapter = priv->adapter;
63 int ret = 0;
64 struct txpd localtxpd;
65 struct txpd *plocaltxpd = &localtxpd;
66 u8 *p802x_hdr;
67 struct tx_radiotap_hdr *pradiotap_hdr;
68 u32 new_rate;
69 u8 *ptr = priv->adapter->tmptxbuf;
70
71 ENTER();
72
73 if (priv->adapter->surpriseremoved)
74 return -1;
75
76 if ((priv->adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0)
77 lbs_dbg_hex("TX packet: ", skb->data,
78 min_t(unsigned int, skb->len, 100));
79
80 if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
81 lbs_pr_debug(1, "Tx error: Bad skb length %d : %d\n",
82 skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
83 ret = -1;
84 goto done;
85 }
86
87 memset(plocaltxpd, 0, sizeof(struct txpd));
88
89 plocaltxpd->tx_packet_length = skb->len;
90
91 /* offset of actual data */
92 plocaltxpd->tx_packet_location = sizeof(struct txpd);
93
94 /* TxCtrl set by user or default */
95 plocaltxpd->tx_control = adapter->pkttxctrl;
96
97 p802x_hdr = skb->data;
98 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
99
100 /* locate radiotap header */
101 pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data;
102
103 /* set txpd fields from the radiotap header */
104 new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
105 if (new_rate != 0) {
106 /* erase tx_control[4:0] */
107 plocaltxpd->tx_control &= ~0x1f;
108 /* write new tx_control[4:0] */
109 plocaltxpd->tx_control |= new_rate;
110 }
111
112 /* skip the radiotap header */
113 p802x_hdr += sizeof(struct tx_radiotap_hdr);
114 plocaltxpd->tx_packet_length -= sizeof(struct tx_radiotap_hdr);
115
116 }
117 /* copy destination address from 802.3 or 802.11 header */
118 if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
119 memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
120 else
121 memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
122
123 lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
124
125 if (IS_MESH_FRAME(skb)) {
126 plocaltxpd->tx_control |= TxPD_MESH_FRAME;
127 }
128
129 memcpy(ptr, plocaltxpd, sizeof(struct txpd));
130
131 ptr += sizeof(struct txpd);
132
133 lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, plocaltxpd->tx_packet_length);
134 memcpy(ptr, p802x_hdr, plocaltxpd->tx_packet_length);
135 ret = libertas_sbi_host_to_card(priv, MVMS_DAT,
136 priv->adapter->tmptxbuf,
137 plocaltxpd->tx_packet_length +
138 sizeof(struct txpd));
139
140 if (ret) {
141 lbs_pr_debug(1, "Tx error: libertas_sbi_host_to_card failed: 0x%X\n", ret);
142 goto done;
143 }
144
145 lbs_pr_debug(1, "SendSinglePacket succeeds\n");
146
147 done:
148 if (!ret) {
149 priv->stats.tx_packets++;
150 priv->stats.tx_bytes += skb->len;
151 } else {
152 priv->stats.tx_dropped++;
153 priv->stats.tx_errors++;
154 }
155
156 if (!ret && priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
157 /* Keep the skb to echo it back once Tx feedback is
158 received from FW */
159 skb_orphan(skb);
160 /* stop processing outgoing pkts */
161 netif_stop_queue(priv->wlan_dev.netdev);
162 /* freeze any packets already in our queues */
163 priv->adapter->TxLockFlag = 1;
164 } else {
165 dev_kfree_skb_any(skb);
166 priv->adapter->currenttxskb = NULL;
167 }
168
169 LEAVE();
170 return ret;
171}
172
173
174void libertas_tx_runqueue(wlan_private *priv)
175{
176 wlan_adapter *adapter = priv->adapter;
177 int i;
178
179 spin_lock(&adapter->txqueue_lock);
180 for (i = 0; i < adapter->tx_queue_idx; i++) {
181 struct sk_buff *skb = adapter->tx_queue_ps[i];
182 spin_unlock(&adapter->txqueue_lock);
183 SendSinglePacket(priv, skb);
184 spin_lock(&adapter->txqueue_lock);
185 }
186 adapter->tx_queue_idx = 0;
187 spin_unlock(&adapter->txqueue_lock);
188}
189
190static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
191{
192 wlan_adapter *adapter = priv->adapter;
193
194 spin_lock(&adapter->txqueue_lock);
195
196 WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
197 adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
198 if (adapter->tx_queue_idx == NR_TX_QUEUE)
199 netif_stop_queue(priv->wlan_dev.netdev);
200 else
201 netif_start_queue(priv->wlan_dev.netdev);
202
203 spin_unlock(&adapter->txqueue_lock);
204}
205
206/**
207 * @brief This function checks the conditions and sends packet to IF
208 * layer if everything is ok.
209 *
210 * @param priv A pointer to wlan_private structure
211 * @return n/a
212 */
213int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
214{
215 int ret = -1;
216
217 ENTER();
218
219 lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100));
220
221 if (priv->wlan_dev.dnld_sent) {
222 lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
223 priv->wlan_dev.dnld_sent);
224 goto done;
225 }
226
227 if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
228 (priv->adapter->psstate == PS_STATE_PRE_SLEEP)) {
229 wlan_tx_queue(priv, skb);
230 return ret;
231 }
232
233 priv->adapter->currenttxskb = skb;
234
235 ret = SendSinglePacket(priv, skb);
236done:
237 LEAVE();
238 return ret;
239}
240
241/**
242 * @brief This function sends to the host the last transmitted packet,
243 * filling the radiotap headers with transmission information.
244 *
245 * @param priv A pointer to wlan_private structure
246 * @param status A 32 bit value containing transmission status.
247 *
248 * @returns void
249 */
250void libertas_send_tx_feedback(wlan_private * priv)
251{
252 wlan_adapter *adapter = priv->adapter;
253 struct tx_radiotap_hdr *radiotap_hdr;
254 u32 status = adapter->eventcause;
255 int txfail;
256 int try_count;
257
258 if (adapter->radiomode != WLAN_RADIOMODE_RADIOTAP ||
259 adapter->currenttxskb == NULL)
260 return;
261
262 radiotap_hdr = (struct tx_radiotap_hdr *)adapter->currenttxskb->data;
263
264 if ((adapter->debugmode & MRVDRV_DEBUG_TX_PATH) != 0)
265 lbs_dbg_hex("TX feedback: ", (u8 *) radiotap_hdr,
266 min_t(unsigned int, adapter->currenttxskb->len, 100));
267
268 txfail = (status >> 24);
269
270#if 0
271 /* The version of roofnet that we've tested does not use this yet
272 * But it may be used in the future.
273 */
274 if (txfail)
275 radiotap_hdr->flags &= IEEE80211_RADIOTAP_F_TX_FAIL;
276#endif
277 try_count = (status >> 16) & 0xff;
278 radiotap_hdr->data_retries = (try_count) ?
279 (1 + adapter->txretrycount - try_count) : 0;
280 libertas_upload_rx_packet(priv, adapter->currenttxskb);
281 adapter->currenttxskb = NULL;
282 priv->adapter->TxLockFlag = 0;
283 if (priv->adapter->connect_status == libertas_connected)
284 netif_wake_queue(priv->wlan_dev.netdev);
285}
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
new file mode 100644
index 000000000000..09d62f8b1a16
--- /dev/null
+++ b/drivers/net/wireless/libertas/types.h
@@ -0,0 +1,289 @@
1/**
2 * This header file contains definition for global types
3 */
4#ifndef _WLAN_TYPES_
5#define _WLAN_TYPES_
6
7#include <linux/if_ether.h>
8
9/** IEEE type definitions */
10enum ieeetypes_elementid {
11 SSID = 0,
12 SUPPORTED_RATES,
13 FH_PARAM_SET,
14 DS_PARAM_SET,
15 CF_PARAM_SET,
16 TIM,
17 IBSS_PARAM_SET,
18 COUNTRY_INFO = 7,
19
20 CHALLENGE_TEXT = 16,
21
22 EXTENDED_SUPPORTED_RATES = 50,
23
24 VENDOR_SPECIFIC_221 = 221,
25
26 WPA_IE = 221,
27 WPA2_IE = 48,
28
29 EXTRA_IE = 133,
30} __attribute__ ((packed));
31
32#define CAPINFO_MASK (~(0xda00))
33
34struct ieeetypes_capinfo {
35 u8 ess:1;
36 u8 ibss:1;
37 u8 cfpollable:1;
38 u8 cfpollrqst:1;
39 u8 privacy:1;
40 u8 shortpreamble:1;
41 u8 pbcc:1;
42 u8 chanagility:1;
43 u8 spectrummgmt:1;
44 u8 rsrvd3:1;
45 u8 shortslottime:1;
46 u8 apsd:1;
47 u8 rsvrd2:1;
48 u8 dsssofdm:1;
49 u8 rsrvd1:2;
50} __attribute__ ((packed));
51
52struct ieeetypes_cfparamset {
53 u8 elementid;
54 u8 len;
55 u8 cfpcnt;
56 u8 cfpperiod;
57 u16 cfpmaxduration;
58 u16 cfpdurationremaining;
59} __attribute__ ((packed));
60
61
62struct ieeetypes_ibssparamset {
63 u8 elementid;
64 u8 len;
65 u16 atimwindow;
66} __attribute__ ((packed));
67
68union IEEEtypes_ssparamset {
69 struct ieeetypes_cfparamset cfparamset;
70 struct ieeetypes_ibssparamset ibssparamset;
71} __attribute__ ((packed));
72
73struct ieeetypes_fhparamset {
74 u8 elementid;
75 u8 len;
76 u16 dwelltime;
77 u8 hopset;
78 u8 hoppattern;
79 u8 hopindex;
80} __attribute__ ((packed));
81
82struct ieeetypes_dsparamset {
83 u8 elementid;
84 u8 len;
85 u8 currentchan;
86} __attribute__ ((packed));
87
88union ieeetypes_phyparamset {
89 struct ieeetypes_fhparamset fhparamset;
90 struct ieeetypes_dsparamset dsparamset;
91} __attribute__ ((packed));
92
93struct ieeetypes_assocrsp {
94 struct ieeetypes_capinfo capability;
95 u16 statuscode;
96 u16 aid;
97 u8 iebuffer[1];
98} __attribute__ ((packed));
99
100/** TLV type ID definition */
101#define PROPRIETARY_TLV_BASE_ID 0x0100
102
103/* Terminating TLV type */
104#define MRVL_TERMINATE_TLV_ID 0xffff
105
106#define TLV_TYPE_SSID 0x0000
107#define TLV_TYPE_RATES 0x0001
108#define TLV_TYPE_PHY_FH 0x0002
109#define TLV_TYPE_PHY_DS 0x0003
110#define TLV_TYPE_CF 0x0004
111#define TLV_TYPE_IBSS 0x0006
112
113#define TLV_TYPE_DOMAIN 0x0007
114
115#define TLV_TYPE_POWER_CAPABILITY 0x0021
116
117#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
118#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
119#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2)
120#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 4)
121#define TLV_TYPE_SNR_LOW (PROPRIETARY_TLV_BASE_ID + 5)
122#define TLV_TYPE_FAILCOUNT (PROPRIETARY_TLV_BASE_ID + 6)
123#define TLV_TYPE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 7)
124#define TLV_TYPE_LED_GPIO (PROPRIETARY_TLV_BASE_ID + 8)
125#define TLV_TYPE_LEDBEHAVIOR (PROPRIETARY_TLV_BASE_ID + 9)
126#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10)
127#define TLV_TYPE_REASSOCAP (PROPRIETARY_TLV_BASE_ID + 11)
128#define TLV_TYPE_POWER_TBL_2_4GHZ (PROPRIETARY_TLV_BASE_ID + 12)
129#define TLV_TYPE_POWER_TBL_5GHZ (PROPRIETARY_TLV_BASE_ID + 13)
130#define TLV_TYPE_BCASTPROBE (PROPRIETARY_TLV_BASE_ID + 14)
131#define TLV_TYPE_NUMSSID_PROBE (PROPRIETARY_TLV_BASE_ID + 15)
132#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16)
133#define TLV_TYPE_CRYPTO_DATA (PROPRIETARY_TLV_BASE_ID + 17)
134#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18)
135#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
136#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
137#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
138
139/** TLV related data structures*/
140struct mrvlietypesheader {
141 u16 type;
142 u16 len;
143} __attribute__ ((packed));
144
145struct mrvlietypes_data {
146 struct mrvlietypesheader header;
147 u8 Data[1];
148} __attribute__ ((packed));
149
150struct mrvlietypes_ratesparamset {
151 struct mrvlietypesheader header;
152 u8 rates[1];
153} __attribute__ ((packed));
154
155struct mrvlietypes_ssidparamset {
156 struct mrvlietypesheader header;
157 u8 ssid[1];
158} __attribute__ ((packed));
159
160struct mrvlietypes_wildcardssidparamset {
161 struct mrvlietypesheader header;
162 u8 MaxSsidlength;
163 u8 ssid[1];
164} __attribute__ ((packed));
165
166struct chanscanmode {
167 u8 passivescan:1;
168 u8 disablechanfilt:1;
169 u8 reserved_2_7:6;
170} __attribute__ ((packed));
171
172struct chanscanparamset {
173 u8 radiotype;
174 u8 channumber;
175 struct chanscanmode chanscanmode;
176 u16 minscantime;
177 u16 maxscantime;
178} __attribute__ ((packed));
179
180struct mrvlietypes_chanlistparamset {
181 struct mrvlietypesheader header;
182 struct chanscanparamset chanscanparam[1];
183} __attribute__ ((packed));
184
185struct cfparamset {
186 u8 cfpcnt;
187 u8 cfpperiod;
188 u16 cfpmaxduration;
189 u16 cfpdurationremaining;
190} __attribute__ ((packed));
191
192struct ibssparamset {
193 u16 atimwindow;
194} __attribute__ ((packed));
195
196struct mrvlietypes_ssparamset {
197 struct mrvlietypesheader header;
198 union {
199 struct cfparamset cfparamset[1];
200 struct ibssparamset ibssparamset[1];
201 } cf_ibss;
202} __attribute__ ((packed));
203
204struct fhparamset {
205 u16 dwelltime;
206 u8 hopset;
207 u8 hoppattern;
208 u8 hopindex;
209} __attribute__ ((packed));
210
211struct dsparamset {
212 u8 currentchan;
213} __attribute__ ((packed));
214
215struct mrvlietypes_phyparamset {
216 struct mrvlietypesheader header;
217 union {
218 struct fhparamset fhparamset[1];
219 struct dsparamset dsparamset[1];
220 } fh_ds;
221} __attribute__ ((packed));
222
223struct mrvlietypes_rsnparamset {
224 struct mrvlietypesheader header;
225 u8 rsnie[1];
226} __attribute__ ((packed));
227
228struct mrvlietypes_tsftimestamp {
229 struct mrvlietypesheader header;
230 __le64 tsftable[1];
231} __attribute__ ((packed));
232
233/** Local Power capability */
234struct mrvlietypes_powercapability {
235 struct mrvlietypesheader header;
236 s8 minpower;
237 s8 maxpower;
238} __attribute__ ((packed));
239
240struct mrvlietypes_rssithreshold {
241 struct mrvlietypesheader header;
242 u8 rssivalue;
243 u8 rssifreq;
244} __attribute__ ((packed));
245
246struct mrvlietypes_snrthreshold {
247 struct mrvlietypesheader header;
248 u8 snrvalue;
249 u8 snrfreq;
250} __attribute__ ((packed));
251
252struct mrvlietypes_failurecount {
253 struct mrvlietypesheader header;
254 u8 failvalue;
255 u8 Failfreq;
256} __attribute__ ((packed));
257
258struct mrvlietypes_beaconsmissed {
259 struct mrvlietypesheader header;
260 u8 beaconmissed;
261 u8 reserved;
262} __attribute__ ((packed));
263
264struct mrvlietypes_numprobes {
265 struct mrvlietypesheader header;
266 u16 numprobes;
267} __attribute__ ((packed));
268
269struct mrvlietypes_bcastprobe {
270 struct mrvlietypesheader header;
271 u16 bcastprobe;
272} __attribute__ ((packed));
273
274struct mrvlietypes_numssidprobe {
275 struct mrvlietypesheader header;
276 u16 numssidprobe;
277} __attribute__ ((packed));
278
279struct led_pin {
280 u8 led;
281 u8 pin;
282} __attribute__ ((packed));
283
284struct mrvlietypes_ledgpio {
285 struct mrvlietypesheader header;
286 struct led_pin ledpin[1];
287} __attribute__ ((packed));
288
289#endif /* _WLAN_TYPES_ */
diff --git a/drivers/net/wireless/libertas/version.h b/drivers/net/wireless/libertas/version.h
new file mode 100644
index 000000000000..e86f65ae79b8
--- /dev/null
+++ b/drivers/net/wireless/libertas/version.h
@@ -0,0 +1,8 @@
1#define DRIVER_RELEASE_VERSION "320.p0"
2const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
3#ifdef DEBUG
4 "-dbg"
5#endif
6 "";
7
8
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
new file mode 100644
index 000000000000..4a52336bc0f6
--- /dev/null
+++ b/drivers/net/wireless/libertas/wext.c
@@ -0,0 +1,2769 @@
1/**
2 * This file contains ioctl functions
3 */
4#include <linux/ctype.h>
5#include <linux/delay.h>
6#include <linux/if.h>
7#include <linux/if_arp.h>
8#include <linux/wireless.h>
9#include <linux/bitops.h>
10
11#include <net/ieee80211.h>
12#include <net/iw_handler.h>
13
14#include "host.h"
15#include "radiotap.h"
16#include "decl.h"
17#include "defs.h"
18#include "dev.h"
19#include "join.h"
20#include "version.h"
21#include "wext.h"
22#include "assoc.h"
23
24
25/**
26 * @brief Convert mw value to dbm value
27 *
28 * @param mw the value of mw
29 * @return the value of dbm
30 */
31static int mw_to_dbm(int mw)
32{
33 if (mw < 2)
34 return 0;
35 else if (mw < 3)
36 return 3;
37 else if (mw < 4)
38 return 5;
39 else if (mw < 6)
40 return 7;
41 else if (mw < 7)
42 return 8;
43 else if (mw < 8)
44 return 9;
45 else if (mw < 10)
46 return 10;
47 else if (mw < 13)
48 return 11;
49 else if (mw < 16)
50 return 12;
51 else if (mw < 20)
52 return 13;
53 else if (mw < 25)
54 return 14;
55 else if (mw < 32)
56 return 15;
57 else if (mw < 40)
58 return 16;
59 else if (mw < 50)
60 return 17;
61 else if (mw < 63)
62 return 18;
63 else if (mw < 79)
64 return 19;
65 else if (mw < 100)
66 return 20;
67 else
68 return 21;
69}
70
71/**
72 * @brief Find the channel frequency power info with specific channel
73 *
74 * @param adapter A pointer to wlan_adapter structure
75 * @param band it can be BAND_A, BAND_G or BAND_B
76 * @param channel the channel for looking
77 * @return A pointer to struct chan_freq_power structure or NULL if not find.
78 */
79struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * adapter,
80 u8 band, u16 channel)
81{
82 struct chan_freq_power *cfp = NULL;
83 struct region_channel *rc;
84 int count = sizeof(adapter->region_channel) /
85 sizeof(adapter->region_channel[0]);
86 int i, j;
87
88 for (j = 0; !cfp && (j < count); j++) {
89 rc = &adapter->region_channel[j];
90
91 if (adapter->enable11d)
92 rc = &adapter->universal_channel[j];
93 if (!rc->valid || !rc->CFP)
94 continue;
95 if (rc->band != band)
96 continue;
97 for (i = 0; i < rc->nrcfp; i++) {
98 if (rc->CFP[i].channel == channel) {
99 cfp = &rc->CFP[i];
100 break;
101 }
102 }
103 }
104
105 if (!cfp && channel)
106 lbs_pr_debug(1, "libertas_find_cfp_by_band_and_channel(): cannot find "
107 "cfp by band %d & channel %d\n", band, channel);
108
109 return cfp;
110}
111
112/**
113 * @brief Find the channel frequency power info with specific frequency
114 *
115 * @param adapter A pointer to wlan_adapter structure
116 * @param band it can be BAND_A, BAND_G or BAND_B
117 * @param freq the frequency for looking
118 * @return A pointer to struct chan_freq_power structure or NULL if not find.
119 */
120static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
121 u8 band, u32 freq)
122{
123 struct chan_freq_power *cfp = NULL;
124 struct region_channel *rc;
125 int count = sizeof(adapter->region_channel) /
126 sizeof(adapter->region_channel[0]);
127 int i, j;
128
129 for (j = 0; !cfp && (j < count); j++) {
130 rc = &adapter->region_channel[j];
131
132 if (adapter->enable11d)
133 rc = &adapter->universal_channel[j];
134 if (!rc->valid || !rc->CFP)
135 continue;
136 if (rc->band != band)
137 continue;
138 for (i = 0; i < rc->nrcfp; i++) {
139 if (rc->CFP[i].freq == freq) {
140 cfp = &rc->CFP[i];
141 break;
142 }
143 }
144 }
145
146 if (!cfp && freq)
147 lbs_pr_debug(1, "find_cfp_by_band_and_freql(): cannot find cfp by "
148 "band %d & freq %d\n", band, freq);
149
150 return cfp;
151}
152
153static int updatecurrentchannel(wlan_private * priv)
154{
155 int ret;
156
157 /*
158 ** the channel in f/w could be out of sync, get the current channel
159 */
160 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
161 cmd_opt_802_11_rf_channel_get,
162 cmd_option_waitforrsp, 0, NULL);
163
164 lbs_pr_debug(1, "Current channel = %d\n",
165 priv->adapter->curbssparams.channel);
166
167 return ret;
168}
169
170static int setcurrentchannel(wlan_private * priv, int channel)
171{
172 lbs_pr_debug(1, "Set channel = %d\n", channel);
173
174 /*
175 ** Current channel is not set to adhocchannel requested, set channel
176 */
177 return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
178 cmd_opt_802_11_rf_channel_set,
179 cmd_option_waitforrsp, 0, &channel));
180}
181
182static int changeadhocchannel(wlan_private * priv, int channel)
183{
184 int ret = 0;
185 wlan_adapter *adapter = priv->adapter;
186
187 adapter->adhocchannel = channel;
188
189 updatecurrentchannel(priv);
190
191 if (adapter->curbssparams.channel == adapter->adhocchannel) {
192 /* adhocchannel is set to the current channel already */
193 LEAVE();
194 return 0;
195 }
196
197 lbs_pr_debug(1, "Updating channel from %d to %d\n",
198 adapter->curbssparams.channel, adapter->adhocchannel);
199
200 setcurrentchannel(priv, adapter->adhocchannel);
201
202 updatecurrentchannel(priv);
203
204 if (adapter->curbssparams.channel != adapter->adhocchannel) {
205 lbs_pr_debug(1, "failed to updated channel to %d, channel = %d\n",
206 adapter->adhocchannel, adapter->curbssparams.channel);
207 LEAVE();
208 return -1;
209 }
210
211 if (adapter->connect_status == libertas_connected) {
212 int i;
213 struct WLAN_802_11_SSID curadhocssid;
214
215 lbs_pr_debug(1, "channel Changed while in an IBSS\n");
216
217 /* Copy the current ssid */
218 memcpy(&curadhocssid, &adapter->curbssparams.ssid,
219 sizeof(struct WLAN_802_11_SSID));
220
221 /* Exit Adhoc mode */
222 lbs_pr_debug(1, "In changeadhocchannel(): Sending Adhoc Stop\n");
223 ret = libertas_stop_adhoc_network(priv);
224
225 if (ret) {
226 LEAVE();
227 return ret;
228 }
229 /* Scan for the network, do not save previous results. Stale
230 * scan data will cause us to join a non-existant adhoc network
231 */
232 libertas_send_specific_SSID_scan(priv, &curadhocssid, 0);
233
234 // find out the BSSID that matches the current SSID
235 i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
236 wlan802_11ibss);
237
238 if (i >= 0) {
239 lbs_pr_debug(1, "SSID found at %d in List,"
240 "so join\n", i);
241 libertas_join_adhoc_network(priv, &adapter->scantable[i]);
242 } else {
243 // else send START command
244 lbs_pr_debug(1, "SSID not found in list, "
245 "so creating adhoc with ssid = %s\n",
246 curadhocssid.ssid);
247 libertas_start_adhoc_network(priv, &curadhocssid);
248 } // end of else (START command)
249 }
250
251 LEAVE();
252 return 0;
253}
254
255/**
256 * @brief Set Radio On/OFF
257 *
258 * @param priv A pointer to wlan_private structure
259 * @option Radio Option
260 * @return 0 --success, otherwise fail
261 */
262int wlan_radio_ioctl(wlan_private * priv, u8 option)
263{
264 int ret = 0;
265 wlan_adapter *adapter = priv->adapter;
266
267 ENTER();
268
269 if (adapter->radioon != option) {
270 lbs_pr_debug(1, "Switching %s the Radio\n", option ? "On" : "Off");
271 adapter->radioon = option;
272
273 ret = libertas_prepare_and_send_command(priv,
274 cmd_802_11_radio_control,
275 cmd_act_set,
276 cmd_option_waitforrsp, 0, NULL);
277 }
278
279 LEAVE();
280 return ret;
281}
282
283/**
284 * @brief Copy rates
285 *
286 * @param dest A pointer to Dest Buf
287 * @param src A pointer to Src Buf
288 * @param len The len of Src Buf
289 * @return Number of rates copyed
290 */
291static inline int copyrates(u8 * dest, int pos, u8 * src, int len)
292{
293 int i;
294
295 for (i = 0; i < len && src[i]; i++, pos++) {
296 if (pos >= sizeof(u8) * WLAN_SUPPORTED_RATES)
297 break;
298 dest[pos] = src[i];
299 }
300
301 return pos;
302}
303
304/**
305 * @brief Get active data rates
306 *
307 * @param adapter A pointer to wlan_adapter structure
308 * @param rate The buf to return the active rates
309 * @return The number of rates
310 */
311static int get_active_data_rates(wlan_adapter * adapter,
312 u8* rates)
313{
314 int k = 0;
315
316 ENTER();
317
318 if (adapter->connect_status != libertas_connected) {
319 if (adapter->inframode == wlan802_11infrastructure) {
320 //Infra. mode
321 lbs_pr_debug(1, "Infra\n");
322 k = copyrates(rates, k, libertas_supported_rates,
323 sizeof(libertas_supported_rates));
324 } else {
325 //ad-hoc mode
326 lbs_pr_debug(1, "Adhoc G\n");
327 k = copyrates(rates, k, libertas_adhoc_rates_g,
328 sizeof(libertas_adhoc_rates_g));
329 }
330 } else {
331 k = copyrates(rates, 0, adapter->curbssparams.datarates,
332 adapter->curbssparams.numofrates);
333 }
334
335 LEAVE();
336
337 return k;
338}
339
340static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
341 char *cwrq, char *extra)
342{
343 const char *cp;
344 char comm[6] = { "COMM-" };
345 char mrvl[6] = { "MRVL-" };
346 int cnt;
347
348 ENTER();
349
350 strcpy(cwrq, mrvl);
351
352 cp = strstr(libertas_driver_version, comm);
353 if (cp == libertas_driver_version) //skip leading "COMM-"
354 cp = libertas_driver_version + strlen(comm);
355 else
356 cp = libertas_driver_version;
357
358 cnt = strlen(mrvl);
359 cwrq += cnt;
360 while (cnt < 16 && (*cp != '-')) {
361 *cwrq++ = toupper(*cp++);
362 cnt++;
363 }
364 *cwrq = '\0';
365
366 LEAVE();
367
368 return 0;
369}
370
371static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
372 struct iw_freq *fwrq, char *extra)
373{
374 wlan_private *priv = dev->priv;
375 wlan_adapter *adapter = priv->adapter;
376 struct chan_freq_power *cfp;
377
378 ENTER();
379
380 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,
381 adapter->curbssparams.channel);
382
383 if (!cfp) {
384 if (adapter->curbssparams.channel)
385 lbs_pr_debug(1, "Invalid channel=%d\n",
386 adapter->curbssparams.channel);
387 return -EINVAL;
388 }
389
390 fwrq->m = (long)cfp->freq * 100000;
391 fwrq->e = 1;
392
393 lbs_pr_debug(1, "freq=%u\n", fwrq->m);
394
395 LEAVE();
396 return 0;
397}
398
399static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
400 struct sockaddr *awrq, char *extra)
401{
402 wlan_private *priv = dev->priv;
403 wlan_adapter *adapter = priv->adapter;
404
405 ENTER();
406
407 if (adapter->connect_status == libertas_connected) {
408 memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);
409 } else {
410 memset(awrq->sa_data, 0, ETH_ALEN);
411 }
412 awrq->sa_family = ARPHRD_ETHER;
413
414 LEAVE();
415 return 0;
416}
417
418static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
419 struct iw_point *dwrq, char *extra)
420{
421 wlan_private *priv = dev->priv;
422 wlan_adapter *adapter = priv->adapter;
423
424 ENTER();
425
426 /*
427 * Check the size of the string
428 */
429
430 if (dwrq->length > 16) {
431 return -E2BIG;
432 }
433
434 mutex_lock(&adapter->lock);
435 memset(adapter->nodename, 0, sizeof(adapter->nodename));
436 memcpy(adapter->nodename, extra, dwrq->length);
437 mutex_unlock(&adapter->lock);
438
439 LEAVE();
440 return 0;
441}
442
443static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
444 struct iw_point *dwrq, char *extra)
445{
446 wlan_private *priv = dev->priv;
447 wlan_adapter *adapter = priv->adapter;
448
449 ENTER();
450
451 /*
452 * Get the Nick Name saved
453 */
454
455 mutex_lock(&adapter->lock);
456 strncpy(extra, adapter->nodename, 16);
457 mutex_unlock(&adapter->lock);
458
459 extra[16] = '\0';
460
461 /*
462 * If none, we may want to get the one that was set
463 */
464
465 /*
466 * Push it out !
467 */
468 dwrq->length = strlen(extra) + 1;
469
470 LEAVE();
471 return 0;
472}
473
474static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
475 struct iw_param *vwrq, char *extra)
476{
477 int ret = 0;
478 wlan_private *priv = dev->priv;
479 wlan_adapter *adapter = priv->adapter;
480 int rthr = vwrq->value;
481
482 ENTER();
483
484 if (vwrq->disabled) {
485 adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
486 } else {
487 if (rthr < MRVDRV_RTS_MIN_VALUE || rthr > MRVDRV_RTS_MAX_VALUE)
488 return -EINVAL;
489 adapter->rtsthsd = rthr;
490 }
491
492 ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
493 cmd_act_set, cmd_option_waitforrsp,
494 OID_802_11_RTS_THRESHOLD, &rthr);
495
496 LEAVE();
497 return ret;
498}
499
500static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,
501 struct iw_param *vwrq, char *extra)
502{
503 int ret = 0;
504 wlan_private *priv = dev->priv;
505 wlan_adapter *adapter = priv->adapter;
506
507 ENTER();
508
509 adapter->rtsthsd = 0;
510 ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
511 cmd_act_get, cmd_option_waitforrsp,
512 OID_802_11_RTS_THRESHOLD, NULL);
513 if (ret) {
514 LEAVE();
515 return ret;
516 }
517
518 vwrq->value = adapter->rtsthsd;
519 vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)
520 || (vwrq->value > MRVDRV_RTS_MAX_VALUE));
521 vwrq->fixed = 1;
522
523 LEAVE();
524 return 0;
525}
526
527static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
528 struct iw_param *vwrq, char *extra)
529{
530 int ret = 0;
531 int fthr = vwrq->value;
532 wlan_private *priv = dev->priv;
533 wlan_adapter *adapter = priv->adapter;
534
535 ENTER();
536
537 if (vwrq->disabled) {
538 adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
539 } else {
540 if (fthr < MRVDRV_FRAG_MIN_VALUE
541 || fthr > MRVDRV_FRAG_MAX_VALUE)
542 return -EINVAL;
543 adapter->fragthsd = fthr;
544 }
545
546 ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
547 cmd_act_set, cmd_option_waitforrsp,
548 OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);
549 LEAVE();
550 return ret;
551}
552
553static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,
554 struct iw_param *vwrq, char *extra)
555{
556 int ret = 0;
557 wlan_private *priv = dev->priv;
558 wlan_adapter *adapter = priv->adapter;
559
560 ENTER();
561
562 adapter->fragthsd = 0;
563 ret = libertas_prepare_and_send_command(priv,
564 cmd_802_11_snmp_mib,
565 cmd_act_get, cmd_option_waitforrsp,
566 OID_802_11_FRAGMENTATION_THRESHOLD, NULL);
567 if (ret) {
568 LEAVE();
569 return ret;
570 }
571
572 vwrq->value = adapter->fragthsd;
573 vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)
574 || (vwrq->value > MRVDRV_FRAG_MAX_VALUE));
575 vwrq->fixed = 1;
576
577 LEAVE();
578 return ret;
579}
580
581static int wlan_get_mode(struct net_device *dev,
582 struct iw_request_info *info, u32 * uwrq, char *extra)
583{
584 wlan_private *priv = dev->priv;
585 wlan_adapter *adapter = priv->adapter;
586
587 ENTER();
588
589 switch (adapter->inframode) {
590 case wlan802_11ibss:
591 *uwrq = IW_MODE_ADHOC;
592 break;
593
594 case wlan802_11infrastructure:
595 *uwrq = IW_MODE_INFRA;
596 break;
597
598 default:
599 case wlan802_11autounknown:
600 *uwrq = IW_MODE_AUTO;
601 break;
602 }
603
604 LEAVE();
605 return 0;
606}
607
608static int wlan_get_txpow(struct net_device *dev,
609 struct iw_request_info *info,
610 struct iw_param *vwrq, char *extra)
611{
612 int ret = 0;
613 wlan_private *priv = dev->priv;
614 wlan_adapter *adapter = priv->adapter;
615
616 ENTER();
617
618 ret = libertas_prepare_and_send_command(priv,
619 cmd_802_11_rf_tx_power,
620 cmd_act_tx_power_opt_get,
621 cmd_option_waitforrsp, 0, NULL);
622
623 if (ret) {
624 LEAVE();
625 return ret;
626 }
627
628 lbs_pr_debug(1, "TXPOWER GET %d dbm.\n", adapter->txpowerlevel);
629 vwrq->value = adapter->txpowerlevel;
630 vwrq->fixed = 1;
631 if (adapter->radioon) {
632 vwrq->disabled = 0;
633 vwrq->flags = IW_TXPOW_DBM;
634 } else {
635 vwrq->disabled = 1;
636 }
637
638 LEAVE();
639 return 0;
640}
641
642static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
643 struct iw_param *vwrq, char *extra)
644{
645 int ret = 0;
646 wlan_private *priv = dev->priv;
647 wlan_adapter *adapter = priv->adapter;
648
649 ENTER();
650
651 if (vwrq->flags == IW_RETRY_LIMIT) {
652 /* The MAC has a 4-bit Total_Tx_Count register
653 Total_Tx_Count = 1 + Tx_Retry_Count */
654#define TX_RETRY_MIN 0
655#define TX_RETRY_MAX 14
656 if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX)
657 return -EINVAL;
658
659 /* Adding 1 to convert retry count to try count */
660 adapter->txretrycount = vwrq->value + 1;
661
662 ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
663 cmd_act_set,
664 cmd_option_waitforrsp,
665 OID_802_11_TX_RETRYCOUNT, NULL);
666
667 if (ret) {
668 LEAVE();
669 return ret;
670 }
671 } else {
672 return -EOPNOTSUPP;
673 }
674
675 LEAVE();
676 return 0;
677}
678
679static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
680 struct iw_param *vwrq, char *extra)
681{
682 wlan_private *priv = dev->priv;
683 wlan_adapter *adapter = priv->adapter;
684 int ret = 0;
685
686 ENTER();
687 adapter->txretrycount = 0;
688 ret = libertas_prepare_and_send_command(priv,
689 cmd_802_11_snmp_mib,
690 cmd_act_get, cmd_option_waitforrsp,
691 OID_802_11_TX_RETRYCOUNT, NULL);
692 if (ret) {
693 LEAVE();
694 return ret;
695 }
696 vwrq->disabled = 0;
697 if (!vwrq->flags) {
698 vwrq->flags = IW_RETRY_LIMIT;
699 /* Subtract 1 to convert try count to retry count */
700 vwrq->value = adapter->txretrycount - 1;
701 }
702
703 LEAVE();
704 return 0;
705}
706
707static inline void sort_channels(struct iw_freq *freq, int num)
708{
709 int i, j;
710 struct iw_freq temp;
711
712 for (i = 0; i < num; i++)
713 for (j = i + 1; j < num; j++)
714 if (freq[i].i > freq[j].i) {
715 temp.i = freq[i].i;
716 temp.m = freq[i].m;
717
718 freq[i].i = freq[j].i;
719 freq[i].m = freq[j].m;
720
721 freq[j].i = temp.i;
722 freq[j].m = temp.m;
723 }
724}
725
726/* data rate listing
727 MULTI_BANDS:
728 abg a b b/g
729 Infra G(12) A(8) B(4) G(12)
730 Adhoc A+B(12) A(8) B(4) B(4)
731
732 non-MULTI_BANDS:
733 b b/g
734 Infra B(4) G(12)
735 Adhoc B(4) B(4)
736 */
737/**
738 * @brief Get Range Info
739 *
740 * @param dev A pointer to net_device structure
741 * @param info A pointer to iw_request_info structure
742 * @param vwrq A pointer to iw_param structure
743 * @param extra A pointer to extra data buf
744 * @return 0 --success, otherwise fail
745 */
746static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
747 struct iw_point *dwrq, char *extra)
748{
749 int i, j;
750 wlan_private *priv = dev->priv;
751 wlan_adapter *adapter = priv->adapter;
752 struct iw_range *range = (struct iw_range *)extra;
753 struct chan_freq_power *cfp;
754 u8 rates[WLAN_SUPPORTED_RATES];
755
756 u8 flag = 0;
757
758 ENTER();
759
760 dwrq->length = sizeof(struct iw_range);
761 memset(range, 0, sizeof(struct iw_range));
762
763 range->min_nwid = 0;
764 range->max_nwid = 0;
765
766 memset(rates, 0, sizeof(rates));
767 range->num_bitrates = get_active_data_rates(adapter, rates);
768
769 for (i = 0; i < min_t(__u8, range->num_bitrates, IW_MAX_BITRATES) && rates[i];
770 i++) {
771 range->bitrate[i] = (rates[i] & 0x7f) * 500000;
772 }
773 range->num_bitrates = i;
774 lbs_pr_debug(1, "IW_MAX_BITRATES=%d num_bitrates=%d\n", IW_MAX_BITRATES,
775 range->num_bitrates);
776
777 range->num_frequency = 0;
778 if (priv->adapter->enable11d &&
779 adapter->connect_status == libertas_connected) {
780 u8 chan_no;
781 u8 band;
782
783 struct parsed_region_chan_11d *parsed_region_chan =
784 &adapter->parsed_region_chan;
785
786 if (parsed_region_chan == NULL) {
787 lbs_pr_debug(1, "11D:parsed_region_chan is NULL\n");
788 LEAVE();
789 return 0;
790 }
791 band = parsed_region_chan->band;
792 lbs_pr_debug(1, "band=%d NoOfChan=%d\n", band,
793 parsed_region_chan->nr_chan);
794
795 for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
796 && (i < parsed_region_chan->nr_chan); i++) {
797 chan_no = parsed_region_chan->chanpwr[i].chan;
798 lbs_pr_debug(1, "chan_no=%d\n", chan_no);
799 range->freq[range->num_frequency].i = (long)chan_no;
800 range->freq[range->num_frequency].m =
801 (long)libertas_chan_2_freq(chan_no, band) * 100000;
802 range->freq[range->num_frequency].e = 1;
803 range->num_frequency++;
804 }
805 flag = 1;
806 }
807 if (!flag) {
808 for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
809 && (j < sizeof(adapter->region_channel)
810 / sizeof(adapter->region_channel[0])); j++) {
811 cfp = adapter->region_channel[j].CFP;
812 for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
813 && adapter->region_channel[j].valid
814 && cfp
815 && (i < adapter->region_channel[j].nrcfp); i++) {
816 range->freq[range->num_frequency].i =
817 (long)cfp->channel;
818 range->freq[range->num_frequency].m =
819 (long)cfp->freq * 100000;
820 range->freq[range->num_frequency].e = 1;
821 cfp++;
822 range->num_frequency++;
823 }
824 }
825 }
826
827 lbs_pr_debug(1, "IW_MAX_FREQUENCIES=%d num_frequency=%d\n",
828 IW_MAX_FREQUENCIES, range->num_frequency);
829
830 range->num_channels = range->num_frequency;
831
832 sort_channels(&range->freq[0], range->num_frequency);
833
834 /*
835 * Set an indication of the max TCP throughput in bit/s that we can
836 * expect using this interface
837 */
838 if (i > 2)
839 range->throughput = 5000 * 1000;
840 else
841 range->throughput = 1500 * 1000;
842
843 range->min_rts = MRVDRV_RTS_MIN_VALUE;
844 range->max_rts = MRVDRV_RTS_MAX_VALUE;
845 range->min_frag = MRVDRV_FRAG_MIN_VALUE;
846 range->max_frag = MRVDRV_FRAG_MAX_VALUE;
847
848 range->encoding_size[0] = 5;
849 range->encoding_size[1] = 13;
850 range->num_encoding_sizes = 2;
851 range->max_encoding_tokens = 4;
852
853 range->min_pmp = 1000000;
854 range->max_pmp = 120000000;
855 range->min_pmt = 1000;
856 range->max_pmt = 1000000;
857 range->pmp_flags = IW_POWER_PERIOD;
858 range->pmt_flags = IW_POWER_TIMEOUT;
859 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
860
861 /*
862 * Minimum version we recommend
863 */
864 range->we_version_source = 15;
865
866 /*
867 * Version we are compiled with
868 */
869 range->we_version_compiled = WIRELESS_EXT;
870
871 range->retry_capa = IW_RETRY_LIMIT;
872 range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
873
874 range->min_retry = TX_RETRY_MIN;
875 range->max_retry = TX_RETRY_MAX;
876
877 /*
878 * Set the qual, level and noise range values
879 */
880 range->max_qual.qual = 100;
881 range->max_qual.level = 0;
882 range->max_qual.noise = 0;
883 range->max_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
884
885 range->avg_qual.qual = 70;
886 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
887 range->avg_qual.level = 0;
888 range->avg_qual.noise = 0;
889 range->avg_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
890
891 range->sensitivity = 0;
892
893 /*
894 * Setup the supported power level ranges
895 */
896 memset(range->txpower, 0, sizeof(range->txpower));
897 range->txpower[0] = 5;
898 range->txpower[1] = 7;
899 range->txpower[2] = 9;
900 range->txpower[3] = 11;
901 range->txpower[4] = 13;
902 range->txpower[5] = 15;
903 range->txpower[6] = 17;
904 range->txpower[7] = 19;
905
906 range->num_txpower = 8;
907 range->txpower_capa = IW_TXPOW_DBM;
908 range->txpower_capa |= IW_TXPOW_RANGE;
909
910 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
911 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
912 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
913 range->event_capa[1] = IW_EVENT_CAPA_K_1;
914
915 if (adapter->fwcapinfo & FW_CAPINFO_WPA) {
916 range->enc_capa = IW_ENC_CAPA_WPA
917 | IW_ENC_CAPA_WPA2
918 | IW_ENC_CAPA_CIPHER_TKIP
919 | IW_ENC_CAPA_CIPHER_CCMP;
920 }
921
922 LEAVE();
923 return 0;
924}
925
926static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
927 struct iw_param *vwrq, char *extra)
928{
929 wlan_private *priv = dev->priv;
930 wlan_adapter *adapter = priv->adapter;
931
932 ENTER();
933
934 /* PS is currently supported only in Infrastructure mode
935 * Remove this check if it is to be supported in IBSS mode also
936 */
937
938 if (vwrq->disabled) {
939 adapter->psmode = wlan802_11powermodecam;
940 if (adapter->psstate != PS_STATE_FULL_POWER) {
941 libertas_ps_wakeup(priv, cmd_option_waitforrsp);
942 }
943
944 return 0;
945 }
946
947 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
948 lbs_pr_debug(1,
949 "Setting power timeout command is not supported\n");
950 return -EINVAL;
951 } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
952 lbs_pr_debug(1, "Setting power period command is not supported\n");
953 return -EINVAL;
954 }
955
956 if (adapter->psmode != wlan802_11powermodecam) {
957 return 0;
958 }
959
960 adapter->psmode = wlan802_11powermodemax_psp;
961
962 if (adapter->connect_status == libertas_connected) {
963 libertas_ps_sleep(priv, cmd_option_waitforrsp);
964 }
965
966 LEAVE();
967 return 0;
968}
969
970static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,
971 struct iw_param *vwrq, char *extra)
972{
973 wlan_private *priv = dev->priv;
974 wlan_adapter *adapter = priv->adapter;
975 int mode;
976
977 ENTER();
978
979 mode = adapter->psmode;
980
981 if ((vwrq->disabled = (mode == wlan802_11powermodecam))
982 || adapter->connect_status == libertas_disconnected) {
983 LEAVE();
984 return 0;
985 }
986
987 vwrq->value = 0;
988
989 LEAVE();
990 return 0;
991}
992
993/*
994 * iwpriv settable callbacks
995 */
996
997static const iw_handler wlan_private_handler[] = {
998 NULL, /* SIOCIWFIRSTPRIV */
999};
1000
1001static const struct iw_priv_args wlan_private_args[] = {
1002 /*
1003 * { cmd, set_args, get_args, name }
1004 */
1005 {
1006 WLANSCAN_TYPE,
1007 IW_PRIV_TYPE_CHAR | 8,
1008 IW_PRIV_TYPE_CHAR | 8,
1009 "scantype"},
1010
1011 {
1012 WLAN_SETINT_GETINT,
1013 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1014 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1015 ""},
1016 {
1017 WLANNF,
1018 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1019 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1020 "getNF"},
1021 {
1022 WLANRSSI,
1023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1024 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1025 "getRSSI"},
1026 {
1027 WLANENABLE11D,
1028 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1029 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1030 "enable11d"},
1031 {
1032 WLANADHOCGRATE,
1033 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1034 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1035 "adhocgrate"},
1036
1037 {
1038 WLAN_SUBCMD_SET_PRESCAN,
1039 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1040 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1041 "prescan"},
1042 {
1043 WLAN_SETONEINT_GETONEINT,
1044 IW_PRIV_TYPE_INT | 1,
1045 IW_PRIV_TYPE_INT | 1,
1046 ""},
1047 {
1048 WLAN_BEACON_INTERVAL,
1049 IW_PRIV_TYPE_INT | 1,
1050 IW_PRIV_TYPE_INT | 1,
1051 "bcninterval"},
1052 {
1053 WLAN_LISTENINTRVL,
1054 IW_PRIV_TYPE_INT | 1,
1055 IW_PRIV_TYPE_INT | 1,
1056 "lolisteninter"},
1057 {
1058 WLAN_TXCONTROL,
1059 IW_PRIV_TYPE_INT | 1,
1060 IW_PRIV_TYPE_INT | 1,
1061 "txcontrol"},
1062 {
1063 WLAN_NULLPKTINTERVAL,
1064 IW_PRIV_TYPE_INT | 1,
1065 IW_PRIV_TYPE_INT | 1,
1066 "psnullinterval"},
1067 /* Using iwpriv sub-command feature */
1068 {
1069 WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */
1070 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1071 IW_PRIV_TYPE_NONE,
1072 ""},
1073
1074 {
1075 WLAN_SUBCMD_SETRXANTENNA,
1076 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1077 IW_PRIV_TYPE_NONE,
1078 "setrxant"},
1079 {
1080 WLAN_SUBCMD_SETTXANTENNA,
1081 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1082 IW_PRIV_TYPE_NONE,
1083 "settxant"},
1084 {
1085 WLANSETAUTHALG,
1086 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1087 IW_PRIV_TYPE_NONE,
1088 "authalgs",
1089 },
1090 {
1091 WLANSET8021XAUTHALG,
1092 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1093 IW_PRIV_TYPE_NONE,
1094 "8021xauthalgs",
1095 },
1096 {
1097 WLANSETENCRYPTIONMODE,
1098 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1099 IW_PRIV_TYPE_NONE,
1100 "encryptionmode",
1101 },
1102 {
1103 WLANSETREGION,
1104 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1105 IW_PRIV_TYPE_NONE,
1106 "setregioncode"},
1107 {
1108 WLAN_SET_LISTEN_INTERVAL,
1109 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1110 IW_PRIV_TYPE_NONE,
1111 "setlisteninter"},
1112 {
1113 WLAN_SET_MULTIPLE_DTIM,
1114 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1115 IW_PRIV_TYPE_NONE,
1116 "setmultipledtim"},
1117 {
1118 WLAN_SET_ATIM_WINDOW,
1119 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1120 IW_PRIV_TYPE_NONE,
1121 "atimwindow"},
1122 {
1123 WLANSETBCNAVG,
1124 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1125 IW_PRIV_TYPE_NONE,
1126 "setbcnavg"},
1127 {
1128 WLANSETDATAAVG,
1129 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1130 IW_PRIV_TYPE_NONE,
1131 "setdataavg"},
1132 {
1133 WLAN_SET_LINKMODE,
1134 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1135 IW_PRIV_TYPE_NONE,
1136 "linkmode"},
1137 {
1138 WLAN_SET_RADIOMODE,
1139 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1140 IW_PRIV_TYPE_NONE,
1141 "radiomode"},
1142 {
1143 WLAN_SET_DEBUGMODE,
1144 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1145 IW_PRIV_TYPE_NONE,
1146 "debugmode"},
1147 {
1148 WLAN_SUBCMD_MESH_SET_TTL,
1149 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1150 IW_PRIV_TYPE_NONE,
1151 "mesh_set_ttl"},
1152 {
1153 WLAN_SETNONE_GETONEINT,
1154 IW_PRIV_TYPE_NONE,
1155 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1156 ""},
1157 {
1158 WLANGETREGION,
1159 IW_PRIV_TYPE_NONE,
1160 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1161 "getregioncode"},
1162 {
1163 WLAN_GET_LISTEN_INTERVAL,
1164 IW_PRIV_TYPE_NONE,
1165 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1166 "getlisteninter"},
1167 {
1168 WLAN_GET_MULTIPLE_DTIM,
1169 IW_PRIV_TYPE_NONE,
1170 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1171 "getmultipledtim"},
1172 {
1173 WLAN_GET_TX_RATE,
1174 IW_PRIV_TYPE_NONE,
1175 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1176 "gettxrate"},
1177 {
1178 WLANGETBCNAVG,
1179 IW_PRIV_TYPE_NONE,
1180 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1181 "getbcnavg"},
1182 {
1183 WLAN_GET_LINKMODE,
1184 IW_PRIV_TYPE_NONE,
1185 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1186 "get_linkmode"},
1187 {
1188 WLAN_GET_RADIOMODE,
1189 IW_PRIV_TYPE_NONE,
1190 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1191 "get_radiomode"},
1192 {
1193 WLAN_GET_DEBUGMODE,
1194 IW_PRIV_TYPE_NONE,
1195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1196 "get_debugmode"},
1197 {
1198 WLAN_SUBCMD_FWT_CLEANUP,
1199 IW_PRIV_TYPE_NONE,
1200 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1201 "fwt_cleanup"},
1202 {
1203 WLAN_SUBCMD_FWT_TIME,
1204 IW_PRIV_TYPE_NONE,
1205 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1206 "fwt_time"},
1207 {
1208 WLAN_SUBCMD_MESH_GET_TTL,
1209 IW_PRIV_TYPE_NONE,
1210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
1211 "mesh_get_ttl"},
1212 {
1213 WLAN_SETNONE_GETTWELVE_CHAR,
1214 IW_PRIV_TYPE_NONE,
1215 IW_PRIV_TYPE_CHAR | 12,
1216 ""},
1217 {
1218 WLAN_SUBCMD_GETRXANTENNA,
1219 IW_PRIV_TYPE_NONE,
1220 IW_PRIV_TYPE_CHAR | 12,
1221 "getrxant"},
1222 {
1223 WLAN_SUBCMD_GETTXANTENNA,
1224 IW_PRIV_TYPE_NONE,
1225 IW_PRIV_TYPE_CHAR | 12,
1226 "gettxant"},
1227 {
1228 WLAN_GET_TSF,
1229 IW_PRIV_TYPE_NONE,
1230 IW_PRIV_TYPE_CHAR | 12,
1231 "gettsf"},
1232 {
1233 WLAN_SETNONE_GETNONE,
1234 IW_PRIV_TYPE_NONE,
1235 IW_PRIV_TYPE_NONE,
1236 ""},
1237 {
1238 WLANDEAUTH,
1239 IW_PRIV_TYPE_NONE,
1240 IW_PRIV_TYPE_NONE,
1241 "deauth"},
1242 {
1243 WLANADHOCSTOP,
1244 IW_PRIV_TYPE_NONE,
1245 IW_PRIV_TYPE_NONE,
1246 "adhocstop"},
1247 {
1248 WLANRADIOON,
1249 IW_PRIV_TYPE_NONE,
1250 IW_PRIV_TYPE_NONE,
1251 "radioon"},
1252 {
1253 WLANRADIOOFF,
1254 IW_PRIV_TYPE_NONE,
1255 IW_PRIV_TYPE_NONE,
1256 "radiooff"},
1257 {
1258 WLANWLANIDLEON,
1259 IW_PRIV_TYPE_NONE,
1260 IW_PRIV_TYPE_NONE,
1261 "wlanidle-on"},
1262 {
1263 WLANWLANIDLEOFF,
1264 IW_PRIV_TYPE_NONE,
1265 IW_PRIV_TYPE_NONE,
1266 "wlanidle-off"},
1267 {
1268 WLAN_SUBCMD_FWT_RESET,
1269 IW_PRIV_TYPE_NONE,
1270 IW_PRIV_TYPE_NONE,
1271 "fwt_reset"},
1272 {
1273 WLAN_SUBCMD_BT_RESET,
1274 IW_PRIV_TYPE_NONE,
1275 IW_PRIV_TYPE_NONE,
1276 "bt_reset"},
1277 {
1278 WLAN_SET128CHAR_GET128CHAR,
1279 IW_PRIV_TYPE_CHAR | 128,
1280 IW_PRIV_TYPE_CHAR | 128,
1281 ""},
1282 /* BT Management */
1283 {
1284 WLAN_SUBCMD_BT_ADD,
1285 IW_PRIV_TYPE_CHAR | 128,
1286 IW_PRIV_TYPE_CHAR | 128,
1287 "bt_add"},
1288 {
1289 WLAN_SUBCMD_BT_DEL,
1290 IW_PRIV_TYPE_CHAR | 128,
1291 IW_PRIV_TYPE_CHAR | 128,
1292 "bt_del"},
1293 {
1294 WLAN_SUBCMD_BT_LIST,
1295 IW_PRIV_TYPE_CHAR | 128,
1296 IW_PRIV_TYPE_CHAR | 128,
1297 "bt_list"},
1298 /* FWT Management */
1299 {
1300 WLAN_SUBCMD_FWT_ADD,
1301 IW_PRIV_TYPE_CHAR | 128,
1302 IW_PRIV_TYPE_CHAR | 128,
1303 "fwt_add"},
1304 {
1305 WLAN_SUBCMD_FWT_DEL,
1306 IW_PRIV_TYPE_CHAR | 128,
1307 IW_PRIV_TYPE_CHAR | 128,
1308 "fwt_del"},
1309 {
1310 WLAN_SUBCMD_FWT_LOOKUP,
1311 IW_PRIV_TYPE_CHAR | 128,
1312 IW_PRIV_TYPE_CHAR | 128,
1313 "fwt_lookup"},
1314 {
1315 WLAN_SUBCMD_FWT_LIST_NEIGHBOR,
1316 IW_PRIV_TYPE_CHAR | 128,
1317 IW_PRIV_TYPE_CHAR | 128,
1318 "fwt_list_neigh"},
1319 {
1320 WLAN_SUBCMD_FWT_LIST,
1321 IW_PRIV_TYPE_CHAR | 128,
1322 IW_PRIV_TYPE_CHAR | 128,
1323 "fwt_list"},
1324 {
1325 WLAN_SUBCMD_FWT_LIST_ROUTE,
1326 IW_PRIV_TYPE_CHAR | 128,
1327 IW_PRIV_TYPE_CHAR | 128,
1328 "fwt_list_route"},
1329 {
1330 WLANSCAN_MODE,
1331 IW_PRIV_TYPE_CHAR | 128,
1332 IW_PRIV_TYPE_CHAR | 128,
1333 "scanmode"},
1334 {
1335 WLAN_GET_ADHOC_STATUS,
1336 IW_PRIV_TYPE_CHAR | 128,
1337 IW_PRIV_TYPE_CHAR | 128,
1338 "getadhocstatus"},
1339 {
1340 WLAN_SETNONE_GETWORDCHAR,
1341 IW_PRIV_TYPE_NONE,
1342 IW_PRIV_TYPE_CHAR | 128,
1343 ""},
1344 {
1345 WLANSETWPAIE,
1346 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 24,
1347 IW_PRIV_TYPE_NONE,
1348 "setwpaie"},
1349 {
1350 WLANGETLOG,
1351 IW_PRIV_TYPE_NONE,
1352 IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE,
1353 "getlog"},
1354 {
1355 WLAN_SET_GET_SIXTEEN_INT,
1356 IW_PRIV_TYPE_INT | 16,
1357 IW_PRIV_TYPE_INT | 16,
1358 ""},
1359 {
1360 WLAN_TPCCFG,
1361 IW_PRIV_TYPE_INT | 16,
1362 IW_PRIV_TYPE_INT | 16,
1363 "tpccfg"},
1364 {
1365 WLAN_POWERCFG,
1366 IW_PRIV_TYPE_INT | 16,
1367 IW_PRIV_TYPE_INT | 16,
1368 "powercfg"},
1369 {
1370 WLAN_AUTO_FREQ_SET,
1371 IW_PRIV_TYPE_INT | 16,
1372 IW_PRIV_TYPE_INT | 16,
1373 "setafc"},
1374 {
1375 WLAN_AUTO_FREQ_GET,
1376 IW_PRIV_TYPE_INT | 16,
1377 IW_PRIV_TYPE_INT | 16,
1378 "getafc"},
1379 {
1380 WLAN_SCANPROBES,
1381 IW_PRIV_TYPE_INT | 16,
1382 IW_PRIV_TYPE_INT | 16,
1383 "scanprobes"},
1384 {
1385 WLAN_LED_GPIO_CTRL,
1386 IW_PRIV_TYPE_INT | 16,
1387 IW_PRIV_TYPE_INT | 16,
1388 "ledgpio"},
1389 {
1390 WLAN_ADAPT_RATESET,
1391 IW_PRIV_TYPE_INT | 16,
1392 IW_PRIV_TYPE_INT | 16,
1393 "rateadapt"},
1394 {
1395 WLAN_INACTIVITY_TIMEOUT,
1396 IW_PRIV_TYPE_INT | 16,
1397 IW_PRIV_TYPE_INT | 16,
1398 "inactivityto"},
1399 {
1400 WLANSNR,
1401 IW_PRIV_TYPE_INT | 16,
1402 IW_PRIV_TYPE_INT | 16,
1403 "getSNR"},
1404 {
1405 WLAN_GET_RATE,
1406 IW_PRIV_TYPE_INT | 16,
1407 IW_PRIV_TYPE_INT | 16,
1408 "getrate"},
1409 {
1410 WLAN_GET_RXINFO,
1411 IW_PRIV_TYPE_INT | 16,
1412 IW_PRIV_TYPE_INT | 16,
1413 "getrxinfo"},
1414};
1415
1416static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
1417{
1418 enum {
1419 POOR = 30,
1420 FAIR = 60,
1421 GOOD = 80,
1422 VERY_GOOD = 90,
1423 EXCELLENT = 95,
1424 PERFECT = 100
1425 };
1426 wlan_private *priv = dev->priv;
1427 wlan_adapter *adapter = priv->adapter;
1428 u32 rssi_qual;
1429 u32 tx_qual;
1430 u32 quality = 0;
1431 int stats_valid = 0;
1432 u8 rssi;
1433 u32 tx_retries;
1434
1435 ENTER();
1436
1437 priv->wstats.status = adapter->inframode;
1438
1439 /* If we're not associated, all quality values are meaningless */
1440 if (adapter->connect_status != libertas_connected)
1441 goto out;
1442
1443 /* Quality by RSSI */
1444 priv->wstats.qual.level =
1445 CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
1446 adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
1447
1448 if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
1449 priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
1450 } else {
1451 priv->wstats.qual.noise =
1452 CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
1453 }
1454
1455 lbs_pr_debug(1, "Signal Level = %#x\n", priv->wstats.qual.level);
1456 lbs_pr_debug(1, "Noise = %#x\n", priv->wstats.qual.noise);
1457
1458 rssi = priv->wstats.qual.level - priv->wstats.qual.noise;
1459 if (rssi < 15)
1460 rssi_qual = rssi * POOR / 10;
1461 else if (rssi < 20)
1462 rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR;
1463 else if (rssi < 30)
1464 rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR;
1465 else if (rssi < 40)
1466 rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) /
1467 10 + GOOD;
1468 else
1469 rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) /
1470 10 + VERY_GOOD;
1471 quality = rssi_qual;
1472
1473 /* Quality by TX errors */
1474 priv->wstats.discard.retries = priv->stats.tx_errors;
1475
1476 tx_retries = adapter->logmsg.retry;
1477
1478 if (tx_retries > 75)
1479 tx_qual = (90 - tx_retries) * POOR / 15;
1480 else if (tx_retries > 70)
1481 tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
1482 else if (tx_retries > 65)
1483 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
1484 else if (tx_retries > 50)
1485 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
1486 15 + GOOD;
1487 else
1488 tx_qual = (50 - tx_retries) *
1489 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
1490 quality = min(quality, tx_qual);
1491
1492 priv->wstats.discard.code = adapter->logmsg.wepundecryptable;
1493 priv->wstats.discard.fragment = adapter->logmsg.fcserror;
1494 priv->wstats.discard.retries = tx_retries;
1495 priv->wstats.discard.misc = adapter->logmsg.ackfailure;
1496
1497 /* Calculate quality */
1498 priv->wstats.qual.qual = max(quality, (u32)100);
1499 priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1500 stats_valid = 1;
1501
1502 /* update stats asynchronously for future calls */
1503 libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
1504 0, 0, NULL);
1505 libertas_prepare_and_send_command(priv, cmd_802_11_get_log, 0,
1506 0, 0, NULL);
1507out:
1508 if (!stats_valid) {
1509 priv->wstats.miss.beacon = 0;
1510 priv->wstats.discard.retries = 0;
1511 priv->wstats.qual.qual = 0;
1512 priv->wstats.qual.level = 0;
1513 priv->wstats.qual.noise = 0;
1514 priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED;
1515 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID |
1516 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
1517 }
1518
1519 LEAVE ();
1520 return &priv->wstats;
1521
1522
1523}
1524
1525static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
1526 struct iw_freq *fwrq, char *extra)
1527{
1528 int ret = 0;
1529 wlan_private *priv = dev->priv;
1530 wlan_adapter *adapter = priv->adapter;
1531 int rc = -EINPROGRESS; /* Call commit handler */
1532 struct chan_freq_power *cfp;
1533
1534 ENTER();
1535
1536 /*
1537 * If setting by frequency, convert to a channel
1538 */
1539 if (fwrq->e == 1) {
1540
1541 long f = fwrq->m / 100000;
1542 int c = 0;
1543
1544 cfp = find_cfp_by_band_and_freq(adapter, 0, f);
1545 if (!cfp) {
1546 lbs_pr_debug(1, "Invalid freq=%ld\n", f);
1547 return -EINVAL;
1548 }
1549
1550 c = (int)cfp->channel;
1551
1552 if (c < 0)
1553 return -EINVAL;
1554
1555 fwrq->e = 0;
1556 fwrq->m = c;
1557 }
1558
1559 /*
1560 * Setting by channel number
1561 */
1562 if (fwrq->m > 1000 || fwrq->e > 0) {
1563 rc = -EOPNOTSUPP;
1564 } else {
1565 int channel = fwrq->m;
1566
1567 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel);
1568 if (!cfp) {
1569 rc = -EINVAL;
1570 } else {
1571 if (adapter->inframode == wlan802_11ibss) {
1572 rc = changeadhocchannel(priv, channel);
1573 /* If station is WEP enabled, send the
1574 * command to set WEP in firmware
1575 */
1576 if (adapter->secinfo.WEPstatus ==
1577 wlan802_11WEPenabled) {
1578 lbs_pr_debug(1, "set_freq: WEP enabled\n");
1579 ret = libertas_prepare_and_send_command(priv,
1580 cmd_802_11_set_wep,
1581 cmd_act_add,
1582 cmd_option_waitforrsp,
1583 0,
1584 NULL);
1585
1586 if (ret) {
1587 LEAVE();
1588 return ret;
1589 }
1590
1591 adapter->currentpacketfilter |=
1592 cmd_act_mac_wep_enable;
1593
1594 libertas_set_mac_packet_filter(priv);
1595 }
1596 } else {
1597 rc = -EOPNOTSUPP;
1598 }
1599 }
1600 }
1601
1602 LEAVE();
1603 return rc;
1604}
1605
1606/**
1607 * @brief use index to get the data rate
1608 *
1609 * @param index The index of data rate
1610 * @return data rate or 0
1611 */
1612u32 libertas_index_to_data_rate(u8 index)
1613{
1614 if (index >= sizeof(libertas_wlan_data_rates))
1615 index = 0;
1616
1617 return libertas_wlan_data_rates[index];
1618}
1619
1620/**
1621 * @brief use rate to get the index
1622 *
1623 * @param rate data rate
1624 * @return index or 0
1625 */
1626u8 libertas_data_rate_to_index(u32 rate)
1627{
1628 u8 *ptr;
1629
1630 if (rate)
1631 if ((ptr = memchr(libertas_wlan_data_rates, (u8) rate,
1632 sizeof(libertas_wlan_data_rates))))
1633 return (ptr - libertas_wlan_data_rates);
1634
1635 return 0;
1636}
1637
1638static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
1639 struct iw_param *vwrq, char *extra)
1640{
1641 wlan_private *priv = dev->priv;
1642 wlan_adapter *adapter = priv->adapter;
1643 u32 data_rate;
1644 u16 action;
1645 int ret = 0;
1646 u8 rates[WLAN_SUPPORTED_RATES];
1647 u8 *rate;
1648
1649 ENTER();
1650
1651 lbs_pr_debug(1, "Vwrq->value = %d\n", vwrq->value);
1652
1653 if (vwrq->value == -1) {
1654 action = cmd_act_set_tx_auto; // Auto
1655 adapter->is_datarate_auto = 1;
1656 adapter->datarate = 0;
1657 } else {
1658 if (vwrq->value % 100000) {
1659 return -EINVAL;
1660 }
1661
1662 data_rate = vwrq->value / 500000;
1663
1664 memset(rates, 0, sizeof(rates));
1665 get_active_data_rates(adapter, rates);
1666 rate = rates;
1667 while (*rate) {
1668 lbs_pr_debug(1, "Rate=0x%X Wanted=0x%X\n", *rate,
1669 data_rate);
1670 if ((*rate & 0x7f) == (data_rate & 0x7f))
1671 break;
1672 rate++;
1673 }
1674 if (!*rate) {
1675 lbs_pr_alert( "The fixed data rate 0x%X is out "
1676 "of range.\n", data_rate);
1677 return -EINVAL;
1678 }
1679
1680 adapter->datarate = data_rate;
1681 action = cmd_act_set_tx_fix_rate;
1682 adapter->is_datarate_auto = 0;
1683 }
1684
1685 ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
1686 action, cmd_option_waitforrsp, 0, NULL);
1687
1688 LEAVE();
1689 return ret;
1690}
1691
1692static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
1693 struct iw_param *vwrq, char *extra)
1694{
1695 wlan_private *priv = dev->priv;
1696 wlan_adapter *adapter = priv->adapter;
1697
1698 ENTER();
1699
1700 if (adapter->is_datarate_auto) {
1701 vwrq->fixed = 0;
1702 } else {
1703 vwrq->fixed = 1;
1704 }
1705
1706 vwrq->value = adapter->datarate * 500000;
1707
1708 LEAVE();
1709 return 0;
1710}
1711
1712static int wlan_set_mode(struct net_device *dev,
1713 struct iw_request_info *info, u32 * uwrq, char *extra)
1714{
1715 int ret = 0;
1716 wlan_private *priv = dev->priv;
1717 wlan_adapter *adapter = priv->adapter;
1718 struct assoc_request * assoc_req;
1719 enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
1720
1721 ENTER();
1722
1723 switch (*uwrq) {
1724 case IW_MODE_ADHOC:
1725 lbs_pr_debug(1, "Wanted mode is ad-hoc: current datarate=%#x\n",
1726 adapter->datarate);
1727 new_mode = wlan802_11ibss;
1728 adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
1729 break;
1730
1731 case IW_MODE_INFRA:
1732 lbs_pr_debug(1, "Wanted mode is Infrastructure\n");
1733 new_mode = wlan802_11infrastructure;
1734 break;
1735
1736 case IW_MODE_AUTO:
1737 lbs_pr_debug(1, "Wanted mode is Auto\n");
1738 new_mode = wlan802_11autounknown;
1739 break;
1740
1741 default:
1742 lbs_pr_debug(1, "Wanted mode is Unknown: 0x%x\n", *uwrq);
1743 return -EINVAL;
1744 }
1745
1746 mutex_lock(&adapter->lock);
1747 assoc_req = wlan_get_association_request(adapter);
1748 if (!assoc_req) {
1749 ret = -ENOMEM;
1750 } else {
1751 assoc_req->mode = new_mode;
1752 }
1753
1754 if (ret == 0) {
1755 set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
1756 wlan_postpone_association_work(priv);
1757 } else {
1758 wlan_cancel_association_work(priv);
1759 }
1760 mutex_unlock(&adapter->lock);
1761
1762 LEAVE();
1763 return ret;
1764}
1765
1766
1767/**
1768 * @brief Get Encryption key
1769 *
1770 * @param dev A pointer to net_device structure
1771 * @param info A pointer to iw_request_info structure
1772 * @param vwrq A pointer to iw_param structure
1773 * @param extra A pointer to extra data buf
1774 * @return 0 --success, otherwise fail
1775 */
1776static int wlan_get_encode(struct net_device *dev,
1777 struct iw_request_info *info,
1778 struct iw_point *dwrq, u8 * extra)
1779{
1780 wlan_private *priv = dev->priv;
1781 wlan_adapter *adapter = priv->adapter;
1782 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1783
1784 ENTER();
1785
1786 lbs_pr_debug(1, "flags=0x%x index=%d length=%d wep_tx_keyidx=%d\n",
1787 dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx);
1788
1789 dwrq->flags = 0;
1790
1791 /* Authentication method */
1792 switch (adapter->secinfo.authmode) {
1793 case wlan802_11authmodeopen:
1794 dwrq->flags = IW_ENCODE_OPEN;
1795 break;
1796
1797 case wlan802_11authmodeshared:
1798 case wlan802_11authmodenetworkEAP:
1799 dwrq->flags = IW_ENCODE_RESTRICTED;
1800 break;
1801 default:
1802 dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN;
1803 break;
1804 }
1805
1806 if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
1807 || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
1808 dwrq->flags &= ~IW_ENCODE_DISABLED;
1809 } else {
1810 dwrq->flags |= IW_ENCODE_DISABLED;
1811 }
1812
1813 memset(extra, 0, 16);
1814
1815 mutex_lock(&adapter->lock);
1816
1817 /* Default to returning current transmit key */
1818 if (index < 0)
1819 index = adapter->wep_tx_keyidx;
1820
1821 if ((adapter->wep_keys[index].len) &&
1822 (adapter->secinfo.WEPstatus == wlan802_11WEPenabled)) {
1823 memcpy(extra, adapter->wep_keys[index].key,
1824 adapter->wep_keys[index].len);
1825 dwrq->length = adapter->wep_keys[index].len;
1826
1827 dwrq->flags |= (index + 1);
1828 /* Return WEP enabled */
1829 dwrq->flags &= ~IW_ENCODE_DISABLED;
1830 } else if ((adapter->secinfo.WPAenabled)
1831 || (adapter->secinfo.WPA2enabled)) {
1832 /* return WPA enabled */
1833 dwrq->flags &= ~IW_ENCODE_DISABLED;
1834 } else {
1835 dwrq->flags |= IW_ENCODE_DISABLED;
1836 }
1837
1838 mutex_unlock(&adapter->lock);
1839
1840 dwrq->flags |= IW_ENCODE_NOKEY;
1841
1842 lbs_pr_debug(1, "key:%02x:%02x:%02x:%02x:%02x:%02x keylen=%d\n",
1843 extra[0], extra[1], extra[2],
1844 extra[3], extra[4], extra[5], dwrq->length);
1845
1846 lbs_pr_debug(1, "Return flags=0x%x\n", dwrq->flags);
1847
1848 LEAVE();
1849 return 0;
1850}
1851
1852/**
1853 * @brief Set Encryption key (internal)
1854 *
1855 * @param priv A pointer to private card structure
1856 * @param key_material A pointer to key material
1857 * @param key_length length of key material
1858 * @param index key index to set
1859 * @param set_tx_key Force set TX key (1 = yes, 0 = no)
1860 * @return 0 --success, otherwise fail
1861 */
1862static int wlan_set_wep_key(struct assoc_request *assoc_req,
1863 const char *key_material,
1864 u16 key_length,
1865 u16 index,
1866 int set_tx_key)
1867{
1868 struct WLAN_802_11_KEY *pkey;
1869
1870 ENTER();
1871
1872 /* Paranoid validation of key index */
1873 if (index > 3) {
1874 LEAVE();
1875 return -EINVAL;
1876 }
1877
1878 /* validate max key length */
1879 if (key_length > KEY_LEN_WEP_104) {
1880 LEAVE();
1881 return -EINVAL;
1882 }
1883
1884 pkey = &assoc_req->wep_keys[index];
1885
1886 if (key_length > 0) {
1887 memset(pkey, 0, sizeof(struct WLAN_802_11_KEY));
1888 pkey->type = KEY_TYPE_ID_WEP;
1889
1890 /* Standardize the key length */
1891 pkey->len = (key_length > KEY_LEN_WEP_40) ?
1892 KEY_LEN_WEP_104 : KEY_LEN_WEP_40;
1893 memcpy(pkey->key, key_material, key_length);
1894 }
1895
1896 if (set_tx_key) {
1897 /* Ensure the chosen key is valid */
1898 if (!pkey->len) {
1899 lbs_pr_debug(1, "key not set, so cannot enable it\n");
1900 LEAVE();
1901 return -EINVAL;
1902 }
1903 assoc_req->wep_tx_keyidx = index;
1904 }
1905
1906 assoc_req->secinfo.WEPstatus = wlan802_11WEPenabled;
1907
1908 LEAVE();
1909 return 0;
1910}
1911
1912static int validate_key_index(u16 def_index, u16 raw_index,
1913 u16 *out_index, u16 *is_default)
1914{
1915 if (!out_index || !is_default)
1916 return -EINVAL;
1917
1918 /* Verify index if present, otherwise use default TX key index */
1919 if (raw_index > 0) {
1920 if (raw_index > 4)
1921 return -EINVAL;
1922 *out_index = raw_index - 1;
1923 } else {
1924 *out_index = def_index;
1925 *is_default = 1;
1926 }
1927 return 0;
1928}
1929
1930static void disable_wep(struct assoc_request *assoc_req)
1931{
1932 int i;
1933
1934 /* Set Open System auth mode */
1935 assoc_req->secinfo.authmode = wlan802_11authmodeopen;
1936
1937 /* Clear WEP keys and mark WEP as disabled */
1938 assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
1939 for (i = 0; i < 4; i++)
1940 assoc_req->wep_keys[i].len = 0;
1941
1942 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1943 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1944}
1945
1946/**
1947 * @brief Set Encryption key
1948 *
1949 * @param dev A pointer to net_device structure
1950 * @param info A pointer to iw_request_info structure
1951 * @param vwrq A pointer to iw_param structure
1952 * @param extra A pointer to extra data buf
1953 * @return 0 --success, otherwise fail
1954 */
1955static int wlan_set_encode(struct net_device *dev,
1956 struct iw_request_info *info,
1957 struct iw_point *dwrq, char *extra)
1958{
1959 int ret = 0;
1960 wlan_private *priv = dev->priv;
1961 wlan_adapter *adapter = priv->adapter;
1962 struct assoc_request * assoc_req;
1963 u16 is_default = 0, index = 0, set_tx_key = 0;
1964
1965 ENTER();
1966
1967 mutex_lock(&adapter->lock);
1968 assoc_req = wlan_get_association_request(adapter);
1969 if (!assoc_req) {
1970 ret = -ENOMEM;
1971 goto out;
1972 }
1973
1974 if (dwrq->flags & IW_ENCODE_DISABLED) {
1975 disable_wep (assoc_req);
1976 goto out;
1977 }
1978
1979 ret = validate_key_index(assoc_req->wep_tx_keyidx,
1980 (dwrq->flags & IW_ENCODE_INDEX),
1981 &index, &is_default);
1982 if (ret) {
1983 ret = -EINVAL;
1984 goto out;
1985 }
1986
1987 /* If WEP isn't enabled, or if there is no key data but a valid
1988 * index, set the TX key.
1989 */
1990 if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
1991 || (dwrq->length == 0 && !is_default))
1992 set_tx_key = 1;
1993
1994 ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
1995 if (ret)
1996 goto out;
1997
1998 if (dwrq->length)
1999 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
2000 if (set_tx_key)
2001 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
2002
2003 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
2004 assoc_req->secinfo.authmode = wlan802_11authmodeshared;
2005 } else if (dwrq->flags & IW_ENCODE_OPEN) {
2006 assoc_req->secinfo.authmode = wlan802_11authmodeopen;
2007 }
2008
2009out:
2010 if (ret == 0) {
2011 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
2012 wlan_postpone_association_work(priv);
2013 } else {
2014 wlan_cancel_association_work(priv);
2015 }
2016 mutex_unlock(&adapter->lock);
2017
2018 LEAVE();
2019 return ret;
2020}
2021
2022/**
2023 * @brief Get Extended Encryption key (WPA/802.1x and WEP)
2024 *
2025 * @param dev A pointer to net_device structure
2026 * @param info A pointer to iw_request_info structure
2027 * @param vwrq A pointer to iw_param structure
2028 * @param extra A pointer to extra data buf
2029 * @return 0 on success, otherwise failure
2030 */
2031static int wlan_get_encodeext(struct net_device *dev,
2032 struct iw_request_info *info,
2033 struct iw_point *dwrq,
2034 char *extra)
2035{
2036 int ret = -EINVAL;
2037 wlan_private *priv = dev->priv;
2038 wlan_adapter *adapter = priv->adapter;
2039 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2040 int index, max_key_len;
2041
2042 ENTER();
2043
2044 max_key_len = dwrq->length - sizeof(*ext);
2045 if (max_key_len < 0)
2046 goto out;
2047
2048 index = dwrq->flags & IW_ENCODE_INDEX;
2049 if (index) {
2050 if (index < 1 || index > 4)
2051 goto out;
2052 index--;
2053 } else {
2054 index = adapter->wep_tx_keyidx;
2055 }
2056
2057 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
2058 ext->alg != IW_ENCODE_ALG_WEP) {
2059 if (index != 0 || adapter->inframode != wlan802_11infrastructure)
2060 goto out;
2061 }
2062
2063 dwrq->flags = index + 1;
2064 memset(ext, 0, sizeof(*ext));
2065
2066 if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled)
2067 && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) {
2068 ext->alg = IW_ENCODE_ALG_NONE;
2069 ext->key_len = 0;
2070 dwrq->flags |= IW_ENCODE_DISABLED;
2071 } else {
2072 u8 *key = NULL;
2073
2074 if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
2075 && !adapter->secinfo.WPAenabled
2076 && !adapter->secinfo.WPA2enabled) {
2077 ext->alg = IW_ENCODE_ALG_WEP;
2078 ext->key_len = adapter->wep_keys[index].len;
2079 key = &adapter->wep_keys[index].key[0];
2080 } else if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) &&
2081 (adapter->secinfo.WPAenabled ||
2082 adapter->secinfo.WPA2enabled)) {
2083 /* WPA */
2084 ext->alg = IW_ENCODE_ALG_TKIP;
2085 ext->key_len = 0;
2086 } else {
2087 goto out;
2088 }
2089
2090 if (ext->key_len > max_key_len) {
2091 ret = -E2BIG;
2092 goto out;
2093 }
2094
2095 if (ext->key_len)
2096 memcpy(ext->key, key, ext->key_len);
2097 else
2098 dwrq->flags |= IW_ENCODE_NOKEY;
2099 dwrq->flags |= IW_ENCODE_ENABLED;
2100 }
2101 ret = 0;
2102
2103out:
2104 LEAVE();
2105 return ret;
2106}
2107
2108/**
2109 * @brief Set Encryption key Extended (WPA/802.1x and WEP)
2110 *
2111 * @param dev A pointer to net_device structure
2112 * @param info A pointer to iw_request_info structure
2113 * @param vwrq A pointer to iw_param structure
2114 * @param extra A pointer to extra data buf
2115 * @return 0 --success, otherwise fail
2116 */
2117static int wlan_set_encodeext(struct net_device *dev,
2118 struct iw_request_info *info,
2119 struct iw_point *dwrq,
2120 char *extra)
2121{
2122 int ret = 0;
2123 wlan_private *priv = dev->priv;
2124 wlan_adapter *adapter = priv->adapter;
2125 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2126 int alg = ext->alg;
2127 struct assoc_request * assoc_req;
2128
2129 ENTER();
2130
2131 mutex_lock(&adapter->lock);
2132 assoc_req = wlan_get_association_request(adapter);
2133 if (!assoc_req) {
2134 ret = -ENOMEM;
2135 goto out;
2136 }
2137
2138 if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
2139 disable_wep (assoc_req);
2140 } else if (alg == IW_ENCODE_ALG_WEP) {
2141 u16 is_default = 0, index, set_tx_key = 0;
2142
2143 ret = validate_key_index(assoc_req->wep_tx_keyidx,
2144 (dwrq->flags & IW_ENCODE_INDEX),
2145 &index, &is_default);
2146 if (ret)
2147 goto out;
2148
2149 /* If WEP isn't enabled, or if there is no key data but a valid
2150 * index, or if the set-TX-key flag was passed, set the TX key.
2151 */
2152 if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
2153 || (dwrq->length == 0 && !is_default)
2154 || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY))
2155 set_tx_key = 1;
2156
2157 /* Copy key to driver */
2158 ret = wlan_set_wep_key (assoc_req, ext->key, ext->key_len, index,
2159 set_tx_key);
2160 if (ret)
2161 goto out;
2162
2163 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
2164 assoc_req->secinfo.authmode =
2165 wlan802_11authmodeshared;
2166 } else if (dwrq->flags & IW_ENCODE_OPEN) {
2167 assoc_req->secinfo.authmode =
2168 wlan802_11authmodeopen;
2169 }
2170
2171 /* Mark the various WEP bits as modified */
2172 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
2173 if (dwrq->length)
2174 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
2175 if (set_tx_key)
2176 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
2177
2178 } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
2179 struct WLAN_802_11_KEY * pkey;
2180
2181 /* validate key length */
2182 if (((alg == IW_ENCODE_ALG_TKIP)
2183 && (ext->key_len != KEY_LEN_WPA_TKIP))
2184 || ((alg == IW_ENCODE_ALG_CCMP)
2185 && (ext->key_len != KEY_LEN_WPA_AES))) {
2186 lbs_pr_debug(1, "Invalid size %d for key of alg"
2187 "type %d.\n",
2188 ext->key_len,
2189 alg);
2190 ret = -EINVAL;
2191 goto out;
2192 }
2193
2194 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2195 pkey = &assoc_req->wpa_mcast_key;
2196 else
2197 pkey = &assoc_req->wpa_unicast_key;
2198
2199 memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
2200 memcpy(pkey->key, ext->key, ext->key_len);
2201 pkey->len = ext->key_len;
2202 pkey->flags = KEY_INFO_WPA_ENABLED;
2203
2204 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2205 pkey->flags |= KEY_INFO_WPA_MCAST;
2206 set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
2207 } else {
2208 pkey->flags |= KEY_INFO_WPA_UNICAST;
2209 set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
2210 }
2211
2212 if (alg == IW_ENCODE_ALG_TKIP)
2213 pkey->type = KEY_TYPE_ID_TKIP;
2214 else if (alg == IW_ENCODE_ALG_CCMP)
2215 pkey->type = KEY_TYPE_ID_AES;
2216
2217 /* If WPA isn't enabled yet, do that now */
2218 if ( assoc_req->secinfo.WPAenabled == 0
2219 && assoc_req->secinfo.WPA2enabled == 0) {
2220 assoc_req->secinfo.WPAenabled = 1;
2221 assoc_req->secinfo.WPA2enabled = 1;
2222 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
2223 }
2224
2225 disable_wep (assoc_req);
2226 }
2227
2228out:
2229 if (ret == 0) {
2230 wlan_postpone_association_work(priv);
2231 } else {
2232 wlan_cancel_association_work(priv);
2233 }
2234 mutex_unlock(&adapter->lock);
2235
2236 LEAVE();
2237 return ret;
2238}
2239
2240
2241static int wlan_set_genie(struct net_device *dev,
2242 struct iw_request_info *info,
2243 struct iw_point *dwrq,
2244 char *extra)
2245{
2246 wlan_private *priv = dev->priv;
2247 wlan_adapter *adapter = priv->adapter;
2248 int ret = 0;
2249 struct assoc_request * assoc_req;
2250
2251 ENTER();
2252
2253 mutex_lock(&adapter->lock);
2254 assoc_req = wlan_get_association_request(adapter);
2255 if (!assoc_req) {
2256 ret = -ENOMEM;
2257 goto out;
2258 }
2259
2260 if (dwrq->length > MAX_WPA_IE_LEN ||
2261 (dwrq->length && extra == NULL)) {
2262 ret = -EINVAL;
2263 goto out;
2264 }
2265
2266 if (dwrq->length) {
2267 memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length);
2268 assoc_req->wpa_ie_len = dwrq->length;
2269 } else {
2270 memset(&assoc_req->wpa_ie[0], 0, sizeof(adapter->wpa_ie));
2271 assoc_req->wpa_ie_len = 0;
2272 }
2273
2274out:
2275 if (ret == 0) {
2276 set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags);
2277 wlan_postpone_association_work(priv);
2278 } else {
2279 wlan_cancel_association_work(priv);
2280 }
2281 mutex_unlock(&adapter->lock);
2282
2283 LEAVE();
2284 return ret;
2285}
2286
2287static int wlan_get_genie(struct net_device *dev,
2288 struct iw_request_info *info,
2289 struct iw_point *dwrq,
2290 char *extra)
2291{
2292 wlan_private *priv = dev->priv;
2293 wlan_adapter *adapter = priv->adapter;
2294
2295 ENTER();
2296
2297 if (adapter->wpa_ie_len == 0) {
2298 dwrq->length = 0;
2299 LEAVE();
2300 return 0;
2301 }
2302
2303 if (dwrq->length < adapter->wpa_ie_len) {
2304 LEAVE();
2305 return -E2BIG;
2306 }
2307
2308 dwrq->length = adapter->wpa_ie_len;
2309 memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len);
2310
2311 LEAVE();
2312 return 0;
2313}
2314
2315
2316static int wlan_set_auth(struct net_device *dev,
2317 struct iw_request_info *info,
2318 struct iw_param *dwrq,
2319 char *extra)
2320{
2321 wlan_private *priv = dev->priv;
2322 wlan_adapter *adapter = priv->adapter;
2323 struct assoc_request * assoc_req;
2324 int ret = 0;
2325 int updated = 0;
2326
2327 ENTER();
2328
2329 mutex_lock(&adapter->lock);
2330 assoc_req = wlan_get_association_request(adapter);
2331 if (!assoc_req) {
2332 ret = -ENOMEM;
2333 goto out;
2334 }
2335
2336 switch (dwrq->flags & IW_AUTH_INDEX) {
2337 case IW_AUTH_TKIP_COUNTERMEASURES:
2338 case IW_AUTH_CIPHER_PAIRWISE:
2339 case IW_AUTH_CIPHER_GROUP:
2340 case IW_AUTH_KEY_MGMT:
2341 /*
2342 * libertas does not use these parameters
2343 */
2344 break;
2345
2346 case IW_AUTH_WPA_VERSION:
2347 if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
2348 assoc_req->secinfo.WPAenabled = 0;
2349 assoc_req->secinfo.WPA2enabled = 0;
2350 }
2351 if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
2352 assoc_req->secinfo.WPAenabled = 1;
2353 assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
2354 assoc_req->secinfo.authmode =
2355 wlan802_11authmodeopen;
2356 }
2357 if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) {
2358 assoc_req->secinfo.WPA2enabled = 1;
2359 assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
2360 assoc_req->secinfo.authmode =
2361 wlan802_11authmodeopen;
2362 }
2363 updated = 1;
2364 break;
2365
2366 case IW_AUTH_DROP_UNENCRYPTED:
2367 if (dwrq->value) {
2368 adapter->currentpacketfilter |=
2369 cmd_act_mac_strict_protection_enable;
2370 } else {
2371 adapter->currentpacketfilter &=
2372 ~cmd_act_mac_strict_protection_enable;
2373 }
2374 updated = 1;
2375 break;
2376
2377 case IW_AUTH_80211_AUTH_ALG:
2378 if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
2379 assoc_req->secinfo.authmode =
2380 wlan802_11authmodeshared;
2381 } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) {
2382 assoc_req->secinfo.authmode =
2383 wlan802_11authmodeopen;
2384 } else if (dwrq->value & IW_AUTH_ALG_LEAP) {
2385 assoc_req->secinfo.authmode =
2386 wlan802_11authmodenetworkEAP;
2387 } else {
2388 ret = -EINVAL;
2389 }
2390 updated = 1;
2391 break;
2392
2393 case IW_AUTH_WPA_ENABLED:
2394 if (dwrq->value) {
2395 if (!assoc_req->secinfo.WPAenabled &&
2396 !assoc_req->secinfo.WPA2enabled) {
2397 assoc_req->secinfo.WPAenabled = 1;
2398 assoc_req->secinfo.WPA2enabled = 1;
2399 assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
2400 assoc_req->secinfo.authmode =
2401 wlan802_11authmodeopen;
2402 }
2403 } else {
2404 assoc_req->secinfo.WPAenabled = 0;
2405 assoc_req->secinfo.WPA2enabled = 0;
2406 }
2407 updated = 1;
2408 break;
2409
2410 default:
2411 ret = -EOPNOTSUPP;
2412 break;
2413 }
2414
2415out:
2416 if (ret == 0) {
2417 if (updated)
2418 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
2419 wlan_postpone_association_work(priv);
2420 } else if (ret != -EOPNOTSUPP) {
2421 wlan_cancel_association_work(priv);
2422 }
2423 mutex_unlock(&adapter->lock);
2424
2425 LEAVE();
2426 return ret;
2427}
2428
2429static int wlan_get_auth(struct net_device *dev,
2430 struct iw_request_info *info,
2431 struct iw_param *dwrq,
2432 char *extra)
2433{
2434 wlan_private *priv = dev->priv;
2435 wlan_adapter *adapter = priv->adapter;
2436
2437 ENTER();
2438
2439 switch (dwrq->flags & IW_AUTH_INDEX) {
2440 case IW_AUTH_WPA_VERSION:
2441 dwrq->value = 0;
2442 if (adapter->secinfo.WPAenabled)
2443 dwrq->value |= IW_AUTH_WPA_VERSION_WPA;
2444 if (adapter->secinfo.WPA2enabled)
2445 dwrq->value |= IW_AUTH_WPA_VERSION_WPA2;
2446 if (!dwrq->value)
2447 dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
2448 break;
2449
2450 case IW_AUTH_DROP_UNENCRYPTED:
2451 dwrq->value = 0;
2452 if (adapter->currentpacketfilter &
2453 cmd_act_mac_strict_protection_enable)
2454 dwrq->value = 1;
2455 break;
2456
2457 case IW_AUTH_80211_AUTH_ALG:
2458 switch (adapter->secinfo.authmode) {
2459 case wlan802_11authmodeshared:
2460 dwrq->value = IW_AUTH_ALG_SHARED_KEY;
2461 break;
2462 case wlan802_11authmodeopen:
2463 dwrq->value = IW_AUTH_ALG_OPEN_SYSTEM;
2464 break;
2465 case wlan802_11authmodenetworkEAP:
2466 dwrq->value = IW_AUTH_ALG_LEAP;
2467 break;
2468 default:
2469 break;
2470 }
2471 break;
2472
2473 case IW_AUTH_WPA_ENABLED:
2474 if (adapter->secinfo.WPAenabled && adapter->secinfo.WPA2enabled)
2475 dwrq->value = 1;
2476 break;
2477
2478 default:
2479 LEAVE();
2480 return -EOPNOTSUPP;
2481 }
2482
2483 LEAVE();
2484 return 0;
2485}
2486
2487
2488static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
2489 struct iw_param *vwrq, char *extra)
2490{
2491 int ret = 0;
2492 wlan_private *priv = dev->priv;
2493 wlan_adapter *adapter = priv->adapter;
2494
2495 u16 dbm;
2496
2497 ENTER();
2498
2499 if (vwrq->disabled) {
2500 wlan_radio_ioctl(priv, RADIO_OFF);
2501 return 0;
2502 }
2503
2504 adapter->preamble = cmd_type_auto_preamble;
2505
2506 wlan_radio_ioctl(priv, RADIO_ON);
2507
2508 if ((vwrq->flags & IW_TXPOW_TYPE) == IW_TXPOW_MWATT) {
2509 dbm = (u16) mw_to_dbm(vwrq->value);
2510 } else
2511 dbm = (u16) vwrq->value;
2512
2513 /* auto tx power control */
2514
2515 if (vwrq->fixed == 0)
2516 dbm = 0xffff;
2517
2518 lbs_pr_debug(1, "<1>TXPOWER SET %d dbm.\n", dbm);
2519
2520 ret = libertas_prepare_and_send_command(priv,
2521 cmd_802_11_rf_tx_power,
2522 cmd_act_tx_power_opt_set_low,
2523 cmd_option_waitforrsp, 0, (void *)&dbm);
2524
2525 LEAVE();
2526 return ret;
2527}
2528
2529static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
2530 struct iw_point *dwrq, char *extra)
2531{
2532 wlan_private *priv = dev->priv;
2533 wlan_adapter *adapter = priv->adapter;
2534
2535 ENTER();
2536 /*
2537 * Note : if dwrq->flags != 0, we should get the relevant SSID from
2538 * the SSID list...
2539 */
2540
2541 /*
2542 * Get the current SSID
2543 */
2544 if (adapter->connect_status == libertas_connected) {
2545 memcpy(extra, adapter->curbssparams.ssid.ssid,
2546 adapter->curbssparams.ssid.ssidlength);
2547 extra[adapter->curbssparams.ssid.ssidlength] = '\0';
2548 } else {
2549 memset(extra, 0, 32);
2550 extra[adapter->curbssparams.ssid.ssidlength] = '\0';
2551 }
2552 /*
2553 * If none, we may want to get the one that was set
2554 */
2555
2556 /* To make the driver backward compatible with WPA supplicant v0.2.4 */
2557 if (dwrq->length == 32) /* check with WPA supplicant buffer size */
2558 dwrq->length = min_t(size_t, adapter->curbssparams.ssid.ssidlength,
2559 IW_ESSID_MAX_SIZE);
2560 else
2561 dwrq->length = adapter->curbssparams.ssid.ssidlength + 1;
2562
2563 dwrq->flags = 1; /* active */
2564
2565 LEAVE();
2566 return 0;
2567}
2568
2569static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
2570 struct iw_point *dwrq, char *extra)
2571{
2572 wlan_private *priv = dev->priv;
2573 wlan_adapter *adapter = priv->adapter;
2574 int ret = 0;
2575 struct WLAN_802_11_SSID ssid;
2576 struct assoc_request * assoc_req;
2577 int ssid_len = dwrq->length;
2578
2579 ENTER();
2580
2581 /*
2582 * WE-20 and earlier NULL pad the end of the SSID and increment
2583 * SSID length so it can be used like a string. WE-21 and later don't,
2584 * but some userspace tools aren't able to cope with the change.
2585 */
2586 if ((ssid_len > 0) && (extra[ssid_len - 1] == '\0'))
2587 ssid_len--;
2588
2589 /* Check the size of the string */
2590 if (ssid_len > IW_ESSID_MAX_SIZE) {
2591 ret = -E2BIG;
2592 goto out;
2593 }
2594
2595 memset(&ssid, 0, sizeof(struct WLAN_802_11_SSID));
2596
2597 if (!dwrq->flags || !ssid_len) {
2598 /* "any" SSID requested; leave SSID blank */
2599 } else {
2600 /* Specific SSID requested */
2601 memcpy(&ssid.ssid, extra, ssid_len);
2602 ssid.ssidlength = ssid_len;
2603 }
2604
2605 lbs_pr_debug(1, "Requested new SSID = %s\n",
2606 (ssid.ssidlength > 0) ? (char *)ssid.ssid : "any");
2607
2608out:
2609 mutex_lock(&adapter->lock);
2610 if (ret == 0) {
2611 /* Get or create the current association request */
2612 assoc_req = wlan_get_association_request(adapter);
2613 if (!assoc_req) {
2614 ret = -ENOMEM;
2615 } else {
2616 /* Copy the SSID to the association request */
2617 memcpy(&assoc_req->ssid, &ssid, sizeof(struct WLAN_802_11_SSID));
2618 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
2619 wlan_postpone_association_work(priv);
2620 }
2621 }
2622
2623 /* Cancel the association request if there was an error */
2624 if (ret != 0) {
2625 wlan_cancel_association_work(priv);
2626 }
2627
2628 mutex_unlock(&adapter->lock);
2629
2630 LEAVE();
2631 return ret;
2632}
2633
2634/**
2635 * @brief Connect to the AP or Ad-hoc Network with specific bssid
2636 *
2637 * @param dev A pointer to net_device structure
2638 * @param info A pointer to iw_request_info structure
2639 * @param awrq A pointer to iw_param structure
2640 * @param extra A pointer to extra data buf
2641 * @return 0 --success, otherwise fail
2642 */
2643static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
2644 struct sockaddr *awrq, char *extra)
2645{
2646 wlan_private *priv = dev->priv;
2647 wlan_adapter *adapter = priv->adapter;
2648 struct assoc_request * assoc_req;
2649 int ret = 0;
2650
2651 ENTER();
2652
2653 if (awrq->sa_family != ARPHRD_ETHER)
2654 return -EINVAL;
2655
2656 lbs_pr_debug(1, "ASSOC: WAP: sa_data: " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
2657
2658 mutex_lock(&adapter->lock);
2659
2660 /* Get or create the current association request */
2661 assoc_req = wlan_get_association_request(adapter);
2662 if (!assoc_req) {
2663 wlan_cancel_association_work(priv);
2664 ret = -ENOMEM;
2665 } else {
2666 /* Copy the BSSID to the association request */
2667 memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN);
2668 set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags);
2669 wlan_postpone_association_work(priv);
2670 }
2671
2672 mutex_unlock(&adapter->lock);
2673
2674 return ret;
2675}
2676
2677void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
2678{
2679 union {
2680 u32 l;
2681 u8 c[4];
2682 } ver;
2683 char fwver[32];
2684
2685 mutex_lock(&adapter->lock);
2686 ver.l = adapter->fwreleasenumber;
2687 mutex_unlock(&adapter->lock);
2688
2689 if (ver.c[3] == 0)
2690 sprintf(fwver, "%u.%u.%u", ver.c[2], ver.c[1], ver.c[0]);
2691 else
2692 sprintf(fwver, "%u.%u.%u.p%u",
2693 ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
2694
2695 snprintf(fwversion, maxlen, fwver);
2696}
2697
2698
2699/*
2700 * iwconfig settable callbacks
2701 */
2702static const iw_handler wlan_handler[] = {
2703 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2704 (iw_handler) wlan_get_name, /* SIOCGIWNAME */
2705 (iw_handler) NULL, /* SIOCSIWNWID */
2706 (iw_handler) NULL, /* SIOCGIWNWID */
2707 (iw_handler) wlan_set_freq, /* SIOCSIWFREQ */
2708 (iw_handler) wlan_get_freq, /* SIOCGIWFREQ */
2709 (iw_handler) wlan_set_mode, /* SIOCSIWMODE */
2710 (iw_handler) wlan_get_mode, /* SIOCGIWMODE */
2711 (iw_handler) NULL, /* SIOCSIWSENS */
2712 (iw_handler) NULL, /* SIOCGIWSENS */
2713 (iw_handler) NULL, /* SIOCSIWRANGE */
2714 (iw_handler) wlan_get_range, /* SIOCGIWRANGE */
2715 (iw_handler) NULL, /* SIOCSIWPRIV */
2716 (iw_handler) NULL, /* SIOCGIWPRIV */
2717 (iw_handler) NULL, /* SIOCSIWSTATS */
2718 (iw_handler) NULL, /* SIOCGIWSTATS */
2719 iw_handler_set_spy, /* SIOCSIWSPY */
2720 iw_handler_get_spy, /* SIOCGIWSPY */
2721 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2722 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2723 (iw_handler) wlan_set_wap, /* SIOCSIWAP */
2724 (iw_handler) wlan_get_wap, /* SIOCGIWAP */
2725 (iw_handler) NULL, /* SIOCSIWMLME */
2726 (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
2727 (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
2728 (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
2729 (iw_handler) wlan_set_essid, /* SIOCSIWESSID */
2730 (iw_handler) wlan_get_essid, /* SIOCGIWESSID */
2731 (iw_handler) wlan_set_nick, /* SIOCSIWNICKN */
2732 (iw_handler) wlan_get_nick, /* SIOCGIWNICKN */
2733 (iw_handler) NULL, /* -- hole -- */
2734 (iw_handler) NULL, /* -- hole -- */
2735 (iw_handler) wlan_set_rate, /* SIOCSIWRATE */
2736 (iw_handler) wlan_get_rate, /* SIOCGIWRATE */
2737 (iw_handler) wlan_set_rts, /* SIOCSIWRTS */
2738 (iw_handler) wlan_get_rts, /* SIOCGIWRTS */
2739 (iw_handler) wlan_set_frag, /* SIOCSIWFRAG */
2740 (iw_handler) wlan_get_frag, /* SIOCGIWFRAG */
2741 (iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */
2742 (iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */
2743 (iw_handler) wlan_set_retry, /* SIOCSIWRETRY */
2744 (iw_handler) wlan_get_retry, /* SIOCGIWRETRY */
2745 (iw_handler) wlan_set_encode, /* SIOCSIWENCODE */
2746 (iw_handler) wlan_get_encode, /* SIOCGIWENCODE */
2747 (iw_handler) wlan_set_power, /* SIOCSIWPOWER */
2748 (iw_handler) wlan_get_power, /* SIOCGIWPOWER */
2749 (iw_handler) NULL, /* -- hole -- */
2750 (iw_handler) NULL, /* -- hole -- */
2751 (iw_handler) wlan_set_genie, /* SIOCSIWGENIE */
2752 (iw_handler) wlan_get_genie, /* SIOCGIWGENIE */
2753 (iw_handler) wlan_set_auth, /* SIOCSIWAUTH */
2754 (iw_handler) wlan_get_auth, /* SIOCGIWAUTH */
2755 (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
2756 (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
2757 (iw_handler) NULL, /* SIOCSIWPMKSA */
2758};
2759
2760struct iw_handler_def libertas_handler_def = {
2761 .num_standard = sizeof(wlan_handler) / sizeof(iw_handler),
2762 .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler),
2763 .num_private_args = sizeof(wlan_private_args) /
2764 sizeof(struct iw_priv_args),
2765 .standard = (iw_handler *) wlan_handler,
2766 .private = (iw_handler *) wlan_private_handler,
2767 .private_args = (struct iw_priv_args *)wlan_private_args,
2768 .get_wireless_stats = wlan_get_wireless_stats,
2769};
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
new file mode 100644
index 000000000000..39f367c38d90
--- /dev/null
+++ b/drivers/net/wireless/libertas/wext.h
@@ -0,0 +1,147 @@
1/**
2 * This file contains definition for IOCTL call.
3 */
4#ifndef _WLAN_WEXT_H_
5#define _WLAN_WEXT_H_
6
7#define SUBCMD_OFFSET 4
8#define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET))
9
10/** PRIVATE CMD ID */
11#define WLANIOCTL SIOCIWFIRSTPRIV
12
13#define WLANSETWPAIE (WLANIOCTL + 0)
14
15#define WLAN_SETINT_GETINT (WLANIOCTL + 7)
16#define WLANNF 1
17#define WLANRSSI 2
18#define WLANENABLE11D 5
19#define WLANADHOCGRATE 6
20#define WLAN_SUBCMD_SET_PRESCAN 11
21
22#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8)
23#define WLANDEAUTH 1
24#define WLANRADIOON 2
25#define WLANRADIOOFF 3
26#define WLANREMOVEADHOCAES 4
27#define WLANADHOCSTOP 5
28#define WLANCIPHERTEST 6
29#define WLANCRYPTOTEST 7
30
31#define WLANWLANIDLEON 10
32#define WLANWLANIDLEOFF 11
33#define WLAN_SUBCMD_BT_RESET 13
34#define WLAN_SUBCMD_FWT_RESET 14
35
36#define WLANGETLOG (WLANIOCTL + 9)
37#define GETLOG_BUFSIZE 300
38
39#define WLANSCAN_TYPE (WLANIOCTL + 11)
40
41#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15)
42#define WLANGETREGION 1
43#define WLAN_GET_LISTEN_INTERVAL 2
44#define WLAN_GET_MULTIPLE_DTIM 3
45#define WLAN_GET_TX_RATE 4
46#define WLANGETBCNAVG 5
47
48#define WLAN_GET_LINKMODE 6
49#define WLAN_GET_RADIOMODE 7
50#define WLAN_GET_DEBUGMODE 8
51#define WLAN_SUBCMD_FWT_CLEANUP 15
52#define WLAN_SUBCMD_FWT_TIME 16
53#define WLAN_SUBCMD_MESH_GET_TTL 17
54
55#define WLANREGCFRDWR (WLANIOCTL + 18)
56
57#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19)
58#define WLAN_SUBCMD_GETRXANTENNA 1
59#define WLAN_SUBCMD_GETTXANTENNA 2
60#define WLAN_GET_TSF 3
61
62#define WLAN_SETNONE_GETWORDCHAR (WLANIOCTL + 21)
63#define WLANGETADHOCAES 1
64
65#define WLAN_SETONEINT_GETONEINT (WLANIOCTL + 23)
66#define WLAN_BEACON_INTERVAL 1
67#define WLAN_LISTENINTRVL 4
68
69#define WLAN_TXCONTROL 6
70#define WLAN_NULLPKTINTERVAL 7
71
72#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24)
73#define WLAN_SUBCMD_SETRXANTENNA 1
74#define WLAN_SUBCMD_SETTXANTENNA 2
75#define WLANSETAUTHALG 5
76#define WLANSET8021XAUTHALG 6
77#define WLANSETENCRYPTIONMODE 7
78#define WLANSETREGION 8
79#define WLAN_SET_LISTEN_INTERVAL 9
80
81#define WLAN_SET_MULTIPLE_DTIM 10
82#define WLAN_SET_ATIM_WINDOW 11
83#define WLANSETBCNAVG 13
84#define WLANSETDATAAVG 14
85#define WLAN_SET_LINKMODE 15
86#define WLAN_SET_RADIOMODE 16
87#define WLAN_SET_DEBUGMODE 17
88#define WLAN_SUBCMD_MESH_SET_TTL 18
89
90#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25)
91#define WLANSCAN_MODE 6
92
93#define WLAN_GET_ADHOC_STATUS 9
94
95#define WLAN_SUBCMD_BT_ADD 18
96#define WLAN_SUBCMD_BT_DEL 19
97#define WLAN_SUBCMD_BT_LIST 20
98#define WLAN_SUBCMD_FWT_ADD 21
99#define WLAN_SUBCMD_FWT_DEL 22
100#define WLAN_SUBCMD_FWT_LOOKUP 23
101#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24
102#define WLAN_SUBCMD_FWT_LIST 25
103#define WLAN_SUBCMD_FWT_LIST_ROUTE 26
104
105#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29)
106#define WLAN_TPCCFG 1
107#define WLAN_POWERCFG 2
108
109#define WLAN_AUTO_FREQ_SET 3
110#define WLAN_AUTO_FREQ_GET 4
111#define WLAN_LED_GPIO_CTRL 5
112#define WLAN_SCANPROBES 6
113#define WLAN_ADAPT_RATESET 8
114#define WLAN_INACTIVITY_TIMEOUT 9
115#define WLANSNR 10
116#define WLAN_GET_RATE 11
117#define WLAN_GET_RXINFO 12
118
119#define WLANCMD52RDWR (WLANIOCTL + 30)
120#define WLANCMD53RDWR (WLANIOCTL + 31)
121#define CMD53BUFLEN 32
122
123#define REG_MAC 0x19
124#define REG_BBP 0x1a
125#define REG_RF 0x1b
126#define REG_EEPROM 0x59
127#define WLAN_LINKMODE_802_3 0
128#define WLAN_LINKMODE_802_11 2
129#define WLAN_RADIOMODE_NONE 0
130#define WLAN_RADIOMODE_RADIOTAP 2
131
132/** wlan_ioctl_regrdwr */
133struct wlan_ioctl_regrdwr {
134 /** Which register to access */
135 u16 whichreg;
136 /** Read or Write */
137 u16 action;
138 u32 offset;
139 u16 NOB;
140 u32 value;
141};
142
143extern struct iw_handler_def libertas_handler_def;
144int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i);
145int wlan_radio_ioctl(wlan_private * priv, u8 option);
146
147#endif /* _WLAN_WEXT_H_ */
diff --git a/drivers/net/wireless/todo.txt b/drivers/net/wireless/todo.txt
deleted file mode 100644
index 32234018de72..000000000000
--- a/drivers/net/wireless/todo.txt
+++ /dev/null
@@ -1,15 +0,0 @@
1 Wireless Todo
2 -------------
3
41) Bring other kernel Wireless LAN drivers here
5 Completed
6
72) Bring new Wireless LAN driver not yet in the kernel there
8 See my web page for details
9 In particular : HostAP
10
113) Misc
12 o Mark wavelan, wavelan_cs, netwave_cs drivers as obsolete
13 o Maybe arlan.c, ray_cs.c and strip.c also deserve to be obsolete
14
15 Jean II
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 87ee3ee020fe..95b4a2a26707 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -67,11 +67,12 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
67 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i); 67 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
68 i += scnprintf(buffer+i, size-i, " "); 68 i += scnprintf(buffer+i, size-i, " ");
69 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i); 69 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
70 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type, 70 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
71 chip->patch_cck_gain ? 'g' : '-', 71 chip->patch_cck_gain ? 'g' : '-',
72 chip->patch_cr157 ? '7' : '-', 72 chip->patch_cr157 ? '7' : '-',
73 chip->patch_6m_band_edge ? '6' : '-', 73 chip->patch_6m_band_edge ? '6' : '-',
74 chip->new_phy_layout ? 'N' : '-'); 74 chip->new_phy_layout ? 'N' : '-',
75 chip->al2230s_bit ? 'S' : '-');
75 return i; 76 return i;
76} 77}
77 78
@@ -114,7 +115,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
114 /* Allocate a single memory block for values and addresses. */ 115 /* Allocate a single memory block for values and addresses. */
115 count16 = 2*count; 116 count16 = 2*count;
116 a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), 117 a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
117 GFP_NOFS); 118 GFP_KERNEL);
118 if (!a16) { 119 if (!a16) {
119 dev_dbg_f(zd_chip_dev(chip), 120 dev_dbg_f(zd_chip_dev(chip),
120 "error ENOMEM in allocation of a16\n"); 121 "error ENOMEM in allocation of a16\n");
@@ -163,7 +164,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
163 164
164 /* Allocate a single memory block for values and addresses. */ 165 /* Allocate a single memory block for values and addresses. */
165 count16 = 2*count; 166 count16 = 2*count;
166 ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_NOFS); 167 ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
167 if (!ioreqs16) { 168 if (!ioreqs16) {
168 r = -ENOMEM; 169 r = -ENOMEM;
169 dev_dbg_f(zd_chip_dev(chip), 170 dev_dbg_f(zd_chip_dev(chip),
@@ -614,16 +615,24 @@ static int patch_cr157(struct zd_chip *chip)
614 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge 615 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
615 * bit (for AL2230, AL2230S) 616 * bit (for AL2230, AL2230S)
616 */ 617 */
617static int patch_6m_band_edge(struct zd_chip *chip, int channel) 618static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
619{
620 ZD_ASSERT(mutex_is_locked(&chip->mutex));
621 if (!chip->patch_6m_band_edge)
622 return 0;
623
624 return zd_rf_patch_6m_band_edge(&chip->rf, channel);
625}
626
627/* Generic implementation of 6M band edge patching, used by most RFs via
628 * zd_rf_generic_patch_6m() */
629int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
618{ 630{
619 struct zd_ioreq16 ioreqs[] = { 631 struct zd_ioreq16 ioreqs[] = {
620 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 632 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
621 { CR47, 0x1e }, 633 { CR47, 0x1e },
622 }; 634 };
623 635
624 if (!chip->patch_6m_band_edge || !chip->rf.patch_6m_band_edge)
625 return 0;
626
627 /* FIXME: Channel 11 is not the edge for all regulatory domains. */ 636 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
628 if (channel == 1 || channel == 11) 637 if (channel == 1 || channel == 11)
629 ioreqs[0].value = 0x12; 638 ioreqs[0].value = 0x12;
@@ -683,17 +692,17 @@ static int zd1211_hw_reset_phy(struct zd_chip *chip)
683 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, 692 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
684 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, 693 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
685 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f }, 694 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
686 { CR123, 0x27 }, { CR125, 0xaa }, { CR127, 0x03 }, 695 { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
687 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 696 { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
688 { CR131, 0x0C }, { CR136, 0xdf }, { CR137, 0x40 }, 697 { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
689 { CR138, 0xa0 }, { CR139, 0xb0 }, { CR140, 0x99 }, 698 { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
690 { CR141, 0x82 }, { CR142, 0x54 }, { CR143, 0x1c }, 699 { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
691 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x4c }, 700 { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
692 { CR149, 0x50 }, { CR150, 0x0e }, { CR151, 0x18 }, 701 { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
693 { CR160, 0xfe }, { CR161, 0xee }, { CR162, 0xaa }, 702 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
694 { CR163, 0xfa }, { CR164, 0xfa }, { CR165, 0xea }, 703 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
695 { CR166, 0xbe }, { CR167, 0xbe }, { CR168, 0x6a }, 704 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
696 { CR169, 0xba }, { CR170, 0xba }, { CR171, 0xba }, 705 { CR170, 0xba }, { CR171, 0xba },
697 /* Note: CR204 must lead the CR203 */ 706 /* Note: CR204 must lead the CR203 */
698 { CR204, 0x7d }, 707 { CR204, 0x7d },
699 { }, 708 { },
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index e57ed75d9425..ce0a5f6da0d2 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -833,6 +833,7 @@ int zd_chip_enable_rx(struct zd_chip *chip);
833void zd_chip_disable_rx(struct zd_chip *chip); 833void zd_chip_disable_rx(struct zd_chip *chip);
834int zd_chip_enable_hwint(struct zd_chip *chip); 834int zd_chip_enable_hwint(struct zd_chip *chip);
835int zd_chip_disable_hwint(struct zd_chip *chip); 835int zd_chip_disable_hwint(struct zd_chip *chip);
836int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel);
836 837
837int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, 838int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
838 u8 rts_rate, int preamble); 839 u8 rts_rate, int preamble);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 4c5f78eac349..6753d240c168 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -156,17 +156,8 @@ void zd_mac_clear(struct zd_mac *mac)
156static int reset_mode(struct zd_mac *mac) 156static int reset_mode(struct zd_mac *mac)
157{ 157{
158 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); 158 struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
159 struct zd_ioreq32 ioreqs[] = { 159 u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER;
160 { CR_RX_FILTER, STA_RX_FILTER }, 160 return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
161 { CR_SNIFFER_ON, 0U },
162 };
163
164 if (ieee->iw_mode == IW_MODE_MONITOR) {
165 ioreqs[0].value = 0xffffffff;
166 ioreqs[1].value = 0x1;
167 }
168
169 return zd_iowrite32a(&mac->chip, ioreqs, ARRAY_SIZE(ioreqs));
170} 161}
171 162
172int zd_mac_open(struct net_device *netdev) 163int zd_mac_open(struct net_device *netdev)
@@ -974,14 +965,14 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee,
974 switch (ieee->iw_mode) { 965 switch (ieee->iw_mode) {
975 case IW_MODE_ADHOC: 966 case IW_MODE_ADHOC:
976 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 || 967 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
977 memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0) 968 compare_ether_addr(hdr->addr3, ieee->bssid) != 0)
978 return 0; 969 return 0;
979 break; 970 break;
980 case IW_MODE_AUTO: 971 case IW_MODE_AUTO:
981 case IW_MODE_INFRA: 972 case IW_MODE_INFRA:
982 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 973 if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
983 IEEE80211_FCTL_FROMDS || 974 IEEE80211_FCTL_FROMDS ||
984 memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0) 975 compare_ether_addr(hdr->addr2, ieee->bssid) != 0)
985 return 0; 976 return 0;
986 break; 977 break;
987 default: 978 default:
@@ -989,9 +980,9 @@ static int is_data_packet_for_us(struct ieee80211_device *ieee,
989 return 0; 980 return 0;
990 } 981 }
991 982
992 return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 || 983 return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 ||
993 (is_multicast_ether_addr(hdr->addr1) && 984 (is_multicast_ether_addr(hdr->addr1) &&
994 memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) || 985 compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) ||
995 (netdev->flags & IFF_PROMISC); 986 (netdev->flags & IFF_PROMISC);
996} 987}
997 988
@@ -1047,7 +1038,7 @@ static void update_qual_rssi(struct zd_mac *mac,
1047 hdr = (struct ieee80211_hdr_3addr *)buffer; 1038 hdr = (struct ieee80211_hdr_3addr *)buffer;
1048 if (length < offsetof(struct ieee80211_hdr_3addr, addr3)) 1039 if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
1049 return; 1040 return;
1050 if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0) 1041 if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0)
1051 return; 1042 return;
1052 1043
1053 spin_lock_irqsave(&mac->lock, flags); 1044 spin_lock_irqsave(&mac->lock, flags);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index f50cff3db916..549c23bcd6cc 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -23,7 +23,7 @@
23#include "zd_ieee80211.h" 23#include "zd_ieee80211.h"
24#include "zd_chip.h" 24#include "zd_chip.h"
25 25
26static const char *rfs[] = { 26static const char * const rfs[] = {
27 [0] = "unknown RF0", 27 [0] = "unknown RF0",
28 [1] = "unknown RF1", 28 [1] = "unknown RF1",
29 [UW2451_RF] = "UW2451_RF", 29 [UW2451_RF] = "UW2451_RF",
@@ -34,7 +34,7 @@ static const char *rfs[] = {
34 [AL2210_RF] = "AL2210_RF", 34 [AL2210_RF] = "AL2210_RF",
35 [MAXIM_NEW_RF] = "MAXIM_NEW_RF", 35 [MAXIM_NEW_RF] = "MAXIM_NEW_RF",
36 [UW2453_RF] = "UW2453_RF", 36 [UW2453_RF] = "UW2453_RF",
37 [AL2230S_RF] = "AL2230S_RF", 37 [UNKNOWN_A_RF] = "UNKNOWN_A_RF",
38 [RALINK_RF] = "RALINK_RF", 38 [RALINK_RF] = "RALINK_RF",
39 [INTERSIL_RF] = "INTERSIL_RF", 39 [INTERSIL_RF] = "INTERSIL_RF",
40 [RF2959_RF] = "RF2959_RF", 40 [RF2959_RF] = "RF2959_RF",
@@ -154,3 +154,17 @@ int zd_switch_radio_off(struct zd_rf *rf)
154 r = t; 154 r = t;
155 return r; 155 return r;
156} 156}
157
158int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel)
159{
160 if (!rf->patch_6m_band_edge)
161 return 0;
162
163 return rf->patch_6m_band_edge(rf, channel);
164}
165
166int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel)
167{
168 return zd_chip_generic_patch_6m_band(zd_rf_to_chip(rf), channel);
169}
170
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index a57732eb69e1..aa9cc105ce60 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -26,7 +26,7 @@
26#define AL2210_RF 0x7 26#define AL2210_RF 0x7
27#define MAXIM_NEW_RF 0x8 27#define MAXIM_NEW_RF 0x8
28#define UW2453_RF 0x9 28#define UW2453_RF 0x9
29#define AL2230S_RF 0xa 29#define UNKNOWN_A_RF 0xa
30#define RALINK_RF 0xb 30#define RALINK_RF 0xb
31#define INTERSIL_RF 0xc 31#define INTERSIL_RF 0xc
32#define RF2959_RF 0xd 32#define RF2959_RF 0xd
@@ -47,17 +47,13 @@ struct zd_rf {
47 u8 type; 47 u8 type;
48 48
49 u8 channel; 49 u8 channel;
50 /*
51 * Whether this RF should patch the 6M band edge
52 * (assuming E2P_POD agrees)
53 */
54 u8 patch_6m_band_edge:1;
55 50
56 /* RF-specific functions */ 51 /* RF-specific functions */
57 int (*init_hw)(struct zd_rf *rf); 52 int (*init_hw)(struct zd_rf *rf);
58 int (*set_channel)(struct zd_rf *rf, u8 channel); 53 int (*set_channel)(struct zd_rf *rf, u8 channel);
59 int (*switch_radio_on)(struct zd_rf *rf); 54 int (*switch_radio_on)(struct zd_rf *rf);
60 int (*switch_radio_off)(struct zd_rf *rf); 55 int (*switch_radio_off)(struct zd_rf *rf);
56 int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel);
61}; 57};
62 58
63const char *zd_rf_name(u8 type); 59const char *zd_rf_name(u8 type);
@@ -72,6 +68,9 @@ int zd_rf_set_channel(struct zd_rf *rf, u8 channel);
72int zd_switch_radio_on(struct zd_rf *rf); 68int zd_switch_radio_on(struct zd_rf *rf);
73int zd_switch_radio_off(struct zd_rf *rf); 69int zd_switch_radio_off(struct zd_rf *rf);
74 70
71int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
72int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
73
75/* Functions for individual RF chips */ 74/* Functions for individual RF chips */
76 75
77int zd_rf_init_rf2959(struct zd_rf *rf); 76int zd_rf_init_rf2959(struct zd_rf *rf);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 5235a7827ac5..511392acfedf 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -59,6 +59,18 @@ static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
59 { CR240, 0x57 }, { CR9, 0xe0 }, 59 { CR240, 0x57 }, { CR9, 0xe0 },
60}; 60};
61 61
62static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
63 { CR47, 0x1e }, /* MARK_002 */
64 { CR106, 0x22 },
65 { CR107, 0x2a }, /* MARK_002 */
66 { CR109, 0x13 }, /* MARK_002 */
67 { CR118, 0xf8 }, /* MARK_002 */
68 { CR119, 0x12 }, { CR122, 0xe0 },
69 { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
70 { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
71 { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
72};
73
62static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) 74static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
63{ 75{
64 int r; 76 int r;
@@ -90,7 +102,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
90 int r; 102 int r;
91 struct zd_chip *chip = zd_rf_to_chip(rf); 103 struct zd_chip *chip = zd_rf_to_chip(rf);
92 104
93 static const struct zd_ioreq16 ioreqs[] = { 105 static const struct zd_ioreq16 ioreqs_init[] = {
94 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, 106 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
95 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, 107 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
96 { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a }, 108 { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a },
@@ -117,10 +129,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
117 { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 }, 129 { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 },
118 { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff }, 130 { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff },
119 { CR253, 0xff }, 131 { CR253, 0xff },
132 };
120 133
121 /* These following happen separately in the vendor driver */ 134 static const struct zd_ioreq16 ioreqs_pll[] = {
122 { },
123
124 /* shdnb(PLL_ON)=0 */ 135 /* shdnb(PLL_ON)=0 */
125 { CR251, 0x2f }, 136 { CR251, 0x2f },
126 /* shdnb(PLL_ON)=1 */ 137 /* shdnb(PLL_ON)=1 */
@@ -128,7 +139,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
128 { CR138, 0x28 }, { CR203, 0x06 }, 139 { CR138, 0x28 }, { CR203, 0x06 },
129 }; 140 };
130 141
131 static const u32 rv[] = { 142 static const u32 rv1[] = {
132 /* Channel 1 */ 143 /* Channel 1 */
133 0x03f790, 144 0x03f790,
134 0x033331, 145 0x033331,
@@ -137,6 +148,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
137 0x0b3331, 148 0x0b3331,
138 0x03b812, 149 0x03b812,
139 0x00fff3, 150 0x00fff3,
151 };
152
153 static const u32 rv2[] = {
140 0x000da4, 154 0x000da4,
141 0x0f4dc5, /* fix freq shift, 0x04edc5 */ 155 0x0f4dc5, /* fix freq shift, 0x04edc5 */
142 0x0805b6, 156 0x0805b6,
@@ -148,8 +162,9 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
148 0x0bdffc, 162 0x0bdffc,
149 0x00000d, 163 0x00000d,
150 0x00500f, 164 0x00500f,
165 };
151 166
152 /* These writes happen separately in the vendor driver */ 167 static const u32 rv3[] = {
153 0x00d00f, 168 0x00d00f,
154 0x004c0f, 169 0x004c0f,
155 0x00540f, 170 0x00540f,
@@ -157,11 +172,38 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
157 0x00500f, 172 0x00500f,
158 }; 173 };
159 174
160 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 175 r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init));
161 if (r) 176 if (r)
162 return r; 177 return r;
163 178
164 r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); 179 if (chip->al2230s_bit) {
180 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
181 ARRAY_SIZE(ioreqs_init_al2230s));
182 if (r)
183 return r;
184 }
185
186 r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS);
187 if (r)
188 return r;
189
190 /* improve band edge for AL2230S */
191 if (chip->al2230s_bit)
192 r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
193 else
194 r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
195 if (r)
196 return r;
197
198 r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS);
199 if (r)
200 return r;
201
202 r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll));
203 if (r)
204 return r;
205
206 r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS);
165 if (r) 207 if (r)
166 return r; 208 return r;
167 209
@@ -227,7 +269,9 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
227 0x481dc0, 269 0x481dc0,
228 0xcfff00, 270 0xcfff00,
229 0x25a000, 271 0x25a000,
272 };
230 273
274 static const u32 rv2[] = {
231 /* To improve AL2230 yield, improve phase noise, 4713 */ 275 /* To improve AL2230 yield, improve phase noise, 4713 */
232 0x25a000, 276 0x25a000,
233 0xa3b2f0, 277 0xa3b2f0,
@@ -250,7 +294,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
250 { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ 294 { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
251 }; 295 };
252 296
253 static const u32 rv2[] = { 297 static const u32 rv3[] = {
254 /* To improve AL2230 yield, 4713 */ 298 /* To improve AL2230 yield, 4713 */
255 0xf01b00, 299 0xf01b00,
256 0xf01e00, 300 0xf01e00,
@@ -269,18 +313,37 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
269 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1)); 313 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
270 if (r) 314 if (r)
271 return r; 315 return r;
316
317 if (chip->al2230s_bit) {
318 r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
319 ARRAY_SIZE(ioreqs_init_al2230s));
320 if (r)
321 return r;
322 }
323
272 r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3); 324 r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3);
273 if (r) 325 if (r)
274 return r; 326 return r;
275 r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1)); 327 r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1));
276 if (r) 328 if (r)
277 return r; 329 return r;
278 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2)); 330
331 if (chip->al2230s_bit)
332 r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
333 else
334 r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
279 if (r) 335 if (r)
280 return r; 336 return r;
337
281 r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2)); 338 r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2));
282 if (r) 339 if (r)
283 return r; 340 return r;
341 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
342 if (r)
343 return r;
344 r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3));
345 if (r)
346 return r;
284 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3)); 347 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
285 if (r) 348 if (r)
286 return r; 349 return r;
@@ -358,12 +421,6 @@ int zd_rf_init_al2230(struct zd_rf *rf)
358{ 421{
359 struct zd_chip *chip = zd_rf_to_chip(rf); 422 struct zd_chip *chip = zd_rf_to_chip(rf);
360 423
361 if (chip->al2230s_bit) {
362 dev_err(zd_chip_dev(chip), "AL2230S devices are not yet "
363 "supported by this driver.\n");
364 return -ENODEV;
365 }
366
367 rf->switch_radio_off = al2230_switch_radio_off; 424 rf->switch_radio_off = al2230_switch_radio_off;
368 if (chip->is_zd1211b) { 425 if (chip->is_zd1211b) {
369 rf->init_hw = zd1211b_al2230_init_hw; 426 rf->init_hw = zd1211b_al2230_init_hw;
@@ -374,6 +431,6 @@ int zd_rf_init_al2230(struct zd_rf *rf)
374 rf->set_channel = zd1211_al2230_set_channel; 431 rf->set_channel = zd1211_al2230_set_channel;
375 rf->switch_radio_on = zd1211_al2230_switch_radio_on; 432 rf->switch_radio_on = zd1211_al2230_switch_radio_on;
376 } 433 }
377 rf->patch_6m_band_edge = 1; 434 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
378 return 0; 435 return 0;
379} 436}
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index a289f95187ec..5e5e9ddc6a74 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -51,9 +51,52 @@ static const u32 std_rv[] = {
51 0xd8c010, 51 0xd8c010,
52}; 52};
53 53
54static int al7230b_init_hw(struct zd_rf *rf) 54static const u32 rv_init1[] = {
55 0x3c9000,
56 0xbfffff,
57 0x700000,
58 0xf15d58,
59};
60
61static const u32 rv_init2[] = {
62 0xf15d59,
63 0xf15d5c,
64 0xf15d58,
65};
66
67static const struct zd_ioreq16 ioreqs_sw[] = {
68 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
69 { CR38, 0x38 }, { CR136, 0xdf },
70};
71
72static int zd1211b_al7230b_finalize(struct zd_chip *chip)
55{ 73{
56 int i, r; 74 int r;
75 static const struct zd_ioreq16 ioreqs[] = {
76 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
77 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
78 { CR203, 0x04 },
79 { },
80 { CR240, 0x80 },
81 };
82
83 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
84 if (r)
85 return r;
86
87 if (chip->new_phy_layout) {
88 /* antenna selection? */
89 r = zd_iowrite16_locked(chip, 0xe5, CR9);
90 if (r)
91 return r;
92 }
93
94 return zd_iowrite16_locked(chip, 0x04, CR203);
95}
96
97static int zd1211_al7230b_init_hw(struct zd_rf *rf)
98{
99 int r;
57 struct zd_chip *chip = zd_rf_to_chip(rf); 100 struct zd_chip *chip = zd_rf_to_chip(rf);
58 101
59 /* All of these writes are identical to AL2230 unless otherwise 102 /* All of these writes are identical to AL2230 unless otherwise
@@ -117,39 +160,136 @@ static int al7230b_init_hw(struct zd_rf *rf)
117 }; 160 };
118 161
119 static const struct zd_ioreq16 ioreqs_2[] = { 162 static const struct zd_ioreq16 ioreqs_2[] = {
120 /* PLL_ON */ 163 { CR251, 0x3f }, /* PLL_ON */
121 { CR251, 0x3f },
122 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, 164 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
123 { CR38, 0x38 }, { CR136, 0xdf }, 165 { CR38, 0x38 }, { CR136, 0xdf },
124 }; 166 };
125 167
126 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); 168 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
127 if (r) 169 if (r)
128 return r; 170 return r;
129 171
130 r = zd_rfwrite_cr_locked(chip, 0x09ec04); 172 r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
131 if (r) 173 if (r)
132 return r; 174 return r;
133 r = zd_rfwrite_cr_locked(chip, 0x8cccc8); 175
176 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
134 if (r) 177 if (r)
135 return r; 178 return r;
136 179
137 for (i = 0; i < ARRAY_SIZE(std_rv); i++) { 180 r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
138 r = zd_rfwrite_cr_locked(chip, std_rv[i]); 181 if (r)
139 if (r) 182 return r;
140 return r;
141 }
142 183
143 r = zd_rfwrite_cr_locked(chip, 0x3c9000); 184 r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
144 if (r) 185 if (r)
145 return r; 186 return r;
146 r = zd_rfwrite_cr_locked(chip, 0xbfffff); 187
188 r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
147 if (r) 189 if (r)
148 return r; 190 return r;
149 r = zd_rfwrite_cr_locked(chip, 0x700000); 191
192 r = zd_iowrite16_locked(chip, 0x06, CR203);
150 if (r) 193 if (r)
151 return r; 194 return r;
152 r = zd_rfwrite_cr_locked(chip, 0xf15d58); 195 r = zd_iowrite16_locked(chip, 0x80, CR240);
196 if (r)
197 return r;
198
199 return 0;
200}
201
202static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
203{
204 int r;
205 struct zd_chip *chip = zd_rf_to_chip(rf);
206
207 static const struct zd_ioreq16 ioreqs_1[] = {
208 { CR240, 0x57 }, { CR9, 0x9 },
209 { },
210 { CR10, 0x8b }, { CR15, 0x20 },
211 { CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
212 { CR20, 0x10 }, /* 4N25->Stone Request */
213 { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 },
214 { CR28, 0x3e }, { CR29, 0x00 },
215 { CR33, 0x28 }, /* 5613 */
216 { CR34, 0x30 },
217 { CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
218 { CR41, 0x24 }, { CR44, 0x32 },
219 { CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
220 { CR47, 0x1e },
221
222 /* ZD1215 5610 */
223 { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 },
224 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
225 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
226 { CR69, 0x28 },
227
228 { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
229 { CR87, 0x0A }, { CR89, 0x04 },
230 { CR90, 0x58 }, /* 5112 */
231 { CR91, 0x00 }, /* 5613 */
232 { CR92, 0x0a },
233 { CR98, 0x8d }, /* 4804, for 1212 new algorithm */
234 { CR99, 0x00 }, { CR100, 0x02 }, { CR101, 0x13 },
235 { CR102, 0x27 },
236 { CR106, 0x20 }, /* change to 0x24 for AL7230B */
237 { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
238 { CR112, 0x1f },
239 };
240
241 static const struct zd_ioreq16 ioreqs_new_phy[] = {
242 { CR107, 0x28 },
243 { CR110, 0x1f }, /* 5127, 0x13->0x1f */
244 { CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
245 { CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 },
246 { CR121, 0x6c }, /* 5613 */
247 };
248
249 static const struct zd_ioreq16 ioreqs_old_phy[] = {
250 { CR107, 0x24 },
251 { CR110, 0x13 }, /* 5127, 0x13->0x1f */
252 { CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
253 { CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 },
254 { CR121, 0x6a }, /* 5613 */
255 };
256
257 static const struct zd_ioreq16 ioreqs_2[] = {
258 { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 },
259 { CR117, 0xfa }, { CR120, 0x4f },
260 { CR122, 0xfc }, /* E0->FCh at 4901 */
261 { CR123, 0x57 }, /* 5613 */
262 { CR125, 0xad }, /* 4804, for 1212 new algorithm */
263 { CR126, 0x6c }, /* 5613 */
264 { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
265 { CR130, 0x10 },
266 { CR131, 0x00 }, /* 5112 */
267 { CR137, 0x50 }, /* 5613 */
268 { CR138, 0xa8 }, /* 5112 */
269 { CR144, 0xac }, /* 5613 */
270 { CR148, 0x40 }, /* 5112 */
271 { CR149, 0x40 }, /* 4O07, 50->40 */
272 { CR150, 0x1a }, /* 5112, 0C->1A */
273 { CR252, 0x34 }, { CR253, 0x34 },
274 { CR251, 0x2f }, /* PLL_OFF */
275 };
276
277 static const struct zd_ioreq16 ioreqs_3[] = {
278 { CR251, 0x7f }, /* PLL_ON */
279 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
280 { CR38, 0x38 }, { CR136, 0xdf },
281 };
282
283 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
284 if (r)
285 return r;
286
287 if (chip->new_phy_layout)
288 r = zd_iowrite16a_locked(chip, ioreqs_new_phy,
289 ARRAY_SIZE(ioreqs_new_phy));
290 else
291 r = zd_iowrite16a_locked(chip, ioreqs_old_phy,
292 ARRAY_SIZE(ioreqs_old_phy));
153 if (r) 293 if (r)
154 return r; 294 return r;
155 295
@@ -157,38 +297,36 @@ static int al7230b_init_hw(struct zd_rf *rf)
157 if (r) 297 if (r)
158 return r; 298 return r;
159 299
160 r = zd_rfwrite_cr_locked(chip, 0xf15d59); 300 r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0]));
161 if (r) 301 if (r)
162 return r; 302 return r;
163 r = zd_rfwrite_cr_locked(chip, 0xf15d5c); 303
304 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
164 if (r) 305 if (r)
165 return r; 306 return r;
166 r = zd_rfwrite_cr_locked(chip, 0xf15d58); 307
308 r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1));
167 if (r) 309 if (r)
168 return r; 310 return r;
169 311
170 r = zd_iowrite16_locked(chip, 0x06, CR203); 312 r = zd_iowrite16a_locked(chip, ioreqs_3, ARRAY_SIZE(ioreqs_3));
171 if (r) 313 if (r)
172 return r; 314 return r;
173 r = zd_iowrite16_locked(chip, 0x80, CR240); 315
316 r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2));
174 if (r) 317 if (r)
175 return r; 318 return r;
176 319
177 return 0; 320 return zd1211b_al7230b_finalize(chip);
178} 321}
179 322
180static int al7230b_set_channel(struct zd_rf *rf, u8 channel) 323static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
181{ 324{
182 int i, r; 325 int r;
183 const u32 *rv = chan_rv[channel-1]; 326 const u32 *rv = chan_rv[channel-1];
184 struct zd_chip *chip = zd_rf_to_chip(rf); 327 struct zd_chip *chip = zd_rf_to_chip(rf);
185 328
186 struct zd_ioreq16 ioreqs_1[] = { 329 static const struct zd_ioreq16 ioreqs[] = {
187 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
188 { CR38, 0x38 }, { CR136, 0xdf },
189 };
190
191 struct zd_ioreq16 ioreqs_2[] = {
192 /* PLL_ON */ 330 /* PLL_ON */
193 { CR251, 0x3f }, 331 { CR251, 0x3f },
194 { CR203, 0x06 }, { CR240, 0x08 }, 332 { CR203, 0x06 }, { CR240, 0x08 },
@@ -203,11 +341,9 @@ static int al7230b_set_channel(struct zd_rf *rf, u8 channel)
203 if (r) 341 if (r)
204 return r; 342 return r;
205 343
206 for (i = 0; i < ARRAY_SIZE(std_rv); i++) { 344 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
207 r = zd_rfwrite_cr_locked(chip, std_rv[i]); 345 if (r)
208 if (r) 346 return r;
209 return r;
210 }
211 347
212 r = zd_rfwrite_cr_locked(chip, 0x3c9000); 348 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
213 if (r) 349 if (r)
@@ -216,24 +352,69 @@ static int al7230b_set_channel(struct zd_rf *rf, u8 channel)
216 if (r) 352 if (r)
217 return r; 353 return r;
218 354
219 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); 355 r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
220 if (r) 356 if (r)
221 return r; 357 return r;
222 358
223 for (i = 0; i < 2; i++) { 359 r = zd_rfwritev_cr_locked(chip, rv, 2);
224 r = zd_rfwrite_cr_locked(chip, rv[i]); 360 if (r)
225 if (r) 361 return r;
226 return r;
227 }
228 362
229 r = zd_rfwrite_cr_locked(chip, 0x3c9000); 363 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
230 if (r) 364 if (r)
231 return r; 365 return r;
232 366
233 return zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2)); 367 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
234} 368}
235 369
236static int al7230b_switch_radio_on(struct zd_rf *rf) 370static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
371{
372 int r;
373 const u32 *rv = chan_rv[channel-1];
374 struct zd_chip *chip = zd_rf_to_chip(rf);
375
376 r = zd_iowrite16_locked(chip, 0x57, CR240);
377 if (r)
378 return r;
379 r = zd_iowrite16_locked(chip, 0xe4, CR9);
380 if (r)
381 return r;
382
383 /* PLL_OFF */
384 r = zd_iowrite16_locked(chip, 0x2f, CR251);
385 if (r)
386 return r;
387 r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
388 if (r)
389 return r;
390
391 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
392 if (r)
393 return r;
394 r = zd_rfwrite_cr_locked(chip, 0xf15d58);
395 if (r)
396 return r;
397
398 r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw));
399 if (r)
400 return r;
401
402 r = zd_rfwritev_cr_locked(chip, rv, 2);
403 if (r)
404 return r;
405
406 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
407 if (r)
408 return r;
409
410 r = zd_iowrite16_locked(chip, 0x7f, CR251);
411 if (r)
412 return r;
413
414 return zd1211b_al7230b_finalize(chip);
415}
416
417static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf)
237{ 418{
238 struct zd_chip *chip = zd_rf_to_chip(rf); 419 struct zd_chip *chip = zd_rf_to_chip(rf);
239 static const struct zd_ioreq16 ioreqs[] = { 420 static const struct zd_ioreq16 ioreqs[] = {
@@ -244,6 +425,17 @@ static int al7230b_switch_radio_on(struct zd_rf *rf)
244 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 425 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
245} 426}
246 427
428static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf)
429{
430 struct zd_chip *chip = zd_rf_to_chip(rf);
431 static const struct zd_ioreq16 ioreqs[] = {
432 { CR11, 0x00 },
433 { CR251, 0x7f },
434 };
435
436 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
437}
438
247static int al7230b_switch_radio_off(struct zd_rf *rf) 439static int al7230b_switch_radio_off(struct zd_rf *rf)
248{ 440{
249 struct zd_chip *chip = zd_rf_to_chip(rf); 441 struct zd_chip *chip = zd_rf_to_chip(rf);
@@ -255,20 +447,45 @@ static int al7230b_switch_radio_off(struct zd_rf *rf)
255 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 447 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
256} 448}
257 449
450/* ZD1211B+AL7230B 6m band edge patching differs slightly from other
451 * configurations */
452static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel)
453{
454 struct zd_chip *chip = zd_rf_to_chip(rf);
455 struct zd_ioreq16 ioreqs[] = {
456 { CR128, 0x14 }, { CR129, 0x12 },
457 };
458
459 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
460 if (channel == 1) {
461 ioreqs[0].value = 0x0e;
462 ioreqs[1].value = 0x10;
463 } else if (channel == 11) {
464 ioreqs[0].value = 0x10;
465 ioreqs[1].value = 0x10;
466 }
467
468 dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
469 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
470}
471
258int zd_rf_init_al7230b(struct zd_rf *rf) 472int zd_rf_init_al7230b(struct zd_rf *rf)
259{ 473{
260 struct zd_chip *chip = zd_rf_to_chip(rf); 474 struct zd_chip *chip = zd_rf_to_chip(rf);
261 475
262 if (chip->is_zd1211b) { 476 if (chip->is_zd1211b) {
263 dev_err(zd_chip_dev(chip), "AL7230B is currently not " 477 rf->init_hw = zd1211b_al7230b_init_hw;
264 "supported for ZD1211B devices\n"); 478 rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
265 return -ENODEV; 479 rf->set_channel = zd1211b_al7230b_set_channel;
480 rf->patch_6m_band_edge = zd1211b_al7230b_patch_6m;
481 } else {
482 rf->init_hw = zd1211_al7230b_init_hw;
483 rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
484 rf->set_channel = zd1211_al7230b_set_channel;
485 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
266 } 486 }
267 487
268 rf->init_hw = al7230b_init_hw;
269 rf->set_channel = al7230b_set_channel;
270 rf->switch_radio_on = al7230b_switch_radio_on;
271 rf->switch_radio_off = al7230b_switch_radio_off; 488 rf->switch_radio_off = al7230b_switch_radio_off;
272 rf->patch_6m_band_edge = 1; 489
273 return 0; 490 return 0;
274} 491}
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index 58247271cc24..2d736bdf707c 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -21,7 +21,7 @@
21#include "zd_usb.h" 21#include "zd_usb.h"
22#include "zd_chip.h" 22#include "zd_chip.h"
23 23
24static u32 rf2959_table[][2] = { 24static const u32 rf2959_table[][2] = {
25 RF_CHANNEL( 1) = { 0x181979, 0x1e6666 }, 25 RF_CHANNEL( 1) = { 0x181979, 0x1e6666 },
26 RF_CHANNEL( 2) = { 0x181989, 0x1e6666 }, 26 RF_CHANNEL( 2) = { 0x181989, 0x1e6666 },
27 RF_CHANNEL( 3) = { 0x181999, 0x1e6666 }, 27 RF_CHANNEL( 3) = { 0x181999, 0x1e6666 },
@@ -228,7 +228,7 @@ static int rf2959_init_hw(struct zd_rf *rf)
228static int rf2959_set_channel(struct zd_rf *rf, u8 channel) 228static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
229{ 229{
230 int i, r; 230 int i, r;
231 u32 *rv = rf2959_table[channel-1]; 231 const u32 *rv = rf2959_table[channel-1];
232 struct zd_chip *chip = zd_rf_to_chip(rf); 232 struct zd_chip *chip = zd_rf_to_chip(rf);
233 233
234 for (i = 0; i < 2; i++) { 234 for (i = 0; i < 2; i++) {
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index edaaad2f648b..e04cffc8adf3 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -52,6 +52,7 @@ static struct usb_device_id usb_ids[] = {
52 { USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 }, 52 { USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 },
53 { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 }, 53 { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
54 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, 54 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
55 { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
55 /* ZD1211B */ 56 /* ZD1211B */
56 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 57 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
57 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 58 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
@@ -62,7 +63,10 @@ static struct usb_device_id usb_ids[] = {
62 { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, 63 { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
63 { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B }, 64 { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B },
64 { USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B }, 65 { USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B },
66 { USB_DEVICE(0x0b05, 0x171b), .driver_info = DEVICE_ZD1211B },
67 { USB_DEVICE(0x0586, 0x3410), .driver_info = DEVICE_ZD1211B },
65 { USB_DEVICE(0x0baf, 0x0121), .driver_info = DEVICE_ZD1211B }, 68 { USB_DEVICE(0x0baf, 0x0121), .driver_info = DEVICE_ZD1211B },
69 { USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
66 /* "Driverless" devices that need ejecting */ 70 /* "Driverless" devices that need ejecting */
67 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, 71 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
68 {} 72 {}
@@ -413,7 +417,7 @@ int zd_usb_enable_int(struct zd_usb *usb)
413 417
414 dev_dbg_f(zd_usb_dev(usb), "\n"); 418 dev_dbg_f(zd_usb_dev(usb), "\n");
415 419
416 urb = usb_alloc_urb(0, GFP_NOFS); 420 urb = usb_alloc_urb(0, GFP_KERNEL);
417 if (!urb) { 421 if (!urb) {
418 r = -ENOMEM; 422 r = -ENOMEM;
419 goto out; 423 goto out;
@@ -431,7 +435,7 @@ int zd_usb_enable_int(struct zd_usb *usb)
431 435
432 /* TODO: make it a DMA buffer */ 436 /* TODO: make it a DMA buffer */
433 r = -ENOMEM; 437 r = -ENOMEM;
434 transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_NOFS); 438 transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL);
435 if (!transfer_buffer) { 439 if (!transfer_buffer) {
436 dev_dbg_f(zd_usb_dev(usb), 440 dev_dbg_f(zd_usb_dev(usb),
437 "couldn't allocate transfer_buffer\n"); 441 "couldn't allocate transfer_buffer\n");
@@ -445,7 +449,7 @@ int zd_usb_enable_int(struct zd_usb *usb)
445 intr->interval); 449 intr->interval);
446 450
447 dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); 451 dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
448 r = usb_submit_urb(urb, GFP_NOFS); 452 r = usb_submit_urb(urb, GFP_KERNEL);
449 if (r) { 453 if (r) {
450 dev_dbg_f(zd_usb_dev(usb), 454 dev_dbg_f(zd_usb_dev(usb),
451 "Couldn't submit urb. Error number %d\n", r); 455 "Couldn't submit urb. Error number %d\n", r);
@@ -594,10 +598,10 @@ static struct urb *alloc_urb(struct zd_usb *usb)
594 struct urb *urb; 598 struct urb *urb;
595 void *buffer; 599 void *buffer;
596 600
597 urb = usb_alloc_urb(0, GFP_NOFS); 601 urb = usb_alloc_urb(0, GFP_KERNEL);
598 if (!urb) 602 if (!urb)
599 return NULL; 603 return NULL;
600 buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_NOFS, 604 buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
601 &urb->transfer_dma); 605 &urb->transfer_dma);
602 if (!buffer) { 606 if (!buffer) {
603 usb_free_urb(urb); 607 usb_free_urb(urb);
@@ -630,7 +634,7 @@ int zd_usb_enable_rx(struct zd_usb *usb)
630 dev_dbg_f(zd_usb_dev(usb), "\n"); 634 dev_dbg_f(zd_usb_dev(usb), "\n");
631 635
632 r = -ENOMEM; 636 r = -ENOMEM;
633 urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_NOFS); 637 urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);
634 if (!urbs) 638 if (!urbs)
635 goto error; 639 goto error;
636 for (i = 0; i < URBS_COUNT; i++) { 640 for (i = 0; i < URBS_COUNT; i++) {
@@ -651,7 +655,7 @@ int zd_usb_enable_rx(struct zd_usb *usb)
651 spin_unlock_irq(&rx->lock); 655 spin_unlock_irq(&rx->lock);
652 656
653 for (i = 0; i < URBS_COUNT; i++) { 657 for (i = 0; i < URBS_COUNT; i++) {
654 r = usb_submit_urb(urbs[i], GFP_NOFS); 658 r = usb_submit_urb(urbs[i], GFP_KERNEL);
655 if (r) 659 if (r)
656 goto error_submit; 660 goto error_submit;
657 } 661 }
@@ -1157,7 +1161,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
1157 } 1161 }
1158 1162
1159 req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16); 1163 req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16);
1160 req = kmalloc(req_len, GFP_NOFS); 1164 req = kmalloc(req_len, GFP_KERNEL);
1161 if (!req) 1165 if (!req)
1162 return -ENOMEM; 1166 return -ENOMEM;
1163 req->id = cpu_to_le16(USB_REQ_READ_REGS); 1167 req->id = cpu_to_le16(USB_REQ_READ_REGS);
@@ -1220,7 +1224,7 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
1220 1224
1221 req_len = sizeof(struct usb_req_write_regs) + 1225 req_len = sizeof(struct usb_req_write_regs) +
1222 count * sizeof(struct reg_data); 1226 count * sizeof(struct reg_data);
1223 req = kmalloc(req_len, GFP_NOFS); 1227 req = kmalloc(req_len, GFP_KERNEL);
1224 if (!req) 1228 if (!req)
1225 return -ENOMEM; 1229 return -ENOMEM;
1226 1230
@@ -1300,7 +1304,7 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
1300 bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); 1304 bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);
1301 1305
1302 req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16); 1306 req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16);
1303 req = kmalloc(req_len, GFP_NOFS); 1307 req = kmalloc(req_len, GFP_KERNEL);
1304 if (!req) 1308 if (!req)
1305 return -ENOMEM; 1309 return -ENOMEM;
1306 1310
diff --git a/include/asm-powerpc/ucc_fast.h b/include/asm-powerpc/ucc_fast.h
index 39d1c90fd2ca..f529f70b1d82 100644
--- a/include/asm-powerpc/ucc_fast.h
+++ b/include/asm-powerpc/ucc_fast.h
@@ -159,6 +159,9 @@ struct ucc_fast_private {
159 struct ucc_fast *uf_regs; /* a pointer to memory map of UCC regs. */ 159 struct ucc_fast *uf_regs; /* a pointer to memory map of UCC regs. */
160 u32 *p_ucce; /* a pointer to the event register in memory. */ 160 u32 *p_ucce; /* a pointer to the event register in memory. */
161 u32 *p_uccm; /* a pointer to the mask register in memory. */ 161 u32 *p_uccm; /* a pointer to the mask register in memory. */
162#ifdef CONFIG_UGETH_TX_ON_DEMAND
163 u16 *p_utodr; /* pointer to the transmit on demand register */
164#endif
162 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ 165 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
163 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ 166 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
164 int stopped_tx; /* Whether channel has been stopped for Tx 167 int stopped_tx; /* Whether channel has been stopped for Tx
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index abb64c437f6f..73710d617775 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -120,44 +120,5 @@ struct fsl_spi_platform_data {
120 u32 sysclk; 120 u32 sysclk;
121}; 121};
122 122
123/* Ethernet interface (phy management and speed)
124*/
125enum enet_interface {
126 ENET_10_MII, /* 10 Base T, MII interface */
127 ENET_10_RMII, /* 10 Base T, RMII interface */
128 ENET_10_RGMII, /* 10 Base T, RGMII interface */
129 ENET_100_MII, /* 100 Base T, MII interface */
130 ENET_100_RMII, /* 100 Base T, RMII interface */
131 ENET_100_RGMII, /* 100 Base T, RGMII interface */
132 ENET_1000_GMII, /* 1000 Base T, GMII interface */
133 ENET_1000_RGMII, /* 1000 Base T, RGMII interface */
134 ENET_1000_TBI, /* 1000 Base T, TBI interface */
135 ENET_1000_RTBI /* 1000 Base T, RTBI interface */
136};
137
138struct ucc_geth_platform_data {
139 /* device specific information */
140 u32 device_flags;
141 u32 phy_reg_addr;
142
143 /* board specific information */
144 u32 board_flags;
145 u8 rx_clock;
146 u8 tx_clock;
147 u32 phy_id;
148 enum enet_interface phy_interface;
149 u32 phy_interrupt;
150 u8 mac_addr[6];
151};
152
153/* Flags related to UCC Gigabit Ethernet device features */
154#define FSL_UGETH_DEV_HAS_GIGABIT 0x00000001
155#define FSL_UGETH_DEV_HAS_COALESCE 0x00000002
156#define FSL_UGETH_DEV_HAS_RMON 0x00000004
157
158/* Flags in ucc_geth_platform_data */
159#define FSL_UGETH_BRD_HAS_PHY_INTR 0x00000001
160 /* if not set use a timer */
161
162#endif /* _FSL_DEVICE_H_ */ 123#endif /* _FSL_DEVICE_H_ */
163#endif /* __KERNEL__ */ 124#endif /* __KERNEL__ */
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index 0fe562af9c8c..db390c511ada 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -43,8 +43,7 @@ struct hdlc_proto {
43 void (*stop)(struct net_device *dev); /* if open & !DCD */ 43 void (*stop)(struct net_device *dev); /* if open & !DCD */
44 void (*detach)(struct net_device *dev); 44 void (*detach)(struct net_device *dev);
45 int (*ioctl)(struct net_device *dev, struct ifreq *ifr); 45 int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
46 unsigned short (*type_trans)(struct sk_buff *skb, 46 __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
47 struct net_device *dev);
48 struct module *module; 47 struct module *module;
49 struct hdlc_proto *next; /* next protocol in the list */ 48 struct hdlc_proto *next; /* next protocol in the list */
50}; 49};
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 5f21b0f68b42..1b0ddbb8a804 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1458,6 +1458,8 @@
1458 1458
1459#define PCI_VENDOR_ID_TOSHIBA_2 0x102f 1459#define PCI_VENDOR_ID_TOSHIBA_2 0x102f
1460#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 1460#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030
1461#define PCI_DEVICE_ID_TOSHIBA_TC35815_NWU 0x0031
1462#define PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939 0x0032
1461#define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105 1463#define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105
1462#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 1464#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108
1463#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 1465#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
diff --git a/include/linux/phy.h b/include/linux/phy.h
index edd4c88ca7d8..2a659789f9ca 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -55,6 +55,7 @@ typedef enum {
55 PHY_INTERFACE_MODE_TBI, 55 PHY_INTERFACE_MODE_TBI,
56 PHY_INTERFACE_MODE_RMII, 56 PHY_INTERFACE_MODE_RMII,
57 PHY_INTERFACE_MODE_RGMII, 57 PHY_INTERFACE_MODE_RGMII,
58 PHY_INTERFACE_MODE_RGMII_ID,
58 PHY_INTERFACE_MODE_RTBI 59 PHY_INTERFACE_MODE_RTBI
59} phy_interface_t; 60} phy_interface_t;
60 61
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 48759b2f57d7..0987aa7a6cf5 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -186,7 +186,7 @@
186 * - Wireless Event capability in struct iw_range 186 * - Wireless Event capability in struct iw_range
187 * - Add support for relative TxPower (yick !) 187 * - Add support for relative TxPower (yick !)
188 * 188 *
189 * V17 to V18 (From Jouni Malinen <jkmaline@cc.hut.fi>) 189 * V17 to V18 (From Jouni Malinen <j@w1.fi>)
190 * ---------- 190 * ----------
191 * - Add support for WPA/WPA2 191 * - Add support for WPA/WPA2
192 * - Add extended encoding configuration (SIOCSIWENCODEEXT and 192 * - Add extended encoding configuration (SIOCSIWENCODEEXT and
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index e02d85f56e60..d56b2923d61a 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -6,8 +6,8 @@
6 * LAN access point) driver for Intersil Prism2/2.5/3. 6 * LAN access point) driver for Intersil Prism2/2.5/3.
7 * 7 *
8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
9 * <jkmaline@cc.hut.fi> 9 * <j@w1.fi>
10 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 10 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
11 * 11 *
12 * Adaption to a generic IEEE 802.11 stack by James Ketrenos 12 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
13 * <jketreno@linux.intel.com> 13 * <jketreno@linux.intel.com>
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index eb476414fd72..b3d65e0bedd3 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -3,8 +3,8 @@
3 * for Intersil Prism2/2.5/3. 3 * for Intersil Prism2/2.5/3.
4 * 4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi> 6 * <j@w1.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
8 * 8 *
9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos 9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
10 * <jketreno@linux.intel.com> 10 * <jketreno@linux.intel.com>
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 429b73892a5f..a0c2b41a24d7 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -66,7 +66,9 @@
66 */ 66 */
67#define IEEE80211_RADIOTAP_HDRLEN 64 67#define IEEE80211_RADIOTAP_HDRLEN 64
68 68
69/* The radio capture header precedes the 802.11 header. */ 69/* The radio capture header precedes the 802.11 header.
70 * All data in the header is little endian on all platforms.
71 */
70struct ieee80211_radiotap_header { 72struct ieee80211_radiotap_header {
71 u8 it_version; /* Version 0. Only increases 73 u8 it_version; /* Version 0. Only increases
72 * for drastic changes, 74 * for drastic changes,
@@ -74,12 +76,12 @@ struct ieee80211_radiotap_header {
74 * new fields does not count. 76 * new fields does not count.
75 */ 77 */
76 u8 it_pad; 78 u8 it_pad;
77 u16 it_len; /* length of the whole 79 __le16 it_len; /* length of the whole
78 * header in bytes, including 80 * header in bytes, including
79 * it_version, it_pad, 81 * it_version, it_pad,
80 * it_len, and data fields. 82 * it_len, and data fields.
81 */ 83 */
82 u32 it_present; /* A bitmap telling which 84 __le32 it_present; /* A bitmap telling which
83 * fields are present. Set bit 31 85 * fields are present. Set bit 31
84 * (0x80000000) to extend the 86 * (0x80000000) to extend the
85 * bitmap by another 32 bits. 87 * bitmap by another 32 bits.
@@ -88,89 +90,102 @@ struct ieee80211_radiotap_header {
88 */ 90 */
89}; 91};
90 92
91/* Name Data type Units 93/* Name Data type Units
92 * ---- --------- ----- 94 * ---- --------- -----
93 * 95 *
94 * IEEE80211_RADIOTAP_TSFT u64 microseconds 96 * IEEE80211_RADIOTAP_TSFT __le64 microseconds
95 * 97 *
96 * Value in microseconds of the MAC's 64-bit 802.11 Time 98 * Value in microseconds of the MAC's 64-bit 802.11 Time
97 * Synchronization Function timer when the first bit of the 99 * Synchronization Function timer when the first bit of the
98 * MPDU arrived at the MAC. For received frames, only. 100 * MPDU arrived at the MAC. For received frames, only.
99 * 101 *
100 * IEEE80211_RADIOTAP_CHANNEL 2 x u16 MHz, bitmap 102 * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
101 * 103 *
102 * Tx/Rx frequency in MHz, followed by flags (see below). 104 * Tx/Rx frequency in MHz, followed by flags (see below).
103 * 105 *
104 * IEEE80211_RADIOTAP_FHSS u16 see below 106 * IEEE80211_RADIOTAP_FHSS __le16 see below
105 * 107 *
106 * For frequency-hopping radios, the hop set (first byte) 108 * For frequency-hopping radios, the hop set (first byte)
107 * and pattern (second byte). 109 * and pattern (second byte).
108 * 110 *
109 * IEEE80211_RADIOTAP_RATE u8 500kb/s 111 * IEEE80211_RADIOTAP_RATE u8 500kb/s
110 * 112 *
111 * Tx/Rx data rate 113 * Tx/Rx data rate
112 * 114 *
113 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from 115 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
114 * one milliwatt (dBm) 116 * one milliwatt (dBm)
115 * 117 *
116 * RF signal power at the antenna, decibel difference from 118 * RF signal power at the antenna, decibel difference from
117 * one milliwatt. 119 * one milliwatt.
118 * 120 *
119 * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from 121 * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
120 * one milliwatt (dBm) 122 * one milliwatt (dBm)
121 * 123 *
122 * RF noise power at the antenna, decibel difference from one 124 * RF noise power at the antenna, decibel difference from one
123 * milliwatt. 125 * milliwatt.
124 * 126 *
125 * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB) 127 * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
126 * 128 *
127 * RF signal power at the antenna, decibel difference from an 129 * RF signal power at the antenna, decibel difference from an
128 * arbitrary, fixed reference. 130 * arbitrary, fixed reference.
129 * 131 *
130 * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB) 132 * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
131 * 133 *
132 * RF noise power at the antenna, decibel difference from an 134 * RF noise power at the antenna, decibel difference from an
133 * arbitrary, fixed reference point. 135 * arbitrary, fixed reference point.
134 * 136 *
135 * IEEE80211_RADIOTAP_LOCK_QUALITY u16 unitless 137 * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
136 * 138 *
137 * Quality of Barker code lock. Unitless. Monotonically 139 * Quality of Barker code lock. Unitless. Monotonically
138 * nondecreasing with "better" lock strength. Called "Signal 140 * nondecreasing with "better" lock strength. Called "Signal
139 * Quality" in datasheets. (Is there a standard way to measure 141 * Quality" in datasheets. (Is there a standard way to measure
140 * this?) 142 * this?)
141 * 143 *
142 * IEEE80211_RADIOTAP_TX_ATTENUATION u16 unitless 144 * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
143 * 145 *
144 * Transmit power expressed as unitless distance from max 146 * Transmit power expressed as unitless distance from max
145 * power set at factory calibration. 0 is max power. 147 * power set at factory calibration. 0 is max power.
146 * Monotonically nondecreasing with lower power levels. 148 * Monotonically nondecreasing with lower power levels.
147 * 149 *
148 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16 decibels (dB) 150 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
149 * 151 *
150 * Transmit power expressed as decibel distance from max power 152 * Transmit power expressed as decibel distance from max power
151 * set at factory calibration. 0 is max power. Monotonically 153 * set at factory calibration. 0 is max power. Monotonically
152 * nondecreasing with lower power levels. 154 * nondecreasing with lower power levels.
153 * 155 *
154 * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from 156 * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
155 * one milliwatt (dBm) 157 * one milliwatt (dBm)
156 * 158 *
157 * Transmit power expressed as dBm (decibels from a 1 milliwatt 159 * Transmit power expressed as dBm (decibels from a 1 milliwatt
158 * reference). This is the absolute power level measured at 160 * reference). This is the absolute power level measured at
159 * the antenna port. 161 * the antenna port.
160 * 162 *
161 * IEEE80211_RADIOTAP_FLAGS u8 bitmap 163 * IEEE80211_RADIOTAP_FLAGS u8 bitmap
162 * 164 *
163 * Properties of transmitted and received frames. See flags 165 * Properties of transmitted and received frames. See flags
164 * defined below. 166 * defined below.
165 * 167 *
166 * IEEE80211_RADIOTAP_ANTENNA u8 antenna index 168 * IEEE80211_RADIOTAP_ANTENNA u8 antenna index
167 * 169 *
168 * Unitless indication of the Rx/Tx antenna for this packet. 170 * Unitless indication of the Rx/Tx antenna for this packet.
169 * The first antenna is antenna 0. 171 * The first antenna is antenna 0.
170 * 172 *
171 * IEEE80211_RADIOTAP_FCS u32 data 173 * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
174 *
175 * Properties of received frames. See flags defined below.
176 *
177 * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
178 *
179 * Properties of transmitted frames. See flags defined below.
180 *
181 * IEEE80211_RADIOTAP_RTS_RETRIES u8 data
182 *
183 * Number of rts retries a transmitted frame used.
184 *
185 * IEEE80211_RADIOTAP_DATA_RETRIES u8 data
186 *
187 * Number of unicast retries a transmitted frame used.
172 * 188 *
173 * FCS from frame in network byte order.
174 */ 189 */
175enum ieee80211_radiotap_type { 190enum ieee80211_radiotap_type {
176 IEEE80211_RADIOTAP_TSFT = 0, 191 IEEE80211_RADIOTAP_TSFT = 0,
@@ -187,7 +202,11 @@ enum ieee80211_radiotap_type {
187 IEEE80211_RADIOTAP_ANTENNA = 11, 202 IEEE80211_RADIOTAP_ANTENNA = 11,
188 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, 203 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
189 IEEE80211_RADIOTAP_DB_ANTNOISE = 13, 204 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
190 IEEE80211_RADIOTAP_EXT = 31, 205 IEEE80211_RADIOTAP_RX_FLAGS = 14,
206 IEEE80211_RADIOTAP_TX_FLAGS = 15,
207 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
208 IEEE80211_RADIOTAP_DATA_RETRIES = 17,
209 IEEE80211_RADIOTAP_EXT = 31
191}; 210};
192 211
193/* Channel flags. */ 212/* Channel flags. */
@@ -219,6 +238,14 @@ enum ieee80211_radiotap_type {
219 * 802.11 header and payload 238 * 802.11 header and payload
220 * (to 32-bit boundary) 239 * (to 32-bit boundary)
221 */ 240 */
241/* For IEEE80211_RADIOTAP_RX_FLAGS */
242#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
243
244/* For IEEE80211_RADIOTAP_TX_FLAGS */
245#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
246 * retries */
247#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
248#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
222 249
223/* Ugly macro to convert literal channel numbers into their mhz equivalents 250/* Ugly macro to convert literal channel numbers into their mhz equivalents
224 * There are certianly some conditions that will break this (like feeding it '30') 251 * There are certianly some conditions that will break this (like feeding it '30')
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 5ed0a98b2d76..df5592c9339f 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Host AP crypto routines 2 * Host AP crypto routines
3 * 3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 4 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> 5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 35aa3426c3fa..b016b4104de6 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver 2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 * 3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -338,7 +338,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
338 338
339 if (ccmp_replay_check(pn, key->rx_pn)) { 339 if (ccmp_replay_check(pn, key->rx_pn)) {
340 if (net_ratelimit()) { 340 if (net_ratelimit()) {
341 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 341 IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=" MAC_FMT
342 " previous PN %02x%02x%02x%02x%02x%02x " 342 " previous PN %02x%02x%02x%02x%02x%02x "
343 "received PN %02x%02x%02x%02x%02x%02x\n", 343 "received PN %02x%02x%02x%02x%02x%02x\n",
344 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), 344 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index fc1f99a59732..5a48d8e0aec1 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver 2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 * 3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -465,7 +465,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
465 465
466 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { 466 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
467 if (net_ratelimit()) { 467 if (net_ratelimit()) {
468 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 468 IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=" MAC_FMT
469 " previous TSC %08x%04x received TSC " 469 " previous TSC %08x%04x received TSC "
470 "%08x%04x\n", MAC_ARG(hdr->addr2), 470 "%08x%04x\n", MAC_ARG(hdr->addr2),
471 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 471 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
@@ -507,7 +507,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
507 tkey->rx_phase1_done = 0; 507 tkey->rx_phase1_done = 0;
508 } 508 }
509 if (net_ratelimit()) { 509 if (net_ratelimit()) {
510 printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 510 IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA="
511 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 511 MAC_FMT "\n", MAC_ARG(hdr->addr2));
512 } 512 }
513 tkey->dot11RSNAStatsTKIPICVErrors++; 513 tkey->dot11RSNAStatsTKIPICVErrors++;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 4eb35079e434..8d182459344e 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver 2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 * 3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> 4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index b1c6d1f717d9..7ec6610841ba 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -5,8 +5,8 @@
5 Portions of this file are based on the WEP enablement code provided by the 5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3 6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi> 8 <j@w1.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
10 10
11 This program is free software; you can redistribute it and/or modify it 11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as 12 under the terms of version 2 of the GNU General Public License as
@@ -229,6 +229,7 @@ void free_ieee80211(struct net_device *dev)
229 229
230static int debug = 0; 230static int debug = 0;
231u32 ieee80211_debug_level = 0; 231u32 ieee80211_debug_level = 0;
232EXPORT_SYMBOL_GPL(ieee80211_debug_level);
232static struct proc_dir_entry *ieee80211_proc = NULL; 233static struct proc_dir_entry *ieee80211_proc = NULL;
233 234
234static int show_debug_level(char *page, char **start, off_t offset, 235static int show_debug_level(char *page, char **start, off_t offset,
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 6ae036b1920f..f2de2e48b021 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -3,8 +3,8 @@
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines 3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4 * 4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi> 6 * <j@w1.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
8 * Copyright (c) 2004-2005, Intel Corporation 8 * Copyright (c) 2004-2005, Intel Corporation
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 40d7a55fe03e..cee5e13bc427 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -5,8 +5,8 @@
5 Portions of this file are based on the WEP enablement code provided by the 5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3 6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi> 8 <j@w1.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
10 10
11 This program is free software; you can redistribute it and/or modify it 11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as 12 under the terms of version 2 of the GNU General Public License as