提交 76fef2b6 编写于 作者: D David S. Miller

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

Conflicts:

	drivers/s390/net/qeth_main.c
...@@ -213,14 +213,6 @@ Who: linuxppc-dev@ozlabs.org ...@@ -213,14 +213,6 @@ Who: linuxppc-dev@ozlabs.org
--------------------------- ---------------------------
What: sk98lin network driver
When: Feburary 2008
Why: In kernel tree version of driver is unmaintained. Sk98lin driver
replaced by the skge driver.
Who: Stephen Hemminger <shemminger@linux-foundation.org>
---------------------------
What: i386/x86_64 bzImage symlinks What: i386/x86_64 bzImage symlinks
When: April 2008 When: April 2008
...@@ -231,8 +223,6 @@ Who: Thomas Gleixner <tglx@linutronix.de> ...@@ -231,8 +223,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
--------------------------- ---------------------------
---------------------------
What: i2c-i810, i2c-prosavage and i2c-savage4 What: i2c-i810, i2c-prosavage and i2c-savage4
When: May 2008 When: May 2008
Why: These drivers are superseded by i810fb, intelfb and savagefb. Why: These drivers are superseded by i810fb, intelfb and savagefb.
......
...@@ -537,11 +537,9 @@ CONFIG_CTC=m ...@@ -537,11 +537,9 @@ CONFIG_CTC=m
# CONFIG_SMSGIUCV is not set # CONFIG_SMSGIUCV is not set
# CONFIG_CLAW is not set # CONFIG_CLAW is not set
CONFIG_QETH=y CONFIG_QETH=y
CONFIG_QETH_L2=y
# CONFIG_QETH_L3=y
# Gigabit Ethernet default settings CONFIG_QETH_IPV6=y
#
# CONFIG_QETH_IPV6 is not set
CONFIG_CCWGROUP=y CONFIG_CCWGROUP=y
# CONFIG_PPP is not set # CONFIG_PPP is not set
# CONFIG_SLIP is not set # CONFIG_SLIP is not set
......
...@@ -48,14 +48,16 @@ EXPORT_SYMBOL(__alloc_ei_netdev); ...@@ -48,14 +48,16 @@ EXPORT_SYMBOL(__alloc_ei_netdev);
#if defined(MODULE) #if defined(MODULE)
int init_module(void) static int __init ns8390_module_init(void)
{ {
return 0; return 0;
} }
void cleanup_module(void) static void __exit ns8390_module_exit(void)
{ {
} }
module_init(ns8390_init_module);
module_exit(ns8390_module_exit);
#endif /* MODULE */ #endif /* MODULE */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -2220,93 +2220,6 @@ config SKY2_DEBUG ...@@ -2220,93 +2220,6 @@ config SKY2_DEBUG
If unsure, say N. If unsure, say N.
config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
depends on PCI
---help---
Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
compliant Gigabit Ethernet Adapter.
This driver supports the original Yukon chipset. This driver is
deprecated and will be removed from the kernel in the near future,
it has been replaced by the skge driver. skge is cleaner and
seems to work better.
This driver does not support the newer Yukon2 chipset. A separate
driver, sky2, is provided to support Yukon2-based adapters.
The following adapters are supported by this driver:
- 3Com 3C940 Gigabit LOM Ethernet Adapter
- 3Com 3C941 Gigabit LOM Ethernet Adapter
- Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
- Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
- Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
- Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
- Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
- Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971T Gigabit Ethernet Adapter
- Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
- EG1032 v2 Instant Gigabit Network Adapter
- EG1064 v2 Instant Gigabit Network Adapter
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
- Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
- Marvell RDK-8001 Adapter
- Marvell RDK-8002 Adapter
- Marvell RDK-8003 Adapter
- Marvell RDK-8004 Adapter
- Marvell RDK-8006 Adapter
- Marvell RDK-8007 Adapter
- Marvell RDK-8008 Adapter
- Marvell RDK-8009 Adapter
- Marvell RDK-8010 Adapter
- Marvell RDK-8011 Adapter
- Marvell RDK-8012 Adapter
- Marvell RDK-8052 Adapter
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
- N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
- SK-9521 10/100/1000Base-T Adapter
- SK-9521 V2.0 10/100/1000Base-T Adapter
- SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
- SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
- SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
- SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
- SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
- SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
- SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
- SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
- SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
- SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
- SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
- SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
- SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
- SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
- SMC EZ Card 1000 (SMC9452TXV.2)
The adapters support Jumbo Frames.
The dual link adapters support link-failover and dual port features.
Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support
the scatter-gather functionality with sendfile(). Please refer to
<file:Documentation/networking/sk98lin.txt> for more information about
optional driver parameters.
Questions concerning this driver may be addressed to:
<linux@syskonnect.de>
If you want to compile this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The module will
be called sk98lin. This is recommended.
config VIA_VELOCITY config VIA_VELOCITY
tristate "VIA Velocity support" tristate "VIA Velocity support"
depends on PCI depends on PCI
......
...@@ -15,7 +15,7 @@ obj-$(CONFIG_CHELSIO_T3) += cxgb3/ ...@@ -15,7 +15,7 @@ obj-$(CONFIG_CHELSIO_T3) += cxgb3/
obj-$(CONFIG_EHEA) += ehea/ obj-$(CONFIG_EHEA) += ehea/
obj-$(CONFIG_CAN) += can/ obj-$(CONFIG_CAN) += can/
obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_ATL1) += atl1/ obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_GIANFAR) += gianfar_driver.o
obj-$(CONFIG_TEHUTI) += tehuti.o obj-$(CONFIG_TEHUTI) += tehuti.o
...@@ -75,7 +75,6 @@ ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y) ...@@ -75,7 +75,6 @@ ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o obj-$(CONFIG_SKY2) += sky2.o
obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
......
...@@ -1010,7 +1010,7 @@ module_param(io, int, 0); ...@@ -1010,7 +1010,7 @@ module_param(io, int, 0);
module_param(irq, int, 0); module_param(irq, int, 0);
module_param(board_type, int, 0); module_param(board_type, int, 0);
int __init init_module(void) static int __init cops_module_init(void)
{ {
if (io == 0) if (io == 0)
printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
...@@ -1021,12 +1021,14 @@ int __init init_module(void) ...@@ -1021,12 +1021,14 @@ int __init init_module(void)
return 0; return 0;
} }
void __exit cleanup_module(void) static void __exit cops_module_exit(void)
{ {
unregister_netdev(cops_dev); unregister_netdev(cops_dev);
cleanup_card(cops_dev); cleanup_card(cops_dev);
free_netdev(cops_dev); free_netdev(cops_dev);
} }
module_init(cops_module_init);
module_exit(cops_module_exit);
#endif /* MODULE */ #endif /* MODULE */
/* /*
......
...@@ -348,14 +348,15 @@ MODULE_LICENSE("GPL"); ...@@ -348,14 +348,15 @@ MODULE_LICENSE("GPL");
#ifdef MODULE #ifdef MODULE
int init_module(void) static int __init com20020_module_init(void)
{ {
BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk(VERSION);
return 0; return 0;
} }
void cleanup_module(void) static void __exit com20020_module_exit(void)
{ {
} }
module_init(com20020_module_init);
module_exit(com20020_module_exit);
#endif /* MODULE */ #endif /* MODULE */
...@@ -881,7 +881,7 @@ MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address"); ...@@ -881,7 +881,7 @@ MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number"); MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)"); MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
int __init init_module(void) static int __init at1700_module_init(void)
{ {
if (io == 0) if (io == 0)
printk("at1700: You should not use auto-probing with insmod!\n"); printk("at1700: You should not use auto-probing with insmod!\n");
...@@ -891,13 +891,14 @@ int __init init_module(void) ...@@ -891,13 +891,14 @@ int __init init_module(void)
return 0; return 0;
} }
void __exit static void __exit at1700_module_exit(void)
cleanup_module(void)
{ {
unregister_netdev(dev_at1700); unregister_netdev(dev_at1700);
cleanup_card(dev_at1700); cleanup_card(dev_at1700);
free_netdev(dev_at1700); free_netdev(dev_at1700);
} }
module_init(at1700_module_init);
module_exit(at1700_module_exit);
#endif /* MODULE */ #endif /* MODULE */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -1155,7 +1155,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) ...@@ -1155,7 +1155,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
#ifdef MODULE #ifdef MODULE
static struct net_device *atarilance_dev; static struct net_device *atarilance_dev;
int __init init_module(void) static int __init atarilance_module_init(void)
{ {
atarilance_dev = atarilance_probe(-1); atarilance_dev = atarilance_probe(-1);
if (IS_ERR(atarilance_dev)) if (IS_ERR(atarilance_dev))
...@@ -1163,13 +1163,14 @@ int __init init_module(void) ...@@ -1163,13 +1163,14 @@ int __init init_module(void)
return 0; return 0;
} }
void __exit cleanup_module(void) static void __exit atarilance_module_exit(void)
{ {
unregister_netdev(atarilance_dev); unregister_netdev(atarilance_dev);
free_irq(atarilance_dev->irq, atarilance_dev); free_irq(atarilance_dev->irq, atarilance_dev);
free_netdev(atarilance_dev); free_netdev(atarilance_dev);
} }
module_init(atarilance_module_init);
module_exit(atarilance_module_exit);
#endif /* MODULE */ #endif /* MODULE */
......
/*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ATL1_H_
#define _ATL1_H_
#include <linux/types.h>
#include <linux/if_vlan.h>
#include "atl1_hw.h"
/* function prototypes needed by multiple files */
s32 atl1_up(struct atl1_adapter *adapter);
void atl1_down(struct atl1_adapter *adapter);
int atl1_reset(struct atl1_adapter *adapter);
s32 atl1_setup_ring_resources(struct atl1_adapter *adapter);
void atl1_free_ring_resources(struct atl1_adapter *adapter);
extern char atl1_driver_name[];
extern char atl1_driver_version[];
extern const struct ethtool_ops atl1_ethtool_ops;
struct atl1_adapter;
#define ATL1_MAX_INTR 3
#define ATL1_MAX_TX_BUF_LEN 0x3000 /* 12288 bytes */
#define ATL1_DEFAULT_TPD 256
#define ATL1_MAX_TPD 1024
#define ATL1_MIN_TPD 64
#define ATL1_DEFAULT_RFD 512
#define ATL1_MIN_RFD 128
#define ATL1_MAX_RFD 2048
#define ATL1_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
#define ATL1_RFD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_free_desc)
#define ATL1_TPD_DESC(R, i) ATL1_GET_DESC(R, i, struct tx_packet_desc)
#define ATL1_RRD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_return_desc)
/*
* This detached comment is preserved for documentation purposes only.
* It was originally attached to some code that got deleted, but seems
* important enough to keep around...
*
* <begin detached comment>
* Some workarounds require millisecond delays and are run during interrupt
* context. Most notably, when establishing link, the phy may need tweaking
* but cannot process phy register reads/writes faster than millisecond
* intervals...and we establish link due to a "link status change" interrupt.
* <end detached comment>
*/
/*
* atl1_ring_header represents a single, contiguous block of DMA space
* mapped for the three descriptor rings (tpd, rfd, rrd) and the two
* message blocks (cmb, smb) described below
*/
struct atl1_ring_header {
void *desc; /* virtual address */
dma_addr_t dma; /* physical address*/
unsigned int size; /* length in bytes */
};
/*
* atl1_buffer is wrapper around a pointer to a socket buffer
* so a DMA handle can be stored along with the skb
*/
struct atl1_buffer {
struct sk_buff *skb; /* socket buffer */
u16 length; /* rx buffer length */
u16 alloced; /* 1 if skb allocated */
dma_addr_t dma;
};
/* transmit packet descriptor (tpd) ring */
struct atl1_tpd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 hw_idx; /* hardware index */
atomic_t next_to_clean;
atomic_t next_to_use;
struct atl1_buffer *buffer_info;
};
/* receive free descriptor (rfd) ring */
struct atl1_rfd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
atomic_t next_to_use;
u16 next_to_clean;
struct atl1_buffer *buffer_info;
};
/* receive return descriptor (rrd) ring */
struct atl1_rrd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
unsigned int size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use;
atomic_t next_to_clean;
};
/* coalescing message block (cmb) */
struct atl1_cmb {
struct coals_msg_block *cmb;
dma_addr_t dma;
};
/* statistics message block (smb) */
struct atl1_smb {
struct stats_msg_block *smb;
dma_addr_t dma;
};
/* Statistics counters */
struct atl1_sft_stats {
u64 rx_packets;
u64 tx_packets;
u64 rx_bytes;
u64 tx_bytes;
u64 multicast;
u64 collisions;
u64 rx_errors;
u64 rx_length_errors;
u64 rx_crc_errors;
u64 rx_frame_errors;
u64 rx_fifo_errors;
u64 rx_missed_errors;
u64 tx_errors;
u64 tx_fifo_errors;
u64 tx_aborted_errors;
u64 tx_window_errors;
u64 tx_carrier_errors;
u64 tx_pause; /* num pause packets transmitted. */
u64 excecol; /* num tx packets w/ excessive collisions. */
u64 deffer; /* num tx packets deferred */
u64 scc; /* num packets subsequently transmitted
* successfully w/ single prior collision. */
u64 mcc; /* num packets subsequently transmitted
* successfully w/ multiple prior collisions. */
u64 latecol; /* num tx packets w/ late collisions. */
u64 tx_underun; /* num tx packets aborted due to transmit
* FIFO underrun, or TRD FIFO underrun */
u64 tx_trunc; /* num tx packets truncated due to size
* exceeding MTU, regardless whether truncated
* by the chip or not. (The name doesn't really
* reflect the meaning in this case.) */
u64 rx_pause; /* num Pause packets received. */
u64 rx_rrd_ov;
u64 rx_trunc;
};
/* hardware structure */
struct atl1_hw {
u8 __iomem *hw_addr;
struct atl1_adapter *back;
enum atl1_dma_order dma_ord;
enum atl1_dma_rcb rcb_value;
enum atl1_dma_req_block dmar_block;
enum atl1_dma_req_block dmaw_block;
u8 preamble_len;
u8 max_retry; /* Retransmission maximum, after which the
* packet will be discarded */
u8 jam_ipg; /* IPG to start JAM for collision based flow
* control in half-duplex mode. In units of
* 8-bit time */
u8 ipgt; /* Desired back to back inter-packet gap.
* The default is 96-bit time */
u8 min_ifg; /* Minimum number of IFG to enforce in between
* receive frames. Frame gap below such IFP
* is dropped */
u8 ipgr1; /* 64bit Carrier-Sense window */
u8 ipgr2; /* 96-bit IPG window */
u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned
* burst. Each TPD is 16 bytes long */
u8 rfd_burst; /* Number of RFD to prefetch in cache-aligned
* burst. Each RFD is 12 bytes long */
u8 rfd_fetch_gap;
u8 rrd_burst; /* Threshold number of RRDs that can be retired
* in a burst. Each RRD is 16 bytes long */
u8 tpd_fetch_th;
u8 tpd_fetch_gap;
u16 tx_jumbo_task_th;
u16 txf_burst; /* Number of data bytes to read in a cache-
* aligned burst. Each SRAM entry is 8 bytes */
u16 rx_jumbo_th; /* Jumbo packet size for non-VLAN packet. VLAN
* packets should add 4 bytes */
u16 rx_jumbo_lkah;
u16 rrd_ret_timer; /* RRD retirement timer. Decrement by 1 after
* every 512ns passes. */
u16 lcol; /* Collision Window */
u16 cmb_tpd;
u16 cmb_rrd;
u16 cmb_rx_timer;
u16 cmb_tx_timer;
u32 smb_timer;
u16 media_type;
u16 autoneg_advertised;
u16 mii_autoneg_adv_reg;
u16 mii_1000t_ctrl_reg;
u32 max_frame_size;
u32 min_frame_size;
u16 dev_rev;
/* spi flash */
u8 flash_vendor;
u8 mac_addr[ETH_ALEN];
u8 perm_mac_addr[ETH_ALEN];
bool phy_configured;
};
struct atl1_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
struct net_device_stats net_stats;
struct atl1_sft_stats soft_stats;
struct vlan_group *vlgrp;
u32 rx_buffer_len;
u32 wol;
u16 link_speed;
u16 link_duplex;
spinlock_t lock;
struct work_struct tx_timeout_task;
struct work_struct link_chg_task;
struct work_struct pcie_dma_to_rst_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
bool phy_timer_pending;
/* all descriptor rings' memory */
struct atl1_ring_header ring_header;
/* TX */
struct atl1_tpd_ring tpd_ring;
spinlock_t mb_lock;
/* RX */
struct atl1_rfd_ring rfd_ring;
struct atl1_rrd_ring rrd_ring;
u64 hw_csum_err;
u64 hw_csum_good;
u16 imt; /* interrupt moderator timer (2us resolution */
u16 ict; /* interrupt clear timer (2us resolution */
struct mii_if_info mii; /* MII interface info */
/* structs defined in atl1_hw.h */
u32 bd_number; /* board number */
bool pci_using_64;
struct atl1_hw hw;
struct atl1_smb smb;
struct atl1_cmb cmb;
};
#endif /* _ATL1_H_ */
/*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/mii.h>
#include <asm/uaccess.h>
#include "atl1.h"
struct atl1_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
int stat_offset;
};
#define ATL1_STAT(m) sizeof(((struct atl1_adapter *)0)->m), \
offsetof(struct atl1_adapter, m)
static struct atl1_stats atl1_gstrings_stats[] = {
{"rx_packets", ATL1_STAT(soft_stats.rx_packets)},
{"tx_packets", ATL1_STAT(soft_stats.tx_packets)},
{"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)},
{"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
{"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
{"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
{"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
{"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
{"multicast", ATL1_STAT(soft_stats.multicast)},
{"collisions", ATL1_STAT(soft_stats.collisions)},
{"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
{"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
{"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)},
{"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)},
{"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)},
{"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
{"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)},
{"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)},
{"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)},
{"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)},
{"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)},
{"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)},
{"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
{"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
{"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
{"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
{"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
{"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
{"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
{"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)},
{"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)}
};
static void atl1_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
int i;
char *p;
for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
p = (char *)adapter+atl1_gstrings_stats[i].stat_offset;
data[i] = (atl1_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
}
static int atl1_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
case ETH_SS_STATS:
return ARRAY_SIZE(atl1_gstrings_stats);
default:
return -EOPNOTSUPP;
}
}
static int atl1_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_TP);
ecmd->advertising = ADVERTISED_TP;
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL) {
ecmd->advertising |= ADVERTISED_Autoneg;
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) {
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->advertising |=
(ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Full);
}
else
ecmd->advertising |= (ADVERTISED_1000baseT_Full);
}
ecmd->port = PORT_TP;
ecmd->phy_address = 0;
ecmd->transceiver = XCVR_INTERNAL;
if (netif_carrier_ok(adapter->netdev)) {
u16 link_speed, link_duplex;
atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
ecmd->speed = link_speed;
if (link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ecmd->speed = -1;
ecmd->duplex = -1;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL)
ecmd->autoneg = AUTONEG_ENABLE;
else
ecmd->autoneg = AUTONEG_DISABLE;
return 0;
}
static int atl1_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
u16 phy_data;
int ret_val = 0;
u16 old_media_type = hw->media_type;
if (netif_running(adapter->netdev)) {
dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
atl1_down(adapter);
}
if (ecmd->autoneg == AUTONEG_ENABLE)
hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
else {
if (ecmd->speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
dev_warn(&adapter->pdev->dev,
"can't force to 1000M half duplex\n");
ret_val = -EINVAL;
goto exit_sset;
}
hw->media_type = MEDIA_TYPE_1000M_FULL;
} else if (ecmd->speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL) {
hw->media_type = MEDIA_TYPE_100M_FULL;
} else
hw->media_type = MEDIA_TYPE_100M_HALF;
} else {
if (ecmd->duplex == DUPLEX_FULL)
hw->media_type = MEDIA_TYPE_10M_FULL;
else
hw->media_type = MEDIA_TYPE_10M_HALF;
}
}
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
ecmd->advertising =
ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Full |
ADVERTISED_Autoneg | ADVERTISED_TP;
break;
case MEDIA_TYPE_1000M_FULL:
ecmd->advertising =
ADVERTISED_1000baseT_Full |
ADVERTISED_Autoneg | ADVERTISED_TP;
break;
default:
ecmd->advertising = 0;
break;
}
if (atl1_phy_setup_autoneg_adv(hw)) {
ret_val = -EINVAL;
dev_warn(&adapter->pdev->dev,
"invalid ethtool speed/duplex setting\n");
goto exit_sset;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL)
phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
else {
switch (hw->media_type) {
case MEDIA_TYPE_100M_FULL:
phy_data =
MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
MII_CR_RESET;
break;
case MEDIA_TYPE_100M_HALF:
phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
break;
case MEDIA_TYPE_10M_FULL:
phy_data =
MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
break;
default: /* MEDIA_TYPE_10M_HALF: */
phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
break;
}
}
atl1_write_phy_reg(hw, MII_BMCR, phy_data);
exit_sset:
if (ret_val)
hw->media_type = old_media_type;
if (netif_running(adapter->netdev)) {
dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
atl1_up(adapter);
} else if (!ret_val) {
dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
atl1_reset(adapter);
}
return ret_val;
}
static void atl1_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
strncpy(drvinfo->driver, atl1_driver_name, sizeof(drvinfo->driver));
strncpy(drvinfo->version, atl1_driver_version,
sizeof(drvinfo->version));
strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->eedump_len = ATL1_EEDUMP_LEN;
}
static void atl1_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0;
if (adapter->wol & ATL1_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & ATL1_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & ATL1_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & ATL1_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
return;
}
static int atl1_set_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;
adapter->wol = 0;
if (wol->wolopts & WAKE_UCAST)
adapter->wol |= ATL1_WUFC_EX;
if (wol->wolopts & WAKE_MCAST)
adapter->wol |= ATL1_WUFC_MC;
if (wol->wolopts & WAKE_BCAST)
adapter->wol |= ATL1_WUFC_BC;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= ATL1_WUFC_MAG;
return 0;
}
static void atl1_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_tpd_ring *txdr = &adapter->tpd_ring;
struct atl1_rfd_ring *rxdr = &adapter->rfd_ring;
ring->rx_max_pending = ATL1_MAX_RFD;
ring->tx_max_pending = ATL1_MAX_TPD;
ring->rx_mini_max_pending = 0;
ring->rx_jumbo_max_pending = 0;
ring->rx_pending = rxdr->count;
ring->tx_pending = txdr->count;
ring->rx_mini_pending = 0;
ring->rx_jumbo_pending = 0;
}
static int atl1_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_tpd_ring *tpdr = &adapter->tpd_ring;
struct atl1_rrd_ring *rrdr = &adapter->rrd_ring;
struct atl1_rfd_ring *rfdr = &adapter->rfd_ring;
struct atl1_tpd_ring tpd_old, tpd_new;
struct atl1_rfd_ring rfd_old, rfd_new;
struct atl1_rrd_ring rrd_old, rrd_new;
struct atl1_ring_header rhdr_old, rhdr_new;
int err;
tpd_old = adapter->tpd_ring;
rfd_old = adapter->rfd_ring;
rrd_old = adapter->rrd_ring;
rhdr_old = adapter->ring_header;
if (netif_running(adapter->netdev))
atl1_down(adapter);
rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD);
rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD :
rfdr->count;
rfdr->count = (rfdr->count + 3) & ~3;
rrdr->count = rfdr->count;
tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD);
tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD :
tpdr->count;
tpdr->count = (tpdr->count + 3) & ~3;
if (netif_running(adapter->netdev)) {
/* try to get new resources before deleting old */
err = atl1_setup_ring_resources(adapter);
if (err)
goto err_setup_ring;
/*
* save the new, restore the old in order to free it,
* then restore the new back again
*/
rfd_new = adapter->rfd_ring;
rrd_new = adapter->rrd_ring;
tpd_new = adapter->tpd_ring;
rhdr_new = adapter->ring_header;
adapter->rfd_ring = rfd_old;
adapter->rrd_ring = rrd_old;
adapter->tpd_ring = tpd_old;
adapter->ring_header = rhdr_old;
atl1_free_ring_resources(adapter);
adapter->rfd_ring = rfd_new;
adapter->rrd_ring = rrd_new;
adapter->tpd_ring = tpd_new;
adapter->ring_header = rhdr_new;
err = atl1_up(adapter);
if (err)
return err;
}
return 0;
err_setup_ring:
adapter->rfd_ring = rfd_old;
adapter->rrd_ring = rrd_old;
adapter->tpd_ring = tpd_old;
adapter->ring_header = rhdr_old;
atl1_up(adapter);
return err;
}
static void atl1_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *epause)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL) {
epause->autoneg = AUTONEG_ENABLE;
} else {
epause->autoneg = AUTONEG_DISABLE;
}
epause->rx_pause = 1;
epause->tx_pause = 1;
}
static int atl1_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *epause)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL) {
epause->autoneg = AUTONEG_ENABLE;
} else {
epause->autoneg = AUTONEG_DISABLE;
}
epause->rx_pause = 1;
epause->tx_pause = 1;
return 0;
}
static u32 atl1_get_rx_csum(struct net_device *netdev)
{
return 1;
}
static void atl1_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
u8 *p = data;
int i;
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
memcpy(p, atl1_gstrings_stats[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
break;
}
}
static int atl1_nway_reset(struct net_device *netdev)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
if (netif_running(netdev)) {
u16 phy_data;
atl1_down(adapter);
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL) {
phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
} else {
switch (hw->media_type) {
case MEDIA_TYPE_100M_FULL:
phy_data = MII_CR_FULL_DUPLEX |
MII_CR_SPEED_100 | MII_CR_RESET;
break;
case MEDIA_TYPE_100M_HALF:
phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
break;
case MEDIA_TYPE_10M_FULL:
phy_data = MII_CR_FULL_DUPLEX |
MII_CR_SPEED_10 | MII_CR_RESET;
break;
default: /* MEDIA_TYPE_10M_HALF */
phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
}
}
atl1_write_phy_reg(hw, MII_BMCR, phy_data);
atl1_up(adapter);
}
return 0;
}
const struct ethtool_ops atl1_ethtool_ops = {
.get_settings = atl1_get_settings,
.set_settings = atl1_set_settings,
.get_drvinfo = atl1_get_drvinfo,
.get_wol = atl1_get_wol,
.set_wol = atl1_set_wol,
.get_ringparam = atl1_get_ringparam,
.set_ringparam = atl1_set_ringparam,
.get_pauseparam = atl1_get_pauseparam,
.set_pauseparam = atl1_set_pauseparam,
.get_rx_csum = atl1_get_rx_csum,
.set_tx_csum = ethtool_op_set_tx_hw_csum,
.get_link = ethtool_op_get_link,
.set_sg = ethtool_op_set_sg,
.get_strings = atl1_get_strings,
.nway_reset = atl1_nway_reset,
.get_ethtool_stats = atl1_get_ethtool_stats,
.get_sset_count = atl1_get_sset_count,
.set_tso = ethtool_op_set_tso,
};
/*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include <asm/byteorder.h>
#include "atl1.h"
/*
* Reset the transmit and receive units; mask and clear all interrupts.
* hw - Struct containing variables accessed by shared code
* return : ATL1_SUCCESS or idle status (if error)
*/
s32 atl1_reset_hw(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
u32 icr;
int i;
/*
* Clear Interrupt mask to stop board from generating
* interrupts & Clear any pending interrupt events
*/
/*
* iowrite32(0, hw->hw_addr + REG_IMR);
* iowrite32(0xffffffff, hw->hw_addr + REG_ISR);
*/
/*
* Issue Soft Reset to the MAC. This will reset the chip's
* transmit, receive, DMA. It will not effect
* the current PCI configuration. The global reset bit is self-
* clearing, and should clear within a microsecond.
*/
iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL);
ioread32(hw->hw_addr + REG_MASTER_CTRL);
iowrite16(1, hw->hw_addr + REG_GPHY_ENABLE);
ioread16(hw->hw_addr + REG_GPHY_ENABLE);
msleep(1); /* delay about 1ms */
/* Wait at least 10ms for All module to be Idle */
for (i = 0; i < 10; i++) {
icr = ioread32(hw->hw_addr + REG_IDLE_STATUS);
if (!icr)
break;
msleep(1); /* delay 1 ms */
cpu_relax(); /* FIXME: is this still the right way to do this? */
}
if (icr) {
dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
return icr;
}
return ATL1_SUCCESS;
}
/* function about EEPROM
*
* check_eeprom_exist
* return 0 if eeprom exist
*/
static int atl1_check_eeprom_exist(struct atl1_hw *hw)
{
u32 value;
value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
if (value & SPI_FLASH_CTRL_EN_VPD) {
value &= ~SPI_FLASH_CTRL_EN_VPD;
iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
}
value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST);
return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
}
static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
{
int i;
u32 control;
if (offset & 3)
return false; /* address do not align */
iowrite32(0, hw->hw_addr + REG_VPD_DATA);
control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
iowrite32(control, hw->hw_addr + REG_VPD_CAP);
ioread32(hw->hw_addr + REG_VPD_CAP);
for (i = 0; i < 10; i++) {
msleep(2);
control = ioread32(hw->hw_addr + REG_VPD_CAP);
if (control & VPD_CAP_VPD_FLAG)
break;
}
if (control & VPD_CAP_VPD_FLAG) {
*p_value = ioread32(hw->hw_addr + REG_VPD_DATA);
return true;
}
return false; /* timeout */
}
/*
* Reads the value from a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
*/
s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
{
u32 val;
int i;
val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
MDIO_CLK_SEL_SHIFT;
iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
ioread32(hw->hw_addr + REG_MDIO_CTRL);
for (i = 0; i < MDIO_WAIT_TIMES; i++) {
udelay(2);
val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
}
if (!(val & (MDIO_START | MDIO_BUSY))) {
*phy_data = (u16) val;
return ATL1_SUCCESS;
}
return ATL1_ERR_PHY;
}
#define CUSTOM_SPI_CS_SETUP 2
#define CUSTOM_SPI_CLK_HI 2
#define CUSTOM_SPI_CLK_LO 2
#define CUSTOM_SPI_CS_HOLD 2
#define CUSTOM_SPI_CS_HI 3
static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
{
int i;
u32 value;
iowrite32(0, hw->hw_addr + REG_SPI_DATA);
iowrite32(addr, hw->hw_addr + REG_SPI_ADDR);
value = SPI_FLASH_CTRL_WAIT_READY |
(CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI &
SPI_FLASH_CTRL_CLK_HI_MASK) <<
SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO &
SPI_FLASH_CTRL_CLK_LO_MASK) <<
SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD &
SPI_FLASH_CTRL_CS_HOLD_MASK) <<
SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI &
SPI_FLASH_CTRL_CS_HI_MASK) <<
SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) <<
SPI_FLASH_CTRL_INS_SHIFT;
iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
value |= SPI_FLASH_CTRL_START;
iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
for (i = 0; i < 10; i++) {
msleep(1); /* 1ms */
value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
if (!(value & SPI_FLASH_CTRL_START))
break;
}
if (value & SPI_FLASH_CTRL_START)
return false;
*buf = ioread32(hw->hw_addr + REG_SPI_DATA);
return true;
}
/*
* get_permanent_address
* return 0 if get valid mac address,
*/
static int atl1_get_permanent_address(struct atl1_hw *hw)
{
u32 addr[2];
u32 i, control;
u16 reg;
u8 eth_addr[ETH_ALEN];
bool key_valid;
if (is_valid_ether_addr(hw->perm_mac_addr))
return 0;
/* init */
addr[0] = addr[1] = 0;
if (!atl1_check_eeprom_exist(hw)) { /* eeprom exist */
reg = 0;
key_valid = false;
/* Read out all EEPROM content */
i = 0;
while (1) {
if (atl1_read_eeprom(hw, i + 0x100, &control)) {
if (key_valid) {
if (reg == REG_MAC_STA_ADDR)
addr[0] = control;
else if (reg == (REG_MAC_STA_ADDR + 4))
addr[1] = control;
key_valid = false;
} else if ((control & 0xff) == 0x5A) {
key_valid = true;
reg = (u16) (control >> 16);
} else
break; /* assume data end while encount an invalid KEYWORD */
} else
break; /* read error */
i += 4;
}
*(u32 *) &eth_addr[2] = swab32(addr[0]);
*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
if (is_valid_ether_addr(eth_addr)) {
memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
return 0;
}
return 1;
}
/* see if SPI FLAGS exist ? */
addr[0] = addr[1] = 0;
reg = 0;
key_valid = false;
i = 0;
while (1) {
if (atl1_spi_read(hw, i + 0x1f000, &control)) {
if (key_valid) {
if (reg == REG_MAC_STA_ADDR)
addr[0] = control;
else if (reg == (REG_MAC_STA_ADDR + 4))
addr[1] = control;
key_valid = false;
} else if ((control & 0xff) == 0x5A) {
key_valid = true;
reg = (u16) (control >> 16);
} else
break; /* data end */
} else
break; /* read error */
i += 4;
}
*(u32 *) &eth_addr[2] = swab32(addr[0]);
*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
if (is_valid_ether_addr(eth_addr)) {
memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
return 0;
}
/*
* On some motherboards, the MAC address is written by the
* BIOS directly to the MAC register during POST, and is
* not stored in eeprom. If all else thus far has failed
* to fetch the permanent MAC address, try reading it directly.
*/
addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
*(u32 *) &eth_addr[2] = swab32(addr[0]);
*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
if (is_valid_ether_addr(eth_addr)) {
memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
return 0;
}
return 1;
}
/*
* Reads the adapter's MAC address from the EEPROM
* hw - Struct containing variables accessed by shared code
*/
s32 atl1_read_mac_addr(struct atl1_hw *hw)
{
u16 i;
if (atl1_get_permanent_address(hw))
random_ether_addr(hw->perm_mac_addr);
for (i = 0; i < ETH_ALEN; i++)
hw->mac_addr[i] = hw->perm_mac_addr[i];
return ATL1_SUCCESS;
}
/*
* Hashes an address to determine its location in the multicast table
* hw - Struct containing variables accessed by shared code
* mc_addr - the multicast address to hash
*
* atl1_hash_mc_addr
* purpose
* set hash value for a multicast address
* hash calcu processing :
* 1. calcu 32bit CRC for multicast address
* 2. reverse crc with MSB to LSB
*/
u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
{
u32 crc32, value = 0;
int i;
crc32 = ether_crc_le(6, mc_addr);
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
return value;
}
/*
* Sets the bit in the multicast table corresponding to the hash value.
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*/
void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
{
u32 hash_bit, hash_reg;
u32 mta;
/*
* The HASH Table is a register array of 2 32-bit registers.
* It is treated like an array of 64 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the
* upper 7 bits of the hash value and the bit within that
* register are determined by the lower 5 bits of the value.
*/
hash_reg = (hash_value >> 31) & 0x1;
hash_bit = (hash_value >> 26) & 0x1F;
mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
mta |= (1 << hash_bit);
iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
}
/*
* Writes a value to a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to write
* data - data to write to the PHY
*/
s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data)
{
int i;
u32 val;
val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
(reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
MDIO_SUP_PREAMBLE |
MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
ioread32(hw->hw_addr + REG_MDIO_CTRL);
for (i = 0; i < MDIO_WAIT_TIMES; i++) {
udelay(2);
val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
}
if (!(val & (MDIO_START | MDIO_BUSY)))
return ATL1_SUCCESS;
return ATL1_ERR_PHY;
}
/*
* Make L001's PHY out of Power Saving State (bug)
* hw - Struct containing variables accessed by shared code
* when power on, L001's PHY always on Power saving State
* (Gigabit Link forbidden)
*/
static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
{
s32 ret;
ret = atl1_write_phy_reg(hw, 29, 0x0029);
if (ret)
return ret;
return atl1_write_phy_reg(hw, 30, 0);
}
/*
*TODO: do something or get rid of this
*/
s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
{
/* s32 ret_val;
* u16 phy_data;
*/
/*
ret_val = atl1_write_phy_reg(hw, ...);
ret_val = atl1_write_phy_reg(hw, ...);
....
*/
return ATL1_SUCCESS;
}
/*
* Resets the PHY and make all config validate
* hw - Struct containing variables accessed by shared code
*
* Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
*/
static s32 atl1_phy_reset(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL)
phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
else {
switch (hw->media_type) {
case MEDIA_TYPE_100M_FULL:
phy_data =
MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
MII_CR_RESET;
break;
case MEDIA_TYPE_100M_HALF:
phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
break;
case MEDIA_TYPE_10M_FULL:
phy_data =
MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
break;
default: /* MEDIA_TYPE_10M_HALF: */
phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
break;
}
}
ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data);
if (ret_val) {
u32 val;
int i;
/* pcie serdes link may be down! */
dev_dbg(&pdev->dev, "pcie phy link down\n");
for (i = 0; i < 25; i++) {
msleep(1);
val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
if (!(val & (MDIO_START | MDIO_BUSY)))
break;
}
if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
return ret_val;
}
}
return ATL1_SUCCESS;
}
/*
* Configures PHY autoneg and flow control advertisement settings
* hw - Struct containing variables accessed by shared code
*/
s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
{
s32 ret_val;
s16 mii_autoneg_adv_reg;
s16 mii_1000t_ctrl_reg;
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
/* Read the MII 1000Base-T Control Register (Address 9). */
mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
/*
* First we clear all the 10/100 mb speed bits in the Auto-Neg
* Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T Control Register (Address 9).
*/
mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK;
/*
* Need to parse media_type and set up
* the appropriate PHY registers.
*/
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
MII_AR_10T_FD_CAPS |
MII_AR_100TX_HD_CAPS |
MII_AR_100TX_FD_CAPS);
mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS;
break;
case MEDIA_TYPE_1000M_FULL:
mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS;
break;
case MEDIA_TYPE_100M_FULL:
mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
break;
case MEDIA_TYPE_100M_HALF:
mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
break;
case MEDIA_TYPE_10M_FULL:
mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
break;
default:
mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
break;
}
/* flow control fixed to enable all */
mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
if (ret_val)
return ret_val;
ret_val = atl1_write_phy_reg(hw, MII_AT001_CR, mii_1000t_ctrl_reg);
if (ret_val)
return ret_val;
return ATL1_SUCCESS;
}
/*
* Configures link settings.
* hw - Struct containing variables accessed by shared code
* Assumes the hardware has previously been reset and the
* transmitter and receiver are not enabled.
*/
static s32 atl1_setup_link(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
/*
* Options:
* PHY will advertise value(s) parsed from
* autoneg_advertised and fc
* no matter what autoneg is , We will not wait link result.
*/
ret_val = atl1_phy_setup_autoneg_adv(hw);
if (ret_val) {
dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
return ret_val;
}
/* SW.Reset , En-Auto-Neg if needed */
ret_val = atl1_phy_reset(hw);
if (ret_val) {
dev_dbg(&pdev->dev, "error resetting phy\n");
return ret_val;
}
hw->phy_configured = true;
return ret_val;
}
static struct atl1_spi_flash_dev flash_table[] = {
/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */
{"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62},
{"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60},
{"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7},
};
static void atl1_init_flash_opcode(struct atl1_hw *hw)
{
if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
hw->flash_vendor = 0; /* ATMEL */
/* Init OP table */
iowrite8(flash_table[hw->flash_vendor].cmd_program,
hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM);
iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase,
hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE);
iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase,
hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE);
iowrite8(flash_table[hw->flash_vendor].cmd_rdid,
hw->hw_addr + REG_SPI_FLASH_OP_RDID);
iowrite8(flash_table[hw->flash_vendor].cmd_wren,
hw->hw_addr + REG_SPI_FLASH_OP_WREN);
iowrite8(flash_table[hw->flash_vendor].cmd_rdsr,
hw->hw_addr + REG_SPI_FLASH_OP_RDSR);
iowrite8(flash_table[hw->flash_vendor].cmd_wrsr,
hw->hw_addr + REG_SPI_FLASH_OP_WRSR);
iowrite8(flash_table[hw->flash_vendor].cmd_read,
hw->hw_addr + REG_SPI_FLASH_OP_READ);
}
/*
* Performs basic configuration of the adapter.
* hw - Struct containing variables accessed by shared code
* Assumes that the controller has previously been reset and is in a
* post-reset uninitialized state. Initializes multicast table,
* and Calls routines to setup link
* Leaves the transmit and receive units disabled and uninitialized.
*/
s32 atl1_init_hw(struct atl1_hw *hw)
{
u32 ret_val = 0;
/* Zero out the Multicast HASH table */
iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
/* clear the old settings from the multicast hash table */
iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
atl1_init_flash_opcode(hw);
if (!hw->phy_configured) {
/* enable GPHY LinkChange Interrrupt */
ret_val = atl1_write_phy_reg(hw, 18, 0xC00);
if (ret_val)
return ret_val;
/* make PHY out of power-saving state */
ret_val = atl1_phy_leave_power_saving(hw);
if (ret_val)
return ret_val;
/* Call a subroutine to configure the link */
ret_val = atl1_setup_link(hw);
}
return ret_val;
}
/*
* Detects the current speed and duplex settings of the hardware.
* hw - Struct containing variables accessed by shared code
* speed - Speed of the connection
* duplex - Duplex setting of the connection
*/
s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
/* ; --- Read PHY Specific Status Register (17) */
ret_val = atl1_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
if (ret_val)
return ret_val;
if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
return ATL1_ERR_PHY_RES;
switch (phy_data & MII_AT001_PSSR_SPEED) {
case MII_AT001_PSSR_1000MBS:
*speed = SPEED_1000;
break;
case MII_AT001_PSSR_100MBS:
*speed = SPEED_100;
break;
case MII_AT001_PSSR_10MBS:
*speed = SPEED_10;
break;
default:
dev_dbg(&pdev->dev, "error getting speed\n");
return ATL1_ERR_PHY_SPEED;
break;
}
if (phy_data & MII_AT001_PSSR_DPLX)
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
return ATL1_SUCCESS;
}
void atl1_set_mac_addr(struct atl1_hw *hw)
{
u32 value;
/*
* 00-0B-6A-F6-00-DC
* 0: 6AF600DC 1: 000B
* low dword
*/
value = (((u32) hw->mac_addr[2]) << 24) |
(((u32) hw->mac_addr[3]) << 16) |
(((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5]));
iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR);
/* high dword */
value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2));
}
此差异已折叠。
obj-$(CONFIG_ATL1) += atl1.o obj-$(CONFIG_ATL1) += atl1.o
atl1-y += atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o
此差异已折叠。
/* /* atlx.c -- common functions for Attansic network drivers
*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com> * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com> * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
* *
* Derived from Intel e1000 driver * Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
...@@ -21,10 +23,235 @@ ...@@ -21,10 +23,235 @@
* Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* Including this file like a header is a temporary hack, I promise. -- CHS */
#ifndef ATLX_C
#define ATLX_C
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/moduleparam.h> #include <linux/workqueue.h>
#include <linux/pci.h>
#include "atl1.h" #include "atlx.h"
static struct atlx_spi_flash_dev flash_table[] = {
/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SEC_ERS CHIP_ERS */
{"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62},
{"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60},
{"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7},
};
static int atlx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCGMIIPHY:
case SIOCGMIIREG:
case SIOCSMIIREG:
return atlx_mii_ioctl(netdev, ifr, cmd);
default:
return -EOPNOTSUPP;
}
}
/*
* atlx_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
*
* Returns 0 on success, negative on failure
*/
static int atlx_set_mac(struct net_device *netdev, void *p)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
if (netif_running(netdev))
return -EBUSY;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
atlx_set_mac_addr(&adapter->hw);
return 0;
}
static void atlx_check_for_link(struct atlx_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
u16 phy_data = 0;
spin_lock(&adapter->lock);
adapter->phy_timer_pending = false;
atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
spin_unlock(&adapter->lock);
/* notify upper layer link down ASAP */
if (!(phy_data & BMSR_LSTATUS)) {
/* Link Down */
if (netif_carrier_ok(netdev)) {
/* old link state: Up */
dev_info(&adapter->pdev->dev, "%s link is down\n",
netdev->name);
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
}
schedule_work(&adapter->link_chg_task);
}
/*
* atlx_set_multi - Multicast and Promiscuous mode set
* @netdev: network interface device structure
*
* The set_multi entry point is called whenever the multicast address
* list or the network interface flags are updated. This routine is
* responsible for configuring the hardware for proper multicast,
* promiscuous mode, and all-multi behavior.
*/
static void atlx_set_multi(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
struct atlx_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
u32 rctl;
u32 hash_value;
/* Check for Promiscuous and All Multicast modes */
rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
if (netdev->flags & IFF_PROMISC)
rctl |= MAC_CTRL_PROMIS_EN;
else if (netdev->flags & IFF_ALLMULTI) {
rctl |= MAC_CTRL_MC_ALL_EN;
rctl &= ~MAC_CTRL_PROMIS_EN;
} else
rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
/* clear the old settings from the multicast hash table */
iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
/* compute mc addresses' hash value ,and put it into hash table */
for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr);
atlx_hash_set(hw, hash_value);
}
}
/*
* atlx_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
*/
static void atlx_irq_enable(struct atlx_adapter *adapter)
{
iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
ioread32(adapter->hw.hw_addr + REG_IMR);
}
/*
* atlx_irq_disable - Mask off interrupt generation on the NIC
* @adapter: board private structure
*/
static void atlx_irq_disable(struct atlx_adapter *adapter)
{
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
ioread32(adapter->hw.hw_addr + REG_IMR);
synchronize_irq(adapter->pdev->irq);
}
static void atlx_clear_phy_int(struct atlx_adapter *adapter)
{
u16 phy_data;
unsigned long flags;
spin_lock_irqsave(&adapter->lock, flags);
atlx_read_phy_reg(&adapter->hw, 19, &phy_data);
spin_unlock_irqrestore(&adapter->lock, flags);
}
/*
* atlx_get_stats - Get System Network Statistics
* @netdev: network interface device structure
*
* Returns the address of the device statistics structure.
* The statistics are actually updated from the timer callback.
*/
static struct net_device_stats *atlx_get_stats(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
return &adapter->net_stats;
}
/*
* atlx_tx_timeout - Respond to a Tx Hang
* @netdev: network interface device structure
*/
static void atlx_tx_timeout(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */
schedule_work(&adapter->tx_timeout_task);
}
/*
* atlx_link_chg_task - deal with link change event Out of interrupt context
*/
static void atlx_link_chg_task(struct work_struct *work)
{
struct atlx_adapter *adapter;
unsigned long flags;
adapter = container_of(work, struct atlx_adapter, link_chg_task);
spin_lock_irqsave(&adapter->lock, flags);
atlx_check_link(adapter);
spin_unlock_irqrestore(&adapter->lock, flags);
}
static void atlx_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
unsigned long flags;
u32 ctrl;
spin_lock_irqsave(&adapter->lock, flags);
/* atlx_irq_disable(adapter); FIXME: confirm/remove */
adapter->vlgrp = grp;
if (grp) {
/* enable VLAN tag insert/strip */
ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
ctrl |= MAC_CTRL_RMV_VLAN;
iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
} else {
/* disable VLAN tag insert/strip */
ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
ctrl &= ~MAC_CTRL_RMV_VLAN;
iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
}
/* atlx_irq_enable(adapter); FIXME */
spin_unlock_irqrestore(&adapter->lock, flags);
}
static void atlx_restore_vlan(struct atlx_adapter *adapter)
{
atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
}
/* /*
* This is the only thing that needs to be changed to adjust the * This is the only thing that needs to be changed to adjust the
...@@ -46,8 +273,9 @@ ...@@ -46,8 +273,9 @@
* Default Value: 100 (200us) * Default Value: 100 (200us)
*/ */
static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
static int num_int_mod_timer = 0; static int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int, &num_int_mod_timer, 0); module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
/* /*
...@@ -62,7 +290,7 @@ MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); ...@@ -62,7 +290,7 @@ MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
* Default Value: 0 * Default Value: 0
*/ */
static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
static int num_flash_vendor = 0; static int num_flash_vendor;
module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0); module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0);
MODULE_PARM_DESC(flash_vendor, "SPI flash vendor"); MODULE_PARM_DESC(flash_vendor, "SPI flash vendor");
...@@ -94,7 +322,8 @@ struct atl1_option { ...@@ -94,7 +322,8 @@ struct atl1_option {
} arg; } arg;
}; };
static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev) static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
struct pci_dev *pdev)
{ {
if (*value == OPTION_UNSET) { if (*value == OPTION_UNSET) {
*value = opt->def; *value = opt->def;
...@@ -169,8 +398,8 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) ...@@ -169,8 +398,8 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
.err = "using default of " .err = "using default of "
__MODULE_STRING(DEFAULT_INT_MOD_CNT), __MODULE_STRING(DEFAULT_INT_MOD_CNT),
.def = DEFAULT_INT_MOD_CNT, .def = DEFAULT_INT_MOD_CNT,
.arg = {.r = .arg = {.r = {.min = MIN_INT_MOD_CNT,
{.min = MIN_INT_MOD_CNT,.max = MAX_INT_MOD_CNT}} .max = MAX_INT_MOD_CNT} }
}; };
int val; int val;
if (num_int_mod_timer > bd) { if (num_int_mod_timer > bd) {
...@@ -188,9 +417,8 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) ...@@ -188,9 +417,8 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
.err = "using default of " .err = "using default of "
__MODULE_STRING(FLASH_VENDOR_DEFAULT), __MODULE_STRING(FLASH_VENDOR_DEFAULT),
.def = DEFAULT_INT_MOD_CNT, .def = DEFAULT_INT_MOD_CNT,
.arg = {.r = .arg = {.r = {.min = FLASH_VENDOR_MIN,
{.min = FLASH_VENDOR_MIN,.max = .max = FLASH_VENDOR_MAX} }
FLASH_VENDOR_MAX}}
}; };
int val; int val;
if (num_flash_vendor > bd) { if (num_flash_vendor > bd) {
...@@ -201,3 +429,5 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) ...@@ -201,3 +429,5 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
adapter->hw.flash_vendor = (u8) (opt.def); adapter->hw.flash_vendor = (u8) (opt.def);
} }
} }
#endif /* ATLX_C */
/* atlx_hw.h -- common hardware definitions for Attansic network drivers
*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ATLX_H
#define ATLX_H
#include <linux/module.h>
#include <linux/types.h>
#define ATLX_DRIVER_VERSION "2.1.1"
MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION(ATLX_DRIVER_VERSION);
#define ATLX_ERR_PHY 2
#define ATLX_ERR_PHY_SPEED 7
#define ATLX_ERR_PHY_RES 8
#define SPEED_0 0xffff
#define SPEED_10 10
#define SPEED_100 100
#define SPEED_1000 1000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define MEDIA_TYPE_AUTO_SENSOR 0
/* register definitions */
#define REG_PM_CTRLSTAT 0x44
#define REG_PCIE_CAP_LIST 0x58
#define REG_VPD_CAP 0x6C
#define VPD_CAP_ID_MASK 0xFF
#define VPD_CAP_ID_SHIFT 0
#define VPD_CAP_NEXT_PTR_MASK 0xFF
#define VPD_CAP_NEXT_PTR_SHIFT 8
#define VPD_CAP_VPD_ADDR_MASK 0x7FFF
#define VPD_CAP_VPD_ADDR_SHIFT 16
#define VPD_CAP_VPD_FLAG 0x80000000
#define REG_VPD_DATA 0x70
#define REG_SPI_FLASH_CTRL 0x200
#define SPI_FLASH_CTRL_STS_NON_RDY 0x1
#define SPI_FLASH_CTRL_STS_WEN 0x2
#define SPI_FLASH_CTRL_STS_WPEN 0x80
#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF
#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0
#define SPI_FLASH_CTRL_INS_MASK 0x7
#define SPI_FLASH_CTRL_INS_SHIFT 8
#define SPI_FLASH_CTRL_START 0x800
#define SPI_FLASH_CTRL_EN_VPD 0x2000
#define SPI_FLASH_CTRL_LDSTART 0x8000
#define SPI_FLASH_CTRL_CS_HI_MASK 0x3
#define SPI_FLASH_CTRL_CS_HI_SHIFT 16
#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3
#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18
#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3
#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20
#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3
#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22
#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3
#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24
#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3
#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26
#define SPI_FLASH_CTRL_WAIT_READY 0x10000000
#define REG_SPI_ADDR 0x204
#define REG_SPI_DATA 0x208
#define REG_SPI_FLASH_CONFIG 0x20C
#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF
#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0
#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3
#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000
#define REG_SPI_FLASH_OP_PROGRAM 0x210
#define REG_SPI_FLASH_OP_SC_ERASE 0x211
#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
#define REG_SPI_FLASH_OP_RDID 0x213
#define REG_SPI_FLASH_OP_WREN 0x214
#define REG_SPI_FLASH_OP_RDSR 0x215
#define REG_SPI_FLASH_OP_WRSR 0x216
#define REG_SPI_FLASH_OP_READ 0x217
#define REG_TWSI_CTRL 0x218
#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
#define TWSI_CTRL_LD_OFFSET_SHIFT 0
#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7
#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8
#define TWSI_CTRL_SW_LDSTART 0x800
#define TWSI_CTRL_HW_LDSTART 0x1000
#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F
#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15
#define TWSI_CTRL_LD_EXIST 0x400000
#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3
#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23
#define TWSI_CTRL_FREQ_SEL_100K 0
#define TWSI_CTRL_FREQ_SEL_200K 1
#define TWSI_CTRL_FREQ_SEL_300K 2
#define TWSI_CTRL_FREQ_SEL_400K 3
#define TWSI_CTRL_SMB_SLV_ADDR /* FIXME: define or remove */
#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3
#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
#define REG_PCIE_DEV_MISC_CTRL 0x21C
#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2
#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8
#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10
#define REG_PCIE_PHYMISC 0x1000
#define PCIE_PHYMISC_FORCE_RCV_DET 0x4
#define REG_PCIE_DLL_TX_CTRL1 0x1104
#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK 0x400
#define PCIE_DLL_TX_CTRL1_DEF 0x568
#define REG_LTSSM_TEST_MODE 0x12FC
#define LTSSM_TEST_MODE_DEF 0x6500
/* Master Control Register */
#define REG_MASTER_CTRL 0x1400
#define MASTER_CTRL_SOFT_RST 0x1
#define MASTER_CTRL_MTIMER_EN 0x2
#define MASTER_CTRL_ITIMER_EN 0x4
#define MASTER_CTRL_MANUAL_INT 0x8
#define MASTER_CTRL_REV_NUM_SHIFT 16
#define MASTER_CTRL_REV_NUM_MASK 0xFF
#define MASTER_CTRL_DEV_ID_SHIFT 24
#define MASTER_CTRL_DEV_ID_MASK 0xFF
/* Timer Initial Value Register */
#define REG_MANUAL_TIMER_INIT 0x1404
/* IRQ Moderator Timer Initial Value Register */
#define REG_IRQ_MODU_TIMER_INIT 0x1408
#define REG_PHY_ENABLE 0x140C
/* IRQ Anti-Lost Timer Initial Value Register */
#define REG_CMBDISDMA_TIMER 0x140E
/* Block IDLE Status Register */
#define REG_IDLE_STATUS 0x1410
/* MDIO Control Register */
#define REG_MDIO_CTRL 0x1414
#define MDIO_DATA_MASK 0xFFFF
#define MDIO_DATA_SHIFT 0
#define MDIO_REG_ADDR_MASK 0x1F
#define MDIO_REG_ADDR_SHIFT 16
#define MDIO_RW 0x200000
#define MDIO_SUP_PREAMBLE 0x400000
#define MDIO_START 0x800000
#define MDIO_CLK_SEL_SHIFT 24
#define MDIO_CLK_25_4 0
#define MDIO_CLK_25_6 2
#define MDIO_CLK_25_8 3
#define MDIO_CLK_25_10 4
#define MDIO_CLK_25_14 5
#define MDIO_CLK_25_20 6
#define MDIO_CLK_25_28 7
#define MDIO_BUSY 0x8000000
/* MII PHY Status Register */
#define REG_PHY_STATUS 0x1418
/* BIST Control and Status Register0 (for the Packet Memory) */
#define REG_BIST0_CTRL 0x141C
#define BIST0_NOW 0x1
#define BIST0_SRAM_FAIL 0x2
#define BIST0_FUSE_FLAG 0x4
#define REG_BIST1_CTRL 0x1420
#define BIST1_NOW 0x1
#define BIST1_SRAM_FAIL 0x2
#define BIST1_FUSE_FLAG 0x4
/* SerDes Lock Detect Control and Status Register */
#define REG_SERDES_LOCK 0x1424
#define SERDES_LOCK_DETECT 1
#define SERDES_LOCK_DETECT_EN 2
/* MAC Control Register */
#define REG_MAC_CTRL 0x1480
#define MAC_CTRL_TX_EN 1
#define MAC_CTRL_RX_EN 2
#define MAC_CTRL_TX_FLOW 4
#define MAC_CTRL_RX_FLOW 8
#define MAC_CTRL_LOOPBACK 0x10
#define MAC_CTRL_DUPLX 0x20
#define MAC_CTRL_ADD_CRC 0x40
#define MAC_CTRL_PAD 0x80
#define MAC_CTRL_LENCHK 0x100
#define MAC_CTRL_HUGE_EN 0x200
#define MAC_CTRL_PRMLEN_SHIFT 10
#define MAC_CTRL_PRMLEN_MASK 0xF
#define MAC_CTRL_RMV_VLAN 0x4000
#define MAC_CTRL_PROMIS_EN 0x8000
#define MAC_CTRL_MC_ALL_EN 0x2000000
#define MAC_CTRL_BC_EN 0x4000000
/* MAC IPG/IFG Control Register */
#define REG_MAC_IPG_IFG 0x1484
#define MAC_IPG_IFG_IPGT_SHIFT 0
#define MAC_IPG_IFG_IPGT_MASK 0x7F
#define MAC_IPG_IFG_MIFG_SHIFT 8
#define MAC_IPG_IFG_MIFG_MASK 0xFF
#define MAC_IPG_IFG_IPGR1_SHIFT 16
#define MAC_IPG_IFG_IPGR1_MASK 0x7F
#define MAC_IPG_IFG_IPGR2_SHIFT 24
#define MAC_IPG_IFG_IPGR2_MASK 0x7F
/* MAC STATION ADDRESS */
#define REG_MAC_STA_ADDR 0x1488
/* Hash table for multicast address */
#define REG_RX_HASH_TABLE 0x1490
/* MAC Half-Duplex Control Register */
#define REG_MAC_HALF_DUPLX_CTRL 0x1498
#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0
#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3FF
#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xF
#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000
#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000
#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20
#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xF
#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24
#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xF
/* Maximum Frame Length Control Register */
#define REG_MTU 0x149C
/* Wake-On-Lan control register */
#define REG_WOL_CTRL 0x14A0
#define WOL_PATTERN_EN 0x1
#define WOL_PATTERN_PME_EN 0x2
#define WOL_MAGIC_EN 0x4
#define WOL_MAGIC_PME_EN 0x8
#define WOL_LINK_CHG_EN 0x10
#define WOL_LINK_CHG_PME_EN 0x20
#define WOL_PATTERN_ST 0x100
#define WOL_MAGIC_ST 0x200
#define WOL_LINKCHG_ST 0x400
#define WOL_PT0_EN 0x10000
#define WOL_PT1_EN 0x20000
#define WOL_PT2_EN 0x40000
#define WOL_PT3_EN 0x80000
#define WOL_PT4_EN 0x100000
#define WOL_PT0_MATCH 0x1000000
#define WOL_PT1_MATCH 0x2000000
#define WOL_PT2_MATCH 0x4000000
#define WOL_PT3_MATCH 0x8000000
#define WOL_PT4_MATCH 0x10000000
/* Internal SRAM Partition Register, high 32 bits */
#define REG_SRAM_RFD_ADDR 0x1500
/* Descriptor Control register, high 32 bits */
#define REG_DESC_BASE_ADDR_HI 0x1540
/* Interrupt Status Register */
#define REG_ISR 0x1600
#define ISR_UR_DETECTED 0x1000000
#define ISR_FERR_DETECTED 0x2000000
#define ISR_NFERR_DETECTED 0x4000000
#define ISR_CERR_DETECTED 0x8000000
#define ISR_PHY_LINKDOWN 0x10000000
#define ISR_DIS_INT 0x80000000
/* Interrupt Mask Register */
#define REG_IMR 0x1604
#define REG_RFD_RRD_IDX 0x1800
#define REG_TPD_IDX 0x1804
/* MII definitions */
/* PHY Common Register */
#define MII_ATLX_CR 0x09
#define MII_ATLX_SR 0x0A
#define MII_ATLX_ESR 0x0F
#define MII_ATLX_PSCR 0x10
#define MII_ATLX_PSSR 0x11
/* PHY Control Register */
#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100,
* 00=10
*/
#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
#define MII_CR_POWER_DOWN 0x0800 /* Power down */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100,
* 00=10
*/
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
#define MII_CR_SPEED_MASK 0x2040
#define MII_CR_SPEED_1000 0x0040
#define MII_CR_SPEED_100 0x2000
#define MII_CR_SPEED_10 0x0000
/* PHY Status Register */
#define MII_SR_EXTENDED_CAPS 0x0001 /* Ext register capabilities */
#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext stat info in Reg 0x0F */
#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
/* Link partner ability register */
#define MII_LPA_SLCT 0x001f /* Same as advertise selector */
#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */
#define MII_LPA_PAUSE 0x0400 /* PAUSE */
#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */
#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */
#define MII_LPA_LPACK 0x4000 /* Link partner acked us */
#define MII_LPA_NPAGE 0x8000 /* Next page bit */
/* Autoneg Advertisement Register */
#define MII_AR_SELECTOR_FIELD 0x0001 /* IEEE 802.3 CSMA/CD */
#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
#define MII_AR_PAUSE 0x0400 /* Pause operation desired */
#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Dir bit */
#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability support */
#define MII_AR_SPEED_MASK 0x01E0
#define MII_AR_DEFAULT_CAP_MASK 0x0DE0
/* 1000BASE-T Control Register */
#define MII_ATLX_CR_1000T_HD_CAPS 0x0100 /* Adv 1000T HD cap */
#define MII_ATLX_CR_1000T_FD_CAPS 0x0200 /* Adv 1000T FD cap */
#define MII_ATLX_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device,
* 0=DTE device */
#define MII_ATLX_CR_1000T_MS_VALUE 0x0800 /* 1=Config PHY as Master,
* 0=Configure PHY as Slave */
#define MII_ATLX_CR_1000T_MS_ENABLE 0x1000 /* 1=Man Master/Slave config,
* 0=Auto Master/Slave config
*/
#define MII_ATLX_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
#define MII_ATLX_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
#define MII_ATLX_CR_1000T_TEST_MODE_2 0x4000 /* Master Xmit Jitter test */
#define MII_ATLX_CR_1000T_TEST_MODE_3 0x6000 /* Slave Xmit Jitter test */
#define MII_ATLX_CR_1000T_TEST_MODE_4 0x8000 /* Xmitter Distortion test */
#define MII_ATLX_CR_1000T_SPEED_MASK 0x0300
#define MII_ATLX_CR_1000T_DEFAULT_CAP_MASK 0x0300
/* 1000BASE-T Status Register */
#define MII_ATLX_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
#define MII_ATLX_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
#define MII_ATLX_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master
* 0=Slave
*/
#define MII_ATLX_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config
* fault */
#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS_SHIFT 12
#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS_SHIFT 13
/* Extended Status Register */
#define MII_ATLX_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
#define MII_ATLX_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
#define MII_ATLX_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
#define MII_ATLX_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
/* ATLX PHY Specific Control Register */
#define MII_ATLX_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Func disabled */
#define MII_ATLX_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enbld */
#define MII_ATLX_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
#define MII_ATLX_PSCR_MAC_POWERDOWN 0x0008
#define MII_ATLX_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low
* 0=CLK125 toggling
*/
#define MII_ATLX_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5,
* Manual MDI configuration
*/
#define MII_ATLX_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
#define MII_ATLX_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover
* 100BASE-TX/10BASE-T: MDI
* Mode */
#define MII_ATLX_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
* all speeds.
*/
#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended
* 10BASE-T distance
* (Lower 10BASE-T RX
* Threshold)
* 0=Normal 10BASE-T RX
* Threshold
*/
#define MII_ATLX_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in
* 100BASE-TX
* 0=MII interface in
* 100BASE-TX
*/
#define MII_ATLX_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler dsbl */
#define MII_ATLX_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
#define MII_ATLX_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
#define MII_ATLX_PSCR_POLARITY_REVERSAL_SHIFT 1
#define MII_ATLX_PSCR_AUTO_X_MODE_SHIFT 5
#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
/* ATLX PHY Specific Status Register */
#define MII_ATLX_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
#define MII_ATLX_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
#define MII_ATLX_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
#define MII_ATLX_PSSR_10MBS 0x0000 /* 00=10Mbs */
#define MII_ATLX_PSSR_100MBS 0x4000 /* 01=100Mbs */
#define MII_ATLX_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
/* PCI Command Register Bit Definitions */
#define PCI_REG_COMMAND 0x04 /* PCI Command Register */
#define CMD_IO_SPACE 0x0001
#define CMD_MEMORY_SPACE 0x0002
#define CMD_BUS_MASTER 0x0004
/* Wake Up Filter Control */
#define ATLX_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define ATLX_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define ATLX_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define ATLX_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
#define ATLX_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define ADVERTISE_10_HALF 0x0001
#define ADVERTISE_10_FULL 0x0002
#define ADVERTISE_100_HALF 0x0004
#define ADVERTISE_100_FULL 0x0008
#define ADVERTISE_1000_HALF 0x0010
#define ADVERTISE_1000_FULL 0x0020
#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */
#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */
#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA */
#define EEPROM_SUM 0xBABA
#define NODE_ADDRESS_SIZE 6
struct atlx_spi_flash_dev {
const char *manu_name; /* manufacturer id */
/* op-code */
u8 cmd_wrsr;
u8 cmd_read;
u8 cmd_program;
u8 cmd_wren;
u8 cmd_wrdi;
u8 cmd_rdsr;
u8 cmd_rdid;
u8 cmd_sector_erase;
u8 cmd_chip_erase;
};
#endif /* ATLX_H */
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#include "ixgbe_type.h" #include "ixgbe_type.h"
#include "ixgbe_common.h" #include "ixgbe_common.h"
#ifdef CONFIG_DCA
#include <linux/dca.h>
#endif
#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args) #define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args)
...@@ -120,7 +123,6 @@ struct ixgbe_queue_stats { ...@@ -120,7 +123,6 @@ struct ixgbe_queue_stats {
}; };
struct ixgbe_ring { struct ixgbe_ring {
struct ixgbe_adapter *adapter; /* backlink */
void *desc; /* descriptor ring memory */ void *desc; /* descriptor ring memory */
dma_addr_t dma; /* phys. address of descriptor ring */ dma_addr_t dma; /* phys. address of descriptor ring */
unsigned int size; /* length in bytes */ unsigned int size; /* length in bytes */
...@@ -128,6 +130,7 @@ struct ixgbe_ring { ...@@ -128,6 +130,7 @@ struct ixgbe_ring {
unsigned int next_to_use; unsigned int next_to_use;
unsigned int next_to_clean; unsigned int next_to_clean;
int queue_index; /* needed for multiqueue queue management */
union { union {
struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info;
...@@ -136,8 +139,21 @@ struct ixgbe_ring { ...@@ -136,8 +139,21 @@ struct ixgbe_ring {
u16 head; u16 head;
u16 tail; u16 tail;
unsigned int total_bytes;
unsigned int total_packets;
u16 reg_idx; /* holds the special value that gets the hardware register
* offset associated with this ring, which is different
* for DCE and RSS modes */
#ifdef CONFIG_DCA
/* cpu for tx queue */
int cpu;
#endif
struct ixgbe_queue_stats stats; struct ixgbe_queue_stats stats;
u8 v_idx; /* maps directly to the index for this ring in the hardware
* vector array, can also be used for finding the bit in EICR
* and friends that represents the vector for this ring */
u32 eims_value; u32 eims_value;
u16 itr_register; u16 itr_register;
...@@ -146,6 +162,33 @@ struct ixgbe_ring { ...@@ -146,6 +162,33 @@ struct ixgbe_ring {
u16 work_limit; /* max work per interrupt */ u16 work_limit; /* max work per interrupt */
}; };
#define RING_F_VMDQ 1
#define RING_F_RSS 2
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 16
struct ixgbe_ring_feature {
int indices;
int mask;
};
#define MAX_RX_QUEUES 64
#define MAX_TX_QUEUES 32
/* MAX_MSIX_Q_VECTORS of these are allocated,
* but we only use one per queue-specific vector.
*/
struct ixgbe_q_vector {
struct ixgbe_adapter *adapter;
struct napi_struct napi;
DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
u8 rxr_count; /* Rx ring count assigned to this vector */
u8 txr_count; /* Tx ring count assigned to this vector */
u8 tx_eitr;
u8 rx_eitr;
u32 eitr;
};
/* Helper macros to switch between ints/sec and what the register uses. /* Helper macros to switch between ints/sec and what the register uses.
* And yes, it's the same math going both ways. * And yes, it's the same math going both ways.
*/ */
...@@ -166,6 +209,14 @@ struct ixgbe_ring { ...@@ -166,6 +209,14 @@ struct ixgbe_ring {
#define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 #define IXGBE_MAX_JUMBO_FRAME_SIZE 16128
#define OTHER_VECTOR 1
#define NON_Q_VECTORS (OTHER_VECTOR)
#define MAX_MSIX_Q_VECTORS 16
#define MIN_MSIX_Q_VECTORS 2
#define MAX_MSIX_COUNT (MAX_MSIX_Q_VECTORS + NON_Q_VECTORS)
#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
/* board specific private data structure */ /* board specific private data structure */
struct ixgbe_adapter { struct ixgbe_adapter {
struct timer_list watchdog_timer; struct timer_list watchdog_timer;
...@@ -173,10 +224,16 @@ struct ixgbe_adapter { ...@@ -173,10 +224,16 @@ struct ixgbe_adapter {
u16 bd_number; u16 bd_number;
u16 rx_buf_len; u16 rx_buf_len;
struct work_struct reset_task; struct work_struct reset_task;
struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
/* Interrupt Throttle Rate */
u32 itr_setting;
u16 eitr_low;
u16 eitr_high;
/* TX */ /* TX */
struct ixgbe_ring *tx_ring; /* One per active queue */ struct ixgbe_ring *tx_ring; /* One per active queue */
struct napi_struct napi;
u64 restart_queue; u64 restart_queue;
u64 lsc_int; u64 lsc_int;
u64 hw_tso_ctxt; u64 hw_tso_ctxt;
...@@ -192,22 +249,27 @@ struct ixgbe_adapter { ...@@ -192,22 +249,27 @@ struct ixgbe_adapter {
u64 non_eop_descs; u64 non_eop_descs;
int num_tx_queues; int num_tx_queues;
int num_rx_queues; int num_rx_queues;
int num_msix_vectors;
struct ixgbe_ring_feature ring_feature[3];
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
u64 rx_hdr_split; u64 rx_hdr_split;
u32 alloc_rx_page_failed; u32 alloc_rx_page_failed;
u32 alloc_rx_buff_failed; u32 alloc_rx_buff_failed;
/* Some features need tri-state capability,
* thus the additional *_CAPABLE flags.
*/
u32 flags; u32 flags;
#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1) #define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1 << 0)
#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1) #define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1)
#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 2) #define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 2)
#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3) #define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3)
#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4) #define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4)
#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5)
/* Interrupt Throttle Rate */ #define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 6)
u32 rx_eitr; #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7)
u32 tx_eitr; #define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 8)
/* OS defined structs */ /* OS defined structs */
struct net_device *netdev; struct net_device *netdev;
...@@ -218,7 +280,10 @@ struct ixgbe_adapter { ...@@ -218,7 +280,10 @@ struct ixgbe_adapter {
struct ixgbe_hw hw; struct ixgbe_hw hw;
u16 msg_enable; u16 msg_enable;
struct ixgbe_hw_stats stats; struct ixgbe_hw_stats stats;
char lsc_name[IFNAMSIZ + 5];
/* Interrupt Throttle Rate */
u32 rx_eitr;
u32 tx_eitr;
unsigned long state; unsigned long state;
u64 tx_busy; u64 tx_busy;
......
...@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) ...@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
static int ixgbe_set_tso(struct net_device *netdev, u32 data) static int ixgbe_set_tso(struct net_device *netdev, u32 data)
{ {
if (data) { if (data) {
netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_TSO6;
} else { } else {
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int i;
#endif
netif_stop_queue(netdev);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_stop_subqueue(netdev, i);
#endif
netdev->features &= ~NETIF_F_TSO; netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6; netdev->features &= ~NETIF_F_TSO6;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
for (i = 0; i < adapter->num_tx_queues; i++)
netif_start_subqueue(netdev, i);
#endif
netif_start_queue(netdev);
} }
return 0; return 0;
} }
...@@ -873,13 +886,13 @@ static int ixgbe_get_coalesce(struct net_device *netdev, ...@@ -873,13 +886,13 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
if (adapter->rx_eitr == 0) if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
ec->rx_coalesce_usecs = 0; ec->rx_coalesce_usecs = adapter->rx_eitr;
else else
ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
if (adapter->tx_eitr == 0) if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
ec->tx_coalesce_usecs = 0; ec->tx_coalesce_usecs = adapter->tx_eitr;
else else
ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
...@@ -893,22 +906,26 @@ static int ixgbe_set_coalesce(struct net_device *netdev, ...@@ -893,22 +906,26 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
((ec->rx_coalesce_usecs > 0) && ((ec->rx_coalesce_usecs != 0) &&
(ec->rx_coalesce_usecs != 1) &&
(ec->rx_coalesce_usecs != 3) &&
(ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
return -EINVAL; return -EINVAL;
if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
((ec->tx_coalesce_usecs > 0) && ((ec->tx_coalesce_usecs != 0) &&
(ec->tx_coalesce_usecs != 1) &&
(ec->tx_coalesce_usecs != 3) &&
(ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
return -EINVAL; return -EINVAL;
/* convert to rate of irq's per second */ /* convert to rate of irq's per second */
if (ec->rx_coalesce_usecs == 0) if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
adapter->rx_eitr = 0; adapter->rx_eitr = ec->rx_coalesce_usecs;
else else
adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
if (ec->tx_coalesce_usecs == 0) if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
adapter->tx_eitr = 0; adapter->tx_eitr = ec->rx_coalesce_usecs;
else else
adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
......
此差异已折叠。
此差异已折叠。
...@@ -360,7 +360,10 @@ struct stat_block { ...@@ -360,7 +360,10 @@ struct stat_block {
#define MAX_TX_FIFOS 8 #define MAX_TX_FIFOS 8
#define MAX_RX_RINGS 8 #define MAX_RX_RINGS 8
#define FIFO_DEFAULT_NUM 1 #define FIFO_DEFAULT_NUM 5
#define FIFO_UDP_MAX_NUM 2 /* 0 - even, 1 -odd ports */
#define FIFO_OTHER_MAX_NUM 1
#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) #define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) #define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
...@@ -379,6 +382,8 @@ static int fifo_map[][MAX_TX_FIFOS] = { ...@@ -379,6 +382,8 @@ static int fifo_map[][MAX_TX_FIFOS] = {
{0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7},
}; };
static u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7};
/* Maintains Per FIFO related information. */ /* Maintains Per FIFO related information. */
struct tx_fifo_config { struct tx_fifo_config {
#define MAX_AVAILABLE_TXDS 8192 #define MAX_AVAILABLE_TXDS 8192
...@@ -431,6 +436,12 @@ struct config_param { ...@@ -431,6 +436,12 @@ struct config_param {
/* Tx Side */ /* Tx Side */
u32 tx_fifo_num; /*Number of Tx FIFOs */ u32 tx_fifo_num; /*Number of Tx FIFOs */
/* 0-No steering, 1-Priority steering, 2-Default fifo map */
#define NO_STEERING 0
#define TX_PRIORITY_STEERING 0x1
#define TX_DEFAULT_STEERING 0x2
u8 tx_steering_type;
u8 fifo_mapping[MAX_TX_FIFOS]; u8 fifo_mapping[MAX_TX_FIFOS];
struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */
u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */
...@@ -464,6 +475,7 @@ struct config_param { ...@@ -464,6 +475,7 @@ struct config_param {
int max_mc_addr; /* xena=64 herc=256 */ int max_mc_addr; /* xena=64 herc=256 */
int max_mac_addr; /* xena=16 herc=64 */ int max_mac_addr; /* xena=16 herc=64 */
int mc_start_offset; /* xena=16 herc=64 */ int mc_start_offset; /* xena=16 herc=64 */
u8 multiq;
}; };
/* Structure representing MAC Addrs */ /* Structure representing MAC Addrs */
...@@ -534,6 +546,7 @@ struct RxD_t { ...@@ -534,6 +546,7 @@ struct RxD_t {
#define RXD_OWN_XENA s2BIT(7) #define RXD_OWN_XENA s2BIT(7)
#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15)) #define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
#define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8)
#define RXD_FRAME_VLAN_TAG s2BIT(24)
#define RXD_FRAME_PROTO_IPV4 s2BIT(27) #define RXD_FRAME_PROTO_IPV4 s2BIT(27)
#define RXD_FRAME_PROTO_IPV6 s2BIT(28) #define RXD_FRAME_PROTO_IPV6 s2BIT(28)
#define RXD_FRAME_IP_FRAG s2BIT(29) #define RXD_FRAME_IP_FRAG s2BIT(29)
...@@ -720,6 +733,15 @@ struct fifo_info { ...@@ -720,6 +733,15 @@ struct fifo_info {
* the buffers * the buffers
*/ */
struct tx_curr_get_info tx_curr_get_info; struct tx_curr_get_info tx_curr_get_info;
#define FIFO_QUEUE_START 0
#define FIFO_QUEUE_STOP 1
int queue_state;
/* copy of sp->dev pointer */
struct net_device *dev;
/* copy of multiq status */
u8 multiq;
/* Per fifo lock */ /* Per fifo lock */
spinlock_t tx_lock; spinlock_t tx_lock;
...@@ -808,10 +830,11 @@ struct lro { ...@@ -808,10 +830,11 @@ struct lro {
int sg_num; int sg_num;
int in_use; int in_use;
__be16 window; __be16 window;
u16 vlan_tag;
u32 cur_tsval; u32 cur_tsval;
__be32 cur_tsecr; __be32 cur_tsecr;
u8 saw_ts; u8 saw_ts;
}; } ____cacheline_aligned;
/* These flags represent the devices temporary state */ /* These flags represent the devices temporary state */
enum s2io_device_state_t enum s2io_device_state_t
...@@ -885,6 +908,27 @@ struct s2io_nic { ...@@ -885,6 +908,27 @@ struct s2io_nic {
*/ */
int rx_csum; int rx_csum;
/* Below variables are used for fifo selection to transmit a packet */
u16 fifo_selector[MAX_TX_FIFOS];
/* Total fifos for tcp packets */
u8 total_tcp_fifos;
/*
* Beginning index of udp for udp packets
* Value will be equal to
* (tx_fifo_num - FIFO_UDP_MAX_NUM - FIFO_OTHER_MAX_NUM)
*/
u8 udp_fifo_idx;
u8 total_udp_fifos;
/*
* Beginning index of fifo for all other packets
* Value will be equal to (tx_fifo_num - FIFO_OTHER_MAX_NUM)
*/
u8 other_fifo_idx;
/* after blink, the adapter must be restored with original /* after blink, the adapter must be restored with original
* values. * values.
*/ */
...@@ -1087,7 +1131,7 @@ static int ...@@ -1087,7 +1131,7 @@ static int
s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro,
struct RxD_t *rxdp, struct s2io_nic *sp); struct RxD_t *rxdp, struct s2io_nic *sp);
static void clear_lro_session(struct lro *lro); static void clear_lro_session(struct lro *lro);
static void queue_rx_frame(struct sk_buff *skb); static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag);
static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro); static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro);
static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
struct sk_buff *skb, u32 tcp_len); struct sk_buff *skb, u32 tcp_len);
......
#
# Makefile for the SysKonnect SK-98xx device driver.
#
#
# Standalone driver params
# SKPARAM += -DSK_KERNEL_24
# SKPARAM += -DSK_KERNEL_24_26
# SKPARAM += -DSK_KERNEL_26
# SKPARAM += -DSK_KERNEL_22_24
obj-$(CONFIG_SK98LIN) += sk98lin.o
sk98lin-objs := \
skge.o \
skethtool.o \
skdim.o \
skaddr.o \
skgehwt.o \
skgeinit.o \
skgepnmi.o \
skgesirq.o \
ski2c.o \
sklm80.o \
skqueue.o \
skrlmt.o \
sktimer.o \
skvpd.o \
skxmac2.o
# DBGDEF = \
# -DDEBUG
ifdef DEBUG
DBGDEF += \
-DSK_DEBUG_CHKMOD=0x00000000L \
-DSK_DEBUG_CHKCAT=0x00000000L
endif
# **** possible debug modules for SK_DEBUG_CHKMOD *****************
# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
# SK_DBGMOD_VPD 0x00000008L /* VPD module */
# SK_DBGMOD_I2C 0x00000010L /* I2C module */
# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
# SK_DBGMOD_DRV 0x00010000L /* DRV module */
# **** possible debug categories for SK_DEBUG_CHKCAT **************
# *** common modules ***
# SK_DBGCAT_INIT 0x00000001L module/driver initialization
# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
# SK_DBGCAT_ERR 0x00000004L error handling paths
# SK_DBGCAT_TX 0x00000008L transmit path
# SK_DBGCAT_RX 0x00000010L receive path
# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
# SK_DBGCAT_QUEUE 0x00000040L any queue management
# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
# *** driver (file skge.c) ***
# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
# SK_DBGCAT_DRV_??? 0x00020000 not used
# SK_DBGCAT_DRV_MCA 0x00040000 multicast
# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
# SK_DBGCAT_DRV_??? 0x00400000 not used
# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
clean:
rm -f core *.o *.a *.s
/******************************************************************************
*
* Name: lm80.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.6 $
* Date: $Date: 2003/05/13 17:26:52 $
* Purpose: Contains all defines for the LM80 Chip
* (National Semiconductor).
*
******************************************************************************/
/******************************************************************************
*
* (C)Copyright 1998-2002 SysKonnect.
* (C)Copyright 2002-2003 Marvell.
*
* 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.
*
******************************************************************************/
#ifndef __INC_LM80_H
#define __INC_LM80_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines ********************************************************************/
/*
* LM80 register definition
*
* All registers are 8 bit wide
*/
#define LM80_CFG 0x00 /* Configuration Register */
#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
/* 0x07 - 0x1f reserved */
/* current values */
#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
#define LM80_TEMP_IN 0x27 /* current Temperature value */
#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
/* limit values */
#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
/* 0x3e - 0x3f reserved */
/*
* LM80 bit definitions
*/
/* LM80_CFG Configuration Register */
#define LM80_CFG_START (1<<0) /* start monitoring operation */
#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
#define LM80_CFG_RESET (1<<4) /* signals a reset */
#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
/* LM80_ISRC_1 Interrupt Status Register 1 */
/* LM80_IMSK_1 Interrupt Mask Register 1 */
#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
/* LM80_ISRC_2 Interrupt Status Register 2 */
/* LM80_IMSK_2 Interrupt Mask Register 2 */
#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
/* bit 6 and 7 are reserved in LM80_ISRC_2 */
#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
/* 0x07 - 0x1f reserved */
/* LM80_VT0_IN current Voltage 0 value */
/* LM80_VT1_IN current Voltage 1 value */
/* LM80_VT2_IN current Voltage 2 value */
/* LM80_VT3_IN current Voltage 3 value */
/* LM80_VT4_IN current Voltage 4 value */
/* LM80_VT5_IN current Voltage 5 value */
/* LM80_VT6_IN current Voltage 6 value */
/* LM80_TEMP_IN current temperature value */
/* LM80_FAN1_IN current Fan 1 count */
/* LM80_FAN2_IN current Fan 2 count */
/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
/* LM80_THOT_LIM_UP hot temperature limit (high) */
/* LM80_THOT_LIM_LO hot temperature limit (low) */
/* LM80_TOS_LIM_UP OS temperature limit (high) */
/* LM80_TOS_LIM_LO OS temperature limit (low) */
/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
/* 0x3e - 0x3f reserved */
#define LM80_ADDR 0x28 /* LM80 default addr */
/* typedefs *******************************************************************/
/* function prototypes ********************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INC_LM80_H */
此差异已折叠。
此差异已折叠。
/******************************************************************************
*
* Name: skdebug.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.14 $
* Date: $Date: 2003/05/13 17:26:00 $
* Purpose: SK specific DEBUG support
*
******************************************************************************/
/******************************************************************************
*
* (C)Copyright 1998-2002 SysKonnect.
* (C)Copyright 2002-2003 Marvell.
*
* 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.
*
******************************************************************************/
#ifndef __INC_SKDEBUG_H
#define __INC_SKDEBUG_H
#ifdef DEBUG
#ifndef SK_DBG_MSG
#define SK_DBG_MSG(pAC,comp,cat,arg) \
if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
((cat) & SK_DBG_CHKCAT(pAC)) ) { \
SK_DBG_PRINTF arg ; \
}
#endif
#else
#define SK_DBG_MSG(pAC,comp,lev,arg)
#endif
/* PLS NOTE:
* =========
* Due to any restrictions of kernel printf routines do not use other
* format identifiers as: %x %d %c %s .
* Never use any combined format identifiers such as: %lx %ld in your
* printf - argument (arg) because some OS specific kernel printfs may
* only support some basic identifiers.
*/
/* Debug modules */
#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
/* Debug events */
#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
#define SK_DBGCAT_TX 0x00000008L /* transmit path */
#define SK_DBGCAT_RX 0x00000010L /* receive path */
#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
#endif /* __INC_SKDEBUG_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
# Makefile for the Linux "Tulip" family network device drivers. # Makefile for the Linux "Tulip" family network device drivers.
# #
obj-$(CONFIG_PCMCIA_XIRTULIP) += xircom_tulip_cb.o
obj-$(CONFIG_PCMCIA_XIRCOM) += xircom_cb.o obj-$(CONFIG_PCMCIA_XIRCOM) += xircom_cb.o
obj-$(CONFIG_DM9102) += dmfe.o obj-$(CONFIG_DM9102) += dmfe.o
obj-$(CONFIG_WINBOND_840) += winbond-840.o obj-$(CONFIG_WINBOND_840) += winbond-840.o
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册