Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
This commit is contained in:
commit
5bcaa15579
21 changed files with 1735 additions and 233 deletions
|
@ -397,7 +397,7 @@ config SUN3LANCE
|
||||||
If you're not building a kernel for a Sun 3, say N.
|
If you're not building a kernel for a Sun 3, say N.
|
||||||
|
|
||||||
config SUN3_82586
|
config SUN3_82586
|
||||||
tristate "Sun3 on-board Intel 82586 support"
|
bool "Sun3 on-board Intel 82586 support"
|
||||||
depends on NET_ETHERNET && SUN3
|
depends on NET_ETHERNET && SUN3
|
||||||
help
|
help
|
||||||
This driver enables support for the on-board Intel 82586 based
|
This driver enables support for the on-board Intel 82586 based
|
||||||
|
@ -1924,12 +1924,15 @@ config R8169_VLAN
|
||||||
If in doubt, say Y.
|
If in doubt, say Y.
|
||||||
|
|
||||||
config SIS190
|
config SIS190
|
||||||
tristate "SiS190 gigabit ethernet support"
|
tristate "SiS190/SiS191 gigabit ethernet support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
select CRC32
|
select CRC32
|
||||||
select MII
|
select MII
|
||||||
---help---
|
---help---
|
||||||
Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter.
|
Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
|
||||||
|
a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
|
||||||
|
appear in lan on motherboard designs which are based on SiS 965
|
||||||
|
and SiS 966 south bridge.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the module
|
To compile this driver as a module, choose M here: the module
|
||||||
will be called sis190. This is recommended.
|
will be called sis190. This is recommended.
|
||||||
|
|
|
@ -88,7 +88,7 @@ struct t1_rx_mode {
|
||||||
|
|
||||||
static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
|
static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
|
||||||
{
|
{
|
||||||
u8 *addr = 0;
|
u8 *addr = NULL;
|
||||||
|
|
||||||
if (rm->idx++ < rm->dev->mc_count) {
|
if (rm->idx++ < rm->dev->mc_count) {
|
||||||
addr = rm->list->dmi_addr;
|
addr = rm->list->dmi_addr;
|
||||||
|
@ -190,7 +190,7 @@ struct sge;
|
||||||
struct peespi;
|
struct peespi;
|
||||||
|
|
||||||
struct adapter {
|
struct adapter {
|
||||||
u8 *regs;
|
u8 __iomem *regs;
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
unsigned long registered_device_map;
|
unsigned long registered_device_map;
|
||||||
unsigned long open_device_map;
|
unsigned long open_device_map;
|
||||||
|
|
|
@ -824,7 +824,7 @@ static void cxgb_proc_cleanup(struct adapter *adapter,
|
||||||
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
|
||||||
{
|
{
|
||||||
struct adapter *adapter = dev->priv;
|
struct adapter *adapter = dev->priv;
|
||||||
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
|
struct mii_ioctl_data *data = if_mii(req);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGMIIPHY:
|
case SIOCGMIIPHY:
|
||||||
|
|
|
@ -1270,7 +1270,7 @@ struct e1000_hw_stats {
|
||||||
|
|
||||||
/* Structure containing variables used by the shared code (e1000_hw.c) */
|
/* Structure containing variables used by the shared code (e1000_hw.c) */
|
||||||
struct e1000_hw {
|
struct e1000_hw {
|
||||||
uint8_t *hw_addr;
|
uint8_t __iomem *hw_addr;
|
||||||
uint8_t *flash_address;
|
uint8_t *flash_address;
|
||||||
e1000_mac_type mac_type;
|
e1000_mac_type mac_type;
|
||||||
e1000_phy_type phy_type;
|
e1000_phy_type phy_type;
|
||||||
|
|
|
@ -58,11 +58,10 @@
|
||||||
|
|
||||||
#define INT_CAUSE_UNMASK_ALL 0x0007ffff
|
#define INT_CAUSE_UNMASK_ALL 0x0007ffff
|
||||||
#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
|
#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
|
||||||
#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
|
|
||||||
#define INT_CAUSE_MASK_ALL 0x00000000
|
#define INT_CAUSE_MASK_ALL 0x00000000
|
||||||
|
#define INT_CAUSE_MASK_ALL_EXT 0x00000000
|
||||||
#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
|
#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
|
||||||
#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
|
#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
|
||||||
#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
|
#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
|
||||||
|
@ -259,14 +258,13 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev)
|
||||||
static void mv643xx_eth_set_rx_mode(struct net_device *dev)
|
static void mv643xx_eth_set_rx_mode(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct mv643xx_private *mp = netdev_priv(dev);
|
struct mv643xx_private *mp = netdev_priv(dev);
|
||||||
u32 config_reg;
|
|
||||||
|
|
||||||
config_reg = ethernet_get_config_reg(mp->port_num);
|
|
||||||
if (dev->flags & IFF_PROMISC)
|
if (dev->flags & IFF_PROMISC)
|
||||||
config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
|
mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
|
||||||
else
|
else
|
||||||
config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
|
mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
|
||||||
ethernet_set_config_reg(mp->port_num, config_reg);
|
|
||||||
|
mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -369,15 +367,6 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev,
|
||||||
|
|
||||||
dev_kfree_skb_irq(pkt_info.return_info);
|
dev_kfree_skb_irq(pkt_info.return_info);
|
||||||
released = 0;
|
released = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* Decrement the number of outstanding skbs counter on
|
|
||||||
* the TX queue.
|
|
||||||
*/
|
|
||||||
if (mp->tx_ring_skbs == 0)
|
|
||||||
panic("ERROR - TX outstanding SKBs"
|
|
||||||
" counter is corrupted");
|
|
||||||
mp->tx_ring_skbs--;
|
|
||||||
} else
|
} else
|
||||||
dma_unmap_page(NULL, pkt_info.buf_ptr,
|
dma_unmap_page(NULL, pkt_info.buf_ptr,
|
||||||
pkt_info.byte_cnt, DMA_TO_DEVICE);
|
pkt_info.byte_cnt, DMA_TO_DEVICE);
|
||||||
|
@ -412,15 +401,13 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
|
||||||
struct pkt_info pkt_info;
|
struct pkt_info pkt_info;
|
||||||
|
|
||||||
#ifdef MV643XX_NAPI
|
#ifdef MV643XX_NAPI
|
||||||
while (eth_port_receive(mp, &pkt_info) == ETH_OK && budget > 0) {
|
while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
|
||||||
#else
|
#else
|
||||||
while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
|
while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
|
||||||
#endif
|
#endif
|
||||||
mp->rx_ring_skbs--;
|
mp->rx_ring_skbs--;
|
||||||
received_packets++;
|
received_packets++;
|
||||||
#ifdef MV643XX_NAPI
|
|
||||||
budget--;
|
|
||||||
#endif
|
|
||||||
/* Update statistics. Note byte count includes 4 byte CRC count */
|
/* Update statistics. Note byte count includes 4 byte CRC count */
|
||||||
stats->rx_packets++;
|
stats->rx_packets++;
|
||||||
stats->rx_bytes += pkt_info.byte_cnt;
|
stats->rx_bytes += pkt_info.byte_cnt;
|
||||||
|
@ -1044,9 +1031,6 @@ static void mv643xx_tx(struct net_device *dev)
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
dev_kfree_skb_irq(pkt_info.return_info);
|
dev_kfree_skb_irq(pkt_info.return_info);
|
||||||
|
|
||||||
if (mp->tx_ring_skbs)
|
|
||||||
mp->tx_ring_skbs--;
|
|
||||||
} else
|
} else
|
||||||
dma_unmap_page(NULL, pkt_info.buf_ptr,
|
dma_unmap_page(NULL, pkt_info.buf_ptr,
|
||||||
pkt_info.byte_cnt, DMA_TO_DEVICE);
|
pkt_info.byte_cnt, DMA_TO_DEVICE);
|
||||||
|
@ -1189,7 +1173,6 @@ linear:
|
||||||
pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
|
pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
pkt_info.return_info = skb;
|
pkt_info.return_info = skb;
|
||||||
mp->tx_ring_skbs++;
|
|
||||||
status = eth_port_send(mp, &pkt_info);
|
status = eth_port_send(mp, &pkt_info);
|
||||||
if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
|
if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
|
||||||
printk(KERN_ERR "%s: Error on transmitting packet\n",
|
printk(KERN_ERR "%s: Error on transmitting packet\n",
|
||||||
|
@ -1274,7 +1257,6 @@ linear:
|
||||||
pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
|
pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
|
||||||
ETH_TX_LAST_DESC;
|
ETH_TX_LAST_DESC;
|
||||||
pkt_info.return_info = skb;
|
pkt_info.return_info = skb;
|
||||||
mp->tx_ring_skbs++;
|
|
||||||
} else {
|
} else {
|
||||||
pkt_info.return_info = 0;
|
pkt_info.return_info = 0;
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1293,6 @@ linear:
|
||||||
pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
|
pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
pkt_info.return_info = skb;
|
pkt_info.return_info = skb;
|
||||||
mp->tx_ring_skbs++;
|
|
||||||
status = eth_port_send(mp, &pkt_info);
|
status = eth_port_send(mp, &pkt_info);
|
||||||
if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
|
if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
|
||||||
printk(KERN_ERR "%s: Error on transmitting packet\n",
|
printk(KERN_ERR "%s: Error on transmitting packet\n",
|
||||||
|
@ -1356,6 +1337,43 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
|
||||||
return &mp->stats;
|
return &mp->stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
|
static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
|
||||||
|
{
|
||||||
|
int port_num = mp->port_num;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&mp->lock, flags);
|
||||||
|
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
|
||||||
|
INT_CAUSE_UNMASK_ALL);
|
||||||
|
mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
|
||||||
|
INT_CAUSE_UNMASK_ALL_EXT);
|
||||||
|
spin_unlock_irqrestore(&mp->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
|
||||||
|
{
|
||||||
|
int port_num = mp->port_num;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&mp->lock, flags);
|
||||||
|
mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
|
||||||
|
INT_CAUSE_MASK_ALL);
|
||||||
|
mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
|
||||||
|
INT_CAUSE_MASK_ALL_EXT);
|
||||||
|
spin_unlock_irqrestore(&mp->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mv643xx_netpoll(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct mv643xx_private *mp = netdev_priv(netdev);
|
||||||
|
|
||||||
|
mv643xx_disable_irq(mp);
|
||||||
|
mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
|
||||||
|
mv643xx_enable_irq(mp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*/
|
/*/
|
||||||
* mv643xx_eth_probe
|
* mv643xx_eth_probe
|
||||||
*
|
*
|
||||||
|
@ -1406,6 +1424,10 @@ static int mv643xx_eth_probe(struct device *ddev)
|
||||||
dev->weight = 64;
|
dev->weight = 64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
|
dev->poll_controller = mv643xx_netpoll;
|
||||||
|
#endif
|
||||||
|
|
||||||
dev->watchdog_timeo = 2 * HZ;
|
dev->watchdog_timeo = 2 * HZ;
|
||||||
dev->tx_queue_len = mp->tx_ring_size;
|
dev->tx_queue_len = mp->tx_ring_size;
|
||||||
dev->base_addr = 0;
|
dev->base_addr = 0;
|
||||||
|
@ -1883,6 +1905,9 @@ static void eth_port_start(struct mv643xx_private *mp)
|
||||||
/* Enable port Rx. */
|
/* Enable port Rx. */
|
||||||
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
|
mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
|
||||||
mp->port_rx_queue_command);
|
mp->port_rx_queue_command);
|
||||||
|
|
||||||
|
/* Disable port bandwidth limits by clearing MTU register */
|
||||||
|
mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2292,34 +2317,6 @@ static void eth_port_reset(unsigned int port_num)
|
||||||
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
|
mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ethernet_set_config_reg - Set specified bits in configuration register.
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
* This function sets specified bits in the given ethernet
|
|
||||||
* configuration register.
|
|
||||||
*
|
|
||||||
* INPUT:
|
|
||||||
* unsigned int eth_port_num Ethernet Port number.
|
|
||||||
* unsigned int value 32 bit value.
|
|
||||||
*
|
|
||||||
* OUTPUT:
|
|
||||||
* The set bits in the value parameter are set in the configuration
|
|
||||||
* register.
|
|
||||||
*
|
|
||||||
* RETURN:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void ethernet_set_config_reg(unsigned int eth_port_num,
|
|
||||||
unsigned int value)
|
|
||||||
{
|
|
||||||
unsigned int eth_config_reg;
|
|
||||||
|
|
||||||
eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num));
|
|
||||||
eth_config_reg |= value;
|
|
||||||
mv_write(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num), eth_config_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eth_port_autoneg_supported(unsigned int eth_port_num)
|
static int eth_port_autoneg_supported(unsigned int eth_port_num)
|
||||||
{
|
{
|
||||||
|
@ -2345,31 +2342,6 @@ static int eth_port_link_is_up(unsigned int eth_port_num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ethernet_get_config_reg - Get the port configuration register
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
* This function returns the configuration register value of the given
|
|
||||||
* ethernet port.
|
|
||||||
*
|
|
||||||
* INPUT:
|
|
||||||
* unsigned int eth_port_num Ethernet Port number.
|
|
||||||
*
|
|
||||||
* OUTPUT:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
* RETURN:
|
|
||||||
* Port configuration register value.
|
|
||||||
*/
|
|
||||||
static unsigned int ethernet_get_config_reg(unsigned int eth_port_num)
|
|
||||||
{
|
|
||||||
unsigned int eth_config_reg;
|
|
||||||
|
|
||||||
eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_EXTEND_REG
|
|
||||||
(eth_port_num));
|
|
||||||
return eth_config_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eth_port_read_smi_reg - Read PHY registers
|
* eth_port_read_smi_reg - Read PHY registers
|
||||||
*
|
*
|
||||||
|
@ -2528,6 +2500,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
|
||||||
return ETH_ERROR;
|
return ETH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp->tx_ring_skbs++;
|
||||||
|
BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
|
||||||
|
|
||||||
/* Get the Tx Desc ring indexes */
|
/* Get the Tx Desc ring indexes */
|
||||||
tx_desc_curr = mp->tx_curr_desc_q;
|
tx_desc_curr = mp->tx_curr_desc_q;
|
||||||
tx_desc_used = mp->tx_used_desc_q;
|
tx_desc_used = mp->tx_used_desc_q;
|
||||||
|
@ -2594,6 +2569,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
|
||||||
if (mp->tx_resource_err)
|
if (mp->tx_resource_err)
|
||||||
return ETH_QUEUE_FULL;
|
return ETH_QUEUE_FULL;
|
||||||
|
|
||||||
|
mp->tx_ring_skbs++;
|
||||||
|
BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
|
||||||
|
|
||||||
/* Get the Tx Desc ring indexes */
|
/* Get the Tx Desc ring indexes */
|
||||||
tx_desc_curr = mp->tx_curr_desc_q;
|
tx_desc_curr = mp->tx_curr_desc_q;
|
||||||
tx_desc_used = mp->tx_used_desc_q;
|
tx_desc_used = mp->tx_used_desc_q;
|
||||||
|
@ -2694,6 +2672,9 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
|
||||||
/* Any Tx return cancels the Tx resource error status */
|
/* Any Tx return cancels the Tx resource error status */
|
||||||
mp->tx_resource_err = 0;
|
mp->tx_resource_err = 0;
|
||||||
|
|
||||||
|
BUG_ON(mp->tx_ring_skbs == 0);
|
||||||
|
mp->tx_ring_skbs--;
|
||||||
|
|
||||||
return ETH_OK;
|
return ETH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -408,10 +408,6 @@ static void eth_port_init(struct mv643xx_private *mp);
|
||||||
static void eth_port_reset(unsigned int eth_port_num);
|
static void eth_port_reset(unsigned int eth_port_num);
|
||||||
static void eth_port_start(struct mv643xx_private *mp);
|
static void eth_port_start(struct mv643xx_private *mp);
|
||||||
|
|
||||||
static void ethernet_set_config_reg(unsigned int eth_port_num,
|
|
||||||
unsigned int value);
|
|
||||||
static unsigned int ethernet_get_config_reg(unsigned int eth_port_num);
|
|
||||||
|
|
||||||
/* Port MAC address routines */
|
/* Port MAC address routines */
|
||||||
static void eth_port_uc_addr_set(unsigned int eth_port_num,
|
static void eth_port_uc_addr_set(unsigned int eth_port_num,
|
||||||
unsigned char *p_addr);
|
unsigned char *p_addr);
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
Updated to EISA probing API 5/2003 by Marc Zyngier.
|
Updated to EISA probing API 5/2003 by Marc Zyngier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char *version =
|
|
||||||
"ne3210.c: Driver revision v0.03, 30/09/98\n";
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/eisa.h>
|
#include <linux/eisa.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -197,7 +194,7 @@ static int __init ne3210_eisa_probe (struct device *device)
|
||||||
ei_status.priv = phys_mem;
|
ei_status.priv = phys_mem;
|
||||||
|
|
||||||
if (ei_debug > 0)
|
if (ei_debug > 0)
|
||||||
printk(version);
|
printk("ne3210 loaded.\n");
|
||||||
|
|
||||||
ei_status.reset_8390 = &ne3210_reset_8390;
|
ei_status.reset_8390 = &ne3210_reset_8390;
|
||||||
ei_status.block_input = &ne3210_block_input;
|
ei_status.block_input = &ne3210_block_input;
|
||||||
|
@ -360,12 +357,12 @@ MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DEVICE_TABLE(eisa, ne3210_ids);
|
MODULE_DEVICE_TABLE(eisa, ne3210_ids);
|
||||||
|
|
||||||
int ne3210_init(void)
|
static int ne3210_init(void)
|
||||||
{
|
{
|
||||||
return eisa_driver_register (&ne3210_eisa_driver);
|
return eisa_driver_register (&ne3210_eisa_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ne3210_cleanup(void)
|
static void ne3210_cleanup(void)
|
||||||
{
|
{
|
||||||
eisa_driver_unregister (&ne3210_eisa_driver);
|
eisa_driver_unregister (&ne3210_eisa_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ menu "PHY device support"
|
||||||
|
|
||||||
config PHYLIB
|
config PHYLIB
|
||||||
tristate "PHY Device support and infrastructure"
|
tristate "PHY Device support and infrastructure"
|
||||||
depends on NET_ETHERNET
|
depends on NET_ETHERNET && (BROKEN || !ARCH_S390)
|
||||||
help
|
help
|
||||||
Ethernet controllers are usually attached to PHY
|
Ethernet controllers are usually attached to PHY
|
||||||
devices. This option provides infrastructure for
|
devices. This option provides infrastructure for
|
||||||
|
|
|
@ -170,7 +170,7 @@ int __init mdio_bus_init(void)
|
||||||
return bus_register(&mdio_bus_type);
|
return bus_register(&mdio_bus_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __exit mdio_bus_exit(void)
|
void mdio_bus_exit(void)
|
||||||
{
|
{
|
||||||
bus_unregister(&mdio_bus_type);
|
bus_unregister(&mdio_bus_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -686,7 +686,7 @@ static void free_shared_mem(struct s2io_nic *nic)
|
||||||
|
|
||||||
static int s2io_verify_pci_mode(nic_t *nic)
|
static int s2io_verify_pci_mode(nic_t *nic)
|
||||||
{
|
{
|
||||||
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
|
XENA_dev_config_t __iomem *bar0 = nic->bar0;
|
||||||
register u64 val64 = 0;
|
register u64 val64 = 0;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ static int s2io_verify_pci_mode(nic_t *nic)
|
||||||
*/
|
*/
|
||||||
static int s2io_print_pci_mode(nic_t *nic)
|
static int s2io_print_pci_mode(nic_t *nic)
|
||||||
{
|
{
|
||||||
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
|
XENA_dev_config_t __iomem *bar0 = nic->bar0;
|
||||||
register u64 val64 = 0;
|
register u64 val64 = 0;
|
||||||
int mode;
|
int mode;
|
||||||
struct config_param *config = &nic->config;
|
struct config_param *config = &nic->config;
|
||||||
|
@ -1403,7 +1403,7 @@ static int init_nic(struct s2io_nic *nic)
|
||||||
writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
|
writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
|
||||||
|
|
||||||
/* Disable RMAC PAD STRIPPING */
|
/* Disable RMAC PAD STRIPPING */
|
||||||
add = (void *) &bar0->mac_cfg;
|
add = &bar0->mac_cfg;
|
||||||
val64 = readq(&bar0->mac_cfg);
|
val64 = readq(&bar0->mac_cfg);
|
||||||
val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
|
val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
|
||||||
writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
|
writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
|
||||||
|
@ -1934,7 +1934,7 @@ static int start_nic(struct s2io_nic *nic)
|
||||||
val64 |= 0x0000800000000000ULL;
|
val64 |= 0x0000800000000000ULL;
|
||||||
writeq(val64, &bar0->gpio_control);
|
writeq(val64, &bar0->gpio_control);
|
||||||
val64 = 0x0411040400000000ULL;
|
val64 = 0x0411040400000000ULL;
|
||||||
writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700));
|
writeq(val64, (void __iomem *)bar0 + 0x2700);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2395,7 +2395,7 @@ static int s2io_poll(struct net_device *dev, int *budget)
|
||||||
int pkt_cnt = 0, org_pkts_to_process;
|
int pkt_cnt = 0, org_pkts_to_process;
|
||||||
mac_info_t *mac_control;
|
mac_info_t *mac_control;
|
||||||
struct config_param *config;
|
struct config_param *config;
|
||||||
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
|
XENA_dev_config_t __iomem *bar0 = nic->bar0;
|
||||||
u64 val64;
|
u64 val64;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2831,7 +2831,7 @@ void s2io_reset(nic_t * sp)
|
||||||
val64 |= 0x0000800000000000ULL;
|
val64 |= 0x0000800000000000ULL;
|
||||||
writeq(val64, &bar0->gpio_control);
|
writeq(val64, &bar0->gpio_control);
|
||||||
val64 = 0x0411040400000000ULL;
|
val64 = 0x0411040400000000ULL;
|
||||||
writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700));
|
writeq(val64, (void __iomem *)bar0 + 0x2700);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3234,7 +3234,7 @@ s2io_alarm_handle(unsigned long data)
|
||||||
|
|
||||||
static void s2io_txpic_intr_handle(nic_t *sp)
|
static void s2io_txpic_intr_handle(nic_t *sp)
|
||||||
{
|
{
|
||||||
XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
|
XENA_dev_config_t __iomem *bar0 = sp->bar0;
|
||||||
u64 val64;
|
u64 val64;
|
||||||
|
|
||||||
val64 = readq(&bar0->pic_int_status);
|
val64 = readq(&bar0->pic_int_status);
|
||||||
|
|
|
@ -179,14 +179,6 @@ enum sis190_register_content {
|
||||||
TxInterFrameGapShift = 24,
|
TxInterFrameGapShift = 24,
|
||||||
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
|
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
|
||||||
|
|
||||||
/* StationControl */
|
|
||||||
_1000bpsF = 0x1c00,
|
|
||||||
_1000bpsH = 0x0c00,
|
|
||||||
_100bpsF = 0x1800,
|
|
||||||
_100bpsH = 0x0800,
|
|
||||||
_10bpsF = 0x1400,
|
|
||||||
_10bpsH = 0x0400,
|
|
||||||
|
|
||||||
LinkStatus = 0x02, // unused
|
LinkStatus = 0x02, // unused
|
||||||
FullDup = 0x01, // unused
|
FullDup = 0x01, // unused
|
||||||
|
|
||||||
|
@ -279,6 +271,12 @@ enum sis190_eeprom_address {
|
||||||
EEPROMMACAddr = 0x03
|
EEPROMMACAddr = 0x03
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum sis190_feature {
|
||||||
|
F_HAS_RGMII = 1,
|
||||||
|
F_PHY_88E1111 = 2,
|
||||||
|
F_PHY_BCM5461 = 4
|
||||||
|
};
|
||||||
|
|
||||||
struct sis190_private {
|
struct sis190_private {
|
||||||
void __iomem *mmio_addr;
|
void __iomem *mmio_addr;
|
||||||
struct pci_dev *pci_dev;
|
struct pci_dev *pci_dev;
|
||||||
|
@ -300,6 +298,7 @@ struct sis190_private {
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
struct mii_if_info mii_if;
|
struct mii_if_info mii_if;
|
||||||
struct list_head first_phy;
|
struct list_head first_phy;
|
||||||
|
u32 features;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sis190_phy {
|
struct sis190_phy {
|
||||||
|
@ -321,24 +320,25 @@ static struct mii_chip_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
u16 id[2];
|
u16 id[2];
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
u32 feature;
|
||||||
} mii_chip_table[] = {
|
} mii_chip_table[] = {
|
||||||
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN },
|
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
|
||||||
{ "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN },
|
{ "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
|
||||||
{ "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN },
|
{ "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
|
||||||
{ "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN },
|
{ "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
|
||||||
{ NULL, }
|
{ NULL, }
|
||||||
};
|
};
|
||||||
|
|
||||||
const static struct {
|
const static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
u8 version; /* depend on docs */
|
|
||||||
u32 RxConfigMask; /* clear the bits supported by this chip */
|
|
||||||
} sis_chip_info[] = {
|
} sis_chip_info[] = {
|
||||||
{ DRV_NAME, 0x00, 0xff7e1880, },
|
{ "SiS 190 PCI Fast Ethernet adapter" },
|
||||||
|
{ "SiS 191 PCI Gigabit Ethernet adapter" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
|
static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
|
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
|
||||||
{ 0, },
|
{ 0, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ MODULE_VERSION(DRV_VERSION);
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
static const u32 sis190_intr_mask =
|
static const u32 sis190_intr_mask =
|
||||||
RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt;
|
RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
|
* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
|
||||||
|
@ -879,11 +879,6 @@ static void sis190_hw_start(struct net_device *dev)
|
||||||
|
|
||||||
SIS_W32(IntrStatus, 0xffffffff);
|
SIS_W32(IntrStatus, 0xffffffff);
|
||||||
SIS_W32(IntrMask, 0x0);
|
SIS_W32(IntrMask, 0x0);
|
||||||
/*
|
|
||||||
* Default is 100Mbps.
|
|
||||||
* A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
|
|
||||||
*/
|
|
||||||
SIS_W16(StationControl, 0x1901);
|
|
||||||
SIS_W32(GMIIControl, 0x0);
|
SIS_W32(GMIIControl, 0x0);
|
||||||
SIS_W32(TxMacControl, 0x60);
|
SIS_W32(TxMacControl, 0x60);
|
||||||
SIS_W16(RxMacControl, 0x02);
|
SIS_W16(RxMacControl, 0x02);
|
||||||
|
@ -923,35 +918,30 @@ static void sis190_phy_task(void * data)
|
||||||
BMSR_ANEGCOMPLETE)) {
|
BMSR_ANEGCOMPLETE)) {
|
||||||
net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
|
net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
|
netif_carrier_off(dev);
|
||||||
mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
|
mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
|
||||||
mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
|
mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
|
||||||
} else {
|
} else {
|
||||||
/* Rejoice ! */
|
/* Rejoice ! */
|
||||||
struct {
|
struct {
|
||||||
int val;
|
int val;
|
||||||
|
u32 ctl;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
u16 ctl;
|
|
||||||
} reg31[] = {
|
} reg31[] = {
|
||||||
{ LPA_1000XFULL | LPA_SLCT,
|
{ LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
|
||||||
"1000 Mbps Full Duplex",
|
"1000 Mbps Full Duplex" },
|
||||||
0x01 | _1000bpsF },
|
{ LPA_1000XHALF | LPA_SLCT, 0x07000c00,
|
||||||
{ LPA_1000XHALF | LPA_SLCT,
|
"1000 Mbps Half Duplex" },
|
||||||
"1000 Mbps Half Duplex",
|
{ LPA_100FULL, 0x04000800 | 0x00001000,
|
||||||
0x01 | _1000bpsH },
|
"100 Mbps Full Duplex" },
|
||||||
{ LPA_100FULL,
|
{ LPA_100HALF, 0x04000800,
|
||||||
"100 Mbps Full Duplex",
|
"100 Mbps Half Duplex" },
|
||||||
0x01 | _100bpsF },
|
{ LPA_10FULL, 0x04000400 | 0x00001000,
|
||||||
{ LPA_100HALF,
|
"10 Mbps Full Duplex" },
|
||||||
"100 Mbps Half Duplex",
|
{ LPA_10HALF, 0x04000400,
|
||||||
0x01 | _100bpsH },
|
"10 Mbps Half Duplex" },
|
||||||
{ LPA_10FULL,
|
{ 0, 0x04000400, "unknown" }
|
||||||
"10 Mbps Full Duplex",
|
}, *p;
|
||||||
0x01 | _10bpsF },
|
|
||||||
{ LPA_10HALF,
|
|
||||||
"10 Mbps Half Duplex",
|
|
||||||
0x01 | _10bpsH },
|
|
||||||
{ 0, "unknown", 0x0000 }
|
|
||||||
}, *p;
|
|
||||||
u16 adv;
|
u16 adv;
|
||||||
|
|
||||||
val = mdio_read(ioaddr, phy_id, 0x1f);
|
val = mdio_read(ioaddr, phy_id, 0x1f);
|
||||||
|
@ -964,12 +954,29 @@ static void sis190_phy_task(void * data)
|
||||||
|
|
||||||
val &= adv;
|
val &= adv;
|
||||||
|
|
||||||
for (p = reg31; p->ctl; p++) {
|
for (p = reg31; p->val; p++) {
|
||||||
if ((val & p->val) == p->val)
|
if ((val & p->val) == p->val)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (p->ctl)
|
|
||||||
SIS_W16(StationControl, p->ctl);
|
p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
|
||||||
|
|
||||||
|
if ((tp->features & F_HAS_RGMII) &&
|
||||||
|
(tp->features & F_PHY_BCM5461)) {
|
||||||
|
// Set Tx Delay in RGMII mode.
|
||||||
|
mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
|
||||||
|
udelay(200);
|
||||||
|
mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
|
||||||
|
p->ctl |= 0x03000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIS_W32(StationControl, p->ctl);
|
||||||
|
|
||||||
|
if (tp->features & F_HAS_RGMII) {
|
||||||
|
SIS_W32(RGDelay, 0x0441);
|
||||||
|
SIS_W32(RGDelay, 0x0440);
|
||||||
|
}
|
||||||
|
|
||||||
net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
|
net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
|
||||||
p->msg);
|
p->msg);
|
||||||
netif_carrier_on(dev);
|
netif_carrier_on(dev);
|
||||||
|
@ -1308,6 +1315,7 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
|
||||||
phy->type = (p->type == MIX) ?
|
phy->type = (p->type == MIX) ?
|
||||||
((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
|
((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
|
||||||
LAN : HOME) : p->type;
|
LAN : HOME) : p->type;
|
||||||
|
tp->features |= p->feature;
|
||||||
} else
|
} else
|
||||||
phy->type = UNKNOWN;
|
phy->type = UNKNOWN;
|
||||||
|
|
||||||
|
@ -1316,6 +1324,25 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
|
||||||
(phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
|
(phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
|
||||||
|
{
|
||||||
|
if (tp->features & F_PHY_88E1111) {
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
int phy_id = tp->mii_if.phy_id;
|
||||||
|
u16 reg[2][2] = {
|
||||||
|
{ 0x808b, 0x0ce1 },
|
||||||
|
{ 0x808f, 0x0c60 }
|
||||||
|
}, *p;
|
||||||
|
|
||||||
|
p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
|
||||||
|
|
||||||
|
mdio_write(ioaddr, phy_id, 0x1b, p[0]);
|
||||||
|
udelay(200);
|
||||||
|
mdio_write(ioaddr, phy_id, 0x14, p[1]);
|
||||||
|
udelay(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sis190_mii_probe - Probe MII PHY for sis190
|
* sis190_mii_probe - Probe MII PHY for sis190
|
||||||
* @dev: the net device to probe for
|
* @dev: the net device to probe for
|
||||||
|
@ -1366,6 +1393,8 @@ static int __devinit sis190_mii_probe(struct net_device *dev)
|
||||||
/* Select default PHY for mac */
|
/* Select default PHY for mac */
|
||||||
sis190_default_phy(dev);
|
sis190_default_phy(dev);
|
||||||
|
|
||||||
|
sis190_mii_probe_88e1111_fixup(tp);
|
||||||
|
|
||||||
mii_if->dev = dev;
|
mii_if->dev = dev;
|
||||||
mii_if->mdio_read = __mdio_read;
|
mii_if->mdio_read = __mdio_read;
|
||||||
mii_if->mdio_write = __mdio_write;
|
mii_if->mdio_write = __mdio_write;
|
||||||
|
@ -1505,6 +1534,11 @@ static void sis190_tx_timeout(struct net_device *dev)
|
||||||
netif_wake_queue(dev);
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
|
||||||
|
{
|
||||||
|
tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
|
static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
|
||||||
struct net_device *dev)
|
struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -1532,6 +1566,8 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
|
||||||
((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
|
((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1577,6 +1613,8 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
|
||||||
outb(0x12, 0x78);
|
outb(0x12, 0x78);
|
||||||
reg = inb(0x79);
|
reg = inb(0x79);
|
||||||
|
|
||||||
|
sis190_set_rgmii(tp, reg);
|
||||||
|
|
||||||
/* Restore the value to ISA Bridge */
|
/* Restore the value to ISA Bridge */
|
||||||
pci_write_config_byte(isa_bridge, 0x48, tmp8);
|
pci_write_config_byte(isa_bridge, 0x48, tmp8);
|
||||||
pci_dev_put(isa_bridge);
|
pci_dev_put(isa_bridge);
|
||||||
|
@ -1799,6 +1837,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
|
||||||
dev->dev_addr[2], dev->dev_addr[3],
|
dev->dev_addr[2], dev->dev_addr[3],
|
||||||
dev->dev_addr[4], dev->dev_addr[5]);
|
dev->dev_addr[4], dev->dev_addr[5]);
|
||||||
|
|
||||||
|
net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
|
||||||
|
(tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
|
||||||
|
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
|
|
||||||
sis190_set_speed_auto(dev);
|
sis190_set_speed_auto(dev);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/ptrace.h>
|
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
@ -34,6 +33,7 @@
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
|
|
|
@ -289,8 +289,8 @@ config APPLE_AIRPORT
|
||||||
a non-standard interface
|
a non-standard interface
|
||||||
|
|
||||||
config PLX_HERMES
|
config PLX_HERMES
|
||||||
tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)"
|
tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
|
||||||
depends on PCI && HERMES && EXPERIMENTAL
|
depends on PCI && HERMES
|
||||||
help
|
help
|
||||||
Enable support for PCMCIA cards supported by the "Hermes" (aka
|
Enable support for PCMCIA cards supported by the "Hermes" (aka
|
||||||
orinoco) driver when used in PLX9052 based PCI adaptors. These
|
orinoco) driver when used in PLX9052 based PCI adaptors. These
|
||||||
|
@ -299,12 +299,9 @@ config PLX_HERMES
|
||||||
802.11b PCMCIA cards can be used in desktop machines. The Netgear
|
802.11b PCMCIA cards can be used in desktop machines. The Netgear
|
||||||
MA301 is such an adaptor.
|
MA301 is such an adaptor.
|
||||||
|
|
||||||
Support for these adaptors is so far still incomplete and buggy.
|
|
||||||
You have been warned.
|
|
||||||
|
|
||||||
config TMD_HERMES
|
config TMD_HERMES
|
||||||
tristate "Hermes in TMD7160 based PCI adaptor support (EXPERIMENTAL)"
|
tristate "Hermes in TMD7160 based PCI adaptor support"
|
||||||
depends on PCI && HERMES && EXPERIMENTAL
|
depends on PCI && HERMES
|
||||||
help
|
help
|
||||||
Enable support for PCMCIA cards supported by the "Hermes" (aka
|
Enable support for PCMCIA cards supported by the "Hermes" (aka
|
||||||
orinoco) driver when used in TMD7160 based PCI adaptors. These
|
orinoco) driver when used in TMD7160 based PCI adaptors. These
|
||||||
|
@ -312,12 +309,18 @@ config TMD_HERMES
|
||||||
PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
|
PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
|
||||||
802.11b PCMCIA cards can be used in desktop machines.
|
802.11b PCMCIA cards can be used in desktop machines.
|
||||||
|
|
||||||
Support for these adaptors is so far still incomplete and buggy.
|
config NORTEL_HERMES
|
||||||
You have been warned.
|
tristate "Nortel emobility PCI adaptor support"
|
||||||
|
depends on PCI && HERMES
|
||||||
|
help
|
||||||
|
Enable support for PCMCIA cards supported by the "Hermes" (aka
|
||||||
|
orinoco) driver when used in Nortel emobility PCI adaptors. These
|
||||||
|
adaptors are not full PCMCIA controllers, but act as a more limited
|
||||||
|
PCI <-> PCMCIA bridge.
|
||||||
|
|
||||||
config PCI_HERMES
|
config PCI_HERMES
|
||||||
tristate "Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)"
|
tristate "Prism 2.5 PCI 802.11b adaptor support"
|
||||||
depends on PCI && HERMES && EXPERIMENTAL
|
depends on PCI && HERMES
|
||||||
help
|
help
|
||||||
Enable support for PCI and mini-PCI 802.11b wireless NICs based on
|
Enable support for PCI and mini-PCI 802.11b wireless NICs based on
|
||||||
the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
|
the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
|
||||||
|
@ -372,6 +375,19 @@ config PCMCIA_HERMES
|
||||||
configure your card and that /etc/pcmcia/wireless.opts works:
|
configure your card and that /etc/pcmcia/wireless.opts works:
|
||||||
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
||||||
|
|
||||||
|
config PCMCIA_SPECTRUM
|
||||||
|
tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
|
||||||
|
depends on NET_RADIO && PCMCIA && HERMES
|
||||||
|
---help---
|
||||||
|
|
||||||
|
This is a driver for 802.11b cards using RAM-loadable Symbol
|
||||||
|
firmware, such as Symbol Wireless Networker LA4100, CompactFlash
|
||||||
|
cards by Socket Communications and Intel PRO/Wireless 2011B.
|
||||||
|
|
||||||
|
This driver requires firmware download on startup. Utilities
|
||||||
|
for downloading Symbol firmware are available at
|
||||||
|
<http://sourceforge.net/projects/orinoco/>
|
||||||
|
|
||||||
config AIRO_CS
|
config AIRO_CS
|
||||||
tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
|
tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
|
||||||
depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
|
depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
|
||||||
|
|
|
@ -22,6 +22,8 @@ obj-$(CONFIG_APPLE_AIRPORT) += airport.o
|
||||||
obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
|
obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
|
||||||
obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
|
obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
|
||||||
obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
|
obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
|
||||||
|
obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o
|
||||||
|
obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o
|
||||||
|
|
||||||
obj-$(CONFIG_AIRO) += airo.o
|
obj-$(CONFIG_AIRO) += airo.o
|
||||||
obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
|
obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
|
||||||
|
|
|
@ -327,38 +327,38 @@ static struct iw_handler_def ipw2100_wx_handler_def;
|
||||||
|
|
||||||
static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
|
static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
|
||||||
{
|
{
|
||||||
*val = readl((void *)(dev->base_addr + reg));
|
*val = readl((void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
|
IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void write_register(struct net_device *dev, u32 reg, u32 val)
|
static inline void write_register(struct net_device *dev, u32 reg, u32 val)
|
||||||
{
|
{
|
||||||
writel(val, (void *)(dev->base_addr + reg));
|
writel(val, (void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
|
IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
|
static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
|
||||||
{
|
{
|
||||||
*val = readw((void *)(dev->base_addr + reg));
|
*val = readw((void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
|
IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
|
static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
|
||||||
{
|
{
|
||||||
*val = readb((void *)(dev->base_addr + reg));
|
*val = readb((void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
|
IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
|
static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
|
||||||
{
|
{
|
||||||
writew(val, (void *)(dev->base_addr + reg));
|
writew(val, (void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
|
IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
|
static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
|
||||||
{
|
{
|
||||||
writeb(val, (void *)(dev->base_addr + reg));
|
writeb(val, (void __iomem *)(dev->base_addr + reg));
|
||||||
IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
|
IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
|
||||||
static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
|
static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
|
||||||
{
|
{
|
||||||
return (dev->base_addr &&
|
return (dev->base_addr &&
|
||||||
(readl((void *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
|
(readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
|
||||||
== IPW_DATA_DOA_DEBUG_VALUE));
|
== IPW_DATA_DOA_DEBUG_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2125,19 +2125,19 @@ static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ipw2100_status_indicator status_handlers[] = {
|
static const struct ipw2100_status_indicator status_handlers[] = {
|
||||||
IPW2100_HANDLER(IPW_STATE_INITIALIZED, 0),
|
IPW2100_HANDLER(IPW_STATE_INITIALIZED, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, 0),
|
IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
|
IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
|
||||||
IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
|
IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
|
||||||
IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, 0),
|
IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
|
IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
|
||||||
IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, 0),
|
IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_LEFT_PSP, 0),
|
IPW2100_HANDLER(IPW_STATE_LEFT_PSP, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
|
IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
|
||||||
IPW2100_HANDLER(IPW_STATE_DISABLED, 0),
|
IPW2100_HANDLER(IPW_STATE_DISABLED, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_POWER_DOWN, 0),
|
IPW2100_HANDLER(IPW_STATE_POWER_DOWN, NULL),
|
||||||
IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
|
IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
|
||||||
IPW2100_HANDLER(-1, 0)
|
IPW2100_HANDLER(-1, NULL)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6327,7 +6327,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
|
||||||
|
|
||||||
static struct net_device *ipw2100_alloc_device(
|
static struct net_device *ipw2100_alloc_device(
|
||||||
struct pci_dev *pci_dev,
|
struct pci_dev *pci_dev,
|
||||||
char *base_addr,
|
void __iomem *base_addr,
|
||||||
unsigned long mem_start,
|
unsigned long mem_start,
|
||||||
unsigned long mem_len)
|
unsigned long mem_len)
|
||||||
{
|
{
|
||||||
|
@ -6474,7 +6474,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
||||||
const struct pci_device_id *ent)
|
const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
unsigned long mem_start, mem_len, mem_flags;
|
unsigned long mem_start, mem_len, mem_flags;
|
||||||
char *base_addr = NULL;
|
void __iomem *base_addr = NULL;
|
||||||
struct net_device *dev = NULL;
|
struct net_device *dev = NULL;
|
||||||
struct ipw2100_priv *priv = NULL;
|
struct ipw2100_priv *priv = NULL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -6664,7 +6664,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_addr)
|
if (base_addr)
|
||||||
iounmap((char*)base_addr);
|
iounmap(base_addr);
|
||||||
|
|
||||||
pci_release_regions(pci_dev);
|
pci_release_regions(pci_dev);
|
||||||
pci_disable_device(pci_dev);
|
pci_disable_device(pci_dev);
|
||||||
|
@ -6714,7 +6714,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
|
||||||
free_irq(dev->irq, priv);
|
free_irq(dev->irq, priv);
|
||||||
|
|
||||||
if (dev->base_addr)
|
if (dev->base_addr)
|
||||||
iounmap((unsigned char *)dev->base_addr);
|
iounmap((void __iomem *)dev->base_addr);
|
||||||
|
|
||||||
free_ieee80211(dev);
|
free_ieee80211(dev);
|
||||||
}
|
}
|
||||||
|
@ -8574,6 +8574,7 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
|
||||||
struct net_device *dev = priv->net_dev;
|
struct net_device *dev = priv->net_dev;
|
||||||
const unsigned char *microcode_data = fw->uc.data;
|
const unsigned char *microcode_data = fw->uc.data;
|
||||||
unsigned int microcode_data_left = fw->uc.size;
|
unsigned int microcode_data_left = fw->uc.size;
|
||||||
|
void __iomem *reg = (void __iomem *)dev->base_addr;
|
||||||
|
|
||||||
struct symbol_alive_response response;
|
struct symbol_alive_response response;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -8581,23 +8582,23 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
|
||||||
|
|
||||||
/* Symbol control */
|
/* Symbol control */
|
||||||
write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
|
write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
|
write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* HW config */
|
/* HW config */
|
||||||
write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
|
write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
|
write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* EN_CS_ACCESS bit to reset control store pointer */
|
/* EN_CS_ACCESS bit to reset control store pointer */
|
||||||
write_nic_byte(dev, 0x210000, 0x40);
|
write_nic_byte(dev, 0x210000, 0x40);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210000, 0x0);
|
write_nic_byte(dev, 0x210000, 0x0);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210000, 0x40);
|
write_nic_byte(dev, 0x210000, 0x40);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* copy microcode from buffer into Symbol */
|
/* copy microcode from buffer into Symbol */
|
||||||
|
|
||||||
|
@ -8609,31 +8610,31 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
|
||||||
|
|
||||||
/* EN_CS_ACCESS bit to reset the control store pointer */
|
/* EN_CS_ACCESS bit to reset the control store pointer */
|
||||||
write_nic_byte(dev, 0x210000, 0x0);
|
write_nic_byte(dev, 0x210000, 0x0);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* Enable System (Reg 0)
|
/* Enable System (Reg 0)
|
||||||
* first enable causes garbage in RX FIFO */
|
* first enable causes garbage in RX FIFO */
|
||||||
write_nic_byte(dev, 0x210000, 0x0);
|
write_nic_byte(dev, 0x210000, 0x0);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210000, 0x80);
|
write_nic_byte(dev, 0x210000, 0x80);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* Reset External Baseband Reg */
|
/* Reset External Baseband Reg */
|
||||||
write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
|
write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
|
write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* HW Config (Reg 5) */
|
/* HW Config (Reg 5) */
|
||||||
write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
|
write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
|
write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
|
|
||||||
/* Enable System (Reg 0)
|
/* Enable System (Reg 0)
|
||||||
* second enable should be OK */
|
* second enable should be OK */
|
||||||
write_nic_byte(dev, 0x210000, 0x00); // clear enable system
|
write_nic_byte(dev, 0x210000, 0x00); // clear enable system
|
||||||
readl((void *)(dev->base_addr));
|
readl(reg);
|
||||||
write_nic_byte(dev, 0x210000, 0x80); // set enable system
|
write_nic_byte(dev, 0x210000, 0x80); // set enable system
|
||||||
|
|
||||||
/* check Symbol is enabled - upped this from 5 as it wasn't always
|
/* check Symbol is enabled - upped this from 5 as it wasn't always
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
|
|
|
@ -1053,8 +1053,9 @@ static void orinoco_join_ap(struct net_device *dev)
|
||||||
u16 channel;
|
u16 channel;
|
||||||
} __attribute__ ((packed)) req;
|
} __attribute__ ((packed)) req;
|
||||||
const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
|
const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
|
||||||
struct prism2_scan_apinfo *atom;
|
struct prism2_scan_apinfo *atom = NULL;
|
||||||
int offset = 4;
|
int offset = 4;
|
||||||
|
int found = 0;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
u16 len;
|
u16 len;
|
||||||
|
|
||||||
|
@ -1089,15 +1090,18 @@ static void orinoco_join_ap(struct net_device *dev)
|
||||||
* we were requested to join */
|
* we were requested to join */
|
||||||
for (; offset + atom_len <= len; offset += atom_len) {
|
for (; offset + atom_len <= len; offset += atom_len) {
|
||||||
atom = (struct prism2_scan_apinfo *) (buf + offset);
|
atom = (struct prism2_scan_apinfo *) (buf + offset);
|
||||||
if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0)
|
if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
|
||||||
goto found;
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(1, "%s: Requested AP not found in scan results\n",
|
if (! found) {
|
||||||
dev->name);
|
DEBUG(1, "%s: Requested AP not found in scan results\n",
|
||||||
goto out;
|
dev->name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
found:
|
|
||||||
memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
|
memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
|
||||||
req.channel = atom->channel; /* both are little-endian */
|
req.channel = atom->channel; /* both are little-endian */
|
||||||
err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
|
err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
|
||||||
|
@ -1284,8 +1288,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
|
||||||
/* Read scan data */
|
/* Read scan data */
|
||||||
err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
|
err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
|
||||||
infofid, sizeof(info));
|
infofid, sizeof(info));
|
||||||
if (err)
|
if (err) {
|
||||||
|
kfree(buf);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ORINOCO_DEBUG
|
#ifdef ORINOCO_DEBUG
|
||||||
{
|
{
|
||||||
|
@ -4021,7 +4027,8 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate scan data returned from the card to a card independant
|
/* Translate scan data returned from the card to a card independant
|
||||||
* format that the Wireless Tools will understand - Jean II */
|
* format that the Wireless Tools will understand - Jean II
|
||||||
|
* Return message length or -errno for fatal errors */
|
||||||
static inline int orinoco_translate_scan(struct net_device *dev,
|
static inline int orinoco_translate_scan(struct net_device *dev,
|
||||||
char *buffer,
|
char *buffer,
|
||||||
char *scan,
|
char *scan,
|
||||||
|
@ -4061,13 +4068,19 @@ static inline int orinoco_translate_scan(struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
case FIRMWARE_TYPE_INTERSIL:
|
case FIRMWARE_TYPE_INTERSIL:
|
||||||
offset = 4;
|
offset = 4;
|
||||||
if (priv->has_hostscan)
|
if (priv->has_hostscan) {
|
||||||
atom_len = scan[0] + (scan[1] << 8);
|
atom_len = le16_to_cpup((u16 *)scan);
|
||||||
else
|
/* Sanity check for atom_len */
|
||||||
|
if (atom_len < sizeof(struct prism2_scan_apinfo)) {
|
||||||
|
printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
|
||||||
|
dev->name, atom_len);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
} else
|
||||||
atom_len = offsetof(struct prism2_scan_apinfo, atim);
|
atom_len = offsetof(struct prism2_scan_apinfo, atim);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that we got an whole number of atoms */
|
/* Check that we got an whole number of atoms */
|
||||||
|
@ -4075,7 +4088,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
|
||||||
printk(KERN_ERR "%s: Unexpected scan data length %d, "
|
printk(KERN_ERR "%s: Unexpected scan data length %d, "
|
||||||
"atom_len %d, offset %d\n", dev->name, scan_len,
|
"atom_len %d, offset %d\n", dev->name, scan_len,
|
||||||
atom_len, offset);
|
atom_len, offset);
|
||||||
return 0;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the entries one by one */
|
/* Read the entries one by one */
|
||||||
|
@ -4210,33 +4223,41 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
|
||||||
/* We have some results to push back to user space */
|
/* We have some results to push back to user space */
|
||||||
|
|
||||||
/* Translate to WE format */
|
/* Translate to WE format */
|
||||||
srq->length = orinoco_translate_scan(dev, extra,
|
int ret = orinoco_translate_scan(dev, extra,
|
||||||
priv->scan_result,
|
priv->scan_result,
|
||||||
priv->scan_len);
|
priv->scan_len);
|
||||||
|
|
||||||
/* Return flags */
|
if (ret < 0) {
|
||||||
srq->flags = (__u16) priv->scan_mode;
|
err = ret;
|
||||||
|
kfree(priv->scan_result);
|
||||||
|
priv->scan_result = NULL;
|
||||||
|
} else {
|
||||||
|
srq->length = ret;
|
||||||
|
|
||||||
/* Results are here, so scan no longer in progress */
|
/* Return flags */
|
||||||
priv->scan_inprogress = 0;
|
srq->flags = (__u16) priv->scan_mode;
|
||||||
|
|
||||||
/* In any case, Scan results will be cleaned up in the
|
/* In any case, Scan results will be cleaned up in the
|
||||||
* reset function and when exiting the driver.
|
* reset function and when exiting the driver.
|
||||||
* The person triggering the scanning may never come to
|
* The person triggering the scanning may never come to
|
||||||
* pick the results, so we need to do it in those places.
|
* pick the results, so we need to do it in those places.
|
||||||
* Jean II */
|
* Jean II */
|
||||||
|
|
||||||
#ifdef SCAN_SINGLE_READ
|
#ifdef SCAN_SINGLE_READ
|
||||||
/* If you enable this option, only one client (the first
|
/* If you enable this option, only one client (the first
|
||||||
* one) will be able to read the result (and only one
|
* one) will be able to read the result (and only one
|
||||||
* time). If there is multiple concurent clients that
|
* time). If there is multiple concurent clients that
|
||||||
* want to read scan results, this behavior is not
|
* want to read scan results, this behavior is not
|
||||||
* advisable - Jean II */
|
* advisable - Jean II */
|
||||||
kfree(priv->scan_result);
|
kfree(priv->scan_result);
|
||||||
priv->scan_result = NULL;
|
priv->scan_result = NULL;
|
||||||
#endif /* SCAN_SINGLE_READ */
|
#endif /* SCAN_SINGLE_READ */
|
||||||
/* Here, if too much time has elapsed since last scan,
|
/* Here, if too much time has elapsed since last scan,
|
||||||
* we may want to clean up scan results... - Jean II */
|
* we may want to clean up scan results... - Jean II */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan is no longer in progress */
|
||||||
|
priv->scan_inprogress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
orinoco_unlock(priv, &flags);
|
orinoco_unlock(priv, &flags);
|
||||||
|
|
|
@ -604,7 +604,6 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
|
||||||
|
|
||||||
static struct pcmcia_device_id orinoco_cs_ids[] = {
|
static struct pcmcia_device_id orinoco_cs_ids[] = {
|
||||||
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
|
PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
|
||||||
PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001),
|
|
||||||
PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
|
PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
|
||||||
PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
|
PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
|
||||||
PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
|
PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
|
||||||
|
|
324
drivers/net/wireless/orinoco_nortel.c
Normal file
324
drivers/net/wireless/orinoco_nortel.c
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/* orinoco_nortel.c
|
||||||
|
*
|
||||||
|
* Driver for Prism II devices which would usually be driven by orinoco_cs,
|
||||||
|
* but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 Tobias Hoffmann
|
||||||
|
* (C) 2003 Christoph Jungegger <disdos@traum404.de>
|
||||||
|
*
|
||||||
|
* Some of this code is borrowed from orinoco_plx.c
|
||||||
|
* Copyright (C) 2001 Daniel Barlow
|
||||||
|
* Some of this code is borrowed from orinoco_pci.c
|
||||||
|
* Copyright (C) 2001 Jean Tourrilhes
|
||||||
|
* Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
|
||||||
|
* has been copied from it. linux-wlan-ng-0.1.10 is originally :
|
||||||
|
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License
|
||||||
|
* at http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS"
|
||||||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||||
|
* the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the
|
||||||
|
* terms of the GNU General Public License version 2 (the "GPL"), in
|
||||||
|
* which case the provisions of the GPL are applicable instead of the
|
||||||
|
* above. If you wish to allow the use of your version of this file
|
||||||
|
* only under the terms of the GPL and not to allow others to use your
|
||||||
|
* version of this file under the MPL, indicate your decision by
|
||||||
|
* deleting the provisions above and replace them with the notice and
|
||||||
|
* other provisions required by the GPL. If you do not delete the
|
||||||
|
* provisions above, a recipient may use your version of this file
|
||||||
|
* under either the MPL or the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DRIVER_NAME "orinoco_nortel"
|
||||||
|
#define PFX DRIVER_NAME ": "
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/timer.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/fcntl.h>
|
||||||
|
|
||||||
|
#include <pcmcia/cisreg.h>
|
||||||
|
|
||||||
|
#include "hermes.h"
|
||||||
|
#include "orinoco.h"
|
||||||
|
|
||||||
|
#define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */
|
||||||
|
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
|
||||||
|
|
||||||
|
|
||||||
|
/* Nortel specific data */
|
||||||
|
struct nortel_pci_card {
|
||||||
|
unsigned long iobase1;
|
||||||
|
unsigned long iobase2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a soft reset of the PCI card using the Configuration Option Register
|
||||||
|
* We need this to get going...
|
||||||
|
* This is the part of the code that is strongly inspired from wlan-ng
|
||||||
|
*
|
||||||
|
* Note bis : Don't try to access HERMES_CMD during the reset phase.
|
||||||
|
* It just won't work !
|
||||||
|
*/
|
||||||
|
static int nortel_pci_cor_reset(struct orinoco_private *priv)
|
||||||
|
{
|
||||||
|
struct nortel_pci_card *card = priv->card;
|
||||||
|
|
||||||
|
/* Assert the reset until the card notice */
|
||||||
|
outw_p(8, card->iobase1 + 2);
|
||||||
|
inw(card->iobase2 + COR_OFFSET);
|
||||||
|
outw_p(0x80, card->iobase2 + COR_OFFSET);
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
/* Give time for the card to recover from this hard effort */
|
||||||
|
outw_p(0, card->iobase2 + COR_OFFSET);
|
||||||
|
outw_p(0, card->iobase2 + COR_OFFSET);
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
/* set COR as usual */
|
||||||
|
outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
|
||||||
|
outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
outw_p(0x228, card->iobase1 + 2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nortel_pci_hw_init(struct nortel_pci_card *card)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
/* setup bridge */
|
||||||
|
if (inw(card->iobase1) & 1) {
|
||||||
|
printk(KERN_ERR PFX "brg1 answer1 wrong\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
outw_p(0x118, card->iobase1 + 2);
|
||||||
|
outw_p(0x108, card->iobase1 + 2);
|
||||||
|
mdelay(30);
|
||||||
|
outw_p(0x8, card->iobase1 + 2);
|
||||||
|
for (i = 0; i < 30; i++) {
|
||||||
|
mdelay(30);
|
||||||
|
if (inw(card->iobase1) & 0x10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 30) {
|
||||||
|
printk(KERN_ERR PFX "brg1 timed out\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
if (inw(card->iobase2 + 0xe0) & 1) {
|
||||||
|
printk(KERN_ERR PFX "brg2 answer1 wrong\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
if (inw(card->iobase2 + 0xe2) & 1) {
|
||||||
|
printk(KERN_ERR PFX "brg2 answer2 wrong\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
if (inw(card->iobase2 + 0xe4) & 1) {
|
||||||
|
printk(KERN_ERR PFX "brg2 answer3 wrong\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the PCMCIA COR-Register */
|
||||||
|
outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
|
||||||
|
mdelay(1);
|
||||||
|
reg = inw(card->iobase2 + COR_OFFSET);
|
||||||
|
if (reg != COR_VALUE) {
|
||||||
|
printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
|
||||||
|
reg);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set leds */
|
||||||
|
outw_p(1, card->iobase1 + 10);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nortel_pci_init_one(struct pci_dev *pdev,
|
||||||
|
const struct pci_device_id *ent)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct orinoco_private *priv;
|
||||||
|
struct nortel_pci_card *card;
|
||||||
|
struct net_device *dev;
|
||||||
|
void __iomem *iomem;
|
||||||
|
|
||||||
|
err = pci_enable_device(pdev);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR PFX "Cannot enable PCI device\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pci_request_regions(pdev, DRIVER_NAME);
|
||||||
|
if (err != 0) {
|
||||||
|
printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
|
||||||
|
goto fail_resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
iomem = pci_iomap(pdev, 3, 0);
|
||||||
|
if (!iomem) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto fail_map_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate network device */
|
||||||
|
dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
|
||||||
|
if (!dev) {
|
||||||
|
printk(KERN_ERR PFX "Cannot allocate network device\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto fail_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = netdev_priv(dev);
|
||||||
|
card = priv->card;
|
||||||
|
card->iobase1 = pci_resource_start(pdev, 0);
|
||||||
|
card->iobase2 = pci_resource_start(pdev, 1);
|
||||||
|
dev->base_addr = pci_resource_start(pdev, 2);
|
||||||
|
SET_MODULE_OWNER(dev);
|
||||||
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||||
|
|
||||||
|
hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);
|
||||||
|
|
||||||
|
printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
|
||||||
|
"io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);
|
||||||
|
|
||||||
|
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
|
||||||
|
dev->name, dev);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
|
||||||
|
err = -EBUSY;
|
||||||
|
goto fail_irq;
|
||||||
|
}
|
||||||
|
dev->irq = pdev->irq;
|
||||||
|
|
||||||
|
err = nortel_pci_hw_init(card);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR PFX "Hardware initialization failed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nortel_pci_cor_reset(priv);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR PFX "Initial reset failed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
err = register_netdev(dev);
|
||||||
|
if (err) {
|
||||||
|
printk(KERN_ERR PFX "Cannot register network device\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_set_drvdata(pdev, dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free_irq(pdev->irq, dev);
|
||||||
|
|
||||||
|
fail_irq:
|
||||||
|
pci_set_drvdata(pdev, NULL);
|
||||||
|
free_orinocodev(dev);
|
||||||
|
|
||||||
|
fail_alloc:
|
||||||
|
pci_iounmap(pdev, iomem);
|
||||||
|
|
||||||
|
fail_map_io:
|
||||||
|
pci_release_regions(pdev);
|
||||||
|
|
||||||
|
fail_resources:
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct net_device *dev = pci_get_drvdata(pdev);
|
||||||
|
struct orinoco_private *priv = netdev_priv(dev);
|
||||||
|
struct nortel_pci_card *card = priv->card;
|
||||||
|
|
||||||
|
/* clear leds */
|
||||||
|
outw_p(0, card->iobase1 + 10);
|
||||||
|
|
||||||
|
unregister_netdev(dev);
|
||||||
|
free_irq(dev->irq, dev);
|
||||||
|
pci_set_drvdata(pdev, NULL);
|
||||||
|
free_orinocodev(dev);
|
||||||
|
pci_iounmap(pdev, priv->hw.iobase);
|
||||||
|
pci_release_regions(pdev);
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct pci_device_id nortel_pci_id_table[] = {
|
||||||
|
/* Nortel emobility PCI */
|
||||||
|
{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
|
||||||
|
{0,},
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
|
||||||
|
|
||||||
|
static struct pci_driver nortel_pci_driver = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.id_table = nortel_pci_id_table,
|
||||||
|
.probe = nortel_pci_init_one,
|
||||||
|
.remove = __devexit_p(nortel_pci_remove_one),
|
||||||
|
};
|
||||||
|
|
||||||
|
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
|
||||||
|
" (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
|
||||||
|
MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
|
||||||
|
MODULE_DESCRIPTION
|
||||||
|
("Driver for wireless LAN cards using the Nortel PCI bridge");
|
||||||
|
MODULE_LICENSE("Dual MPL/GPL");
|
||||||
|
|
||||||
|
static int __init nortel_pci_init(void)
|
||||||
|
{
|
||||||
|
printk(KERN_DEBUG "%s\n", version);
|
||||||
|
return pci_module_init(&nortel_pci_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit nortel_pci_exit(void)
|
||||||
|
{
|
||||||
|
pci_unregister_driver(&nortel_pci_driver);
|
||||||
|
ssleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(nortel_pci_init);
|
||||||
|
module_exit(nortel_pci_exit);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* c-indent-level: 8
|
||||||
|
* c-basic-offset: 8
|
||||||
|
* tab-width: 8
|
||||||
|
* End:
|
||||||
|
*/
|
1120
drivers/net/wireless/spectrum_cs.c
Normal file
1120
drivers/net/wireless/spectrum_cs.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -695,7 +695,7 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ethtool_get_perm_addr(struct net_device *dev, void *useraddr)
|
static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
|
||||||
{
|
{
|
||||||
struct ethtool_perm_addr epaddr;
|
struct ethtool_perm_addr epaddr;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
|
|
Loading…
Add table
Reference in a new issue