提交 a7c243b5 编写于 作者: L Linus Torvalds

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

=========================== Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
Intel(R) PRO/Wireless 2100 Network Connection
Copyright (C) 2003-2005, Intel Corporation
README.ipw2100 README.ipw2100
March 14, 2005 Version: 1.1.3
Date : October 17, 2005
===========================
Index Index
--------------------------- -----------------------------------------------
0. Introduction 0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Release 1.1.0 Current Features 1. Introduction
2. Command Line Parameters 2. Release 1.1.3 Current Features
3. Sysfs Helper Files 3. Command Line Parameters
4. Radio Kill Switch 4. Sysfs Helper Files
5. Dynamic Firmware 5. Radio Kill Switch
6. Power Management 6. Dynamic Firmware
7. Support 7. Power Management
8. License 8. Support
9. License
===========================
0. Introduction 0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
------------ ----- ----- ---- --- -- - -----------------------------------------------
Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
Intel wireless LAN adapters are engineered, manufactured, tested, and
quality checked to ensure that they meet all necessary local and
governmental regulatory agency requirements for the regions that they
are designated and/or marked to ship into. Since wireless LANs are
generally unlicensed devices that share spectrum with radars,
satellites, and other licensed and unlicensed devices, it is sometimes
necessary to dynamically detect, avoid, and limit usage to avoid
interference with these devices. In many instances Intel is required to
provide test data to prove regional and local compliance to regional and
governmental regulations before certification or approval to use the
product is granted. Intel's wireless LAN's EEPROM, firmware, and
software driver are designed to carefully control parameters that affect
radio operation and to ensure electromagnetic compliance (EMC). These
parameters include, without limitation, RF power, spectrum usage,
channel scanning, and human exposure.
For these reasons Intel cannot permit any manipulation by third parties
of the software provided in binary format with the wireless WLAN
adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
patches, utilities, or code with the Intel wireless LAN adapters that
have been manipulated by an unauthorized party (i.e., patches,
utilities, or code (including open source code modifications) which have
not been validated by Intel), (i) you will be solely responsible for
ensuring the regulatory compliance of the products, (ii) Intel will bear
no liability, under any theory of liability for any issues associated
with the modified products, including without limitation, claims under
the warranty and/or issues arising from regulatory non-compliance, and
(iii) Intel will not provide or be required to assist in providing
support to any third parties for such modified products.
Note: Many regulatory agencies consider Wireless LAN adapters to be
modules, and accordingly, condition system-level regulatory approval
upon receipt and review of test data documenting that the antennas and
system configuration do not cause the EMC and radio operation to be
non-compliant.
The drivers available for download from SourceForge are provided as a
part of a development project. Conformance to local regulatory
requirements is the responsibility of the individual developer. As
such, if you are interested in deploying or shipping a driver as part of
solution intended to be used for purposes other than development, please
obtain a tested driver from Intel Customer Support at:
http://support.intel.com/support/notebook/sb/CS-006408.htm
1. Introduction
-----------------------------------------------
This document provides a brief overview of the features supported by the This document provides a brief overview of the features supported by the
IPW2100 driver project. The main project website, where the latest IPW2100 driver project. The main project website, where the latest
...@@ -34,9 +89,8 @@ potential fixes and patches, as well as links to the development mailing list ...@@ -34,9 +89,8 @@ potential fixes and patches, as well as links to the development mailing list
for the driver project. for the driver project.
=========================== 2. Release 1.1.3 Current Supported Features
1. Release 1.1.0 Current Supported Features -----------------------------------------------
---------------------------
- Managed (BSS) and Ad-Hoc (IBSS) - Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open) - WEP (shared key and open)
- Wireless Tools support - Wireless Tools support
...@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been ...@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been
performed on a given feature. performed on a given feature.
=========================== 3. Command Line Parameters
2. Command Line Parameters -----------------------------------------------
---------------------------
If the driver is built as a module, the following optional parameters are used If the driver is built as a module, the following optional parameters are used
by entering them on the command line with the modprobe command using this by entering them on the command line with the modprobe command using this
...@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */ ...@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */ disable boolean disable=1 /* Do not power the HW */
=========================== 4. Sysfs Helper Files
3. Sysfs Helper Files
--------------------------- ---------------------------
-----------------------------------------------
There are several ways to control the behavior of the driver. Many of the There are several ways to control the behavior of the driver. Many of the
general capabilities are exposed through the Wireless Tools (iwconfig). There general capabilities are exposed through the Wireless Tools (iwconfig). There
...@@ -120,9 +173,8 @@ For the device level files, see /sys/bus/pci/drivers/ipw2100: ...@@ -120,9 +173,8 @@ For the device level files, see /sys/bus/pci/drivers/ipw2100:
based RF kill from ON -> OFF -> ON, the radio will NOT come back on based RF kill from ON -> OFF -> ON, the radio will NOT come back on
=========================== 5. Radio Kill Switch
4. Radio Kill Switch -----------------------------------------------
---------------------------
Most laptops provide the ability for the user to physically disable the radio. Most laptops provide the ability for the user to physically disable the radio.
Some vendors have implemented this as a physical switch that requires no Some vendors have implemented this as a physical switch that requires no
software to turn the radio off and on. On other laptops, however, the switch software to turn the radio off and on. On other laptops, however, the switch
...@@ -134,9 +186,8 @@ See the Sysfs helper file 'rf_kill' for determining the state of the RF switch ...@@ -134,9 +186,8 @@ See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
on your system. on your system.
=========================== 6. Dynamic Firmware
5. Dynamic Firmware -----------------------------------------------
---------------------------
As the firmware is licensed under a restricted use license, it can not be As the firmware is licensed under a restricted use license, it can not be
included within the kernel sources. To enable the IPW2100 you will need a included within the kernel sources. To enable the IPW2100 you will need a
firmware image to load into the wireless NIC's processors. firmware image to load into the wireless NIC's processors.
...@@ -146,9 +197,8 @@ You can obtain these images from <http://ipw2100.sf.net/firmware.php>. ...@@ -146,9 +197,8 @@ You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
See INSTALL for instructions on installing the firmware. See INSTALL for instructions on installing the firmware.
=========================== 7. Power Management
6. Power Management -----------------------------------------------
---------------------------
The IPW2100 supports the configuration of the Power Save Protocol The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports through a private wireless extension interface. The IPW2100 supports
the following different modes: the following different modes:
...@@ -200,9 +250,8 @@ xxxx/yyyy will be replaced with 'off' -- the level reported will be the active ...@@ -200,9 +250,8 @@ xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
level if `iwconfig eth1 power on` is invoked. level if `iwconfig eth1 power on` is invoked.
=========================== 8. Support
7. Support -----------------------------------------------
---------------------------
For general development information and support, For general development information and support,
go to: go to:
...@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels ...@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
http://supportmail.intel.com http://supportmail.intel.com
=========================== 9. License
8. License -----------------------------------------------
---------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
......
Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of: Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
Intel(R) PRO/Wireless 2200BG Network Connection Intel(R) PRO/Wireless 2200BG Network Connection
Intel(R) PRO/Wireless 2915ABG Network Connection Intel(R) PRO/Wireless 2915ABG Network Connection
Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R) Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
PRO/Wireless 2200BG Driver for Linux is a unified driver that works on PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
both hardware adapters listed above. In this document the Intel(R) both hardware adapters listed above. In this document the Intel(R)
PRO/Wireless 2915ABG Driver for Linux will be used to reference the PRO/Wireless 2915ABG Driver for Linux will be used to reference the
unified driver. unified driver.
Copyright (C) 2004-2005, Intel Corporation Copyright (C) 2004-2005, Intel Corporation
README.ipw2200 README.ipw2200
Version: 1.0.0 Version: 1.0.8
Date : January 31, 2005 Date : October 20, 2005
Index Index
----------------------------------------------- -----------------------------------------------
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Introduction 1. Introduction
1.1. Overview of features 1.1. Overview of features
1.2. Module parameters 1.2. Module parameters
1.3. Wireless Extension Private Methods 1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files 1.4. Sysfs Helper Files
2. About the Version Numbers 2. Ad-Hoc Networking
3. Support 3. Interacting with Wireless Tools
4. License 3.1. iwconfig mode
4. About the Version Numbers
5. Firmware installation
6. Support
7. License
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
-----------------------------------------------
Important Notice FOR ALL USERS OR DISTRIBUTORS!!!!
Intel wireless LAN adapters are engineered, manufactured, tested, and
quality checked to ensure that they meet all necessary local and
governmental regulatory agency requirements for the regions that they
are designated and/or marked to ship into. Since wireless LANs are
generally unlicensed devices that share spectrum with radars,
satellites, and other licensed and unlicensed devices, it is sometimes
necessary to dynamically detect, avoid, and limit usage to avoid
interference with these devices. In many instances Intel is required to
provide test data to prove regional and local compliance to regional and
governmental regulations before certification or approval to use the
product is granted. Intel's wireless LAN's EEPROM, firmware, and
software driver are designed to carefully control parameters that affect
radio operation and to ensure electromagnetic compliance (EMC). These
parameters include, without limitation, RF power, spectrum usage,
channel scanning, and human exposure.
For these reasons Intel cannot permit any manipulation by third parties
of the software provided in binary format with the wireless WLAN
adapters (e.g., the EEPROM and firmware). Furthermore, if you use any
patches, utilities, or code with the Intel wireless LAN adapters that
have been manipulated by an unauthorized party (i.e., patches,
utilities, or code (including open source code modifications) which have
not been validated by Intel), (i) you will be solely responsible for
ensuring the regulatory compliance of the products, (ii) Intel will bear
no liability, under any theory of liability for any issues associated
with the modified products, including without limitation, claims under
the warranty and/or issues arising from regulatory non-compliance, and
(iii) Intel will not provide or be required to assist in providing
support to any third parties for such modified products.
Note: Many regulatory agencies consider Wireless LAN adapters to be
modules, and accordingly, condition system-level regulatory approval
upon receipt and review of test data documenting that the antennas and
system configuration do not cause the EMC and radio operation to be
non-compliant.
The drivers available for download from SourceForge are provided as a
part of a development project. Conformance to local regulatory
requirements is the responsibility of the individual developer. As
such, if you are interested in deploying or shipping a driver as part of
solution intended to be used for purposes other than development, please
obtain a tested driver from Intel Customer Support at:
http://support.intel.com/support/notebook/sb/CS-006408.htm
1. Introduction 1. Introduction
...@@ -45,7 +101,7 @@ file. ...@@ -45,7 +101,7 @@ file.
1.1. Overview of Features 1.1. Overview of Features
----------------------------------------------- -----------------------------------------------
The current release (1.0.0) supports the following features: The current release (1.0.8) supports the following features:
+ BSS mode (Infrastructure, Managed) + BSS mode (Infrastructure, Managed)
+ IBSS mode (Ad-Hoc) + IBSS mode (Ad-Hoc)
...@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features: ...@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features:
+ Full A rate support (2915 only) + Full A rate support (2915 only)
+ Transmit power control + Transmit power control
+ S state support (ACPI suspend/resume) + S state support (ACPI suspend/resume)
The following features are currently enabled, but not officially
supported:
+ WPA
+ long/short preamble support + long/short preamble support
+ Monitor mode (aka RFMon)
The distinction between officially supported and enabled is a reflection
on the amount of validation and interoperability testing that has been
performed on a given feature.
1.2. Command Line Parameters 1.2. Command Line Parameters
----------------------------------------------- -----------------------------------------------
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
2915ABG Driver for Linux allows certain configuration options to be 2915ABG Driver for Linux allows configuration options to be provided
provided as module parameters. The most common way to specify a module as module parameters. The most common way to specify a module parameter
parameter is via the command line. is via the command line.
The general form is: The general form is:
...@@ -96,14 +162,18 @@ Where the supported parameter are: ...@@ -96,14 +162,18 @@ Where the supported parameter are:
debug debug
If using a debug build, this is used to control the amount of debug If using a debug build, this is used to control the amount of debug
info is logged. See the 'dval' and 'load' script for more info on info is logged. See the 'dvals' and 'load' script for more info on
how to use this (the dval and load scripts are provided as part how to use this (the dvals and load scripts are provided as part
of the ipw2200 development snapshot releases available from the of the ipw2200 development snapshot releases available from the
SourceForge project at http://ipw2200.sf.net) SourceForge project at http://ipw2200.sf.net)
led
Can be used to turn on experimental LED code.
0 = Off, 1 = On. Default is 0.
mode mode
Can be used to set the default mode of the adapter. Can be used to set the default mode of the adapter.
0 = Managed, 1 = Ad-Hoc 0 = Managed, 1 = Ad-Hoc, 2 = Monitor
1.3. Wireless Extension Private Methods 1.3. Wireless Extension Private Methods
...@@ -164,8 +234,8 @@ The supported private methods are: ...@@ -164,8 +234,8 @@ The supported private methods are:
----------------------------------------------- -----------------------------------------------
The Linux kernel provides a pseudo file system that can be used to The Linux kernel provides a pseudo file system that can be used to
access various components of the operating system. The Intel(R) access various components of the operating system. The Intel(R)
PRO/Wireless 2915ABG Driver for Linux exposes several configuration PRO/Wireless 2915ABG Driver for Linux exposes several configuration
parameters through this mechanism. parameters through this mechanism.
An entry in the sysfs can support reading and/or writing. You can An entry in the sysfs can support reading and/or writing. You can
...@@ -184,13 +254,13 @@ You can set the debug level via: ...@@ -184,13 +254,13 @@ You can set the debug level via:
Where $VALUE would be a number in the case of this sysfs entry. The Where $VALUE would be a number in the case of this sysfs entry. The
input to sysfs files does not have to be a number. For example, the input to sysfs files does not have to be a number. For example, the
firmware loader used by hotplug utilizes sysfs entries for transferring firmware loader used by hotplug utilizes sysfs entries for transfering
the firmware image from user space into the driver. the firmware image from user space into the driver.
The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
at two levels -- driver level, which apply to all instances of the at two levels -- driver level, which apply to all instances of the driver
driver (in the event that there are more than one device installed) and (in the event that there are more than one device installed) and device
device level, which applies only to the single specific instance. level, which applies only to the single specific instance.
1.4.1 Driver Level Sysfs Helper Files 1.4.1 Driver Level Sysfs Helper Files
...@@ -203,6 +273,7 @@ For the driver level files, look in /sys/bus/pci/drivers/ipw2200/ ...@@ -203,6 +273,7 @@ For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
This controls the same global as the 'debug' module parameter This controls the same global as the 'debug' module parameter
1.4.2 Device Level Sysfs Helper Files 1.4.2 Device Level Sysfs Helper Files
----------------------------------------------- -----------------------------------------------
...@@ -213,7 +284,7 @@ For the device level files, look in ...@@ -213,7 +284,7 @@ For the device level files, look in
For example: For example:
/sys/bus/pci/drivers/ipw2200/0000:02:01.0 /sys/bus/pci/drivers/ipw2200/0000:02:01.0
For the device level files, see /sys/bus/pci/[drivers/ipw2200: For the device level files, see /sys/bus/pci/drivers/ipw2200:
rf_kill rf_kill
read - read -
...@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200: ...@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200:
ucode ucode
read-only access to the ucode version number read-only access to the ucode version number
led
read -
0 = LED code disabled
1 = LED code enabled
write -
0 = Disable LED code
1 = Enable LED code
NOTE: The LED code has been reported to hang some systems when
running ifconfig and is therefore disabled by default.
2. Ad-Hoc Networking
-----------------------------------------------
When using a device in an Ad-Hoc network, it is useful to understand the
sequence and requirements for the driver to be able to create, join, or
merge networks.
The following attempts to provide enough information so that you can
have a consistent experience while using the driver as a member of an
Ad-Hoc network.
2.1. Joining an Ad-Hoc Network
-----------------------------------------------
The easiest way to get onto an Ad-Hoc network is to join one that
already exists.
2. About the Version Numbers 2.2. Creating an Ad-Hoc Network
-----------------------------------------------
An Ad-Hoc networks is created using the syntax of the Wireless tool.
For Example:
iwconfig eth1 mode ad-hoc essid testing channel 2
2.3. Merging Ad-Hoc Networks
-----------------------------------------------
3. Interaction with Wireless Tools
-----------------------------------------------
3.1 iwconfig mode
-----------------------------------------------
When configuring the mode of the adapter, all run-time configured parameters
are reset to the value used when the module was loaded. This includes
channels, rates, ESSID, etc.
4. About the Version Numbers
----------------------------------------------- -----------------------------------------------
Due to the nature of open source development projects, there are Due to the nature of open source development projects, there are
...@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected. ...@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected.
The major version number will be incremented when significant changes The major version number will be incremented when significant changes
are made to the driver. Currently, there are no major changes planned. are made to the driver. Currently, there are no major changes planned.
5. Firmware installation
----------------------------------------------
The driver requires a firmware image, download it and extract the
files under /lib/firmware (or wherever your hotplug's firmware.agent
will look for firmware files)
The firmware can be downloaded from the following URL:
3. Support http://ipw2200.sf.net/
6. Support
----------------------------------------------- -----------------------------------------------
For installation support of the 1.0.0 version, you can contact For direct support of the 1.0.0 version, you can contact
http://supportmail.intel.com, or you can use the open source project http://supportmail.intel.com, or you can use the open source project
support. support.
For general information and support, go to: For general information and support, go to:
...@@ -272,7 +405,7 @@ For general information and support, go to: ...@@ -272,7 +405,7 @@ For general information and support, go to:
http://ipw2200.sf.net/ http://ipw2200.sf.net/
4. License 7. License
----------------------------------------------- -----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
...@@ -297,4 +430,3 @@ For general information and support, go to: ...@@ -297,4 +430,3 @@ For general information and support, go to:
James P. Ketrenos <ipw2100-admin@linux.intel.com> James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
...@@ -1330,6 +1330,24 @@ M: john.ronciak@intel.com ...@@ -1330,6 +1330,24 @@ M: john.ronciak@intel.com
W: http://sourceforge.net/projects/e1000/ W: http://sourceforge.net/projects/e1000/
S: Supported S: Supported
INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
P: Yi Zhu
M: yi.zhu@intel.com
P: James Ketrenos
M: jketreno@linux.intel.com
L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
W: http://ipw2100.sourceforge.net
S: Supported
INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
P: Yi Zhu
M: yi.zhu@intel.com
P: James Ketrenos
M: jketreno@linux.intel.com
L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
W: http://ipw2200.sourceforge.net
S: Supported
IOC3 DRIVER IOC3 DRIVER
P: Ralf Baechle P: Ralf Baechle
M: ralf@linux-mips.org M: ralf@linux-mips.org
......
...@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) ...@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
return err; return err;
} }
static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static void uml_net_get_drvinfo(struct net_device *dev,
{ struct ethtool_drvinfo *info)
static const struct ethtool_drvinfo info = { {
.cmd = ETHTOOL_GDRVINFO, strcpy(info->driver, DRIVER_NAME);
.driver = DRIVER_NAME, strcpy(info->version, "42");
.version = "42",
};
void *useraddr;
u32 ethcmd;
switch (cmd) {
case SIOCETHTOOL:
useraddr = ifr->ifr_data;
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GDRVINFO:
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
default:
return -EOPNOTSUPP;
}
default:
return -EINVAL;
}
} }
static struct ethtool_ops uml_net_ethtool_ops = {
.get_drvinfo = uml_net_get_drvinfo,
.get_link = ethtool_op_get_link,
};
void uml_net_user_timer_expire(unsigned long _conn) void uml_net_user_timer_expire(unsigned long _conn)
{ {
#ifdef undef #ifdef undef
...@@ -359,7 +343,7 @@ static int eth_configure(int n, void *init, char *mac, ...@@ -359,7 +343,7 @@ static int eth_configure(int n, void *init, char *mac,
dev->tx_timeout = uml_net_tx_timeout; dev->tx_timeout = uml_net_tx_timeout;
dev->set_mac_address = uml_net_set_mac; dev->set_mac_address = uml_net_set_mac;
dev->change_mtu = uml_net_change_mtu; dev->change_mtu = uml_net_change_mtu;
dev->do_ioctl = uml_net_ioctl; dev->ethtool_ops = &uml_net_ethtool_ops;
dev->watchdog_timeo = (HZ >> 1); dev->watchdog_timeo = (HZ >> 1);
dev->irq = UM_ETH_IRQ; dev->irq = UM_ETH_IRQ;
......
...@@ -611,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu) ...@@ -611,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL; return -EINVAL;
} }
static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
#if 0
static const struct ethtool_drvinfo info = {
.cmd = ETHTOOL_GDRVINFO,
.driver = DRIVER_NAME,
.version = "42",
};
void *useraddr;
u32 ethcmd;
switch (cmd) {
case SIOCETHTOOL:
useraddr = ifr->ifr_data;
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GDRVINFO:
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
default:
return -EOPNOTSUPP;
}
default:
return -EINVAL;
}
#endif
return -EINVAL;
}
void iss_net_user_timer_expire(unsigned long _conn) void iss_net_user_timer_expire(unsigned long _conn)
{ {
} }
...@@ -730,7 +698,6 @@ static int iss_net_configure(int index, char *init) ...@@ -730,7 +698,6 @@ static int iss_net_configure(int index, char *init)
dev->tx_timeout = iss_net_tx_timeout; dev->tx_timeout = iss_net_tx_timeout;
dev->set_mac_address = iss_net_set_mac; dev->set_mac_address = iss_net_set_mac;
dev->change_mtu = iss_net_change_mtu; dev->change_mtu = iss_net_change_mtu;
dev->do_ioctl = iss_net_ioctl;
dev->watchdog_timeo = (HZ >> 1); dev->watchdog_timeo = (HZ >> 1);
dev->irq = -1; dev->irq = -1;
......
...@@ -447,7 +447,7 @@ config NET_SB1250_MAC ...@@ -447,7 +447,7 @@ config NET_SB1250_MAC
config SGI_IOC3_ETH config SGI_IOC3_ETH
bool "SGI IOC3 Ethernet" bool "SGI IOC3 Ethernet"
depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN depends on NET_ETHERNET && PCI && SGI_IP27
select CRC32 select CRC32
select MII select MII
help help
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#define DRV_MODULE_NAME "b44" #define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.95" #define DRV_MODULE_VERSION "0.96"
#define DRV_MODULE_RELDATE "Aug 3, 2004" #define DRV_MODULE_RELDATE "Nov 8, 2005"
#define B44_DEF_MSG_ENABLE \ #define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \ (NETIF_MSG_DRV | \
...@@ -101,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); ...@@ -101,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static void b44_halt(struct b44 *); static void b44_halt(struct b44 *);
static void b44_init_rings(struct b44 *); static void b44_init_rings(struct b44 *);
static void b44_init_hw(struct b44 *); static void b44_init_hw(struct b44 *);
static int b44_poll(struct net_device *dev, int *budget);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void b44_poll_controller(struct net_device *dev);
#endif
static int dma_desc_align_mask; static int dma_desc_align_mask;
static int dma_desc_sync_size; static int dma_desc_sync_size;
static const char b44_gstrings[][ETH_GSTRING_LEN] = {
#define _B44(x...) # x,
B44_STAT_REG_DECLARE
#undef _B44
};
static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
dma_addr_t dma_base, dma_addr_t dma_base,
unsigned long offset, unsigned long offset,
...@@ -501,7 +503,10 @@ static void b44_stats_update(struct b44 *bp) ...@@ -501,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
*val++ += br32(bp, reg); *val++ += br32(bp, reg);
} }
val = &bp->hw_stats.rx_good_octets;
/* Pad */
reg += 8*4UL;
for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
*val++ += br32(bp, reg); *val++ += br32(bp, reg);
} }
...@@ -652,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -652,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
/* Hardware bug work-around, the chip is unable to do PCI DMA /* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */ to/from anything above 1GB :-( */
if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
/* Sigh... */ /* Sigh... */
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
...@@ -662,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -662,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
mapping = pci_map_single(bp->pdev, skb->data, mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -ENOMEM; return -ENOMEM;
...@@ -889,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -889,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct net_device *dev = dev_id; struct net_device *dev = dev_id;
struct b44 *bp = netdev_priv(dev); struct b44 *bp = netdev_priv(dev);
unsigned long flags;
u32 istat, imask; u32 istat, imask;
int handled = 0; int handled = 0;
spin_lock_irqsave(&bp->lock, flags); spin_lock(&bp->lock);
istat = br32(bp, B44_ISTAT); istat = br32(bp, B44_ISTAT);
imask = br32(bp, B44_IMASK); imask = br32(bp, B44_IMASK);
...@@ -904,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -904,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
istat &= imask; istat &= imask;
if (istat) { if (istat) {
handled = 1; handled = 1;
if (unlikely(!netif_running(dev))) {
printk(KERN_INFO "%s: late interrupt.\n", dev->name);
goto irq_ack;
}
if (netif_rx_schedule_prep(dev)) { if (netif_rx_schedule_prep(dev)) {
/* NOTE: These writes are posted by the readback of /* NOTE: These writes are posted by the readback of
* the ISTAT register below. * the ISTAT register below.
...@@ -916,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -916,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
dev->name); dev->name);
} }
irq_ack:
bw32(bp, B44_ISTAT, istat); bw32(bp, B44_ISTAT, istat);
br32(bp, B44_ISTAT); br32(bp, B44_ISTAT);
} }
spin_unlock_irqrestore(&bp->lock, flags); spin_unlock(&bp->lock);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
...@@ -947,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -947,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct b44 *bp = netdev_priv(dev); struct b44 *bp = netdev_priv(dev);
struct sk_buff *bounce_skb; struct sk_buff *bounce_skb;
int rc = NETDEV_TX_OK;
dma_addr_t mapping; dma_addr_t mapping;
u32 len, entry, ctrl; u32 len, entry, ctrl;
...@@ -956,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -956,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This is a hard error, log it. */ /* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irq(&bp->lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name); dev->name);
return 1; goto err_out;
} }
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
if(mapping+len > B44_DMA_MASK) { if (mapping + len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */ /* Chip can't handle DMA to/from >1GB, use bounce buffer */
pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
GFP_ATOMIC|GFP_DMA); GFP_ATOMIC|GFP_DMA);
if (!bounce_skb) if (!bounce_skb)
return NETDEV_TX_BUSY; goto err_out;
mapping = pci_map_single(bp->pdev, bounce_skb->data, mapping = pci_map_single(bp->pdev, bounce_skb->data,
len, PCI_DMA_TODEVICE); len, PCI_DMA_TODEVICE);
if(mapping+len > B44_DMA_MASK) { if (mapping + len > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping, pci_unmap_single(bp->pdev, mapping,
len, PCI_DMA_TODEVICE); len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(bounce_skb); dev_kfree_skb_any(bounce_skb);
return NETDEV_TX_BUSY; goto err_out;
} }
memcpy(skb_put(bounce_skb, len), skb->data, skb->len); memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
...@@ -1018,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1018,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (TX_BUFFS_AVAIL(bp) < 1) if (TX_BUFFS_AVAIL(bp) < 1)
netif_stop_queue(dev); netif_stop_queue(dev);
dev->trans_start = jiffies;
out_unlock:
spin_unlock_irq(&bp->lock); spin_unlock_irq(&bp->lock);
dev->trans_start = jiffies; return rc;
return 0; err_out:
rc = NETDEV_TX_BUSY;
goto out_unlock;
} }
static int b44_change_mtu(struct net_device *dev, int new_mtu) static int b44_change_mtu(struct net_device *dev, int new_mtu)
...@@ -1096,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp) ...@@ -1096,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
* *
* The chip has been shut down and the driver detached from * The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will * the networking, so no interrupts or new tx packets will
* end up in the driver. bp->lock is not held and we are not * end up in the driver.
* in an interrupt context and thus may sleep.
*/ */
static void b44_init_rings(struct b44 *bp) static void b44_init_rings(struct b44 *bp)
{ {
...@@ -1169,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp) ...@@ -1169,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
int size; int size;
size = B44_RX_RING_SIZE * sizeof(struct ring_info); size = B44_RX_RING_SIZE * sizeof(struct ring_info);
bp->rx_buffers = kmalloc(size, GFP_KERNEL); bp->rx_buffers = kzalloc(size, GFP_KERNEL);
if (!bp->rx_buffers) if (!bp->rx_buffers)
goto out_err; goto out_err;
memset(bp->rx_buffers, 0, size);
size = B44_TX_RING_SIZE * sizeof(struct ring_info); size = B44_TX_RING_SIZE * sizeof(struct ring_info);
bp->tx_buffers = kmalloc(size, GFP_KERNEL); bp->tx_buffers = kzalloc(size, GFP_KERNEL);
if (!bp->tx_buffers) if (!bp->tx_buffers)
goto out_err; goto out_err;
memset(bp->tx_buffers, 0, size);
size = DMA_TABLE_BYTES; size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
...@@ -1189,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp) ...@@ -1189,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp)
struct dma_desc *rx_ring; struct dma_desc *rx_ring;
dma_addr_t rx_ring_dma; dma_addr_t rx_ring_dma;
if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) rx_ring = kzalloc(size, GFP_KERNEL);
if (!rx_ring)
goto out_err; goto out_err;
memset(rx_ring, 0, size);
rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
...@@ -1215,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp) ...@@ -1215,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
struct dma_desc *tx_ring; struct dma_desc *tx_ring;
dma_addr_t tx_ring_dma; dma_addr_t tx_ring_dma;
if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) tx_ring = kzalloc(size, GFP_KERNEL);
if (!tx_ring)
goto out_err; goto out_err;
memset(tx_ring, 0, size);
tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_TO_DEVICE); DMA_TO_DEVICE);
...@@ -1381,22 +1394,21 @@ static int b44_open(struct net_device *dev) ...@@ -1381,22 +1394,21 @@ static int b44_open(struct net_device *dev)
err = b44_alloc_consistent(bp); err = b44_alloc_consistent(bp);
if (err) if (err)
return err; goto out;
err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
if (err)
goto err_out_free;
spin_lock_irq(&bp->lock);
b44_init_rings(bp); b44_init_rings(bp);
b44_init_hw(bp); b44_init_hw(bp);
bp->flags |= B44_FLAG_INIT_COMPLETE;
netif_carrier_off(dev); netif_carrier_off(dev);
b44_check_phy(bp); b44_check_phy(bp);
spin_unlock_irq(&bp->lock); err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
if (unlikely(err < 0)) {
b44_chip_reset(bp);
b44_free_rings(bp);
b44_free_consistent(bp);
goto out;
}
init_timer(&bp->timer); init_timer(&bp->timer);
bp->timer.expires = jiffies + HZ; bp->timer.expires = jiffies + HZ;
...@@ -1405,11 +1417,7 @@ static int b44_open(struct net_device *dev) ...@@ -1405,11 +1417,7 @@ static int b44_open(struct net_device *dev)
add_timer(&bp->timer); add_timer(&bp->timer);
b44_enable_ints(bp); b44_enable_ints(bp);
out:
return 0;
err_out_free:
b44_free_consistent(bp);
return err; return err;
} }
...@@ -1444,6 +1452,8 @@ static int b44_close(struct net_device *dev) ...@@ -1444,6 +1452,8 @@ static int b44_close(struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
netif_poll_disable(dev);
del_timer_sync(&bp->timer); del_timer_sync(&bp->timer);
spin_lock_irq(&bp->lock); spin_lock_irq(&bp->lock);
...@@ -1453,13 +1463,14 @@ static int b44_close(struct net_device *dev) ...@@ -1453,13 +1463,14 @@ static int b44_close(struct net_device *dev)
#endif #endif
b44_halt(bp); b44_halt(bp);
b44_free_rings(bp); b44_free_rings(bp);
bp->flags &= ~B44_FLAG_INIT_COMPLETE;
netif_carrier_off(bp->dev); netif_carrier_off(bp->dev);
spin_unlock_irq(&bp->lock); spin_unlock_irq(&bp->lock);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
netif_poll_enable(dev);
b44_free_consistent(bp); b44_free_consistent(bp);
return 0; return 0;
...@@ -1524,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev) ...@@ -1524,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
{ {
struct b44 *bp = netdev_priv(dev); struct b44 *bp = netdev_priv(dev);
u32 val; u32 val;
int i=0;
unsigned char zero[6] = {0,0,0,0,0,0};
val = br32(bp, B44_RXCONFIG); val = br32(bp, B44_RXCONFIG);
val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
...@@ -1533,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev) ...@@ -1533,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
val |= RXCONFIG_PROMISC; val |= RXCONFIG_PROMISC;
bw32(bp, B44_RXCONFIG, val); bw32(bp, B44_RXCONFIG, val);
} else { } else {
unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
int i = 0;
__b44_set_mac_addr(bp); __b44_set_mac_addr(bp);
if (dev->flags & IFF_ALLMULTI) if (dev->flags & IFF_ALLMULTI)
val |= RXCONFIG_ALLMULTI; val |= RXCONFIG_ALLMULTI;
else else
i=__b44_load_mcast(bp, dev); i = __b44_load_mcast(bp, dev);
for(;i<64;i++) { for (; i < 64; i++) {
__b44_cam_write(bp, zero, i); __b44_cam_write(bp, zero, i);
} }
bw32(bp, B44_RXCONFIG, val); bw32(bp, B44_RXCONFIG, val);
...@@ -1604,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -1604,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct b44 *bp = netdev_priv(dev); struct b44 *bp = netdev_priv(dev);
if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) if (!netif_running(dev))
return -EAGAIN; return -EAGAIN;
cmd->supported = (SUPPORTED_Autoneg); cmd->supported = (SUPPORTED_Autoneg);
cmd->supported |= (SUPPORTED_100baseT_Half | cmd->supported |= (SUPPORTED_100baseT_Half |
...@@ -1642,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -1642,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct b44 *bp = netdev_priv(dev); struct b44 *bp = netdev_priv(dev);
if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) if (!netif_running(dev))
return -EAGAIN; return -EAGAIN;
/* We do not support gigabit. */ /* We do not support gigabit. */
...@@ -1772,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev, ...@@ -1772,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
return 0; return 0;
} }
static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
case ETH_SS_STATS:
memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
break;
}
}
static int b44_get_stats_count(struct net_device *dev)
{
return ARRAY_SIZE(b44_gstrings);
}
static void b44_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct b44 *bp = netdev_priv(dev);
u32 *val = &bp->hw_stats.tx_good_octets;
u32 i;
spin_lock_irq(&bp->lock);
b44_stats_update(bp);
for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
*data++ = *val++;
spin_unlock_irq(&bp->lock);
}
static struct ethtool_ops b44_ethtool_ops = { static struct ethtool_ops b44_ethtool_ops = {
.get_drvinfo = b44_get_drvinfo, .get_drvinfo = b44_get_drvinfo,
.get_settings = b44_get_settings, .get_settings = b44_get_settings,
...@@ -1784,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = { ...@@ -1784,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
.set_pauseparam = b44_set_pauseparam, .set_pauseparam = b44_set_pauseparam,
.get_msglevel = b44_get_msglevel, .get_msglevel = b44_get_msglevel,
.set_msglevel = b44_set_msglevel, .set_msglevel = b44_set_msglevel,
.get_strings = b44_get_strings,
.get_stats_count = b44_get_stats_count,
.get_ethtool_stats = b44_get_ethtool_stats,
.get_perm_addr = ethtool_op_get_perm_addr, .get_perm_addr = ethtool_op_get_perm_addr,
}; };
...@@ -1892,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev, ...@@ -1892,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
if (err) { if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, " printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n"); "aborting.\n");
goto err_out_free_res; goto err_out_free_res;
} }
b44reg_base = pci_resource_start(pdev, 0); b44reg_base = pci_resource_start(pdev, 0);
...@@ -1916,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev, ...@@ -1916,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
bp = netdev_priv(dev); bp = netdev_priv(dev);
bp->pdev = pdev; bp->pdev = pdev;
bp->dev = dev; bp->dev = dev;
if (b44_debug >= 0)
bp->msg_enable = (1 << b44_debug) - 1; bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
else
bp->msg_enable = B44_DEF_MSG_ENABLE;
spin_lock_init(&bp->lock); spin_lock_init(&bp->lock);
...@@ -2009,17 +2053,14 @@ static int __devinit b44_init_one(struct pci_dev *pdev, ...@@ -2009,17 +2053,14 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
static void __devexit b44_remove_one(struct pci_dev *pdev) static void __devexit b44_remove_one(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
struct b44 *bp = netdev_priv(dev);
if (dev) { unregister_netdev(dev);
struct b44 *bp = netdev_priv(dev); iounmap(bp->regs);
free_netdev(dev);
unregister_netdev(dev); pci_release_regions(pdev);
iounmap(bp->regs); pci_disable_device(pdev);
free_netdev(dev); pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
} }
static int b44_suspend(struct pci_dev *pdev, pm_message_t state) static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
......
...@@ -346,29 +346,63 @@ struct ring_info { ...@@ -346,29 +346,63 @@ struct ring_info {
#define B44_MCAST_TABLE_SIZE 32 #define B44_MCAST_TABLE_SIZE 32
#define B44_STAT_REG_DECLARE \
_B44(tx_good_octets) \
_B44(tx_good_pkts) \
_B44(tx_octets) \
_B44(tx_pkts) \
_B44(tx_broadcast_pkts) \
_B44(tx_multicast_pkts) \
_B44(tx_len_64) \
_B44(tx_len_65_to_127) \
_B44(tx_len_128_to_255) \
_B44(tx_len_256_to_511) \
_B44(tx_len_512_to_1023) \
_B44(tx_len_1024_to_max) \
_B44(tx_jabber_pkts) \
_B44(tx_oversize_pkts) \
_B44(tx_fragment_pkts) \
_B44(tx_underruns) \
_B44(tx_total_cols) \
_B44(tx_single_cols) \
_B44(tx_multiple_cols) \
_B44(tx_excessive_cols) \
_B44(tx_late_cols) \
_B44(tx_defered) \
_B44(tx_carrier_lost) \
_B44(tx_pause_pkts) \
_B44(rx_good_octets) \
_B44(rx_good_pkts) \
_B44(rx_octets) \
_B44(rx_pkts) \
_B44(rx_broadcast_pkts) \
_B44(rx_multicast_pkts) \
_B44(rx_len_64) \
_B44(rx_len_65_to_127) \
_B44(rx_len_128_to_255) \
_B44(rx_len_256_to_511) \
_B44(rx_len_512_to_1023) \
_B44(rx_len_1024_to_max) \
_B44(rx_jabber_pkts) \
_B44(rx_oversize_pkts) \
_B44(rx_fragment_pkts) \
_B44(rx_missed_pkts) \
_B44(rx_crc_align_errs) \
_B44(rx_undersize) \
_B44(rx_crc_errs) \
_B44(rx_align_errs) \
_B44(rx_symbol_errs) \
_B44(rx_pause_pkts) \
_B44(rx_nonpause_pkts)
/* SW copy of device statistics, kept up to date by periodic timer /* SW copy of device statistics, kept up to date by periodic timer
* which probes HW values. Must have same relative layout as HW * which probes HW values. Check b44_stats_update if you mess with
* register above, because b44_stats_update depends upon this. * the layout
*/ */
struct b44_hw_stats { struct b44_hw_stats {
u32 tx_good_octets, tx_good_pkts, tx_octets; #define _B44(x) u32 x;
u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; B44_STAT_REG_DECLARE
u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; #undef _B44
u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
u32 tx_underruns, tx_total_cols, tx_single_cols;
u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
u32 __pad1[8];
u32 rx_good_octets, rx_good_pkts, rx_octets;
u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
u32 rx_pause_pkts, rx_nonpause_pkts;
}; };
struct b44 { struct b44 {
...@@ -386,7 +420,6 @@ struct b44 { ...@@ -386,7 +420,6 @@ struct b44 {
u32 dma_offset; u32 dma_offset;
u32 flags; u32 flags;
#define B44_FLAG_INIT_COMPLETE 0x00000001
#define B44_FLAG_BUGGY_TXPTR 0x00000002 #define B44_FLAG_BUGGY_TXPTR 0x00000002
#define B44_FLAG_REORDER_BUG 0x00000004 #define B44_FLAG_REORDER_BUG 0x00000004
#define B44_FLAG_PAUSE_AUTO 0x00008000 #define B44_FLAG_PAUSE_AUTO 0x00008000
......
...@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_ ...@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
/* /*
* Compute the features available to the bonding device by * Compute the common dev->feature set available to all slaves. Some
* intersection of all of the slave devices' BOND_INTERSECT_FEATURES. * feature bits are managed elsewhere, so preserve feature bits set on
* Call this after attaching or detaching a slave to update the * master device that are not part of the examined set.
* bond's features.
*/ */
static int bond_compute_features(struct bonding *bond) static int bond_compute_features(struct bonding *bond)
{ {
int i; unsigned long features = BOND_INTERSECT_FEATURES;
struct slave *slave; struct slave *slave;
struct net_device *bond_dev = bond->dev; struct net_device *bond_dev = bond->dev;
int features = bond->bond_features; int i;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i)
struct net_device * slave_dev = slave->dev; features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
if (i == 0) {
features |= BOND_INTERSECT_FEATURES;
}
features &=
~(~slave_dev->features & BOND_INTERSECT_FEATURES);
}
/* turn off NETIF_F_SG if we need a csum and h/w can't do it */
if ((features & NETIF_F_SG) && if ((features & NETIF_F_SG) &&
!(features & (NETIF_F_IP_CSUM | !(features & (NETIF_F_IP_CSUM |
NETIF_F_NO_CSUM | NETIF_F_NO_CSUM |
NETIF_F_HW_CSUM))) { NETIF_F_HW_CSUM)))
features &= ~NETIF_F_SG; features &= ~NETIF_F_SG;
}
features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
bond_dev->features = features; bond_dev->features = features;
return 0; return 0;
...@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par ...@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER); NETIF_F_HW_VLAN_FILTER);
bond->bond_features = bond_dev->features;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond); bond_create_proc_entry(bond);
#endif #endif
......
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
#include "bond_3ad.h" #include "bond_3ad.h"
#include "bond_alb.h" #include "bond_alb.h"
#define DRV_VERSION "2.6.4" #define DRV_VERSION "2.6.5"
#define DRV_RELDATE "September 26, 2005" #define DRV_RELDATE "November 4, 2005"
#define DRV_NAME "bonding" #define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
...@@ -211,9 +211,6 @@ struct bonding { ...@@ -211,9 +211,6 @@ struct bonding {
struct bond_params params; struct bond_params params;
struct list_head vlan_list; struct list_head vlan_list;
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
/* the features the bonding device supports, independently
* of any slaves */
int bond_features;
}; };
/** /**
......
...@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void e100_rx(struct net_device *dev); static void e100_rx(struct net_device *dev);
static int e100_close(struct net_device *dev); static int e100_close(struct net_device *dev);
static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
static int e100_set_config(struct net_device* dev, struct ifmap* map); static int e100_set_config(struct net_device* dev, struct ifmap* map);
static void e100_tx_timeout(struct net_device *dev); static void e100_tx_timeout(struct net_device *dev);
static struct net_device_stats *e100_get_stats(struct net_device *dev); static struct net_device_stats *e100_get_stats(struct net_device *dev);
...@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net); ...@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
static void e100_clear_network_leds(unsigned long dummy); static void e100_clear_network_leds(unsigned long dummy);
static void e100_set_network_leds(int active); static void e100_set_network_leds(int active);
static struct ethtool_ops e100_ethtool_ops;
static void broadcom_check_speed(struct net_device* dev); static void broadcom_check_speed(struct net_device* dev);
static void broadcom_check_duplex(struct net_device* dev); static void broadcom_check_duplex(struct net_device* dev);
static void tdk_check_speed(struct net_device* dev); static void tdk_check_speed(struct net_device* dev);
...@@ -495,6 +496,7 @@ etrax_ethernet_init(void) ...@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
dev->get_stats = e100_get_stats; dev->get_stats = e100_get_stats;
dev->set_multicast_list = set_multicast_list; dev->set_multicast_list = set_multicast_list;
dev->set_mac_address = e100_set_mac_address; dev->set_mac_address = e100_set_mac_address;
dev->ethtool_ops = &e100_ethtool_ops;
dev->do_ioctl = e100_ioctl; dev->do_ioctl = e100_ioctl;
dev->set_config = e100_set_config; dev->set_config = e100_set_config;
dev->tx_timeout = e100_tx_timeout; dev->tx_timeout = e100_tx_timeout;
...@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
spin_lock(&np->lock); /* Preempt protection */ spin_lock(&np->lock); /* Preempt protection */
switch (cmd) { switch (cmd) {
case SIOCETHTOOL:
return e100_ethtool_ioctl(dev,ifr);
case SIOCGMIIPHY: /* Get PHY address */ case SIOCGMIIPHY: /* Get PHY address */
data->phy_id = mdio_phy_addr; data->phy_id = mdio_phy_addr;
break; break;
...@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
} }
static int static int e100_set_settings(struct net_device *dev,
e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) struct ethtool_cmd *ecmd)
{ {
struct ethtool_cmd ecmd; ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
return -EFAULT;
switch (ecmd.cmd) {
case ETHTOOL_GSET:
{
memset((void *) &ecmd, 0, sizeof (ecmd));
ecmd.supported =
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
ecmd.port = PORT_TP; ecmd->port = PORT_TP;
ecmd.transceiver = XCVR_EXTERNAL; ecmd->transceiver = XCVR_EXTERNAL;
ecmd.phy_address = mdio_phy_addr; ecmd->phy_address = mdio_phy_addr;
ecmd.speed = current_speed; ecmd->speed = current_speed;
ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
ecmd.advertising = ADVERTISED_TP; ecmd->advertising = ADVERTISED_TP;
if (current_duplex == autoneg && current_speed_selection == 0)
ecmd.advertising |= ADVERTISED_Autoneg; if (current_duplex == autoneg && current_speed_selection == 0)
else { ecmd->advertising |= ADVERTISED_Autoneg;
ecmd.advertising |= else {
ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | ecmd->advertising |=
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
if (current_speed_selection == 10) ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); if (current_speed_selection == 10)
else if (current_speed_selection == 100) ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); ADVERTISED_100baseT_Full);
if (current_duplex == half) else if (current_speed_selection == 100)
ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
else if (current_duplex == full) ADVERTISED_10baseT_Full);
ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); if (current_duplex == half)
} ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
ecmd.autoneg = AUTONEG_ENABLE; ADVERTISED_100baseT_Full);
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) else if (current_duplex == full)
return -EFAULT; ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
} ADVERTISED_100baseT_Half);
break; }
case ETHTOOL_SSET:
{ ecmd->autoneg = AUTONEG_ENABLE;
if (!capable(CAP_NET_ADMIN)) { return 0;
return -EPERM; }
}
if (ecmd.autoneg == AUTONEG_ENABLE) { static int e100_set_settings(struct net_device *dev,
e100_set_duplex(dev, autoneg); struct ethtool_cmd *ecmd)
e100_set_speed(dev, 0); {
} else { if (ecmd->autoneg == AUTONEG_ENABLE) {
e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); e100_set_duplex(dev, autoneg);
e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); e100_set_speed(dev, 0);
} } else {
} e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
break; e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
case ETHTOOL_GDRVINFO:
{
struct ethtool_drvinfo info;
memset((void *) &info, 0, sizeof (info));
strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
info.regdump_len = 0;
info.eedump_len = 0;
info.testinfo_len = 0;
if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT;
}
break;
case ETHTOOL_NWAY_RST:
if (current_duplex == autoneg && current_speed_selection == 0)
e100_negotiate(dev);
break;
default:
return -EOPNOTSUPP;
break;
} }
return 0;
}
static void e100_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
}
static int e100_nway_reset(struct net_device *dev)
{
if (current_duplex == autoneg && current_speed_selection == 0)
e100_negotiate(dev);
return 0; return 0;
} }
static struct ethtool_ops e100_ethtool_ops = {
.get_settings = e100_get_settings,
.set_settings = e100_set_settings,
.get_drvinfo = e100_get_drvinfo,
.nway_reset = e100_nway_reset,
.get_link = ethtool_op_get_link,
};
static int static int
e100_set_config(struct net_device *dev, struct ifmap *map) e100_set_config(struct net_device *dev, struct ifmap *map)
{ {
......
...@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi- ...@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
static int __init dgrs_init_module (void) static int __init dgrs_init_module (void)
{ {
int i; int i;
int eisacount = 0, pcicount = 0; int cardcount = 0;
/* /*
* Command line variable overrides * Command line variable overrides
...@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void) ...@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
* Find and configure all the cards * Find and configure all the cards
*/ */
#ifdef CONFIG_EISA #ifdef CONFIG_EISA
eisacount = eisa_driver_register(&dgrs_eisa_driver); cardcount = eisa_driver_register(&dgrs_eisa_driver);
if (eisacount < 0) if (cardcount < 0)
return eisacount; return cardcount;
#endif
#ifdef CONFIG_PCI
pcicount = pci_register_driver(&dgrs_pci_driver);
if (pcicount)
return pcicount;
#endif #endif
cardcount = pci_register_driver(&dgrs_pci_driver);
if (cardcount)
return cardcount;
return 0; return 0;
} }
......
...@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) ...@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
if(pci_dma_mapping_error(rx->dma_addr)) { if(pci_dma_mapping_error(rx->dma_addr)) {
dev_kfree_skb_any(rx->skb); dev_kfree_skb_any(rx->skb);
rx->skb = 0; rx->skb = NULL;
rx->dma_addr = 0; rx->dma_addr = 0;
return -ENOMEM; return -ENOMEM;
} }
...@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic) ...@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
if((err = e100_hw_init(nic))) if((err = e100_hw_init(nic)))
goto err_clean_cbs; goto err_clean_cbs;
e100_set_multicast_list(nic->netdev); e100_set_multicast_list(nic->netdev);
e100_start_receiver(nic, 0); e100_start_receiver(nic, NULL);
mod_timer(&nic->watchdog, jiffies); mod_timer(&nic->watchdog, jiffies);
if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
nic->netdev->name, nic->netdev))) nic->netdev->name, nic->netdev)))
...@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) ...@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
BMCR_LOOPBACK); BMCR_LOOPBACK);
e100_start_receiver(nic, 0); e100_start_receiver(nic, NULL);
if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
err = -ENOMEM; err = -ENOMEM;
......
...@@ -110,7 +110,6 @@ ...@@ -110,7 +110,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ip.h> /* for iph */ #include <linux/ip.h> /* for iph */
#include <linux/in.h> /* for IPPROTO_... */ #include <linux/in.h> /* for IPPROTO_... */
#include <linux/eeprom.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/prefetch.h> #include <linux/prefetch.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
...@@ -445,7 +444,6 @@ struct ns83820 { ...@@ -445,7 +444,6 @@ struct ns83820 {
u32 MEAR_cache; u32 MEAR_cache;
u32 IMR_cache; u32 IMR_cache;
struct eeprom ee;
unsigned linkstate; unsigned linkstate;
...@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac) ...@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
unsigned i; unsigned i;
for (i=0; i<3; i++) { for (i=0; i<3; i++) {
u32 data; u32 data;
#if 0 /* I've left this in as an example of how to use eeprom.h */
data = eeprom_readw(&dev->ee, 0xa + 2 - i);
#else
/* Read from the perfect match memory: this is loaded by /* Read from the perfect match memory: this is loaded by
* the chip from the EEPROM via the EELOAD self test. * the chip from the EEPROM via the EELOAD self test.
*/ */
writel(i*2, dev->base + RFCR); writel(i*2, dev->base + RFCR);
data = readl(dev->base + RFDR); data = readl(dev->base + RFDR);
#endif
*mac++ = data; *mac++ = data;
*mac++ = data >> 8; *mac++ = data >> 8;
} }
...@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ ...@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
spin_lock_init(&dev->misc_lock); spin_lock_init(&dev->misc_lock);
dev->pci_dev = pci_dev; dev->pci_dev = pci_dev;
dev->ee.cache = &dev->MEAR_cache;
dev->ee.lock = &dev->misc_lock;
SET_MODULE_OWNER(ndev); SET_MODULE_OWNER(ndev);
SET_NETDEV_DEV(ndev, &pci_dev->dev); SET_NETDEV_DEV(ndev, &pci_dev->dev);
...@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ ...@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->IMR_cache = 0; dev->IMR_cache = 0;
setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
0);
err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
DRV_NAME, ndev); DRV_NAME, ndev);
if (err) { if (err) {
......
...@@ -1531,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1531,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
#define LINK_UP_DOWN_INTERRUPT 1 #define LINK_UP_DOWN_INTERRUPT 1
#define MAC_RMAC_ERR_TIMER 2 #define MAC_RMAC_ERR_TIMER 2
int s2io_link_fault_indication(nic_t *nic) static int s2io_link_fault_indication(nic_t *nic)
{ {
if (nic->intr_type != INTA) if (nic->intr_type != INTA)
return MAC_RMAC_ERR_TIMER; return MAC_RMAC_ERR_TIMER;
...@@ -1863,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag) ...@@ -1863,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
* *
*/ */
void fix_mac_address(nic_t * sp) static void fix_mac_address(nic_t * sp)
{ {
XENA_dev_config_t __iomem *bar0 = sp->bar0; XENA_dev_config_t __iomem *bar0 = sp->bar0;
u64 val64; u64 val64;
...@@ -2159,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) ...@@ -2159,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
* SUCCESS on success or an appropriate -ve value on failure. * SUCCESS on success or an appropriate -ve value on failure.
*/ */
int fill_rx_buffers(struct s2io_nic *nic, int ring_no) static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
{ {
struct net_device *dev = nic->dev; struct net_device *dev = nic->dev;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -2830,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) ...@@ -2830,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
* SUCCESS on success and FAILURE on failure. * SUCCESS on success and FAILURE on failure.
*/ */
int wait_for_cmd_complete(nic_t * sp) static int wait_for_cmd_complete(nic_t * sp)
{ {
XENA_dev_config_t __iomem *bar0 = sp->bar0; XENA_dev_config_t __iomem *bar0 = sp->bar0;
int ret = FAILURE, cnt = 0; int ret = FAILURE, cnt = 0;
...@@ -3076,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp) ...@@ -3076,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
return SUCCESS; return SUCCESS;
} }
int wait_for_msix_trans(nic_t *nic, int i) static int wait_for_msix_trans(nic_t *nic, int i)
{ {
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
u64 val64; u64 val64;
...@@ -3115,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic) ...@@ -3115,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic)
} }
} }
void store_xmsi_data(nic_t *nic) static void store_xmsi_data(nic_t *nic)
{ {
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
u64 val64, addr, data; u64 val64, addr, data;
...@@ -3287,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic) ...@@ -3287,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
* file on failure. * file on failure.
*/ */
int s2io_open(struct net_device *dev) static int s2io_open(struct net_device *dev)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
int err = 0; int err = 0;
...@@ -3417,7 +3417,7 @@ failed\n", dev->name, i); ...@@ -3417,7 +3417,7 @@ failed\n", dev->name, i);
* file on failure. * file on failure.
*/ */
int s2io_close(struct net_device *dev) static int s2io_close(struct net_device *dev)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
int i; int i;
...@@ -3466,7 +3466,7 @@ int s2io_close(struct net_device *dev) ...@@ -3466,7 +3466,7 @@ int s2io_close(struct net_device *dev)
* 0 on success & 1 on failure. * 0 on success & 1 on failure.
*/ */
int s2io_xmit(struct sk_buff *skb, struct net_device *dev) static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
...@@ -3912,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp) ...@@ -3912,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
* pointer to the updated net_device_stats structure. * pointer to the updated net_device_stats structure.
*/ */
struct net_device_stats *s2io_get_stats(struct net_device *dev) static struct net_device_stats *s2io_get_stats(struct net_device *dev)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
mac_info_t *mac_control; mac_info_t *mac_control;
...@@ -5105,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev, ...@@ -5105,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
} }
int s2io_ethtool_get_regs_len(struct net_device *dev) static int s2io_ethtool_get_regs_len(struct net_device *dev)
{ {
return (XENA_REG_SPACE); return (XENA_REG_SPACE);
} }
u32 s2io_ethtool_get_rx_csum(struct net_device * dev) static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
return (sp->rx_csum); return (sp->rx_csum);
} }
int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
...@@ -5128,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) ...@@ -5128,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
return 0; return 0;
} }
int s2io_get_eeprom_len(struct net_device *dev)
static int s2io_get_eeprom_len(struct net_device *dev)
{ {
return (XENA_EEPROM_SPACE); return (XENA_EEPROM_SPACE);
} }
int s2io_ethtool_self_test_count(struct net_device *dev) static int s2io_ethtool_self_test_count(struct net_device *dev)
{ {
return (S2IO_TEST_LEN); return (S2IO_TEST_LEN);
} }
void s2io_ethtool_get_strings(struct net_device *dev,
u32 stringset, u8 * data) static void s2io_ethtool_get_strings(struct net_device *dev,
u32 stringset, u8 * data)
{ {
switch (stringset) { switch (stringset) {
case ETH_SS_TEST: case ETH_SS_TEST:
...@@ -5154,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev) ...@@ -5154,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
return (S2IO_STAT_LEN); return (S2IO_STAT_LEN);
} }
int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
{ {
if (data) if (data)
dev->features |= NETIF_F_IP_CSUM; dev->features |= NETIF_F_IP_CSUM;
...@@ -5207,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = { ...@@ -5207,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
* function always return EOPNOTSUPPORTED * function always return EOPNOTSUPPORTED
*/ */
int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -5223,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -5223,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* file on failure. * file on failure.
*/ */
int s2io_change_mtu(struct net_device *dev, int new_mtu) static int s2io_change_mtu(struct net_device *dev, int new_mtu)
{ {
nic_t *sp = dev->priv; nic_t *sp = dev->priv;
......
...@@ -37,12 +37,13 @@ ...@@ -37,12 +37,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mii.h>
#include <asm/irq.h> #include <asm/irq.h>
#include "skge.h" #include "skge.h"
#define DRV_NAME "skge" #define DRV_NAME "skge"
#define DRV_VERSION "1.1" #define DRV_VERSION "1.2"
#define PFX DRV_NAME " " #define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128 #define DEFAULT_TX_RING_SIZE 128
...@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); ...@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static int skge_up(struct net_device *dev); static int skge_up(struct net_device *dev);
static int skge_down(struct net_device *dev); static int skge_down(struct net_device *dev);
static void skge_tx_clean(struct skge_port *skge); static void skge_tx_clean(struct skge_port *skge);
static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static void genesis_get_stats(struct skge_port *skge, u64 *data); static void genesis_get_stats(struct skge_port *skge, u64 *data);
static void yukon_get_stats(struct skge_port *skge, u64 *data); static void yukon_get_stats(struct skge_port *skge, u64 *data);
static void yukon_init(struct skge_hw *hw, int port); static void yukon_init(struct skge_hw *hw, int port);
...@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, ...@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs->len - B3_RI_WTO_R1); regs->len - B3_RI_WTO_R1);
} }
/* Wake on Lan only supported on Yukon chps with rev 1 or above */ /* Wake on Lan only supported on Yukon chips with rev 1 or above */
static int wol_supported(const struct skge_hw *hw) static int wol_supported(const struct skge_hw *hw)
{ {
return !((hw->chip_id == CHIP_ID_GENESIS || return !((hw->chip_id == CHIP_ID_GENESIS ||
...@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ...@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0; return 0;
} }
/* Determine supported/adverised modes based on hardware. /* Determine supported/advertised modes based on hardware.
* Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
*/ */
static u32 skge_supported_modes(const struct skge_hw *hw) static u32 skge_supported_modes(const struct skge_hw *hw)
{ {
...@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw) ...@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
return 78215; /* or: 78.125 MHz */ return 78215; /* or: 78.125 MHz */
} }
/* Chip hz to microseconds */ /* Chip HZ to microseconds */
static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
{ {
return (ticks * 1000) / hwkhz(hw); return (ticks * 1000) / hwkhz(hw);
} }
/* Microseconds to chip hz */ /* Microseconds to chip HZ */
static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
{ {
return hwkhz(hw) * usec / 1000; return hwkhz(hw) * usec / 1000;
...@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge) ...@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
} }
static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
{ {
int i; int i;
u16 v;
xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
v = xm_read16(hw, port, XM_PHY_DATA); xm_read16(hw, port, XM_PHY_DATA);
/* Need to wait for external PHY */ /* Need to wait for external PHY */
for (i = 0; i < PHY_RETRIES; i++) { for (i = 0; i < PHY_RETRIES; i++) {
udelay(1); udelay(1);
if (xm_read16(hw, port, XM_MMU_CMD) if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
& XM_MMU_PHY_RDY)
goto ready; goto ready;
} }
printk(KERN_WARNING PFX "%s: phy read timed out\n", return -ETIMEDOUT;
hw->dev[port]->name);
return 0;
ready: ready:
v = xm_read16(hw, port, XM_PHY_DATA); *val = xm_read16(hw, port, XM_PHY_DATA);
return 0;
}
static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
u16 v = 0;
if (__xm_phy_read(hw, port, reg, &v))
printk(KERN_WARNING PFX "%s: phy read timed out\n",
hw->dev[port]->name);
return v; return v;
} }
static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{ {
int i; int i;
...@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) ...@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
goto ready; goto ready;
udelay(1); udelay(1);
} }
printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", return -EIO;
hw->dev[port]->name);
ready: ready:
xm_write16(hw, port, XM_PHY_DATA, val); xm_write16(hw, port, XM_PHY_DATA, val);
for (i = 0; i < PHY_RETRIES; i++) { return 0;
udelay(1);
if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
return;
}
printk(KERN_WARNING PFX "%s: phy write timed out\n",
hw->dev[port]->name);
} }
static void genesis_init(struct skge_hw *hw) static void genesis_init(struct skge_hw *hw)
...@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) ...@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
/* Use link status change interrrupt */ /* Use link status change interrupt */
xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
bcom_check_link(hw, port); bcom_check_link(hw, port);
...@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) ...@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write32(hw, B2_GP_IO, r); skge_write32(hw, B2_GP_IO, r);
skge_read32(hw, B2_GP_IO); skge_read32(hw, B2_GP_IO);
/* Enable GMII interfac */ /* Enable GMII interface */
xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
bcom_phy_init(skge, jumbo); bcom_phy_init(skge, jumbo);
...@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) ...@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* that jumbo frames larger than 8192 bytes will be * that jumbo frames larger than 8192 bytes will be
* truncated. Disabling all bad frame filtering causes * truncated. Disabling all bad frame filtering causes
* the RX FIFO to operate in streaming mode, in which * the RX FIFO to operate in streaming mode, in which
* case the XMAC will start transfering frames out of the * case the XMAC will start transferring frames out of the
* RX FIFO as soon as the FIFO threshold is reached. * RX FIFO as soon as the FIFO threshold is reached.
*/ */
xm_write32(hw, port, XM_MODE, XM_DEF_MODE); xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
...@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge) ...@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
/* /*
* If the transfer stucks at the MAC the STOP command will not * If the transfer sticks at the MAC the STOP command will not
* terminate if we don't flush the XMAC's transmit FIFO ! * terminate if we don't flush the XMAC's transmit FIFO !
*/ */
xm_write32(hw, port, XM_MODE, xm_write32(hw, port, XM_MODE,
...@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) ...@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
} }
} }
static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
int i;
gma_write16(hw, port, GM_SMI_DATA, val);
gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
break;
}
}
static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
int i;
gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr)
| GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
goto ready;
}
printk(KERN_WARNING PFX "%s: phy read timeout\n",
hw->dev[port]->name);
return 0;
ready:
return gma_read16(hw, port, GM_SMI_DATA);
}
static void genesis_link_up(struct skge_port *skge) static void genesis_link_up(struct skge_port *skge)
{ {
struct skge_hw *hw = skge->hw; struct skge_hw *hw = skge->hw;
...@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge) ...@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
} }
/* Marvell Phy Initailization */ static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
int i;
gma_write16(hw, port, GM_SMI_DATA, val);
gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
return 0;
}
printk(KERN_WARNING PFX "%s: phy write timeout\n",
hw->dev[port]->name);
return -EIO;
}
static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
{
int i;
gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr)
| GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
goto ready;
}
return -ETIMEDOUT;
ready:
*val = gma_read16(hw, port, GM_SMI_DATA);
return 0;
}
static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
u16 v = 0;
if (__gm_phy_read(hw, port, reg, &v))
printk(KERN_WARNING PFX "%s: phy read timeout\n",
hw->dev[port]->name);
return v;
}
/* Marvell Phy Initialization */
static void yukon_init(struct skge_hw *hw, int port) static void yukon_init(struct skge_hw *hw, int port)
{ {
struct skge_port *skge = netdev_priv(hw->dev[port]); struct skge_port *skge = netdev_priv(hw->dev[port]);
...@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port) ...@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
} }
/* Go into power down mode */
static void yukon_suspend(struct skge_hw *hw, int port)
{
u16 ctrl;
ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
ctrl |= PHY_M_PC_POL_R_DIS;
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
ctrl |= PHY_CT_RESET;
gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
/* switch IEEE compatible power down mode on */
ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
ctrl |= PHY_CT_PDOWN;
gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
}
static void yukon_stop(struct skge_port *skge) static void yukon_stop(struct skge_port *skge)
{ {
struct skge_hw *hw = skge->hw; struct skge_hw *hw = skge->hw;
...@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge) ...@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
& ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
gma_read16(hw, port, GM_GP_CTRL); gma_read16(hw, port, GM_GP_CTRL);
if (hw->chip_id == CHIP_ID_YUKON_LITE && yukon_suspend(hw, port);
hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
u32 io = skge_read32(hw, B2_GP_IO);
io |= GP_DIR_9 | GP_IO_9;
skge_write32(hw, B2_GP_IO, io);
skge_read32(hw, B2_GP_IO);
}
/* set GPHY Control reset */ /* set GPHY Control reset */
skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
...@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge) ...@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
/* XXX restart autonegotiation? */ /* XXX restart autonegotiation? */
} }
/* Basic MII support */
static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct mii_ioctl_data *data = if_mii(ifr);
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
int err = -EOPNOTSUPP;
if (!netif_running(dev))
return -ENODEV; /* Phy still in reset */
switch(cmd) {
case SIOCGMIIPHY:
data->phy_id = hw->phy_addr;
/* fallthru */
case SIOCGMIIREG: {
u16 val = 0;
spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
else
err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
spin_unlock_bh(&hw->phy_lock);
data->val_out = val;
break;
}
case SIOCSMIIREG:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
data->val_in);
else
err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
data->val_in);
spin_unlock_bh(&hw->phy_lock);
break;
}
return err;
}
static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
{ {
u32 end; u32 end;
...@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev) ...@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
hw->intr_mask |= portirqmask[port]; hw->intr_mask |= portirqmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask); skge_write32(hw, B0_IMSK, hw->intr_mask);
/* Initialze MAC */ /* Initialize MAC */
spin_lock_bh(&hw->phy_lock); spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS) if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_init(hw, port); genesis_mac_init(hw, port);
...@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev) ...@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
reg = gma_read16(hw, port, GM_RX_CTRL); reg = gma_read16(hw, port, GM_RX_CTRL);
reg |= GM_RXCR_UCF_ENA; reg |= GM_RXCR_UCF_ENA;
if (dev->flags & IFF_PROMISC) /* promiscious */ if (dev->flags & IFF_PROMISC) /* promiscuous */
reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
else if (dev->flags & IFF_ALLMULTI) /* all multicast */ else if (dev->flags & IFF_ALLMULTI) /* all multicast */
memset(filter, 0xff, sizeof(filter)); memset(filter, 0xff, sizeof(filter));
...@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget) ...@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
unsigned int to_do = min(dev->quota, *budget); unsigned int to_do = min(dev->quota, *budget);
unsigned int work_done = 0; unsigned int work_done = 0;
for (e = ring->to_clean; work_done < to_do; e = e->next) { for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
struct skge_rx_desc *rd = e->desc; struct skge_rx_desc *rd = e->desc;
struct sk_buff *skb; struct sk_buff *skb;
u32 control; u32 control;
...@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget) ...@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
if (work_done >= to_do) if (work_done >= to_do)
return 1; /* not done */ return 1; /* not done */
local_irq_disable(); netif_rx_complete(dev);
__netif_rx_complete(dev);
hw->intr_mask |= portirqmask[skge->port]; hw->intr_mask |= portirqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask); skge_write32(hw, B0_IMSK, hw->intr_mask);
local_irq_enable(); skge_read32(hw, B0_IMSK);
return 0; return 0;
} }
...@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev) ...@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct skge_element *e; struct skge_element *e;
spin_lock(&skge->tx_lock); spin_lock(&skge->tx_lock);
for (e = ring->to_clean; e != ring->to_use; e = e->next) { for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
struct skge_tx_desc *td = e->desc; struct skge_tx_desc *td = e->desc;
u32 control; u32 control;
...@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw) ...@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
} }
/* /*
* Interrrupt from PHY are handled in tasklet (soft irq) * Interrupt from PHY are handled in tasklet (soft irq)
* because accessing phy registers requires spin wait which might * because accessing phy registers requires spin wait which might
* cause excess interrupt latency. * cause excess interrupt latency.
*/ */
...@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data) ...@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
local_irq_enable(); local_irq_enable();
} }
static inline void skge_wakeup(struct net_device *dev)
{
struct skge_port *skge = netdev_priv(dev);
prefetch(skge->rx_ring.to_clean);
netif_rx_schedule(dev);
}
static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct skge_hw *hw = dev_id; struct skge_hw *hw = dev_id;
...@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
status &= hw->intr_mask; status &= hw->intr_mask;
if (status & IS_R1_F) { if (status & IS_R1_F) {
hw->intr_mask &= ~IS_R1_F; hw->intr_mask &= ~IS_R1_F;
netif_rx_schedule(hw->dev[0]); skge_wakeup(hw->dev[0]);
} }
if (status & IS_R2_F) { if (status & IS_R2_F) {
hw->intr_mask &= ~IS_R2_F; hw->intr_mask &= ~IS_R2_F;
netif_rx_schedule(hw->dev[1]); skge_wakeup(hw->dev[1]);
} }
if (status & IS_XA1_F) if (status & IS_XA1_F)
...@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw) ...@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
*/ */
static int skge_reset(struct skge_hw *hw) static int skge_reset(struct skge_hw *hw)
{ {
u32 reg;
u16 ctst; u16 ctst;
u8 t8, mac_cfg, pmd_type, phy_type; u8 t8, mac_cfg, pmd_type, phy_type;
int i; int i;
...@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw) ...@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */ /* switch power to VCC (WA for VAUX problem) */
skge_write8(hw, B0_POWER_CTRL, skge_write8(hw, B0_POWER_CTRL,
PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
/* avoid boards with stuck Hardware error bits */ /* avoid boards with stuck Hardware error bits */
if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
(skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
...@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw) ...@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
hw->intr_mask &= ~IS_HW_ERR; hw->intr_mask &= ~IS_HW_ERR;
} }
/* Clear PHY COMA */
skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
reg &= ~PCI_PHY_COMA;
pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
for (i = 0; i < hw->ports; i++) { for (i = 0; i < hw->ports; i++) {
skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
...@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, ...@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
SET_NETDEV_DEV(dev, &hw->pdev->dev); SET_NETDEV_DEV(dev, &hw->pdev->dev);
dev->open = skge_up; dev->open = skge_up;
dev->stop = skge_down; dev->stop = skge_down;
dev->do_ioctl = skge_ioctl;
dev->hard_start_xmit = skge_xmit_frame; dev->hard_start_xmit = skge_xmit_frame;
dev->get_stats = skge_get_stats; dev->get_stats = skge_get_stats;
if (hw->chip_id == CHIP_ID_GENESIS) if (hw->chip_id == CHIP_ID_GENESIS)
...@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, ...@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
} }
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
/* byte swap decriptors in hardware */ /* byte swap descriptors in hardware */
{ {
u32 reg; u32 reg;
...@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev, ...@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
#endif #endif
err = -ENOMEM; err = -ENOMEM;
hw = kmalloc(sizeof(*hw), GFP_KERNEL); hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw) { if (!hw) {
printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
pci_name(pdev)); pci_name(pdev));
goto err_out_free_regions; goto err_out_free_regions;
} }
memset(hw, 0, sizeof(*hw));
hw->pdev = pdev; hw->pdev = pdev;
spin_lock_init(&hw->phy_lock); spin_lock_init(&hw->phy_lock);
tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
...@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, ...@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
if (err) if (err)
goto err_out_free_irq; goto err_out_free_irq;
printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
pci_resource_start(pdev, 0), pdev->irq, pci_resource_start(pdev, 0), pdev->irq,
skge_board_name(hw), hw->chip_rev); skge_board_name(hw), hw->chip_rev);
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
/* PCI config registers */ /* PCI config registers */
#define PCI_DEV_REG1 0x40 #define PCI_DEV_REG1 0x40
#define PCI_PHY_COMA 0x8000000
#define PCI_VIO 0x2000000
#define PCI_DEV_REG2 0x44 #define PCI_DEV_REG2 0x44
#define PCI_REV_DESC 0x4 #define PCI_REV_DESC 0x4
......
...@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) { ...@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
StatusRid status_rid; StatusRid status_rid;
int i; int i;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
...@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode, ...@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
int i, j; int i, j;
u32 *vals = stats.vals; u32 *vals = stats.vals;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
...@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) { ...@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
struct airo_info *ai = dev->priv; struct airo_info *ai = dev->priv;
int i; int i;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer); kfree (data->rbuffer);
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
memset( data->wbuffer, 0, 2048 );
data->maxwritelen = 2048; data->maxwritelen = 2048;
data->on_close = proc_config_on_close; data->on_close = proc_config_on_close;
...@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) { ...@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
int j=0; int j=0;
int rc; int rc;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
memset(&wkr, 0, sizeof(wkr)); memset(&wkr, 0, sizeof(wkr));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
memset(data->rbuffer, 0, 180);
data->writelen = 0; data->writelen = 0;
data->maxwritelen = 80; data->maxwritelen = 80;
if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) { if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer); kfree (data->rbuffer);
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
memset( data->wbuffer, 0, 80 );
data->on_close = proc_wepkey_on_close; data->on_close = proc_wepkey_on_close;
ptr = data->rbuffer; ptr = data->rbuffer;
...@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) { ...@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
char *ptr; char *ptr;
SsidRid SSID_rid; SsidRid SSID_rid;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
...@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) { ...@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
} }
data->writelen = 0; data->writelen = 0;
data->maxwritelen = 33*3; data->maxwritelen = 33*3;
if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) { if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer); kfree (data->rbuffer);
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
memset( data->wbuffer, 0, 33*3 );
data->on_close = proc_SSID_on_close; data->on_close = proc_SSID_on_close;
readSsidRid(ai, &SSID_rid); readSsidRid(ai, &SSID_rid);
...@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { ...@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
char *ptr; char *ptr;
APListRid APList_rid; APListRid APList_rid;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
...@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { ...@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
} }
data->writelen = 0; data->writelen = 0;
data->maxwritelen = 4*6*3; data->maxwritelen = 4*6*3;
if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) { if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer); kfree (data->rbuffer);
kfree (file->private_data); kfree (file->private_data);
return -ENOMEM; return -ENOMEM;
} }
memset( data->wbuffer, 0, data->maxwritelen );
data->on_close = proc_APList_on_close; data->on_close = proc_APList_on_close;
readAPListRid(ai, &APList_rid); readAPListRid(ai, &APList_rid);
...@@ -5297,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { ...@@ -5297,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
/* If doLoseSync is not 1, we won't do a Lose Sync */ /* If doLoseSync is not 1, we won't do a Lose Sync */
int doLoseSync = -1; int doLoseSync = -1;
if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM; return -ENOMEM;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data; data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
kfree (file->private_data); kfree (file->private_data);
......
...@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void) ...@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void)
DEBUG(0, "airo_attach()\n"); DEBUG(0, "airo_attach()\n");
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) { if (!link) {
printk(KERN_ERR "airo_cs: no memory for new device\n"); printk(KERN_ERR "airo_cs: no memory for new device\n");
return NULL; return NULL;
} }
memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */ /* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
...@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void) ...@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) { if (!local) {
printk(KERN_ERR "airo_cs: no memory for new device\n"); printk(KERN_ERR "airo_cs: no memory for new device\n");
kfree (link); kfree (link);
return NULL; return NULL;
} }
memset(local, 0, sizeof(local_info_t));
link->priv = local; link->priv = local;
/* Register with Card Services */ /* Register with Card Services */
......
...@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev, ...@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
int k,i,j; int k,i,j;
dwrq->length = sizeof(struct iw_range); dwrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(range)); memset(range, 0, sizeof(struct iw_range));
range->min_nwid = 0x0000; range->min_nwid = 0x0000;
range->max_nwid = 0x0000; range->max_nwid = 0x0000;
range->num_channels = 0; range->num_channels = 0;
......
...@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void) ...@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
DEBUG(0, "atmel_attach()\n"); DEBUG(0, "atmel_attach()\n");
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) { if (!link) {
printk(KERN_ERR "atmel_cs: no memory for new device\n"); printk(KERN_ERR "atmel_cs: no memory for new device\n");
return NULL; return NULL;
} }
memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */ /* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
...@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void) ...@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) { if (!local) {
printk(KERN_ERR "atmel_cs: no memory for new device\n"); printk(KERN_ERR "atmel_cs: no memory for new device\n");
kfree (link); kfree (link);
return NULL; return NULL;
} }
memset(local, 0, sizeof(local_info_t));
link->priv = local; link->priv = local;
/* Register with Card Services */ /* Register with Card Services */
......
此差异已折叠。
/****************************************************************************** /******************************************************************************
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as under the terms of version 2 of the GNU General Public License as
...@@ -92,7 +92,6 @@ struct ipw2100_rx_packet; ...@@ -92,7 +92,6 @@ struct ipw2100_rx_packet;
#define IPW_DL_IOCTL (1<<14) #define IPW_DL_IOCTL (1<<14)
#define IPW_DL_RF_KILL (1<<17) #define IPW_DL_RF_KILL (1<<17)
#define IPW_DL_MANAGE (1<<15) #define IPW_DL_MANAGE (1<<15)
#define IPW_DL_FW (1<<16) #define IPW_DL_FW (1<<16)
...@@ -155,7 +154,9 @@ extern const char *band_str[]; ...@@ -155,7 +154,9 @@ extern const char *band_str[];
struct bd_status { struct bd_status {
union { union {
struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields; struct {
u8 nlf:1, txType:2, intEnabled:1, reserved:4;
} fields;
u8 field; u8 field;
} info; } info;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -164,7 +165,7 @@ struct ipw2100_bd { ...@@ -164,7 +165,7 @@ struct ipw2100_bd {
u32 host_addr; u32 host_addr;
u32 buf_length; u32 buf_length;
struct bd_status status; struct bd_status status;
/* number of fragments for frame (should be set only for /* number of fragments for frame (should be set only for
* 1st TBD) */ * 1st TBD) */
u8 num_fragments; u8 num_fragments;
u8 reserved[6]; u8 reserved[6];
...@@ -292,10 +293,10 @@ struct ipw2100_cmd_header { ...@@ -292,10 +293,10 @@ struct ipw2100_cmd_header {
struct ipw2100_data_header { struct ipw2100_data_header {
u32 host_command_reg; u32 host_command_reg;
u32 host_command_reg1; u32 host_command_reg1;
u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
u8 key[16]; u8 key[16];
u8 reserved[10]; // f/w reserved u8 reserved[10]; // f/w reserved
u8 src_addr[ETH_ALEN]; u8 src_addr[ETH_ALEN];
...@@ -305,14 +306,13 @@ struct ipw2100_data_header { ...@@ -305,14 +306,13 @@ struct ipw2100_data_header {
/* Host command data structure */ /* Host command data structure */
struct host_command { struct host_command {
u32 host_command; // COMMAND ID u32 host_command; // COMMAND ID
u32 host_command1; // COMMAND ID u32 host_command1; // COMMAND ID
u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
u32 host_command_length; // LENGTH u32 host_command_length; // LENGTH
u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
} __attribute__ ((packed)); } __attribute__ ((packed));
typedef enum { typedef enum {
POWER_ON_RESET, POWER_ON_RESET,
EXIT_POWER_DOWN_RESET, EXIT_POWER_DOWN_RESET,
...@@ -327,17 +327,16 @@ enum { ...@@ -327,17 +327,16 @@ enum {
RX RX
}; };
struct ipw2100_tx_packet { struct ipw2100_tx_packet {
int type; int type;
int index; int index;
union { union {
struct { /* COMMAND */ struct { /* COMMAND */
struct ipw2100_cmd_header* cmd; struct ipw2100_cmd_header *cmd;
dma_addr_t cmd_phys; dma_addr_t cmd_phys;
} c_struct; } c_struct;
struct { /* DATA */ struct { /* DATA */
struct ipw2100_data_header* data; struct ipw2100_data_header *data;
dma_addr_t data_phys; dma_addr_t data_phys;
struct ieee80211_txb *txb; struct ieee80211_txb *txb;
} d_struct; } d_struct;
...@@ -347,7 +346,6 @@ struct ipw2100_tx_packet { ...@@ -347,7 +346,6 @@ struct ipw2100_tx_packet {
struct list_head list; struct list_head list;
}; };
struct ipw2100_rx_packet { struct ipw2100_rx_packet {
struct ipw2100_rx *rxp; struct ipw2100_rx *rxp;
dma_addr_t dma_addr; dma_addr_t dma_addr;
...@@ -431,13 +429,13 @@ enum { ...@@ -431,13 +429,13 @@ enum {
}; };
#define STATUS_POWERED (1<<0) #define STATUS_POWERED (1<<0)
#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */ #define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */ #define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */ #define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */ #define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */ #define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */ #define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */ #define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
#define STATUS_INT_ENABLED (1<<11) #define STATUS_INT_ENABLED (1<<11)
#define STATUS_RF_KILL_HW (1<<12) #define STATUS_RF_KILL_HW (1<<12)
#define STATUS_RF_KILL_SW (1<<13) #define STATUS_RF_KILL_SW (1<<13)
...@@ -450,9 +448,7 @@ enum { ...@@ -450,9 +448,7 @@ enum {
#define STATUS_SCAN_COMPLETE (1<<26) #define STATUS_SCAN_COMPLETE (1<<26)
#define STATUS_WX_EVENT_PENDING (1<<27) #define STATUS_WX_EVENT_PENDING (1<<27)
#define STATUS_RESET_PENDING (1<<29) #define STATUS_RESET_PENDING (1<<29)
#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */ #define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
/* Internal NIC states */ /* Internal NIC states */
#define IPW_STATE_INITIALIZED (1<<0) #define IPW_STATE_INITIALIZED (1<<0)
...@@ -468,11 +464,9 @@ enum { ...@@ -468,11 +464,9 @@ enum {
#define IPW_STATE_POWER_DOWN (1<<10) #define IPW_STATE_POWER_DOWN (1<<10)
#define IPW_STATE_SCANNING (1<<11) #define IPW_STATE_SCANNING (1<<11)
#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ #define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#define CFG_CUSTOM_MAC (1<<3) #define CFG_CUSTOM_MAC (1<<3)
#define CFG_LONG_PREAMBLE (1<<4) #define CFG_LONG_PREAMBLE (1<<4)
#define CFG_ASSOCIATE (1<<6) #define CFG_ASSOCIATE (1<<6)
...@@ -480,14 +474,17 @@ enum { ...@@ -480,14 +474,17 @@ enum {
#define CFG_ADHOC_CREATE (1<<8) #define CFG_ADHOC_CREATE (1<<8)
#define CFG_C3_DISABLED (1<<9) #define CFG_C3_DISABLED (1<<9)
#define CFG_PASSIVE_SCAN (1<<10) #define CFG_PASSIVE_SCAN (1<<10)
#ifdef CONFIG_IPW2100_MONITOR
#define CFG_CRC_CHECK (1<<11)
#endif
#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ #define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ #define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
struct ipw2100_priv { struct ipw2100_priv {
int stop_hang_check; /* Set 1 when shutting down to kill hang_check */ int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */ int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
struct ieee80211_device *ieee; struct ieee80211_device *ieee;
unsigned long status; unsigned long status;
...@@ -518,19 +515,16 @@ struct ipw2100_priv { ...@@ -518,19 +515,16 @@ struct ipw2100_priv {
unsigned long hw_features; unsigned long hw_features;
int hangs; int hangs;
u32 last_rtc; u32 last_rtc;
int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */ int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
u8* snapshot[0x30]; u8 *snapshot[0x30];
u8 mandatory_bssid_mac[ETH_ALEN]; u8 mandatory_bssid_mac[ETH_ALEN];
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
int power_mode; int power_mode;
/* WEP data */
struct ieee80211_security sec;
int messages_sent; int messages_sent;
int short_retry_limit; int short_retry_limit;
int long_retry_limit; int long_retry_limit;
...@@ -598,7 +592,6 @@ struct ipw2100_priv { ...@@ -598,7 +592,6 @@ struct ipw2100_priv {
wait_queue_head_t wait_command_queue; wait_queue_head_t wait_command_queue;
}; };
/********************************************************* /*********************************************************
* Host Command -> From Driver to FW * Host Command -> From Driver to FW
*********************************************************/ *********************************************************/
...@@ -645,7 +638,6 @@ struct ipw2100_priv { ...@@ -645,7 +638,6 @@ struct ipw2100_priv {
#define CARD_DISABLE_PHY_OFF 61 #define CARD_DISABLE_PHY_OFF 61
#define MSDU_TX_RATES 62 #define MSDU_TX_RATES 62
/* Rogue AP Detection */ /* Rogue AP Detection */
#define SET_STATION_STAT_BITS 64 #define SET_STATION_STAT_BITS 64
#define CLEAR_STATIONS_STAT_BITS 65 #define CLEAR_STATIONS_STAT_BITS 65
...@@ -654,8 +646,6 @@ struct ipw2100_priv { ...@@ -654,8 +646,6 @@ struct ipw2100_priv {
#define DISASSOCIATION_BSSID 68 #define DISASSOCIATION_BSSID 68
#define SET_WPA_IE 69 #define SET_WPA_IE 69
/* system configuration bit mask: */ /* system configuration bit mask: */
#define IPW_CFG_MONITOR 0x00004 #define IPW_CFG_MONITOR 0x00004
#define IPW_CFG_PREAMBLE_AUTO 0x00010 #define IPW_CFG_PREAMBLE_AUTO 0x00010
...@@ -703,7 +693,7 @@ struct ipw2100_priv { ...@@ -703,7 +693,7 @@ struct ipw2100_priv {
#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB) #define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1 #define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2 #define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3 #define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4 #define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5 #define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16 #define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
...@@ -783,9 +773,6 @@ struct ipw2100_priv { ...@@ -783,9 +773,6 @@ struct ipw2100_priv {
#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli #define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli #define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr) #define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
#define IPW_MAX_80211_PAYLOAD_SIZE 2304U #define IPW_MAX_80211_PAYLOAD_SIZE 2304U
#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312 #define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
...@@ -842,8 +829,8 @@ struct ipw2100_rx { ...@@ -842,8 +829,8 @@ struct ipw2100_rx {
#define IPW_TX_POWER_MIN_DBM (-12) #define IPW_TX_POWER_MIN_DBM (-12)
#define IPW_TX_POWER_MAX_DBM 16 #define IPW_TX_POWER_MAX_DBM 16
#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan #define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan #define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
#define REG_MIN_CHANNEL 0 #define REG_MIN_CHANNEL 0
#define REG_MAX_CHANNEL 14 #define REG_MAX_CHANNEL 14
...@@ -855,7 +842,6 @@ struct ipw2100_rx { ...@@ -855,7 +842,6 @@ struct ipw2100_rx {
#define DIVERSITY_ANTENNA_A 1 // Use antenna A #define DIVERSITY_ANTENNA_A 1 // Use antenna A
#define DIVERSITY_ANTENNA_B 2 // Use antenna B #define DIVERSITY_ANTENNA_B 2 // Use antenna B
#define HOST_COMMAND_WAIT 0 #define HOST_COMMAND_WAIT 0
#define HOST_COMMAND_NO_WAIT 1 #define HOST_COMMAND_NO_WAIT 1
...@@ -872,10 +858,9 @@ struct ipw2100_rx { ...@@ -872,10 +858,9 @@ struct ipw2100_rx {
#define TYPE_ASSOCIATION_REQUEST 0x0013 #define TYPE_ASSOCIATION_REQUEST 0x0013
#define TYPE_REASSOCIATION_REQUEST 0x0014 #define TYPE_REASSOCIATION_REQUEST 0x0014
#define HW_FEATURE_RFKILL 0x0001
#define HW_FEATURE_RFKILL (0x0001) #define RF_KILLSWITCH_OFF 1
#define RF_KILLSWITCH_OFF (1) #define RF_KILLSWITCH_ON 0
#define RF_KILLSWITCH_ON (0)
#define IPW_COMMAND_POOL_SIZE 40 #define IPW_COMMAND_POOL_SIZE 40
...@@ -894,7 +879,7 @@ struct ipw2100_rx { ...@@ -894,7 +879,7 @@ struct ipw2100_rx {
// Fixed size data: Ordinal Table 1 // Fixed size data: Ordinal Table 1
typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
// Transmit statistics // Transmit statistics
IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU) IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU) IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU) IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
...@@ -904,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW ...@@ -904,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
IPW_ORD_STAT_TX_BEACON, // # of tx beacon IPW_ORD_STAT_TX_BEACON, // # of tx beacon
IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
IPW_ORD_STAT_TX_RETRIES, // # of Tx retries IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
// Receive statistics // Receive statistics
...@@ -951,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW ...@@ -951,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
...@@ -976,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW ...@@ -976,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_AUTH, // # of authentication Rx IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
...@@ -1005,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW ...@@ -1005,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
// PSP Statistics // PSP Statistics
IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
// Association and roaming // Association and roaming
IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
// AP table entry. set to 0 if not associated // AP table entry. set to 0 if not associated
...@@ -1150,7 +1135,7 @@ struct ipw2100_fw_chunk { ...@@ -1150,7 +1135,7 @@ struct ipw2100_fw_chunk {
}; };
struct ipw2100_fw_chunk_set { struct ipw2100_fw_chunk_set {
const void *data; const void *data;
unsigned long size; unsigned long size;
}; };
...@@ -1163,4 +1148,4 @@ struct ipw2100_fw { ...@@ -1163,4 +1148,4 @@ struct ipw2100_fw {
#define MAX_FW_VERSION_LEN 14 #define MAX_FW_VERSION_LEN 14
#endif /* _IPW2100_H */ #endif /* _IPW2100_H */
此差异已折叠。
此差异已折叠。
...@@ -111,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block, ...@@ -111,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
void void
isl38xx_trigger_device(int asleep, void __iomem *device_base) isl38xx_trigger_device(int asleep, void __iomem *device_base)
{ {
u32 reg, counter = 0; u32 reg;
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES
u32 counter = 0;
struct timeval current_time; struct timeval current_time;
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
#endif #endif
...@@ -130,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base) ...@@ -130,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
current_time.tv_sec, (long)current_time.tv_usec, current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG)); readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif #endif
udelay(ISL38XX_WRITEIO_DELAY);
reg = readl(device_base + ISL38XX_INT_IDENT_REG); reg = readl(device_base + ISL38XX_INT_IDENT_REG);
if (reg == 0xabadface) { if (reg == 0xabadface) {
...@@ -144,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base) ...@@ -144,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
(reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
udelay(ISL38XX_WRITEIO_DELAY); udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
counter++; counter++;
#endif
} }
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES
...@@ -152,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base) ...@@ -152,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
"%08li.%08li Device register read %08x\n", "%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec, current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG)); readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time); do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING, DEBUG(SHOW_TRACING,
"%08li.%08li Device asleep counter %i\n", "%08li.%08li Device asleep counter %i\n",
...@@ -170,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base) ...@@ -170,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
/* perform another read on the Device Status Register */ /* perform another read on the Device Status Register */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG); reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time); do_gettimeofday(&current_time);
...@@ -186,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base) ...@@ -186,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
ISL38XX_DEV_INT_REG); ISL38XX_DEV_INT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
} }
} }
......
...@@ -226,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -226,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
priv->data_low_tx_full = 1; priv->data_low_tx_full = 1;
} }
/* set the transmission time */
ndev->trans_start = jiffies;
priv->statistics.tx_packets++;
priv->statistics.tx_bytes += skb->len;
/* trigger the device */ /* trigger the device */
islpci_trigger(priv); islpci_trigger(priv);
/* unlock the driver code */ /* unlock the driver code */
spin_unlock_irqrestore(&priv->slock, flags); spin_unlock_irqrestore(&priv->slock, flags);
/* set the transmission time */
ndev->trans_start = jiffies;
priv->statistics.tx_packets++;
priv->statistics.tx_bytes += skb->len;
return 0; return 0;
drop_free: drop_free:
......
...@@ -4608,9 +4608,8 @@ wavelan_attach(void) ...@@ -4608,9 +4608,8 @@ wavelan_attach(void)
#endif #endif
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) return NULL; if (!link) return NULL;
memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */ /* The io structure describes IO port mapping */
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
......
...@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void) ...@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
int ret; int ret;
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(*link), GFP_KERNEL); link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link) if (!link)
goto out; goto out;
memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */ /* The io structure describes IO port mapping */
link->io.NumPorts1 = 16; link->io.NumPorts1 = 16;
......
/* credit winbond-840.c
*/
#include <asm/io.h>
struct eeprom_ops {
void (*set_cs)(void *ee);
void (*clear_cs)(void *ee);
};
#define EEPOL_EEDI 0x01
#define EEPOL_EEDO 0x02
#define EEPOL_EECLK 0x04
#define EEPOL_EESEL 0x08
struct eeprom {
void *dev;
struct eeprom_ops *ops;
void __iomem * addr;
unsigned ee_addr_bits;
unsigned eesel;
unsigned eeclk;
unsigned eedo;
unsigned eedi;
unsigned polarity;
unsigned ee_state;
spinlock_t *lock;
u32 *cache;
};
u8 eeprom_readb(struct eeprom *ee, unsigned address);
void eeprom_read(struct eeprom *ee, unsigned address, u8 *bytes,
unsigned count);
void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data);
void eeprom_write(struct eeprom *ee, unsigned address, u8 *bytes,
unsigned count);
/* The EEPROM commands include the alway-set leading bit. */
enum EEPROM_Cmds {
EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
};
void setup_ee_mem_bitbanger(struct eeprom *ee, void __iomem *memaddr, int eesel_bit, int eeclk_bit, int eedo_bit, int eedi_bit, unsigned polarity)
{
ee->addr = memaddr;
ee->eesel = 1 << eesel_bit;
ee->eeclk = 1 << eeclk_bit;
ee->eedo = 1 << eedo_bit;
ee->eedi = 1 << eedi_bit;
ee->polarity = polarity;
*ee->cache = readl(ee->addr);
}
/* foo. put this in a .c file */
static inline void eeprom_update(struct eeprom *ee, u32 mask, int pol)
{
unsigned long flags;
u32 data;
spin_lock_irqsave(ee->lock, flags);
data = *ee->cache;
data &= ~mask;
if (pol)
data |= mask;
*ee->cache = data;
//printk("update: %08x\n", data);
writel(data, ee->addr);
spin_unlock_irqrestore(ee->lock, flags);
}
void eeprom_clk_lo(struct eeprom *ee)
{
int pol = !!(ee->polarity & EEPOL_EECLK);
eeprom_update(ee, ee->eeclk, pol);
udelay(2);
}
void eeprom_clk_hi(struct eeprom *ee)
{
int pol = !!(ee->polarity & EEPOL_EECLK);
eeprom_update(ee, ee->eeclk, !pol);
udelay(2);
}
void eeprom_send_addr(struct eeprom *ee, unsigned address)
{
int pol = !!(ee->polarity & EEPOL_EEDI);
unsigned i;
address |= 6 << 6;
/* Shift the read command bits out. */
for (i=0; i<11; i++) {
eeprom_update(ee, ee->eedi, ((address >> 10) & 1) ^ pol);
address <<= 1;
eeprom_clk_hi(ee);
eeprom_clk_lo(ee);
}
eeprom_update(ee, ee->eedi, pol);
}
u16 eeprom_readw(struct eeprom *ee, unsigned address)
{
unsigned i;
u16 res = 0;
eeprom_clk_lo(ee);
eeprom_update(ee, ee->eesel, 1 ^ !!(ee->polarity & EEPOL_EESEL));
eeprom_send_addr(ee, address);
for (i=0; i<16; i++) {
u32 data;
eeprom_clk_hi(ee);
res <<= 1;
data = readl(ee->addr);
//printk("eeprom_readw: %08x\n", data);
res |= !!(data & ee->eedo) ^ !!(ee->polarity & EEPOL_EEDO);
eeprom_clk_lo(ee);
}
eeprom_update(ee, ee->eesel, 0 ^ !!(ee->polarity & EEPOL_EESEL));
return res;
}
void eeprom_writeb(struct eeprom *ee, unsigned address, u8 data)
{
}
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <linux/kernel.h> /* ARRAY_SIZE */ #include <linux/kernel.h> /* ARRAY_SIZE */
#include <linux/wireless.h> #include <linux/wireless.h>
#define IEEE80211_VERSION "git-1.1.6" #define IEEE80211_VERSION "git-1.1.7"
#define IEEE80211_DATA_LEN 2304 #define IEEE80211_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
......
...@@ -31,6 +31,7 @@ enum { ...@@ -31,6 +31,7 @@ enum {
struct ieee80211_crypto_ops { struct ieee80211_crypto_ops {
const char *name; const char *name;
struct list_head list;
/* init new crypto context (e.g., allocate private data space, /* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated * select IV, etc.); returns NULL on failure or pointer to allocated
......
...@@ -11,15 +11,14 @@ ...@@ -11,15 +11,14 @@
* *
*/ */
#include <linux/config.h> #include <linux/errno.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/string.h> #include <linux/string.h>
#include <asm/errno.h>
#include <net/ieee80211.h> #include <net/ieee80211.h>
MODULE_AUTHOR("Jouni Malinen"); MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto"); MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -29,32 +28,20 @@ struct ieee80211_crypto_alg { ...@@ -29,32 +28,20 @@ struct ieee80211_crypto_alg {
struct ieee80211_crypto_ops *ops; struct ieee80211_crypto_ops *ops;
}; };
struct ieee80211_crypto { static LIST_HEAD(ieee80211_crypto_algs);
struct list_head algs; static DEFINE_SPINLOCK(ieee80211_crypto_lock);
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{ {
struct list_head *ptr, *n; struct ieee80211_crypt_data *entry, *next;
struct ieee80211_crypt_data *entry;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags); spin_lock_irqsave(&ieee->lock, flags);
list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
if (list_empty(&ieee->crypt_deinit_list))
goto unlock;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
if (atomic_read(&entry->refcnt) != 0 && !force) if (atomic_read(&entry->refcnt) != 0 && !force)
continue; continue;
list_del(ptr); list_del(&entry->list);
if (entry->ops) { if (entry->ops) {
entry->ops->deinit(entry->priv); entry->ops->deinit(entry->priv);
...@@ -62,7 +49,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) ...@@ -62,7 +49,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
} }
kfree(entry); kfree(entry);
} }
unlock:
spin_unlock_irqrestore(&ieee->lock, flags); spin_unlock_irqrestore(&ieee->lock, flags);
} }
...@@ -125,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) ...@@ -125,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
unsigned long flags; unsigned long flags;
struct ieee80211_crypto_alg *alg; struct ieee80211_crypto_alg *alg;
if (hcrypt == NULL)
return -1;
alg = kmalloc(sizeof(*alg), GFP_KERNEL); alg = kmalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL) if (alg == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -135,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) ...@@ -135,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
memset(alg, 0, sizeof(*alg)); memset(alg, 0, sizeof(*alg));
alg->ops = ops; alg->ops = ops;
spin_lock_irqsave(&hcrypt->lock, flags); spin_lock_irqsave(&ieee80211_crypto_lock, flags);
list_add(&alg->list, &hcrypt->algs); list_add(&alg->list, &ieee80211_crypto_algs);
spin_unlock_irqrestore(&hcrypt->lock, flags); spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
ops->name); ops->name);
...@@ -147,64 +130,49 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) ...@@ -147,64 +130,49 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
{ {
struct ieee80211_crypto_alg *alg;
unsigned long flags; unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *del_alg = NULL;
if (hcrypt == NULL)
return -1;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *)ptr;
if (alg->ops == ops) {
list_del(&alg->list);
del_alg = alg;
break;
}
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (del_alg) { spin_lock_irqsave(&ieee80211_crypto_lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
"'%s'\n", ops->name); if (alg->ops == ops)
kfree(del_alg); goto found;
} }
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
return del_alg ? 0 : -1; return -EINVAL;
found:
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s'\n", ops->name);
list_del(&alg->list);
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
kfree(alg);
return 0;
} }
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
{ {
struct ieee80211_crypto_alg *alg;
unsigned long flags; unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *found_alg = NULL; spin_lock_irqsave(&ieee80211_crypto_lock, flags);
list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
if (hcrypt == NULL) if (strcmp(alg->ops->name, name) == 0)
return NULL; goto found;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *)ptr;
if (strcmp(alg->ops->name, name) == 0) {
found_alg = alg;
break;
}
} }
spin_unlock_irqrestore(&hcrypt->lock, flags); spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
return NULL;
if (found_alg) found:
return found_alg->ops; spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
else return alg->ops;
return NULL;
} }
static void *ieee80211_crypt_null_init(int keyidx) static void *ieee80211_crypt_null_init(int keyidx)
{ {
return (void *)1; return (void *)1;
} }
static void ieee80211_crypt_null_deinit(void *priv) static void ieee80211_crypt_null_deinit(void *priv)
{ {
} }
...@@ -213,56 +181,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = { ...@@ -213,56 +181,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.name = "NULL", .name = "NULL",
.init = ieee80211_crypt_null_init, .init = ieee80211_crypt_null_init,
.deinit = ieee80211_crypt_null_deinit, .deinit = ieee80211_crypt_null_deinit,
.encrypt_mpdu = NULL,
.decrypt_mpdu = NULL,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = NULL,
.get_key = NULL,
.extra_mpdu_prefix_len = 0,
.extra_mpdu_postfix_len = 0,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static int __init ieee80211_crypto_init(void) static int __init ieee80211_crypto_init(void)
{ {
int ret = -ENOMEM; return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
if (!hcrypt)
goto out;
memset(hcrypt, 0, sizeof(*hcrypt));
INIT_LIST_HEAD(&hcrypt->algs);
spin_lock_init(&hcrypt->lock);
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
if (ret < 0) {
kfree(hcrypt);
hcrypt = NULL;
}
out:
return ret;
} }
static void __exit ieee80211_crypto_deinit(void) static void __exit ieee80211_crypto_deinit(void)
{ {
struct list_head *ptr, *n; ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
BUG_ON(!list_empty(&ieee80211_crypto_algs));
if (hcrypt == NULL)
return;
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
ptr = n, n = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *)ptr;
list_del(ptr);
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s' (deinit)\n", alg->ops->name);
kfree(alg);
}
kfree(hcrypt);
} }
EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
......
...@@ -369,6 +369,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ...@@ -369,6 +369,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Put this code here so that we avoid duplicating it in all /* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */ * Rx paths. - Jean II */
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ #ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
#ifdef CONFIG_NET_RADIO
/* If spy monitoring on */ /* If spy monitoring on */
if (ieee->spy_data.spy_number > 0) { if (ieee->spy_data.spy_number > 0) {
struct iw_quality wstats; struct iw_quality wstats;
...@@ -395,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ...@@ -395,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Update spy records */ /* Update spy records */
wireless_spy_update(ieee->dev, hdr->addr2, &wstats); wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
} }
#endif /* CONFIG_NET_RADIO */
#endif /* IW_WIRELESS_SPY */ #endif /* IW_WIRELESS_SPY */
#ifdef NOT_YET #ifdef NOT_YET
......
...@@ -161,9 +161,11 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee, ...@@ -161,9 +161,11 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
(ieee->perfect_rssi - ieee->worst_rssi) - (ieee->perfect_rssi - ieee->worst_rssi) -
(ieee->perfect_rssi - network->stats.rssi) * (ieee->perfect_rssi - network->stats.rssi) *
(15 * (ieee->perfect_rssi - ieee->worst_rssi) + (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
62 * (ieee->perfect_rssi - network->stats.rssi))) / 62 * (ieee->perfect_rssi -
((ieee->perfect_rssi - ieee->worst_rssi) * network->stats.rssi))) /
(ieee->perfect_rssi - ieee->worst_rssi)); ((ieee->perfect_rssi -
ieee->worst_rssi) * (ieee->perfect_rssi -
ieee->worst_rssi));
if (iwe.u.qual.qual > 100) if (iwe.u.qual.qual > 100)
iwe.u.qual.qual = 100; iwe.u.qual.qual = 100;
else if (iwe.u.qual.qual < 1) else if (iwe.u.qual.qual < 1)
...@@ -520,7 +522,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, ...@@ -520,7 +522,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
crypt = &ieee->crypt[idx]; crypt = &ieee->crypt[idx];
group_key = 1; group_key = 1;
} else { } else {
if (idx != 0) /* some Cisco APs use idx>0 for unicast in dynamic WEP */
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
return -EINVAL; return -EINVAL;
if (ieee->iw_mode == IW_MODE_INFRA) if (ieee->iw_mode == IW_MODE_INFRA)
crypt = &ieee->crypt[idx]; crypt = &ieee->crypt[idx];
...@@ -688,7 +691,8 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee, ...@@ -688,7 +691,8 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
} else } else
idx = ieee->tx_keyidx; idx = ieee->tx_keyidx;
if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
ext->alg != IW_ENCODE_ALG_WEP)
if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册