提交 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 Network Connection Driver for Linux
Intel(R) PRO/Wireless 2100 Driver for Linux in support of:
Intel(R) PRO/Wireless 2100 Network Connection
Copyright (C) 2003-2005, Intel Corporation
README.ipw2100
March 14, 2005
Version: 1.1.3
Date : October 17, 2005
===========================
Index
---------------------------
0. Introduction
1. Release 1.1.0 Current Features
2. Command Line Parameters
3. Sysfs Helper Files
4. Radio Kill Switch
5. Dynamic Firmware
6. Power Management
7. Support
8. License
===========================
0. Introduction
------------ ----- ----- ---- --- -- -
-----------------------------------------------
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Introduction
2. Release 1.1.3 Current Features
3. Command Line Parameters
4. Sysfs Helper Files
5. Radio Kill Switch
6. Dynamic Firmware
7. Power Management
8. Support
9. 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
-----------------------------------------------
This document provides a brief overview of the features supported by the
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
for the driver project.
===========================
1. Release 1.1.0 Current Supported Features
---------------------------
2. Release 1.1.3 Current Supported Features
-----------------------------------------------
- Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open)
- Wireless Tools support
......@@ -51,9 +105,8 @@ on the amount of validation and interoperability testing that has been
performed on a given feature.
===========================
2. Command Line Parameters
---------------------------
3. Command Line Parameters
-----------------------------------------------
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
......@@ -75,9 +128,9 @@ associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */
===========================
3. Sysfs Helper Files
4. Sysfs Helper Files
---------------------------
-----------------------------------------------
There are several ways to control the behavior of the driver. Many of the
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:
based RF kill from ON -> OFF -> ON, the radio will NOT come back on
===========================
4. Radio Kill Switch
---------------------------
5. Radio Kill Switch
-----------------------------------------------
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
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
on your system.
===========================
5. Dynamic Firmware
---------------------------
6. Dynamic Firmware
-----------------------------------------------
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
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>.
See INSTALL for instructions on installing the firmware.
===========================
6. Power Management
---------------------------
7. Power Management
-----------------------------------------------
The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports
the following different modes:
......@@ -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.
===========================
7. Support
---------------------------
8. Support
-----------------------------------------------
For general development information and support,
go to:
......@@ -218,9 +267,8 @@ For installation support on the ipw2100 1.1.0 driver on Linux kernels
http://supportmail.intel.com
===========================
8. License
---------------------------
9. License
-----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
......
Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
Intel(R) PRO/Wireless 2200BG Network Connection
Intel(R) PRO/Wireless 2915ABG Network Connection
Intel(R) PRO/Wireless 2200BG Network Connection
Intel(R) PRO/Wireless 2915ABG Network Connection
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
both hardware adapters listed above. In this document the Intel(R)
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
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
both hardware adapters listed above. In this document the Intel(R)
PRO/Wireless 2915ABG Driver for Linux will be used to reference the
unified driver.
Copyright (C) 2004-2005, Intel Corporation
README.ipw2200
Version: 1.0.0
Date : January 31, 2005
Version: 1.0.8
Date : October 20, 2005
Index
-----------------------------------------------
0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER
1. Introduction
1.1. Overview of features
1.2. Module parameters
1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files
2. About the Version Numbers
3. Support
4. License
2. Ad-Hoc Networking
3. Interacting with Wireless Tools
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
......@@ -45,7 +101,7 @@ file.
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)
+ IBSS mode (Ad-Hoc)
......@@ -56,17 +112,27 @@ The current release (1.0.0) supports the following features:
+ Full A rate support (2915 only)
+ Transmit power control
+ S state support (ACPI suspend/resume)
The following features are currently enabled, but not officially
supported:
+ WPA
+ 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
-----------------------------------------------
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
2915ABG Driver for Linux allows certain configuration options to be
provided as module parameters. The most common way to specify a module
parameter is via the command line.
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
2915ABG Driver for Linux allows configuration options to be provided
as module parameters. The most common way to specify a module parameter
is via the command line.
The general form is:
......@@ -96,14 +162,18 @@ Where the supported parameter are:
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
how to use this (the dval and load scripts are provided as part
info is logged. See the 'dvals' and 'load' script for more info on
how to use this (the dvals and load scripts are provided as part
of the ipw2200 development snapshot releases available from the
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
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
......@@ -164,8 +234,8 @@ The supported private methods are:
-----------------------------------------------
The Linux kernel provides a pseudo file system that can be used to
access various components of the operating system. The Intel(R)
PRO/Wireless 2915ABG Driver for Linux exposes several configuration
access various components of the operating system. The Intel(R)
PRO/Wireless 2915ABG Driver for Linux exposes several configuration
parameters through this mechanism.
An entry in the sysfs can support reading and/or writing. You can
......@@ -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
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 Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries
at two levels -- driver level, which apply to all instances of the
driver (in the event that there are more than one device installed) and
device level, which applies only to the single specific instance.
at two levels -- driver level, which apply to all instances of the driver
(in the event that there are more than one device installed) and device
level, which applies only to the single specific instance.
1.4.1 Driver Level Sysfs Helper Files
......@@ -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
1.4.2 Device Level Sysfs Helper Files
-----------------------------------------------
......@@ -213,7 +284,7 @@ For the device level files, look in
For example:
/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
read -
......@@ -231,8 +302,59 @@ For the device level files, see /sys/bus/pci/[drivers/ipw2200:
ucode
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
......@@ -259,12 +381,23 @@ available as quickly as possible, unknown anomalies should be expected.
The major version number will be incremented when significant changes
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
http://supportmail.intel.com, or you can use the open source project
For direct support of the 1.0.0 version, you can contact
http://supportmail.intel.com, or you can use the open source project
support.
For general information and support, go to:
......@@ -272,7 +405,7 @@ For general information and support, go to:
http://ipw2200.sf.net/
4. License
7. License
-----------------------------------------------
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
......@@ -297,4 +430,3 @@ For general information and support, go to:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
......@@ -1330,6 +1330,24 @@ M: john.ronciak@intel.com
W: http://sourceforge.net/projects/e1000/
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
P: Ralf Baechle
M: ralf@linux-mips.org
......
......@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
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;
}
static void uml_net_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
strcpy(info->driver, DRIVER_NAME);
strcpy(info->version, "42");
}
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)
{
#ifdef undef
......@@ -359,7 +343,7 @@ static int eth_configure(int n, void *init, char *mac,
dev->tx_timeout = uml_net_tx_timeout;
dev->set_mac_address = uml_net_set_mac;
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->irq = UM_ETH_IRQ;
......
......@@ -611,38 +611,6 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
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)
{
}
......@@ -730,7 +698,6 @@ static int iss_net_configure(int index, char *init)
dev->tx_timeout = iss_net_tx_timeout;
dev->set_mac_address = iss_net_set_mac;
dev->change_mtu = iss_net_change_mtu;
dev->do_ioctl = iss_net_ioctl;
dev->watchdog_timeo = (HZ >> 1);
dev->irq = -1;
......
......@@ -447,7 +447,7 @@ config NET_SB1250_MAC
config SGI_IOC3_ETH
bool "SGI IOC3 Ethernet"
depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
depends on NET_ETHERNET && PCI && SGI_IP27
select CRC32
select MII
help
......
......@@ -28,8 +28,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.95"
#define DRV_MODULE_RELDATE "Aug 3, 2004"
#define DRV_MODULE_VERSION "0.96"
#define DRV_MODULE_RELDATE "Nov 8, 2005"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
......@@ -101,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static void b44_halt(struct b44 *);
static void b44_init_rings(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_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,
dma_addr_t dma_base,
unsigned long offset,
......@@ -501,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
*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) {
*val++ += br32(bp, reg);
}
......@@ -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
to/from anything above 1GB :-( */
if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
/* Sigh... */
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
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)
mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ,
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);
dev_kfree_skb_any(skb);
return -ENOMEM;
......@@ -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 b44 *bp = netdev_priv(dev);
unsigned long flags;
u32 istat, imask;
int handled = 0;
spin_lock_irqsave(&bp->lock, flags);
spin_lock(&bp->lock);
istat = br32(bp, B44_ISTAT);
imask = br32(bp, B44_IMASK);
......@@ -904,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
istat &= imask;
if (istat) {
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)) {
/* NOTE: These writes are posted by the readback of
* the ISTAT register below.
......@@ -916,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
dev->name);
}
irq_ack:
bw32(bp, B44_ISTAT, istat);
br32(bp, B44_ISTAT);
}
spin_unlock_irqrestore(&bp->lock, flags);
spin_unlock(&bp->lock);
return IRQ_RETVAL(handled);
}
......@@ -947,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
struct sk_buff *bounce_skb;
int rc = NETDEV_TX_OK;
dma_addr_t mapping;
u32 len, entry, ctrl;
......@@ -956,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
netif_stop_queue(dev);
spin_unlock_irq(&bp->lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return 1;
goto err_out;
}
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 */
pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
GFP_ATOMIC|GFP_DMA);
if (!bounce_skb)
return NETDEV_TX_BUSY;
goto err_out;
mapping = pci_map_single(bp->pdev, bounce_skb->data,
len, PCI_DMA_TODEVICE);
if(mapping+len > B44_DMA_MASK) {
if (mapping + len > B44_DMA_MASK) {
pci_unmap_single(bp->pdev, mapping,
len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(bounce_skb);
return NETDEV_TX_BUSY;
goto err_out;
}
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)
if (TX_BUFFS_AVAIL(bp) < 1)
netif_stop_queue(dev);
dev->trans_start = jiffies;
out_unlock:
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)
......@@ -1096,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
*
* The chip has been shut down and the driver detached from
* the networking, so no interrupts or new tx packets will
* end up in the driver. bp->lock is not held and we are not
* in an interrupt context and thus may sleep.
* end up in the driver.
*/
static void b44_init_rings(struct b44 *bp)
{
......@@ -1169,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
int size;
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)
goto out_err;
memset(bp->rx_buffers, 0, size);
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)
goto out_err;
memset(bp->tx_buffers, 0, size);
size = DMA_TABLE_BYTES;
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)
struct dma_desc *rx_ring;
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;
memset(rx_ring, 0, size);
rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL);
......@@ -1215,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
struct dma_desc *tx_ring;
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;
memset(tx_ring, 0, size);
tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
......@@ -1381,22 +1394,21 @@ static int b44_open(struct net_device *dev)
err = b44_alloc_consistent(bp);
if (err)
return err;
err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
if (err)
goto err_out_free;
spin_lock_irq(&bp->lock);
goto out;
b44_init_rings(bp);
b44_init_hw(bp);
bp->flags |= B44_FLAG_INIT_COMPLETE;
netif_carrier_off(dev);
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);
bp->timer.expires = jiffies + HZ;
......@@ -1405,11 +1417,7 @@ static int b44_open(struct net_device *dev)
add_timer(&bp->timer);
b44_enable_ints(bp);
return 0;
err_out_free:
b44_free_consistent(bp);
out:
return err;
}
......@@ -1444,6 +1452,8 @@ static int b44_close(struct net_device *dev)
netif_stop_queue(dev);
netif_poll_disable(dev);
del_timer_sync(&bp->timer);
spin_lock_irq(&bp->lock);
......@@ -1453,13 +1463,14 @@ static int b44_close(struct net_device *dev)
#endif
b44_halt(bp);
b44_free_rings(bp);
bp->flags &= ~B44_FLAG_INIT_COMPLETE;
netif_carrier_off(bp->dev);
spin_unlock_irq(&bp->lock);
free_irq(dev->irq, dev);
netif_poll_enable(dev);
b44_free_consistent(bp);
return 0;
......@@ -1524,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
u32 val;
int i=0;
unsigned char zero[6] = {0,0,0,0,0,0};
val = br32(bp, B44_RXCONFIG);
val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
......@@ -1533,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
val |= RXCONFIG_PROMISC;
bw32(bp, B44_RXCONFIG, val);
} else {
unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
int i = 0;
__b44_set_mac_addr(bp);
if (dev->flags & IFF_ALLMULTI)
val |= RXCONFIG_ALLMULTI;
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);
}
bw32(bp, B44_RXCONFIG, val);
......@@ -1604,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
if (!netif_running(dev))
return -EAGAIN;
cmd->supported = (SUPPORTED_Autoneg);
cmd->supported |= (SUPPORTED_100baseT_Half |
......@@ -1642,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
if (!netif_running(dev))
return -EAGAIN;
/* We do not support gigabit. */
......@@ -1772,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
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 = {
.get_drvinfo = b44_get_drvinfo,
.get_settings = b44_get_settings,
......@@ -1784,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
.set_pauseparam = b44_set_pauseparam,
.get_msglevel = b44_get_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,
};
......@@ -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);
if (err) {
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
goto err_out_free_res;
printk(KERN_ERR PFX "No usable DMA configuration, "
"aborting.\n");
goto err_out_free_res;
}
b44reg_base = pci_resource_start(pdev, 0);
......@@ -1916,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
bp = netdev_priv(dev);
bp->pdev = pdev;
bp->dev = dev;
if (b44_debug >= 0)
bp->msg_enable = (1 << b44_debug) - 1;
else
bp->msg_enable = B44_DEF_MSG_ENABLE;
bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
spin_lock_init(&bp->lock);
......@@ -2009,17 +2053,14 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
static void __devexit b44_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct b44 *bp = netdev_priv(dev);
if (dev) {
struct b44 *bp = netdev_priv(dev);
unregister_netdev(dev);
iounmap(bp->regs);
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
unregister_netdev(dev);
iounmap(bp->regs);
free_netdev(dev);
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)
......
......@@ -346,29 +346,63 @@ struct ring_info {
#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
* which probes HW values. Must have same relative layout as HW
* register above, because b44_stats_update depends upon this.
* which probes HW values. Check b44_stats_update if you mess with
* the layout
*/
struct b44_hw_stats {
u32 tx_good_octets, tx_good_pkts, tx_octets;
u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts;
u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255;
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;
#define _B44(x) u32 x;
B44_STAT_REG_DECLARE
#undef _B44
};
struct b44 {
......@@ -386,7 +420,6 @@ struct b44 {
u32 dma_offset;
u32 flags;
#define B44_FLAG_INIT_COMPLETE 0x00000001
#define B44_FLAG_BUGGY_TXPTR 0x00000002
#define B44_FLAG_REORDER_BUG 0x00000004
#define B44_FLAG_PAUSE_AUTO 0x00008000
......
......@@ -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)
/*
* Compute the features available to the bonding device by
* intersection of all of the slave devices' BOND_INTERSECT_FEATURES.
* Call this after attaching or detaching a slave to update the
* bond's features.
* Compute the common dev->feature set available to all slaves. Some
* feature bits are managed elsewhere, so preserve feature bits set on
* master device that are not part of the examined set.
*/
static int bond_compute_features(struct bonding *bond)
{
int i;
unsigned long features = BOND_INTERSECT_FEATURES;
struct slave *slave;
struct net_device *bond_dev = bond->dev;
int features = bond->bond_features;
int i;
bond_for_each_slave(bond, slave, i) {
struct net_device * slave_dev = slave->dev;
if (i == 0) {
features |= BOND_INTERSECT_FEATURES;
}
features &=
~(~slave_dev->features & BOND_INTERSECT_FEATURES);
}
bond_for_each_slave(bond, slave, i)
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) &&
!(features & (NETIF_F_IP_CSUM |
NETIF_F_NO_CSUM |
NETIF_F_HW_CSUM))) {
!(features & (NETIF_F_IP_CSUM |
NETIF_F_NO_CSUM |
NETIF_F_HW_CSUM)))
features &= ~NETIF_F_SG;
}
features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
bond_dev->features = features;
return 0;
......@@ -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_FILTER);
bond->bond_features = bond_dev->features;
#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
#endif
......
......@@ -40,8 +40,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "2.6.4"
#define DRV_RELDATE "September 26, 2005"
#define DRV_VERSION "2.6.5"
#define DRV_RELDATE "November 4, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
......@@ -211,9 +211,6 @@ struct bonding {
struct bond_params params;
struct list_head vlan_list;
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)
static void e100_rx(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_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
static int e100_set_config(struct net_device* dev, struct ifmap* map);
static void e100_tx_timeout(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);
static void e100_clear_network_leds(unsigned long dummy);
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_duplex(struct net_device* dev);
static void tdk_check_speed(struct net_device* dev);
......@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
dev->get_stats = e100_get_stats;
dev->set_multicast_list = set_multicast_list;
dev->set_mac_address = e100_set_mac_address;
dev->ethtool_ops = &e100_ethtool_ops;
dev->do_ioctl = e100_ioctl;
dev->set_config = e100_set_config;
dev->tx_timeout = e100_tx_timeout;
......@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
spin_lock(&np->lock); /* Preempt protection */
switch (cmd) {
case SIOCETHTOOL:
return e100_ethtool_ioctl(dev,ifr);
case SIOCGMIIPHY: /* Get PHY address */
data->phy_id = mdio_phy_addr;
break;
......@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0;
}
static int
e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
static int e100_set_settings(struct net_device *dev,
struct ethtool_cmd *ecmd)
{
struct ethtool_cmd ecmd;
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 |
ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
ecmd.port = PORT_TP;
ecmd.transceiver = XCVR_EXTERNAL;
ecmd.phy_address = mdio_phy_addr;
ecmd.speed = current_speed;
ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
ecmd.advertising = ADVERTISED_TP;
if (current_duplex == autoneg && current_speed_selection == 0)
ecmd.advertising |= ADVERTISED_Autoneg;
else {
ecmd.advertising |=
ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
if (current_speed_selection == 10)
ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full);
else if (current_speed_selection == 100)
ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full);
if (current_duplex == half)
ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full);
else if (current_duplex == full)
ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half);
}
ecmd.autoneg = AUTONEG_ENABLE;
if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
return -EFAULT;
}
break;
case ETHTOOL_SSET:
{
if (!capable(CAP_NET_ADMIN)) {
return -EPERM;
}
if (ecmd.autoneg == AUTONEG_ENABLE) {
e100_set_duplex(dev, autoneg);
e100_set_speed(dev, 0);
} else {
e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100);
}
}
break;
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;
ecmd->port = PORT_TP;
ecmd->transceiver = XCVR_EXTERNAL;
ecmd->phy_address = mdio_phy_addr;
ecmd->speed = current_speed;
ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
ecmd->advertising = ADVERTISED_TP;
if (current_duplex == autoneg && current_speed_selection == 0)
ecmd->advertising |= ADVERTISED_Autoneg;
else {
ecmd->advertising |=
ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
if (current_speed_selection == 10)
ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full);
else if (current_speed_selection == 100)
ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full);
if (current_duplex == half)
ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Full);
else if (current_duplex == full)
ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
ADVERTISED_100baseT_Half);
}
ecmd->autoneg = AUTONEG_ENABLE;
return 0;
}
static int e100_set_settings(struct net_device *dev,
struct ethtool_cmd *ecmd)
{
if (ecmd->autoneg == AUTONEG_ENABLE) {
e100_set_duplex(dev, autoneg);
e100_set_speed(dev, 0);
} else {
e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
}
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;
}
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
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-
static int __init dgrs_init_module (void)
{
int i;
int eisacount = 0, pcicount = 0;
int cardcount = 0;
/*
* Command line variable overrides
......@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
* Find and configure all the cards
*/
#ifdef CONFIG_EISA
eisacount = eisa_driver_register(&dgrs_eisa_driver);
if (eisacount < 0)
return eisacount;
#endif
#ifdef CONFIG_PCI
pcicount = pci_register_driver(&dgrs_pci_driver);
if (pcicount)
return pcicount;
cardcount = eisa_driver_register(&dgrs_eisa_driver);
if (cardcount < 0)
return cardcount;
#endif
cardcount = pci_register_driver(&dgrs_pci_driver);
if (cardcount)
return cardcount;
return 0;
}
......
......@@ -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)) {
dev_kfree_skb_any(rx->skb);
rx->skb = 0;
rx->skb = NULL;
rx->dma_addr = 0;
return -ENOMEM;
}
......@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
if((err = e100_hw_init(nic)))
goto err_clean_cbs;
e100_set_multicast_list(nic->netdev);
e100_start_receiver(nic, 0);
e100_start_receiver(nic, NULL);
mod_timer(&nic->watchdog, jiffies);
if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
nic->netdev->name, nic->netdev)))
......@@ -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,
BMCR_LOOPBACK);
e100_start_receiver(nic, 0);
e100_start_receiver(nic, NULL);
if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
err = -ENOMEM;
......
......@@ -110,7 +110,6 @@
#include <linux/init.h>
#include <linux/ip.h> /* for iph */
#include <linux/in.h> /* for IPPROTO_... */
#include <linux/eeprom.h>
#include <linux/compiler.h>
#include <linux/prefetch.h>
#include <linux/ethtool.h>
......@@ -445,7 +444,6 @@ struct ns83820 {
u32 MEAR_cache;
u32 IMR_cache;
struct eeprom ee;
unsigned linkstate;
......@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
unsigned i;
for (i=0; i<3; i++) {
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
* the chip from the EEPROM via the EELOAD self test.
*/
writel(i*2, dev->base + RFCR);
data = readl(dev->base + RFDR);
#endif
*mac++ = data;
*mac++ = data >> 8;
}
......@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
spin_lock_init(&dev->misc_lock);
dev->pci_dev = pci_dev;
dev->ee.cache = &dev->MEAR_cache;
dev->ee.lock = &dev->misc_lock;
SET_MODULE_OWNER(ndev);
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_
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,
DRV_NAME, ndev);
if (err) {
......
......@@ -1531,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
#define LINK_UP_DOWN_INTERRUPT 1
#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)
return MAC_RMAC_ERR_TIMER;
......@@ -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;
u64 val64;
......@@ -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.
*/
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 sk_buff *skb;
......@@ -2830,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
* 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;
int ret = FAILURE, cnt = 0;
......@@ -3076,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
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;
u64 val64;
......@@ -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;
u64 val64, addr, data;
......@@ -3287,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
* file on failure.
*/
int s2io_open(struct net_device *dev)
static int s2io_open(struct net_device *dev)
{
nic_t *sp = dev->priv;
int err = 0;
......@@ -3417,7 +3417,7 @@ failed\n", dev->name, i);
* file on failure.
*/
int s2io_close(struct net_device *dev)
static int s2io_close(struct net_device *dev)
{
nic_t *sp = dev->priv;
int i;
......@@ -3466,7 +3466,7 @@ int s2io_close(struct net_device *dev)
* 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;
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)
* 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;
mac_info_t *mac_control;
......@@ -5105,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
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);
}
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;
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;
......@@ -5128,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
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);
}
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);
}
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) {
case ETH_SS_TEST:
......@@ -5154,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
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)
dev->features |= NETIF_F_IP_CSUM;
......@@ -5207,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
* 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;
}
......@@ -5223,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* 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;
......
......@@ -37,12 +37,13 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
#include <linux/mii.h>
#include <asm/irq.h>
#include "skge.h"
#define DRV_NAME "skge"
#define DRV_VERSION "1.1"
#define DRV_VERSION "1.2"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
......@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static int skge_up(struct net_device *dev);
static int skge_down(struct net_device *dev);
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 void gm_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 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 yukon_get_stats(struct skge_port *skge, u64 *data);
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,
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)
{
return !((hw->chip_id == CHIP_ID_GENESIS ||
......@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
/* Determine supported/adverised modes based on hardware.
* Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
/* Determine supported/advertised modes based on hardware.
* Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
*/
static u32 skge_supported_modes(const struct skge_hw *hw)
{
......@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
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)
{
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)
{
return hwkhz(hw) * usec / 1000;
......@@ -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);
}
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;
u16 v;
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 */
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
if (xm_read16(hw, port, XM_MMU_CMD)
& XM_MMU_PHY_RDY)
if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
goto ready;
}
printk(KERN_WARNING PFX "%s: phy read timed out\n",
hw->dev[port]->name);
return 0;
return -ETIMEDOUT;
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;
}
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;
......@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
goto ready;
udelay(1);
}
printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
hw->dev[port]->name);
return -EIO;
ready:
xm_write16(hw, port, XM_PHY_DATA, val);
for (i = 0; i < PHY_RETRIES; i++) {
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);
return 0;
}
static void genesis_init(struct skge_hw *hw)
......@@ -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_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);
bcom_check_link(hw, port);
......@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write32(hw, B2_GP_IO, r);
skge_read32(hw, B2_GP_IO);
/* Enable GMII interfac */
/* Enable GMII interface */
xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
bcom_phy_init(skge, jumbo);
......@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* that jumbo frames larger than 8192 bytes will be
* truncated. Disabling all bad frame filtering causes
* 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.
*/
xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
......@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
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 !
*/
xm_write32(hw, port, XM_MODE,
......@@ -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)
{
struct skge_hw *hw = skge->hw;
......@@ -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)
{
struct skge_port *skge = netdev_priv(hw->dev[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);
}
/* 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)
{
struct skge_hw *hw = skge->hw;
......@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
& ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
gma_read16(hw, port, GM_GP_CTRL);
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
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);
}
yukon_suspend(hw, port);
/* set GPHY Control reset */
skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
......@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
/* 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)
{
u32 end;
......@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
hw->intr_mask |= portirqmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
/* Initialze MAC */
/* Initialize MAC */
spin_lock_bh(&hw->phy_lock);
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_init(hw, port);
......@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
reg = gma_read16(hw, port, GM_RX_CTRL);
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);
else if (dev->flags & IFF_ALLMULTI) /* all multicast */
memset(filter, 0xff, sizeof(filter));
......@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
unsigned int to_do = min(dev->quota, *budget);
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 sk_buff *skb;
u32 control;
......@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
if (work_done >= to_do)
return 1; /* not done */
local_irq_disable();
__netif_rx_complete(dev);
netif_rx_complete(dev);
hw->intr_mask |= portirqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
local_irq_enable();
skge_read32(hw, B0_IMSK);
return 0;
}
......@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct skge_element *e;
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;
u32 control;
......@@ -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
* cause excess interrupt latency.
*/
......@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
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)
{
struct skge_hw *hw = dev_id;
......@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
status &= hw->intr_mask;
if (status & 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) {
hw->intr_mask &= ~IS_R2_F;
netif_rx_schedule(hw->dev[1]);
skge_wakeup(hw->dev[1]);
}
if (status & IS_XA1_F)
......@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
*/
static int skge_reset(struct skge_hw *hw)
{
u32 reg;
u16 ctst;
u8 t8, mac_cfg, pmd_type, phy_type;
int i;
......@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */
skge_write8(hw, B0_POWER_CTRL,
PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
/* avoid boards with stuck Hardware error bits */
if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
(skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
......@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
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++) {
skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
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,
SET_NETDEV_DEV(dev, &hw->pdev->dev);
dev->open = skge_up;
dev->stop = skge_down;
dev->do_ioctl = skge_ioctl;
dev->hard_start_xmit = skge_xmit_frame;
dev->get_stats = skge_get_stats;
if (hw->chip_id == CHIP_ID_GENESIS)
......@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
}
#ifdef __BIG_ENDIAN
/* byte swap decriptors in hardware */
/* byte swap descriptors in hardware */
{
u32 reg;
......@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
#endif
err = -ENOMEM;
hw = kmalloc(sizeof(*hw), GFP_KERNEL);
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw) {
printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
pci_name(pdev));
goto err_out_free_regions;
}
memset(hw, 0, sizeof(*hw));
hw->pdev = pdev;
spin_lock_init(&hw->phy_lock);
tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
......@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
if (err)
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,
skge_board_name(hw), hw->chip_rev);
......
......@@ -6,6 +6,8 @@
/* PCI config registers */
#define PCI_DEV_REG1 0x40
#define PCI_PHY_COMA 0x8000000
#define PCI_VIO 0x2000000
#define PCI_DEV_REG2 0x44
#define PCI_REV_DESC 0x4
......
......@@ -4535,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
StatusRid status_rid;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
......@@ -4615,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
int i, j;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
......@@ -4881,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
struct airo_info *ai = dev->priv;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
return -ENOMEM;
}
if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
memset( data->wbuffer, 0, 2048 );
data->maxwritelen = 2048;
data->on_close = proc_config_on_close;
......@@ -5155,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
int j=0;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
memset(&wkr, 0, sizeof(wkr));
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);
return -ENOMEM;
}
memset(data->rbuffer, 0, 180);
data->writelen = 0;
data->maxwritelen = 80;
if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
kfree (data->rbuffer);
kfree (file->private_data);
return -ENOMEM;
}
memset( data->wbuffer, 0, 80 );
data->on_close = proc_wepkey_on_close;
ptr = data->rbuffer;
......@@ -5203,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
char *ptr;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
......@@ -5213,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
}
data->writelen = 0;
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 (file->private_data);
return -ENOMEM;
}
memset( data->wbuffer, 0, 33*3 );
data->on_close = proc_SSID_on_close;
readSsidRid(ai, &SSID_rid);
......@@ -5247,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
char *ptr;
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
......@@ -5257,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
}
data->writelen = 0;
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 (file->private_data);
return -ENOMEM;
}
memset( data->wbuffer, 0, data->maxwritelen );
data->on_close = proc_APList_on_close;
readAPListRid(ai, &APList_rid);
......@@ -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 */
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;
memset(file->private_data, 0, sizeof(struct proc_data));
data = (struct proc_data *)file->private_data;
if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
kfree (file->private_data);
......
......@@ -170,12 +170,11 @@ static dev_link_t *airo_attach(void)
DEBUG(0, "airo_attach()\n");
/* 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) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
return NULL;
}
memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
......@@ -194,13 +193,12 @@ static dev_link_t *airo_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* 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) {
printk(KERN_ERR "airo_cs: no memory for new device\n");
kfree (link);
return NULL;
}
memset(local, 0, sizeof(local_info_t));
link->priv = local;
/* Register with Card Services */
......
......@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
int k,i,j;
dwrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(range));
memset(range, 0, sizeof(struct iw_range));
range->min_nwid = 0x0000;
range->max_nwid = 0x0000;
range->num_channels = 0;
......
......@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
DEBUG(0, "atmel_attach()\n");
/* 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) {
printk(KERN_ERR "atmel_cs: no memory for new device\n");
return NULL;
}
memset(link, 0, sizeof(struct dev_link_t));
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
......@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
link->conf.IntType = INT_MEMORY_AND_IO;
/* 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) {
printk(KERN_ERR "atmel_cs: no memory for new device\n");
kfree (link);
return NULL;
}
memset(local, 0, sizeof(local_info_t));
link->priv = local;
/* 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
under the terms of version 2 of the GNU General Public License as
......@@ -92,7 +92,6 @@ struct ipw2100_rx_packet;
#define IPW_DL_IOCTL (1<<14)
#define IPW_DL_RF_KILL (1<<17)
#define IPW_DL_MANAGE (1<<15)
#define IPW_DL_FW (1<<16)
......@@ -155,7 +154,9 @@ extern const char *band_str[];
struct bd_status {
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;
} info;
} __attribute__ ((packed));
......@@ -164,7 +165,7 @@ struct ipw2100_bd {
u32 host_addr;
u32 buf_length;
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) */
u8 num_fragments;
u8 reserved[6];
......@@ -292,10 +293,10 @@ struct ipw2100_cmd_header {
struct ipw2100_data_header {
u32 host_command_reg;
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 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 reserved[10]; // f/w reserved
u8 src_addr[ETH_ALEN];
......@@ -305,14 +306,13 @@ struct ipw2100_data_header {
/* Host command data structure */
struct host_command {
u32 host_command; // COMMAND ID
u32 host_command1; // COMMAND ID
u32 host_command; // COMMAND ID
u32 host_command1; // COMMAND ID
u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
u32 host_command_length; // LENGTH
u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
} __attribute__ ((packed));
typedef enum {
POWER_ON_RESET,
EXIT_POWER_DOWN_RESET,
......@@ -327,17 +327,16 @@ enum {
RX
};
struct ipw2100_tx_packet {
int type;
int index;
union {
struct { /* COMMAND */
struct ipw2100_cmd_header* cmd;
struct { /* COMMAND */
struct ipw2100_cmd_header *cmd;
dma_addr_t cmd_phys;
} c_struct;
struct { /* DATA */
struct ipw2100_data_header* data;
struct { /* DATA */
struct ipw2100_data_header *data;
dma_addr_t data_phys;
struct ieee80211_txb *txb;
} d_struct;
......@@ -347,7 +346,6 @@ struct ipw2100_tx_packet {
struct list_head list;
};
struct ipw2100_rx_packet {
struct ipw2100_rx *rxp;
dma_addr_t dma_addr;
......@@ -431,13 +429,13 @@ enum {
};
#define STATUS_POWERED (1<<0)
#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
#define STATUS_INT_ENABLED (1<<11)
#define STATUS_RF_KILL_HW (1<<12)
#define STATUS_RF_KILL_SW (1<<13)
......@@ -450,9 +448,7 @@ enum {
#define STATUS_SCAN_COMPLETE (1<<26)
#define STATUS_WX_EVENT_PENDING (1<<27)
#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 */
#define IPW_STATE_INITIALIZED (1<<0)
......@@ -468,11 +464,9 @@ enum {
#define IPW_STATE_POWER_DOWN (1<<10)
#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_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#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_BSSID (1<<2) /* Restrict assoc. to single BSSID */
#define CFG_CUSTOM_MAC (1<<3)
#define CFG_LONG_PREAMBLE (1<<4)
#define CFG_ASSOCIATE (1<<6)
......@@ -480,14 +474,17 @@ enum {
#define CFG_ADHOC_CREATE (1<<8)
#define CFG_C3_DISABLED (1<<9)
#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_PRIVACY_ON (1<<1) /* Off = No privacy */
#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
struct ipw2100_priv {
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_hang_check; /* Set 1 when shutting down to kill hang_check */
int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
struct ieee80211_device *ieee;
unsigned long status;
......@@ -518,19 +515,16 @@ struct ipw2100_priv {
unsigned long hw_features;
int hangs;
u32 last_rtc;
int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
u8* snapshot[0x30];
int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
u8 *snapshot[0x30];
u8 mandatory_bssid_mac[ETH_ALEN];
u8 mac_addr[ETH_ALEN];
int power_mode;
/* WEP data */
struct ieee80211_security sec;
int messages_sent;
int short_retry_limit;
int long_retry_limit;
......@@ -598,7 +592,6 @@ struct ipw2100_priv {
wait_queue_head_t wait_command_queue;
};
/*********************************************************
* Host Command -> From Driver to FW
*********************************************************/
......@@ -645,7 +638,6 @@ struct ipw2100_priv {
#define CARD_DISABLE_PHY_OFF 61
#define MSDU_TX_RATES 62
/* Rogue AP Detection */
#define SET_STATION_STAT_BITS 64
#define CLEAR_STATIONS_STAT_BITS 65
......@@ -654,8 +646,6 @@ struct ipw2100_priv {
#define DISASSOCIATION_BSSID 68
#define SET_WPA_IE 69
/* system configuration bit mask: */
#define IPW_CFG_MONITOR 0x00004
#define IPW_CFG_PREAMBLE_AUTO 0x00010
......@@ -703,7 +693,7 @@ struct ipw2100_priv {
#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
#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_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
......@@ -783,9 +773,6 @@ struct ipw2100_priv {
#define IPW_CARD_DISABLE_PHY_OFF_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_MAX_80211_PAYLOAD_SIZE 2304U
#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
......@@ -842,8 +829,8 @@ struct ipw2100_rx {
#define IPW_TX_POWER_MIN_DBM (-12)
#define IPW_TX_POWER_MAX_DBM 16
#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
#define REG_MIN_CHANNEL 0
#define REG_MAX_CHANNEL 14
......@@ -855,7 +842,6 @@ struct ipw2100_rx {
#define DIVERSITY_ANTENNA_A 1 // Use antenna A
#define DIVERSITY_ANTENNA_B 2 // Use antenna B
#define HOST_COMMAND_WAIT 0
#define HOST_COMMAND_NO_WAIT 1
......@@ -872,10 +858,9 @@ struct ipw2100_rx {
#define TYPE_ASSOCIATION_REQUEST 0x0013
#define TYPE_REASSOCIATION_REQUEST 0x0014
#define HW_FEATURE_RFKILL (0x0001)
#define RF_KILLSWITCH_OFF (1)
#define RF_KILLSWITCH_ON (0)
#define HW_FEATURE_RFKILL 0x0001
#define RF_KILLSWITCH_OFF 1
#define RF_KILLSWITCH_ON 0
#define IPW_COMMAND_POOL_SIZE 40
......@@ -894,7 +879,7 @@ struct ipw2100_rx {
// Fixed size data: Ordinal Table 1
typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
// 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_DIR_DATA, // # of successful Directed Tx's (MSDU)
......@@ -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_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_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_NULL_DATA = 21, // # of successful NULL data Tx's
IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
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_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_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_BEACON, // # of tx beacon
IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
IPW_ORD_STAT_TX_BEACON, // # of tx beacon
IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
IPW_ORD_STAT_TX_AUTH, // # of successful Authentication 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_RETRIES, // # of Tx retries
IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
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_RETRY11, // # of Tx retries at 11MBPS
IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
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_RETRY11, // # of Tx retries at 11MBPS
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_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_STX, //NS // # of times backoff aborted
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_BPDU, //NS // # of spanning tree BPDUs sent
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_ERR_ACK, // # of tx err due to acks
// Receive statistics
......@@ -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_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_DATA2, // # of nondirected packets at 2MB
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
IPW_ORD_STAT_RX_AUTH, // # of authentication 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_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_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_CRC11, // # of Rx CRC errors at 11MB
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_CRC1, // # of Rx CRC errors at 1MB
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_CRC11, // # of Rx CRC errors at 11MB
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_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
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_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
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_DUPLICATE11, // # of duplicate rx packets at 11MB
IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
IPW_ORD_PERS_DB_LOCK = 120, // # locking 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
IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
// 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_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_TIMS, // # of PSP TIMs received
IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
// Association and roaming
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_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
// AP table entry. set to 0 if not associated
......@@ -1150,7 +1135,7 @@ struct ipw2100_fw_chunk {
};
struct ipw2100_fw_chunk_set {
const void *data;
const void *data;
unsigned long size;
};
......@@ -1163,4 +1148,4 @@ struct ipw2100_fw {
#define MAX_FW_VERSION_LEN 14
#endif /* _IPW2100_H */
#endif /* _IPW2100_H */
此差异已折叠。
此差异已折叠。
......@@ -111,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
void
isl38xx_trigger_device(int asleep, void __iomem *device_base)
{
u32 reg, counter = 0;
u32 reg;
#if VERBOSE > SHOW_ERROR_MESSAGES
u32 counter = 0;
struct timeval current_time;
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
#endif
......@@ -130,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
udelay(ISL38XX_WRITEIO_DELAY);
reg = readl(device_base + ISL38XX_INT_IDENT_REG);
if (reg == 0xabadface) {
......@@ -144,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
(reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
counter++;
#endif
}
#if VERBOSE > SHOW_ERROR_MESSAGES
......@@ -152,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
"%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING,
"%08li.%08li Device asleep counter %i\n",
......@@ -170,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
/* perform another read on the Device Status Register */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
......@@ -186,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
ISL38XX_DEV_INT_REG);
udelay(ISL38XX_WRITEIO_DELAY);
}
}
......
......@@ -226,17 +226,17 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
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 */
islpci_trigger(priv);
/* unlock the driver code */
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;
drop_free:
......
......@@ -4608,9 +4608,8 @@ wavelan_attach(void)
#endif
/* 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;
memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 8;
......
......@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
int ret;
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(*link), GFP_KERNEL);
link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link)
goto out;
memset(link, 0, sizeof(struct dev_link_t));
/* The io structure describes IO port mapping */
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 @@
#include <linux/kernel.h> /* ARRAY_SIZE */
#include <linux/wireless.h>
#define IEEE80211_VERSION "git-1.1.6"
#define IEEE80211_VERSION "git-1.1.7"
#define IEEE80211_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
......
......@@ -31,6 +31,7 @@ enum {
struct ieee80211_crypto_ops {
const char *name;
struct list_head list;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
......
......@@ -11,15 +11,14 @@
*
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/string.h>
#include <asm/errno.h>
#include <linux/string.h>
#include <net/ieee80211.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL");
......@@ -29,32 +28,20 @@ struct ieee80211_crypto_alg {
struct ieee80211_crypto_ops *ops;
};
struct ieee80211_crypto {
struct list_head algs;
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
static LIST_HEAD(ieee80211_crypto_algs);
static DEFINE_SPINLOCK(ieee80211_crypto_lock);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
struct ieee80211_crypt_data *entry, *next;
unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags);
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);
list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
list_del(ptr);
list_del(&entry->list);
if (entry->ops) {
entry->ops->deinit(entry->priv);
......@@ -62,7 +49,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
}
kfree(entry);
}
unlock:
spin_unlock_irqrestore(&ieee->lock, flags);
}
......@@ -125,9 +111,6 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
unsigned long flags;
struct ieee80211_crypto_alg *alg;
if (hcrypt == NULL)
return -1;
alg = kmalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL)
return -ENOMEM;
......@@ -135,9 +118,9 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
memset(alg, 0, sizeof(*alg));
alg->ops = ops;
spin_lock_irqsave(&hcrypt->lock, flags);
list_add(&alg->list, &hcrypt->algs);
spin_unlock_irqrestore(&hcrypt->lock, flags);
spin_lock_irqsave(&ieee80211_crypto_lock, flags);
list_add(&alg->list, &ieee80211_crypto_algs);
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
ops->name);
......@@ -147,64 +130,49 @@ int ieee80211_register_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;
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) {
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s'\n", ops->name);
kfree(del_alg);
spin_lock_irqsave(&ieee80211_crypto_lock, flags);
list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
if (alg->ops == ops)
goto found;
}
return del_alg ? 0 : -1;
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
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_alg *alg;
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *found_alg = NULL;
if (hcrypt == NULL)
return NULL;
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_lock_irqsave(&ieee80211_crypto_lock, flags);
list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
if (strcmp(alg->ops->name, name) == 0)
goto found;
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
return NULL;
if (found_alg)
return found_alg->ops;
else
return NULL;
found:
spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
return alg->ops;
}
static void *ieee80211_crypt_null_init(int keyidx)
{
return (void *)1;
}
static void ieee80211_crypt_null_deinit(void *priv)
{
}
......@@ -213,56 +181,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.name = "NULL",
.init = ieee80211_crypt_null_init,
.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,
};
static int __init ieee80211_crypto_init(void)
{
int ret = -ENOMEM;
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;
return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
}
static void __exit ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
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);
ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
BUG_ON(!list_empty(&ieee80211_crypto_algs));
}
EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
......
......@@ -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
* Rx paths. - Jean II */
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
#ifdef CONFIG_NET_RADIO
/* If spy monitoring on */
if (ieee->spy_data.spy_number > 0) {
struct iw_quality wstats;
......@@ -395,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Update spy records */
wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
}
#endif /* CONFIG_NET_RADIO */
#endif /* IW_WIRELESS_SPY */
#ifdef NOT_YET
......
......@@ -161,9 +161,11 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
(ieee->perfect_rssi - ieee->worst_rssi) -
(ieee->perfect_rssi - network->stats.rssi) *
(15 * (ieee->perfect_rssi - ieee->worst_rssi) +
62 * (ieee->perfect_rssi - network->stats.rssi))) /
((ieee->perfect_rssi - ieee->worst_rssi) *
(ieee->perfect_rssi - ieee->worst_rssi));
62 * (ieee->perfect_rssi -
network->stats.rssi))) /
((ieee->perfect_rssi -
ieee->worst_rssi) * (ieee->perfect_rssi -
ieee->worst_rssi));
if (iwe.u.qual.qual > 100)
iwe.u.qual.qual = 100;
else if (iwe.u.qual.qual < 1)
......@@ -520,7 +522,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
crypt = &ieee->crypt[idx];
group_key = 1;
} 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;
if (ieee->iw_mode == IW_MODE_INFRA)
crypt = &ieee->crypt[idx];
......@@ -688,7 +691,8 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
} else
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)
return -EINVAL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册