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

This commit is contained in:
Linus Torvalds 2005-06-27 14:55:50 -07:00
commit 61cca8c72e
44 changed files with 3686 additions and 2504 deletions

View File

@ -1274,6 +1274,7 @@ module_param_array(irq, int, NULL, 0);
module_param_array(io, int, NULL, 0); module_param_array(io, int, NULL, 0);
MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)"); MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)"); MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
MODULE_LICENSE("GPL");
int init_module(void) int init_module(void)
{ {

View File

@ -1320,7 +1320,7 @@ config FORCEDETH
config CS89x0 config CS89x0
tristate "CS89x0 support" tristate "CS89x0 support"
depends on NET_PCI && (ISA || ARCH_IXDP2X01) depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
---help--- ---help---
Support for CS89x0 chipset based Ethernet cards. If you have a Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the network (Ethernet) card of this type, say Y and read the

View File

@ -1285,6 +1285,9 @@ static int b44_open(struct net_device *dev)
b44_init_hw(bp); b44_init_hw(bp);
bp->flags |= B44_FLAG_INIT_COMPLETE; bp->flags |= B44_FLAG_INIT_COMPLETE;
netif_carrier_off(dev);
b44_check_phy(bp);
spin_unlock_irq(&bp->lock); spin_unlock_irq(&bp->lock);
init_timer(&bp->timer); init_timer(&bp->timer);

View File

@ -174,6 +174,13 @@ static unsigned int cs8900_irq_map[] = {1,0,0,0};
#include <asm/irq.h> #include <asm/irq.h>
static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
#elif defined(CONFIG_ARCH_PNX0105)
#include <asm/irq.h>
#include <asm/arch/gpio.h>
#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
#else #else
static unsigned int netcard_portlist[] __initdata = static unsigned int netcard_portlist[] __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@ -431,6 +438,30 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
#endif #endif
} }
#ifdef CONFIG_ARCH_PNX0105
initialize_ebi();
/* Map GPIO registers for the pins connected to the CS8900a. */
if (map_cirrus_gpio() < 0)
return -ENODEV;
reset_cirrus();
/* Map event-router registers. */
if (map_event_router() < 0)
return -ENODEV;
enable_cirrus_irq();
unmap_cirrus_gpio();
unmap_event_router();
dev->base_addr = ioaddr;
for (i = 0 ; i < 3 ; i++)
readreg(dev, 0);
#endif
/* Grab the region so we can find another board if autoIRQ fails. */ /* Grab the region so we can find another board if autoIRQ fails. */
/* WTF is going on here? */ /* WTF is going on here? */
if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) { if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
@ -672,7 +703,7 @@ printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
} else { } else {
i = lp->isa_config & INT_NO_MASK; i = lp->isa_config & INT_NO_MASK;
if (lp->chip_type == CS8900) { if (lp->chip_type == CS8900) {
#ifdef CONFIG_ARCH_IXDP2X01 #if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
i = cs8900_irq_map[0]; i = cs8900_irq_map[0];
#else #else
/* Translate the IRQ using the IRQ mapping table. */ /* Translate the IRQ using the IRQ mapping table. */
@ -1145,7 +1176,7 @@ net_open(struct net_device *dev)
int i; int i;
int ret; int ret;
#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this won't work */ #if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX0105) /* uses irq#1, so this won't work */
if (dev->irq < 2) { if (dev->irq < 2) {
/* Allow interrupts to be generated by the chip */ /* Allow interrupts to be generated by the chip */
/* Cirrus' release had this: */ /* Cirrus' release had this: */
@ -1176,7 +1207,7 @@ net_open(struct net_device *dev)
else else
#endif #endif
{ {
#ifndef CONFIG_ARCH_IXDP2X01 #if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
if (((1 << dev->irq) & lp->irq_map) == 0) { if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map); dev->name, dev->irq, lp->irq_map);
@ -1261,6 +1292,9 @@ net_open(struct net_device *dev)
case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
} }
#ifdef CONFIG_ARCH_PNX0105
result = A_CNF_10B_T;
#endif
if (!result) { if (!result) {
printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
release_irq: release_irq:

View File

@ -16,7 +16,7 @@
#include <linux/config.h> #include <linux/config.h>
#ifdef CONFIG_ARCH_IXDP2X01 #if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
/* IXDP2401/IXDP2801 uses dword-aligned register addressing */ /* IXDP2401/IXDP2801 uses dword-aligned register addressing */
#define CS89x0_PORT(reg) ((reg) * 2) #define CS89x0_PORT(reg) ((reg) * 2)
#else #else

View File

@ -1093,11 +1093,16 @@ static int e100_phy_init(struct nic *nic)
} }
if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000))) {
(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) /* enable/disable MDI/MDI-X auto-switching.
/* enable/disable MDI/MDI-X auto-switching */ MDI/MDI-X auto-switching is disabled for 82551ER/QM chips */
mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, if((nic->mac == mac_82551_E) || (nic->mac == mac_82551_F) ||
nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); (nic->mac == mac_82551_10) || (nic->mii.force_media) ||
!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))
mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, 0);
else
mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, NCONFIG_AUTO_SWITCH);
}
return 0; return 0;
} }
@ -1666,8 +1671,10 @@ static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
if(stat_ack & stat_ack_rnr) if(stat_ack & stat_ack_rnr)
nic->ru_running = RU_SUSPENDED; nic->ru_running = RU_SUSPENDED;
e100_disable_irq(nic); if(likely(netif_rx_schedule_prep(netdev))) {
netif_rx_schedule(netdev); e100_disable_irq(nic);
__netif_rx_schedule(netdev);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -2335,11 +2342,11 @@ static int __devinit e100_probe(struct pci_dev *pdev,
goto err_out_iounmap; goto err_out_iounmap;
} }
e100_phy_init(nic);
if((err = e100_eeprom_load(nic))) if((err = e100_eeprom_load(nic)))
goto err_out_free; goto err_out_free;
e100_phy_init(nic);
memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN); memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
if(!is_valid_ether_addr(netdev->dev_addr)) { if(!is_valid_ether_addr(netdev->dev_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC address from " DPRINTK(PROBE, ERR, "Invalid MAC address from "

View File

@ -140,7 +140,7 @@ struct e1000_adapter;
#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0 #define AUTO_ALL_MODES 0
#define E1000_EEPROM_82544_APM 0x0400 #define E1000_EEPROM_82544_APM 0x0004
#define E1000_EEPROM_APME 0x0400 #define E1000_EEPROM_APME 0x0400
#ifndef E1000_MASTER_SLAVE #ifndef E1000_MASTER_SLAVE
@ -159,7 +159,7 @@ struct e1000_adapter;
* so a DMA handle can be stored along with the buffer */ * so a DMA handle can be stored along with the buffer */
struct e1000_buffer { struct e1000_buffer {
struct sk_buff *skb; struct sk_buff *skb;
uint64_t dma; dma_addr_t dma;
unsigned long time_stamp; unsigned long time_stamp;
uint16_t length; uint16_t length;
uint16_t next_to_watch; uint16_t next_to_watch;

View File

@ -105,7 +105,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
static int static int
e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if(hw->media_type == e1000_media_type_copper) { if(hw->media_type == e1000_media_type_copper) {
@ -141,9 +141,9 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
SUPPORTED_FIBRE | SUPPORTED_FIBRE |
SUPPORTED_Autoneg); SUPPORTED_Autoneg);
ecmd->advertising = (SUPPORTED_1000baseT_Full | ecmd->advertising = (ADVERTISED_1000baseT_Full |
SUPPORTED_FIBRE | ADVERTISED_FIBRE |
SUPPORTED_Autoneg); ADVERTISED_Autoneg);
ecmd->port = PORT_FIBRE; ecmd->port = PORT_FIBRE;
@ -179,13 +179,24 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
static int static int
e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
if(ecmd->autoneg == AUTONEG_ENABLE) { if(ecmd->autoneg == AUTONEG_ENABLE) {
hw->autoneg = 1; hw->autoneg = 1;
hw->autoneg_advertised = 0x002F; if(hw->media_type == e1000_media_type_fiber)
ecmd->advertising = 0x002F; hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
ADVERTISED_FIBRE |
ADVERTISED_Autoneg;
else
hw->autoneg_advertised = ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Full|
ADVERTISED_Autoneg |
ADVERTISED_TP;
ecmd->advertising = hw->autoneg_advertised;
} else } else
if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
return -EINVAL; return -EINVAL;
@ -206,7 +217,7 @@ static void
e1000_get_pauseparam(struct net_device *netdev, e1000_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
pause->autoneg = pause->autoneg =
@ -226,7 +237,7 @@ static int
e1000_set_pauseparam(struct net_device *netdev, e1000_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
adapter->fc_autoneg = pause->autoneg; adapter->fc_autoneg = pause->autoneg;
@ -259,14 +270,14 @@ e1000_set_pauseparam(struct net_device *netdev,
static uint32_t static uint32_t
e1000_get_rx_csum(struct net_device *netdev) e1000_get_rx_csum(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->rx_csum; return adapter->rx_csum;
} }
static int static int
e1000_set_rx_csum(struct net_device *netdev, uint32_t data) e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->rx_csum = data; adapter->rx_csum = data;
if(netif_running(netdev)) { if(netif_running(netdev)) {
@ -286,7 +297,7 @@ e1000_get_tx_csum(struct net_device *netdev)
static int static int
e1000_set_tx_csum(struct net_device *netdev, uint32_t data) e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
if(adapter->hw.mac_type < e1000_82543) { if(adapter->hw.mac_type < e1000_82543) {
if (!data) if (!data)
@ -306,8 +317,8 @@ e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
static int static int
e1000_set_tso(struct net_device *netdev, uint32_t data) e1000_set_tso(struct net_device *netdev, uint32_t data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
if ((adapter->hw.mac_type < e1000_82544) || if((adapter->hw.mac_type < e1000_82544) ||
(adapter->hw.mac_type == e1000_82547)) (adapter->hw.mac_type == e1000_82547))
return data ? -EINVAL : 0; return data ? -EINVAL : 0;
@ -322,14 +333,14 @@ e1000_set_tso(struct net_device *netdev, uint32_t data)
static uint32_t static uint32_t
e1000_get_msglevel(struct net_device *netdev) e1000_get_msglevel(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable; return adapter->msg_enable;
} }
static void static void
e1000_set_msglevel(struct net_device *netdev, uint32_t data) e1000_set_msglevel(struct net_device *netdev, uint32_t data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data; adapter->msg_enable = data;
} }
@ -344,7 +355,7 @@ static void
e1000_get_regs(struct net_device *netdev, e1000_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p) struct ethtool_regs *regs, void *p)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint32_t *regs_buff = p; uint32_t *regs_buff = p;
uint16_t phy_data; uint16_t phy_data;
@ -432,7 +443,7 @@ e1000_get_regs(struct net_device *netdev,
static int static int
e1000_get_eeprom_len(struct net_device *netdev) e1000_get_eeprom_len(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
return adapter->hw.eeprom.word_size * 2; return adapter->hw.eeprom.word_size * 2;
} }
@ -440,7 +451,7 @@ static int
e1000_get_eeprom(struct net_device *netdev, e1000_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes) struct ethtool_eeprom *eeprom, uint8_t *bytes)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff; uint16_t *eeprom_buff;
int first_word, last_word; int first_word, last_word;
@ -486,7 +497,7 @@ static int
e1000_set_eeprom(struct net_device *netdev, e1000_set_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, uint8_t *bytes) struct ethtool_eeprom *eeprom, uint8_t *bytes)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint16_t *eeprom_buff; uint16_t *eeprom_buff;
void *ptr; void *ptr;
@ -547,7 +558,7 @@ static void
e1000_get_drvinfo(struct net_device *netdev, e1000_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, e1000_driver_name, 32); strncpy(drvinfo->driver, e1000_driver_name, 32);
strncpy(drvinfo->version, e1000_driver_version, 32); strncpy(drvinfo->version, e1000_driver_version, 32);
@ -563,7 +574,7 @@ static void
e1000_get_ringparam(struct net_device *netdev, e1000_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type; e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring; struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring; struct e1000_desc_ring *rxdr = &adapter->rx_ring;
@ -584,7 +595,7 @@ static int
e1000_set_ringparam(struct net_device *netdev, e1000_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_mac_type mac_type = adapter->hw.mac_type; e1000_mac_type mac_type = adapter->hw.mac_type;
struct e1000_desc_ring *txdr = &adapter->tx_ring; struct e1000_desc_ring *txdr = &adapter->tx_ring;
struct e1000_desc_ring *rxdr = &adapter->rx_ring; struct e1000_desc_ring *rxdr = &adapter->rx_ring;
@ -651,6 +662,9 @@ err_setup_rx:
E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \ E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
value = E1000_READ_REG(&adapter->hw, R); \ value = E1000_READ_REG(&adapter->hw, R); \
if(value != (test[pat] & W & M)) { \ if(value != (test[pat] & W & M)) { \
DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
"0x%08X expected 0x%08X\n", \
E1000_##R, value, (test[pat] & W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \ *data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \ E1000_82542_##R : E1000_##R; \
return 1; \ return 1; \
@ -663,7 +677,9 @@ err_setup_rx:
uint32_t value; \ uint32_t value; \
E1000_WRITE_REG(&adapter->hw, R, W & M); \ E1000_WRITE_REG(&adapter->hw, R, W & M); \
value = E1000_READ_REG(&adapter->hw, R); \ value = E1000_READ_REG(&adapter->hw, R); \
if ((W & M) != (value & M)) { \ if((W & M) != (value & M)) { \
DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
"expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \ *data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \ E1000_82542_##R : E1000_##R; \
return 1; \ return 1; \
@ -673,18 +689,33 @@ err_setup_rx:
static int static int
e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
{ {
uint32_t value; uint32_t value, before, after;
uint32_t i; uint32_t i, toggle;
/* The status register is Read Only, so a write should fail. /* The status register is Read Only, so a write should fail.
* Some bits that get toggled are ignored. * Some bits that get toggled are ignored.
*/ */
value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833)); switch (adapter->hw.mac_type) {
E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF)); case e1000_82573:
if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) { toggle = 0x7FFFF033;
break;
default:
toggle = 0xFFFFF833;
break;
}
before = E1000_READ_REG(&adapter->hw, STATUS);
value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
if(value != after) {
DPRINTK(DRV, ERR, "failed STATUS register test got: "
"0x%08X expected: 0x%08X\n", after, value);
*data = 1; *data = 1;
return 1; return 1;
} }
/* restore previous status */
E1000_WRITE_REG(&adapter->hw, STATUS, before);
REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF); REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF); REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
@ -766,7 +797,7 @@ e1000_test_intr(int irq,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct net_device *netdev = (struct net_device *) data; struct net_device *netdev = (struct net_device *) data;
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR); adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
@ -1214,6 +1245,7 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82541_rev_2: case e1000_82541_rev_2:
case e1000_82547: case e1000_82547:
case e1000_82547_rev_2: case e1000_82547_rev_2:
case e1000_82573:
return e1000_integrated_phy_loopback(adapter); return e1000_integrated_phy_loopback(adapter);
break; break;
@ -1422,7 +1454,7 @@ static void
e1000_diag_test(struct net_device *netdev, e1000_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, uint64_t *data) struct ethtool_test *eth_test, uint64_t *data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
boolean_t if_running = netif_running(netdev); boolean_t if_running = netif_running(netdev);
if(eth_test->flags == ETH_TEST_FL_OFFLINE) { if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
@ -1482,7 +1514,7 @@ e1000_diag_test(struct net_device *netdev,
static void static void
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) { switch(adapter->hw.device_id) {
@ -1527,7 +1559,7 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
static int static int
e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
switch(adapter->hw.device_id) { switch(adapter->hw.device_id) {
@ -1588,22 +1620,31 @@ e1000_led_blink_callback(unsigned long data)
static int static int
e1000_phys_id(struct net_device *netdev, uint32_t data) e1000_phys_id(struct net_device *netdev, uint32_t data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
if(!adapter->blink_timer.function) { if(adapter->hw.mac_type < e1000_82573) {
init_timer(&adapter->blink_timer); if(!adapter->blink_timer.function) {
adapter->blink_timer.function = e1000_led_blink_callback; init_timer(&adapter->blink_timer);
adapter->blink_timer.data = (unsigned long) adapter; adapter->blink_timer.function = e1000_led_blink_callback;
adapter->blink_timer.data = (unsigned long) adapter;
}
e1000_setup_led(&adapter->hw);
mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer);
}
else {
E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
msleep_interruptible(data * 1000);
} }
e1000_setup_led(&adapter->hw);
mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer);
e1000_led_off(&adapter->hw); e1000_led_off(&adapter->hw);
clear_bit(E1000_LED_ON, &adapter->led_status); clear_bit(E1000_LED_ON, &adapter->led_status);
e1000_cleanup_led(&adapter->hw); e1000_cleanup_led(&adapter->hw);
@ -1614,7 +1655,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
static int static int
e1000_nway_reset(struct net_device *netdev) e1000_nway_reset(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev)) { if(netif_running(netdev)) {
e1000_down(adapter); e1000_down(adapter);
e1000_up(adapter); e1000_up(adapter);
@ -1632,7 +1673,7 @@ static void
e1000_get_ethtool_stats(struct net_device *netdev, e1000_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, uint64_t *data) struct ethtool_stats *stats, uint64_t *data)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
int i; int i;
e1000_update_stats(adapter); e1000_update_stats(adapter);

View File

@ -354,18 +354,27 @@ e1000_set_media_type(struct e1000_hw *hw)
hw->media_type = e1000_media_type_internal_serdes; hw->media_type = e1000_media_type_internal_serdes;
break; break;
default: default:
if(hw->mac_type >= e1000_82543) { switch (hw->mac_type) {
case e1000_82542_rev2_0:
case e1000_82542_rev2_1:
hw->media_type = e1000_media_type_fiber;
break;
case e1000_82573:
/* The STATUS_TBIMODE bit is reserved or reused for the this
* device.
*/
hw->media_type = e1000_media_type_copper;
break;
default:
status = E1000_READ_REG(hw, STATUS); status = E1000_READ_REG(hw, STATUS);
if(status & E1000_STATUS_TBIMODE) { if (status & E1000_STATUS_TBIMODE) {
hw->media_type = e1000_media_type_fiber; hw->media_type = e1000_media_type_fiber;
/* tbi_compatibility not valid on fiber */ /* tbi_compatibility not valid on fiber */
hw->tbi_compatibility_en = FALSE; hw->tbi_compatibility_en = FALSE;
} else { } else {
hw->media_type = e1000_media_type_copper; hw->media_type = e1000_media_type_copper;
} }
} else { break;
/* This is an 82542 (fiber only) */
hw->media_type = e1000_media_type_fiber;
} }
} }
} }
@ -1189,9 +1198,9 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw)
ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
if(ret_val) if(ret_val)
return ret_val; return ret_val;
} }
return E1000_SUCCESS; return E1000_SUCCESS;
} }

View File

@ -66,6 +66,7 @@ typedef enum {
e1000_eeprom_spi, e1000_eeprom_spi,
e1000_eeprom_microwire, e1000_eeprom_microwire,
e1000_eeprom_flash, e1000_eeprom_flash,
e1000_eeprom_none, /* No NVM support */
e1000_num_eeprom_types e1000_num_eeprom_types
} e1000_eeprom_type; } e1000_eeprom_type;

View File

@ -29,6 +29,8 @@
#include "e1000.h" #include "e1000.h"
/* Change Log /* Change Log
* 6.0.58 4/20/05
* o Accepted ethtool cleanup patch from Stephen Hemminger
* 6.0.44+ 2/15/05 * 6.0.44+ 2/15/05
* o applied Anton's patch to resolve tx hang in hardware * o applied Anton's patch to resolve tx hang in hardware
* o Applied Andrew Mortons patch - e1000 stops working after resume * o Applied Andrew Mortons patch - e1000 stops working after resume
@ -41,9 +43,9 @@ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
#else #else
#define DRIVERNAPI "-NAPI" #define DRIVERNAPI "-NAPI"
#endif #endif
#define DRV_VERSION "6.0.54-k2"DRIVERNAPI #define DRV_VERSION "6.0.60-k2"DRIVERNAPI
char e1000_driver_version[] = DRV_VERSION; char e1000_driver_version[] = DRV_VERSION;
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation."; char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table /* e1000_pci_tbl - PCI Device ID Table
* *
@ -517,7 +519,7 @@ e1000_probe(struct pci_dev *pdev,
SET_NETDEV_DEV(netdev, &pdev->dev); SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev); pci_set_drvdata(pdev, netdev);
adapter = netdev->priv; adapter = netdev_priv(netdev);
adapter->netdev = netdev; adapter->netdev = netdev;
adapter->pdev = pdev; adapter->pdev = pdev;
adapter->hw.back = adapter; adapter->hw.back = adapter;
@ -738,7 +740,7 @@ static void __devexit
e1000_remove(struct pci_dev *pdev) e1000_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t manc, swsm; uint32_t manc, swsm;
flush_scheduled_work(); flush_scheduled_work();
@ -871,7 +873,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
static int static int
e1000_open(struct net_device *netdev) e1000_open(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
int err; int err;
/* allocate transmit descriptors */ /* allocate transmit descriptors */
@ -919,7 +921,7 @@ err_setup_tx:
static int static int
e1000_close(struct net_device *netdev) e1000_close(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_down(adapter); e1000_down(adapter);
@ -1599,7 +1601,7 @@ e1000_leave_82542_rst(struct e1000_adapter *adapter)
static int static int
e1000_set_mac(struct net_device *netdev, void *p) e1000_set_mac(struct net_device *netdev, void *p)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p; struct sockaddr *addr = p;
if(!is_valid_ether_addr(addr->sa_data)) if(!is_valid_ether_addr(addr->sa_data))
@ -1634,7 +1636,7 @@ e1000_set_mac(struct net_device *netdev, void *p)
static void static void
e1000_set_multi(struct net_device *netdev) e1000_set_multi(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr; struct dev_mc_list *mc_ptr;
unsigned long flags; unsigned long flags;
@ -2213,7 +2215,7 @@ e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
static int static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD; unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0; unsigned int tx_flags = 0;
@ -2344,7 +2346,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static void static void
e1000_tx_timeout(struct net_device *netdev) e1000_tx_timeout(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */ /* Do the reset outside of interrupt context */
schedule_work(&adapter->tx_timeout_task); schedule_work(&adapter->tx_timeout_task);
@ -2353,7 +2355,7 @@ e1000_tx_timeout(struct net_device *netdev)
static void static void
e1000_tx_timeout_task(struct net_device *netdev) e1000_tx_timeout_task(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_down(adapter); e1000_down(adapter);
e1000_up(adapter); e1000_up(adapter);
@ -2370,7 +2372,7 @@ e1000_tx_timeout_task(struct net_device *netdev)
static struct net_device_stats * static struct net_device_stats *
e1000_get_stats(struct net_device *netdev) e1000_get_stats(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
e1000_update_stats(adapter); e1000_update_stats(adapter);
return &adapter->net_stats; return &adapter->net_stats;
@ -2387,7 +2389,7 @@ e1000_get_stats(struct net_device *netdev)
static int static int
e1000_change_mtu(struct net_device *netdev, int new_mtu) e1000_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
@ -2598,7 +2600,7 @@ static irqreturn_t
e1000_intr(int irq, void *data, struct pt_regs *regs) e1000_intr(int irq, void *data, struct pt_regs *regs)
{ {
struct net_device *netdev = data; struct net_device *netdev = data;
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
uint32_t icr = E1000_READ_REG(hw, ICR); uint32_t icr = E1000_READ_REG(hw, ICR);
#ifndef CONFIG_E1000_NAPI #ifndef CONFIG_E1000_NAPI
@ -2661,7 +2663,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
static int static int
e1000_clean(struct net_device *netdev, int *budget) e1000_clean(struct net_device *netdev, int *budget)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
int work_to_do = min(*budget, netdev->quota); int work_to_do = min(*budget, netdev->quota);
int tx_cleaned; int tx_cleaned;
int work_done = 0; int work_done = 0;
@ -2672,8 +2674,8 @@ e1000_clean(struct net_device *netdev, int *budget)
*budget -= work_done; *budget -= work_done;
netdev->quota -= work_done; netdev->quota -= work_done;
/* If no Tx and no Rx work done, exit the polling mode */
if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
/* If no Tx and not enough Rx work done, exit the polling mode */
netif_rx_complete(netdev); netif_rx_complete(netdev);
e1000_irq_enable(adapter); e1000_irq_enable(adapter);
return 0; return 0;
@ -2769,13 +2771,13 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter)
i = tx_ring->next_to_clean; i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch; eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop); eop_desc = E1000_TX_DESC(*tx_ring, eop);
DPRINTK(TX_ERR, ERR, "Detected Tx Unit Hang\n" DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
" TDH <%x>\n" " TDH <%x>\n"
" TDT <%x>\n" " TDT <%x>\n"
" next_to_use <%x>\n" " next_to_use <%x>\n"
" next_to_clean <%x>\n" " next_to_clean <%x>\n"
"buffer_info[next_to_clean]\n" "buffer_info[next_to_clean]\n"
" dma <%llx>\n" " dma <%zx>\n"
" time_stamp <%lx>\n" " time_stamp <%lx>\n"
" next_to_watch <%x>\n" " next_to_watch <%x>\n"
" jiffies <%lx>\n" " jiffies <%lx>\n"
@ -2994,7 +2996,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
i = rx_ring->next_to_clean; i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC_PS(*rx_ring, i); rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
staterr = rx_desc->wb.middle.status_error; staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
while(staterr & E1000_RXD_STAT_DD) { while(staterr & E1000_RXD_STAT_DD) {
buffer_info = &rx_ring->buffer_info[i]; buffer_info = &rx_ring->buffer_info[i];
@ -3065,16 +3067,16 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.middle.vlan & le16_to_cpu(rx_desc->wb.middle.vlan) &
E1000_RXD_SPC_VLAN_MASK)); E1000_RXD_SPC_VLAN_MASK);
} else { } else {
netif_receive_skb(skb); netif_receive_skb(skb);
} }
#else /* CONFIG_E1000_NAPI */ #else /* CONFIG_E1000_NAPI */
if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_hwaccel_rx(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.middle.vlan & le16_to_cpu(rx_desc->wb.middle.vlan) &
E1000_RXD_SPC_VLAN_MASK)); E1000_RXD_SPC_VLAN_MASK);
} else { } else {
netif_rx(skb); netif_rx(skb);
} }
@ -3087,7 +3089,7 @@ next_desc:
if(unlikely(++i == rx_ring->count)) i = 0; if(unlikely(++i == rx_ring->count)) i = 0;
rx_desc = E1000_RX_DESC_PS(*rx_ring, i); rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
staterr = rx_desc->wb.middle.status_error; staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
} }
rx_ring->next_to_clean = i; rx_ring->next_to_clean = i;
adapter->alloc_rx_buf(adapter); adapter->alloc_rx_buf(adapter);
@ -3371,11 +3373,12 @@ e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
static int static int
e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
struct mii_ioctl_data *data = if_mii(ifr); struct mii_ioctl_data *data = if_mii(ifr);
int retval; int retval;
uint16_t mii_reg; uint16_t mii_reg;
uint16_t spddplx; uint16_t spddplx;
unsigned long flags;
if(adapter->hw.media_type != e1000_media_type_copper) if(adapter->hw.media_type != e1000_media_type_copper)
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -3385,22 +3388,29 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
data->phy_id = adapter->hw.phy_addr; data->phy_id = adapter->hw.phy_addr;
break; break;
case SIOCGMIIREG: case SIOCGMIIREG:
if (!capable(CAP_NET_ADMIN)) if(!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, spin_lock_irqsave(&adapter->stats_lock, flags);
&data->val_out)) if(e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
&data->val_out)) {
spin_unlock_irqrestore(&adapter->stats_lock, flags);
return -EIO; return -EIO;
}
spin_unlock_irqrestore(&adapter->stats_lock, flags);
break; break;
case SIOCSMIIREG: case SIOCSMIIREG:
if (!capable(CAP_NET_ADMIN)) if(!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
if (data->reg_num & ~(0x1F)) if(data->reg_num & ~(0x1F))
return -EFAULT; return -EFAULT;
mii_reg = data->val_in; mii_reg = data->val_in;
if (e1000_write_phy_reg(&adapter->hw, data->reg_num, spin_lock_irqsave(&adapter->stats_lock, flags);
mii_reg)) if(e1000_write_phy_reg(&adapter->hw, data->reg_num,
mii_reg)) {
spin_unlock_irqrestore(&adapter->stats_lock, flags);
return -EIO; return -EIO;
if (adapter->hw.phy_type == e1000_phy_m88) { }
if(adapter->hw.phy_type == e1000_phy_m88) {
switch (data->reg_num) { switch (data->reg_num) {
case PHY_CTRL: case PHY_CTRL:
if(mii_reg & MII_CR_POWER_DOWN) if(mii_reg & MII_CR_POWER_DOWN)
@ -3420,8 +3430,12 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
HALF_DUPLEX; HALF_DUPLEX;
retval = e1000_set_spd_dplx(adapter, retval = e1000_set_spd_dplx(adapter,
spddplx); spddplx);
if(retval) if(retval) {
spin_unlock_irqrestore(
&adapter->stats_lock,
flags);
return retval; return retval;
}
} }
if(netif_running(adapter->netdev)) { if(netif_running(adapter->netdev)) {
e1000_down(adapter); e1000_down(adapter);
@ -3431,8 +3445,11 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
break; break;
case M88E1000_PHY_SPEC_CTRL: case M88E1000_PHY_SPEC_CTRL:
case M88E1000_EXT_PHY_SPEC_CTRL: case M88E1000_EXT_PHY_SPEC_CTRL:
if (e1000_phy_reset(&adapter->hw)) if(e1000_phy_reset(&adapter->hw)) {
spin_unlock_irqrestore(
&adapter->stats_lock, flags);
return -EIO; return -EIO;
}
break; break;
} }
} else { } else {
@ -3448,6 +3465,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
break; break;
} }
} }
spin_unlock_irqrestore(&adapter->stats_lock, flags);
break; break;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -3504,7 +3522,7 @@ e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
static void static void
e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t ctrl, rctl; uint32_t ctrl, rctl;
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
@ -3544,7 +3562,7 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
static void static void
e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t vfta, index; uint32_t vfta, index;
if((adapter->hw.mng_cookie.status & if((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
@ -3560,7 +3578,7 @@ e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
static void static void
e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t vfta, index; uint32_t vfta, index;
e1000_irq_disable(adapter); e1000_irq_disable(adapter);
@ -3601,6 +3619,13 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
{ {
adapter->hw.autoneg = 0; adapter->hw.autoneg = 0;
/* Fiber NICs only allow 1000 gbps Full duplex */
if((adapter->hw.media_type == e1000_media_type_fiber) &&
spddplx != (SPEED_1000 + DUPLEX_FULL)) {
DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
return -EINVAL;
}
switch(spddplx) { switch(spddplx) {
case SPEED_10 + DUPLEX_HALF: case SPEED_10 + DUPLEX_HALF:
adapter->hw.forced_speed_duplex = e1000_10_half; adapter->hw.forced_speed_duplex = e1000_10_half;
@ -3647,7 +3672,7 @@ static int
e1000_suspend(struct pci_dev *pdev, uint32_t state) e1000_suspend(struct pci_dev *pdev, uint32_t state)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm; uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
uint32_t wufc = adapter->wol; uint32_t wufc = adapter->wol;
@ -3740,12 +3765,12 @@ static int
e1000_resume(struct pci_dev *pdev) e1000_resume(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
uint32_t manc, ret, swsm; uint32_t manc, ret_val, swsm;
pci_set_power_state(pdev, 0); pci_set_power_state(pdev, 0);
pci_restore_state(pdev); pci_restore_state(pdev);
ret = pci_enable_device(pdev); ret_val = pci_enable_device(pdev);
pci_set_master(pdev); pci_set_master(pdev);
pci_enable_wake(pdev, 3, 0); pci_enable_wake(pdev, 3, 0);
@ -3788,7 +3813,7 @@ e1000_resume(struct pci_dev *pdev)
static void static void
e1000_netpoll(struct net_device *netdev) e1000_netpoll(struct net_device *netdev)
{ {
struct e1000_adapter *adapter = netdev->priv; struct e1000_adapter *adapter = netdev_priv(netdev);
disable_irq(adapter->pdev->irq); disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_intr(adapter->pdev->irq, netdev, NULL);
enable_irq(adapter->pdev->irq); enable_irq(adapter->pdev->irq);

View File

@ -82,6 +82,9 @@
* 0.31: 14 Nov 2004: ethtool support for getting/setting link * 0.31: 14 Nov 2004: ethtool support for getting/setting link
* capabilities. * capabilities.
* 0.32: 16 Apr 2005: RX_ERROR4 handling added. * 0.32: 16 Apr 2005: RX_ERROR4 handling added.
* 0.33: 16 May 2005: Support for MCP51 added.
* 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.
* 0.35: 26 Jun 2005: Support for MCP55 added.
* *
* Known bugs: * Known bugs:
* We suspect that on some hardware no TX done interrupts are generated. * We suspect that on some hardware no TX done interrupts are generated.
@ -93,7 +96,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic. * superfluous timer interrupts from the nic.
*/ */
#define FORCEDETH_VERSION "0.32" #define FORCEDETH_VERSION "0.35"
#define DRV_NAME "forcedeth" #define DRV_NAME "forcedeth"
#include <linux/module.h> #include <linux/module.h>
@ -2005,7 +2008,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* handle different descriptor versions */ /* handle different descriptor versions */
if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 ||
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 ||
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3) pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3 ||
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_13)
np->desc_ver = DESC_VER_1; np->desc_ver = DESC_VER_1;
else else
np->desc_ver = DESC_VER_2; np->desc_ver = DESC_VER_2;
@ -2215,56 +2220,84 @@ static struct pci_device_id pci_tbl[] = {
.device = PCI_DEVICE_ID_NVIDIA_NVENET_4, .device = PCI_DEVICE_ID_NVIDIA_NVENET_4,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce3 Ethernet Controller */ { /* nForce3 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_5, .device = PCI_DEVICE_ID_NVIDIA_NVENET_5,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce3 Ethernet Controller */ { /* nForce3 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_6, .device = PCI_DEVICE_ID_NVIDIA_NVENET_6,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* nForce3 Ethernet Controller */ { /* nForce3 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_7, .device = PCI_DEVICE_ID_NVIDIA_NVENET_7,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* CK804 Ethernet Controller */ { /* CK804 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_8, .device = PCI_DEVICE_ID_NVIDIA_NVENET_8,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* CK804 Ethernet Controller */ { /* CK804 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_9, .device = PCI_DEVICE_ID_NVIDIA_NVENET_9,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* MCP04 Ethernet Controller */ { /* MCP04 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_10, .device = PCI_DEVICE_ID_NVIDIA_NVENET_10,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{ /* MCP04 Ethernet Controller */ { /* MCP04 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA, .vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_11, .device = PCI_DEVICE_ID_NVIDIA_NVENET_11,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* MCP51 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_12,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* MCP51 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_13,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* MCP55 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_14,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
},
{ /* MCP55 Ethernet Controller */
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NVENET_15,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
}, },
{0,}, {0,},
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* /*
* drivers/net/gianfar.h * drivers/net/gianfar.h
* *
* Gianfar Ethernet Driver * Gianfar Ethernet Driver
@ -53,6 +53,12 @@
/* The maximum number of packets to be handled in one call of gfar_poll */ /* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64 #define GFAR_DEV_WEIGHT 64
/* Length for FCB */
#define GMAC_FCB_LEN 8
/* Default padding amount */
#define DEFAULT_PADDING 2
/* Number of bytes to align the rx bufs to */ /* Number of bytes to align the rx bufs to */
#define RXBUF_ALIGNMENT 64 #define RXBUF_ALIGNMENT 64
@ -91,7 +97,7 @@ extern const char gfar_driver_version[];
#define JUMBO_FRAME_SIZE 9600 #define JUMBO_FRAME_SIZE 9600
/* Latency of interface clock in nanoseconds */ /* Latency of interface clock in nanoseconds */
/* Interface clock latency , in this case, means the /* Interface clock latency , in this case, means the
* time described by a value of 1 in the interrupt * time described by a value of 1 in the interrupt
* coalescing registers' time fields. Since those fields * coalescing registers' time fields. Since those fields
* refer to the time it takes for 64 clocks to pass, the * refer to the time it takes for 64 clocks to pass, the
@ -166,9 +172,28 @@ extern const char gfar_driver_version[];
mk_ic_icft(count) | \ mk_ic_icft(count) | \
mk_ic_ictt(time)) mk_ic_ictt(time))
#define RCTRL_PAL_MASK 0x001f0000
#define RCTRL_VLEX 0x00002000
#define RCTRL_FILREN 0x00001000
#define RCTRL_GHTX 0x00000400
#define RCTRL_IPCSEN 0x00000200
#define RCTRL_TUCSEN 0x00000100
#define RCTRL_PRSDEP_MASK 0x000000c0
#define RCTRL_PRSDEP_INIT 0x000000c0
#define RCTRL_PROM 0x00000008 #define RCTRL_PROM 0x00000008
#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \
| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
#define RCTRL_EXTHASH (RCTRL_GHTX)
#define RCTRL_VLAN (RCTRL_PRSDEP_INIT)
#define RSTAT_CLEAR_RHALT 0x00800000 #define RSTAT_CLEAR_RHALT 0x00800000
#define TCTRL_IPCSEN 0x00004000
#define TCTRL_TUCSEN 0x00002000
#define TCTRL_VLINS 0x00001000
#define TCTRL_INIT_CSUM (TCTRL_TUCSEN | TCTRL_IPCSEN)
#define IEVENT_INIT_CLEAR 0xffffffff #define IEVENT_INIT_CLEAR 0xffffffff
#define IEVENT_BABR 0x80000000 #define IEVENT_BABR 0x80000000
#define IEVENT_RXC 0x40000000 #define IEVENT_RXC 0x40000000
@ -187,12 +212,16 @@ extern const char gfar_driver_version[];
#define IEVENT_RXB0 0x00008000 #define IEVENT_RXB0 0x00008000
#define IEVENT_GRSC 0x00000100 #define IEVENT_GRSC 0x00000100
#define IEVENT_RXF0 0x00000080 #define IEVENT_RXF0 0x00000080
#define IEVENT_FIR 0x00000008
#define IEVENT_FIQ 0x00000004
#define IEVENT_DPE 0x00000002
#define IEVENT_PERR 0x00000001
#define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0) #define IEVENT_RX_MASK (IEVENT_RXB0 | IEVENT_RXF0)
#define IEVENT_TX_MASK (IEVENT_TXB | IEVENT_TXF) #define IEVENT_TX_MASK (IEVENT_TXB | IEVENT_TXF)
#define IEVENT_ERR_MASK \ #define IEVENT_ERR_MASK \
(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
| IEVENT_CRL | IEVENT_XFUN) | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR)
#define IMASK_INIT_CLEAR 0x00000000 #define IMASK_INIT_CLEAR 0x00000000
#define IMASK_BABR 0x80000000 #define IMASK_BABR 0x80000000
@ -212,10 +241,15 @@ extern const char gfar_driver_version[];
#define IMASK_RXB0 0x00008000 #define IMASK_RXB0 0x00008000
#define IMASK_GTSC 0x00000100 #define IMASK_GTSC 0x00000100
#define IMASK_RXFEN0 0x00000080 #define IMASK_RXFEN0 0x00000080
#define IMASK_FIR 0x00000008
#define IMASK_FIQ 0x00000004
#define IMASK_DPE 0x00000002
#define IMASK_PERR 0x00000001
#define IMASK_RX_DISABLED ~(IMASK_RXFEN0 | IMASK_BSY) #define IMASK_RX_DISABLED ~(IMASK_RXFEN0 | IMASK_BSY)
#define IMASK_DEFAULT (IMASK_TXEEN | IMASK_TXFEN | IMASK_TXBEN | \ #define IMASK_DEFAULT (IMASK_TXEEN | IMASK_TXFEN | IMASK_TXBEN | \
IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \ IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
IMASK_XFUN | IMASK_RXC | IMASK_BABT) IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
| IMASK_PERR)
/* Attribute fields */ /* Attribute fields */
@ -254,6 +288,18 @@ extern const char gfar_driver_version[];
#define TXBD_RETRYLIMIT 0x0040 #define TXBD_RETRYLIMIT 0x0040
#define TXBD_RETRYCOUNTMASK 0x003c #define TXBD_RETRYCOUNTMASK 0x003c
#define TXBD_UNDERRUN 0x0002 #define TXBD_UNDERRUN 0x0002
#define TXBD_TOE 0x0002
/* Tx FCB param bits */
#define TXFCB_VLN 0x80
#define TXFCB_IP 0x40
#define TXFCB_IP6 0x20
#define TXFCB_TUP 0x10
#define TXFCB_UDP 0x08
#define TXFCB_CIP 0x04
#define TXFCB_CTU 0x02
#define TXFCB_NPH 0x01
#define TXFCB_DEFAULT (TXFCB_IP|TXFCB_TUP|TXFCB_CTU|TXFCB_NPH)
/* RxBD status field bits */ /* RxBD status field bits */
#define RXBD_EMPTY 0x8000 #define RXBD_EMPTY 0x8000
@ -273,6 +319,18 @@ extern const char gfar_driver_version[];
#define RXBD_TRUNCATED 0x0001 #define RXBD_TRUNCATED 0x0001
#define RXBD_STATS 0x01ff #define RXBD_STATS 0x01ff
/* Rx FCB status field bits */
#define RXFCB_VLN 0x8000
#define RXFCB_IP 0x4000
#define RXFCB_IP6 0x2000
#define RXFCB_TUP 0x1000
#define RXFCB_CIP 0x0800
#define RXFCB_CTU 0x0400
#define RXFCB_EIP 0x0200
#define RXFCB_ETU 0x0100
#define RXFCB_PERR_MASK 0x000c
#define RXFCB_PERR_BADL3 0x0008
struct txbd8 struct txbd8
{ {
u16 status; /* Status Fields */ u16 status; /* Status Fields */
@ -280,6 +338,22 @@ struct txbd8
u32 bufPtr; /* Buffer Pointer */ u32 bufPtr; /* Buffer Pointer */
}; };
struct txfcb {
u8 vln:1,
ip:1,
ip6:1,
tup:1,
udp:1,
cip:1,
ctu:1,
nph:1;
u8 reserved;
u8 l4os; /* Level 4 Header Offset */
u8 l3os; /* Level 3 Header Offset */
u16 phcs; /* Pseudo-header Checksum */
u16 vlctl; /* VLAN control word */
};
struct rxbd8 struct rxbd8
{ {
u16 status; /* Status Fields */ u16 status; /* Status Fields */
@ -287,6 +361,21 @@ struct rxbd8
u32 bufPtr; /* Buffer Pointer */ u32 bufPtr; /* Buffer Pointer */
}; };
struct rxfcb {
u16 vln:1,
ip:1,
ip6:1,
tup:1,
cip:1,
ctu:1,
eip:1,
etu:1;
u8 rq; /* Receive Queue index */
u8 pro; /* Layer 4 Protocol */
u16 reserved;
u16 vlctl; /* VLAN control word */
};
struct rmon_mib struct rmon_mib
{ {
u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */ u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */
@ -371,90 +460,191 @@ struct gfar_stats {
struct gfar { struct gfar {
u8 res1[16]; u32 tsec_id; /* 0x.000 - Controller ID register */
u32 ievent; /* 0x.010 - Interrupt Event Register */ u8 res1[12];
u32 imask; /* 0x.014 - Interrupt Mask Register */ u32 ievent; /* 0x.010 - Interrupt Event Register */
u32 edis; /* 0x.018 - Error Disabled Register */ u32 imask; /* 0x.014 - Interrupt Mask Register */
u32 edis; /* 0x.018 - Error Disabled Register */
u8 res2[4]; u8 res2[4];
u32 ecntrl; /* 0x.020 - Ethernet Control Register */ u32 ecntrl; /* 0x.020 - Ethernet Control Register */
u32 minflr; /* 0x.024 - Minimum Frame Length Register */ u32 minflr; /* 0x.024 - Minimum Frame Length Register */
u32 ptv; /* 0x.028 - Pause Time Value Register */ u32 ptv; /* 0x.028 - Pause Time Value Register */
u32 dmactrl; /* 0x.02c - DMA Control Register */ u32 dmactrl; /* 0x.02c - DMA Control Register */
u32 tbipa; /* 0x.030 - TBI PHY Address Register */ u32 tbipa; /* 0x.030 - TBI PHY Address Register */
u8 res3[88]; u8 res3[88];
u32 fifo_tx_thr; /* 0x.08c - FIFO transmit threshold register */ u32 fifo_tx_thr; /* 0x.08c - FIFO transmit threshold register */
u8 res4[8]; u8 res4[8];
u32 fifo_tx_starve; /* 0x.098 - FIFO transmit starve register */ u32 fifo_tx_starve; /* 0x.098 - FIFO transmit starve register */
u32 fifo_tx_starve_shutoff; /* 0x.09c - FIFO transmit starve shutoff register */ u32 fifo_tx_starve_shutoff; /* 0x.09c - FIFO transmit starve shutoff register */
u8 res5[96]; u8 res5[4];
u32 tctrl; /* 0x.100 - Transmit Control Register */ u32 fifo_rx_pause; /* 0x.0a4 - FIFO receive pause threshold register */
u32 tstat; /* 0x.104 - Transmit Status Register */ u32 fifo_rx_alarm; /* 0x.0a8 - FIFO receive alarm threshold register */
u8 res6[4]; u8 res6[84];
u32 tbdlen; /* 0x.10c - Transmit Buffer Descriptor Data Length Register */ u32 tctrl; /* 0x.100 - Transmit Control Register */
u32 txic; /* 0x.110 - Transmit Interrupt Coalescing Configuration Register */ u32 tstat; /* 0x.104 - Transmit Status Register */
u8 res7[16]; u32 dfvlan; /* 0x.108 - Default VLAN Control word */
u32 ctbptr; /* 0x.124 - Current Transmit Buffer Descriptor Pointer Register */ u32 tbdlen; /* 0x.10c - Transmit Buffer Descriptor Data Length Register */
u8 res8[92]; u32 txic; /* 0x.110 - Transmit Interrupt Coalescing Configuration Register */
u32 tbptr; /* 0x.184 - Transmit Buffer Descriptor Pointer Low Register */ u32 tqueue; /* 0x.114 - Transmit queue control register */
u8 res9[124]; u8 res7[40];
u32 tbase; /* 0x.204 - Transmit Descriptor Base Address Register */ u32 tr03wt; /* 0x.140 - TxBD Rings 0-3 round-robin weightings */
u8 res10[168]; u32 tr47wt; /* 0x.144 - TxBD Rings 4-7 round-robin weightings */
u32 ostbd; /* 0x.2b0 - Out-of-Sequence Transmit Buffer Descriptor Register */ u8 res8[52];
u32 ostbdp; /* 0x.2b4 - Out-of-Sequence Transmit Data Buffer Pointer Register */ u32 tbdbph; /* 0x.17c - Tx data buffer pointer high */
u8 res11[72]; u8 res9a[4];
u32 rctrl; /* 0x.300 - Receive Control Register */ u32 tbptr0; /* 0x.184 - TxBD Pointer for ring 0 */
u32 rstat; /* 0x.304 - Receive Status Register */ u8 res9b[4];
u8 res12[4]; u32 tbptr1; /* 0x.18c - TxBD Pointer for ring 1 */
u32 rbdlen; /* 0x.30c - RxBD Data Length Register */ u8 res9c[4];
u32 rxic; /* 0x.310 - Receive Interrupt Coalescing Configuration Register */ u32 tbptr2; /* 0x.194 - TxBD Pointer for ring 2 */
u8 res13[16]; u8 res9d[4];
u32 crbptr; /* 0x.324 - Current Receive Buffer Descriptor Pointer */ u32 tbptr3; /* 0x.19c - TxBD Pointer for ring 3 */
u8 res14[24]; u8 res9e[4];
u32 mrblr; /* 0x.340 - Maximum Receive Buffer Length Register */ u32 tbptr4; /* 0x.1a4 - TxBD Pointer for ring 4 */
u8 res15[64]; u8 res9f[4];
u32 rbptr; /* 0x.384 - Receive Buffer Descriptor Pointer */ u32 tbptr5; /* 0x.1ac - TxBD Pointer for ring 5 */
u8 res16[124]; u8 res9g[4];
u32 rbase; /* 0x.404 - Receive Descriptor Base Address */ u32 tbptr6; /* 0x.1b4 - TxBD Pointer for ring 6 */
u8 res17[248]; u8 res9h[4];
u32 maccfg1; /* 0x.500 - MAC Configuration 1 Register */ u32 tbptr7; /* 0x.1bc - TxBD Pointer for ring 7 */
u32 maccfg2; /* 0x.504 - MAC Configuration 2 Register */ u8 res9[64];
u32 ipgifg; /* 0x.508 - Inter Packet Gap/Inter Frame Gap Register */ u32 tbaseh; /* 0x.200 - TxBD base address high */
u32 hafdup; /* 0x.50c - Half Duplex Register */ u32 tbase0; /* 0x.204 - TxBD Base Address of ring 0 */
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */ u8 res10a[4];
u32 tbase1; /* 0x.20c - TxBD Base Address of ring 1 */
u8 res10b[4];
u32 tbase2; /* 0x.214 - TxBD Base Address of ring 2 */
u8 res10c[4];
u32 tbase3; /* 0x.21c - TxBD Base Address of ring 3 */
u8 res10d[4];
u32 tbase4; /* 0x.224 - TxBD Base Address of ring 4 */
u8 res10e[4];
u32 tbase5; /* 0x.22c - TxBD Base Address of ring 5 */
u8 res10f[4];
u32 tbase6; /* 0x.234 - TxBD Base Address of ring 6 */
u8 res10g[4];
u32 tbase7; /* 0x.23c - TxBD Base Address of ring 7 */
u8 res10[192];
u32 rctrl; /* 0x.300 - Receive Control Register */
u32 rstat; /* 0x.304 - Receive Status Register */
u8 res12[8];
u32 rxic; /* 0x.310 - Receive Interrupt Coalescing Configuration Register */
u32 rqueue; /* 0x.314 - Receive queue control register */
u8 res13[24];
u32 rbifx; /* 0x.330 - Receive bit field extract control register */
u32 rqfar; /* 0x.334 - Receive queue filing table address register */
u32 rqfcr; /* 0x.338 - Receive queue filing table control register */
u32 rqfpr; /* 0x.33c - Receive queue filing table property register */
u32 mrblr; /* 0x.340 - Maximum Receive Buffer Length Register */
u8 res14[56];
u32 rbdbph; /* 0x.37c - Rx data buffer pointer high */
u8 res15a[4];
u32 rbptr0; /* 0x.384 - RxBD pointer for ring 0 */
u8 res15b[4];
u32 rbptr1; /* 0x.38c - RxBD pointer for ring 1 */
u8 res15c[4];
u32 rbptr2; /* 0x.394 - RxBD pointer for ring 2 */
u8 res15d[4];
u32 rbptr3; /* 0x.39c - RxBD pointer for ring 3 */
u8 res15e[4];
u32 rbptr4; /* 0x.3a4 - RxBD pointer for ring 4 */
u8 res15f[4];
u32 rbptr5; /* 0x.3ac - RxBD pointer for ring 5 */
u8 res15g[4];
u32 rbptr6; /* 0x.3b4 - RxBD pointer for ring 6 */
u8 res15h[4];
u32 rbptr7; /* 0x.3bc - RxBD pointer for ring 7 */
u8 res16[64];
u32 rbaseh; /* 0x.400 - RxBD base address high */
u32 rbase0; /* 0x.404 - RxBD base address of ring 0 */
u8 res17a[4];
u32 rbase1; /* 0x.40c - RxBD base address of ring 1 */
u8 res17b[4];
u32 rbase2; /* 0x.414 - RxBD base address of ring 2 */
u8 res17c[4];
u32 rbase3; /* 0x.41c - RxBD base address of ring 3 */
u8 res17d[4];
u32 rbase4; /* 0x.424 - RxBD base address of ring 4 */
u8 res17e[4];
u32 rbase5; /* 0x.42c - RxBD base address of ring 5 */
u8 res17f[4];
u32 rbase6; /* 0x.434 - RxBD base address of ring 6 */
u8 res17g[4];
u32 rbase7; /* 0x.43c - RxBD base address of ring 7 */
u8 res17[192];
u32 maccfg1; /* 0x.500 - MAC Configuration 1 Register */
u32 maccfg2; /* 0x.504 - MAC Configuration 2 Register */
u32 ipgifg; /* 0x.508 - Inter Packet Gap/Inter Frame Gap Register */
u32 hafdup; /* 0x.50c - Half Duplex Register */
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
u8 res18[12]; u8 res18[12];
u32 miimcfg; /* 0x.520 - MII Management Configuration Register */ u32 miimcfg; /* 0x.520 - MII Management Configuration Register */
u32 miimcom; /* 0x.524 - MII Management Command Register */ u32 miimcom; /* 0x.524 - MII Management Command Register */
u32 miimadd; /* 0x.528 - MII Management Address Register */ u32 miimadd; /* 0x.528 - MII Management Address Register */
u32 miimcon; /* 0x.52c - MII Management Control Register */ u32 miimcon; /* 0x.52c - MII Management Control Register */
u32 miimstat; /* 0x.530 - MII Management Status Register */ u32 miimstat; /* 0x.530 - MII Management Status Register */
u32 miimind; /* 0x.534 - MII Management Indicator Register */ u32 miimind; /* 0x.534 - MII Management Indicator Register */
u8 res19[4]; u8 res19[4];
u32 ifstat; /* 0x.53c - Interface Status Register */ u32 ifstat; /* 0x.53c - Interface Status Register */
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */ u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
u32 macstnaddr2; /* 0x.544 - Station Address Part 2 Register */ u32 macstnaddr2; /* 0x.544 - Station Address Part 2 Register */
u8 res20[312]; u32 mac01addr1; /* 0x.548 - MAC exact match address 1, part 1 */
struct rmon_mib rmon; u32 mac01addr2; /* 0x.54c - MAC exact match address 1, part 2 */
u8 res21[192]; u32 mac02addr1; /* 0x.550 - MAC exact match address 2, part 1 */
u32 iaddr0; /* 0x.800 - Indivdual address register 0 */ u32 mac02addr2; /* 0x.554 - MAC exact match address 2, part 2 */
u32 iaddr1; /* 0x.804 - Indivdual address register 1 */ u32 mac03addr1; /* 0x.558 - MAC exact match address 3, part 1 */
u32 iaddr2; /* 0x.808 - Indivdual address register 2 */ u32 mac03addr2; /* 0x.55c - MAC exact match address 3, part 2 */
u32 iaddr3; /* 0x.80c - Indivdual address register 3 */ u32 mac04addr1; /* 0x.560 - MAC exact match address 4, part 1 */
u32 iaddr4; /* 0x.810 - Indivdual address register 4 */ u32 mac04addr2; /* 0x.564 - MAC exact match address 4, part 2 */
u32 iaddr5; /* 0x.814 - Indivdual address register 5 */ u32 mac05addr1; /* 0x.568 - MAC exact match address 5, part 1 */
u32 iaddr6; /* 0x.818 - Indivdual address register 6 */ u32 mac05addr2; /* 0x.56c - MAC exact match address 5, part 2 */
u32 iaddr7; /* 0x.81c - Indivdual address register 7 */ u32 mac06addr1; /* 0x.570 - MAC exact match address 6, part 1 */
u32 mac06addr2; /* 0x.574 - MAC exact match address 6, part 2 */
u32 mac07addr1; /* 0x.578 - MAC exact match address 7, part 1 */
u32 mac07addr2; /* 0x.57c - MAC exact match address 7, part 2 */
u32 mac08addr1; /* 0x.580 - MAC exact match address 8, part 1 */
u32 mac08addr2; /* 0x.584 - MAC exact match address 8, part 2 */
u32 mac09addr1; /* 0x.588 - MAC exact match address 9, part 1 */
u32 mac09addr2; /* 0x.58c - MAC exact match address 9, part 2 */
u32 mac10addr1; /* 0x.590 - MAC exact match address 10, part 1*/
u32 mac10addr2; /* 0x.594 - MAC exact match address 10, part 2*/
u32 mac11addr1; /* 0x.598 - MAC exact match address 11, part 1*/
u32 mac11addr2; /* 0x.59c - MAC exact match address 11, part 2*/
u32 mac12addr1; /* 0x.5a0 - MAC exact match address 12, part 1*/
u32 mac12addr2; /* 0x.5a4 - MAC exact match address 12, part 2*/
u32 mac13addr1; /* 0x.5a8 - MAC exact match address 13, part 1*/
u32 mac13addr2; /* 0x.5ac - MAC exact match address 13, part 2*/
u32 mac14addr1; /* 0x.5b0 - MAC exact match address 14, part 1*/
u32 mac14addr2; /* 0x.5b4 - MAC exact match address 14, part 2*/
u32 mac15addr1; /* 0x.5b8 - MAC exact match address 15, part 1*/
u32 mac15addr2; /* 0x.5bc - MAC exact match address 15, part 2*/
u8 res20[192];
struct rmon_mib rmon; /* 0x.680-0x.73c */
u32 rrej; /* 0x.740 - Receive filer rejected packet counter */
u8 res21[188];
u32 igaddr0; /* 0x.800 - Indivdual/Group address register 0*/
u32 igaddr1; /* 0x.804 - Indivdual/Group address register 1*/
u32 igaddr2; /* 0x.808 - Indivdual/Group address register 2*/
u32 igaddr3; /* 0x.80c - Indivdual/Group address register 3*/
u32 igaddr4; /* 0x.810 - Indivdual/Group address register 4*/
u32 igaddr5; /* 0x.814 - Indivdual/Group address register 5*/
u32 igaddr6; /* 0x.818 - Indivdual/Group address register 6*/
u32 igaddr7; /* 0x.81c - Indivdual/Group address register 7*/
u8 res22[96]; u8 res22[96];
u32 gaddr0; /* 0x.880 - Global address register 0 */ u32 gaddr0; /* 0x.880 - Group address register 0 */
u32 gaddr1; /* 0x.884 - Global address register 1 */ u32 gaddr1; /* 0x.884 - Group address register 1 */
u32 gaddr2; /* 0x.888 - Global address register 2 */ u32 gaddr2; /* 0x.888 - Group address register 2 */
u32 gaddr3; /* 0x.88c - Global address register 3 */ u32 gaddr3; /* 0x.88c - Group address register 3 */
u32 gaddr4; /* 0x.890 - Global address register 4 */ u32 gaddr4; /* 0x.890 - Group address register 4 */
u32 gaddr5; /* 0x.894 - Global address register 5 */ u32 gaddr5; /* 0x.894 - Group address register 5 */
u32 gaddr6; /* 0x.898 - Global address register 6 */ u32 gaddr6; /* 0x.898 - Group address register 6 */
u32 gaddr7; /* 0x.89c - Global address register 7 */ u32 gaddr7; /* 0x.89c - Group address register 7 */
u8 res23[856]; u8 res23a[352];
u32 attr; /* 0x.bf8 - Attributes Register */ u32 fifocfg; /* 0x.a00 - FIFO interface config register */
u32 attreli; /* 0x.bfc - Attributes Extract Length and Extract Index Register */ u8 res23b[252];
u8 res23c[248];
u32 attr; /* 0x.bf8 - Attributes Register */
u32 attreli; /* 0x.bfc - Attributes Extract Length and Extract Index Register */
u8 res24[1024]; u8 res24[1024];
}; };
@ -496,6 +686,8 @@ struct gfar_private {
struct txbd8 *cur_tx; /* Next free ring entry */ struct txbd8 *cur_tx; /* Next free ring entry */
struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ struct txbd8 *dirty_tx; /* The Ring entry to be freed. */
struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */ struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */
u32 *hash_regs[16];
int hash_width;
struct gfar *phyregs; struct gfar *phyregs;
struct work_struct tq; struct work_struct tq;
struct timer_list phy_info_timer; struct timer_list phy_info_timer;
@ -506,9 +698,12 @@ struct gfar_private {
unsigned int rx_stash_size; unsigned int rx_stash_size;
unsigned int tx_ring_size; unsigned int tx_ring_size;
unsigned int rx_ring_size; unsigned int rx_ring_size;
wait_queue_head_t rxcleanupq;
unsigned int rxclean;
unsigned char vlan_enable:1,
rx_csum_enable:1,
extended_hash:1;
unsigned short padding;
struct vlan_group *vlgrp;
/* Info structure initialized by board setup code */ /* Info structure initialized by board setup code */
unsigned int interruptTransmit; unsigned int interruptTransmit;
unsigned int interruptReceive; unsigned int interruptReceive;
@ -519,6 +714,8 @@ struct gfar_private {
int oldspeed; int oldspeed;
int oldduplex; int oldduplex;
int oldlink; int oldlink;
uint32_t msg_enable;
}; };
extern inline u32 gfar_read(volatile unsigned *addr) extern inline u32 gfar_read(volatile unsigned *addr)

View File

@ -46,16 +46,18 @@
extern int startup_gfar(struct net_device *dev); extern int startup_gfar(struct net_device *dev);
extern void stop_gfar(struct net_device *dev); extern void stop_gfar(struct net_device *dev);
extern void gfar_receive(int irq, void *dev_id, struct pt_regs *regs); extern void gfar_halt(struct net_device *dev);
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
u64 * buf); u64 * buf);
void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals); static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);
static char stat_gstrings[][ETH_GSTRING_LEN] = { static char stat_gstrings[][ETH_GSTRING_LEN] = {
"rx-dropped-by-kernel", "rx-dropped-by-kernel",
@ -118,57 +120,56 @@ static char stat_gstrings[][ETH_GSTRING_LEN] = {
"tx-fragmented-frames", "tx-fragmented-frames",
}; };
/* Fill in a buffer with the strings which correspond to the
* stats */
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
{
struct gfar_private *priv = netdev_priv(dev);
if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
else
memcpy(buf, stat_gstrings,
GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
}
/* Fill in an array of 64-bit statistics from various sources. /* Fill in an array of 64-bit statistics from various sources.
* This array will be appended to the end of the ethtool_stats * This array will be appended to the end of the ethtool_stats
* structure, and returned to user space * structure, and returned to user space
*/ */
void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
{ {
int i; int i;
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
u32 *rmon = (u32 *) & priv->regs->rmon;
u64 *extra = (u64 *) & priv->extra_stats; u64 *extra = (u64 *) & priv->extra_stats;
struct gfar_stats *stats = (struct gfar_stats *) buf;
for (i = 0; i < GFAR_RMON_LEN; i++) { if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
stats->rmon[i] = (u64) (rmon[i]); u32 *rmon = (u32 *) & priv->regs->rmon;
} struct gfar_stats *stats = (struct gfar_stats *) buf;
for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) { for (i = 0; i < GFAR_RMON_LEN; i++)
stats->extra[i] = extra[i]; stats->rmon[i] = (u64) (rmon[i]);
}
for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
stats->extra[i] = extra[i];
} else
for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
buf[i] = extra[i];
} }
/* Returns the number of stats (and their corresponding strings) */ /* Returns the number of stats (and their corresponding strings) */
int gfar_stats_count(struct net_device *dev) static int gfar_stats_count(struct net_device *dev)
{ {
return GFAR_STATS_LEN;
}
void gfar_gstrings_normon(struct net_device *dev, u32 stringset, u8 * buf)
{
memcpy(buf, stat_gstrings, GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
}
void gfar_fill_stats_normon(struct net_device *dev,
struct ethtool_stats *dummy, u64 * buf)
{
int i;
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
u64 *extra = (u64 *) & priv->extra_stats;
for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) { if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
buf[i] = extra[i]; return GFAR_STATS_LEN;
} else
return GFAR_EXTRA_STATS_LEN;
} }
int gfar_stats_count_normon(struct net_device *dev)
{
return GFAR_EXTRA_STATS_LEN;
}
/* Fills in the drvinfo structure with some basic info */ /* Fills in the drvinfo structure with some basic info */
void gfar_gdrvinfo(struct net_device *dev, struct static void gfar_gdrvinfo(struct net_device *dev, struct
ethtool_drvinfo *drvinfo) ethtool_drvinfo *drvinfo)
{ {
strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN);
@ -182,7 +183,7 @@ void gfar_gdrvinfo(struct net_device *dev, struct
} }
/* Return the current settings in the ethtool_cmd structure */ /* Return the current settings in the ethtool_cmd structure */
int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
uint gigabit_support = uint gigabit_support =
@ -216,13 +217,13 @@ int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
} }
/* Return the length of the register structure */ /* Return the length of the register structure */
int gfar_reglen(struct net_device *dev) static int gfar_reglen(struct net_device *dev)
{ {
return sizeof (struct gfar); return sizeof (struct gfar);
} }
/* Return a dump of the GFAR register space */ /* Return a dump of the GFAR register space */
void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{ {
int i; int i;
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
@ -233,13 +234,6 @@ void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regb
buf[i] = theregs[i]; buf[i] = theregs[i];
} }
/* Fill in a buffer with the strings which correspond to the
* stats */
void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
{
memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
}
/* Convert microseconds to ethernet clock ticks, which changes /* Convert microseconds to ethernet clock ticks, which changes
* depending on what speed the controller is running at */ * depending on what speed the controller is running at */
static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs) static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs)
@ -291,9 +285,12 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
/* Get the coalescing parameters, and put them in the cvals /* Get the coalescing parameters, and put them in the cvals
* structure. */ * structure. */
int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
cvals->rx_max_coalesced_frames = priv->rxcount; cvals->rx_max_coalesced_frames = priv->rxcount;
@ -337,10 +334,13 @@ int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
* Both cvals->*_usecs and cvals->*_frames have to be > 0 * Both cvals->*_usecs and cvals->*_frames have to be > 0
* in order for coalescing to be active * in order for coalescing to be active
*/ */
int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
return -EOPNOTSUPP;
/* Set up rx coalescing */ /* Set up rx coalescing */
if ((cvals->rx_coalesce_usecs == 0) || if ((cvals->rx_coalesce_usecs == 0) ||
(cvals->rx_max_coalesced_frames == 0)) (cvals->rx_max_coalesced_frames == 0))
@ -379,7 +379,7 @@ int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
/* Fills in rvals with the current ring parameters. Currently, /* Fills in rvals with the current ring parameters. Currently,
* rx, rx_mini, and rx_jumbo rings are the same size, as mini and * rx, rx_mini, and rx_jumbo rings are the same size, as mini and
* jumbo are ignored by the driver */ * jumbo are ignored by the driver */
void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
@ -401,9 +401,8 @@ void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
* necessary so that we don't mess things up while we're in * necessary so that we don't mess things up while we're in
* motion. We wait for the ring to be clean before reallocating * motion. We wait for the ring to be clean before reallocating
* the rings. */ * the rings. */
int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
{ {
u32 tempval;
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
int err = 0; int err = 0;
@ -425,44 +424,116 @@ int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
return -EINVAL; return -EINVAL;
} }
/* Stop the controller so we don't rx any more frames */
/* But first, make sure we clear the bits */
tempval = gfar_read(&priv->regs->dmactrl);
tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
gfar_write(&priv->regs->dmactrl, tempval);
tempval = gfar_read(&priv->regs->dmactrl);
tempval |= (DMACTRL_GRS | DMACTRL_GTS);
gfar_write(&priv->regs->dmactrl, tempval);
while (!(gfar_read(&priv->regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC)))
cpu_relax();
/* Note that rx is not clean right now */
priv->rxclean = 0;
if (dev->flags & IFF_UP) { if (dev->flags & IFF_UP) {
/* Tell the driver to process the rest of the frames */ unsigned long flags;
gfar_receive(0, (void *) dev, NULL);
/* Now wait for it to be done */ /* Halt TX and RX, and process the frames which
wait_event_interruptible(priv->rxcleanupq, priv->rxclean); * have already been received */
spin_lock_irqsave(&priv->lock, flags);
/* Ok, all packets have been handled. Now we bring it down, gfar_halt(dev);
* change the ring size, and bring it up */ gfar_clean_rx_ring(dev, priv->rx_ring_size);
spin_unlock_irqrestore(&priv->lock, flags);
/* Now we take down the rings to rebuild them */
stop_gfar(dev); stop_gfar(dev);
} }
/* Change the size */
priv->rx_ring_size = rvals->rx_pending; priv->rx_ring_size = rvals->rx_pending;
priv->tx_ring_size = rvals->tx_pending; priv->tx_ring_size = rvals->tx_pending;
/* Rebuild the rings with the new size */
if (dev->flags & IFF_UP)
err = startup_gfar(dev);
return err;
}
static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
{
struct gfar_private *priv = netdev_priv(dev);
int err = 0;
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
return -EOPNOTSUPP;
if (dev->flags & IFF_UP) {
unsigned long flags;
/* Halt TX and RX, and process the frames which
* have already been received */
spin_lock_irqsave(&priv->lock, flags);
gfar_halt(dev);
gfar_clean_rx_ring(dev, priv->rx_ring_size);
spin_unlock_irqrestore(&priv->lock, flags);
/* Now we take down the rings to rebuild them */
stop_gfar(dev);
}
priv->rx_csum_enable = data;
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP)
err = startup_gfar(dev); err = startup_gfar(dev);
return err; return err;
} }
static uint32_t gfar_get_rx_csum(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
return 0;
return priv->rx_csum_enable;
}
static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
{
unsigned long flags;
struct gfar_private *priv = netdev_priv(dev);
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
return -EOPNOTSUPP;
spin_lock_irqsave(&priv->lock, flags);
gfar_halt(dev);
if (data)
dev->features |= NETIF_F_IP_CSUM;
else
dev->features &= ~NETIF_F_IP_CSUM;
gfar_start(dev);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static uint32_t gfar_get_tx_csum(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
return 0;
return (dev->features & NETIF_F_IP_CSUM) != 0;
}
static uint32_t gfar_get_msglevel(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
return priv->msg_enable;
}
static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
{
struct gfar_private *priv = netdev_priv(dev);
priv->msg_enable = data;
}
struct ethtool_ops gfar_ethtool_ops = { struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings, .get_settings = gfar_gsettings,
.get_drvinfo = gfar_gdrvinfo, .get_drvinfo = gfar_gdrvinfo,
@ -476,52 +547,10 @@ struct ethtool_ops gfar_ethtool_ops = {
.get_strings = gfar_gstrings, .get_strings = gfar_gstrings,
.get_stats_count = gfar_stats_count, .get_stats_count = gfar_stats_count,
.get_ethtool_stats = gfar_fill_stats, .get_ethtool_stats = gfar_fill_stats,
}; .get_rx_csum = gfar_get_rx_csum,
.get_tx_csum = gfar_get_tx_csum,
struct ethtool_ops gfar_normon_nocoalesce_ethtool_ops = { .set_rx_csum = gfar_set_rx_csum,
.get_settings = gfar_gsettings, .set_tx_csum = gfar_set_tx_csum,
.get_drvinfo = gfar_gdrvinfo, .get_msglevel = gfar_get_msglevel,
.get_regs_len = gfar_reglen, .set_msglevel = gfar_set_msglevel,
.get_regs = gfar_get_regs,
.get_link = ethtool_op_get_link,
.get_ringparam = gfar_gringparam,
.set_ringparam = gfar_sringparam,
.get_strings = gfar_gstrings_normon,
.get_stats_count = gfar_stats_count_normon,
.get_ethtool_stats = gfar_fill_stats_normon,
};
struct ethtool_ops gfar_nocoalesce_ethtool_ops = {
.get_settings = gfar_gsettings,
.get_drvinfo = gfar_gdrvinfo,
.get_regs_len = gfar_reglen,
.get_regs = gfar_get_regs,
.get_link = ethtool_op_get_link,
.get_ringparam = gfar_gringparam,
.set_ringparam = gfar_sringparam,
.get_strings = gfar_gstrings,
.get_stats_count = gfar_stats_count,
.get_ethtool_stats = gfar_fill_stats,
};
struct ethtool_ops gfar_normon_ethtool_ops = {
.get_settings = gfar_gsettings,
.get_drvinfo = gfar_gdrvinfo,
.get_regs_len = gfar_reglen,
.get_regs = gfar_get_regs,
.get_link = ethtool_op_get_link,
.get_coalesce = gfar_gcoalesce,
.set_coalesce = gfar_scoalesce,
.get_ringparam = gfar_gringparam,
.set_ringparam = gfar_sringparam,
.get_strings = gfar_gstrings_normon,
.get_stats_count = gfar_stats_count_normon,
.get_ethtool_stats = gfar_fill_stats_normon,
};
struct ethtool_ops *gfar_op_array[] = {
&gfar_ethtool_ops,
&gfar_normon_ethtool_ops,
&gfar_nocoalesce_ethtool_ops,
&gfar_normon_nocoalesce_ethtool_ops
}; };

View File

@ -850,7 +850,7 @@ static int pcnet32_phys_id(struct net_device *dev, u32 data)
if ((!data) || (data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))) if ((!data) || (data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
schedule_timeout(data * HZ); msleep_interruptible(data * 1000);
del_timer_sync(&lp->blink_timer); del_timer_sync(&lp->blink_timer);
/* Restore the original value of the bcrs */ /* Restore the original value of the bcrs */

View File

@ -90,7 +90,6 @@ static int sb1000_close(struct net_device *dev);
/* SB1000 hardware routines to be used during open/configuration phases */ /* SB1000 hardware routines to be used during open/configuration phases */
static inline void nicedelay(unsigned long usecs);
static inline int card_wait_for_busy_clear(const int ioaddr[], static inline int card_wait_for_busy_clear(const int ioaddr[],
const char* name); const char* name);
static inline int card_wait_for_ready(const int ioaddr[], const char* name, static inline int card_wait_for_ready(const int ioaddr[], const char* name,
@ -254,13 +253,6 @@ static struct pnp_driver sb1000_driver = {
static const int TimeOutJiffies = (875 * HZ) / 100; static const int TimeOutJiffies = (875 * HZ) / 100;
static inline void nicedelay(unsigned long usecs)
{
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
return;
}
/* Card Wait For Busy Clear (cannot be used during an interrupt) */ /* Card Wait For Busy Clear (cannot be used during an interrupt) */
static inline int static inline int
card_wait_for_busy_clear(const int ioaddr[], const char* name) card_wait_for_busy_clear(const int ioaddr[], const char* name)
@ -475,7 +467,7 @@ sb1000_reset(const int ioaddr[], const char* name)
udelay(1000); udelay(1000);
outb(0x0, port); outb(0x0, port);
inb(port); inb(port);
nicedelay(60000); ssleep(1);
outb(0x4, port); outb(0x4, port);
inb(port); inb(port);
udelay(1000); udelay(1000);
@ -537,7 +529,7 @@ sb1000_activate(const int ioaddr[], const char* name)
const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00}; const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00};
const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00}; const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
nicedelay(50000); ssleep(1);
if ((status = card_send_command(ioaddr, name, Command0, st))) if ((status = card_send_command(ioaddr, name, Command0, st)))
return status; return status;
if ((status = card_send_command(ioaddr, name, Command1, st))) if ((status = card_send_command(ioaddr, name, Command1, st)))
@ -944,7 +936,7 @@ sb1000_open(struct net_device *dev)
/* initialize sb1000 */ /* initialize sb1000 */
if ((status = sb1000_reset(ioaddr, name))) if ((status = sb1000_reset(ioaddr, name)))
return status; return status;
nicedelay(200000); ssleep(1);
if ((status = sb1000_check_CRC(ioaddr, name))) if ((status = sb1000_check_CRC(ioaddr, name)))
return status; return status;

View File

@ -6,8 +6,8 @@ obj-$(CONFIG_SKFP) += skfp.o
skfp-objs := skfddi.o hwmtm.o fplustm.o smt.o cfm.o \ skfp-objs := skfddi.o hwmtm.o fplustm.o smt.o cfm.o \
ecm.o pcmplc.o pmf.o queue.o rmt.o \ ecm.o pcmplc.o pmf.o queue.o rmt.o \
smtdef.o smtinit.o smttimer.o srf.o smtparse.o\ smtdef.o smtinit.o smttimer.o srf.o hwt.o \
hwt.o drvfbi.o ess.o drvfbi.o ess.o
# NOTE: # NOTE:
# Compiling this driver produces some warnings (and some more are # Compiling this driver produces some warnings (and some more are

View File

@ -105,8 +105,8 @@ extern int AIX_vpdReadByte() ;
#endif #endif
/* Prototypes of local functions. */ /* Prototype of a local function. */
void smt_stop_watchdog(struct s_smc *smc); static void smt_stop_watchdog(struct s_smc *smc);
#ifdef MCA #ifdef MCA
static int read_card_id() ; static int read_card_id() ;
@ -631,7 +631,7 @@ void plc_clear_irq(struct s_smc *smc, int p)
* LED_Y_OFF just switch yellow LED off * LED_Y_OFF just switch yellow LED off
* LED_Y_ON just switch yello LED on * LED_Y_ON just switch yello LED on
*/ */
void led_indication(struct s_smc *smc, int led_event) static void led_indication(struct s_smc *smc, int led_event)
{ {
/* use smc->hw.mac_ring_is_up == TRUE /* use smc->hw.mac_ring_is_up == TRUE
* as indication for Ring Operational * as indication for Ring Operational
@ -764,122 +764,6 @@ void llc_recover_tx(struct s_smc *smc)
#endif #endif
} }
/*--------------------------- DMA init ----------------------------*/
#ifdef ISA
/*
* init DMA
*/
void init_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
/*
* set cascade mode,
* clear mask bit (enable DMA cannal)
*/
if (dma > 3) {
outp(0xd6,(dma & 0x03) | 0xc0) ;
outp(0xd4, dma & 0x03) ;
}
else {
outp(0x0b,(dma & 0x03) | 0xc0) ;
outp(0x0a,dma & 0x03) ;
}
}
/*
* disable DMA
*/
void dis_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
/*
* set mask bit (disable DMA cannal)
*/
if (dma > 3) {
outp(0xd4,(dma & 0x03) | 0x04) ;
}
else {
outp(0x0a,(dma & 0x03) | 0x04) ;
}
}
#endif /* ISA */
#ifdef EISA
/*arrays with io addresses of dma controller length and address registers*/
static const int cntr[8] = { 0x001,0x003,0x005,0x007,0,0x0c6,0x0ca,0x0ce } ;
static const int base[8] = { 0x000,0x002,0x004,0x006,0,0x0c4,0x0c8,0x0cc } ;
static const int page[8] = { 0x087,0x083,0x081,0x082,0,0x08b,0x089,0x08a } ;
void init_dma(struct s_smc *smc, int dma)
{
/*
* extended mode register
* 32 bit IO
* type c
* TC output
* disable stop
*/
/* mode read (write) demand */
smc->hw.dma_rmode = (dma & 3) | 0x08 | 0x0 ;
smc->hw.dma_wmode = (dma & 3) | 0x04 | 0x0 ;
/* 32 bit IO's, burst DMA mode (type "C") */
smc->hw.dma_emode = (dma & 3) | 0x08 | 0x30 ;
outp((dma < 4) ? 0x40b : 0x4d6,smc->hw.dma_emode) ;
/* disable chaining */
outp((dma < 4) ? 0x40a : 0x4d4,(dma&3)) ;
/*load dma controller addresses for fast access during set dma*/
smc->hw.dma_base_word_count = cntr[smc->hw.dma];
smc->hw.dma_base_address = base[smc->hw.dma];
smc->hw.dma_base_address_page = page[smc->hw.dma];
}
void dis_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
outp((dma < 4) ? 0x0a : 0xd4,(dma&3)|4) ;/* mask bit */
}
#endif /* EISA */
#ifdef MCA
void init_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
SK_UNUSED(dma) ;
}
void dis_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
SK_UNUSED(dma) ;
}
#endif
#ifdef PCI
void init_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
SK_UNUSED(dma) ;
}
void dis_dma(struct s_smc *smc, int dma)
{
SK_UNUSED(smc) ;
SK_UNUSED(dma) ;
}
#endif
#ifdef MULT_OEM #ifdef MULT_OEM
static int is_equal_num(char comp1[], char comp2[], int num) static int is_equal_num(char comp1[], char comp2[], int num)
{ {
@ -1407,7 +1291,7 @@ void smt_start_watchdog(struct s_smc *smc)
#endif /* DEBUG */ #endif /* DEBUG */
} }
void smt_stop_watchdog(struct s_smc *smc) static void smt_stop_watchdog(struct s_smc *smc)
{ {
SK_UNUSED(smc) ; /* Make LINT happy. */ SK_UNUSED(smc) ; /* Make LINT happy. */
#ifndef DEBUG #ifndef DEBUG
@ -1422,104 +1306,6 @@ void smt_stop_watchdog(struct s_smc *smc)
} }
#ifdef PCI #ifdef PCI
static char get_rom_byte(struct s_smc *smc, u_short addr)
{
GET_PAGE(addr) ;
return (READ_PROM(ADDR(B2_FDP))) ;
}
/*
* ROM image defines
*/
#define ROM_SIG_1 0
#define ROM_SIG_2 1
#define PCI_DATA_1 0x18
#define PCI_DATA_2 0x19
/*
* PCI data structure defines
*/
#define VPD_DATA_1 0x08
#define VPD_DATA_2 0x09
#define IMAGE_LEN_1 0x10
#define IMAGE_LEN_2 0x11
#define CODE_TYPE 0x14
#define INDICATOR 0x15
/*
* BEGIN_MANUAL_ENTRY(mac_drv_vpd_read)
* mac_drv_vpd_read(smc,buf,size,image)
*
* function DOWNCALL (FDDIWARE)
* reads the VPD data of the FPROM and writes it into the
* buffer
*
* para buf points to the buffer for the VPD data
* size size of the VPD data buffer
* image boot image; code type of the boot image
* image = 0 Intel x86, PC-AT compatible
* 1 OPENBOOT standard for PCI
* 2-FF reserved
*
* returns len number of VPD data bytes read form the FPROM
* <0 number of read bytes
* >0 error: data invalid
*
* END_MANUAL_ENTRY
*/
int mac_drv_vpd_read(struct s_smc *smc, char *buf, int size, char image)
{
u_short ibase ;
u_short pci_base ;
u_short vpd ;
int len ;
len = 0 ;
ibase = 0 ;
/*
* as long images defined
*/
while (get_rom_byte(smc,ibase+ROM_SIG_1) == 0x55 &&
(u_char) get_rom_byte(smc,ibase+ROM_SIG_2) == 0xaa) {
/*
* get the pointer to the PCI data structure
*/
pci_base = ibase + get_rom_byte(smc,ibase+PCI_DATA_1) +
(get_rom_byte(smc,ibase+PCI_DATA_2) << 8) ;
if (image == get_rom_byte(smc,pci_base+CODE_TYPE)) {
/*
* we have the right image, read the VPD data
*/
vpd = ibase + get_rom_byte(smc,pci_base+VPD_DATA_1) +
(get_rom_byte(smc,pci_base+VPD_DATA_2) << 8) ;
if (vpd == ibase) {
break ; /* no VPD data */
}
for (len = 0; len < size; len++,buf++,vpd++) {
*buf = get_rom_byte(smc,vpd) ;
}
break ;
}
else {
/*
* try the next image
*/
if (get_rom_byte(smc,pci_base+INDICATOR) & 0x80) {
break ; /* this was the last image */
}
ibase = ibase + get_rom_byte(smc,ibase+IMAGE_LEN_1) +
(get_rom_byte(smc,ibase+IMAGE_LEN_2) << 8) ;
}
}
return(len) ;
}
void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value)
{
smc->hw.pci_fix_value = fix_value ;
}
void mac_do_pci_fix(struct s_smc *smc) void mac_do_pci_fix(struct s_smc *smc)
{ {

View File

@ -102,7 +102,7 @@ void ess_timer_poll(struct s_smc *smc);
void ess_para_change(struct s_smc *smc); void ess_para_change(struct s_smc *smc);
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
int fs); int fs);
int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead); static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
/* /*
@ -375,7 +375,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
* determines the synchronous bandwidth, set the TSYNC register and the * determines the synchronous bandwidth, set the TSYNC register and the
* mib variables SBAPayload, SBAOverhead and fddiMACT-NEG. * mib variables SBAPayload, SBAOverhead and fddiMACT-NEG.
*/ */
int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead) static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
{ {
/* /*
* determine the synchronous bandwidth (sync_bw) in bytes per T-NEG, * determine the synchronous bandwidth (sync_bw) in bytes per T-NEG,

View File

@ -1114,30 +1114,6 @@ void mac_clear_multicast(struct s_smc *smc)
} }
} }
/*
BEGIN_MANUAL_ENTRY(if,func;others;2)
int mac_set_func_addr(smc,f_addr)
struct s_smc *smc ;
u_long f_addr ;
Function DOWNCALL (SMT, fplustm.c)
Set a Token-Ring functional address, the address will
be activated after calling mac_update_multicast()
Para f_addr functional bits in non-canonical format
Returns 0: always success
END_MANUAL_ENTRY()
*/
int mac_set_func_addr(struct s_smc *smc, u_long f_addr)
{
smc->hw.fp.func_addr = f_addr ;
return(0) ;
}
/* /*
BEGIN_MANUAL_ENTRY(if,func;others;2) BEGIN_MANUAL_ENTRY(if,func;others;2)
@ -1202,52 +1178,6 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
return(0) ; return(0) ;
} }
/*
BEGIN_MANUAL_ENTRY(if,func;others;2)
void mac_del_multicast(smc,addr,can)
struct s_smc *smc ;
struct fddi_addr *addr ;
int can ;
Function DOWNCALL (SMT, fplustm.c)
Delete an entry from the multicast table
Para addr pointer to a multicast address
can = 0: the multicast address has the physical format
= 1: the multicast address has the canonical format
| 0x80 permanent
END_MANUAL_ENTRY()
*/
void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
{
SK_LOC_DECL(struct fddi_addr,own) ;
struct s_fpmc *tb ;
if (!(tb = mac_get_mc_table(smc,addr,&own,1,can & ~0x80)))
return ;
/*
* permanent addresses must be deleted with perm bit
* and vice versa
*/
if (( tb->perm && (can & 0x80)) ||
(!tb->perm && !(can & 0x80))) {
/*
* delete it
*/
if (tb->n) {
tb->n-- ;
if (tb->perm) {
smc->hw.fp.smt_slots_used-- ;
}
else {
smc->hw.fp.os_slots_used-- ;
}
}
}
}
/* /*
* mode * mode
*/ */

View File

@ -507,7 +507,6 @@ void pcm_status_state(struct s_smc *smc, int np, int *type, int *state,
int *remote, int *mac); int *remote, int *mac);
void plc_config_mux(struct s_smc *smc, int mux); void plc_config_mux(struct s_smc *smc, int mux);
void sm_lem_evaluate(struct s_smc *smc); void sm_lem_evaluate(struct s_smc *smc);
void smt_clear_una_dna(struct s_smc *smc);
void mac_update_counter(struct s_smc *smc); void mac_update_counter(struct s_smc *smc);
void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off); void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off);
void sm_ma_control(struct s_smc *smc, int mode); void sm_ma_control(struct s_smc *smc, int mode);
@ -541,11 +540,9 @@ void smt_timer_poll(struct s_smc *smc);
u_long smt_get_time(void); u_long smt_get_time(void);
u_long smt_get_tid(struct s_smc *smc); u_long smt_get_tid(struct s_smc *smc);
void smt_timer_done(struct s_smc *smc); void smt_timer_done(struct s_smc *smc);
void smt_set_defaults(struct s_smc *smc);
void smt_fixup_mib(struct s_smc *smc); void smt_fixup_mib(struct s_smc *smc);
void smt_reset_defaults(struct s_smc *smc, int level); void smt_reset_defaults(struct s_smc *smc, int level);
void smt_agent_task(struct s_smc *smc); void smt_agent_task(struct s_smc *smc);
void smt_please_reconnect(struct s_smc *smc, int reconn_time);
int smt_check_para(struct s_smc *smc, struct smt_header *sm, int smt_check_para(struct s_smc *smc, struct smt_header *sm,
const u_short list[]); const u_short list[]);
void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr); void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr);
@ -568,7 +565,6 @@ int pcm_get_s_port(struct s_smc *smc);
int pcm_rooted_station(struct s_smc *smc); int pcm_rooted_station(struct s_smc *smc);
int cfm_get_mac_input(struct s_smc *smc); int cfm_get_mac_input(struct s_smc *smc);
int cfm_get_mac_output(struct s_smc *smc); int cfm_get_mac_output(struct s_smc *smc);
int port_to_mib(struct s_smc *smc, int p);
int cem_build_path(struct s_smc *smc, char *to, int path_index); int cem_build_path(struct s_smc *smc, char *to, int path_index);
int sm_mac_get_tx_state(struct s_smc *smc); int sm_mac_get_tx_state(struct s_smc *smc);
char *get_pcmstate(struct s_smc *smc, int np); char *get_pcmstate(struct s_smc *smc, int np);
@ -580,8 +576,6 @@ void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local);
void smt_set_timestamp(struct s_smc *smc, u_char *p); void smt_set_timestamp(struct s_smc *smc, u_char *p);
void mac_set_rx_mode(struct s_smc *smc, int mode); void mac_set_rx_mode(struct s_smc *smc, int mode);
int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can); int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
int mac_set_func_addr(struct s_smc *smc, u_long f_addr);
void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
void mac_update_multicast(struct s_smc *smc); void mac_update_multicast(struct s_smc *smc);
void mac_clear_multicast(struct s_smc *smc); void mac_clear_multicast(struct s_smc *smc);
void set_formac_tsync(struct s_smc *smc, long sync_bw); void set_formac_tsync(struct s_smc *smc, long sync_bw);
@ -599,7 +593,6 @@ void plc_irq(struct s_smc *smc, int np, unsigned int cmd);
int smt_set_mac_opvalues(struct s_smc *smc); int smt_set_mac_opvalues(struct s_smc *smc);
#ifdef TAG_MODE #ifdef TAG_MODE
void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value);
void mac_do_pci_fix(struct s_smc *smc); void mac_do_pci_fix(struct s_smc *smc);
void mac_drv_clear_tx_queue(struct s_smc *smc); void mac_drv_clear_tx_queue(struct s_smc *smc);
void mac_drv_repair_descr(struct s_smc *smc); void mac_drv_repair_descr(struct s_smc *smc);

View File

@ -261,31 +261,6 @@ struct os_debug {
#define HWM_GET_CURR_TXD(smc,queue) (struct s_smt_fp_txd volatile *)\ #define HWM_GET_CURR_TXD(smc,queue) (struct s_smt_fp_txd volatile *)\
(smc)->hw.fp.tx_q[queue].tx_curr_put (smc)->hw.fp.tx_q[queue].tx_curr_put
/*
* BEGIN_MANUAL_ENTRY(HWM_TX_CHECK)
* void HWM_TX_CHECK(smc,frame_status,low_water)
*
* function MACRO (hardware module, hwmtm.h)
* This macro is invoked by the OS-specific before it left it's
* driver_send function. This macro calls mac_drv_clear_txd
* if the free TxDs of the current transmit queue is equal or
* lower than the given low water mark.
*
* para frame_status status of the frame, see design description
* low_water low water mark of free TxD's
*
* END_MANUAL_ENTRY
*/
#ifndef HWM_NO_FLOW_CTL
#define HWM_TX_CHECK(smc,frame_status,low_water) {\
if ((low_water)>=(smc)->hw.fp.tx_q[(frame_status)&QUEUE_A0].tx_free) {\
mac_drv_clear_txd(smc) ;\
}\
}
#else
#define HWM_TX_CHECK(smc,frame_status,low_water) mac_drv_clear_txd(smc)
#endif
/* /*
* BEGIN_MANUAL_ENTRY(HWM_GET_RX_FRAG_LEN) * BEGIN_MANUAL_ENTRY(HWM_GET_RX_FRAG_LEN)
* int HWM_GET_RX_FRAG_LEN(rxd) * int HWM_GET_RX_FRAG_LEN(rxd)

View File

@ -86,6 +86,7 @@ static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue);
static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue); static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue);
static SMbuf* get_llc_rx(struct s_smc *smc); static SMbuf* get_llc_rx(struct s_smc *smc);
static SMbuf* get_txd_mb(struct s_smc *smc); static SMbuf* get_txd_mb(struct s_smc *smc);
static void mac_drv_clear_txd(struct s_smc *smc);
/* /*
------------------------------------------------------------- -------------------------------------------------------------
@ -146,7 +147,6 @@ extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
*/ */
void process_receive(struct s_smc *smc); void process_receive(struct s_smc *smc);
void fddi_isr(struct s_smc *smc); void fddi_isr(struct s_smc *smc);
void mac_drv_clear_txd(struct s_smc *smc);
void smt_free_mbuf(struct s_smc *smc, SMbuf *mb); void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
void init_driver_fplus(struct s_smc *smc); void init_driver_fplus(struct s_smc *smc);
void mac_drv_rx_mode(struct s_smc *smc, int mode); void mac_drv_rx_mode(struct s_smc *smc, int mode);
@ -158,7 +158,6 @@ void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len, void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
int frame_status); int frame_status);
int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len);
int mac_drv_init(struct s_smc *smc); int mac_drv_init(struct s_smc *smc);
int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len, int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
int frame_status); int frame_status);
@ -1448,35 +1447,6 @@ void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
NDD_TRACE("RHfE",r,AIX_REVERSE(r->rxd_rbadr),0) ; NDD_TRACE("RHfE",r,AIX_REVERSE(r->rxd_rbadr),0) ;
} }
#ifndef NDIS_OS2
/*
* BEGIN_MANUAL_ENTRY(mac_drv_rx_frag)
* int mac_drv_rx_frag(smc,virt,len)
*
* function DOWNCALL (hwmtm.c)
* mac_drv_rx_frag fills the fragment with a part of the frame.
*
* para virt the virtual address of the fragment
* len the length in bytes of the fragment
*
* return 0: success code, no errors possible
*
* END_MANUAL_ENTRY
*/
int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len)
{
NDD_TRACE("RHSB",virt,len,smc->os.hwm.r.mb_pos) ;
DB_RX("receive from queue: len/virt: = %d/%x",len,virt,4) ;
memcpy((char far *)virt,smc->os.hwm.r.mb_pos,len) ;
smc->os.hwm.r.mb_pos += len ;
NDD_TRACE("RHSE",smc->os.hwm.r.mb_pos,0,0) ;
return(0) ;
}
#endif
/* /*
* BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue) * BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue)
* *
@ -1978,7 +1948,7 @@ void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc)
* *
* END_MANUAL_ENTRY * END_MANUAL_ENTRY
*/ */
void mac_drv_clear_txd(struct s_smc *smc) static void mac_drv_clear_txd(struct s_smc *smc)
{ {
struct s_smt_tx_queue *queue ; struct s_smt_tx_queue *queue ;
struct s_smt_fp_txd volatile *t1 ; struct s_smt_fp_txd volatile *t1 ;

View File

@ -1861,13 +1861,6 @@ void plc_irq(struct s_smc *smc, int np, unsigned int cmd)
#endif #endif
} }
void pcm_set_lct_short(struct s_smc *smc, int n)
{
if (n <= 0 || n > 1000)
return ;
smc->s.lct_short = n ;
}
#ifdef DEBUG #ifdef DEBUG
/* /*
* fill state struct * fill state struct

View File

@ -36,12 +36,13 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm);
static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm); static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm);
static const struct s_p_tab* smt_get_ptab(u_short para); static const struct s_p_tab* smt_get_ptab(u_short para);
static int smt_mib_phys(struct s_smc *smc); static int smt_mib_phys(struct s_smc *smc);
int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local, static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
int set); int local, int set);
void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
int index, int local); int index, int local);
static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
int set, int local); int set, int local);
static int port_to_mib(struct s_smc *smc, int p);
#define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e)) #define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e))
#define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e)) #define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e))
@ -1078,8 +1079,8 @@ wrong_error:
/* /*
* set parameter * set parameter
*/ */
int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local, static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
int set) int local, int set)
{ {
#define IFSET(x) if (set) (x) #define IFSET(x) if (set) (x)
@ -1549,7 +1550,7 @@ static int smt_mib_phys(struct s_smc *smc)
#endif #endif
} }
int port_to_mib(struct s_smc *smc, int p) static int port_to_mib(struct s_smc *smc, int p)
{ {
#ifdef CONCENTRATOR #ifdef CONCENTRATOR
SK_UNUSED(smc) ; SK_UNUSED(smc) ;

View File

@ -149,7 +149,6 @@ extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys,
extern void mac_drv_rx_mode(struct s_smc *smc, int mode); extern void mac_drv_rx_mode(struct s_smc *smc, int mode);
extern void mac_drv_clear_rx_queue(struct s_smc *smc); extern void mac_drv_clear_rx_queue(struct s_smc *smc);
extern void enable_tx_irq(struct s_smc *smc, u_short queue); extern void enable_tx_irq(struct s_smc *smc, u_short queue);
extern void mac_drv_clear_txd(struct s_smc *smc);
static struct pci_device_id skfddi_pci_tbl[] = { static struct pci_device_id skfddi_pci_tbl[] = {
{ PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },

View File

@ -110,7 +110,7 @@ static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount
static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed, static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
int len); int len);
void smt_clear_una_dna(struct s_smc *smc); static void smt_clear_una_dna(struct s_smc *smc);
static void smt_clear_old_una_dna(struct s_smc *smc); static void smt_clear_old_una_dna(struct s_smc *smc);
#ifdef CONCENTRATOR #ifdef CONCENTRATOR
static int entity_to_index(void); static int entity_to_index(void);
@ -118,7 +118,7 @@ static int entity_to_index(void);
static void update_dac(struct s_smc *smc, int report); static void update_dac(struct s_smc *smc, int report);
static int div_ratio(u_long upper, u_long lower); static int div_ratio(u_long upper, u_long lower);
#ifdef USE_CAN_ADDR #ifdef USE_CAN_ADDR
void hwm_conv_can(struct s_smc *smc, char *data, int len); static void hwm_conv_can(struct s_smc *smc, char *data, int len);
#else #else
#define hwm_conv_can(smc,data,len) #define hwm_conv_can(smc,data,len)
#endif #endif
@ -216,24 +216,6 @@ void smt_agent_task(struct s_smc *smc)
DB_SMT("SMT agent task\n",0,0) ; DB_SMT("SMT agent task\n",0,0) ;
} }
void smt_please_reconnect(struct s_smc *smc, int reconn_time)
/* struct s_smc *smc; Pointer to SMT context */
/* int reconn_time; Wait for reconnect time in seconds */
{
/*
* The please reconnect variable is used as a timer.
* It is decremented each time smt_event is called.
* This happens every second or when smt_force_irq is called.
* Note: smt_force_irq () is called on some packet receives and
* when a multicast address is changed. Since nothing
* is received during the disconnect and the multicast
* address changes can be viewed as not very often and
* the timer runs out close to its given value
* (reconn_time).
*/
smc->sm.please_reconnect = reconn_time ;
}
#ifndef SMT_REAL_TOKEN_CT #ifndef SMT_REAL_TOKEN_CT
void smt_emulate_token_ct(struct s_smc *smc, int mac_index) void smt_emulate_token_ct(struct s_smc *smc, int mac_index)
{ {
@ -1574,7 +1556,7 @@ static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long see
* clear DNA and UNA * clear DNA and UNA
* called from CFM if configuration changes * called from CFM if configuration changes
*/ */
void smt_clear_una_dna(struct s_smc *smc) static void smt_clear_una_dna(struct s_smc *smc)
{ {
smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
@ -2057,31 +2039,11 @@ int smt_action(struct s_smc *smc, int class, int code, int index)
return(0) ; return(0) ;
} }
/*
* change tneg
* set T_Req in MIB (Path Attribute)
* calculate new values for MAC
* if change required
* disconnect
* set reconnect
* end
*/
void smt_change_t_neg(struct s_smc *smc, u_long tneg)
{
smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ;
if (smt_set_mac_opvalues(smc)) {
RS_SET(smc,RS_EVENT) ;
smc->sm.please_reconnect = 1 ;
queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
}
}
/* /*
* canonical conversion of <len> bytes beginning form *data * canonical conversion of <len> bytes beginning form *data
*/ */
#ifdef USE_CAN_ADDR #ifdef USE_CAN_ADDR
void hwm_conv_can(struct s_smc *smc, char *data, int len) static void hwm_conv_can(struct s_smc *smc, char *data, int len)
{ {
int i ; int i ;

View File

@ -76,11 +76,6 @@ void smt_reset_defaults(struct s_smc *smc, int level);
static void smt_init_mib(struct s_smc *smc, int level); static void smt_init_mib(struct s_smc *smc, int level);
static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper); static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper);
void smt_set_defaults(struct s_smc *smc)
{
smt_reset_defaults(smc,0) ;
}
#define MS2BCLK(x) ((x)*12500L) #define MS2BCLK(x) ((x)*12500L)
#define US2BCLK(x) ((x)*1250L) #define US2BCLK(x) ((x)*1250L)

View File

@ -1,467 +0,0 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* See the file "skfddi.c" for further information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The information in this file is provided "AS IS" without warranty.
*
******************************************************************************/
/*
parser for SMT parameters
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/smt_p.h"
#define KERNEL
#include "h/smtstate.h"
#ifndef lint
static const char ID_sccs[] = "@(#)smtparse.c 1.12 98/10/06 (C) SK " ;
#endif
#ifdef sun
#define _far
#endif
/*
* convert to BCLK units
*/
#define MS2BCLK(x) ((x)*12500L)
#define US2BCLK(x) ((x/10)*125L)
/*
* parameter table
*/
static struct s_ptab {
char *pt_name ;
u_short pt_num ;
u_short pt_type ;
u_long pt_min ;
u_long pt_max ;
} ptab[] = {
{ "PMFPASSWD",0, 0 } ,
{ "USERDATA",1, 0 } ,
{ "LERCUTOFFA",2, 1, 4, 15 } ,
{ "LERCUTOFFB",3, 1, 4, 15 } ,
{ "LERALARMA",4, 1, 4, 15 } ,
{ "LERALARMB",5, 1, 4, 15 } ,
{ "TMAX",6, 1, 5, 165 } ,
{ "TMIN",7, 1, 5, 165 } ,
{ "TREQ",8, 1, 5, 165 } ,
{ "TVX",9, 1, 2500, 10000 } ,
#ifdef ESS
{ "SBAPAYLOAD",10, 1, 0, 1562 } ,
{ "SBAOVERHEAD",11, 1, 50, 5000 } ,
{ "MAXTNEG",12, 1, 5, 165 } ,
{ "MINSEGMENTSIZE",13, 1, 0, 4478 } ,
{ "SBACATEGORY",14, 1, 0, 0xffff } ,
{ "SYNCHTXMODE",15, 0 } ,
#endif
#ifdef SBA
{ "SBACOMMAND",16, 0 } ,
{ "SBAAVAILABLE",17, 1, 0, 100 } ,
#endif
{ NULL }
} ;
/* Define maximum string size for values and keybuffer */
#define MAX_VAL 40
/*
* local function declarations
*/
static u_long parse_num(int type, char _far *value, char *v, u_long mn,
u_long mx, int scale);
static int parse_word(char *buf, char _far *text);
#ifdef SIM
#define DB_MAIN(a,b,c) printf(a,b,c)
#else
#define DB_MAIN(a,b,c)
#endif
/*
* BEGIN_MANUAL_ENTRY()
*
* int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
char _far *value)
*
* parse SMT parameter
* *keyword
* pointer to keyword, must be \0, \n or \r terminated
* *value pointer to value, either char * or u_long *
* if char *
* pointer to value, must be \0, \n or \r terminated
* if u_long *
* contains binary value
*
* type 0: integer
* 1: string
* return
* 0 parameter parsed ok
* != 0 error
* NOTE:
* function can be called with DS != SS
*
*
* END_MANUAL_ENTRY()
*/
int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type,
char _far *value)
{
char keybuf[MAX_VAL+1];
char valbuf[MAX_VAL+1];
char c ;
char *p ;
char *v ;
char *d ;
u_long val = 0 ;
struct s_ptab *pt ;
int st ;
int i ;
/*
* parse keyword
*/
if ((st = parse_word(keybuf,keyword)))
return(st) ;
/*
* parse value if given as string
*/
if (type == 1) {
if ((st = parse_word(valbuf,value)))
return(st) ;
}
/*
* search in table
*/
st = 0 ;
for (pt = ptab ; (v = pt->pt_name) ; pt++) {
for (p = keybuf ; (c = *p) ; p++,v++) {
if (c != *v)
break ;
}
if (!c && !*v)
break ;
}
if (!v)
return(-1) ;
#if 0
printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
#endif
/*
* set value in MIB
*/
if (pt->pt_type)
val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
switch (pt->pt_num) {
case 0 :
v = valbuf ;
d = (char *) smc->mib.fddiPRPMFPasswd ;
for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
*d++ = *v++ ;
DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
break ;
case 1 :
v = valbuf ;
d = (char *) smc->mib.fddiSMTUserData ;
for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
*d++ = *v++ ;
DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
break ;
case 2 :
smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
break ;
case 3 :
smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
break ;
case 4 :
smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
break ;
case 5 :
smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
break ;
case 6 : /* TMAX */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
(u_long) -MS2BCLK((long)val) ;
break ;
case 7 : /* TMIN */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.m[MAC0].fddiMACT_Min =
(u_long) -MS2BCLK((long)val) ;
break ;
case 8 : /* TREQ */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHMaxT_Req =
(u_long) -MS2BCLK((long)val) ;
break ;
case 9 : /* TVX */
DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHTVXLowerBound =
(u_long) -US2BCLK((long)val) ;
break ;
#ifdef ESS
case 10 : /* SBAPAYLOAD */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
if (smc->mib.fddiESSPayload != val) {
smc->ess.raf_act_timer_poll = TRUE ;
smc->mib.fddiESSPayload = val ;
}
break ;
case 11 : /* SBAOVERHEAD */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSOverhead = val ;
break ;
case 12 : /* MAXTNEG */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
break ;
case 13 : /* MINSEGMENTSIZE */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSMinSegmentSize = val ;
break ;
case 14 : /* SBACATEGORY */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSCategory =
(smc->mib.fddiESSCategory & 0xffff) |
((u_long)(val << 16)) ;
break ;
case 15 : /* SYNCHTXMODE */
/* do not use memcmp(valbuf,"ALL",3) because DS != SS */
if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
smc->mib.fddiESSSynchTxMode = TRUE ;
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
}
/* if (!memcmp(valbuf,"SPLIT",5)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
valbuf[3] == 'I' && valbuf[4] == 'T') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiESSSynchTxMode = FALSE ;
}
break ;
#endif
#ifdef SBA
case 16 : /* SBACOMMAND */
/* if (!memcmp(valbuf,"START",5)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
valbuf[3] == 'R' && valbuf[4] == 'T') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiSBACommand = SB_START ;
}
/* if (!memcmp(valbuf,"STOP",4)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
valbuf[3] == 'P') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiSBACommand = SB_STOP ;
}
break ;
case 17 : /* SBAAVAILABLE */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiSBAAvailable = (u_char) val ;
break ;
#endif
}
return(0) ;
}
static int parse_word(char *buf, char _far *text)
{
char c ;
char *p ;
int p_len ;
int quote ;
int i ;
int ok ;
/*
* skip leading white space
*/
p = buf ;
for (i = 0 ; i < MAX_VAL ; i++)
*p++ = 0 ;
p = buf ;
p_len = 0 ;
ok = 0 ;
while ( (c = *text++) && (c != '\n') && (c != '\r')) {
if ((c != ' ') && (c != '\t')) {
ok = 1 ;
break ;
}
}
if (!ok)
return(-1) ;
if (c == '"') {
quote = 1 ;
}
else {
quote = 0 ;
text-- ;
}
/*
* parse valbuf
*/
ok = 0 ;
while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
&& (c != '\r')) {
switch (quote) {
case 0 :
if ((c == ' ') || (c == '\t') || (c == '=')) {
ok = 1 ;
break ;
}
*p++ = c ;
p_len++ ;
break ;
case 2 :
*p++ = c ;
p_len++ ;
quote = 1 ;
break ;
case 1 :
switch (c) {
case '"' :
ok = 1 ;
break ;
case '\\' :
quote = 2 ;
break ;
default :
*p++ = c ;
p_len++ ;
}
}
}
*p++ = 0 ;
for (p = buf ; (c = *p) ; p++) {
if (c >= 'a' && c <= 'z')
*p = c + 'A' - 'a' ;
}
return(0) ;
}
static u_long parse_num(int type, char _far *value, char *v, u_long mn,
u_long mx, int scale)
{
u_long x = 0 ;
char c ;
if (type == 0) { /* integer */
u_long _far *l ;
u_long u1 ;
l = (u_long _far *) value ;
u1 = *l ;
/*
* if the value is negative take the lower limit
*/
if ((long)u1 < 0) {
if (- ((long)u1) > (long) mx) {
u1 = 0 ;
}
else {
u1 = (u_long) - ((long)u1) ;
}
}
x = u1 ;
}
else { /* string */
int sign = 0 ;
if (*v == '-') {
sign = 1 ;
}
while ((c = *v++) && (c >= '0') && (c <= '9')) {
x = x * 10 + c - '0' ;
}
if (scale == 10) {
x *= 10 ;
if (c == '.') {
if ((c = *v++) && (c >= '0') && (c <= '9')) {
x += c - '0' ;
}
}
}
if (sign)
x = (u_long) - ((long)x) ;
}
/*
* if the value is negative
* and the absolute value is outside the limits
* take the lower limit
* else
* take the absoute value
*/
if ((long)x < 0) {
if (- ((long)x) > (long) mx) {
x = 0 ;
}
else {
x = (u_long) - ((long)x) ;
}
}
if (x < mn)
return(mn) ;
else if (x > mx)
return(mx) ;
return(x) ;
}
#if 0
struct s_smc SMC ;
main()
{
char *p ;
char *v ;
char buf[100] ;
int toggle = 0 ;
while (gets(buf)) {
p = buf ;
while (*p && ((*p == ' ') || (*p == '\t')))
p++ ;
while (*p && ((*p != ' ') && (*p != '\t')))
p++ ;
v = p ;
while (*v && ((*v == ' ') || (*v == '\t')))
v++ ;
if ((*v >= '0') && (*v <= '9')) {
toggle = !toggle ;
if (toggle) {
u_long l ;
l = atol(v) ;
smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
}
else
smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
}
else {
smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
}
}
exit(0) ;
}
#endif

View File

@ -315,15 +315,25 @@ static void smc_reset(struct net_device *dev)
struct smc_local *lp = netdev_priv(dev); struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base; void __iomem *ioaddr = lp->base;
unsigned int ctl, cfg; unsigned int ctl, cfg;
struct sk_buff *pending_skb;
DBG(2, "%s: %s\n", dev->name, __FUNCTION__); DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
/* Disable all interrupts */ /* Disable all interrupts, block TX tasklet */
spin_lock(&lp->lock); spin_lock(&lp->lock);
SMC_SELECT_BANK(2); SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0); SMC_SET_INT_MASK(0);
pending_skb = lp->pending_tx_skb;
lp->pending_tx_skb = NULL;
spin_unlock(&lp->lock); spin_unlock(&lp->lock);
/* free any pending tx skb */
if (pending_skb) {
dev_kfree_skb(pending_skb);
lp->stats.tx_errors++;
lp->stats.tx_aborted_errors++;
}
/* /*
* This resets the registers mostly to defaults, but doesn't * This resets the registers mostly to defaults, but doesn't
* affect EEPROM. That seems unnecessary * affect EEPROM. That seems unnecessary
@ -389,14 +399,6 @@ static void smc_reset(struct net_device *dev)
SMC_SELECT_BANK(2); SMC_SELECT_BANK(2);
SMC_SET_MMU_CMD(MC_RESET); SMC_SET_MMU_CMD(MC_RESET);
SMC_WAIT_MMU_BUSY(); SMC_WAIT_MMU_BUSY();
/* clear anything saved */
if (lp->pending_tx_skb != NULL) {
dev_kfree_skb (lp->pending_tx_skb);
lp->pending_tx_skb = NULL;
lp->stats.tx_errors++;
lp->stats.tx_aborted_errors++;
}
} }
/* /*
@ -440,6 +442,7 @@ static void smc_shutdown(struct net_device *dev)
{ {
struct smc_local *lp = netdev_priv(dev); struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base; void __iomem *ioaddr = lp->base;
struct sk_buff *pending_skb;
DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
@ -447,7 +450,11 @@ static void smc_shutdown(struct net_device *dev)
spin_lock(&lp->lock); spin_lock(&lp->lock);
SMC_SELECT_BANK(2); SMC_SELECT_BANK(2);
SMC_SET_INT_MASK(0); SMC_SET_INT_MASK(0);
pending_skb = lp->pending_tx_skb;
lp->pending_tx_skb = NULL;
spin_unlock(&lp->lock); spin_unlock(&lp->lock);
if (pending_skb)
dev_kfree_skb(pending_skb);
/* and tell the card to stay away from that nasty outside world */ /* and tell the card to stay away from that nasty outside world */
SMC_SELECT_BANK(0); SMC_SELECT_BANK(0);
@ -627,7 +634,12 @@ static void smc_hardware_send_pkt(unsigned long data)
} }
skb = lp->pending_tx_skb; skb = lp->pending_tx_skb;
if (unlikely(!skb)) {
smc_special_unlock(&lp->lock);
return;
}
lp->pending_tx_skb = NULL; lp->pending_tx_skb = NULL;
packet_no = SMC_GET_AR(); packet_no = SMC_GET_AR();
if (unlikely(packet_no & AR_FAILED)) { if (unlikely(packet_no & AR_FAILED)) {
printk("%s: Memory allocation failed.\n", dev->name); printk("%s: Memory allocation failed.\n", dev->name);
@ -702,7 +714,6 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(3, "%s: %s\n", dev->name, __FUNCTION__); DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
BUG_ON(lp->pending_tx_skb != NULL); BUG_ON(lp->pending_tx_skb != NULL);
lp->pending_tx_skb = skb;
/* /*
* The MMU wants the number of pages to be the number of 256 bytes * The MMU wants the number of pages to be the number of 256 bytes
@ -718,7 +729,6 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
numPages = ((skb->len & ~1) + (6 - 1)) >> 8; numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
if (unlikely(numPages > 7)) { if (unlikely(numPages > 7)) {
printk("%s: Far too big packet error.\n", dev->name); printk("%s: Far too big packet error.\n", dev->name);
lp->pending_tx_skb = NULL;
lp->stats.tx_errors++; lp->stats.tx_errors++;
lp->stats.tx_dropped++; lp->stats.tx_dropped++;
dev_kfree_skb(skb); dev_kfree_skb(skb);
@ -745,6 +755,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
smc_special_unlock(&lp->lock); smc_special_unlock(&lp->lock);
lp->pending_tx_skb = skb;
if (!poll_count) { if (!poll_count) {
/* oh well, wait until the chip finds memory later */ /* oh well, wait until the chip finds memory later */
netif_stop_queue(dev); netif_stop_queue(dev);
@ -1062,7 +1073,7 @@ static void smc_phy_powerdown(struct net_device *dev)
above). linkwatch_event() also wants the netlink semaphore. above). linkwatch_event() also wants the netlink semaphore.
*/ */
while(lp->work_pending) while(lp->work_pending)
schedule(); yield();
bmcr = smc_phy_read(dev, phy, MII_BMCR); bmcr = smc_phy_read(dev, phy, MII_BMCR);
smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
@ -1606,14 +1617,8 @@ static int smc_close(struct net_device *dev)
/* clear everything */ /* clear everything */
smc_shutdown(dev); smc_shutdown(dev);
tasklet_kill(&lp->tx_task);
smc_phy_powerdown(dev); smc_phy_powerdown(dev);
if (lp->pending_tx_skb) {
dev_kfree_skb(lp->pending_tx_skb);
lp->pending_tx_skb = NULL;
}
return 0; return 0;
} }

View File

@ -455,8 +455,7 @@ static int streamer_reset(struct net_device *dev)
writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL); writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL);
t = jiffies; t = jiffies;
/* Hold soft reset bit for a while */ /* Hold soft reset bit for a while */
current->state = TASK_UNINTERRUPTIBLE; ssleep(1);
schedule_timeout(HZ);
writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET, writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET,
streamer_mmio + BCTL); streamer_mmio + BCTL);
@ -512,8 +511,7 @@ static int streamer_reset(struct net_device *dev)
writew(SISR_MI, streamer_mmio + SISR_MASK_SUM); writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) {
current->state = TASK_INTERRUPTIBLE; msleep_interruptible(100);
schedule_timeout(HZ/10);
if (jiffies - t > 40 * HZ) { if (jiffies - t > 40 * HZ) {
printk(KERN_ERR printk(KERN_ERR
"IBM PCI tokenring card not responding\n"); "IBM PCI tokenring card not responding\n");

View File

@ -242,6 +242,7 @@ static struct pci_device_id tulip_pci_tbl[] = {
{ 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */ { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */
{ 0x10b9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */ { 0x10b9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */
{ 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
{ 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
{ } /* terminate list */ { } /* terminate list */
}; };
MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@ -1756,11 +1757,19 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
if (dev && netif_running (dev) && netif_device_present (dev)) { if (!dev)
netif_device_detach (dev); return -EINVAL;
tulip_down (dev);
/* pci_power_off(pdev, -1); */ if (netif_running(dev))
} tulip_down(dev);
netif_device_detach(dev);
free_irq(dev->irq, dev);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0; return 0;
} }
@ -1768,15 +1777,26 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
static int tulip_resume(struct pci_dev *pdev) static int tulip_resume(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);
int retval;
if (dev && netif_running (dev) && !netif_device_present (dev)) { if (!dev)
#if 1 return -EINVAL;
pci_enable_device (pdev);
#endif pci_set_power_state(pdev, PCI_D0);
/* pci_power_on(pdev); */ pci_restore_state(pdev);
tulip_up (dev);
netif_device_attach (dev); pci_enable_device(pdev);
if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) {
printk (KERN_ERR "tulip: request_irq failed in resume\n");
return retval;
} }
netif_device_attach(dev);
if (netif_running(dev))
tulip_up(dev);
return 0; return 0;
} }

View File

@ -1398,7 +1398,7 @@ static void rhine_tx(struct net_device *dev)
while (rp->dirty_tx != rp->cur_tx) { while (rp->dirty_tx != rp->cur_tx) {
txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status); txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status);
if (debug > 6) if (debug > 6)
printk(KERN_DEBUG " Tx scavenge %d status %8.8x.\n", printk(KERN_DEBUG "Tx scavenge %d status %8.8x.\n",
entry, txstatus); entry, txstatus);
if (txstatus & DescOwn) if (txstatus & DescOwn)
break; break;
@ -1469,7 +1469,7 @@ static void rhine_rx(struct net_device *dev)
int data_size = desc_status >> 16; int data_size = desc_status >> 16;
if (debug > 4) if (debug > 4)
printk(KERN_DEBUG " rhine_rx() status is %8.8x.\n", printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n",
desc_status); desc_status);
if (--boguscnt < 0) if (--boguscnt < 0)
break; break;
@ -1487,7 +1487,7 @@ static void rhine_rx(struct net_device *dev)
} else if (desc_status & RxErr) { } else if (desc_status & RxErr) {
/* There was a error. */ /* There was a error. */
if (debug > 2) if (debug > 2)
printk(KERN_DEBUG " rhine_rx() Rx " printk(KERN_DEBUG "rhine_rx() Rx "
"error was %8.8x.\n", "error was %8.8x.\n",
desc_status); desc_status);
rp->stats.rx_errors++; rp->stats.rx_errors++;

View File

@ -981,6 +981,7 @@ fst_issue_cmd(struct fst_port_info *port, unsigned short cmd)
/* Wait for any previous command to complete */ /* Wait for any previous command to complete */
while (mbval > NAK) { while (mbval > NAK) {
spin_unlock_irqrestore(&card->card_lock, flags); spin_unlock_irqrestore(&card->card_lock, flags);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1); schedule_timeout(1);
spin_lock_irqsave(&card->card_lock, flags); spin_lock_irqsave(&card->card_lock, flags);

View File

@ -900,7 +900,7 @@ typedef struct aironet_ioctl {
unsigned char __user *data; // d-data unsigned char __user *data; // d-data
} aironet_ioctl; } aironet_ioctl;
static char *swversion = "2.1"; static char swversion[] = "2.1";
#endif /* CISCO_EXT */ #endif /* CISCO_EXT */
#define NUM_MODULES 2 #define NUM_MODULES 2

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
#ifndef _ORINOCO_H #ifndef _ORINOCO_H
#define _ORINOCO_H #define _ORINOCO_H
#define DRIVER_VERSION "0.14alpha2" #define DRIVER_VERSION "0.15rc2"
#include <linux/types.h> #include <linux/types.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
@ -22,6 +22,8 @@
#define WIRELESS_SPY // enable iwspy support #define WIRELESS_SPY // enable iwspy support
#define MAX_SCAN_LEN 4096
#define ORINOCO_MAX_KEY_SIZE 14 #define ORINOCO_MAX_KEY_SIZE 14
#define ORINOCO_MAX_KEYS 4 #define ORINOCO_MAX_KEYS 4
@ -30,6 +32,20 @@ struct orinoco_key {
char data[ORINOCO_MAX_KEY_SIZE]; char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct header_struct {
/* 802.3 */
u8 dest[ETH_ALEN];
u8 src[ETH_ALEN];
u16 len;
/* 802.2 */
u8 dsap;
u8 ssap;
u8 ctrl;
/* SNAP */
u8 oui[3];
u16 ethertype;
} __attribute__ ((packed));
typedef enum { typedef enum {
FIRMWARE_TYPE_AGERE, FIRMWARE_TYPE_AGERE,
FIRMWARE_TYPE_INTERSIL, FIRMWARE_TYPE_INTERSIL,
@ -48,6 +64,8 @@ struct orinoco_private {
/* driver state */ /* driver state */
int open; int open;
u16 last_linkstatus; u16 last_linkstatus;
struct work_struct join_work;
struct work_struct wevent_work;
/* Net device stuff */ /* Net device stuff */
struct net_device *ndev; struct net_device *ndev;
@ -74,7 +92,9 @@ struct orinoco_private {
unsigned int has_pm:1; unsigned int has_pm:1;
unsigned int has_preamble:1; unsigned int has_preamble:1;
unsigned int has_sensitivity:1; unsigned int has_sensitivity:1;
unsigned int has_hostscan:1;
unsigned int broken_disableport:1; unsigned int broken_disableport:1;
unsigned int broken_monitor:1;
/* Configuration paramaters */ /* Configuration paramaters */
u32 iw_mode; u32 iw_mode;
@ -84,6 +104,8 @@ struct orinoco_private {
int bitratemode; int bitratemode;
char nick[IW_ESSID_MAX_SIZE+1]; char nick[IW_ESSID_MAX_SIZE+1];
char desired_essid[IW_ESSID_MAX_SIZE+1]; char desired_essid[IW_ESSID_MAX_SIZE+1];
char desired_bssid[ETH_ALEN];
int bssid_fixed;
u16 frag_thresh, mwo_robust; u16 frag_thresh, mwo_robust;
u16 channel; u16 channel;
u16 ap_density, rts_thresh; u16 ap_density, rts_thresh;
@ -98,6 +120,12 @@ struct orinoco_private {
/* Configuration dependent variables */ /* Configuration dependent variables */
int port_type, createibss; int port_type, createibss;
int promiscuous, mc_count; int promiscuous, mc_count;
/* Scanning support */
int scan_inprogress; /* Scan pending... */
u32 scan_mode; /* Type of scan done */
char * scan_result; /* Result of previous scan */
int scan_len; /* Lenght of result */
}; };
#ifdef ORINOCO_DEBUG #ifdef ORINOCO_DEBUG

View File

@ -112,10 +112,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
void void
isl38xx_trigger_device(int asleep, void __iomem *device_base) isl38xx_trigger_device(int asleep, void __iomem *device_base)
{ {
struct timeval current_time;
u32 reg, counter = 0; u32 reg, counter = 0;
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES
struct timeval current_time;
DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
#endif #endif
@ -126,11 +126,11 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
do_gettimeofday(&current_time); do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n", DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n",
current_time.tv_sec, (long)current_time.tv_usec); current_time.tv_sec, (long)current_time.tv_usec);
#endif
DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n", DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec, current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG)); readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
udelay(ISL38XX_WRITEIO_DELAY); udelay(ISL38XX_WRITEIO_DELAY);
reg = readl(device_base + ISL38XX_INT_IDENT_REG); reg = readl(device_base + ISL38XX_INT_IDENT_REG);
@ -148,10 +148,12 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
counter++; counter++;
} }
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_TRACING, DEBUG(SHOW_TRACING,
"%08li.%08li Device register read %08x\n", "%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec, current_time.tv_sec, (long)current_time.tv_usec,
readl(device_base + ISL38XX_CTRL_STAT_REG)); readl(device_base + ISL38XX_CTRL_STAT_REG));
#endif
udelay(ISL38XX_WRITEIO_DELAY); udelay(ISL38XX_WRITEIO_DELAY);
#if VERBOSE > SHOW_ERROR_MESSAGES #if VERBOSE > SHOW_ERROR_MESSAGES

View File

@ -1166,7 +1166,7 @@ static void pegasus_set_multicast(struct net_device *net)
pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
if (netif_msg_link(pegasus)) if (netif_msg_link(pegasus))
pr_info("%s: Promiscuous mode enabled.\n", net->name); pr_info("%s: Promiscuous mode enabled.\n", net->name);
} else if ((net->mc_count > multicast_filter_limit) || } else if (net->mc_count ||
(net->flags & IFF_ALLMULTI)) { (net->flags & IFF_ALLMULTI)) {
pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;

View File

@ -249,6 +249,8 @@ PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
DEFAULT_GPIO_RESET) DEFAULT_GPIO_RESET)
PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002, PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
PEGASUS_DEV( "LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
DEFAULT_GPIO_RESET | PEGASUS_II)
PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b, PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1, PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,

View File

@ -667,7 +667,7 @@ static void rtl8150_set_multicast(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
dev->rx_creg |= cpu_to_le16(0x0001); dev->rx_creg |= cpu_to_le16(0x0001);
info("%s: promiscuous mode", netdev->name); info("%s: promiscuous mode", netdev->name);
} else if ((netdev->mc_count > multicast_filter_limit) || } else if (netdev->mc_count ||
(netdev->flags & IFF_ALLMULTI)) { (netdev->flags & IFF_ALLMULTI)) {
dev->rx_creg &= cpu_to_le16(0xfffe); dev->rx_creg &= cpu_to_le16(0xfffe);
dev->rx_creg |= cpu_to_le16(0x0002); dev->rx_creg |= cpu_to_le16(0x0002);

View File

@ -1284,6 +1284,8 @@
#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348
#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C
#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E
#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372
#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373
#define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849 #define PCI_DEVICE_ID_IMS_8849 0x8849

882
include/net/ieee80211.h Normal file
View File

@ -0,0 +1,882 @@
/*
* Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
* remains copyright by the original authors
*
* Portions of the merged code are based on Host AP (software wireless
* LAN access point) driver for Intersil Prism2/2.5/3.
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
* Copyright (c) 2004, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
#ifndef IEEE80211_H
#define IEEE80211_H
#include <linux/if_ether.h> /* ETH_ALEN */
#include <linux/kernel.h> /* ARRAY_SIZE */
#if WIRELESS_EXT < 17
#define IW_QUAL_QUAL_INVALID 0x10
#define IW_QUAL_LEVEL_INVALID 0x20
#define IW_QUAL_NOISE_INVALID 0x40
#define IW_QUAL_QUAL_UPDATED 0x1
#define IW_QUAL_LEVEL_UPDATED 0x2
#define IW_QUAL_NOISE_UPDATED 0x4
#endif
#define IEEE80211_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6.2.1.1.2.
The figure in section 7.1.2 suggests a body size of up to 2312
bytes is allowed, which is a bit confusing, I suspect this
represents the 2304 bytes of real data, plus a possible 8 bytes of
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
#define IEEE80211_HLEN 30
#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
struct ieee80211_hdr {
u16 frame_ctl;
u16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
u16 seq_ctl;
u8 addr4[ETH_ALEN];
} __attribute__ ((packed));
struct ieee80211_hdr_3addr {
u16 frame_ctl;
u16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
u16 seq_ctl;
} __attribute__ ((packed));
enum eap_type {
EAP_PACKET = 0,
EAPOL_START,
EAPOL_LOGOFF,
EAPOL_KEY,
EAPOL_ENCAP_ASF_ALERT
};
static const char *eap_types[] = {
[EAP_PACKET] = "EAP-Packet",
[EAPOL_START] = "EAPOL-Start",
[EAPOL_LOGOFF] = "EAPOL-Logoff",
[EAPOL_KEY] = "EAPOL-Key",
[EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
};
static inline const char *eap_get_type(int type)
{
return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
}
struct eapol {
u8 snap[6];
u16 ethertype;
u8 version;
u8 type;
u16 length;
} __attribute__ ((packed));
#define IEEE80211_3ADDR_LEN 24
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_FCS_LEN 4
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
/* Frame control field constants */
#define IEEE80211_FCTL_VERS 0x0002
#define IEEE80211_FCTL_FTYPE 0x000c
#define IEEE80211_FCTL_STYPE 0x00f0
#define IEEE80211_FCTL_TODS 0x0100
#define IEEE80211_FCTL_FROMDS 0x0200
#define IEEE80211_FCTL_MOREFRAGS 0x0400
#define IEEE80211_FCTL_RETRY 0x0800
#define IEEE80211_FCTL_PM 0x1000
#define IEEE80211_FCTL_MOREDATA 0x2000
#define IEEE80211_FCTL_WEP 0x4000
#define IEEE80211_FCTL_ORDER 0x8000
#define IEEE80211_FTYPE_MGMT 0x0000
#define IEEE80211_FTYPE_CTL 0x0004
#define IEEE80211_FTYPE_DATA 0x0008
/* management */
#define IEEE80211_STYPE_ASSOC_REQ 0x0000
#define IEEE80211_STYPE_ASSOC_RESP 0x0010
#define IEEE80211_STYPE_REASSOC_REQ 0x0020
#define IEEE80211_STYPE_REASSOC_RESP 0x0030
#define IEEE80211_STYPE_PROBE_REQ 0x0040
#define IEEE80211_STYPE_PROBE_RESP 0x0050
#define IEEE80211_STYPE_BEACON 0x0080
#define IEEE80211_STYPE_ATIM 0x0090
#define IEEE80211_STYPE_DISASSOC 0x00A0
#define IEEE80211_STYPE_AUTH 0x00B0
#define IEEE80211_STYPE_DEAUTH 0x00C0
/* control */
#define IEEE80211_STYPE_PSPOLL 0x00A0
#define IEEE80211_STYPE_RTS 0x00B0
#define IEEE80211_STYPE_CTS 0x00C0
#define IEEE80211_STYPE_ACK 0x00D0
#define IEEE80211_STYPE_CFEND 0x00E0
#define IEEE80211_STYPE_CFENDACK 0x00F0
/* data */
#define IEEE80211_STYPE_DATA 0x0000
#define IEEE80211_STYPE_DATA_CFACK 0x0010
#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
#define IEEE80211_STYPE_NULLFUNC 0x0040
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
/* debug macros */
#ifdef CONFIG_IEEE80211_DEBUG
extern u32 ieee80211_debug_level;
#define IEEE80211_DEBUG(level, fmt, args...) \
do { if (ieee80211_debug_level & (level)) \
printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
#else
#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
#endif /* CONFIG_IEEE80211_DEBUG */
/*
* To use the debug system;
*
* If you are defining a new debug classification, simply add it to the #define
* list here in the form of:
*
* #define IEEE80211_DL_xxxx VALUE
*
* shifting value to the left one bit from the previous entry. xxxx should be
* the name of the classification (for example, WEP)
*
* You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
* classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
* to send output to that classification.
*
* To add your debug level to the list of levels seen when you perform
*
* % cat /proc/net/ipw/debug_level
*
* you simply need to add your entry to the ipw_debug_levels array.
*
* If you do not see debug_level in /proc/net/ipw then you do not have
* CONFIG_IEEE80211_DEBUG defined in your kernel configuration
*
*/
#define IEEE80211_DL_INFO (1<<0)
#define IEEE80211_DL_WX (1<<1)
#define IEEE80211_DL_SCAN (1<<2)
#define IEEE80211_DL_STATE (1<<3)
#define IEEE80211_DL_MGMT (1<<4)
#define IEEE80211_DL_FRAG (1<<5)
#define IEEE80211_DL_EAP (1<<6)
#define IEEE80211_DL_DROP (1<<7)
#define IEEE80211_DL_TX (1<<8)
#define IEEE80211_DL_RX (1<<9)
#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/if_arp.h> /* ARPHRD_ETHER */
#ifndef WIRELESS_SPY
#define WIRELESS_SPY // enable iwspy support
#endif
#include <net/iw_handler.h> // new driver API
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
#endif
/* IEEE 802.11 defines */
#define P80211_OUI_LEN 3
struct ieee80211_snap_hdr {
u8 dsap; /* always 0xAA */
u8 ssap; /* always 0xAA */
u8 ctrl; /* always 0x03 */
u8 oui[P80211_OUI_LEN]; /* organizational universal id */
} __attribute__ ((packed));
#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
#define WLAN_AUTH_CHALLENGE_LEN 128
#define WLAN_CAPABILITY_BSS (1<<0)
#define WLAN_CAPABILITY_IBSS (1<<1)
#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
#define WLAN_CAPABILITY_PRIVACY (1<<4)
#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
#define WLAN_CAPABILITY_PBCC (1<<6)
#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
/* Status codes */
#define WLAN_STATUS_SUCCESS 0
#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
#define WLAN_STATUS_CAPS_UNSUPPORTED 10
#define WLAN_STATUS_REASSOC_NO_ASSOC 11
#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
#define WLAN_STATUS_CHALLENGE_FAIL 15
#define WLAN_STATUS_AUTH_TIMEOUT 16
#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
#define WLAN_STATUS_ASSOC_DENIED_RATES 18
/* 802.11b */
#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
/* Reason codes */
#define WLAN_REASON_UNSPECIFIED 1
#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
#define WLAN_REASON_DEAUTH_LEAVING 3
#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
#define WLAN_REASON_DISASSOC_AP_BUSY 5
#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
/* Information Element IDs */
#define WLAN_EID_SSID 0
#define WLAN_EID_SUPP_RATES 1
#define WLAN_EID_FH_PARAMS 2
#define WLAN_EID_DS_PARAMS 3
#define WLAN_EID_CF_PARAMS 4
#define WLAN_EID_TIM 5
#define WLAN_EID_IBSS_PARAMS 6
#define WLAN_EID_CHALLENGE 16
#define WLAN_EID_RSN 48
#define WLAN_EID_GENERIC 221
#define IEEE80211_MGMT_HDR_LEN 24
#define IEEE80211_DATA_HDR3_LEN 24
#define IEEE80211_DATA_HDR4_LEN 30
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
#define IEEE80211_STATMASK_RATE (1<<3)
#define IEEE80211_STATMASK_WEMASK 0x7
#define IEEE80211_CCK_MODULATION (1<<0)
#define IEEE80211_OFDM_MODULATION (1<<1)
#define IEEE80211_24GHZ_BAND (1<<0)
#define IEEE80211_52GHZ_BAND (1<<1)
#define IEEE80211_CCK_RATE_1MB 0x02
#define IEEE80211_CCK_RATE_2MB 0x04
#define IEEE80211_CCK_RATE_5MB 0x0B
#define IEEE80211_CCK_RATE_11MB 0x16
#define IEEE80211_OFDM_RATE_6MB 0x0C
#define IEEE80211_OFDM_RATE_9MB 0x12
#define IEEE80211_OFDM_RATE_12MB 0x18
#define IEEE80211_OFDM_RATE_18MB 0x24
#define IEEE80211_OFDM_RATE_24MB 0x30
#define IEEE80211_OFDM_RATE_36MB 0x48
#define IEEE80211_OFDM_RATE_48MB 0x60
#define IEEE80211_OFDM_RATE_54MB 0x6C
#define IEEE80211_BASIC_RATE_MASK 0x80
#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
#define IEEE80211_CCK_RATES_MASK 0x0000000F
#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
IEEE80211_CCK_RATE_2MB_MASK)
#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
IEEE80211_CCK_RATE_5MB_MASK | \
IEEE80211_CCK_RATE_11MB_MASK)
#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
IEEE80211_OFDM_RATE_12MB_MASK | \
IEEE80211_OFDM_RATE_24MB_MASK)
#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
IEEE80211_OFDM_RATE_9MB_MASK | \
IEEE80211_OFDM_RATE_18MB_MASK | \
IEEE80211_OFDM_RATE_36MB_MASK | \
IEEE80211_OFDM_RATE_48MB_MASK | \
IEEE80211_OFDM_RATE_54MB_MASK)
#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
IEEE80211_CCK_DEFAULT_RATES_MASK)
#define IEEE80211_NUM_OFDM_RATES 8
#define IEEE80211_NUM_CCK_RATES 4
#define IEEE80211_OFDM_SHIFT_MASK_A 4
/* NOTE: This data is for statistical purposes; not all hardware provides this
* information for frames received. Not setting these will not cause
* any adverse affects. */
struct ieee80211_rx_stats {
u32 mac_time;
s8 rssi;
u8 signal;
u8 noise;
u16 rate; /* in 100 kbps */
u8 received_channel;
u8 control;
u8 mask;
u8 freq;
u16 len;
};
/* IEEE 802.11 requires that STA supports concurrent reception of at least
* three fragmented frames. This define can be increased to support more
* concurrent frames, but it should be noted that each entry can consume about
* 2 kB of RAM and increasing cache size will slow down frame reassembly. */
#define IEEE80211_FRAG_CACHE_LEN 4
struct ieee80211_frag_entry {
unsigned long first_frag_time;
unsigned int seq;
unsigned int last_frag;
struct sk_buff *skb;
u8 src_addr[ETH_ALEN];
u8 dst_addr[ETH_ALEN];
};
struct ieee80211_stats {
unsigned int tx_unicast_frames;
unsigned int tx_multicast_frames;
unsigned int tx_fragments;
unsigned int tx_unicast_octets;
unsigned int tx_multicast_octets;
unsigned int tx_deferred_transmissions;
unsigned int tx_single_retry_frames;
unsigned int tx_multiple_retry_frames;
unsigned int tx_retry_limit_exceeded;
unsigned int tx_discards;
unsigned int rx_unicast_frames;
unsigned int rx_multicast_frames;
unsigned int rx_fragments;
unsigned int rx_unicast_octets;
unsigned int rx_multicast_octets;
unsigned int rx_fcs_errors;
unsigned int rx_discards_no_buffer;
unsigned int tx_discards_wrong_sa;
unsigned int rx_discards_undecryptable;
unsigned int rx_message_in_msg_fragments;
unsigned int rx_message_in_bad_msg_fragments;
};
struct ieee80211_device;
#define SEC_KEY_1 (1<<0)
#define SEC_KEY_2 (1<<1)
#define SEC_KEY_3 (1<<2)
#define SEC_KEY_4 (1<<3)
#define SEC_ACTIVE_KEY (1<<4)
#define SEC_AUTH_MODE (1<<5)
#define SEC_UNICAST_GROUP (1<<6)
#define SEC_LEVEL (1<<7)
#define SEC_ENABLED (1<<8)
#define SEC_LEVEL_0 0 /* None */
#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
#define WEP_KEYS 4
#define WEP_KEY_LEN 13
struct ieee80211_security {
u16 active_key:2,
enabled:1,
auth_mode:2,
auth_algo:4,
unicast_uses_group:1;
u8 key_sizes[WEP_KEYS];
u8 keys[WEP_KEYS][WEP_KEY_LEN];
u8 level;
u16 flags;
} __attribute__ ((packed));
/*
802.11 data frame from AP
,-------------------------------------------------------------------.
Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
|------|------|---------|---------|---------|------|---------|------|
Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
| | tion | (BSSID) | | | ence | data | |
`-------------------------------------------------------------------'
Total: 28-2340 bytes
*/
struct ieee80211_header_data {
u16 frame_ctl;
u16 duration_id;
u8 addr1[6];
u8 addr2[6];
u8 addr3[6];
u16 seq_ctrl;
};
#define BEACON_PROBE_SSID_ID_POSITION 12
/* Management Frame Information Element Types */
#define MFIE_TYPE_SSID 0
#define MFIE_TYPE_RATES 1
#define MFIE_TYPE_FH_SET 2
#define MFIE_TYPE_DS_SET 3
#define MFIE_TYPE_CF_SET 4
#define MFIE_TYPE_TIM 5
#define MFIE_TYPE_IBSS_SET 6
#define MFIE_TYPE_CHALLENGE 16
#define MFIE_TYPE_RSN 48
#define MFIE_TYPE_RATES_EX 50
#define MFIE_TYPE_GENERIC 221
struct ieee80211_info_element_hdr {
u8 id;
u8 len;
} __attribute__ ((packed));
struct ieee80211_info_element {
u8 id;
u8 len;
u8 data[0];
} __attribute__ ((packed));
/*
* These are the data types that can make up management packets
*
u16 auth_algorithm;
u16 auth_sequence;
u16 beacon_interval;
u16 capability;
u8 current_ap[ETH_ALEN];
u16 listen_interval;
struct {
u16 association_id:14, reserved:2;
} __attribute__ ((packed));
u32 time_stamp[2];
u16 reason;
u16 status;
*/
struct ieee80211_authentication {
struct ieee80211_header_data header;
u16 algorithm;
u16 transaction;
u16 status;
struct ieee80211_info_element info_element;
} __attribute__ ((packed));
struct ieee80211_probe_response {
struct ieee80211_header_data header;
u32 time_stamp[2];
u16 beacon_interval;
u16 capability;
struct ieee80211_info_element info_element;
} __attribute__ ((packed));
struct ieee80211_assoc_request_frame {
u16 capability;
u16 listen_interval;
u8 current_ap[ETH_ALEN];
struct ieee80211_info_element info_element;
} __attribute__ ((packed));
struct ieee80211_assoc_response_frame {
struct ieee80211_hdr_3addr header;
u16 capability;
u16 status;
u16 aid;
struct ieee80211_info_element info_element; /* supported rates */
} __attribute__ ((packed));
struct ieee80211_txb {
u8 nr_frags;
u8 encrypted;
u16 reserved;
u16 frag_size;
u16 payload_size;
struct sk_buff *fragments[0];
};
/* SWEEP TABLE ENTRIES NUMBER*/
#define MAX_SWEEP_TAB_ENTRIES 42
#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
* only use 8, and then use extended rates for the remaining supported
* rates. Other APs, however, stick all of their supported rates on the
* main rates information element... */
#define MAX_RATES_LENGTH ((u8)12)
#define MAX_RATES_EX_LENGTH ((u8)16)
#define MAX_NETWORK_COUNT 128
#define CRC_LENGTH 4U
#define MAX_WPA_IE_LEN 64
#define NETWORK_EMPTY_ESSID (1<<0)
#define NETWORK_HAS_OFDM (1<<1)
#define NETWORK_HAS_CCK (1<<2)
struct ieee80211_network {
/* These entries are used to identify a unique network */
u8 bssid[ETH_ALEN];
u8 channel;
/* Ensure null-terminated for any debug msgs */
u8 ssid[IW_ESSID_MAX_SIZE + 1];
u8 ssid_len;
/* These are network statistics */
struct ieee80211_rx_stats stats;
u16 capability;
u8 rates[MAX_RATES_LENGTH];
u8 rates_len;
u8 rates_ex[MAX_RATES_EX_LENGTH];
u8 rates_ex_len;
unsigned long last_scanned;
u8 mode;
u8 flags;
u32 last_associate;
u32 time_stamp[2];
u16 beacon_interval;
u16 listen_interval;
u16 atim_window;
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
u8 rsn_ie[MAX_WPA_IE_LEN];
size_t rsn_ie_len;
struct list_head list;
};
enum ieee80211_state {
IEEE80211_UNINITIALIZED = 0,
IEEE80211_INITIALIZED,
IEEE80211_ASSOCIATING,
IEEE80211_ASSOCIATED,
IEEE80211_AUTHENTICATING,
IEEE80211_AUTHENTICATED,
IEEE80211_SHUTDOWN
};
#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
#define DEFAULT_FTS 2346
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
extern inline int is_broadcast_ether_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
}
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
struct ieee80211_device {
struct net_device *dev;
/* Bookkeeping structures */
struct net_device_stats stats;
struct ieee80211_stats ieee_stats;
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
struct ieee80211_network *networks;
int scans;
int scan_age;
int iw_mode; /* operating mode (IW_MODE_*) */
spinlock_t lock;
int tx_headroom; /* Set to size of any additional room needed at front
* of allocated Tx SKBs */
u32 config;
/* WEP and other encryption related settings at the device level */
int open_wep; /* Set to 1 to allow unencrypted frames */
int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
* WEP key changes */
/* If the host performs {en,de}cryption, then set to 1 */
int host_encrypt;
int host_decrypt;
int ieee802_1x; /* is IEEE 802.1X used */
/* WPA data */
int wpa_enabled;
int drop_unencrypted;
int tkip_countermeasures;
int privacy_invoked;
size_t wpa_ie_len;
u8 *wpa_ie;
struct list_head crypt_deinit_list;
struct ieee80211_crypt_data *crypt[WEP_KEYS];
int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
struct timer_list crypt_deinit_timer;
int bcrx_sta_key; /* use individual keys to override default keys even
* with RX of broad/multicast frames */
/* Fragmentation structures */
struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
unsigned int frag_next_idx;
u16 fts; /* Fragmentation Threshold */
/* Association info */
u8 bssid[ETH_ALEN];
enum ieee80211_state state;
int mode; /* A, B, G */
int modulation; /* CCK, OFDM */
int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
int abg_ture; /* ABG flag */
/* Callback functions */
void (*set_security)(struct net_device *dev,
struct ieee80211_security *sec);
int (*hard_start_xmit)(struct ieee80211_txb *txb,
struct net_device *dev);
int (*reset_port)(struct net_device *dev);
/* This must be the last item so that it points to the data
* allocated beyond this structure by alloc_ieee80211 */
u8 priv[0];
};
#define IEEE_A (1<<0)
#define IEEE_B (1<<1)
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
extern inline void *ieee80211_priv(struct net_device *dev)
{
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
return 1;
/* Otherwise, if the entire essid is 0, we assume it is hidden */
while (essid_len) {
essid_len--;
if (essid[essid_len] != '\0')
return 0;
}
return 1;
}
extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
* combinations of modes, so as long as there is one valid combination
* of ap/device supported modes, then return success
*
*/
if ((mode & IEEE_A) &&
(ieee->modulation & IEEE80211_OFDM_MODULATION) &&
(ieee->freq_band & IEEE80211_52GHZ_BAND))
return 1;
if ((mode & IEEE_G) &&
(ieee->modulation & IEEE80211_OFDM_MODULATION) &&
(ieee->freq_band & IEEE80211_24GHZ_BAND))
return 1;
if ((mode & IEEE_B) &&
(ieee->modulation & IEEE80211_CCK_MODULATION) &&
(ieee->freq_band & IEEE80211_24GHZ_BAND))
return 1;
return 0;
}
extern inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;
switch (WLAN_FC_GET_TYPE(fc)) {
case IEEE80211_FTYPE_DATA:
if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
hdrlen = 30; /* Addr4 */
break;
case IEEE80211_FTYPE_CTL:
switch (WLAN_FC_GET_STYPE(fc)) {
case IEEE80211_STYPE_CTS:
case IEEE80211_STYPE_ACK:
hdrlen = 10;
break;
default:
hdrlen = 16;
break;
}
break;
}
return hdrlen;
}
/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
/* ieee80211_tx.c */
extern int ieee80211_xmit(struct sk_buff *skb,
struct net_device *dev);
extern void ieee80211_txb_free(struct ieee80211_txb *);
/* ieee80211_rx.c */
extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_rx_stats *rx_stats);
extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
struct ieee80211_hdr *header,
struct ieee80211_rx_stats *stats);
/* iee80211_wx.c */
extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *key);
extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
static inline const char *escape_essid(const char *essid, u8 essid_len) {
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = essid;
char *d = escaped;
if (ieee80211_is_empty_essid(essid, essid_len)) {
memcpy(escaped, "<hidden>", sizeof("<hidden>"));
return escaped;
}
essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
while (essid_len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
return escaped;
}
#endif /* IEEE80211_H */