* [git patches] net driver updates for .28
@ 2008-09-03 14:37 Jeff Garzik
2008-09-03 22:08 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Jeff Garzik @ 2008-09-03 14:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev, LKML
Please pull from 'davem-next' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
to receive the following updates:
drivers/net/8139cp.c | 14 +-
drivers/net/8139too.c | 4 +-
drivers/net/Makefile | 2 +-
drivers/net/bonding/bond_alb.c | 4 +-
drivers/net/bonding/bond_main.c | 6 +-
drivers/net/e1000e/82571.c | 153 ++++++-
drivers/net/e1000e/defines.h | 15 +
drivers/net/e1000e/e1000.h | 31 ++-
drivers/net/e1000e/es2lan.c | 2 +-
drivers/net/e1000e/ethtool.c | 60 ++-
drivers/net/e1000e/hw.h | 15 +-
drivers/net/e1000e/ich8lan.c | 173 +++++++-
drivers/net/e1000e/lib.c | 7 +-
drivers/net/e1000e/netdev.c | 435 ++++++++++++++++--
drivers/net/e1000e/param.c | 27 ++
drivers/net/e1000e/phy.c | 194 ++++++++-
drivers/net/ibm_newemac/mal.h | 4 +-
drivers/net/igb/igb_main.c | 12 +-
drivers/net/ixgbe/ixgbe.h | 43 ++-
drivers/net/ixgbe/ixgbe_82598.c | 6 +-
drivers/net/ixgbe/ixgbe_common.c | 140 ++++++-
drivers/net/ixgbe/ixgbe_common.h | 4 +-
drivers/net/ixgbe/ixgbe_ethtool.c | 6 +-
drivers/net/ixgbe/ixgbe_main.c | 721 +++++++++++++++++------------
drivers/net/ixgbe/ixgbe_type.h | 47 +-
drivers/net/myri10ge/myri10ge.c | 1 -
drivers/net/netxen/netxen_nic_ethtool.c | 1 -
drivers/net/r8169.c | 401 ++++++++++++++---
drivers/net/s2io.c | 4 +-
drivers/net/sfc/bitfield.h | 178 +++++---
drivers/net/sfc/boards.c | 12 +-
drivers/net/sfc/boards.h | 2 -
drivers/net/sfc/efx.c | 471 ++++++++-----------
drivers/net/sfc/efx.h | 14 +-
drivers/net/sfc/enum.h | 9 +-
drivers/net/sfc/ethtool.c | 184 ++++----
drivers/net/sfc/falcon.c | 767 ++++++++++++++++++++++---------
drivers/net/sfc/falcon.h | 16 +-
drivers/net/sfc/falcon_hwdefs.h | 79 +++-
drivers/net/sfc/falcon_xmac.c | 330 ++++++--------
drivers/net/sfc/mac.h | 4 -
drivers/net/sfc/mdio_10g.c | 16 +-
drivers/net/sfc/mdio_10g.h | 13 +-
drivers/net/sfc/net_driver.h | 136 +++---
drivers/net/sfc/phy.h | 10 +-
drivers/net/sfc/rx.c | 78 ++--
drivers/net/sfc/rx.h | 4 +-
drivers/net/sfc/selftest.c | 391 +++++++++-------
drivers/net/sfc/selftest.h | 13 +-
drivers/net/sfc/sfe4001.c | 244 ++++++----
drivers/net/sfc/spi.h | 89 ++--
drivers/net/sfc/tenxpress.c | 90 ++---
drivers/net/sfc/tx.c | 383 ++++++++--------
drivers/net/sfc/tx.h | 2 +-
drivers/net/sfc/workarounds.h | 2 -
drivers/net/sfc/xfp_phy.c | 11 +-
drivers/net/sky2.c | 170 +++++--
drivers/net/tokenring/lanstreamer.c | 1 -
drivers/net/via-rhine.c | 8 +-
59 files changed, 4084 insertions(+), 2175 deletions(-)
Alexander Duyck (3):
igb: remove unneeded cleaned variable in clean_tx_irq path
igb: clean up a stray fake netdev code left in rx path
ixgbe: change config srrctl to only program one register per VMDq/RSS id
Ben Hutchings (38):
sfc: Replace net_dev->priv with netdev_priv(net_dev)
sfc: Change first parameter type of {set,clear}_bit_le() to unsigned
sfc: Use separate hardware TX queues to select checksum generation
sfc: Avoid mangling error codes in efx_test_loopback()
sfc: Reduce delays in SFE4001 initialisation
sfc: Remove mistaken hardware workaround
sfc: XMAC statistics fix-ups
sfc: Remove inclusion of workarounds.h from efx.c
sfc: Reverse the XOFF/XON pause frame control fifo thresholds
sfc: Reduce log level for XGXS lane status
sfc: Self-test reporting cleanup
sfc: Speed up loopback self-test
sfc: Don't leak PCI DMA maps in the TSO code when the queue fills up
sfc: Use pci_map_single() to map the skb header when doing TSO
sfc: Reduce the size of struct efx_tx_buffer
sfc: Use explicit bool for boolean variables, parameters and return values
sfc: Set net_device::vlan_features appropriately
sfc: Cleaned up struct tso_state fields
sfc: Removed forced inlining of long functions
sfc: Export boot configuration in EEPROM through ethtool
sfc: Move CPU counting for RSS into a separate function, efx_wanted_rx_queues()
sfc: Remove efx_channel::has_interrupt
sfc: Cleanup RX queue information
sfc: Remove initialisation of RX_FILTER_CTL_REG.NUM_KER
sfc: Make efx_for_each_channel_rx_queue() more efficient
sfc: Remove efx_channel::evqnum field
sfc: Cleanup RX event processing
sfc: Implement get_sset_count, replacing get_stats_count and self_test_count
sfc: Make PHY flash mode a device attribute, not a module parameter
sfc: Enable TSO for 802.1q VLAN devices
sfc: Remove efx_nic_dummy_op_int() as redundant with efx_port_dummy_op_int()
sfc: Remove remnants of multi-port abstraction for MAC registers
sfc: Remove some unreachable error paths
sfc: Cleanup reset code
sfc: Rework the bitfield header so that we can identify fields by bit number
sfc: Extend self-tests
sfc: Remove the STATE_RESETTING flag
sfc: Rework efx_set_multicast_hash()
Brian Haley (1):
bonding: change some __constant_htons() to htons()
Bruce Allan (3):
e1000e: add support for the 82567LM-4 device
e1000e: add support for 82567LM-3 and 82567LF-3 (ICH10D) parts
e1000e: add support for new 82574L part
Christopher Leech (1):
ixgbe: Implement HAVE_SET_RX_MODE
Francois Romieu (6):
r8169: get ethtool settings through the generic mii helper
r8169: Tx performance tweak helper
r8169: use pci_find_capability for the PCI-E features
r8169: add 8168/8101 registers description
r8169: add hw start helpers for the 8168 and the 8101
r8169: additional 8101 and 8102 support
Huang Weiyi (1):
[netdrvr] removed unused #include <version.h>
Ilpo Järvinen (1):
s2io: reindented misleading for loop
Jesse Brandeburg (11):
ixgbe: fix rx csum return status misinterpretation
ixgbe: add little endian annotations for sparse
ixgbe: do not update stats twice each receive
ixgbe: Cleanup references to Tx and Rx rings to becommon across the driver
ixgbe: disable flow control by default
ixgbe: Implement Tx Head Writeback
ixgbe: Lock RSS seed, move rx_buf_len to the rx_ring
ixgbe: should not use HW_CSUM, should use IP* flags
ixgbe: update dca to new interface, fix CONFIG_DCA_MODULE
ixgbe: fix bug where lro settings are per ring
ixgbe: fix dca hints going to wrong processor
Kevin Lo (3):
via-rhine: changed to use netdev_alloc_skb() from dev_alloc_skb
8139cp: use netdev_alloc_skb
8139too: use netdev_alloc_skb
PJ Waskiewicz (1):
ixgbe: use different context for tso and offload
Randy Dunlap (1):
hp-plus: fix link objects
Stephen Hemminger (2):
sky2: EEPROM read/write bug fixes
sky2: display product info on boot.
Steve Hodgson (2):
sfc: Remove unused field efx_channel::reset_work
sfc: Do not call netif_{stop,wake}_queue() before register_netdev
roel kluin (1):
ibm_newemac: MAL[12]_IER_EVENTS definition: 2x *_OTE -> *_DE
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 6011d6f..85fa40a 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -127,7 +127,6 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered mu
(CP)->tx_tail - (CP)->tx_head - 1)
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
-#define RX_OFFSET 2
#define CP_INTERNAL_PHY 32
/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */
@@ -552,14 +551,14 @@ rx_status_loop:
printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
dev->name, rx_tail, status, len);
- buflen = cp->rx_buf_sz + RX_OFFSET;
- new_skb = dev_alloc_skb (buflen);
+ buflen = cp->rx_buf_sz + NET_IP_ALIGN;
+ new_skb = netdev_alloc_skb(dev, buflen);
if (!new_skb) {
dev->stats.rx_dropped++;
goto rx_next;
}
- skb_reserve(new_skb, RX_OFFSET);
+ skb_reserve(new_skb, NET_IP_ALIGN);
dma_unmap_single(&cp->pdev->dev, mapping,
buflen, PCI_DMA_FROMDEVICE);
@@ -1051,19 +1050,20 @@ static void cp_init_hw (struct cp_private *cp)
cpw8_f(Cfg9346, Cfg9346_Lock);
}
-static int cp_refill_rx (struct cp_private *cp)
+static int cp_refill_rx(struct cp_private *cp)
{
+ struct net_device *dev = cp->dev;
unsigned i;
for (i = 0; i < CP_RX_RING_SIZE; i++) {
struct sk_buff *skb;
dma_addr_t mapping;
- skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET);
+ skb = netdev_alloc_skb(dev, cp->rx_buf_sz + NET_IP_ALIGN);
if (!skb)
goto err_out;
- skb_reserve(skb, RX_OFFSET);
+ skb_reserve(skb, NET_IP_ALIGN);
mapping = dma_map_single(&cp->pdev->dev, skb->data,
cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 8a5b0d2..f6ca997 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -2009,9 +2009,9 @@ no_early_rx:
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
- skb = dev_alloc_skb (pkt_size + 2);
+ skb = netdev_alloc_skb(dev, pkt_size + NET_IP_ALIGN);
if (likely(skb)) {
- skb_reserve (skb, 2); /* 16 byte align the IP fields. */
+ skb_reserve (skb, NET_IP_ALIGN); /* 16 byte align the IP fields. */
#if RX_BUF_IDX == 3
wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
#else
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7629c90..f66b79b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -111,7 +111,7 @@ obj-$(CONFIG_EL2) += 3c503.o 8390p.o
obj-$(CONFIG_NE2000) += ne.o 8390p.o
obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o
obj-$(CONFIG_HPLAN) += hp.o 8390p.o
-obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
+obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index b211486..3d39278 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -710,7 +710,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
struct arp_pkt *arp = arp_pkt(skb);
struct slave *tx_slave = NULL;
- if (arp->op_code == __constant_htons(ARPOP_REPLY)) {
+ if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected
* rx channel
*/
@@ -719,7 +719,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
}
dprintk("Server sent ARP Reply packet\n");
- } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) {
+ } else if (arp->op_code == htons(ARPOP_REQUEST)) {
/* Create an entry in the rx_hashtbl for this client as a
* place holder.
* When the arp reply is received the entry will be updated
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c792138..babe461 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3702,7 +3702,7 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
struct ethhdr *data = (struct ethhdr *)skb->data;
struct iphdr *iph = ip_hdr(skb);
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
(data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
}
@@ -3723,8 +3723,8 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
__be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
int layer4_xor = 0;
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
- if (!(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) &&
+ if (skb->protocol == htons(ETH_P_IP)) {
+ if (!(iph->frag_off & htons(IP_MF|IP_OFFSET)) &&
(iph->protocol == IPPROTO_TCP ||
iph->protocol == IPPROTO_UDP)) {
layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 462351c..b2c910c 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -38,6 +38,7 @@
* 82573V Gigabit Ethernet Controller (Copper)
* 82573E Gigabit Ethernet Controller (Copper)
* 82573L Gigabit Ethernet Controller
+ * 82574L Gigabit Network Connection
*/
#include <linux/netdevice.h>
@@ -54,6 +55,8 @@
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */
+
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
@@ -63,6 +66,8 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
static s32 e1000_setup_link_82571(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
+static s32 e1000_led_on_82574(struct e1000_hw *hw);
/**
* e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -92,6 +97,9 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
case e1000_82573:
phy->type = e1000_phy_m88;
break;
+ case e1000_82574:
+ phy->type = e1000_phy_bm;
+ break;
default:
return -E1000_ERR_PHY;
break;
@@ -111,6 +119,10 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
if (phy->id != M88E1111_I_PHY_ID)
return -E1000_ERR_PHY;
break;
+ case e1000_82574:
+ if (phy->id != BME1000_E_PHY_ID_R2)
+ return -E1000_ERR_PHY;
+ break;
default:
return -E1000_ERR_PHY;
break;
@@ -150,6 +162,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82573:
+ case e1000_82574:
if (((eecd >> 15) & 0x3) == 0x3) {
nvm->type = e1000_nvm_flash_hw;
nvm->word_size = 2048;
@@ -245,6 +258,17 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
}
+ switch (hw->mac.type) {
+ case e1000_82574:
+ func->check_mng_mode = e1000_check_mng_mode_82574;
+ func->led_on = e1000_led_on_82574;
+ break;
+ default:
+ func->check_mng_mode = e1000e_check_mng_mode_generic;
+ func->led_on = e1000e_led_on_generic;
+ break;
+ }
+
return 0;
}
@@ -330,6 +354,8 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val;
+ u16 phy_id = 0;
switch (hw->mac.type) {
case e1000_82571:
@@ -345,6 +371,20 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
case e1000_82573:
return e1000e_get_phy_id(hw);
break;
+ case e1000_82574:
+ ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
+ if (ret_val)
+ return ret_val;
+
+ phy->id = (u32)(phy_id << 16);
+ udelay(20);
+ ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
+ if (ret_val)
+ return ret_val;
+
+ phy->id |= (u32)(phy_id);
+ phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+ break;
default:
return -E1000_ERR_PHY;
break;
@@ -421,7 +461,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if (hw->mac.type != e1000_82573)
+ if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
ret_val = e1000e_acquire_nvm(hw);
if (ret_val)
@@ -461,6 +501,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
switch (hw->mac.type) {
case e1000_82573:
+ case e1000_82574:
ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
break;
case e1000_82571:
@@ -735,7 +776,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset.
*/
- if (hw->mac.type == e1000_82573) {
+ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
extcnf_ctrl = er32(EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -776,7 +817,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Need to wait for Phy configuration completion before accessing
* NVM and Phy.
*/
- if (hw->mac.type == e1000_82573)
+ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
msleep(25);
/* Clear any pending interrupt events. */
@@ -843,7 +884,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
ew32(TXDCTL(0), reg_data);
/* ...for both queues. */
- if (mac->type != e1000_82573) {
+ if (mac->type != e1000_82573 && mac->type != e1000_82574) {
reg_data = er32(TXDCTL(1));
reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB |
@@ -918,19 +959,28 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
}
/* Device Control */
- if (hw->mac.type == e1000_82573) {
+ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
reg = er32(CTRL);
reg &= ~(1 << 29);
ew32(CTRL, reg);
}
/* Extended Device Control */
- if (hw->mac.type == e1000_82573) {
+ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
reg = er32(CTRL_EXT);
reg &= ~(1 << 23);
reg |= (1 << 22);
ew32(CTRL_EXT, reg);
}
+
+ /* PCI-Ex Control Register */
+ if (hw->mac.type == e1000_82574) {
+ reg = er32(GCR);
+ reg |= (1 << 22);
+ ew32(GCR, reg);
+ }
+
+ return;
}
/**
@@ -947,7 +997,7 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
u32 vfta_offset = 0;
u32 vfta_bit_in_reg = 0;
- if (hw->mac.type == e1000_82573) {
+ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
if (hw->mng_cookie.vlan_id != 0) {
/*
* The VFTA is a 4096b bit-field, each identifying
@@ -976,6 +1026,48 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
}
/**
+ * e1000_check_mng_mode_82574 - Check manageability is enabled
+ * @hw: pointer to the HW structure
+ *
+ * Reads the NVM Initialization Control Word 2 and returns true
+ * (>0) if any manageability is enabled, else false (0).
+ **/
+static bool e1000_check_mng_mode_82574(struct e1000_hw *hw)
+{
+ u16 data;
+
+ e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+ return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0;
+}
+
+/**
+ * e1000_led_on_82574 - Turn LED on
+ * @hw: pointer to the HW structure
+ *
+ * Turn LED on.
+ **/
+static s32 e1000_led_on_82574(struct e1000_hw *hw)
+{
+ u32 ctrl;
+ u32 i;
+
+ ctrl = hw->mac.ledctl_mode2;
+ if (!(E1000_STATUS_LU & er32(STATUS))) {
+ /*
+ * If no link, then turn LED on by setting the invert bit
+ * for each LED that's "on" (0x0E) in ledctl_mode2.
+ */
+ for (i = 0; i < 4; i++)
+ if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
+ E1000_LEDCTL_MODE_LED_ON)
+ ctrl |= (E1000_LEDCTL_LED0_IVRT << (i * 8));
+ }
+ ew32(LEDCTL, ctrl);
+
+ return 0;
+}
+
+/**
* e1000_update_mc_addr_list_82571 - Update Multicast addresses
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
@@ -1018,7 +1110,8 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
* the default flow control setting, so we explicitly
* set it to full.
*/
- if (hw->mac.type == e1000_82573)
+ if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
+ hw->fc.type == e1000_fc_default)
hw->fc.type = e1000_fc_full;
return e1000e_setup_link(hw);
@@ -1045,6 +1138,7 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
switch (hw->phy.type) {
case e1000_phy_m88:
+ case e1000_phy_bm:
ret_val = e1000e_copper_link_setup_m88(hw);
break;
case e1000_phy_igp_2:
@@ -1114,11 +1208,10 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
return ret_val;
}
- if (hw->mac.type == e1000_82573 &&
+ if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
*data == ID_LED_RESERVED_F746)
*data = ID_LED_DEFAULT_82573;
- else if (*data == ID_LED_RESERVED_0000 ||
- *data == ID_LED_RESERVED_FFFF)
+ else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
*data = ID_LED_DEFAULT;
return 0;
@@ -1265,13 +1358,13 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
}
static struct e1000_mac_operations e82571_mac_ops = {
- .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT,
+ /* .check_mng_mode: mac type dependent */
/* .check_for_link: media type dependent */
.cleanup_led = e1000e_cleanup_led_generic,
.clear_hw_cntrs = e1000_clear_hw_cntrs_82571,
.get_bus_info = e1000e_get_bus_info_pcie,
/* .get_link_up_info: media type dependent */
- .led_on = e1000e_led_on_generic,
+ /* .led_on: mac type dependent */
.led_off = e1000e_led_off_generic,
.update_mc_addr_list = e1000_update_mc_addr_list_82571,
.reset_hw = e1000_reset_hw_82571,
@@ -1312,6 +1405,22 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
.write_phy_reg = e1000e_write_phy_reg_m88,
};
+static struct e1000_phy_operations e82_phy_ops_bm = {
+ .acquire_phy = e1000_get_hw_semaphore_82571,
+ .check_reset_block = e1000e_check_reset_block_generic,
+ .commit_phy = e1000e_phy_sw_reset,
+ .force_speed_duplex = e1000e_phy_force_speed_duplex_m88,
+ .get_cfg_done = e1000e_get_cfg_done,
+ .get_cable_length = e1000e_get_cable_length_m88,
+ .get_phy_info = e1000e_get_phy_info_m88,
+ .read_phy_reg = e1000e_read_phy_reg_bm2,
+ .release_phy = e1000_put_hw_semaphore_82571,
+ .reset_phy = e1000e_phy_hw_reset_generic,
+ .set_d0_lplu_state = e1000_set_d0_lplu_state_82571,
+ .set_d3_lplu_state = e1000e_set_d3_lplu_state,
+ .write_phy_reg = e1000e_write_phy_reg_bm2,
+};
+
static struct e1000_nvm_operations e82571_nvm_ops = {
.acquire_nvm = e1000_acquire_nvm_82571,
.read_nvm = e1000e_read_nvm_eerd,
@@ -1375,3 +1484,21 @@ struct e1000_info e1000_82573_info = {
.nvm_ops = &e82571_nvm_ops,
};
+struct e1000_info e1000_82574_info = {
+ .mac = e1000_82574,
+ .flags = FLAG_HAS_HW_VLAN_FILTER
+ | FLAG_HAS_MSIX
+ | FLAG_HAS_JUMBO_FRAMES
+ | FLAG_HAS_WOL
+ | FLAG_APME_IN_CTRL3
+ | FLAG_RX_CSUM_ENABLED
+ | FLAG_HAS_SMART_POWER_DOWN
+ | FLAG_HAS_AMT
+ | FLAG_HAS_CTRLEXT_ON_LOAD,
+ .pba = 20,
+ .get_variants = e1000_get_variants_82571,
+ .mac_ops = &e82571_mac_ops,
+ .phy_ops = &e82_phy_ops_bm,
+ .nvm_ops = &e82571_nvm_ops,
+};
+
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 14b0e6c..48f79ec 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -71,9 +71,11 @@
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_EIAME 0x01000000
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
+#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
@@ -299,6 +301,7 @@
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
/* Header split receive */
+#define E1000_RFCTL_ACK_DIS 0x00001000
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
@@ -363,6 +366,11 @@
#define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */
#define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */
#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
+#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
+#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
+#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
+#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
+#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */
/*
* This defines the bits that are set in the Interrupt Mask
@@ -386,6 +394,11 @@
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */
+#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */
+#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */
+#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */
+#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */
+#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
@@ -505,6 +518,7 @@
#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
/* 1000BASE-T Control Register */
#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
@@ -540,6 +554,7 @@
#define E1000_EECD_DO 0x00000008 /* NVM Data Out */
#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */
#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
+#define E1000_EECD_PRES 0x00000100 /* NVM Present */
#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */
/* NVM Addressing bits based on type (0-small, 1-large) */
#define E1000_EECD_ADDR_BITS 0x00000400
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index ac4e506..0a1916b 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -62,6 +62,11 @@ struct e1000_info;
e_printk(KERN_NOTICE, adapter, format, ## arg)
+/* Interrupt modes, as used by the IntMode paramter */
+#define E1000E_INT_MODE_LEGACY 0
+#define E1000E_INT_MODE_MSI 1
+#define E1000E_INT_MODE_MSIX 2
+
/* Tx/Rx descriptor defines */
#define E1000_DEFAULT_TXD 256
#define E1000_MAX_TXD 4096
@@ -95,9 +100,11 @@ enum e1000_boards {
board_82571,
board_82572,
board_82573,
+ board_82574,
board_80003es2lan,
board_ich8lan,
board_ich9lan,
+ board_ich10lan,
};
struct e1000_queue_stats {
@@ -146,6 +153,12 @@ struct e1000_ring {
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
+ char name[IFNAMSIZ + 5];
+ u32 ims_val;
+ u32 itr_val;
+ u16 itr_register;
+ int set_itr;
+
struct sk_buff *rx_skb_top;
struct e1000_queue_stats stats;
@@ -274,6 +287,9 @@ struct e1000_adapter {
u32 test_icr;
u32 msg_enable;
+ struct msix_entry *msix_entries;
+ int int_mode;
+ u32 eiac_mask;
u32 eeprom_wol;
u32 wol;
@@ -306,6 +322,7 @@ struct e1000_info {
#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
#define FLAG_IS_ICH (1 << 9)
+#define FLAG_HAS_MSIX (1 << 10)
#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)
#define FLAG_IS_QUAD_PORT_A (1 << 12)
#define FLAG_IS_QUAD_PORT (1 << 13)
@@ -364,6 +381,8 @@ extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
extern void e1000e_update_stats(struct e1000_adapter *adapter);
+extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
+extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
extern unsigned int copybreak;
@@ -372,8 +391,10 @@ extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw);
extern struct e1000_info e1000_82571_info;
extern struct e1000_info e1000_82572_info;
extern struct e1000_info e1000_82573_info;
+extern struct e1000_info e1000_82574_info;
extern struct e1000_info e1000_ich8_info;
extern struct e1000_info e1000_ich9_info;
+extern struct e1000_info e1000_ich10_info;
extern struct e1000_info e1000_es2_info;
extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
@@ -446,10 +467,13 @@ extern s32 e1000e_get_cable_length_m88(struct e1000_hw *hw);
extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw);
extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -520,7 +544,12 @@ static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
return hw->phy.ops.get_phy_info(hw);
}
-extern bool e1000e_check_mng_mode(struct e1000_hw *hw);
+static inline s32 e1000e_check_mng_mode(struct e1000_hw *hw)
+{
+ return hw->mac.ops.check_mng_mode(hw);
+}
+
+extern bool e1000e_check_mng_mode_generic(struct e1000_hw *hw);
extern bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw);
extern s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index dc552d7..da9c09c 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -1247,7 +1247,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
}
static struct e1000_mac_operations es2_mac_ops = {
- .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT,
+ .check_mng_mode = e1000e_check_mng_mode_generic,
/* check_for_link dependent on media type */
.cleanup_led = e1000e_cleanup_led_generic,
.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index e21c9e0..52b762e 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -568,6 +568,7 @@ static int e1000_set_eeprom(struct net_device *netdev,
* and flush shadow RAM for 82573 controllers
*/
if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) ||
+ (hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82573)))
e1000e_update_nvm_checksum(hw);
@@ -779,8 +780,10 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
toggle = 0x7FFFF3FF;
break;
case e1000_82573:
+ case e1000_82574:
case e1000_ich8lan:
case e1000_ich9lan:
+ case e1000_ich10lan:
toggle = 0x7FFFF033;
break;
default:
@@ -833,7 +836,9 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
for (i = 0; i < mac->rar_entry_count; i++)
REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
- 0x8003FFFF, 0xFFFFFFFF);
+ ((mac->type == e1000_ich10lan) ?
+ 0x8007FFFF : 0x8003FFFF),
+ 0xFFFFFFFF);
for (i = 0; i < mac->mta_reg_count; i++)
REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
@@ -884,10 +889,18 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
u32 shared_int = 1;
u32 irq = adapter->pdev->irq;
int i;
+ int ret_val = 0;
+ int int_mode = E1000E_INT_MODE_LEGACY;
*data = 0;
- /* NOTE: we don't test MSI interrupts here, yet */
+ /* NOTE: we don't test MSI/MSI-X interrupts here, yet */
+ if (adapter->int_mode == E1000E_INT_MODE_MSIX) {
+ int_mode = adapter->int_mode;
+ e1000e_reset_interrupt_capability(adapter);
+ adapter->int_mode = E1000E_INT_MODE_LEGACY;
+ e1000e_set_interrupt_capability(adapter);
+ }
/* Hook up test interrupt handler just for this test */
if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
netdev)) {
@@ -895,7 +908,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
} else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED,
netdev->name, netdev)) {
*data = 1;
- return -1;
+ ret_val = -1;
+ goto out;
}
e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));
@@ -905,12 +919,23 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Test each interrupt */
for (i = 0; i < 10; i++) {
- if ((adapter->flags & FLAG_IS_ICH) && (i == 8))
- continue;
-
/* Interrupt to test */
mask = 1 << i;
+ if (adapter->flags & FLAG_IS_ICH) {
+ switch (mask) {
+ case E1000_ICR_RXSEQ:
+ continue;
+ case 0x00000100:
+ if (adapter->hw.mac.type == e1000_ich8lan ||
+ adapter->hw.mac.type == e1000_ich9lan)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+
if (!shared_int) {
/*
* Disable the interrupt to be reported in
@@ -974,7 +999,14 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Unhook test interrupt handler */
free_irq(irq, netdev);
- return *data;
+out:
+ if (int_mode == E1000E_INT_MODE_MSIX) {
+ e1000e_reset_interrupt_capability(adapter);
+ adapter->int_mode = int_mode;
+ e1000e_set_interrupt_capability(adapter);
+ }
+
+ return ret_val;
}
static void e1000_free_desc_rings(struct e1000_adapter *adapter)
@@ -1755,11 +1787,13 @@ static void e1000_led_blink_callback(unsigned long data)
static int e1000_phys_id(struct net_device *netdev, u32 data)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
if (!data)
data = INT_MAX;
- if (adapter->hw.phy.type == e1000_phy_ife) {
+ if ((hw->phy.type == e1000_phy_ife) ||
+ (hw->mac.type == e1000_82574)) {
if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function =
@@ -1769,16 +1803,16 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
mod_timer(&adapter->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer);
- e1e_wphy(&adapter->hw,
- IFE_PHY_SPECIAL_CONTROL_LED, 0);
+ if (hw->phy.type == e1000_phy_ife)
+ e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
} else {
- e1000e_blink_led(&adapter->hw);
+ e1000e_blink_led(hw);
msleep_interruptible(data * 1000);
}
- adapter->hw.mac.ops.led_off(&adapter->hw);
+ hw->mac.ops.led_off(hw);
clear_bit(E1000_LED_ON, &adapter->led_status);
- adapter->hw.mac.ops.cleanup_led(&adapter->hw);
+ hw->mac.ops.cleanup_led(hw);
return 0;
}
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 74f263a..f66ed37 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -65,7 +65,11 @@ enum e1e_registers {
E1000_ICS = 0x000C8, /* Interrupt Cause Set - WO */
E1000_IMS = 0x000D0, /* Interrupt Mask Set - RW */
E1000_IMC = 0x000D8, /* Interrupt Mask Clear - WO */
+ E1000_EIAC_82574 = 0x000DC, /* Ext. Interrupt Auto Clear - RW */
E1000_IAM = 0x000E0, /* Interrupt Acknowledge Auto Mask */
+ E1000_IVAR = 0x000E4, /* Interrupt Vector Allocation - RW */
+ E1000_EITR_82574_BASE = 0x000E8, /* Interrupt Throttling - RW */
+#define E1000_EITR_82574(_n) (E1000_EITR_82574_BASE + (_n << 2))
E1000_RCTL = 0x00100, /* Rx Control - RW */
E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value - RW */
E1000_TXCW = 0x00178, /* Tx Configuration Word - RW */
@@ -332,6 +336,7 @@ enum e1e_registers {
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
+#define E1000_DEV_ID_82574L 0x10D3
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
@@ -346,6 +351,7 @@ enum e1e_registers {
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
+#define E1000_DEV_ID_ICH9_BM 0x10E5
#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5
#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB
@@ -356,6 +362,10 @@ enum e1e_registers {
#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
+#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
+#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
+
+#define E1000_REVISION_4 4
#define E1000_FUNC_1 1
@@ -363,9 +373,11 @@ enum e1000_mac_type {
e1000_82571,
e1000_82572,
e1000_82573,
+ e1000_82574,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
+ e1000_ich10lan,
};
enum e1000_media_type {
@@ -696,8 +708,7 @@ struct e1000_host_mng_command_info {
/* Function pointers and static data for the MAC. */
struct e1000_mac_operations {
- u32 mng_mode_enab;
-
+ bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 9e38452..019b9c0 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -43,7 +43,9 @@
* 82567LM-2 Gigabit Network Connection
* 82567LF-2 Gigabit Network Connection
* 82567V-2 Gigabit Network Connection
- * 82562GT-3 10/100 Network Connection
+ * 82567LF-3 Gigabit Network Connection
+ * 82567LM-3 Gigabit Network Connection
+ * 82567LM-4 Gigabit Network Connection
*/
#include <linux/netdevice.h>
@@ -157,12 +159,15 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw);
static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
u32 offset, u8 byte);
+static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
+ u8 *data);
static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
u16 *data);
static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
u8 size, u16 *data);
static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
+static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
@@ -417,6 +422,22 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_check_mng_mode_ich8lan - Checks management mode
+ * @hw: pointer to the HW structure
+ *
+ * This checks if the adapter has manageability enabled.
+ * This is a function pointer entry point only called by read/write
+ * routines for the PHY and NVM parts.
+ **/
+static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
+{
+ u32 fwsm = er32(FWSM);
+
+ return (fwsm & E1000_FWSM_MODE_MASK) ==
+ (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
+}
+
+/**
* e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
* @hw: pointer to the HW structure
*
@@ -897,6 +918,56 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
}
/**
+ * e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1
+ * @hw: pointer to the HW structure
+ * @bank: pointer to the variable that returns the active bank
+ *
+ * Reads signature byte from the NVM using the flash access registers.
+ **/
+static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ /* flash bank size is in words */
+ u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
+ u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
+ u8 bank_high_byte = 0;
+
+ if (hw->mac.type != e1000_ich10lan) {
+ if (er32(EECD) & E1000_EECD_SEC1VAL)
+ *bank = 1;
+ else
+ *bank = 0;
+ } else {
+ /*
+ * Make sure the signature for bank 0 is valid,
+ * if not check for bank1
+ */
+ e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte);
+ if ((bank_high_byte & 0xC0) == 0x80) {
+ *bank = 0;
+ } else {
+ /*
+ * find if segment 1 is valid by verifying
+ * bit 15:14 = 10b in word 0x13
+ */
+ e1000_read_flash_byte_ich8lan(hw,
+ act_offset + bank1_offset,
+ &bank_high_byte);
+
+ /* bank1 has a valid signature equivalent to SEC1V */
+ if ((bank_high_byte & 0xC0) == 0x80) {
+ *bank = 1;
+ } else {
+ hw_dbg(hw, "ERROR: EEPROM not present\n");
+ return -E1000_ERR_NVM;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
* e1000_read_nvm_ich8lan - Read word(s) from the NVM
* @hw: pointer to the HW structure
* @offset: The offset (in bytes) of the word(s) to read.
@@ -912,6 +983,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
u32 act_offset;
s32 ret_val;
+ u32 bank = 0;
u16 i, word;
if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
@@ -924,10 +996,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
if (ret_val)
return ret_val;
- /* Start with the bank offset, then add the relative offset. */
- act_offset = (er32(EECD) & E1000_EECD_SEC1VAL)
- ? nvm->flash_bank_size
- : 0;
+ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
+ if (ret_val)
+ return ret_val;
+
+ act_offset = (bank) ? nvm->flash_bank_size : 0;
act_offset += offset;
for (i = 0; i < words; i++) {
@@ -1075,6 +1148,29 @@ static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
}
/**
+ * e1000_read_flash_byte_ich8lan - Read byte from flash
+ * @hw: pointer to the HW structure
+ * @offset: The offset of the byte to read.
+ * @data: Pointer to a byte to store the value read.
+ *
+ * Reads a single byte from the NVM using the flash access registers.
+ **/
+static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
+ u8 *data)
+{
+ s32 ret_val;
+ u16 word = 0;
+
+ ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
+ if (ret_val)
+ return ret_val;
+
+ *data = (u8)word;
+
+ return 0;
+}
+
+/**
* e1000_read_flash_data_ich8lan - Read byte or word from NVM
* @hw: pointer to the HW structure
* @offset: The offset (in bytes) of the byte or word to read.
@@ -1205,7 +1301,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 i, act_offset, new_bank_offset, old_bank_offset;
+ u32 i, act_offset, new_bank_offset, old_bank_offset, bank;
s32 ret_val;
u16 data;
@@ -1225,7 +1321,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
* write to bank 0 etc. We also need to erase the segment that
* is going to be written
*/
- if (!(er32(EECD) & E1000_EECD_SEC1VAL)) {
+ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
+ if (ret_val)
+ return ret_val;
+
+ if (bank == 0) {
new_bank_offset = nvm->flash_bank_size;
old_bank_offset = 0;
e1000_erase_flash_bank_ich8lan(hw, 1);
@@ -2189,13 +2289,14 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
* 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
* to a lower speed.
*
- * Should only be called for ICH9 devices.
+ * Should only be called for ICH9 and ICH10 devices.
**/
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
{
u32 phy_ctrl;
- if (hw->mac.type == e1000_ich9lan) {
+ if ((hw->mac.type == e1000_ich10lan) ||
+ (hw->mac.type == e1000_ich9lan)) {
phy_ctrl = er32(PHY_CTRL);
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_GBE_DISABLE;
@@ -2253,6 +2354,39 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
}
/**
+ * e1000_get_cfg_done_ich8lan - Read config done bit
+ * @hw: pointer to the HW structure
+ *
+ * Read the management control register for the config done bit for
+ * completion status. NOTE: silicon which is EEPROM-less will fail trying
+ * to read the config done bit, so an error is *ONLY* logged and returns
+ * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
+ * would not be able to be reset or change link.
+ **/
+static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
+{
+ u32 bank = 0;
+
+ e1000e_get_cfg_done(hw);
+
+ /* If EEPROM is not marked present, init the IGP 3 PHY manually */
+ if (hw->mac.type != e1000_ich10lan) {
+ if (((er32(EECD) & E1000_EECD_PRES) == 0) &&
+ (hw->phy.type == e1000_phy_igp_3)) {
+ e1000e_phy_init_script_igp3(hw);
+ }
+ } else {
+ if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) {
+ /* Maybe we should do a basic PHY config */
+ hw_dbg(hw, "EEPROM not present\n");
+ return -E1000_ERR_CONFIG;
+ }
+ }
+
+ return 0;
+}
+
+/**
* e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
* @hw: pointer to the HW structure
*
@@ -2282,7 +2416,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
}
static struct e1000_mac_operations ich8_mac_ops = {
- .mng_mode_enab = E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT,
+ .check_mng_mode = e1000_check_mng_mode_ich8lan,
.check_for_link = e1000e_check_for_copper_link,
.cleanup_led = e1000_cleanup_led_ich8lan,
.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan,
@@ -2302,7 +2436,7 @@ static struct e1000_phy_operations ich8_phy_ops = {
.check_reset_block = e1000_check_reset_block_ich8lan,
.commit_phy = NULL,
.force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan,
- .get_cfg_done = e1000e_get_cfg_done,
+ .get_cfg_done = e1000_get_cfg_done_ich8lan,
.get_cable_length = e1000e_get_cable_length_igp_2,
.get_phy_info = e1000_get_phy_info_ich8lan,
.read_phy_reg = e1000e_read_phy_reg_igp,
@@ -2357,3 +2491,20 @@ struct e1000_info e1000_ich9_info = {
.nvm_ops = &ich8_nvm_ops,
};
+struct e1000_info e1000_ich10_info = {
+ .mac = e1000_ich10lan,
+ .flags = FLAG_HAS_JUMBO_FRAMES
+ | FLAG_IS_ICH
+ | FLAG_HAS_WOL
+ | FLAG_RX_CSUM_ENABLED
+ | FLAG_HAS_CTRLEXT_ON_LOAD
+ | FLAG_HAS_AMT
+ | FLAG_HAS_ERT
+ | FLAG_HAS_FLASH
+ | FLAG_APME_IN_WUC,
+ .pba = 10,
+ .get_variants = e1000_get_variants_ich8lan,
+ .mac_ops = &ich8_mac_ops,
+ .phy_ops = &ich8_phy_ops,
+ .nvm_ops = &ich8_nvm_ops,
+};
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index f1f4e9d..c733730 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -2222,17 +2222,18 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
}
/**
- * e1000e_check_mng_mode - check management mode
+ * e1000e_check_mng_mode_generic - check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
-bool e1000e_check_mng_mode(struct e1000_hw *hw)
+bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm = er32(FWSM);
- return (fwsm & E1000_FWSM_MODE_MASK) == hw->mac.ops.mng_mode_enab;
+ return (fwsm & E1000_FWSM_MODE_MASK) ==
+ (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
}
/**
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index d266510..0925204 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -55,9 +55,11 @@ static const struct e1000_info *e1000_info_tbl[] = {
[board_82571] = &e1000_82571_info,
[board_82572] = &e1000_82572_info,
[board_82573] = &e1000_82573_info,
+ [board_82574] = &e1000_82574_info,
[board_80003es2lan] = &e1000_es2_info,
[board_ich8lan] = &e1000_ich8_info,
[board_ich9lan] = &e1000_ich9_info,
+ [board_ich10lan] = &e1000_ich10_info,
};
#ifdef DEBUG
@@ -1179,8 +1181,8 @@ static irqreturn_t e1000_intr(int irq, void *data)
struct net_device *netdev = data;
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
-
u32 rctl, icr = er32(ICR);
+
if (!icr)
return IRQ_NONE; /* Not our interrupt */
@@ -1236,6 +1238,263 @@ static irqreturn_t e1000_intr(int irq, void *data)
return IRQ_HANDLED;
}
+static irqreturn_t e1000_msix_other(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 icr = er32(ICR);
+
+ if (!(icr & E1000_ICR_INT_ASSERTED)) {
+ ew32(IMS, E1000_IMS_OTHER);
+ return IRQ_NONE;
+ }
+
+ if (icr & adapter->eiac_mask)
+ ew32(ICS, (icr & adapter->eiac_mask));
+
+ if (icr & E1000_ICR_OTHER) {
+ if (!(icr & E1000_ICR_LSC))
+ goto no_link_interrupt;
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__E1000_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+no_link_interrupt:
+ ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
+
+ return IRQ_HANDLED;
+}
+
+
+static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct e1000_ring *tx_ring = adapter->tx_ring;
+
+
+ adapter->total_tx_bytes = 0;
+ adapter->total_tx_packets = 0;
+
+ if (!e1000_clean_tx_irq(adapter))
+ /* Ring was not completely cleaned, so fire another interrupt */
+ ew32(ICS, tx_ring->ims_val);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+
+ /* Write the ITR value calculated at the end of the
+ * previous interrupt.
+ */
+ if (adapter->rx_ring->set_itr) {
+ writel(1000000000 / (adapter->rx_ring->itr_val * 256),
+ adapter->hw.hw_addr + adapter->rx_ring->itr_register);
+ adapter->rx_ring->set_itr = 0;
+ }
+
+ if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
+ adapter->total_rx_bytes = 0;
+ adapter->total_rx_packets = 0;
+ __netif_rx_schedule(netdev, &adapter->napi);
+ }
+ return IRQ_HANDLED;
+}
+
+/**
+ * e1000_configure_msix - Configure MSI-X hardware
+ *
+ * e1000_configure_msix sets up the hardware to properly
+ * generate MSI-X interrupts.
+ **/
+static void e1000_configure_msix(struct e1000_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct e1000_ring *rx_ring = adapter->rx_ring;
+ struct e1000_ring *tx_ring = adapter->tx_ring;
+ int vector = 0;
+ u32 ctrl_ext, ivar = 0;
+
+ adapter->eiac_mask = 0;
+
+ /* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
+ if (hw->mac.type == e1000_82574) {
+ u32 rfctl = er32(RFCTL);
+ rfctl |= E1000_RFCTL_ACK_DIS;
+ ew32(RFCTL, rfctl);
+ }
+
+#define E1000_IVAR_INT_ALLOC_VALID 0x8
+ /* Configure Rx vector */
+ rx_ring->ims_val = E1000_IMS_RXQ0;
+ adapter->eiac_mask |= rx_ring->ims_val;
+ if (rx_ring->itr_val)
+ writel(1000000000 / (rx_ring->itr_val * 256),
+ hw->hw_addr + rx_ring->itr_register);
+ else
+ writel(1, hw->hw_addr + rx_ring->itr_register);
+ ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
+
+ /* Configure Tx vector */
+ tx_ring->ims_val = E1000_IMS_TXQ0;
+ vector++;
+ if (tx_ring->itr_val)
+ writel(1000000000 / (tx_ring->itr_val * 256),
+ hw->hw_addr + tx_ring->itr_register);
+ else
+ writel(1, hw->hw_addr + tx_ring->itr_register);
+ adapter->eiac_mask |= tx_ring->ims_val;
+ ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
+
+ /* set vector for Other Causes, e.g. link changes */
+ vector++;
+ ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
+ if (rx_ring->itr_val)
+ writel(1000000000 / (rx_ring->itr_val * 256),
+ hw->hw_addr + E1000_EITR_82574(vector));
+ else
+ writel(1, hw->hw_addr + E1000_EITR_82574(vector));
+
+ /* Cause Tx interrupts on every write back */
+ ivar |= (1 << 31);
+
+ ew32(IVAR, ivar);
+
+ /* enable MSI-X PBA support */
+ ctrl_ext = er32(CTRL_EXT);
+ ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
+
+ /* Auto-Mask Other interrupts upon ICR read */
+#define E1000_EIAC_MASK_82574 0x01F00000
+ ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
+ ctrl_ext |= E1000_CTRL_EXT_EIAME;
+ ew32(CTRL_EXT, ctrl_ext);
+ e1e_flush();
+}
+
+void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
+{
+ if (adapter->msix_entries) {
+ pci_disable_msix(adapter->pdev);
+ kfree(adapter->msix_entries);
+ adapter->msix_entries = NULL;
+ } else if (adapter->flags & FLAG_MSI_ENABLED) {
+ pci_disable_msi(adapter->pdev);
+ adapter->flags &= ~FLAG_MSI_ENABLED;
+ }
+
+ return;
+}
+
+/**
+ * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
+ *
+ * Attempt to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
+{
+ int err;
+ int numvecs, i;
+
+
+ switch (adapter->int_mode) {
+ case E1000E_INT_MODE_MSIX:
+ if (adapter->flags & FLAG_HAS_MSIX) {
+ numvecs = 3; /* RxQ0, TxQ0 and other */
+ adapter->msix_entries = kcalloc(numvecs,
+ sizeof(struct msix_entry),
+ GFP_KERNEL);
+ if (adapter->msix_entries) {
+ for (i = 0; i < numvecs; i++)
+ adapter->msix_entries[i].entry = i;
+
+ err = pci_enable_msix(adapter->pdev,
+ adapter->msix_entries,
+ numvecs);
+ if (err == 0)
+ return;
+ }
+ /* MSI-X failed, so fall through and try MSI */
+ e_err("Failed to initialize MSI-X interrupts. "
+ "Falling back to MSI interrupts.\n");
+ e1000e_reset_interrupt_capability(adapter);
+ }
+ adapter->int_mode = E1000E_INT_MODE_MSI;
+ /* Fall through */
+ case E1000E_INT_MODE_MSI:
+ if (!pci_enable_msi(adapter->pdev)) {
+ adapter->flags |= FLAG_MSI_ENABLED;
+ } else {
+ adapter->int_mode = E1000E_INT_MODE_LEGACY;
+ e_err("Failed to initialize MSI interrupts. Falling "
+ "back to legacy interrupts.\n");
+ }
+ /* Fall through */
+ case E1000E_INT_MODE_LEGACY:
+ /* Don't do anything; this is the system default */
+ break;
+ }
+
+ return;
+}
+
+/**
+ * e1000_request_msix - Initialize MSI-X interrupts
+ *
+ * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
+ * kernel.
+ **/
+static int e1000_request_msix(struct e1000_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err = 0, vector = 0;
+
+ if (strlen(netdev->name) < (IFNAMSIZ - 5))
+ sprintf(adapter->rx_ring->name, "%s-rx0", netdev->name);
+ else
+ memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &e1000_intr_msix_rx, 0, adapter->rx_ring->name,
+ netdev);
+ if (err)
+ goto out;
+ adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
+ adapter->rx_ring->itr_val = adapter->itr;
+ vector++;
+
+ if (strlen(netdev->name) < (IFNAMSIZ - 5))
+ sprintf(adapter->tx_ring->name, "%s-tx0", netdev->name);
+ else
+ memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &e1000_intr_msix_tx, 0, adapter->tx_ring->name,
+ netdev);
+ if (err)
+ goto out;
+ adapter->tx_ring->itr_register = E1000_EITR_82574(vector);
+ adapter->tx_ring->itr_val = adapter->itr;
+ vector++;
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+ &e1000_msix_other, 0, netdev->name, netdev);
+ if (err)
+ goto out;
+
+ e1000_configure_msix(adapter);
+ return 0;
+out:
+ return err;
+}
+
/**
* e1000_request_irq - initialize interrupts
*
@@ -1245,28 +1504,32 @@ static irqreturn_t e1000_intr(int irq, void *data)
static int e1000_request_irq(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- int irq_flags = IRQF_SHARED;
int err;
- if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
- err = pci_enable_msi(adapter->pdev);
- if (!err) {
- adapter->flags |= FLAG_MSI_ENABLED;
- irq_flags = 0;
- }
+ if (adapter->msix_entries) {
+ err = e1000_request_msix(adapter);
+ if (!err)
+ return err;
+ /* fall back to MSI */
+ e1000e_reset_interrupt_capability(adapter);
+ adapter->int_mode = E1000E_INT_MODE_MSI;
+ e1000e_set_interrupt_capability(adapter);
+ }
+ if (adapter->flags & FLAG_MSI_ENABLED) {
+ err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0,
+ netdev->name, netdev);
+ if (!err)
+ return err;
+
+ /* fall back to legacy interrupt */
+ e1000e_reset_interrupt_capability(adapter);
+ adapter->int_mode = E1000E_INT_MODE_LEGACY;
}
- err = request_irq(adapter->pdev->irq,
- ((adapter->flags & FLAG_MSI_ENABLED) ?
- &e1000_intr_msi : &e1000_intr),
- irq_flags, netdev->name, netdev);
- if (err) {
- if (adapter->flags & FLAG_MSI_ENABLED) {
- pci_disable_msi(adapter->pdev);
- adapter->flags &= ~FLAG_MSI_ENABLED;
- }
+ err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED,
+ netdev->name, netdev);
+ if (err)
e_err("Unable to allocate interrupt, Error: %d\n", err);
- }
return err;
}
@@ -1275,11 +1538,21 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- free_irq(adapter->pdev->irq, netdev);
- if (adapter->flags & FLAG_MSI_ENABLED) {
- pci_disable_msi(adapter->pdev);
- adapter->flags &= ~FLAG_MSI_ENABLED;
+ if (adapter->msix_entries) {
+ int vector = 0;
+
+ free_irq(adapter->msix_entries[vector].vector, netdev);
+ vector++;
+
+ free_irq(adapter->msix_entries[vector].vector, netdev);
+ vector++;
+
+ /* Other Causes interrupt vector */
+ free_irq(adapter->msix_entries[vector].vector, netdev);
+ return;
}
+
+ free_irq(adapter->pdev->irq, netdev);
}
/**
@@ -1290,6 +1563,8 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
ew32(IMC, ~0);
+ if (adapter->msix_entries)
+ ew32(EIAC_82574, 0);
e1e_flush();
synchronize_irq(adapter->pdev->irq);
}
@@ -1301,7 +1576,12 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- ew32(IMS, IMS_ENABLE_MASK);
+ if (adapter->msix_entries) {
+ ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
+ ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
+ } else {
+ ew32(IMS, IMS_ENABLE_MASK);
+ }
e1e_flush();
}
@@ -1551,9 +1831,8 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
* traffic pattern. Constants in this function were computed
* based on theoretical maximum wire speed and thresholds were set based
* on testing data as well as attempting to minimize response time
- * while increasing bulk throughput.
- * this functionality is controlled by the InterruptThrottleRate module
- * parameter (see e1000_param.c)
+ * while increasing bulk throughput. This functionality is controlled
+ * by the InterruptThrottleRate module parameter.
**/
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
u16 itr_setting, int packets,
@@ -1661,11 +1940,37 @@ set_itr_now:
min(adapter->itr + (new_itr >> 2), new_itr) :
new_itr;
adapter->itr = new_itr;
- ew32(ITR, 1000000000 / (new_itr * 256));
+ adapter->rx_ring->itr_val = new_itr;
+ if (adapter->msix_entries)
+ adapter->rx_ring->set_itr = 1;
+ else
+ ew32(ITR, 1000000000 / (new_itr * 256));
}
}
/**
+ * e1000_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ **/
+static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
+{
+ adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+ if (!adapter->tx_ring)
+ goto err;
+
+ adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+ if (!adapter->rx_ring)
+ goto err;
+
+ return 0;
+err:
+ e_err("Unable to allocate memory for queues\n");
+ kfree(adapter->rx_ring);
+ kfree(adapter->tx_ring);
+ return -ENOMEM;
+}
+
+/**
* e1000_clean - NAPI Rx polling callback
* @napi: struct associated with this polling callback
* @budget: amount of packets driver is allowed to process this poll
@@ -1673,12 +1978,17 @@ set_itr_now:
static int e1000_clean(struct napi_struct *napi, int budget)
{
struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
+ struct e1000_hw *hw = &adapter->hw;
struct net_device *poll_dev = adapter->netdev;
int tx_cleaned = 0, work_done = 0;
/* Must NOT use netdev_priv macro here. */
adapter = poll_dev->priv;
+ if (adapter->msix_entries &&
+ !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
+ goto clean_rx;
+
/*
* e1000_clean is called per-cpu. This lock protects
* tx_ring from being cleaned by multiple cpus
@@ -1690,6 +2000,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
spin_unlock(&adapter->tx_queue_lock);
}
+clean_rx:
adapter->clean_rx(adapter, &work_done, budget);
if (tx_cleaned)
@@ -1700,7 +2011,10 @@ static int e1000_clean(struct napi_struct *napi, int budget)
if (adapter->itr_setting & 3)
e1000_set_itr(adapter);
netif_rx_complete(poll_dev, napi);
- e1000_irq_enable(adapter);
+ if (adapter->msix_entries)
+ ew32(IMS, adapter->rx_ring->ims_val);
+ else
+ e1000_irq_enable(adapter);
}
return work_done;
@@ -2496,6 +2810,8 @@ int e1000e_up(struct e1000_adapter *adapter)
clear_bit(__E1000_DOWN, &adapter->state);
napi_enable(&adapter->napi);
+ if (adapter->msix_entries)
+ e1000_configure_msix(adapter);
e1000_irq_enable(adapter);
/* fire a link change interrupt to start the watchdog */
@@ -2579,13 +2895,10 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
- adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
- if (!adapter->tx_ring)
- goto err;
+ e1000e_set_interrupt_capability(adapter);
- adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
- if (!adapter->rx_ring)
- goto err;
+ if (e1000_alloc_queues(adapter))
+ return -ENOMEM;
spin_lock_init(&adapter->tx_queue_lock);
@@ -2596,12 +2909,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
set_bit(__E1000_DOWN, &adapter->state);
return 0;
-
-err:
- e_err("Unable to allocate memory for queues\n");
- kfree(adapter->rx_ring);
- kfree(adapter->tx_ring);
- return -ENOMEM;
}
/**
@@ -2643,6 +2950,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
/* free the real vector and request a test handler */
e1000_free_irq(adapter);
+ e1000e_reset_interrupt_capability(adapter);
/* Assume that the test fails, if it succeeds then the test
* MSI irq handler will unset this flag */
@@ -2673,6 +2981,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
rmb();
if (adapter->flags & FLAG_MSI_TEST_FAILED) {
+ adapter->int_mode = E1000E_INT_MODE_LEGACY;
err = -EIO;
e_info("MSI interrupt test failed!\n");
}
@@ -2686,7 +2995,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
/* okay so the test worked, restore settings */
e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
msi_test_failed:
- /* restore the original vector, even if it failed */
+ e1000e_set_interrupt_capability(adapter);
e1000_request_irq(adapter);
return err;
}
@@ -2796,7 +3105,7 @@ static int e1000_open(struct net_device *netdev)
* ignore e1000e MSI messages, which means we need to test our MSI
* interrupt now
*/
- {
+ if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
err = e1000_test_msi(adapter);
if (err) {
e_err("Interrupt allocation failed\n");
@@ -2988,7 +3297,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
adapter->stats.algnerrc += er32(ALGNERRC);
adapter->stats.rxerrc += er32(RXERRC);
- adapter->stats.tncrs += er32(TNCRS);
+ if (hw->mac.type != e1000_82574)
+ adapter->stats.tncrs += er32(TNCRS);
adapter->stats.cexterr += er32(CEXTERR);
adapter->stats.tsctc += er32(TSCTC);
adapter->stats.tsctfc += er32(TSCTFC);
@@ -3201,6 +3511,27 @@ static void e1000_watchdog_task(struct work_struct *work)
&adapter->link_duplex);
e1000_print_link_info(adapter);
/*
+ * On supported PHYs, check for duplex mismatch only
+ * if link has autonegotiated at 10/100 half
+ */
+ if ((hw->phy.type == e1000_phy_igp_3 ||
+ hw->phy.type == e1000_phy_bm) &&
+ (hw->mac.autoneg == true) &&
+ (adapter->link_speed == SPEED_10 ||
+ adapter->link_speed == SPEED_100) &&
+ (adapter->link_duplex == HALF_DUPLEX)) {
+ u16 autoneg_exp;
+
+ e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp);
+
+ if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS))
+ e_info("Autonegotiated half duplex but"
+ " link partner cannot autoneg. "
+ " Try forcing full duplex if "
+ "link gets many collisions.\n");
+ }
+
+ /*
* tweak tx_queue_len according to speed/duplex
* and adjust the timeout factor
*/
@@ -3315,7 +3646,10 @@ link_up:
}
/* Cause software interrupt to ensure Rx ring is cleaned */
- ew32(ICS, E1000_ICS_RXDMT0);
+ if (adapter->msix_entries)
+ ew32(ICS, adapter->rx_ring->ims_val);
+ else
+ ew32(ICS, E1000_ICS_RXDMT0);
/* Force detection of hung controller every watchdog period */
adapter->detect_tx_hung = 1;
@@ -4032,6 +4366,7 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
e1000e_down(adapter);
e1000_free_irq(adapter);
}
+ e1000e_reset_interrupt_capability(adapter);
retval = pci_save_state(pdev);
if (retval)
@@ -4158,6 +4493,7 @@ static int e1000_resume(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
+ e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
err = e1000_request_irq(adapter);
if (err)
@@ -4467,6 +4803,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->bd_number = cards_found++;
+ e1000e_check_options(adapter);
+
/* setup adapter struct */
err = e1000_sw_init(adapter);
if (err)
@@ -4573,8 +4911,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->reset_task, e1000_reset_task);
INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
- e1000e_check_options(adapter);
-
/* Initialize link parameters. User can change them with ethtool */
adapter->hw.mac.autoneg = 1;
adapter->fc_autoneg = 1;
@@ -4704,6 +5040,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
if (!e1000_check_reset_block(&adapter->hw))
e1000_phy_hw_reset(&adapter->hw);
+ e1000e_reset_interrupt_capability(adapter);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
@@ -4745,6 +5082,8 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
+
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
board_80003es2lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
@@ -4767,6 +5106,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
@@ -4775,6 +5115,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
+
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index ed912e0..f46db6c 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -114,6 +114,15 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define DEFAULT_ITR 3
#define MAX_ITR 100000
#define MIN_ITR 100
+/* IntMode (Interrupt Mode)
+ *
+ * Valid Range: 0 - 2
+ *
+ * Default Value: 2 (MSI-X)
+ */
+E1000_PARAM(IntMode, "Interrupt Mode");
+#define MAX_INTMODE 2
+#define MIN_INTMODE 0
/*
* Enable Smart Power Down of the PHY
@@ -352,6 +361,24 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
adapter->itr = 20000;
}
}
+ { /* Interrupt Mode */
+ struct e1000_option opt = {
+ .type = range_option,
+ .name = "Interrupt Mode",
+ .err = "defaulting to 2 (MSI-X)",
+ .def = E1000E_INT_MODE_MSIX,
+ .arg = { .r = { .min = MIN_INTMODE,
+ .max = MAX_INTMODE } }
+ };
+
+ if (num_IntMode > bd) {
+ unsigned int int_mode = IntMode[bd];
+ e1000_validate_option(&int_mode, &opt, adapter);
+ adapter->int_mode = int_mode;
+ } else {
+ adapter->int_mode = opt.def;
+ }
+ }
{ /* Smart Power Down */
const struct e1000_option opt = {
.type = enable_option,
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index b133dcf..6cd333a 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -476,7 +476,9 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) {
+ if ((phy->type == e1000_phy_m88) &&
+ (phy->revision < E1000_REVISION_4) &&
+ (phy->id != BME1000_E_PHY_ID_R2)) {
/*
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
@@ -504,6 +506,18 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
return ret_val;
}
+ if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) {
+ /* Set PHY page 0, register 29 to 0x0003 */
+ ret_val = e1e_wphy(hw, 29, 0x0003);
+ if (ret_val)
+ return ret_val;
+
+ /* Set PHY page 0, register 30 to 0x0000 */
+ ret_val = e1e_wphy(hw, 30, 0x0000);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Commit the changes. */
ret_val = e1000e_commit_phy(hw);
if (ret_val)
@@ -1720,6 +1734,91 @@ s32 e1000e_get_cfg_done(struct e1000_hw *hw)
return 0;
}
+/**
+ * e1000e_phy_init_script_igp3 - Inits the IGP3 PHY
+ * @hw: pointer to the HW structure
+ *
+ * Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
+ **/
+s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw)
+{
+ hw_dbg(hw, "Running IGP 3 PHY init script\n");
+
+ /* PHY init IGP 3 */
+ /* Enable rise/fall, 10-mode work in class-A */
+ e1e_wphy(hw, 0x2F5B, 0x9018);
+ /* Remove all caps from Replica path filter */
+ e1e_wphy(hw, 0x2F52, 0x0000);
+ /* Bias trimming for ADC, AFE and Driver (Default) */
+ e1e_wphy(hw, 0x2FB1, 0x8B24);
+ /* Increase Hybrid poly bias */
+ e1e_wphy(hw, 0x2FB2, 0xF8F0);
+ /* Add 4% to Tx amplitude in Gig mode */
+ e1e_wphy(hw, 0x2010, 0x10B0);
+ /* Disable trimming (TTT) */
+ e1e_wphy(hw, 0x2011, 0x0000);
+ /* Poly DC correction to 94.6% + 2% for all channels */
+ e1e_wphy(hw, 0x20DD, 0x249A);
+ /* ABS DC correction to 95.9% */
+ e1e_wphy(hw, 0x20DE, 0x00D3);
+ /* BG temp curve trim */
+ e1e_wphy(hw, 0x28B4, 0x04CE);
+ /* Increasing ADC OPAMP stage 1 currents to max */
+ e1e_wphy(hw, 0x2F70, 0x29E4);
+ /* Force 1000 ( required for enabling PHY regs configuration) */
+ e1e_wphy(hw, 0x0000, 0x0140);
+ /* Set upd_freq to 6 */
+ e1e_wphy(hw, 0x1F30, 0x1606);
+ /* Disable NPDFE */
+ e1e_wphy(hw, 0x1F31, 0xB814);
+ /* Disable adaptive fixed FFE (Default) */
+ e1e_wphy(hw, 0x1F35, 0x002A);
+ /* Enable FFE hysteresis */
+ e1e_wphy(hw, 0x1F3E, 0x0067);
+ /* Fixed FFE for short cable lengths */
+ e1e_wphy(hw, 0x1F54, 0x0065);
+ /* Fixed FFE for medium cable lengths */
+ e1e_wphy(hw, 0x1F55, 0x002A);
+ /* Fixed FFE for long cable lengths */
+ e1e_wphy(hw, 0x1F56, 0x002A);
+ /* Enable Adaptive Clip Threshold */
+ e1e_wphy(hw, 0x1F72, 0x3FB0);
+ /* AHT reset limit to 1 */
+ e1e_wphy(hw, 0x1F76, 0xC0FF);
+ /* Set AHT master delay to 127 msec */
+ e1e_wphy(hw, 0x1F77, 0x1DEC);
+ /* Set scan bits for AHT */
+ e1e_wphy(hw, 0x1F78, 0xF9EF);
+ /* Set AHT Preset bits */
+ e1e_wphy(hw, 0x1F79, 0x0210);
+ /* Change integ_factor of channel A to 3 */
+ e1e_wphy(hw, 0x1895, 0x0003);
+ /* Change prop_factor of channels BCD to 8 */
+ e1e_wphy(hw, 0x1796, 0x0008);
+ /* Change cg_icount + enable integbp for channels BCD */
+ e1e_wphy(hw, 0x1798, 0xD008);
+ /*
+ * Change cg_icount + enable integbp + change prop_factor_master
+ * to 8 for channel A
+ */
+ e1e_wphy(hw, 0x1898, 0xD918);
+ /* Disable AHT in Slave mode on channel A */
+ e1e_wphy(hw, 0x187A, 0x0800);
+ /*
+ * Enable LPLU and disable AN to 1000 in non-D0a states,
+ * Enable SPD+B2B
+ */
+ e1e_wphy(hw, 0x0019, 0x008D);
+ /* Enable restart AN on an1000_dis change */
+ e1e_wphy(hw, 0x001B, 0x2080);
+ /* Enable wh_fifo read clock in 10/100 modes */
+ e1e_wphy(hw, 0x0014, 0x0045);
+ /* Restart AN, Speed selection is 1000 */
+ e1e_wphy(hw, 0x0000, 0x1340);
+
+ return 0;
+}
+
/* Internal function pointers */
/**
@@ -1969,6 +2068,99 @@ out:
}
/**
+ * e1000e_read_phy_reg_bm2 - Read BM PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to be read
+ * @data: pointer to the read data
+ *
+ * Acquires semaphore, if necessary, then reads the PHY register at offset
+ * and storing the retrieved information in data. Release any acquired
+ * semaphores before exiting.
+ **/
+s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ s32 ret_val;
+ u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
+
+ /* Page 800 works differently than the rest so it has its own func */
+ if (page == BM_WUC_PAGE) {
+ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
+ true);
+ return ret_val;
+ }
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
+ hw->phy.addr = 1;
+
+ if (offset > MAX_PHY_MULTI_PAGE_REG) {
+
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
+ page);
+
+ if (ret_val) {
+ hw->phy.ops.release_phy(hw);
+ return ret_val;
+ }
+ }
+
+ ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
+ hw->phy.ops.release_phy(hw);
+
+ return ret_val;
+}
+
+/**
+ * e1000e_write_phy_reg_bm2 - Write BM PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore, if necessary, then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ s32 ret_val;
+ u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
+
+ /* Page 800 works differently than the rest so it has its own func */
+ if (page == BM_WUC_PAGE) {
+ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
+ false);
+ return ret_val;
+ }
+
+ ret_val = hw->phy.ops.acquire_phy(hw);
+ if (ret_val)
+ return ret_val;
+
+ hw->phy.addr = 1;
+
+ if (offset > MAX_PHY_MULTI_PAGE_REG) {
+ /* Page is shifted left, PHY expects (page x 32) */
+ ret_val = e1000e_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
+ page);
+
+ if (ret_val) {
+ hw->phy.ops.release_phy(hw);
+ return ret_val;
+ }
+ }
+
+ ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
+
+ hw->phy.ops.release_phy(hw);
+
+ return ret_val;
+}
+
+/**
* e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
* @hw: pointer to the HW structure
* @offset: register offset to be read or written
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h
index eaa7262..717dc38 100644
--- a/drivers/net/ibm_newemac/mal.h
+++ b/drivers/net/ibm_newemac/mal.h
@@ -102,7 +102,7 @@
/* MAL V1 IER bits */
#define MAL1_IER_NWE 0x00000008
#define MAL1_IER_SOC_EVENTS MAL1_IER_NWE
-#define MAL1_IER_EVENTS (MAL1_IER_SOC_EVENTS | MAL_IER_OTE | \
+#define MAL1_IER_EVENTS (MAL1_IER_SOC_EVENTS | MAL_IER_DE | \
MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
/* MAL V2 IER bits */
@@ -110,7 +110,7 @@
#define MAL2_IER_PRE 0x00000040
#define MAL2_IER_PWE 0x00000020
#define MAL2_IER_SOC_EVENTS (MAL2_IER_PT | MAL2_IER_PRE | MAL2_IER_PWE)
-#define MAL2_IER_EVENTS (MAL2_IER_SOC_EVENTS | MAL_IER_OTE | \
+#define MAL2_IER_EVENTS (MAL2_IER_SOC_EVENTS | MAL_IER_DE | \
MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 634c4c9..93d02ef 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3563,10 +3563,6 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
struct net_device *netdev = adapter->netdev;
int work_done = 0;
- /* Keep link state information with original netdev */
- if (!netif_carrier_ok(netdev))
- goto quit_polling;
-
#ifdef CONFIG_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring);
@@ -3576,7 +3572,6 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
/* If not enough Rx work done, exit the polling mode */
if ((work_done == 0) || !netif_running(netdev)) {
-quit_polling:
netif_rx_complete(netdev, napi);
if (adapter->itr_setting & 3) {
@@ -3617,16 +3612,14 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
unsigned int i;
u32 head, oldhead;
unsigned int count = 0;
- bool cleaned = false;
- bool retval = true;
unsigned int total_bytes = 0, total_packets = 0;
+ bool retval = true;
rmb();
head = get_head(tx_ring);
i = tx_ring->next_to_clean;
while (1) {
while (i != head) {
- cleaned = true;
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
skb = buffer_info->skb;
@@ -3643,7 +3636,6 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
}
igb_unmap_and_free_tx_resource(adapter, buffer_info);
- tx_desc->upper.data = 0;
i++;
if (i == tx_ring->count)
@@ -3665,7 +3657,7 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
done_cleaning:
tx_ring->next_to_clean = i;
- if (unlikely(cleaned &&
+ if (unlikely(count &&
netif_carrier_ok(netdev) &&
IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
/* Make sure that anybody stopping the queue after this
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 956914a..90b5383 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -37,7 +37,7 @@
#include "ixgbe_type.h"
#include "ixgbe_common.h"
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
#include <linux/dca.h>
#endif
@@ -69,12 +69,12 @@
/* flow control */
#define IXGBE_DEFAULT_FCRTL 0x10000
-#define IXGBE_MIN_FCRTL 0
+#define IXGBE_MIN_FCRTL 0x40
#define IXGBE_MAX_FCRTL 0x7FF80
#define IXGBE_DEFAULT_FCRTH 0x20000
-#define IXGBE_MIN_FCRTH 0
+#define IXGBE_MIN_FCRTH 0x600
#define IXGBE_MAX_FCRTH 0x7FFF0
-#define IXGBE_DEFAULT_FCPAUSE 0x6800 /* may be too long */
+#define IXGBE_DEFAULT_FCPAUSE 0xFFFF
#define IXGBE_MIN_FCPAUSE 0
#define IXGBE_MAX_FCPAUSE 0xFFFF
@@ -150,7 +150,7 @@ struct ixgbe_ring {
* offset associated with this ring, which is different
* for DCE and RSS modes */
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
/* cpu for tx queue */
int cpu;
#endif
@@ -166,6 +166,7 @@ struct ixgbe_ring {
char name[IFNAMSIZ + 5];
u16 work_limit; /* max work per interrupt */
+ u16 rx_buf_len;
};
#define RING_F_VMDQ 1
@@ -228,7 +229,6 @@ struct ixgbe_adapter {
struct timer_list watchdog_timer;
struct vlan_group *vlgrp;
u16 bd_number;
- u16 rx_buf_len;
struct work_struct reset_task;
struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
@@ -267,15 +267,28 @@ struct ixgbe_adapter {
* thus the additional *_CAPABLE flags.
*/
u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1 << 0)
-#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 1)
-#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 2)
-#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 3)
-#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 4)
-#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5)
-#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 6)
-#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7)
-#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 8)
+#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
+#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
+#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
+#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
+#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
+#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
+#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
+#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
+#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
+#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
+#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
+#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
+#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
+#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
+#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
+#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
+#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
+#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
+
+/* default to trying for four seconds */
+#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
/* OS defined structs */
struct net_device *netdev;
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index f96358b..ba09063 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -36,6 +36,8 @@
#define IXGBE_82598_MAX_TX_QUEUES 32
#define IXGBE_82598_MAX_RX_QUEUES 64
#define IXGBE_82598_RAR_ENTRIES 16
+#define IXGBE_82598_MC_TBL_SIZE 128
+#define IXGBE_82598_VFT_TBL_SIZE 128
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw);
static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
@@ -60,7 +62,9 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
+ hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE;
+ hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE;
+ hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES;
/* PHY ops are filled in by default properly for Fiber only */
if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 7fd6aeb..9c0d0a1 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -661,7 +661,7 @@ s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
{
u32 i;
- u32 rar_entries = hw->mac.num_rx_addrs;
+ u32 rar_entries = hw->mac.num_rar_entries;
/*
* If the current mac address is valid, assume it is a software override
@@ -705,13 +705,114 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
hw_dbg(hw, " Clearing MTA\n");
- for (i = 0; i < IXGBE_MC_TBL_SIZE; i++)
+ for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
return 0;
}
/**
+ * ixgbe_add_uc_addr - Adds a secondary unicast address.
+ * @hw: pointer to hardware structure
+ * @addr: new address
+ *
+ * Adds it to unused receive address register or goes into promiscuous mode.
+ **/
+void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
+{
+ u32 rar_entries = hw->mac.num_rar_entries;
+ u32 rar;
+
+ hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n",
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+ /*
+ * Place this address in the RAR if there is room,
+ * else put the controller into promiscuous mode
+ */
+ if (hw->addr_ctrl.rar_used_count < rar_entries) {
+ rar = hw->addr_ctrl.rar_used_count -
+ hw->addr_ctrl.mc_addr_in_rar_count;
+ ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV);
+ hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
+ hw->addr_ctrl.rar_used_count++;
+ } else {
+ hw->addr_ctrl.overflow_promisc++;
+ }
+
+ hw_dbg(hw, "ixgbe_add_uc_addr Complete\n");
+}
+
+/**
+ * ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses
+ * @hw: pointer to hardware structure
+ * @addr_list: the list of new addresses
+ * @addr_count: number of addresses
+ * @next: iterator function to walk the address list
+ *
+ * The given list replaces any existing list. Clears the secondary addrs from
+ * receive address registers. Uses unused receive address registers for the
+ * first secondary addresses, and falls back to promiscuous mode as needed.
+ *
+ * Drivers using secondary unicast addresses must set user_set_promisc when
+ * manually putting the device into promiscuous mode.
+ **/
+s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
+ u32 addr_count, ixgbe_mc_addr_itr next)
+{
+ u8 *addr;
+ u32 i;
+ u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
+ u32 uc_addr_in_use;
+ u32 fctrl;
+ u32 vmdq;
+
+ /*
+ * Clear accounting of old secondary address list,
+ * don't count RAR[0]
+ */
+ uc_addr_in_use = hw->addr_ctrl.rar_used_count -
+ hw->addr_ctrl.mc_addr_in_rar_count - 1;
+ hw->addr_ctrl.rar_used_count -= uc_addr_in_use;
+ hw->addr_ctrl.overflow_promisc = 0;
+
+ /* Zero out the other receive addresses */
+ hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use);
+ for (i = 1; i <= uc_addr_in_use; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
+ }
+
+ /* Add the new addresses */
+ for (i = 0; i < addr_count; i++) {
+ hw_dbg(hw, " Adding the secondary addresses:\n");
+ addr = next(hw, &addr_list, &vmdq);
+ ixgbe_add_uc_addr(hw, addr);
+ }
+
+ if (hw->addr_ctrl.overflow_promisc) {
+ /* enable promisc if not already in overflow or set by user */
+ if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
+ hw_dbg(hw, " Entering address overflow promisc mode\n");
+ fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl |= IXGBE_FCTRL_UPE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ }
+ } else {
+ /* only disable if set by overflow, not by user */
+ if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) {
+ hw_dbg(hw, " Leaving address overflow promisc mode\n");
+ fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl &= ~IXGBE_FCTRL_UPE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ }
+ }
+
+ hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n");
+ return 0;
+}
+
+/**
* ixgbe_mta_vector - Determines bit-vector in multicast table to set
* @hw: pointer to hardware structure
* @mc_addr: the multicast address
@@ -794,7 +895,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
**/
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
{
- u32 rar_entries = hw->mac.num_rx_addrs;
+ u32 rar_entries = hw->mac.num_rar_entries;
hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
mc_addr[0], mc_addr[1], mc_addr[2],
@@ -823,7 +924,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
* @hw: pointer to hardware structure
* @mc_addr_list: the list of new multicast addresses
* @mc_addr_count: number of addresses
- * @pad: number of bytes between addresses in the list
+ * @next: iterator function to walk the multicast address list
*
* The given list replaces any existing list. Clears the MC addrs from receive
* address registers and the multicast table. Uses unsed receive address
@@ -831,10 +932,11 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
* multicast table.
**/
s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, u32 pad)
+ u32 mc_addr_count, ixgbe_mc_addr_itr next)
{
u32 i;
- u32 rar_entries = hw->mac.num_rx_addrs;
+ u32 rar_entries = hw->mac.num_rar_entries;
+ u32 vmdq;
/*
* Set the new number of MC addresses that we are being requested to
@@ -854,14 +956,13 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
/* Clear the MTA */
hw_dbg(hw, " Clearing MTA\n");
- for (i = 0; i < IXGBE_MC_TBL_SIZE; i++)
+ for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
/* Add the new addresses */
for (i = 0; i < mc_addr_count; i++) {
hw_dbg(hw, " Adding the multicast addresses:\n");
- ixgbe_add_mc_addr(hw, mc_addr_list +
- (i * (IXGBE_ETH_LENGTH_OF_ADDRESS + pad)));
+ ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq));
}
/* Enable mta */
@@ -884,11 +985,11 @@ static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
u32 offset;
u32 vlanbyte;
- for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++)
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
- for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++)
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
0);
@@ -964,6 +1065,13 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
/*
+ * 10 gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.type == ixgbe_fc_default)
+ hw->fc.type = ixgbe_fc_full;
+
+ /*
* We want to save off the original Flow Control configuration just in
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
@@ -1016,6 +1124,16 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
/*
+ * Check for invalid software configuration, zeros are completely
+ * invalid for all parameters used past this point, and if we enable
+ * flow control with zero water marks, we blast flow control packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Flow control structure initialized incorrectly\n");
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
+ }
+
+ /*
* We need to set up the Receive Threshold high and low water
* marks as well as (optionally) enabling the transmission of
* XON frames.
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index de6ddd5..c75ecba 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -47,7 +47,9 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
u32 enable_addr);
s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, u32 pad);
+ u32 mc_addr_count, ixgbe_mc_addr_itr next);
+s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list,
+ u32 mc_addr_count, ixgbe_mc_addr_itr next);
s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 3efe5dd..61c000e 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -233,15 +233,15 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
static u32 ixgbe_get_tx_csum(struct net_device *netdev)
{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
+ return (netdev->features & NETIF_F_IP_CSUM) != 0;
}
static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
{
if (data)
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
else
- netdev->features &= ~NETIF_F_HW_CSUM;
+ netdev->features &= ~NETIF_F_IP_CSUM;
return 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 53f41b6..99e0b34 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -80,7 +80,7 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
void *p);
static struct notifier_block dca_notifier = {
@@ -148,8 +148,7 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
*tx_buffer_info)
{
if (tx_buffer_info->dma) {
- pci_unmap_page(adapter->pdev,
- tx_buffer_info->dma,
+ pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
tx_buffer_info->length, PCI_DMA_TODEVICE);
tx_buffer_info->dma = 0;
}
@@ -162,32 +161,35 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring,
- unsigned int eop,
- union ixgbe_adv_tx_desc *eop_desc)
+ unsigned int eop)
{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 head, tail;
+
/* Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of i */
+ * check with the clearing of time_stamp and movement of eop */
+ head = IXGBE_READ_REG(hw, tx_ring->head);
+ tail = IXGBE_READ_REG(hw, tx_ring->tail);
adapter->detect_tx_hung = false;
- if (tx_ring->tx_buffer_info[eop].dma &&
+ if ((head != tail) &&
+ tx_ring->tx_buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
!(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
/* detected Tx unit hang */
+ union ixgbe_adv_tx_desc *tx_desc;
+ tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
- " TDH <%x>\n"
- " TDT <%x>\n"
+ " Tx Queue <%d>\n"
+ " TDH, TDT <%x>, <%x>\n"
" next_to_use <%x>\n"
" next_to_clean <%x>\n"
"tx_buffer_info[next_to_clean]\n"
" time_stamp <%lx>\n"
- " next_to_watch <%x>\n"
- " jiffies <%lx>\n"
- " next_to_watch.status <%x>\n",
- readl(adapter->hw.hw_addr + tx_ring->head),
- readl(adapter->hw.hw_addr + tx_ring->tail),
- tx_ring->next_to_use,
- tx_ring->next_to_clean,
- tx_ring->tx_buffer_info[eop].time_stamp,
- eop, jiffies, eop_desc->wb.status);
+ " jiffies <%lx>\n",
+ tx_ring->queue_index,
+ head, tail,
+ tx_ring->next_to_use, eop,
+ tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
return true;
}
@@ -203,65 +205,75 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
+#define GET_TX_HEAD_FROM_RING(ring) (\
+ *(volatile u32 *) \
+ ((union ixgbe_adv_tx_desc *)(ring)->desc + (ring)->count))
+static void ixgbe_tx_timeout(struct net_device *netdev);
+
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
* @adapter: board private structure
+ * @tx_ring: tx ring to clean
**/
static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
- struct net_device *netdev = adapter->netdev;
- union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
+ union ixgbe_adv_tx_desc *tx_desc;
struct ixgbe_tx_buffer *tx_buffer_info;
- unsigned int i, eop;
- bool cleaned = false;
- unsigned int total_tx_bytes = 0, total_tx_packets = 0;
+ struct net_device *netdev = adapter->netdev;
+ struct sk_buff *skb;
+ unsigned int i;
+ u32 head, oldhead;
+ unsigned int count = 0;
+ unsigned int total_bytes = 0, total_packets = 0;
+ rmb();
+ head = GET_TX_HEAD_FROM_RING(tx_ring);
+ head = le32_to_cpu(head);
i = tx_ring->next_to_clean;
- eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
- while (eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) {
- cleaned = false;
- while (!cleaned) {
+ while (1) {
+ while (i != head) {
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
- cleaned = (i == eop);
+ skb = tx_buffer_info->skb;
- tx_ring->stats.bytes += tx_buffer_info->length;
- if (cleaned) {
- struct sk_buff *skb = tx_buffer_info->skb;
+ if (skb) {
unsigned int segs, bytecount;
+
+ /* gso_segs is currently only valid for tcp */
segs = skb_shinfo(skb)->gso_segs ?: 1;
/* multiply data chunks by size of headers */
bytecount = ((segs - 1) * skb_headlen(skb)) +
- skb->len;
- total_tx_packets += segs;
- total_tx_bytes += bytecount;
+ skb->len;
+ total_packets += segs;
+ total_bytes += bytecount;
}
+
ixgbe_unmap_and_free_tx_resource(adapter,
- tx_buffer_info);
- tx_desc->wb.status = 0;
+ tx_buffer_info);
i++;
if (i == tx_ring->count)
i = 0;
- }
-
- tx_ring->stats.packets++;
-
- eop = tx_ring->tx_buffer_info[i].next_to_watch;
- eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
-
- /* weight of a sort for tx, avoid endless transmit cleanup */
- if (total_tx_packets >= tx_ring->work_limit)
- break;
- }
+ count++;
+ if (count == tx_ring->count)
+ goto done_cleaning;
+ }
+ oldhead = head;
+ rmb();
+ head = GET_TX_HEAD_FROM_RING(tx_ring);
+ head = le32_to_cpu(head);
+ if (head == oldhead)
+ goto done_cleaning;
+ } /* while (1) */
+
+done_cleaning:
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
- if (total_tx_packets && netif_carrier_ok(netdev) &&
- (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+ if (unlikely(count && netif_carrier_ok(netdev) &&
+ (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
@@ -269,59 +281,68 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!test_bit(__IXGBE_DOWN, &adapter->state)) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
- adapter->restart_queue++;
+ ++adapter->restart_queue;
}
}
- if (adapter->detect_tx_hung)
- if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
- netif_stop_subqueue(netdev, tx_ring->queue_index);
+ if (adapter->detect_tx_hung) {
+ if (ixgbe_check_tx_hang(adapter, tx_ring, i)) {
+ /* schedule immediate reset if we believe we hung */
+ DPRINTK(PROBE, INFO,
+ "tx hang %d detected, resetting adapter\n",
+ adapter->tx_timeout_count + 1);
+ ixgbe_tx_timeout(adapter->netdev);
+ }
+ }
- if (total_tx_packets >= tx_ring->work_limit)
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
+ /* re-arm the interrupt */
+ if ((total_packets >= tx_ring->work_limit) ||
+ (count == tx_ring->count))
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
- tx_ring->total_bytes += total_tx_bytes;
- tx_ring->total_packets += total_tx_packets;
- adapter->net_stats.tx_bytes += total_tx_bytes;
- adapter->net_stats.tx_packets += total_tx_packets;
- cleaned = total_tx_packets ? true : false;
- return cleaned;
+ tx_ring->total_bytes += total_bytes;
+ tx_ring->total_packets += total_packets;
+ tx_ring->stats.bytes += total_bytes;
+ tx_ring->stats.packets += total_packets;
+ adapter->net_stats.tx_bytes += total_bytes;
+ adapter->net_stats.tx_packets += total_packets;
+ return (total_packets ? true : false);
}
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rxr)
+ struct ixgbe_ring *rx_ring)
{
u32 rxctrl;
int cpu = get_cpu();
- int q = rxr - adapter->rx_ring;
+ int q = rx_ring - adapter->rx_ring;
- if (rxr->cpu != cpu) {
+ if (rx_ring->cpu != cpu) {
rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
- rxctrl |= dca_get_tag(cpu);
+ rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
- rxr->cpu = cpu;
+ rx_ring->cpu = cpu;
}
put_cpu();
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *txr)
+ struct ixgbe_ring *tx_ring)
{
u32 txctrl;
int cpu = get_cpu();
- int q = txr - adapter->tx_ring;
+ int q = tx_ring - adapter->tx_ring;
- if (txr->cpu != cpu) {
+ if (tx_ring->cpu != cpu) {
txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
- txctrl |= dca_get_tag(cpu);
+ txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
- txr->cpu = cpu;
+ tx_ring->cpu = cpu;
}
put_cpu();
}
@@ -351,11 +372,14 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
switch (event) {
case DCA_PROVIDER_ADD:
- adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
+ /* if we're already enabled, don't do it again */
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ break;
/* Always use CB2 mode, difference is masked
* in the CB driver. */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
if (dca_add_requester(dev) == 0) {
+ adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
ixgbe_setup_dca(adapter);
break;
}
@@ -372,7 +396,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
return 0;
}
-#endif /* CONFIG_DCA */
+#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */
/**
* ixgbe_receive_skb - Send a completed packet up the stack
* @adapter: board private structure
@@ -420,14 +444,12 @@ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
* @skb: skb currently being received and modified
**/
static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
- u32 status_err,
- struct sk_buff *skb)
+ u32 status_err, struct sk_buff *skb)
{
skb->ip_summed = CHECKSUM_NONE;
- /* Ignore Checksum bit is set, or rx csum disabled */
- if ((status_err & IXGBE_RXD_STAT_IXSM) ||
- !(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
+ /* Rx csum disabled */
+ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
return;
/* if IP and error */
@@ -455,37 +477,36 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
* @adapter: address of board private structure
**/
static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int cleaned_count)
+ struct ixgbe_ring *rx_ring,
+ int cleaned_count)
{
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
- struct ixgbe_rx_buffer *rx_buffer_info;
- struct sk_buff *skb;
+ struct ixgbe_rx_buffer *bi;
unsigned int i;
- unsigned int bufsz = adapter->rx_buf_len + NET_IP_ALIGN;
+ unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN;
i = rx_ring->next_to_use;
- rx_buffer_info = &rx_ring->rx_buffer_info[i];
+ bi = &rx_ring->rx_buffer_info[i];
while (cleaned_count--) {
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
- if (!rx_buffer_info->page &&
- (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
- rx_buffer_info->page = alloc_page(GFP_ATOMIC);
- if (!rx_buffer_info->page) {
+ if (!bi->page &&
+ (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
+ bi->page = alloc_page(GFP_ATOMIC);
+ if (!bi->page) {
adapter->alloc_rx_page_failed++;
goto no_buffers;
}
- rx_buffer_info->page_dma =
- pci_map_page(pdev, rx_buffer_info->page,
- 0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ bi->page_dma = pci_map_page(pdev, bi->page, 0,
+ PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
}
- if (!rx_buffer_info->skb) {
- skb = netdev_alloc_skb(netdev, bufsz);
+ if (!bi->skb) {
+ struct sk_buff *skb = netdev_alloc_skb(netdev, bufsz);
if (!skb) {
adapter->alloc_rx_buff_failed++;
@@ -499,28 +520,25 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
*/
skb_reserve(skb, NET_IP_ALIGN);
- rx_buffer_info->skb = skb;
- rx_buffer_info->dma = pci_map_single(pdev, skb->data,
- bufsz,
- PCI_DMA_FROMDEVICE);
+ bi->skb = skb;
+ bi->dma = pci_map_single(pdev, skb->data, bufsz,
+ PCI_DMA_FROMDEVICE);
}
/* Refresh the desc even if buffer_addrs didn't change because
* each write-back erases this info. */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- rx_desc->read.pkt_addr =
- cpu_to_le64(rx_buffer_info->page_dma);
- rx_desc->read.hdr_addr =
- cpu_to_le64(rx_buffer_info->dma);
+ rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
+ rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
} else {
- rx_desc->read.pkt_addr =
- cpu_to_le64(rx_buffer_info->dma);
+ rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
}
i++;
if (i == rx_ring->count)
i = 0;
- rx_buffer_info = &rx_ring->rx_buffer_info[i];
+ bi = &rx_ring->rx_buffer_info[i];
}
+
no_buffers:
if (rx_ring->next_to_use != i) {
rx_ring->next_to_use = i;
@@ -538,9 +556,19 @@ no_buffers:
}
}
+static inline u16 ixgbe_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc)
+{
+ return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
+}
+
+static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
+{
+ return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
+}
+
static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int *work_done, int work_to_do)
+ struct ixgbe_ring *rx_ring,
+ int *work_done, int work_to_do)
{
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
@@ -548,36 +576,35 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
struct sk_buff *skb;
unsigned int i;
- u32 upper_len, len, staterr;
+ u32 len, staterr;
u16 hdr_info;
bool cleaned = false;
int cleaned_count = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
i = rx_ring->next_to_clean;
- upper_len = 0;
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
rx_buffer_info = &rx_ring->rx_buffer_info[i];
while (staterr & IXGBE_RXD_STAT_DD) {
+ u32 upper_len = 0;
if (*work_done >= work_to_do)
break;
(*work_done)++;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- hdr_info =
- le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info);
- len =
- ((hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
- IXGBE_RXDADV_HDRBUFLEN_SHIFT);
+ hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
+ len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
+ IXGBE_RXDADV_HDRBUFLEN_SHIFT;
if (hdr_info & IXGBE_RXDADV_SPH)
adapter->rx_hdr_split++;
if (len > IXGBE_RX_HDR_SIZE)
len = IXGBE_RX_HDR_SIZE;
upper_len = le16_to_cpu(rx_desc->wb.upper.length);
- } else
+ } else {
len = le16_to_cpu(rx_desc->wb.upper.length);
+ }
cleaned = true;
skb = rx_buffer_info->skb;
@@ -586,8 +613,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
if (len && !skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- adapter->rx_buf_len + NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
+ rx_ring->rx_buf_len + NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
skb_put(skb, len);
}
@@ -666,9 +693,6 @@ next_desc:
if (cleaned_count)
ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
-
rx_ring->total_packets += total_rx_packets;
rx_ring->total_bytes += total_rx_bytes;
adapter->net_stats.rx_bytes += total_rx_bytes;
@@ -901,7 +925,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
{
struct ixgbe_q_vector *q_vector = data;
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *txr;
+ struct ixgbe_ring *tx_ring;
int i, r_idx;
if (!q_vector->txr_count)
@@ -909,14 +933,14 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
- txr = &(adapter->tx_ring[r_idx]);
-#ifdef CONFIG_DCA
+ tx_ring = &(adapter->tx_ring[r_idx]);
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_tx_dca(adapter, txr);
+ ixgbe_update_tx_dca(adapter, tx_ring);
#endif
- txr->total_bytes = 0;
- txr->total_packets = 0;
- ixgbe_clean_tx_irq(adapter, txr);
+ tx_ring->total_bytes = 0;
+ tx_ring->total_packets = 0;
+ ixgbe_clean_tx_irq(adapter, tx_ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
r_idx + 1);
}
@@ -933,18 +957,18 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
{
struct ixgbe_q_vector *q_vector = data;
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *rxr;
+ struct ixgbe_ring *rx_ring;
int r_idx;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
if (!q_vector->rxr_count)
return IRQ_HANDLED;
- rxr = &(adapter->rx_ring[r_idx]);
+ rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rxr->v_idx);
- rxr->total_bytes = 0;
- rxr->total_packets = 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
+ rx_ring->total_bytes = 0;
+ rx_ring->total_packets = 0;
netif_rx_schedule(adapter->netdev, &q_vector->napi);
return IRQ_HANDLED;
@@ -969,18 +993,18 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
struct ixgbe_q_vector *q_vector =
container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *rxr;
+ struct ixgbe_ring *rx_ring;
int work_done = 0;
long r_idx;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
- rxr = &(adapter->rx_ring[r_idx]);
-#ifdef CONFIG_DCA
+ rx_ring = &(adapter->rx_ring[r_idx]);
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
- ixgbe_update_rx_dca(adapter, rxr);
+ ixgbe_update_rx_dca(adapter, rx_ring);
#endif
- ixgbe_clean_rx_irq(adapter, rxr, &work_done, budget);
+ ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
@@ -988,7 +1012,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rxr->v_idx);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
}
return work_done;
@@ -1347,26 +1371,31 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_configure_tx - Configure 8254x Transmit Unit after Reset
+ * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset
* @adapter: board private structure
*
* Configure the Tx unit of the MAC after a reset.
**/
static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
{
- u64 tdba;
+ u64 tdba, tdwba;
struct ixgbe_hw *hw = &adapter->hw;
u32 i, j, tdlen, txctrl;
/* Setup the HW Tx Head and Tail descriptor pointers */
for (i = 0; i < adapter->num_tx_queues; i++) {
- j = adapter->tx_ring[i].reg_idx;
- tdba = adapter->tx_ring[i].dma;
- tdlen = adapter->tx_ring[i].count *
- sizeof(union ixgbe_adv_tx_desc);
+ struct ixgbe_ring *ring = &adapter->tx_ring[i];
+ j = ring->reg_idx;
+ tdba = ring->dma;
+ tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc);
IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
- (tdba & DMA_32BIT_MASK));
+ (tdba & DMA_32BIT_MASK));
IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
+ tdwba = ring->dma +
+ (ring->count * sizeof(union ixgbe_adv_tx_desc));
+ tdwba |= IXGBE_TDWBAL_HEAD_WB_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(j), tdwba & DMA_32BIT_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(j), (tdwba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
@@ -1375,16 +1404,62 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
/* Disable Tx Head Writeback RO bit, since this hoses
* bookkeeping if things aren't delivered in order.
*/
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
}
}
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
+
+static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
+{
+ struct ixgbe_ring *rx_ring;
+ u32 srrctl;
+ int queue0;
+ unsigned long mask;
+
+ /* program one srrctl register per VMDq index */
+ if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
+ long shift, len;
+ mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
+ len = sizeof(adapter->ring_feature[RING_F_VMDQ].mask) * 8;
+ shift = find_first_bit(&mask, len);
+ queue0 = index & mask;
+ index = (index & mask) >> shift;
+ /* program one srrctl per RSS queue since RDRXCTL.MVMEN is enabled */
+ } else {
+ mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
+ queue0 = index & mask;
+ index = index & mask;
+ }
+
+ rx_ring = &adapter->rx_ring[queue0];
+
+ srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index));
+
+ srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
+ srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
+
+ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+ srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+ srrctl |= ((IXGBE_RX_HDR_SIZE <<
+ IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+ IXGBE_SRRCTL_BSIZEHDR_MASK);
+ } else {
+ srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
+
+ if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
+ srrctl |= IXGBE_RXBUFFER_2048 >>
+ IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ else
+ srrctl |= rx_ring->rx_buf_len >>
+ IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ }
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
+}
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
/**
* ixgbe_get_skb_hdr - helper function for LRO header processing
* @skb: pointer to sk_buff to be added to LRO packet
@@ -1399,8 +1474,8 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
union ixgbe_adv_rx_desc *rx_desc = priv;
/* Verify that this is a valid IPv4 TCP packet */
- if (!(rx_desc->wb.lower.lo_dword.pkt_info &
- (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)))
+ if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) &&
+ (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP)))
return -1;
/* Set network headers */
@@ -1412,8 +1487,11 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
return 0;
}
+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+
/**
- * ixgbe_configure_rx - Configure 8254x Receive Unit after Reset
+ * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
* @adapter: board private structure
*
* Configure the Rx unit of the MAC after a reset.
@@ -1426,10 +1504,14 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
int i, j;
u32 rdlen, rxctrl, rxcsum;
- u32 random[10];
+ static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D,
+ 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
+ 0x6A3E67EA, 0x14364D17, 0x3BED200D};
u32 fctrl, hlreg0;
u32 pages;
- u32 reta = 0, mrqc, srrctl;
+ u32 reta = 0, mrqc;
+ u32 rdrxctl;
+ int rx_buf_len;
/* Decide whether to use packet split mode or not */
if (netdev->mtu > ETH_DATA_LEN)
@@ -1439,12 +1521,12 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- adapter->rx_buf_len = IXGBE_RX_HDR_SIZE;
+ rx_buf_len = IXGBE_RX_HDR_SIZE;
} else {
if (netdev->mtu <= ETH_DATA_LEN)
- adapter->rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+ rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
- adapter->rx_buf_len = ALIGN(max_frame, 1024);
+ rx_buf_len = ALIGN(max_frame, 1024);
}
fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
@@ -1461,28 +1543,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
pages = PAGE_USE_COUNT(adapter->netdev->mtu);
- srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(0));
- srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
- srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
-
- if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- srrctl |= PAGE_SIZE >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
- srrctl |= ((IXGBE_RX_HDR_SIZE <<
- IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
- IXGBE_SRRCTL_BSIZEHDR_MASK);
- } else {
- srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
- if (adapter->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
- srrctl |=
- IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- else
- srrctl |=
- adapter->rx_buf_len >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- }
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(0), srrctl);
-
rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
/* disable receives while setting up the descriptors */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1492,25 +1552,43 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
* the Base and Length of the Rx Descriptor Ring */
for (i = 0; i < adapter->num_rx_queues; i++) {
rdba = adapter->rx_ring[i].dma;
- IXGBE_WRITE_REG(hw, IXGBE_RDBAL(i), (rdba & DMA_32BIT_MASK));
- IXGBE_WRITE_REG(hw, IXGBE_RDBAH(i), (rdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_RDLEN(i), rdlen);
- IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0);
- adapter->rx_ring[i].head = IXGBE_RDH(i);
- adapter->rx_ring[i].tail = IXGBE_RDT(i);
- }
-
- /* Intitial LRO Settings */
- adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
- adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
- adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
- adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
- adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
- adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
- adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
- adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ j = adapter->rx_ring[i].reg_idx;
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_32BIT_MASK));
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
+ IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
+ adapter->rx_ring[i].head = IXGBE_RDH(j);
+ adapter->rx_ring[i].tail = IXGBE_RDT(j);
+ adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+ /* Intitial LRO Settings */
+ adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
+ adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
+ adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
+ adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+ adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
+ adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
+ adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+
+ ixgbe_configure_srrctl(adapter, j);
+ }
+
+ /*
+ * For VMDq support of different descriptor types or
+ * buffer sizes through the use of multiple SRRCTL
+ * registers, RDRXCTL.MVMEN must be set to 1
+ *
+ * also, the manual doesn't mention it clearly but DCA hints
+ * will only use queue 0's tags unless this bit is set. Side
+ * effects of setting this bit are only that SRRCTL must be
+ * fully programmed [0..15]
+ */
+ rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+ rdrxctl |= IXGBE_RDRXCTL_MVMEN;
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
/* Fill out redirection table */
@@ -1525,22 +1603,20 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
/* Fill out hash function seeds */
- /* XXX use a random constant here to glue certain flows */
- get_random_bytes(&random[0], 40);
for (i = 0; i < 10; i++)
- IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), random[i]);
+ IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
mrqc = IXGBE_MRQC_RSSEN
/* Perform hash on these packet types */
- | IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
+ | IXGBE_MRQC_RSS_FIELD_IPV4
+ | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_EX
+ | IXGBE_MRQC_RSS_FIELD_IPV6
+ | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
}
@@ -1621,23 +1697,37 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
}
}
+static u8 *ixgbe_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr, u32 *vmdq)
+{
+ struct dev_mc_list *mc_ptr;
+ u8 *addr = *mc_addr_ptr;
+ *vmdq = 0;
+
+ mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]);
+ if (mc_ptr->next)
+ *mc_addr_ptr = mc_ptr->next->dmi_addr;
+ else
+ *mc_addr_ptr = NULL;
+
+ return addr;
+}
+
/**
- * ixgbe_set_multi - Multicast and Promiscuous mode set
+ * ixgbe_set_rx_mode - Unicast, 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.
+ * The set_rx_method entry point is called whenever the unicast/multicast
+ * address list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast and
+ * promiscuous mode.
**/
-static void ixgbe_set_multi(struct net_device *netdev)
+static void ixgbe_set_rx_mode(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- struct dev_mc_list *mc_ptr;
- u8 *mta_list;
u32 fctrl, vlnctrl;
- int i;
+ u8 *addr_list = NULL;
+ int addr_count = 0;
/* Check for Promiscuous and All Multicast modes */
@@ -1645,6 +1735,7 @@ static void ixgbe_set_multi(struct net_device *netdev)
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
if (netdev->flags & IFF_PROMISC) {
+ hw->addr_ctrl.user_set_promisc = 1;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vlnctrl &= ~IXGBE_VLNCTRL_VFE;
} else {
@@ -1655,33 +1746,25 @@ static void ixgbe_set_multi(struct net_device *netdev)
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
}
vlnctrl |= IXGBE_VLNCTRL_VFE;
+ hw->addr_ctrl.user_set_promisc = 0;
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
- if (netdev->mc_count) {
- mta_list = kcalloc(netdev->mc_count, ETH_ALEN, GFP_ATOMIC);
- if (!mta_list)
- return;
-
- /* Shared function expects packed array of only addresses. */
- mc_ptr = netdev->mc_list;
-
- for (i = 0; i < netdev->mc_count; i++) {
- if (!mc_ptr)
- break;
- memcpy(mta_list + (i * ETH_ALEN), mc_ptr->dmi_addr,
- ETH_ALEN);
- mc_ptr = mc_ptr->next;
- }
-
- ixgbe_update_mc_addr_list(hw, mta_list, i, 0);
- kfree(mta_list);
- } else {
- ixgbe_update_mc_addr_list(hw, NULL, 0, 0);
- }
+ /* reprogram secondary unicast list */
+ addr_count = netdev->uc_count;
+ if (addr_count)
+ addr_list = netdev->uc_list->dmi_addr;
+ ixgbe_update_uc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
+ /* reprogram multicast list */
+ addr_count = netdev->mc_count;
+ if (addr_count)
+ addr_list = netdev->mc_list->dmi_addr;
+ ixgbe_update_mc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
}
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -1725,7 +1808,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int i;
- ixgbe_set_multi(netdev);
+ ixgbe_set_rx_mode(netdev);
ixgbe_restore_vlan(adapter);
@@ -1778,6 +1861,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
for (i = 0; i < adapter->num_tx_queues; i++) {
j = adapter->tx_ring[i].reg_idx;
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
+ /* enable WTHRESH=8 descriptors, to encourage burst writeback */
+ txdctl |= (8 << 16);
txdctl |= IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
}
@@ -1901,7 +1986,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- adapter->rx_buf_len,
+ rx_ring->rx_buf_len,
PCI_DMA_FROMDEVICE);
rx_buffer_info->dma = 0;
}
@@ -2017,11 +2102,28 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
+ adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
+ dca_remove_requester(&adapter->pdev->dev);
+ }
+
+#endif
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+ /* since we reset the hardware DCA settings were cleared */
+ if (dca_add_requester(&adapter->pdev->dev) == 0) {
+ adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
+ /* always use CB2 mode, difference is masked
+ * in the CB driver */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+ ixgbe_setup_dca(adapter);
+ }
+#endif
}
static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -2076,7 +2178,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
struct ixgbe_adapter *adapter = q_vector->adapter;
int tx_cleaned = 0, work_done = 0;
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
ixgbe_update_tx_dca(adapter, adapter->tx_ring);
ixgbe_update_rx_dca(adapter, adapter->rx_ring);
@@ -2449,8 +2551,12 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->tx_eitr = 1;
/* default flow control settings */
- hw->fc.original_type = ixgbe_fc_full;
- hw->fc.type = ixgbe_fc_full;
+ hw->fc.original_type = ixgbe_fc_none;
+ hw->fc.type = ixgbe_fc_none;
+ hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
+ hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
+ hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
+ hw->fc.send_xon = true;
/* select 10G link by default */
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
@@ -2481,93 +2587,94 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/**
* ixgbe_setup_tx_resources - allocate Tx resources (Descriptors)
* @adapter: board private structure
- * @txdr: tx descriptor ring (for a specific queue) to setup
+ * @tx_ring: tx descriptor ring (for a specific queue) to setup
*
* Return 0 on success, negative on failure
**/
int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *txdr)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
- size = sizeof(struct ixgbe_tx_buffer) * txdr->count;
- txdr->tx_buffer_info = vmalloc(size);
- if (!txdr->tx_buffer_info) {
- DPRINTK(PROBE, ERR,
- "Unable to allocate memory for the transmit descriptor ring\n");
- return -ENOMEM;
- }
- memset(txdr->tx_buffer_info, 0, size);
+ size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
+ tx_ring->tx_buffer_info = vmalloc(size);
+ if (!tx_ring->tx_buffer_info)
+ goto err;
+ memset(tx_ring->tx_buffer_info, 0, size);
/* round up to nearest 4K */
- txdr->size = txdr->count * sizeof(union ixgbe_adv_tx_desc);
- txdr->size = ALIGN(txdr->size, 4096);
-
- txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
- if (!txdr->desc) {
- vfree(txdr->tx_buffer_info);
- DPRINTK(PROBE, ERR,
- "Memory allocation failed for the tx desc ring\n");
- return -ENOMEM;
- }
+ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc) +
+ sizeof(u32);
+ tx_ring->size = ALIGN(tx_ring->size, 4096);
- txdr->next_to_use = 0;
- txdr->next_to_clean = 0;
- txdr->work_limit = txdr->count;
+ tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+ &tx_ring->dma);
+ if (!tx_ring->desc)
+ goto err;
+ tx_ring->next_to_use = 0;
+ tx_ring->next_to_clean = 0;
+ tx_ring->work_limit = tx_ring->count;
return 0;
+
+err:
+ vfree(tx_ring->tx_buffer_info);
+ tx_ring->tx_buffer_info = NULL;
+ DPRINTK(PROBE, ERR, "Unable to allocate memory for the transmit "
+ "descriptor ring\n");
+ return -ENOMEM;
}
/**
* ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
- * @rxdr: rx descriptor ring (for a specific queue) to setup
+ * @rx_ring: rx descriptor ring (for a specific queue) to setup
*
* Returns 0 on success, negative on failure
**/
int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rxdr)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
- rxdr->lro_mgr.lro_arr = vmalloc(size);
- if (!rxdr->lro_mgr.lro_arr)
+ rx_ring->lro_mgr.lro_arr = vmalloc(size);
+ if (!rx_ring->lro_mgr.lro_arr)
return -ENOMEM;
- memset(rxdr->lro_mgr.lro_arr, 0, size);
+ memset(rx_ring->lro_mgr.lro_arr, 0, size);
- size = sizeof(struct ixgbe_rx_buffer) * rxdr->count;
- rxdr->rx_buffer_info = vmalloc(size);
- if (!rxdr->rx_buffer_info) {
+ size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
+ rx_ring->rx_buffer_info = vmalloc(size);
+ if (!rx_ring->rx_buffer_info) {
DPRINTK(PROBE, ERR,
"vmalloc allocation failed for the rx desc ring\n");
goto alloc_failed;
}
- memset(rxdr->rx_buffer_info, 0, size);
+ memset(rx_ring->rx_buffer_info, 0, size);
/* Round up to nearest 4K */
- rxdr->size = rxdr->count * sizeof(union ixgbe_adv_rx_desc);
- rxdr->size = ALIGN(rxdr->size, 4096);
+ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
+ rx_ring->size = ALIGN(rx_ring->size, 4096);
- rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+ rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size, &rx_ring->dma);
- if (!rxdr->desc) {
+ if (!rx_ring->desc) {
DPRINTK(PROBE, ERR,
"Memory allocation failed for the rx desc ring\n");
- vfree(rxdr->rx_buffer_info);
+ vfree(rx_ring->rx_buffer_info);
goto alloc_failed;
}
- rxdr->next_to_clean = 0;
- rxdr->next_to_use = 0;
+ rx_ring->next_to_clean = 0;
+ rx_ring->next_to_use = 0;
return 0;
alloc_failed:
- vfree(rxdr->lro_mgr.lro_arr);
- rxdr->lro_mgr.lro_arr = NULL;
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
return -ENOMEM;
}
@@ -2579,7 +2686,7 @@ alloc_failed:
* Free all transmit software resources
**/
static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -3024,6 +3131,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
mss_l4len_idx |=
(skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT);
+ /* use index 1 for TSO */
+ mss_l4len_idx |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
tx_buffer_info->time_stamp = jiffies;
@@ -3096,6 +3205,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
}
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
+ /* use index zero for tx checksum offload */
context_desc->mss_l4len_idx = 0;
tx_buffer_info->time_stamp = jiffies;
@@ -3204,6 +3314,8 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
IXGBE_ADVTXD_POPTS_SHIFT;
+ /* use index 1 context for tso */
+ olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
if (tx_flags & IXGBE_TX_FLAGS_IPV4)
olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
IXGBE_ADVTXD_POPTS_SHIFT;
@@ -3510,7 +3622,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->stop = &ixgbe_close;
netdev->hard_start_xmit = &ixgbe_xmit_frame;
netdev->get_stats = &ixgbe_get_stats;
- netdev->set_multicast_list = &ixgbe_set_multi;
+ netdev->set_rx_mode = &ixgbe_set_rx_mode;
+ netdev->set_multicast_list = &ixgbe_set_rx_mode;
netdev->set_mac_address = &ixgbe_set_mac;
netdev->change_mtu = &ixgbe_change_mtu;
ixgbe_set_ethtool_ops(netdev);
@@ -3550,18 +3663,19 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_sw_init;
netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
+ NETIF_F_IP_CSUM |
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
- netdev->features |= NETIF_F_LRO;
+ netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
+ netdev->features |= NETIF_F_LRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
- netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_IP_CSUM;
netdev->vlan_features |= NETIF_F_SG;
if (pci_using_dac)
@@ -3588,13 +3702,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
- /* initialize default flow control settings */
- hw->fc.original_type = ixgbe_fc_full;
- hw->fc.type = ixgbe_fc_full;
- hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
- hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
- hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
-
err = ixgbe_init_interrupt_scheme(adapter);
if (err)
goto err_sw_init;
@@ -3641,7 +3748,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_register;
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
@@ -3691,7 +3798,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
flush_scheduled_work();
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&pdev->dev);
@@ -3824,7 +3931,7 @@ static int __init ixgbe_init_module(void)
printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
dca_register_notify(&dca_notifier);
#endif
@@ -3841,13 +3948,13 @@ module_init(ixgbe_init_module);
**/
static void __exit ixgbe_exit_module(void)
{
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
dca_unregister_notify(&dca_notifier);
#endif
pci_unregister_driver(&ixgbe_driver);
}
-#ifdef CONFIG_DCA
+#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
void *p)
{
@@ -3858,7 +3965,7 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
-#endif /* CONFIG_DCA */
+#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */
module_exit(ixgbe_exit_module);
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index c0282a2..3e9c483 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -356,12 +356,10 @@
#define IXGBE_ANLP2 0x042B4
#define IXGBE_ATLASCTL 0x04800
-/* RSCCTL Bit Masks */
-#define IXGBE_RSCCTL_RSCEN 0x01
-#define IXGBE_RSCCTL_MAXDESC_1 0x00
-#define IXGBE_RSCCTL_MAXDESC_4 0x04
-#define IXGBE_RSCCTL_MAXDESC_8 0x08
-#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+/* RDRXCTL Bit Masks */
+#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min Threshold Size */
+#define IXGBE_RDRXCTL_MVMEN 0x00000020
+#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
/* CTRL Bit Masks */
#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */
@@ -822,10 +820,6 @@
#define IXGBE_RAH_VIND_SHIFT 18
#define IXGBE_RAH_AV 0x80000000
-/* Filters */
-#define IXGBE_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
-#define IXGBE_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
/* Header split receive */
#define IXGBE_RFCTL_ISCSI_DIS 0x00000001
#define IXGBE_RFCTL_ISCSI_DWC_MASK 0x0000003E
@@ -1007,15 +1001,15 @@ struct ixgbe_legacy_tx_desc {
__le32 data;
struct {
__le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
+ u8 cso; /* Checksum offset */
+ u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
__le32 data;
struct {
u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
+ u8 css; /* Checksum start */
__le16 vlan;
} fields;
} upper;
@@ -1039,9 +1033,9 @@ union ixgbe_adv_tx_desc {
struct ixgbe_legacy_rx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
__le16 length; /* Length of data DMAed into data buffer */
- u16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
+ __le16 csum; /* Packet checksum */
+ u8 status; /* Descriptor status */
+ u8 errors; /* Descriptor Errors */
__le16 vlan;
};
@@ -1053,15 +1047,18 @@ union ixgbe_adv_rx_desc {
} read;
struct {
struct {
- struct {
- __le16 pkt_info; /* RSS type, Packet type */
- __le16 hdr_info; /* Split Header, header len */
+ union {
+ __le32 data;
+ struct {
+ __le16 pkt_info; /* RSS type, Packet type */
+ __le16 hdr_info; /* Split Header, header len */
+ } hs_rss;
} lo_dword;
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
- u16 csum; /* Packet Checksum */
+ __le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
@@ -1167,6 +1164,8 @@ struct ixgbe_addr_filter_info {
u32 rar_used_count;
u32 mc_addr_in_rar_count;
u32 mta_in_use;
+ u32 overflow_promisc;
+ bool user_set_promisc;
};
/* Flow control parameters */
@@ -1242,6 +1241,10 @@ struct ixgbe_hw_stats {
/* forward declaration */
struct ixgbe_hw;
+/* iterator type for walking multicast address lists */
+typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
+ u32 *vmdq);
+
struct ixgbe_mac_operations {
s32 (*reset)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
@@ -1263,9 +1266,11 @@ struct ixgbe_mac_info {
u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
s32 mc_filter_type;
+ u32 mcft_size;
+ u32 vft_size;
+ u32 num_rar_entries;
u32 num_rx_queues;
u32 num_tx_queues;
- u32 num_rx_addrs;
u32 link_attach_type;
u32 link_mode_select;
bool link_settings_loaded;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f684753..d6524db 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -56,7 +56,6 @@
#include <linux/ethtool.h>
#include <linux/firmware.h>
#include <linux/delay.h>
-#include <linux/version.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
#include <linux/crc32.h>
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 4ad3e08..b974ca0 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -38,7 +38,6 @@
#include <asm/io.h>
#include <linux/netdevice.h>
#include <linux/ethtool.h>
-#include <linux/version.h>
#include "netxen_nic.h"
#include "netxen_nic_hw.h"
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0f6f974..1822491 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -61,6 +61,7 @@ static const int multicast_filter_limit = 32;
/* MAC address length */
#define MAC_ADDR_LEN 6
+#define MAX_READ_REQUEST_SHIFT 12
#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
@@ -95,6 +96,10 @@ enum mac_version {
RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
+ RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
+ RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
+ RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
+ RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
@@ -121,6 +126,10 @@ static const struct {
_R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
+ _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
+ _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
+ _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
+ _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
_R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
_R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
_R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -196,9 +205,6 @@ enum rtl_registers {
Config5 = 0x56,
MultiIntr = 0x5c,
PHYAR = 0x60,
- TBICSR = 0x64,
- TBI_ANAR = 0x68,
- TBI_LPAR = 0x6a,
PHYstatus = 0x6c,
RxMaxSize = 0xda,
CPlusCmd = 0xe0,
@@ -212,6 +218,32 @@ enum rtl_registers {
FuncForceEvent = 0xfc,
};
+enum rtl8110_registers {
+ TBICSR = 0x64,
+ TBI_ANAR = 0x68,
+ TBI_LPAR = 0x6a,
+};
+
+enum rtl8168_8101_registers {
+ CSIDR = 0x64,
+ CSIAR = 0x68,
+#define CSIAR_FLAG 0x80000000
+#define CSIAR_WRITE_CMD 0x80000000
+#define CSIAR_BYTE_ENABLE 0x0f
+#define CSIAR_BYTE_ENABLE_SHIFT 12
+#define CSIAR_ADDR_MASK 0x0fff
+
+ EPHYAR = 0x80,
+#define EPHYAR_FLAG 0x80000000
+#define EPHYAR_WRITE_CMD 0x80000000
+#define EPHYAR_REG_MASK 0x1f
+#define EPHYAR_REG_SHIFT 16
+#define EPHYAR_DATA_MASK 0xffff
+ DBG_REG = 0xd1,
+#define FIX_NAK_1 (1 << 4)
+#define FIX_NAK_2 (1 << 3)
+};
+
enum rtl_register_content {
/* InterruptStatusBits */
SYSErr = 0x8000,
@@ -265,7 +297,13 @@ enum rtl_register_content {
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
/* Config1 register p.24 */
+ LEDS1 = (1 << 7),
+ LEDS0 = (1 << 6),
MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
+ Speed_down = (1 << 4),
+ MEMMAP = (1 << 3),
+ IOMAP = (1 << 2),
+ VPD = (1 << 1),
PMEnable = (1 << 0), /* Power Management Enable */
/* Config2 register p. 25 */
@@ -275,6 +313,7 @@ enum rtl_register_content {
/* Config3 register p.25 */
MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
+ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
/* Config5 register p.27 */
BWF = (1 << 6), /* Accept Broadcast wakeup frame */
@@ -292,7 +331,16 @@ enum rtl_register_content {
TBINwComplete = 0x01000000,
/* CPlusCmd p.31 */
- PktCntrDisable = (1 << 7), // 8168
+ EnableBist = (1 << 15), // 8168 8101
+ Mac_dbgo_oe = (1 << 14), // 8168 8101
+ Normal_mode = (1 << 13), // unused
+ Force_half_dup = (1 << 12), // 8168 8101
+ Force_rxflow_en = (1 << 11), // 8168 8101
+ Force_txflow_en = (1 << 10), // 8168 8101
+ Cxpl_dbg_sel = (1 << 9), // 8168 8101
+ ASF = (1 << 8), // 8168 8101
+ PktCntrDisable = (1 << 7), // 8168 8101
+ Mac_dbgo_sel = 0x001c, // 8168
RxVlan = (1 << 6),
RxChkSum = (1 << 5),
PCIDAC = (1 << 4),
@@ -370,8 +418,9 @@ struct ring_info {
};
enum features {
- RTL_FEATURE_WOL = (1 << 0),
- RTL_FEATURE_MSI = (1 << 1),
+ RTL_FEATURE_WOL = (1 << 0),
+ RTL_FEATURE_MSI = (1 << 1),
+ RTL_FEATURE_GMII = (1 << 2),
};
struct rtl8169_private {
@@ -406,13 +455,16 @@ struct rtl8169_private {
struct vlan_group *vlgrp;
#endif
int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
void (*phy_reset_enable)(void __iomem *);
void (*hw_start)(struct net_device *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
+ int pcie_cap;
struct delayed_work task;
unsigned features;
+
+ struct mii_if_info mii;
};
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -482,6 +534,94 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
return value;
}
+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
+{
+ mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
+}
+
+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
+ int val)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ mdio_write(ioaddr, location, val);
+}
+
+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return mdio_read(ioaddr, location);
+}
+
+static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
+{
+ unsigned int i;
+
+ RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
+ (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
+
+ for (i = 0; i < 100; i++) {
+ if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
+ break;
+ udelay(10);
+ }
+}
+
+static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
+{
+ u16 value = 0xffff;
+ unsigned int i;
+
+ RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
+
+ for (i = 0; i < 100; i++) {
+ if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
+ value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
+ break;
+ }
+ udelay(10);
+ }
+
+ return value;
+}
+
+static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
+{
+ unsigned int i;
+
+ RTL_W32(CSIDR, value);
+ RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
+
+ for (i = 0; i < 100; i++) {
+ if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
+ break;
+ udelay(10);
+ }
+}
+
+static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
+{
+ u32 value = ~0x00;
+ unsigned int i;
+
+ RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
+
+ for (i = 0; i < 100; i++) {
+ if (RTL_R32(CSIAR) & CSIAR_FLAG) {
+ value = RTL_R32(CSIDR);
+ break;
+ }
+ udelay(10);
+ }
+
+ return value;
+}
+
static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
{
RTL_W16(IntrMask, 0x0000);
@@ -705,8 +845,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
}
}
- /* The 8100e/8101e do Fast Ethernet only. */
- if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+ /* The 8100e/8101e/8102e do Fast Ethernet only. */
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
(tp->mac_version == RTL_GIGA_MAC_VER_14) ||
(tp->mac_version == RTL_GIGA_MAC_VER_15) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
@@ -850,7 +994,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
#endif
-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
@@ -867,65 +1011,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->speed = SPEED_1000;
cmd->duplex = DUPLEX_FULL; /* Always set */
+
+ return 0;
}
-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- u8 status;
-
- cmd->supported = SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_TP;
-
- cmd->autoneg = 1;
- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
-
- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
- cmd->advertising |= ADVERTISED_10baseT_Half;
- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
- cmd->advertising |= ADVERTISED_10baseT_Full;
- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
- cmd->advertising |= ADVERTISED_100baseT_Half;
- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
- cmd->advertising |= ADVERTISED_100baseT_Full;
- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
- cmd->advertising |= ADVERTISED_1000baseT_Full;
-
- status = RTL_R8(PHYstatus);
-
- if (status & _1000bpsF)
- cmd->speed = SPEED_1000;
- else if (status & _100bps)
- cmd->speed = SPEED_100;
- else if (status & _10bps)
- cmd->speed = SPEED_10;
-
- if (status & TxFlowCtrl)
- cmd->advertising |= ADVERTISED_Asym_Pause;
- if (status & RxFlowCtrl)
- cmd->advertising |= ADVERTISED_Pause;
-
- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
- DUPLEX_FULL : DUPLEX_HALF;
+
+ return mii_ethtool_gset(&tp->mii, cmd);
}
static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
unsigned long flags;
+ int rc;
spin_lock_irqsave(&tp->lock, flags);
- tp->get_settings(dev, cmd);
+ rc = tp->get_settings(dev, cmd);
spin_unlock_irqrestore(&tp->lock, flags);
- return 0;
+ return rc;
}
static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1116,8 +1224,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
/* 8101 family. */
+ { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
+ { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
+ { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
+ { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
+ { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
+ { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
{ 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
+ { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
{ 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
+ { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
+ { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
{ 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
/* FIXME: where did these entries come from ? -- FR */
{ 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
@@ -1279,6 +1396,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
+{
+ struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0003 },
+ { 0x08, 0x441d },
+ { 0x01, 0x9100 },
+ { 0x1f, 0x0000 }
+ };
+
+ mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_patch(ioaddr, 0x11, 1 << 12);
+ mdio_patch(ioaddr, 0x19, 1 << 13);
+
+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
static void rtl_hw_phy_config(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -1296,6 +1429,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_04:
rtl8169sb_hw_phy_config(ioaddr);
break;
+ case RTL_GIGA_MAC_VER_07:
+ case RTL_GIGA_MAC_VER_08:
+ case RTL_GIGA_MAC_VER_09:
+ rtl8102e_hw_phy_config(ioaddr);
+ break;
case RTL_GIGA_MAC_VER_18:
rtl8168cp_hw_phy_config(ioaddr);
break;
@@ -1513,7 +1651,7 @@ static const struct rtl_cfg_info {
unsigned int align;
u16 intr_event;
u16 napi_event;
- unsigned msi;
+ unsigned features;
} rtl_cfg_infos [] = {
[RTL_CFG_0] = {
.hw_start = rtl_hw_start_8169,
@@ -1522,7 +1660,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .msi = 0
+ .features = RTL_FEATURE_GMII
},
[RTL_CFG_1] = {
.hw_start = rtl_hw_start_8168,
@@ -1531,7 +1669,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
- .msi = RTL_FEATURE_MSI
+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
},
[RTL_CFG_2] = {
.hw_start = rtl_hw_start_8101,
@@ -1540,7 +1678,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .msi = RTL_FEATURE_MSI
+ .features = RTL_FEATURE_MSI
}
};
@@ -1552,7 +1690,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
u8 cfg2;
cfg2 = RTL_R8(Config2) & ~MSIEnable;
- if (cfg->msi) {
+ if (cfg->features & RTL_FEATURE_MSI) {
if (pci_enable_msi(pdev)) {
dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
} else {
@@ -1578,6 +1716,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
const unsigned int region = cfg->region;
struct rtl8169_private *tp;
+ struct mii_if_info *mii;
struct net_device *dev;
void __iomem *ioaddr;
unsigned int i;
@@ -1602,6 +1741,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->pci_dev = pdev;
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
+ mii = &tp->mii;
+ mii->dev = dev;
+ mii->mdio_read = rtl_mdio_read;
+ mii->mdio_write = rtl_mdio_write;
+ mii->phy_id_mask = 0x1f;
+ mii->reg_num_mask = 0x1f;
+ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
+
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pci_enable_device(pdev);
if (rc < 0) {
@@ -1670,6 +1817,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_res_4;
}
+ tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!tp->pcie_cap && netif_msg_probe(tp))
+ dev_info(&pdev->dev, "no PCI Express capability\n");
+
/* Unneeded ? Don't mess with Mrs. Murphy. */
rtl8169_irq_mask_and_ack(ioaddr);
@@ -2061,12 +2212,51 @@ static void rtl_hw_start_8169(struct net_device *dev)
RTL_W16(IntrMask, tp->intr_event);
}
+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct rtl8169_private *tp = netdev_priv(dev);
+ int cap = tp->pcie_cap;
+
+ if (cap) {
+ u16 ctl;
+
+ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
+ }
+}
+
+static void rtl_csi_access_enable(void __iomem *ioaddr)
+{
+ u32 csi;
+
+ csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
+ rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
+}
+
+struct ephy_info {
+ unsigned int offset;
+ u16 mask;
+ u16 bits;
+};
+
+static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
+{
+ u16 w;
+
+ while (len-- > 0) {
+ w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
+ rtl_ephy_write(ioaddr, e->offset, w);
+ e++;
+ }
+}
+
static void rtl_hw_start_8168(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
- u8 ctl;
RTL_W8(Cfg9346, Cfg9346_Unlock);
@@ -2080,10 +2270,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W16(CPlusCmd, tp->cp_cmd);
- /* Tx performance tweak. */
- pci_read_config_byte(pdev, 0x69, &ctl);
- ctl = (ctl & ~0x70) | 0x50;
- pci_write_config_byte(pdev, 0x69, ctl);
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
RTL_W16(IntrMitigate, 0x5151);
@@ -2110,6 +2297,70 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W16(IntrMask, tp->intr_event);
}
+#define R810X_CPCMD_QUIRK_MASK (\
+ EnableBist | \
+ Mac_dbgo_oe | \
+ Force_half_dup | \
+ Force_half_dup | \
+ Force_txflow_en | \
+ Cxpl_dbg_sel | \
+ ASF | \
+ PktCntrDisable | \
+ PCIDAC | \
+ PCIMulRW)
+
+static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ static struct ephy_info e_info_8102e_1[] = {
+ { 0x01, 0, 0x6e65 },
+ { 0x02, 0, 0x091f },
+ { 0x03, 0, 0xc2f9 },
+ { 0x06, 0, 0xafb5 },
+ { 0x07, 0, 0x0e00 },
+ { 0x19, 0, 0xec80 },
+ { 0x01, 0, 0x2e65 },
+ { 0x01, 0, 0x6e65 }
+ };
+ u8 cfg1;
+
+ rtl_csi_access_enable(ioaddr);
+
+ RTL_W8(DBG_REG, FIX_NAK_1);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(Config1,
+ LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
+
+ cfg1 = RTL_R8(Config1);
+ if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
+ RTL_W8(Config1, cfg1 & ~LEDS0);
+
+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
+
+ rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
+}
+
+static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ rtl_csi_access_enable(ioaddr);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
+
+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
+}
+
+static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ rtl_hw_start_8102e_2(ioaddr, pdev);
+
+ rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
+}
+
static void rtl_hw_start_8101(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -2118,8 +2369,26 @@ static void rtl_hw_start_8101(struct net_device *dev)
if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
- pci_write_config_word(pdev, 0x68, 0x00);
- pci_write_config_word(pdev, 0x69, 0x08);
+ int cap = tp->pcie_cap;
+
+ if (cap) {
+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
+ PCI_EXP_DEVCTL_NOSNOOP_EN);
+ }
+ }
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_07:
+ rtl_hw_start_8102e_1(ioaddr, pdev);
+ break;
+
+ case RTL_GIGA_MAC_VER_08:
+ rtl_hw_start_8102e_3(ioaddr, pdev);
+ break;
+
+ case RTL_GIGA_MAC_VER_09:
+ rtl_hw_start_8102e_2(ioaddr, pdev);
+ break;
}
RTL_W8(Cfg9346, Cfg9346_Unlock);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index a2b0730..243db33 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -8175,8 +8175,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
break;
}
if (sp->config.multiq) {
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- mac_control->fifos[i].multiq = config->multiq;
+ for (i = 0; i < sp->config.tx_fifo_num; i++)
+ mac_control->fifos[i].multiq = config->multiq;
DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n",
dev->name);
} else
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h
index 2c79d27..d95c218 100644
--- a/drivers/net/sfc/bitfield.h
+++ b/drivers/net/sfc/bitfield.h
@@ -52,9 +52,9 @@
*
* The maximum width mask that can be generated is 64 bits.
*/
-#define EFX_MASK64(field) \
- (EFX_WIDTH(field) == 64 ? ~((u64) 0) : \
- (((((u64) 1) << EFX_WIDTH(field))) - 1))
+#define EFX_MASK64(width) \
+ ((width) == 64 ? ~((u64) 0) : \
+ (((((u64) 1) << (width))) - 1))
/* Mask equal in width to the specified field.
*
@@ -63,9 +63,9 @@
* The maximum width mask that can be generated is 32 bits. Use
* EFX_MASK64 for higher width fields.
*/
-#define EFX_MASK32(field) \
- (EFX_WIDTH(field) == 32 ? ~((u32) 0) : \
- (((((u32) 1) << EFX_WIDTH(field))) - 1))
+#define EFX_MASK32(width) \
+ ((width) == 32 ? ~((u32) 0) : \
+ (((((u32) 1) << (width))) - 1))
/* A doubleword (i.e. 4 byte) datatype - little-endian in HW */
typedef union efx_dword {
@@ -138,44 +138,49 @@ typedef union efx_oword {
EFX_EXTRACT_NATIVE(le32_to_cpu(element), min, max, low, high)
#define EFX_EXTRACT_OWORD64(oword, low, high) \
- (EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \
- EFX_EXTRACT64((oword).u64[1], 64, 127, low, high))
+ ((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \
+ EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) & \
+ EFX_MASK64(high + 1 - low))
#define EFX_EXTRACT_QWORD64(qword, low, high) \
- EFX_EXTRACT64((qword).u64[0], 0, 63, low, high)
+ (EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) & \
+ EFX_MASK64(high + 1 - low))
#define EFX_EXTRACT_OWORD32(oword, low, high) \
- (EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \
- EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \
- EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \
- EFX_EXTRACT32((oword).u32[3], 96, 127, low, high))
+ ((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \
+ EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \
+ EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \
+ EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) & \
+ EFX_MASK32(high + 1 - low))
#define EFX_EXTRACT_QWORD32(qword, low, high) \
- (EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \
- EFX_EXTRACT32((qword).u32[1], 32, 63, low, high))
+ ((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \
+ EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) & \
+ EFX_MASK32(high + 1 - low))
-#define EFX_EXTRACT_DWORD(dword, low, high) \
- EFX_EXTRACT32((dword).u32[0], 0, 31, low, high)
+#define EFX_EXTRACT_DWORD(dword, low, high) \
+ (EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) & \
+ EFX_MASK32(high + 1 - low))
-#define EFX_OWORD_FIELD64(oword, field) \
- (EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \
- & EFX_MASK64(field))
+#define EFX_OWORD_FIELD64(oword, field) \
+ EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field))
-#define EFX_QWORD_FIELD64(qword, field) \
- (EFX_EXTRACT_QWORD64(qword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \
- & EFX_MASK64(field))
+#define EFX_QWORD_FIELD64(qword, field) \
+ EFX_EXTRACT_QWORD64(qword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field))
-#define EFX_OWORD_FIELD32(oword, field) \
- (EFX_EXTRACT_OWORD32(oword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \
- & EFX_MASK32(field))
+#define EFX_OWORD_FIELD32(oword, field) \
+ EFX_EXTRACT_OWORD32(oword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field))
-#define EFX_QWORD_FIELD32(qword, field) \
- (EFX_EXTRACT_QWORD32(qword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \
- & EFX_MASK32(field))
+#define EFX_QWORD_FIELD32(qword, field) \
+ EFX_EXTRACT_QWORD32(qword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field))
-#define EFX_DWORD_FIELD(dword, field) \
- (EFX_EXTRACT_DWORD(dword, EFX_LOW_BIT(field), EFX_HIGH_BIT(field)) \
- & EFX_MASK32(field))
+#define EFX_DWORD_FIELD(dword, field) \
+ EFX_EXTRACT_DWORD(dword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field))
#define EFX_OWORD_IS_ZERO64(oword) \
(((oword).u64[0] | (oword).u64[1]) == (__force __le64) 0)
@@ -411,69 +416,102 @@ typedef union efx_oword {
* for read-modify-write operations.
*
*/
-
#define EFX_INVERT_OWORD(oword) do { \
(oword).u64[0] = ~((oword).u64[0]); \
(oword).u64[1] = ~((oword).u64[1]); \
} while (0)
-#define EFX_INSERT_FIELD64(...) \
- cpu_to_le64(EFX_INSERT_FIELD_NATIVE(__VA_ARGS__))
+#define EFX_AND_OWORD(oword, from, mask) \
+ do { \
+ (oword).u64[0] = (from).u64[0] & (mask).u64[0]; \
+ (oword).u64[1] = (from).u64[1] & (mask).u64[1]; \
+ } while (0)
+
+#define EFX_OR_OWORD(oword, from, mask) \
+ do { \
+ (oword).u64[0] = (from).u64[0] | (mask).u64[0]; \
+ (oword).u64[1] = (from).u64[1] | (mask).u64[1]; \
+ } while (0)
-#define EFX_INSERT_FIELD32(...) \
- cpu_to_le32(EFX_INSERT_FIELD_NATIVE(__VA_ARGS__))
+#define EFX_INSERT64(min, max, low, high, value) \
+ cpu_to_le64(EFX_INSERT_NATIVE(min, max, low, high, value))
-#define EFX_INPLACE_MASK64(min, max, field) \
- EFX_INSERT_FIELD64(min, max, field, EFX_MASK64(field))
+#define EFX_INSERT32(min, max, low, high, value) \
+ cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value))
-#define EFX_INPLACE_MASK32(min, max, field) \
- EFX_INSERT_FIELD32(min, max, field, EFX_MASK32(field))
+#define EFX_INPLACE_MASK64(min, max, low, high) \
+ EFX_INSERT64(min, max, low, high, EFX_MASK64(high + 1 - low))
-#define EFX_SET_OWORD_FIELD64(oword, field, value) do { \
+#define EFX_INPLACE_MASK32(min, max, low, high) \
+ EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low))
+
+#define EFX_SET_OWORD64(oword, low, high, value) do { \
(oword).u64[0] = (((oword).u64[0] \
- & ~EFX_INPLACE_MASK64(0, 63, field)) \
- | EFX_INSERT_FIELD64(0, 63, field, value)); \
+ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \
+ | EFX_INSERT64(0, 63, low, high, value)); \
(oword).u64[1] = (((oword).u64[1] \
- & ~EFX_INPLACE_MASK64(64, 127, field)) \
- | EFX_INSERT_FIELD64(64, 127, field, value)); \
+ & ~EFX_INPLACE_MASK64(64, 127, low, high)) \
+ | EFX_INSERT64(64, 127, low, high, value)); \
} while (0)
-#define EFX_SET_QWORD_FIELD64(qword, field, value) do { \
+#define EFX_SET_QWORD64(qword, low, high, value) do { \
(qword).u64[0] = (((qword).u64[0] \
- & ~EFX_INPLACE_MASK64(0, 63, field)) \
- | EFX_INSERT_FIELD64(0, 63, field, value)); \
+ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \
+ | EFX_INSERT64(0, 63, low, high, value)); \
} while (0)
-#define EFX_SET_OWORD_FIELD32(oword, field, value) do { \
+#define EFX_SET_OWORD32(oword, low, high, value) do { \
(oword).u32[0] = (((oword).u32[0] \
- & ~EFX_INPLACE_MASK32(0, 31, field)) \
- | EFX_INSERT_FIELD32(0, 31, field, value)); \
+ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \
+ | EFX_INSERT32(0, 31, low, high, value)); \
(oword).u32[1] = (((oword).u32[1] \
- & ~EFX_INPLACE_MASK32(32, 63, field)) \
- | EFX_INSERT_FIELD32(32, 63, field, value)); \
+ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \
+ | EFX_INSERT32(32, 63, low, high, value)); \
(oword).u32[2] = (((oword).u32[2] \
- & ~EFX_INPLACE_MASK32(64, 95, field)) \
- | EFX_INSERT_FIELD32(64, 95, field, value)); \
+ & ~EFX_INPLACE_MASK32(64, 95, low, high)) \
+ | EFX_INSERT32(64, 95, low, high, value)); \
(oword).u32[3] = (((oword).u32[3] \
- & ~EFX_INPLACE_MASK32(96, 127, field)) \
- | EFX_INSERT_FIELD32(96, 127, field, value)); \
+ & ~EFX_INPLACE_MASK32(96, 127, low, high)) \
+ | EFX_INSERT32(96, 127, low, high, value)); \
} while (0)
-#define EFX_SET_QWORD_FIELD32(qword, field, value) do { \
+#define EFX_SET_QWORD32(qword, low, high, value) do { \
(qword).u32[0] = (((qword).u32[0] \
- & ~EFX_INPLACE_MASK32(0, 31, field)) \
- | EFX_INSERT_FIELD32(0, 31, field, value)); \
+ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \
+ | EFX_INSERT32(0, 31, low, high, value)); \
(qword).u32[1] = (((qword).u32[1] \
- & ~EFX_INPLACE_MASK32(32, 63, field)) \
- | EFX_INSERT_FIELD32(32, 63, field, value)); \
+ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \
+ | EFX_INSERT32(32, 63, low, high, value)); \
} while (0)
-#define EFX_SET_DWORD_FIELD(dword, field, value) do { \
- (dword).u32[0] = (((dword).u32[0] \
- & ~EFX_INPLACE_MASK32(0, 31, field)) \
- | EFX_INSERT_FIELD32(0, 31, field, value)); \
+#define EFX_SET_DWORD32(dword, low, high, value) do { \
+ (dword).u32[0] = (((dword).u32[0] \
+ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \
+ | EFX_INSERT32(0, 31, low, high, value)); \
} while (0)
+#define EFX_SET_OWORD_FIELD64(oword, field, value) \
+ EFX_SET_OWORD64(oword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field), value)
+
+#define EFX_SET_QWORD_FIELD64(qword, field, value) \
+ EFX_SET_QWORD64(qword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field), value)
+
+#define EFX_SET_OWORD_FIELD32(oword, field, value) \
+ EFX_SET_OWORD32(oword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field), value)
+
+#define EFX_SET_QWORD_FIELD32(qword, field, value) \
+ EFX_SET_QWORD32(qword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field), value)
+
+#define EFX_SET_DWORD_FIELD(dword, field, value) \
+ EFX_SET_DWORD32(dword, EFX_LOW_BIT(field), \
+ EFX_HIGH_BIT(field), value)
+
+
+
#if BITS_PER_LONG == 64
#define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64
#define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64
@@ -502,4 +540,10 @@ typedef union efx_oword {
#define EFX_DMA_TYPE_WIDTH(width) \
(((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH)
+
+/* Static initialiser */
+#define EFX_OWORD32(a, b, c, d) \
+ { .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \
+ __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } }
+
#endif /* EFX_BITFIELD_H */
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index d3d3dd0..99e6023 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -31,23 +31,23 @@ static void blink_led_timer(unsigned long context)
mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
}
-static void board_blink(struct efx_nic *efx, int blink)
+static void board_blink(struct efx_nic *efx, bool blink)
{
struct efx_blinker *blinker = &efx->board_info.blinker;
/* The rtnl mutex serialises all ethtool ioctls, so
* nothing special needs doing here. */
if (blink) {
- blinker->resubmit = 1;
- blinker->state = 0;
+ blinker->resubmit = true;
+ blinker->state = false;
setup_timer(&blinker->timer, blink_led_timer,
(unsigned long)efx);
mod_timer(&blinker->timer, jiffies + BLINK_INTERVAL);
} else {
- blinker->resubmit = 0;
+ blinker->resubmit = false;
if (blinker->timer.function)
del_timer_sync(&blinker->timer);
- efx->board_info.set_fault_led(efx, 0);
+ efx->board_info.set_fault_led(efx, false);
}
}
@@ -78,7 +78,7 @@ static int sfe4002_init_leds(struct efx_nic *efx)
return 0;
}
-static void sfe4002_fault_led(struct efx_nic *efx, int state)
+static void sfe4002_fault_led(struct efx_nic *efx, bool state)
{
xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
QUAKE_LED_OFF);
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index e5e8443..c6e01b6 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -21,7 +21,5 @@ enum efx_board_type {
extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
extern int sfe4001_init(struct efx_nic *efx);
-/* Are we putting the PHY into flash config mode */
-extern unsigned int sfe4001_phy_flash_cfg;
#endif
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 45c72ee..0d47d6f 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -28,7 +28,6 @@
#include "efx.h"
#include "mdio_10g.h"
#include "falcon.h"
-#include "workarounds.h"
#include "mac.h"
#define EFX_MAX_MTU (9 * 1024)
@@ -52,7 +51,7 @@ static struct workqueue_struct *refill_workqueue;
* This sets the default for new devices. It can be controlled later
* using ethtool.
*/
-static int lro = 1;
+static int lro = true;
module_param(lro, int, 0644);
MODULE_PARM_DESC(lro, "Large receive offload acceleration");
@@ -65,7 +64,7 @@ MODULE_PARM_DESC(lro, "Large receive offload acceleration");
* This is forced to 0 for MSI interrupt mode as the interrupt vector
* is not written
*/
-static unsigned int separate_tx_and_rx_channels = 1;
+static unsigned int separate_tx_and_rx_channels = true;
/* This is the weight assigned to each of the (per-channel) virtual
* NAPI devices.
@@ -81,7 +80,7 @@ unsigned int efx_monitor_interval = 1 * HZ;
/* This controls whether or not the hardware monitor will trigger a
* reset when it detects an error condition.
*/
-static unsigned int monitor_reset = 1;
+static unsigned int monitor_reset = true;
/* This controls whether or not the driver will initialise devices
* with invalid MAC addresses stored in the EEPROM or flash. If true,
@@ -141,8 +140,7 @@ static void efx_fini_channels(struct efx_nic *efx);
#define EFX_ASSERT_RESET_SERIALISED(efx) \
do { \
- if ((efx->state == STATE_RUNNING) || \
- (efx->state == STATE_RESETTING)) \
+ if (efx->state == STATE_RUNNING) \
ASSERT_RTNL(); \
} while (0)
@@ -159,16 +157,18 @@ static void efx_fini_channels(struct efx_nic *efx);
* never be concurrently called more than once on the same channel,
* though different channels may be being processed concurrently.
*/
-static inline int efx_process_channel(struct efx_channel *channel, int rx_quota)
+static int efx_process_channel(struct efx_channel *channel, int rx_quota)
{
- int rxdmaqs;
- struct efx_rx_queue *rx_queue;
+ struct efx_nic *efx = channel->efx;
+ int rx_packets;
- if (unlikely(channel->efx->reset_pending != RESET_TYPE_NONE ||
+ if (unlikely(efx->reset_pending != RESET_TYPE_NONE ||
!channel->enabled))
- return rx_quota;
+ return 0;
- rxdmaqs = falcon_process_eventq(channel, &rx_quota);
+ rx_packets = falcon_process_eventq(channel, rx_quota);
+ if (rx_packets == 0)
+ return 0;
/* Deliver last RX packet. */
if (channel->rx_pkt) {
@@ -180,16 +180,9 @@ static inline int efx_process_channel(struct efx_channel *channel, int rx_quota)
efx_flush_lro(channel);
efx_rx_strategy(channel);
- /* Refill descriptor rings as necessary */
- rx_queue = &channel->efx->rx_queue[0];
- while (rxdmaqs) {
- if (rxdmaqs & 0x01)
- efx_fast_push_rx_descriptors(rx_queue);
- rx_queue++;
- rxdmaqs >>= 1;
- }
+ efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
- return rx_quota;
+ return rx_packets;
}
/* Mark channel as finished processing
@@ -203,7 +196,7 @@ static inline void efx_channel_processed(struct efx_channel *channel)
/* The interrupt handler for this channel may set work_pending
* as soon as we acknowledge the events we've seen. Make sure
* it's cleared before then. */
- channel->work_pending = 0;
+ channel->work_pending = false;
smp_wmb();
falcon_eventq_read_ack(channel);
@@ -219,14 +212,12 @@ static int efx_poll(struct napi_struct *napi, int budget)
struct efx_channel *channel =
container_of(napi, struct efx_channel, napi_str);
struct net_device *napi_dev = channel->napi_dev;
- int unused;
int rx_packets;
EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n",
channel->channel, raw_smp_processor_id());
- unused = efx_process_channel(channel, budget);
- rx_packets = (budget - unused);
+ rx_packets = efx_process_channel(channel, budget);
if (rx_packets < budget) {
/* There is no race here; although napi_disable() will
@@ -260,7 +251,7 @@ void efx_process_channel_now(struct efx_channel *channel)
falcon_disable_interrupts(efx);
if (efx->legacy_irq)
synchronize_irq(efx->legacy_irq);
- if (channel->has_interrupt && channel->irq)
+ if (channel->irq)
synchronize_irq(channel->irq);
/* Wait for any NAPI processing to complete */
@@ -290,13 +281,13 @@ static int efx_probe_eventq(struct efx_channel *channel)
}
/* Prepare channel's event queue */
-static int efx_init_eventq(struct efx_channel *channel)
+static void efx_init_eventq(struct efx_channel *channel)
{
EFX_LOG(channel->efx, "chan %d init event queue\n", channel->channel);
channel->eventq_read_ptr = 0;
- return falcon_init_eventq(channel);
+ falcon_init_eventq(channel);
}
static void efx_fini_eventq(struct efx_channel *channel)
@@ -362,12 +353,11 @@ static int efx_probe_channel(struct efx_channel *channel)
* to propagate configuration changes (mtu, checksum offload), or
* to clear hardware error conditions
*/
-static int efx_init_channels(struct efx_nic *efx)
+static void efx_init_channels(struct efx_nic *efx)
{
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
struct efx_channel *channel;
- int rc = 0;
/* Calculate the rx buffer allocation parameters required to
* support the current MTU, including padding for header
@@ -382,36 +372,20 @@ static int efx_init_channels(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
EFX_LOG(channel->efx, "init chan %d\n", channel->channel);
- rc = efx_init_eventq(channel);
- if (rc)
- goto err;
+ efx_init_eventq(channel);
- efx_for_each_channel_tx_queue(tx_queue, channel) {
- rc = efx_init_tx_queue(tx_queue);
- if (rc)
- goto err;
- }
+ efx_for_each_channel_tx_queue(tx_queue, channel)
+ efx_init_tx_queue(tx_queue);
/* The rx buffer allocation strategy is MTU dependent */
efx_rx_strategy(channel);
- efx_for_each_channel_rx_queue(rx_queue, channel) {
- rc = efx_init_rx_queue(rx_queue);
- if (rc)
- goto err;
- }
+ efx_for_each_channel_rx_queue(rx_queue, channel)
+ efx_init_rx_queue(rx_queue);
WARN_ON(channel->rx_pkt != NULL);
efx_rx_strategy(channel);
}
-
- return 0;
-
- err:
- EFX_ERR(efx, "failed to initialise channel %d\n",
- channel ? channel->channel : -1);
- efx_fini_channels(efx);
- return rc;
}
/* This enables event queue processing and packet transmission.
@@ -432,8 +406,8 @@ static void efx_start_channel(struct efx_channel *channel)
/* The interrupt handler for this channel may set work_pending
* as soon as we enable it. Make sure it's cleared before
* then. Similarly, make sure it sees the enabled flag set. */
- channel->work_pending = 0;
- channel->enabled = 1;
+ channel->work_pending = false;
+ channel->enabled = true;
smp_wmb();
napi_enable(&channel->napi_str);
@@ -456,7 +430,7 @@ static void efx_stop_channel(struct efx_channel *channel)
EFX_LOG(channel->efx, "stop chan %d\n", channel->channel);
- channel->enabled = 0;
+ channel->enabled = false;
napi_disable(&channel->napi_str);
/* Ensure that any worker threads have exited or will be no-ops */
@@ -526,8 +500,6 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay)
*/
static void efx_link_status_changed(struct efx_nic *efx)
{
- int carrier_ok;
-
/* SFC Bug 5356: A net_dev notifier is registered, so we must ensure
* that no events are triggered between unregister_netdev() and the
* driver unloading. A more general condition is that NETDEV_CHANGE
@@ -535,8 +507,12 @@ static void efx_link_status_changed(struct efx_nic *efx)
if (!netif_running(efx->net_dev))
return;
- carrier_ok = netif_carrier_ok(efx->net_dev) ? 1 : 0;
- if (efx->link_up != carrier_ok) {
+ if (efx->port_inhibited) {
+ netif_carrier_off(efx->net_dev);
+ return;
+ }
+
+ if (efx->link_up != netif_carrier_ok(efx->net_dev)) {
efx->n_link_state_changes++;
if (efx->link_up)
@@ -577,13 +553,19 @@ static void efx_link_status_changed(struct efx_nic *efx)
/* This call reinitialises the MAC to pick up new PHY settings. The
* caller must hold the mac_lock */
-static void __efx_reconfigure_port(struct efx_nic *efx)
+void __efx_reconfigure_port(struct efx_nic *efx)
{
WARN_ON(!mutex_is_locked(&efx->mac_lock));
EFX_LOG(efx, "reconfiguring MAC from PHY settings on CPU %d\n",
raw_smp_processor_id());
+ /* Serialise the promiscuous flag with efx_set_multicast_list. */
+ if (efx_dev_registered(efx)) {
+ netif_addr_lock_bh(efx->net_dev);
+ netif_addr_unlock_bh(efx->net_dev);
+ }
+
falcon_reconfigure_xmac(efx);
/* Inform kernel of loss/gain of carrier */
@@ -661,7 +643,8 @@ static int efx_init_port(struct efx_nic *efx)
if (rc)
return rc;
- efx->port_initialized = 1;
+ efx->port_initialized = true;
+ efx->stats_enabled = true;
/* Reconfigure port to program MAC registers */
falcon_reconfigure_xmac(efx);
@@ -678,7 +661,7 @@ static void efx_start_port(struct efx_nic *efx)
BUG_ON(efx->port_enabled);
mutex_lock(&efx->mac_lock);
- efx->port_enabled = 1;
+ efx->port_enabled = true;
__efx_reconfigure_port(efx);
mutex_unlock(&efx->mac_lock);
}
@@ -692,7 +675,7 @@ static void efx_stop_port(struct efx_nic *efx)
EFX_LOG(efx, "stop port\n");
mutex_lock(&efx->mac_lock);
- efx->port_enabled = 0;
+ efx->port_enabled = false;
mutex_unlock(&efx->mac_lock);
/* Serialise against efx_set_multicast_list() */
@@ -710,9 +693,9 @@ static void efx_fini_port(struct efx_nic *efx)
return;
falcon_fini_xmac(efx);
- efx->port_initialized = 0;
+ efx->port_initialized = false;
- efx->link_up = 0;
+ efx->link_up = false;
efx_link_status_changed(efx);
}
@@ -823,53 +806,61 @@ static void efx_fini_io(struct efx_nic *efx)
pci_disable_device(efx->pci_dev);
}
-/* Probe the number and type of interrupts we are able to obtain. */
+/* Get number of RX queues wanted. Return number of online CPU
+ * packages in the expectation that an IRQ balancer will spread
+ * interrupts across them. */
+static int efx_wanted_rx_queues(void)
+{
+ cpumask_t core_mask;
+ int count;
+ int cpu;
+
+ cpus_clear(core_mask);
+ count = 0;
+ for_each_online_cpu(cpu) {
+ if (!cpu_isset(cpu, core_mask)) {
+ ++count;
+ cpus_or(core_mask, core_mask,
+ topology_core_siblings(cpu));
+ }
+ }
+
+ return count;
+}
+
+/* Probe the number and type of interrupts we are able to obtain, and
+ * the resulting numbers of channels and RX queues.
+ */
static void efx_probe_interrupts(struct efx_nic *efx)
{
- int max_channel = efx->type->phys_addr_channels - 1;
- struct msix_entry xentries[EFX_MAX_CHANNELS];
+ int max_channels =
+ min_t(int, efx->type->phys_addr_channels, EFX_MAX_CHANNELS);
int rc, i;
if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
- BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX));
-
- if (rss_cpus == 0) {
- cpumask_t core_mask;
- int cpu;
-
- cpus_clear(core_mask);
- efx->rss_queues = 0;
- for_each_online_cpu(cpu) {
- if (!cpu_isset(cpu, core_mask)) {
- ++efx->rss_queues;
- cpus_or(core_mask, core_mask,
- topology_core_siblings(cpu));
- }
- }
- } else {
- efx->rss_queues = rss_cpus;
- }
+ struct msix_entry xentries[EFX_MAX_CHANNELS];
+ int wanted_ints;
- efx->rss_queues = min(efx->rss_queues, max_channel + 1);
- efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS);
+ /* We want one RX queue and interrupt per CPU package
+ * (or as specified by the rss_cpus module parameter).
+ * We will need one channel per interrupt.
+ */
+ wanted_ints = rss_cpus ? rss_cpus : efx_wanted_rx_queues();
+ efx->n_rx_queues = min(wanted_ints, max_channels);
- /* Request maximum number of MSI interrupts, and fill out
- * the channel interrupt information the allowed allocation */
- for (i = 0; i < efx->rss_queues; i++)
+ for (i = 0; i < efx->n_rx_queues; i++)
xentries[i].entry = i;
- rc = pci_enable_msix(efx->pci_dev, xentries, efx->rss_queues);
+ rc = pci_enable_msix(efx->pci_dev, xentries, efx->n_rx_queues);
if (rc > 0) {
- EFX_BUG_ON_PARANOID(rc >= efx->rss_queues);
- efx->rss_queues = rc;
+ EFX_BUG_ON_PARANOID(rc >= efx->n_rx_queues);
+ efx->n_rx_queues = rc;
rc = pci_enable_msix(efx->pci_dev, xentries,
- efx->rss_queues);
+ efx->n_rx_queues);
}
if (rc == 0) {
- for (i = 0; i < efx->rss_queues; i++) {
- efx->channel[i].has_interrupt = 1;
+ for (i = 0; i < efx->n_rx_queues; i++)
efx->channel[i].irq = xentries[i].vector;
- }
} else {
/* Fall back to single channel MSI */
efx->interrupt_mode = EFX_INT_MODE_MSI;
@@ -879,11 +870,10 @@ static void efx_probe_interrupts(struct efx_nic *efx)
/* Try single interrupt MSI */
if (efx->interrupt_mode == EFX_INT_MODE_MSI) {
- efx->rss_queues = 1;
+ efx->n_rx_queues = 1;
rc = pci_enable_msi(efx->pci_dev);
if (rc == 0) {
efx->channel[0].irq = efx->pci_dev->irq;
- efx->channel[0].has_interrupt = 1;
} else {
EFX_ERR(efx, "could not enable MSI\n");
efx->interrupt_mode = EFX_INT_MODE_LEGACY;
@@ -892,10 +882,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)
/* Assume legacy interrupts */
if (efx->interrupt_mode == EFX_INT_MODE_LEGACY) {
- efx->rss_queues = 1;
- /* Every channel is interruptible */
- for (i = 0; i < EFX_MAX_CHANNELS; i++)
- efx->channel[i].has_interrupt = 1;
+ efx->n_rx_queues = 1;
efx->legacy_irq = efx->pci_dev->irq;
}
}
@@ -905,7 +892,7 @@ static void efx_remove_interrupts(struct efx_nic *efx)
struct efx_channel *channel;
/* Remove MSI/MSI-X interrupts */
- efx_for_each_channel_with_interrupt(channel, efx)
+ efx_for_each_channel(channel, efx)
channel->irq = 0;
pci_disable_msi(efx->pci_dev);
pci_disable_msix(efx->pci_dev);
@@ -914,45 +901,22 @@ static void efx_remove_interrupts(struct efx_nic *efx)
efx->legacy_irq = 0;
}
-/* Select number of used resources
- * Should be called after probe_interrupts()
- */
-static void efx_select_used(struct efx_nic *efx)
+static void efx_set_channels(struct efx_nic *efx)
{
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
- int i;
-
- /* TX queues. One per port per channel with TX capability
- * (more than one per port won't work on Linux, due to out
- * of order issues... but will be fine on Solaris)
- */
- tx_queue = &efx->tx_queue[0];
- /* Perform this for each channel with TX capabilities.
- * At the moment, we only support a single TX queue
- */
- tx_queue->used = 1;
- if ((!EFX_INT_MODE_USE_MSI(efx)) && separate_tx_and_rx_channels)
- tx_queue->channel = &efx->channel[1];
- else
- tx_queue->channel = &efx->channel[0];
- tx_queue->channel->used_flags |= EFX_USED_BY_TX;
- tx_queue++;
-
- /* RX queues. Each has a dedicated channel. */
- for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
- rx_queue = &efx->rx_queue[i];
+ efx_for_each_tx_queue(tx_queue, efx) {
+ if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels)
+ tx_queue->channel = &efx->channel[1];
+ else
+ tx_queue->channel = &efx->channel[0];
+ tx_queue->channel->used_flags |= EFX_USED_BY_TX;
+ }
- if (i < efx->rss_queues) {
- rx_queue->used = 1;
- /* If we allow multiple RX queues per channel
- * we need to decide that here
- */
- rx_queue->channel = &efx->channel[rx_queue->queue];
- rx_queue->channel->used_flags |= EFX_USED_BY_RX;
- rx_queue++;
- }
+ efx_for_each_rx_queue(rx_queue, efx) {
+ rx_queue->channel = &efx->channel[rx_queue->queue];
+ rx_queue->channel->used_flags |= EFX_USED_BY_RX;
}
}
@@ -971,8 +935,7 @@ static int efx_probe_nic(struct efx_nic *efx)
* in MSI-X interrupts. */
efx_probe_interrupts(efx);
- /* Determine number of RX queues and TX queues */
- efx_select_used(efx);
+ efx_set_channels(efx);
/* Initialise the interrupt moderation settings */
efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec);
@@ -1058,7 +1021,8 @@ static void efx_start_all(struct efx_nic *efx)
/* Mark the port as enabled so port reconfigurations can start, then
* restart the transmit interface early so the watchdog timer stops */
efx_start_port(efx);
- efx_wake_queue(efx);
+ if (efx_dev_registered(efx))
+ efx_wake_queue(efx);
efx_for_each_channel(channel, efx)
efx_start_channel(channel);
@@ -1109,7 +1073,7 @@ static void efx_stop_all(struct efx_nic *efx)
falcon_disable_interrupts(efx);
if (efx->legacy_irq)
synchronize_irq(efx->legacy_irq);
- efx_for_each_channel_with_interrupt(channel, efx) {
+ efx_for_each_channel(channel, efx) {
if (channel->irq)
synchronize_irq(channel->irq);
}
@@ -1133,8 +1097,8 @@ static void efx_stop_all(struct efx_nic *efx)
/* Stop the kernel transmit interface late, so the watchdog
* timer isn't ticking over the flush */
- efx_stop_queue(efx);
if (efx_dev_registered(efx)) {
+ efx_stop_queue(efx);
netif_tx_lock_bh(efx->net_dev);
netif_tx_unlock_bh(efx->net_dev);
}
@@ -1151,24 +1115,16 @@ static void efx_remove_all(struct efx_nic *efx)
}
/* A convinience function to safely flush all the queues */
-int efx_flush_queues(struct efx_nic *efx)
+void efx_flush_queues(struct efx_nic *efx)
{
- int rc;
-
EFX_ASSERT_RESET_SERIALISED(efx);
efx_stop_all(efx);
efx_fini_channels(efx);
- rc = efx_init_channels(efx);
- if (rc) {
- efx_schedule_reset(efx, RESET_TYPE_DISABLE);
- return rc;
- }
+ efx_init_channels(efx);
efx_start_all(efx);
-
- return 0;
}
/**************************************************************************
@@ -1249,7 +1205,7 @@ static void efx_monitor(struct work_struct *data)
*/
static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
EFX_ASSERT_RESET_SERIALISED(efx);
@@ -1303,10 +1259,10 @@ static void efx_fini_napi(struct efx_nic *efx)
*/
static void efx_netpoll(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
- efx_for_each_channel_with_interrupt(channel, efx)
+ efx_for_each_channel(channel, efx)
efx_schedule_channel(channel);
}
@@ -1321,12 +1277,15 @@ static void efx_netpoll(struct net_device *net_dev)
/* Context: process, rtnl_lock() held. */
static int efx_net_open(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
EFX_ASSERT_RESET_SERIALISED(efx);
EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name,
raw_smp_processor_id());
+ if (efx->phy_mode & PHY_MODE_SPECIAL)
+ return -EBUSY;
+
efx_start_all(efx);
return 0;
}
@@ -1337,8 +1296,7 @@ static int efx_net_open(struct net_device *net_dev)
*/
static int efx_net_stop(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
- int rc;
+ struct efx_nic *efx = netdev_priv(net_dev);
EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name,
raw_smp_processor_id());
@@ -1346,9 +1304,7 @@ static int efx_net_stop(struct net_device *net_dev)
/* Stop the device and flush all the channels */
efx_stop_all(efx);
efx_fini_channels(efx);
- rc = efx_init_channels(efx);
- if (rc)
- efx_schedule_reset(efx, RESET_TYPE_DISABLE);
+ efx_init_channels(efx);
return 0;
}
@@ -1356,7 +1312,7 @@ static int efx_net_stop(struct net_device *net_dev)
/* Context: process, dev_base_lock or RTNL held, non-blocking. */
static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_mac_stats *mac_stats = &efx->mac_stats;
struct net_device_stats *stats = &net_dev->stats;
@@ -1366,7 +1322,7 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
- if (efx->state == STATE_RUNNING) {
+ if (efx->stats_enabled) {
falcon_update_stats_xmac(efx);
falcon_update_nic_stats(efx);
}
@@ -1403,7 +1359,7 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
/* Context: netif_tx_lock held, BHs disabled. */
static void efx_watchdog(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d: %s\n",
atomic_read(&efx->netif_stop_count), efx->port_enabled,
@@ -1417,7 +1373,7 @@ static void efx_watchdog(struct net_device *net_dev)
/* Context: process, rtnl_lock() held. */
static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
int rc = 0;
EFX_ASSERT_RESET_SERIALISED(efx);
@@ -1431,21 +1387,15 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
efx_fini_channels(efx);
net_dev->mtu = new_mtu;
- rc = efx_init_channels(efx);
- if (rc)
- goto fail;
+ efx_init_channels(efx);
efx_start_all(efx);
return rc;
-
- fail:
- efx_schedule_reset(efx, RESET_TYPE_DISABLE);
- return rc;
}
static int efx_set_mac_address(struct net_device *net_dev, void *data)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct sockaddr *addr = data;
char *new_addr = addr->sa_data;
@@ -1466,26 +1416,19 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
return 0;
}
-/* Context: netif_tx_lock held, BHs disabled. */
+/* Context: netif_addr_lock held, BHs disabled. */
static void efx_set_multicast_list(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct dev_mc_list *mc_list = net_dev->mc_list;
union efx_multicast_hash *mc_hash = &efx->multicast_hash;
- int promiscuous;
+ bool promiscuous = !!(net_dev->flags & IFF_PROMISC);
+ bool changed = (efx->promiscuous != promiscuous);
u32 crc;
int bit;
int i;
- /* Set per-MAC promiscuity flag and reconfigure MAC if necessary */
- promiscuous = (net_dev->flags & IFF_PROMISC) ? 1 : 0;
- if (efx->promiscuous != promiscuous) {
- efx->promiscuous = promiscuous;
- /* Close the window between efx_stop_port() and efx_flush_all()
- * by only queuing work when the port is enabled. */
- if (efx->port_enabled)
- queue_work(efx->workqueue, &efx->reconfigure_work);
- }
+ efx->promiscuous = promiscuous;
/* Build multicast hash table */
if (promiscuous || (net_dev->flags & IFF_ALLMULTI)) {
@@ -1500,6 +1443,13 @@ static void efx_set_multicast_list(struct net_device *net_dev)
}
}
+ if (!efx->port_enabled)
+ /* Delay pushing settings until efx_start_port() */
+ return;
+
+ if (changed)
+ queue_work(efx->workqueue, &efx->reconfigure_work);
+
/* Create and activate new global multicast hash table */
falcon_set_multicast_hash(efx);
}
@@ -1510,7 +1460,7 @@ static int efx_netdev_event(struct notifier_block *this,
struct net_device *net_dev = ptr;
if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) {
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
strcpy(efx->name, net_dev->name);
}
@@ -1568,7 +1518,7 @@ static void efx_unregister_netdev(struct efx_nic *efx)
if (!efx->net_dev)
return;
- BUG_ON(efx->net_dev->priv != efx);
+ BUG_ON(netdev_priv(efx->net_dev) != efx);
/* Free up any skbs still remaining. This has to happen before
* we try to unregister the netdev as running their destructors
@@ -1588,49 +1538,60 @@ static void efx_unregister_netdev(struct efx_nic *efx)
*
**************************************************************************/
-/* The final hardware and software finalisation before reset. */
-static int efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+/* Tears down the entire software state and most of the hardware state
+ * before reset. */
+void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
int rc;
EFX_ASSERT_RESET_SERIALISED(efx);
+ /* The net_dev->get_stats handler is quite slow, and will fail
+ * if a fetch is pending over reset. Serialise against it. */
+ spin_lock(&efx->stats_lock);
+ efx->stats_enabled = false;
+ spin_unlock(&efx->stats_lock);
+
+ efx_stop_all(efx);
+ mutex_lock(&efx->mac_lock);
+
rc = falcon_xmac_get_settings(efx, ecmd);
- if (rc) {
+ if (rc)
EFX_ERR(efx, "could not back up PHY settings\n");
- goto fail;
- }
efx_fini_channels(efx);
- return 0;
-
- fail:
- return rc;
}
-/* The first part of software initialisation after a hardware reset
- * This function does not handle serialisation with the kernel, it
- * assumes the caller has done this */
-static int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+/* This function will always ensure that the locks acquired in
+ * efx_reset_down() are released. A failure return code indicates
+ * that we were unable to reinitialise the hardware, and the
+ * driver should be disabled. If ok is false, then the rx and tx
+ * engines are not restarted, pending a RESET_DISABLE. */
+int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
{
int rc;
- rc = efx_init_channels(efx);
- if (rc)
- goto fail1;
+ EFX_ASSERT_RESET_SERIALISED(efx);
- /* Restore MAC and PHY settings. */
- rc = falcon_xmac_set_settings(efx, ecmd);
+ rc = falcon_init_nic(efx);
if (rc) {
- EFX_ERR(efx, "could not restore PHY settings\n");
- goto fail2;
+ EFX_ERR(efx, "failed to initialise NIC\n");
+ ok = false;
}
- return 0;
+ if (ok) {
+ efx_init_channels(efx);
- fail2:
- efx_fini_channels(efx);
- fail1:
+ if (falcon_xmac_set_settings(efx, ecmd))
+ EFX_ERR(efx, "could not restore PHY settings\n");
+ }
+
+ mutex_unlock(&efx->mac_lock);
+
+ if (ok) {
+ efx_start_all(efx);
+ efx->stats_enabled = true;
+ }
return rc;
}
@@ -1659,25 +1620,14 @@ static int efx_reset(struct efx_nic *efx)
goto unlock_rtnl;
}
- efx->state = STATE_RESETTING;
EFX_INFO(efx, "resetting (%d)\n", method);
- /* The net_dev->get_stats handler is quite slow, and will fail
- * if a fetch is pending over reset. Serialise against it. */
- spin_lock(&efx->stats_lock);
- spin_unlock(&efx->stats_lock);
-
- efx_stop_all(efx);
- mutex_lock(&efx->mac_lock);
-
- rc = efx_reset_down(efx, &ecmd);
- if (rc)
- goto fail1;
+ efx_reset_down(efx, &ecmd);
rc = falcon_reset_hw(efx, method);
if (rc) {
EFX_ERR(efx, "failed to reset hardware\n");
- goto fail2;
+ goto fail;
}
/* Allow resets to be rescheduled. */
@@ -1689,46 +1639,27 @@ static int efx_reset(struct efx_nic *efx)
* can respond to requests. */
pci_set_master(efx->pci_dev);
- /* Reinitialise device. This is appropriate in the RESET_TYPE_DISABLE
- * case so the driver can talk to external SRAM */
- rc = falcon_init_nic(efx);
- if (rc) {
- EFX_ERR(efx, "failed to initialise NIC\n");
- goto fail3;
- }
-
/* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) {
- /* Reinitialise the device anyway so the driver unload sequence
- * can talk to the external SRAM */
- falcon_init_nic(efx);
rc = -EIO;
- goto fail4;
+ goto fail;
}
- rc = efx_reset_up(efx, &ecmd);
+ rc = efx_reset_up(efx, &ecmd, true);
if (rc)
- goto fail5;
+ goto disable;
- mutex_unlock(&efx->mac_lock);
EFX_LOG(efx, "reset complete\n");
-
- efx->state = STATE_RUNNING;
- efx_start_all(efx);
-
unlock_rtnl:
rtnl_unlock();
return 0;
- fail5:
- fail4:
- fail3:
- fail2:
- fail1:
+ fail:
+ efx_reset_up(efx, &ecmd, false);
+ disable:
EFX_ERR(efx, "has been disabled\n");
efx->state = STATE_DISABLED;
- mutex_unlock(&efx->mac_lock);
rtnl_unlock();
efx_unregister_netdev(efx);
efx_fini_port(efx);
@@ -1801,7 +1732,7 @@ static struct pci_device_id efx_pci_table[] __devinitdata = {
*
* Dummy PHY/MAC/Board operations
*
- * Can be used where the MAC does not implement this operation
+ * Can be used for some unimplemented operations
* Needed so all function pointers are valid and do not have to be tested
* before use
*
@@ -1811,7 +1742,7 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
return 0;
}
void efx_port_dummy_op_void(struct efx_nic *efx) {}
-void efx_port_dummy_op_blink(struct efx_nic *efx, int blink) {}
+void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
static struct efx_phy_operations efx_dummy_phy_operations = {
.init = efx_port_dummy_op_int,
@@ -1822,17 +1753,12 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
.reset_xaui = efx_port_dummy_op_void,
};
-/* Dummy board operations */
-static int efx_nic_dummy_op_int(struct efx_nic *nic)
-{
- return 0;
-}
-
static struct efx_board efx_dummy_board_info = {
- .init = efx_nic_dummy_op_int,
- .init_leds = efx_port_dummy_op_int,
- .set_fault_led = efx_port_dummy_op_blink,
- .fini = efx_port_dummy_op_void,
+ .init = efx_port_dummy_op_int,
+ .init_leds = efx_port_dummy_op_int,
+ .set_fault_led = efx_port_dummy_op_blink,
+ .blink = efx_port_dummy_op_blink,
+ .fini = efx_port_dummy_op_void,
};
/**************************************************************************
@@ -1865,7 +1791,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->board_info = efx_dummy_board_info;
efx->net_dev = net_dev;
- efx->rx_checksum_enabled = 1;
+ efx->rx_checksum_enabled = true;
spin_lock_init(&efx->netif_stop_lock);
spin_lock_init(&efx->stats_lock);
mutex_init(&efx->mac_lock);
@@ -1878,10 +1804,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
channel = &efx->channel[i];
channel->efx = efx;
channel->channel = i;
- channel->evqnum = i;
- channel->work_pending = 0;
+ channel->work_pending = false;
}
- for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
+ for (i = 0; i < EFX_TX_QUEUE_COUNT; i++) {
tx_queue = &efx->tx_queue[i];
tx_queue->efx = efx;
tx_queue->queue = i;
@@ -2056,19 +1981,16 @@ static int efx_pci_probe_main(struct efx_nic *efx)
goto fail5;
}
- rc = efx_init_channels(efx);
- if (rc)
- goto fail6;
+ efx_init_channels(efx);
rc = falcon_init_interrupt(efx);
if (rc)
- goto fail7;
+ goto fail6;
return 0;
- fail7:
- efx_fini_channels(efx);
fail6:
+ efx_fini_channels(efx);
efx_fini_port(efx);
fail5:
fail4:
@@ -2105,7 +2027,10 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
NETIF_F_HIGHDMA | NETIF_F_TSO);
if (lro)
net_dev->features |= NETIF_F_LRO;
- efx = net_dev->priv;
+ /* Mask for features that also apply to VLAN devices */
+ net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
+ NETIF_F_HIGHDMA | NETIF_F_TSO);
+ efx = netdev_priv(net_dev);
pci_set_drvdata(pci_dev, efx);
rc = efx_init_struct(efx, type, pci_dev, net_dev);
if (rc)
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 3b2f69f..d02937b 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -28,15 +28,21 @@ extern void efx_wake_queue(struct efx_nic *efx);
/* RX */
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
- unsigned int len, int checksummed, int discard);
+ unsigned int len, bool checksummed, bool discard);
extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay);
/* Channels */
extern void efx_process_channel_now(struct efx_channel *channel);
-extern int efx_flush_queues(struct efx_nic *efx);
+extern void efx_flush_queues(struct efx_nic *efx);
/* Ports */
extern void efx_reconfigure_port(struct efx_nic *efx);
+extern void __efx_reconfigure_port(struct efx_nic *efx);
+
+/* Reset handling */
+extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
+ bool ok);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
@@ -50,7 +56,7 @@ extern void efx_hex_dump(const u8 *, unsigned int, const char *);
/* Dummy PHY ops for PHY drivers */
extern int efx_port_dummy_op_int(struct efx_nic *efx);
extern void efx_port_dummy_op_void(struct efx_nic *efx);
-extern void efx_port_dummy_op_blink(struct efx_nic *efx, int blink);
+extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink);
extern unsigned int efx_monitor_interval;
@@ -59,7 +65,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
{
EFX_TRACE(channel->efx, "channel %d scheduling NAPI poll on CPU%d\n",
channel->channel, raw_smp_processor_id());
- channel->work_pending = 1;
+ channel->work_pending = true;
netif_rx_schedule(channel->napi_dev, &channel->napi_str);
}
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index c53290d..cec15db 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -52,12 +52,11 @@ extern const char *efx_loopback_mode_names[];
#define LOOPBACK_MASK(_efx) \
(1 << (_efx)->loopback_mode)
-#define LOOPBACK_INTERNAL(_efx) \
- ((LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)) ? 1 : 0)
+#define LOOPBACK_INTERNAL(_efx) \
+ (!!(LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx)))
-#define LOOPBACK_OUT_OF(_from, _to, _mask) \
- (((LOOPBACK_MASK(_from) & (_mask)) && \
- ((LOOPBACK_MASK(_to) & (_mask)) == 0)) ? 1 : 0)
+#define LOOPBACK_OUT_OF(_from, _to, _mask) \
+ ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
/*****************************************************************************/
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index e2c75d1..fa98af5 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -17,6 +17,7 @@
#include "ethtool.h"
#include "falcon.h"
#include "gmii.h"
+#include "spi.h"
#include "mac.h"
const char *efx_loopback_mode_names[] = {
@@ -32,8 +33,6 @@ const char *efx_loopback_mode_names[] = {
[LOOPBACK_NETWORK] = "NETWORK",
};
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);
-
struct ethtool_string {
char name[ETH_GSTRING_LEN];
};
@@ -173,6 +172,11 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
/* Number of ethtool statistics */
#define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
+/* EEPROM range with gPXE configuration */
+#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
+#define EFX_ETHTOOL_EEPROM_MIN 0x100U
+#define EFX_ETHTOOL_EEPROM_MAX 0x400U
+
/**************************************************************************
*
* Ethtool operations
@@ -183,7 +187,7 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
/* Identify device by flashing LEDs */
static int efx_ethtool_phys_id(struct net_device *net_dev, u32 seconds)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
efx->board_info.blink(efx, 1);
schedule_timeout_interruptible(seconds * HZ);
@@ -195,7 +199,7 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 seconds)
int efx_ethtool_get_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
int rc;
mutex_lock(&efx->mac_lock);
@@ -209,7 +213,7 @@ int efx_ethtool_get_settings(struct net_device *net_dev,
int efx_ethtool_set_settings(struct net_device *net_dev,
struct ethtool_cmd *ecmd)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
int rc;
mutex_lock(&efx->mac_lock);
@@ -224,7 +228,7 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
static void efx_ethtool_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *info)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
strlcpy(info->driver, EFX_DRIVER_NAME, sizeof(info->driver));
strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version));
@@ -329,7 +333,10 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
unsigned int n = 0;
enum efx_loopback_mode mode;
- /* Interrupt */
+ efx_fill_test(n++, strings, data, &tests->mii,
+ "core", 0, "mii", NULL);
+ efx_fill_test(n++, strings, data, &tests->nvram,
+ "core", 0, "nvram", NULL);
efx_fill_test(n++, strings, data, &tests->interrupt,
"core", 0, "interrupt", NULL);
@@ -349,16 +356,17 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
"eventq.poll", NULL);
}
- /* PHY presence */
- efx_fill_test(n++, strings, data, &tests->phy_ok,
- EFX_PORT_NAME, "phy_ok", NULL);
+ efx_fill_test(n++, strings, data, &tests->registers,
+ "core", 0, "registers", NULL);
+ efx_fill_test(n++, strings, data, &tests->phy,
+ EFX_PORT_NAME, "phy", NULL);
/* Loopback tests */
efx_fill_test(n++, strings, data, &tests->loopback_speed,
EFX_PORT_NAME, "loopback.speed", NULL);
efx_fill_test(n++, strings, data, &tests->loopback_full_duplex,
EFX_PORT_NAME, "loopback.full_duplex", NULL);
- for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
+ for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) {
if (!(efx->loopback_modes & (1 << mode)))
continue;
n = efx_fill_loopback_test(efx,
@@ -369,22 +377,24 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
return n;
}
-static int efx_ethtool_get_stats_count(struct net_device *net_dev)
+static int efx_ethtool_get_sset_count(struct net_device *net_dev,
+ int string_set)
{
- return EFX_ETHTOOL_NUM_STATS;
-}
-
-static int efx_ethtool_self_test_count(struct net_device *net_dev)
-{
- struct efx_nic *efx = net_dev->priv;
-
- return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
+ switch (string_set) {
+ case ETH_SS_STATS:
+ return EFX_ETHTOOL_NUM_STATS;
+ case ETH_SS_TEST:
+ return efx_ethtool_fill_self_tests(netdev_priv(net_dev),
+ NULL, NULL, NULL);
+ default:
+ return -EINVAL;
+ }
}
static void efx_ethtool_get_strings(struct net_device *net_dev,
u32 string_set, u8 *strings)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct ethtool_string *ethtool_strings =
(struct ethtool_string *)strings;
int i;
@@ -410,7 +420,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
struct ethtool_stats *stats,
u64 *data)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_mac_stats *mac_stats = &efx->mac_stats;
struct efx_ethtool_stat *stat;
struct efx_channel *channel;
@@ -442,60 +452,21 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
}
}
-static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
-{
- int rc;
-
- /* Our TSO requires TX checksumming, so force TX checksumming
- * on when TSO is enabled.
- */
- if (enable) {
- rc = efx_ethtool_set_tx_csum(net_dev, 1);
- if (rc)
- return rc;
- }
-
- return ethtool_op_set_tso(net_dev, enable);
-}
-
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
-{
- struct efx_nic *efx = net_dev->priv;
- int rc;
-
- rc = ethtool_op_set_tx_csum(net_dev, enable);
- if (rc)
- return rc;
-
- efx_flush_queues(efx);
-
- /* Our TSO requires TX checksumming, so disable TSO when
- * checksumming is disabled
- */
- if (!enable) {
- rc = efx_ethtool_set_tso(net_dev, 0);
- if (rc)
- return rc;
- }
-
- return 0;
-}
-
static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
/* No way to stop the hardware doing the checks; we just
* ignore the result.
*/
- efx->rx_checksum_enabled = (enable ? 1 : 0);
+ efx->rx_checksum_enabled = !!enable;
return 0;
}
static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
return efx->rx_checksum_enabled;
}
@@ -503,7 +474,7 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
static void efx_ethtool_self_test(struct net_device *net_dev,
struct ethtool_test *test, u64 *data)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_self_tests efx_tests;
int offline, already_up;
int rc;
@@ -533,15 +504,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
goto out;
/* Perform offline tests only if online tests passed */
- if (offline) {
- /* Stop the kernel from sending packets during the test. */
- efx_stop_queue(efx);
- rc = efx_flush_queues(efx);
- if (!rc)
- rc = efx_offline_test(efx, &efx_tests,
- efx->loopback_modes);
- efx_wake_queue(efx);
- }
+ if (offline)
+ rc = efx_offline_test(efx, &efx_tests,
+ efx->loopback_modes);
out:
if (!already_up)
@@ -561,22 +526,65 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
/* Restart autonegotiation */
static int efx_ethtool_nway_reset(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
return mii_nway_restart(&efx->mii);
}
static u32 efx_ethtool_get_link(struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
return efx->link_up;
}
+static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_spi_device *spi = efx->spi_eeprom;
+
+ if (!spi)
+ return 0;
+ return min(spi->size, EFX_ETHTOOL_EEPROM_MAX) -
+ min(spi->size, EFX_ETHTOOL_EEPROM_MIN);
+}
+
+static int efx_ethtool_get_eeprom(struct net_device *net_dev,
+ struct ethtool_eeprom *eeprom, u8 *buf)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_spi_device *spi = efx->spi_eeprom;
+ size_t len;
+ int rc;
+
+ rc = falcon_spi_read(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
+ eeprom->len, &len, buf);
+ eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC;
+ eeprom->len = len;
+ return rc;
+}
+
+static int efx_ethtool_set_eeprom(struct net_device *net_dev,
+ struct ethtool_eeprom *eeprom, u8 *buf)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_spi_device *spi = efx->spi_eeprom;
+ size_t len;
+ int rc;
+
+ if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC)
+ return -EINVAL;
+
+ rc = falcon_spi_write(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
+ eeprom->len, &len, buf);
+ eeprom->len = len;
+ return rc;
+}
+
static int efx_ethtool_get_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
struct efx_channel *channel;
@@ -614,7 +622,7 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
static int efx_ethtool_set_coalesce(struct net_device *net_dev,
struct ethtool_coalesce *coalesce)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
unsigned tx_usecs, rx_usecs;
@@ -657,7 +665,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
enum efx_fc_type flow_control = efx->flow_control;
int rc;
@@ -680,11 +688,11 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
- pause->rx_pause = (efx->flow_control & EFX_FC_RX) ? 1 : 0;
- pause->tx_pause = (efx->flow_control & EFX_FC_TX) ? 1 : 0;
- pause->autoneg = (efx->flow_control & EFX_FC_AUTO) ? 1 : 0;
+ pause->rx_pause = !!(efx->flow_control & EFX_FC_RX);
+ pause->tx_pause = !!(efx->flow_control & EFX_FC_TX);
+ pause->autoneg = !!(efx->flow_control & EFX_FC_AUTO);
}
@@ -694,6 +702,9 @@ struct ethtool_ops efx_ethtool_ops = {
.get_drvinfo = efx_ethtool_get_drvinfo,
.nway_reset = efx_ethtool_nway_reset,
.get_link = efx_ethtool_get_link,
+ .get_eeprom_len = efx_ethtool_get_eeprom_len,
+ .get_eeprom = efx_ethtool_get_eeprom,
+ .set_eeprom = efx_ethtool_set_eeprom,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
.get_pauseparam = efx_ethtool_get_pauseparam,
@@ -701,17 +712,16 @@ struct ethtool_ops efx_ethtool_ops = {
.get_rx_csum = efx_ethtool_get_rx_csum,
.set_rx_csum = efx_ethtool_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = efx_ethtool_set_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
- .set_tso = efx_ethtool_set_tso,
+ .set_tso = ethtool_op_set_tso,
.get_flags = ethtool_op_get_flags,
.set_flags = ethtool_op_set_flags,
- .self_test_count = efx_ethtool_self_test_count,
+ .get_sset_count = efx_ethtool_get_sset_count,
.self_test = efx_ethtool_self_test,
.get_strings = efx_ethtool_get_strings,
.phys_id = efx_ethtool_phys_id,
- .get_stats_count = efx_ethtool_get_stats_count,
.get_ethtool_stats = efx_ethtool_get_stats,
};
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 9138ee5..e0c0b23 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -242,7 +242,7 @@ static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
* falcon_alloc_special_buffer()) in Falcon's buffer table, allowing
* it to be used for event queues, descriptor rings etc.
*/
-static int
+static void
falcon_init_special_buffer(struct efx_nic *efx,
struct efx_special_buffer *buffer)
{
@@ -266,8 +266,6 @@ falcon_init_special_buffer(struct efx_nic *efx,
BUF_OWNER_ID_FBUF, 0);
falcon_write_sram(efx, &buf_desc, index);
}
-
- return 0;
}
/* Unmaps a buffer from Falcon and clears the buffer table entries */
@@ -449,16 +447,13 @@ int falcon_probe_tx(struct efx_tx_queue *tx_queue)
sizeof(efx_qword_t));
}
-int falcon_init_tx(struct efx_tx_queue *tx_queue)
+void falcon_init_tx(struct efx_tx_queue *tx_queue)
{
efx_oword_t tx_desc_ptr;
struct efx_nic *efx = tx_queue->efx;
- int rc;
/* Pin TX descriptor ring */
- rc = falcon_init_special_buffer(efx, &tx_queue->txd);
- if (rc)
- return rc;
+ falcon_init_special_buffer(efx, &tx_queue->txd);
/* Push TX descriptor ring to card */
EFX_POPULATE_OWORD_10(tx_desc_ptr,
@@ -466,7 +461,7 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
TX_ISCSI_DDIG_EN, 0,
TX_ISCSI_HDIG_EN, 0,
TX_DESCQ_BUF_BASE_ID, tx_queue->txd.index,
- TX_DESCQ_EVQ_ID, tx_queue->channel->evqnum,
+ TX_DESCQ_EVQ_ID, tx_queue->channel->channel,
TX_DESCQ_OWNER_ID, 0,
TX_DESCQ_LABEL, tx_queue->queue,
TX_DESCQ_SIZE, FALCON_TXD_RING_ORDER,
@@ -474,9 +469,9 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
TX_NON_IP_DROP_DIS_B0, 1);
if (falcon_rev(efx) >= FALCON_REV_B0) {
- int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM);
- EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum);
- EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum);
+ int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
+ EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
+ EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
}
falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
@@ -485,17 +480,16 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue)
if (falcon_rev(efx) < FALCON_REV_B0) {
efx_oword_t reg;
- BUG_ON(tx_queue->queue >= 128); /* HW limit */
+ /* Only 128 bits in this register */
+ BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
falcon_read(efx, ®, TX_CHKSM_CFG_REG_KER_A1);
- if (efx->net_dev->features & NETIF_F_IP_CSUM)
+ if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
clear_bit_le(tx_queue->queue, (void *)®);
else
set_bit_le(tx_queue->queue, (void *)®);
falcon_write(efx, ®, TX_CHKSM_CFG_REG_KER_A1);
}
-
- return 0;
}
static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
@@ -538,7 +532,7 @@ static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
if (EFX_WORKAROUND_11557(efx)) {
efx_oword_t reg;
- int enabled;
+ bool enabled;
falcon_read_table(efx, ®, efx->type->txd_ptr_tbl_base,
tx_queue->queue);
@@ -638,29 +632,26 @@ int falcon_probe_rx(struct efx_rx_queue *rx_queue)
sizeof(efx_qword_t));
}
-int falcon_init_rx(struct efx_rx_queue *rx_queue)
+void falcon_init_rx(struct efx_rx_queue *rx_queue)
{
efx_oword_t rx_desc_ptr;
struct efx_nic *efx = rx_queue->efx;
- int rc;
- int is_b0 = falcon_rev(efx) >= FALCON_REV_B0;
- int iscsi_digest_en = is_b0;
+ bool is_b0 = falcon_rev(efx) >= FALCON_REV_B0;
+ bool iscsi_digest_en = is_b0;
EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n",
rx_queue->queue, rx_queue->rxd.index,
rx_queue->rxd.index + rx_queue->rxd.entries - 1);
/* Pin RX descriptor ring */
- rc = falcon_init_special_buffer(efx, &rx_queue->rxd);
- if (rc)
- return rc;
+ falcon_init_special_buffer(efx, &rx_queue->rxd);
/* Push RX descriptor ring to card */
EFX_POPULATE_OWORD_10(rx_desc_ptr,
RX_ISCSI_DDIG_EN, iscsi_digest_en,
RX_ISCSI_HDIG_EN, iscsi_digest_en,
RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index,
- RX_DESCQ_EVQ_ID, rx_queue->channel->evqnum,
+ RX_DESCQ_EVQ_ID, rx_queue->channel->channel,
RX_DESCQ_OWNER_ID, 0,
RX_DESCQ_LABEL, rx_queue->queue,
RX_DESCQ_SIZE, FALCON_RXD_RING_ORDER,
@@ -670,7 +661,6 @@ int falcon_init_rx(struct efx_rx_queue *rx_queue)
RX_DESCQ_EN, 1);
falcon_write_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
rx_queue->queue);
- return 0;
}
static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
@@ -694,7 +684,8 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
read_ptr = channel->eventq_read_ptr;
for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
efx_qword_t *event = falcon_event(channel, read_ptr);
- int ev_code, ev_sub_code, ev_queue, ev_failed;
+ int ev_code, ev_sub_code, ev_queue;
+ bool ev_failed;
if (!falcon_event_present(event))
break;
@@ -721,7 +712,7 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
if (EFX_WORKAROUND_11557(efx)) {
efx_oword_t reg;
- int enabled;
+ bool enabled;
falcon_read_table(efx, ®, efx->type->rxd_ptr_tbl_base,
rx_queue->queue);
@@ -793,7 +784,7 @@ void falcon_eventq_read_ack(struct efx_channel *channel)
EFX_POPULATE_DWORD_1(reg, EVQ_RPTR_DWORD, channel->eventq_read_ptr);
falcon_writel_table(efx, ®, efx->type->evq_rptr_tbl_base,
- channel->evqnum);
+ channel->channel);
}
/* Use HW to insert a SW defined event */
@@ -802,7 +793,7 @@ void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event)
efx_oword_t drv_ev_reg;
EFX_POPULATE_OWORD_2(drv_ev_reg,
- DRV_EV_QID, channel->evqnum,
+ DRV_EV_QID, channel->channel,
DRV_EV_DATA,
EFX_QWORD_FIELD64(*event, WHOLE_EVENT));
falcon_write(channel->efx, &drv_ev_reg, DRV_EV_REG_KER);
@@ -813,8 +804,8 @@ void falcon_generate_event(struct efx_channel *channel, efx_qword_t *event)
* Falcon batches TX completion events; the message we receive is of
* the form "complete all TX events up to this index".
*/
-static inline void falcon_handle_tx_event(struct efx_channel *channel,
- efx_qword_t *event)
+static void falcon_handle_tx_event(struct efx_channel *channel,
+ efx_qword_t *event)
{
unsigned int tx_ev_desc_ptr;
unsigned int tx_ev_q_label;
@@ -847,39 +838,19 @@ static inline void falcon_handle_tx_event(struct efx_channel *channel,
}
}
-/* Check received packet's destination MAC address. */
-static int check_dest_mac(struct efx_rx_queue *rx_queue,
- const efx_qword_t *event)
-{
- struct efx_rx_buffer *rx_buf;
- struct efx_nic *efx = rx_queue->efx;
- int rx_ev_desc_ptr;
- struct ethhdr *eh;
-
- if (efx->promiscuous)
- return 1;
-
- rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
- rx_buf = efx_rx_buffer(rx_queue, rx_ev_desc_ptr);
- eh = (struct ethhdr *)rx_buf->data;
- if (memcmp(eh->h_dest, efx->net_dev->dev_addr, ETH_ALEN))
- return 0;
- return 1;
-}
-
/* Detect errors included in the rx_evt_pkt_ok bit. */
static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
const efx_qword_t *event,
- unsigned *rx_ev_pkt_ok,
- int *discard, int byte_count)
+ bool *rx_ev_pkt_ok,
+ bool *discard)
{
struct efx_nic *efx = rx_queue->efx;
- unsigned rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
- unsigned rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
- unsigned rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
- unsigned rx_ev_pkt_type, rx_ev_other_err, rx_ev_pause_frm;
- unsigned rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
- int snap, non_ip;
+ bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
+ bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err;
+ bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
+ bool rx_ev_other_err, rx_ev_pause_frm;
+ bool rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
+ unsigned rx_ev_pkt_type;
rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT);
@@ -903,41 +874,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
rx_ev_buf_owner_id_err | rx_ev_eth_crc_err |
rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err);
- snap = (rx_ev_pkt_type == RX_EV_PKT_TYPE_LLC_DECODE) ||
- (rx_ev_pkt_type == RX_EV_PKT_TYPE_VLAN_LLC_DECODE);
- non_ip = (rx_ev_hdr_type == RX_EV_HDR_TYPE_NON_IP_DECODE);
-
- /* SFC bug 5475/8970: The Falcon XMAC incorrectly calculates the
- * length field of an LLC frame, which sets TOBE_DISC. We could set
- * PASS_LEN_ERR, but we want the MAC to filter out short frames (to
- * protect the RX block).
- *
- * bug5475 - LLC/SNAP: Falcon identifies SNAP packets.
- * bug8970 - LLC/noSNAP: Falcon does not provide an LLC flag.
- * LLC can't encapsulate IP, so by definition
- * these packets are NON_IP.
- *
- * Unicast mismatch will also cause TOBE_DISC, so the driver needs
- * to check this.
- */
- if (EFX_WORKAROUND_5475(efx) && rx_ev_tobe_disc && (snap || non_ip)) {
- /* If all the other flags are zero then we can state the
- * entire packet is ok, which will flag to the kernel not
- * to recalculate checksums.
- */
- if (!(non_ip | rx_ev_other_err | rx_ev_pause_frm))
- *rx_ev_pkt_ok = 1;
-
- rx_ev_tobe_disc = 0;
-
- /* TOBE_DISC is set for unicast mismatch. But given that
- * we can't trust TOBE_DISC here, we must validate the dest
- * MAC address ourselves.
- */
- if (!rx_ev_mcast_pkt && !check_dest_mac(rx_queue, event))
- rx_ev_tobe_disc = 1;
- }
-
/* Count errors that are not in MAC stats. */
if (rx_ev_frm_trunc)
++rx_queue->channel->n_rx_frm_trunc;
@@ -961,7 +897,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
#ifdef EFX_ENABLE_DEBUG
if (rx_ev_other_err) {
EFX_INFO_RL(efx, " RX queue %d unexpected RX event "
- EFX_QWORD_FMT "%s%s%s%s%s%s%s%s%s\n",
+ EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
rx_queue->queue, EFX_QWORD_VAL(*event),
rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
rx_ev_ip_hdr_chksum_err ?
@@ -972,8 +908,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
rx_ev_frm_trunc ? " [FRM_TRUNC]" : "",
rx_ev_drib_nib ? " [DRIB_NIB]" : "",
rx_ev_tobe_disc ? " [TOBE_DISC]" : "",
- rx_ev_pause_frm ? " [PAUSE]" : "",
- snap ? " [SNAP/LLC]" : "");
+ rx_ev_pause_frm ? " [PAUSE]" : "");
}
#endif
@@ -1006,13 +941,13 @@ static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue,
* Also "is multicast" and "matches multicast filter" flags can be used to
* discard non-matching multicast packets.
*/
-static inline int falcon_handle_rx_event(struct efx_channel *channel,
- const efx_qword_t *event)
+static void falcon_handle_rx_event(struct efx_channel *channel,
+ const efx_qword_t *event)
{
- unsigned int rx_ev_q_label, rx_ev_desc_ptr, rx_ev_byte_cnt;
- unsigned int rx_ev_pkt_ok, rx_ev_hdr_type, rx_ev_mcast_pkt;
+ unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt;
+ unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
unsigned expected_ptr;
- int discard = 0, checksummed;
+ bool rx_ev_pkt_ok, discard = false, checksummed;
struct efx_rx_queue *rx_queue;
struct efx_nic *efx = channel->efx;
@@ -1022,16 +957,14 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_JUMBO_CONT));
WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_SOP) != 1);
+ WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL) != channel->channel);
- rx_ev_q_label = EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL);
- rx_queue = &efx->rx_queue[rx_ev_q_label];
+ rx_queue = &efx->rx_queue[channel->channel];
rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK;
- if (unlikely(rx_ev_desc_ptr != expected_ptr)) {
+ if (unlikely(rx_ev_desc_ptr != expected_ptr))
falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
- return rx_ev_q_label;
- }
if (likely(rx_ev_pkt_ok)) {
/* If packet is marked as OK and packet type is TCP/IPv4 or
@@ -1040,8 +973,8 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type);
} else {
falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok,
- &discard, rx_ev_byte_cnt);
- checksummed = 0;
+ &discard);
+ checksummed = false;
}
/* Detect multicast packets that didn't match the filter */
@@ -1051,14 +984,12 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
EFX_QWORD_FIELD(*event, RX_EV_MCAST_HASH_MATCH);
if (unlikely(!rx_ev_mcast_hash_match))
- discard = 1;
+ discard = true;
}
/* Handle received packet */
efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
checksummed, discard);
-
- return rx_ev_q_label;
}
/* Global events are basically PHY events */
@@ -1066,23 +997,23 @@ static void falcon_handle_global_event(struct efx_channel *channel,
efx_qword_t *event)
{
struct efx_nic *efx = channel->efx;
- int is_phy_event = 0, handled = 0;
+ bool is_phy_event = false, handled = false;
/* Check for interrupt on either port. Some boards have a
* single PHY wired to the interrupt line for port 1. */
if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) ||
EFX_QWORD_FIELD(*event, G_PHY1_INTR) ||
EFX_QWORD_FIELD(*event, XG_PHY_INTR))
- is_phy_event = 1;
+ is_phy_event = true;
if ((falcon_rev(efx) >= FALCON_REV_B0) &&
EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0))
- is_phy_event = 1;
+ is_phy_event = true;
if (is_phy_event) {
efx->phy_op->clear_interrupt(efx);
queue_work(efx->workqueue, &efx->reconfigure_work);
- handled = 1;
+ handled = true;
}
if (EFX_QWORD_FIELD_VER(efx, *event, RX_RECOVERY)) {
@@ -1092,7 +1023,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
atomic_inc(&efx->rx_reset);
efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ?
RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE);
- handled = 1;
+ handled = true;
}
if (!handled)
@@ -1163,13 +1094,12 @@ static void falcon_handle_driver_event(struct efx_channel *channel,
}
}
-int falcon_process_eventq(struct efx_channel *channel, int *rx_quota)
+int falcon_process_eventq(struct efx_channel *channel, int rx_quota)
{
unsigned int read_ptr;
efx_qword_t event, *p_event;
int ev_code;
- int rxq;
- int rxdmaqs = 0;
+ int rx_packets = 0;
read_ptr = channel->eventq_read_ptr;
@@ -1191,9 +1121,8 @@ int falcon_process_eventq(struct efx_channel *channel, int *rx_quota)
switch (ev_code) {
case RX_IP_EV_DECODE:
- rxq = falcon_handle_rx_event(channel, &event);
- rxdmaqs |= (1 << rxq);
- (*rx_quota)--;
+ falcon_handle_rx_event(channel, &event);
+ ++rx_packets;
break;
case TX_IP_EV_DECODE:
falcon_handle_tx_event(channel, &event);
@@ -1220,10 +1149,10 @@ int falcon_process_eventq(struct efx_channel *channel, int *rx_quota)
/* Increment read pointer */
read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- } while (*rx_quota);
+ } while (rx_packets < rx_quota);
channel->eventq_read_ptr = read_ptr;
- return rxdmaqs;
+ return rx_packets;
}
void falcon_set_int_moderation(struct efx_channel *channel)
@@ -1251,7 +1180,7 @@ void falcon_set_int_moderation(struct efx_channel *channel)
TIMER_VAL, 0);
}
falcon_writel_page_locked(efx, &timer_cmd, TIMER_CMD_REG_KER,
- channel->evqnum);
+ channel->channel);
}
@@ -1265,20 +1194,17 @@ int falcon_probe_eventq(struct efx_channel *channel)
return falcon_alloc_special_buffer(efx, &channel->eventq, evq_size);
}
-int falcon_init_eventq(struct efx_channel *channel)
+void falcon_init_eventq(struct efx_channel *channel)
{
efx_oword_t evq_ptr;
struct efx_nic *efx = channel->efx;
- int rc;
EFX_LOG(efx, "channel %d event queue in special buffers %d-%d\n",
channel->channel, channel->eventq.index,
channel->eventq.index + channel->eventq.entries - 1);
/* Pin event queue buffer */
- rc = falcon_init_special_buffer(efx, &channel->eventq);
- if (rc)
- return rc;
+ falcon_init_special_buffer(efx, &channel->eventq);
/* Fill event queue with all ones (i.e. empty events) */
memset(channel->eventq.addr, 0xff, channel->eventq.len);
@@ -1289,11 +1215,9 @@ int falcon_init_eventq(struct efx_channel *channel)
EVQ_SIZE, FALCON_EVQ_ORDER,
EVQ_BUF_BASE_ID, channel->eventq.index);
falcon_write_table(efx, &evq_ptr, efx->type->evq_ptr_tbl_base,
- channel->evqnum);
+ channel->channel);
falcon_set_int_moderation(channel);
-
- return 0;
}
void falcon_fini_eventq(struct efx_channel *channel)
@@ -1304,7 +1228,7 @@ void falcon_fini_eventq(struct efx_channel *channel)
/* Remove event queue from card */
EFX_ZERO_OWORD(eventq_ptr);
falcon_write_table(efx, &eventq_ptr, efx->type->evq_ptr_tbl_base,
- channel->evqnum);
+ channel->channel);
/* Unpin event queue */
falcon_fini_special_buffer(efx, &channel->eventq);
@@ -1371,7 +1295,7 @@ void falcon_enable_interrupts(struct efx_nic *efx)
/* Force processing of all the channels to get the EVQ RPTRs up to
date */
- efx_for_each_channel_with_interrupt(channel, efx)
+ efx_for_each_channel(channel, efx)
efx_schedule_channel(channel);
}
@@ -1589,7 +1513,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx)
offset < RX_RSS_INDIR_TBL_B0 + 0x800;
offset += 0x10) {
EFX_POPULATE_DWORD_1(dword, RX_RSS_INDIR_ENT_B0,
- i % efx->rss_queues);
+ i % efx->n_rx_queues);
falcon_writel(efx, &dword, offset);
i++;
}
@@ -1621,7 +1545,7 @@ int falcon_init_interrupt(struct efx_nic *efx)
}
/* Hook MSI or MSI-X interrupt */
- efx_for_each_channel_with_interrupt(channel, efx) {
+ efx_for_each_channel(channel, efx) {
rc = request_irq(channel->irq, falcon_msi_interrupt,
IRQF_PROBE_SHARED, /* Not shared */
efx->name, channel);
@@ -1634,7 +1558,7 @@ int falcon_init_interrupt(struct efx_nic *efx)
return 0;
fail2:
- efx_for_each_channel_with_interrupt(channel, efx)
+ efx_for_each_channel(channel, efx)
free_irq(channel->irq, channel);
fail1:
return rc;
@@ -1646,7 +1570,7 @@ void falcon_fini_interrupt(struct efx_nic *efx)
efx_oword_t reg;
/* Disable MSI/MSI-X interrupts */
- efx_for_each_channel_with_interrupt(channel, efx) {
+ efx_for_each_channel(channel, efx) {
if (channel->irq)
free_irq(channel->irq, channel);
}
@@ -1674,64 +1598,195 @@ void falcon_fini_interrupt(struct efx_nic *efx)
/* Wait for SPI command completion */
static int falcon_spi_wait(struct efx_nic *efx)
{
+ unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10);
efx_oword_t reg;
- int cmd_en, timer_active;
- int count;
+ bool cmd_en, timer_active;
- count = 0;
- do {
+ for (;;) {
falcon_read(efx, ®, EE_SPI_HCMD_REG_KER);
cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN);
timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE);
if (!cmd_en && !timer_active)
return 0;
- udelay(10);
- } while (++count < 10000); /* wait upto 100msec */
- EFX_ERR(efx, "timed out waiting for SPI\n");
- return -ETIMEDOUT;
+ if (time_after_eq(jiffies, timeout)) {
+ EFX_ERR(efx, "timed out waiting for SPI\n");
+ return -ETIMEDOUT;
+ }
+ cpu_relax();
+ }
}
-static int
-falcon_spi_read(struct efx_nic *efx, int device_id, unsigned int command,
- unsigned int address, unsigned int addr_len,
- void *data, unsigned int len)
+static int falcon_spi_cmd(const struct efx_spi_device *spi,
+ unsigned int command, int address,
+ const void *in, void *out, unsigned int len)
{
+ struct efx_nic *efx = spi->efx;
+ bool addressed = (address >= 0);
+ bool reading = (out != NULL);
efx_oword_t reg;
int rc;
- BUG_ON(len > FALCON_SPI_MAX_LEN);
+ /* Input validation */
+ if (len > FALCON_SPI_MAX_LEN)
+ return -EINVAL;
/* Check SPI not currently being accessed */
rc = falcon_spi_wait(efx);
if (rc)
return rc;
- /* Program address register */
- EFX_POPULATE_OWORD_1(reg, EE_SPI_HADR_ADR, address);
- falcon_write(efx, ®, EE_SPI_HADR_REG_KER);
+ /* Program address register, if we have an address */
+ if (addressed) {
+ EFX_POPULATE_OWORD_1(reg, EE_SPI_HADR_ADR, address);
+ falcon_write(efx, ®, EE_SPI_HADR_REG_KER);
+ }
+
+ /* Program data register, if we have data */
+ if (in != NULL) {
+ memcpy(®, in, len);
+ falcon_write(efx, ®, EE_SPI_HDATA_REG_KER);
+ }
- /* Issue read command */
+ /* Issue read/write command */
EFX_POPULATE_OWORD_7(reg,
EE_SPI_HCMD_CMD_EN, 1,
- EE_SPI_HCMD_SF_SEL, device_id,
+ EE_SPI_HCMD_SF_SEL, spi->device_id,
EE_SPI_HCMD_DABCNT, len,
- EE_SPI_HCMD_READ, EE_SPI_READ,
+ EE_SPI_HCMD_READ, reading,
EE_SPI_HCMD_DUBCNT, 0,
- EE_SPI_HCMD_ADBCNT, addr_len,
+ EE_SPI_HCMD_ADBCNT,
+ (addressed ? spi->addr_len : 0),
EE_SPI_HCMD_ENC, command);
falcon_write(efx, ®, EE_SPI_HCMD_REG_KER);
- /* Wait for read to complete */
+ /* Wait for read/write to complete */
rc = falcon_spi_wait(efx);
if (rc)
return rc;
/* Read data */
- falcon_read(efx, ®, EE_SPI_HDATA_REG_KER);
- memcpy(data, ®, len);
+ if (out != NULL) {
+ falcon_read(efx, ®, EE_SPI_HDATA_REG_KER);
+ memcpy(out, ®, len);
+ }
+
return 0;
}
+static unsigned int
+falcon_spi_write_limit(const struct efx_spi_device *spi, unsigned int start)
+{
+ return min(FALCON_SPI_MAX_LEN,
+ (spi->block_size - (start & (spi->block_size - 1))));
+}
+
+static inline u8
+efx_spi_munge_command(const struct efx_spi_device *spi,
+ const u8 command, const unsigned int address)
+{
+ return command | (((address >> 8) & spi->munge_address) << 3);
+}
+
+
+static int falcon_spi_fast_wait(const struct efx_spi_device *spi)
+{
+ u8 status;
+ int i, rc;
+
+ /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */
+ for (i = 0; i < 50; i++) {
+ udelay(20);
+
+ rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
+ &status, sizeof(status));
+ if (rc)
+ return rc;
+ if (!(status & SPI_STATUS_NRDY))
+ return 0;
+ }
+ EFX_ERR(spi->efx,
+ "timed out waiting for device %d last status=0x%02x\n",
+ spi->device_id, status);
+ return -ETIMEDOUT;
+}
+
+int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
+ size_t len, size_t *retlen, u8 *buffer)
+{
+ unsigned int command, block_len, pos = 0;
+ int rc = 0;
+
+ while (pos < len) {
+ block_len = min((unsigned int)len - pos,
+ FALCON_SPI_MAX_LEN);
+
+ command = efx_spi_munge_command(spi, SPI_READ, start + pos);
+ rc = falcon_spi_cmd(spi, command, start + pos, NULL,
+ buffer + pos, block_len);
+ if (rc)
+ break;
+ pos += block_len;
+
+ /* Avoid locking up the system */
+ cond_resched();
+ if (signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ }
+
+ if (retlen)
+ *retlen = pos;
+ return rc;
+}
+
+int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
+ size_t len, size_t *retlen, const u8 *buffer)
+{
+ u8 verify_buffer[FALCON_SPI_MAX_LEN];
+ unsigned int command, block_len, pos = 0;
+ int rc = 0;
+
+ while (pos < len) {
+ rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+ if (rc)
+ break;
+
+ block_len = min((unsigned int)len - pos,
+ falcon_spi_write_limit(spi, start + pos));
+ command = efx_spi_munge_command(spi, SPI_WRITE, start + pos);
+ rc = falcon_spi_cmd(spi, command, start + pos,
+ buffer + pos, NULL, block_len);
+ if (rc)
+ break;
+
+ rc = falcon_spi_fast_wait(spi);
+ if (rc)
+ break;
+
+ command = efx_spi_munge_command(spi, SPI_READ, start + pos);
+ rc = falcon_spi_cmd(spi, command, start + pos,
+ NULL, verify_buffer, block_len);
+ if (memcmp(verify_buffer, buffer + pos, block_len)) {
+ rc = -EIO;
+ break;
+ }
+
+ pos += block_len;
+
+ /* Avoid locking up the system */
+ cond_resched();
+ if (signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ }
+
+ if (retlen)
+ *retlen = pos;
+ return rc;
+}
+
/**************************************************************************
*
* MAC wrapper
@@ -1812,7 +1867,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
{
efx_oword_t reg;
int link_speed;
- unsigned int tx_fc;
+ bool tx_fc;
if (efx->link_options & GM_LPA_10000)
link_speed = 0x3;
@@ -1847,7 +1902,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
/* Transmission of pause frames when RX crosses the threshold is
* covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL.
* Action on receipt of pause frames is controller by XM_DIS_FCNTL */
- tx_fc = (efx->flow_control & EFX_FC_TX) ? 1 : 0;
+ tx_fc = !!(efx->flow_control & EFX_FC_TX);
falcon_read(efx, ®, RX_CFG_REG_KER);
EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc);
@@ -1951,7 +2006,7 @@ static int falcon_gmii_wait(struct efx_nic *efx)
static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
int addr, int value)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
@@ -2019,7 +2074,7 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
* could be read, -1 will be returned. */
static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
{
- struct efx_nic *efx = net_dev->priv;
+ struct efx_nic *efx = netdev_priv(net_dev);
unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
efx_oword_t reg;
int value = -1;
@@ -2120,7 +2175,7 @@ int falcon_probe_port(struct efx_nic *efx)
return rc;
/* Set up GMII structure for PHY */
- efx->mii.supports_gmii = 1;
+ efx->mii.supports_gmii = true;
falcon_init_mdio(&efx->mii);
/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
@@ -2168,6 +2223,170 @@ void falcon_set_multicast_hash(struct efx_nic *efx)
falcon_write(efx, &mc_hash->oword[1], MAC_MCAST_HASH_REG1_KER);
}
+
+/**************************************************************************
+ *
+ * Falcon test code
+ *
+ **************************************************************************/
+
+int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
+{
+ struct falcon_nvconfig *nvconfig;
+ struct efx_spi_device *spi;
+ void *region;
+ int rc, magic_num, struct_ver;
+ __le16 *word, *limit;
+ u32 csum;
+
+ region = kmalloc(NVCONFIG_END, GFP_KERNEL);
+ if (!region)
+ return -ENOMEM;
+ nvconfig = region + NVCONFIG_OFFSET;
+
+ spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom;
+ rc = falcon_spi_read(spi, 0, NVCONFIG_END, NULL, region);
+ if (rc) {
+ EFX_ERR(efx, "Failed to read %s\n",
+ efx->spi_flash ? "flash" : "EEPROM");
+ rc = -EIO;
+ goto out;
+ }
+
+ magic_num = le16_to_cpu(nvconfig->board_magic_num);
+ struct_ver = le16_to_cpu(nvconfig->board_struct_ver);
+
+ rc = -EINVAL;
+ if (magic_num != NVCONFIG_BOARD_MAGIC_NUM) {
+ EFX_ERR(efx, "NVRAM bad magic 0x%x\n", magic_num);
+ goto out;
+ }
+ if (struct_ver < 2) {
+ EFX_ERR(efx, "NVRAM has ancient version 0x%x\n", struct_ver);
+ goto out;
+ } else if (struct_ver < 4) {
+ word = &nvconfig->board_magic_num;
+ limit = (__le16 *) (nvconfig + 1);
+ } else {
+ word = region;
+ limit = region + NVCONFIG_END;
+ }
+ for (csum = 0; word < limit; ++word)
+ csum += le16_to_cpu(*word);
+
+ if (~csum & 0xffff) {
+ EFX_ERR(efx, "NVRAM has incorrect checksum\n");
+ goto out;
+ }
+
+ rc = 0;
+ if (nvconfig_out)
+ memcpy(nvconfig_out, nvconfig, sizeof(*nvconfig));
+
+ out:
+ kfree(region);
+ return rc;
+}
+
+/* Registers tested in the falcon register test */
+static struct {
+ unsigned address;
+ efx_oword_t mask;
+} efx_test_registers[] = {
+ { ADR_REGION_REG_KER,
+ EFX_OWORD32(0x0001FFFF, 0x0001FFFF, 0x0001FFFF, 0x0001FFFF) },
+ { RX_CFG_REG_KER,
+ EFX_OWORD32(0xFFFFFFFE, 0x00017FFF, 0x00000000, 0x00000000) },
+ { TX_CFG_REG_KER,
+ EFX_OWORD32(0x7FFF0037, 0x00000000, 0x00000000, 0x00000000) },
+ { TX_CFG2_REG_KER,
+ EFX_OWORD32(0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF) },
+ { MAC0_CTRL_REG_KER,
+ EFX_OWORD32(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000) },
+ { SRM_TX_DC_CFG_REG_KER,
+ EFX_OWORD32(0x001FFFFF, 0x00000000, 0x00000000, 0x00000000) },
+ { RX_DC_CFG_REG_KER,
+ EFX_OWORD32(0x0000000F, 0x00000000, 0x00000000, 0x00000000) },
+ { RX_DC_PF_WM_REG_KER,
+ EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) },
+ { DP_CTRL_REG,
+ EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_GLB_CFG_REG,
+ EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_TX_CFG_REG,
+ EFX_OWORD32(0x00080164, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_RX_CFG_REG,
+ EFX_OWORD32(0x07100A0C, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_RX_PARAM_REG,
+ EFX_OWORD32(0x00001FF8, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_FC_REG,
+ EFX_OWORD32(0xFFFF0001, 0x00000000, 0x00000000, 0x00000000) },
+ { XM_ADR_LO_REG,
+ EFX_OWORD32(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000) },
+ { XX_SD_CTL_REG,
+ EFX_OWORD32(0x0003FF0F, 0x00000000, 0x00000000, 0x00000000) },
+};
+
+static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b,
+ const efx_oword_t *mask)
+{
+ return ((a->u64[0] ^ b->u64[0]) & mask->u64[0]) ||
+ ((a->u64[1] ^ b->u64[1]) & mask->u64[1]);
+}
+
+int falcon_test_registers(struct efx_nic *efx)
+{
+ unsigned address = 0, i, j;
+ efx_oword_t mask, imask, original, reg, buf;
+
+ /* Falcon should be in loopback to isolate the XMAC from the PHY */
+ WARN_ON(!LOOPBACK_INTERNAL(efx));
+
+ for (i = 0; i < ARRAY_SIZE(efx_test_registers); ++i) {
+ address = efx_test_registers[i].address;
+ mask = imask = efx_test_registers[i].mask;
+ EFX_INVERT_OWORD(imask);
+
+ falcon_read(efx, &original, address);
+
+ /* bit sweep on and off */
+ for (j = 0; j < 128; j++) {
+ if (!EFX_EXTRACT_OWORD32(mask, j, j))
+ continue;
+
+ /* Test this testable bit can be set in isolation */
+ EFX_AND_OWORD(reg, original, mask);
+ EFX_SET_OWORD32(reg, j, j, 1);
+
+ falcon_write(efx, ®, address);
+ falcon_read(efx, &buf, address);
+
+ if (efx_masked_compare_oword(®, &buf, &mask))
+ goto fail;
+
+ /* Test this testable bit can be cleared in isolation */
+ EFX_OR_OWORD(reg, original, mask);
+ EFX_SET_OWORD32(reg, j, j, 0);
+
+ falcon_write(efx, ®, address);
+ falcon_read(efx, &buf, address);
+
+ if (efx_masked_compare_oword(®, &buf, &mask))
+ goto fail;
+ }
+
+ falcon_write(efx, &original, address);
+ }
+
+ return 0;
+
+fail:
+ EFX_ERR(efx, "wrote "EFX_OWORD_FMT" read "EFX_OWORD_FMT
+ " at address 0x%x mask "EFX_OWORD_FMT"\n", EFX_OWORD_VAL(reg),
+ EFX_OWORD_VAL(buf), address, EFX_OWORD_VAL(mask));
+ return -EIO;
+}
+
/**************************************************************************
*
* Device reset
@@ -2305,68 +2524,103 @@ static int falcon_reset_sram(struct efx_nic *efx)
return -ETIMEDOUT;
}
+static int falcon_spi_device_init(struct efx_nic *efx,
+ struct efx_spi_device **spi_device_ret,
+ unsigned int device_id, u32 device_type)
+{
+ struct efx_spi_device *spi_device;
+
+ if (device_type != 0) {
+ spi_device = kmalloc(sizeof(*spi_device), GFP_KERNEL);
+ if (!spi_device)
+ return -ENOMEM;
+ spi_device->device_id = device_id;
+ spi_device->size =
+ 1 << SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_SIZE);
+ spi_device->addr_len =
+ SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ADDR_LEN);
+ spi_device->munge_address = (spi_device->size == 1 << 9 &&
+ spi_device->addr_len == 1);
+ spi_device->block_size =
+ 1 << SPI_DEV_TYPE_FIELD(device_type,
+ SPI_DEV_TYPE_BLOCK_SIZE);
+
+ spi_device->efx = efx;
+ } else {
+ spi_device = NULL;
+ }
+
+ kfree(*spi_device_ret);
+ *spi_device_ret = spi_device;
+ return 0;
+}
+
+
+static void falcon_remove_spi_devices(struct efx_nic *efx)
+{
+ kfree(efx->spi_eeprom);
+ efx->spi_eeprom = NULL;
+ kfree(efx->spi_flash);
+ efx->spi_flash = NULL;
+}
+
/* Extract non-volatile configuration */
static int falcon_probe_nvconfig(struct efx_nic *efx)
{
struct falcon_nvconfig *nvconfig;
- efx_oword_t nic_stat;
- int device_id;
- unsigned addr_len;
- size_t offset, len;
- int magic_num, struct_ver, board_rev;
+ int board_rev;
int rc;
- /* Find the boot device. */
- falcon_read(efx, &nic_stat, NIC_STAT_REG);
- if (EFX_OWORD_FIELD(nic_stat, SF_PRST)) {
- device_id = EE_SPI_FLASH;
- addr_len = 3;
- } else if (EFX_OWORD_FIELD(nic_stat, EE_PRST)) {
- device_id = EE_SPI_EEPROM;
- addr_len = 2;
- } else {
- return -ENODEV;
- }
-
nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL);
+ if (!nvconfig)
+ return -ENOMEM;
- /* Read the whole configuration structure into memory. */
- for (offset = 0; offset < sizeof(*nvconfig); offset += len) {
- len = min(sizeof(*nvconfig) - offset,
- (size_t) FALCON_SPI_MAX_LEN);
- rc = falcon_spi_read(efx, device_id, SPI_READ,
- NVCONFIG_BASE + offset, addr_len,
- (char *)nvconfig + offset, len);
- if (rc)
- goto out;
- }
-
- /* Read the MAC addresses */
- memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
-
- /* Read the board configuration. */
- magic_num = le16_to_cpu(nvconfig->board_magic_num);
- struct_ver = le16_to_cpu(nvconfig->board_struct_ver);
-
- if (magic_num != NVCONFIG_BOARD_MAGIC_NUM || struct_ver < 2) {
- EFX_ERR(efx, "Non volatile memory bad magic=%x ver=%x "
- "therefore using defaults\n", magic_num, struct_ver);
+ rc = falcon_read_nvram(efx, nvconfig);
+ if (rc == -EINVAL) {
+ EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
efx->phy_type = PHY_TYPE_NONE;
efx->mii.phy_id = PHY_ADDR_INVALID;
board_rev = 0;
+ rc = 0;
+ } else if (rc) {
+ goto fail1;
} else {
struct falcon_nvconfig_board_v2 *v2 = &nvconfig->board_v2;
+ struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
efx->phy_type = v2->port0_phy_type;
efx->mii.phy_id = v2->port0_phy_addr;
board_rev = le16_to_cpu(v2->board_revision);
+
+ if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
+ __le32 fl = v3->spi_device_type[EE_SPI_FLASH];
+ __le32 ee = v3->spi_device_type[EE_SPI_EEPROM];
+ rc = falcon_spi_device_init(efx, &efx->spi_flash,
+ EE_SPI_FLASH,
+ le32_to_cpu(fl));
+ if (rc)
+ goto fail2;
+ rc = falcon_spi_device_init(efx, &efx->spi_eeprom,
+ EE_SPI_EEPROM,
+ le32_to_cpu(ee));
+ if (rc)
+ goto fail2;
+ }
}
+ /* Read the MAC addresses */
+ memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
+
EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
efx_set_board_info(efx, board_rev);
- out:
+ kfree(nvconfig);
+ return 0;
+
+ fail2:
+ falcon_remove_spi_devices(efx);
+ fail1:
kfree(nvconfig);
return rc;
}
@@ -2417,6 +2671,86 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
return 0;
}
+/* Probe all SPI devices on the NIC */
+static void falcon_probe_spi_devices(struct efx_nic *efx)
+{
+ efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg;
+ bool has_flash, has_eeprom, boot_is_external;
+
+ falcon_read(efx, &gpio_ctl, GPIO_CTL_REG_KER);
+ falcon_read(efx, &nic_stat, NIC_STAT_REG);
+ falcon_read(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER);
+
+ has_flash = EFX_OWORD_FIELD(nic_stat, SF_PRST);
+ has_eeprom = EFX_OWORD_FIELD(nic_stat, EE_PRST);
+ boot_is_external = EFX_OWORD_FIELD(gpio_ctl, BOOTED_USING_NVDEVICE);
+
+ if (has_flash) {
+ /* Default flash SPI device: Atmel AT25F1024
+ * 128 KB, 24-bit address, 32 KB erase block,
+ * 256 B write block
+ */
+ u32 flash_device_type =
+ (17 << SPI_DEV_TYPE_SIZE_LBN)
+ | (3 << SPI_DEV_TYPE_ADDR_LEN_LBN)
+ | (0x52 << SPI_DEV_TYPE_ERASE_CMD_LBN)
+ | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN)
+ | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN);
+
+ falcon_spi_device_init(efx, &efx->spi_flash,
+ EE_SPI_FLASH, flash_device_type);
+
+ if (!boot_is_external) {
+ /* Disable VPD and set clock dividers to safe
+ * values for initial programming.
+ */
+ EFX_LOG(efx, "Booted from internal ASIC settings;"
+ " setting SPI config\n");
+ EFX_POPULATE_OWORD_3(ee_vpd_cfg, EE_VPD_EN, 0,
+ /* 125 MHz / 7 ~= 20 MHz */
+ EE_SF_CLOCK_DIV, 7,
+ /* 125 MHz / 63 ~= 2 MHz */
+ EE_EE_CLOCK_DIV, 63);
+ falcon_write(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER);
+ }
+ }
+
+ if (has_eeprom) {
+ u32 eeprom_device_type;
+
+ /* If it has no flash, it must have a large EEPROM
+ * for chip config; otherwise check whether 9-bit
+ * addressing is used for VPD configuration
+ */
+ if (has_flash &&
+ (!boot_is_external ||
+ EFX_OWORD_FIELD(ee_vpd_cfg, EE_VPD_EN_AD9_MODE))) {
+ /* Default SPI device: Atmel AT25040 or similar
+ * 512 B, 9-bit address, 8 B write block
+ */
+ eeprom_device_type =
+ (9 << SPI_DEV_TYPE_SIZE_LBN)
+ | (1 << SPI_DEV_TYPE_ADDR_LEN_LBN)
+ | (3 << SPI_DEV_TYPE_BLOCK_SIZE_LBN);
+ } else {
+ /* "Large" SPI device: Atmel AT25640 or similar
+ * 8 KB, 16-bit address, 32 B write block
+ */
+ eeprom_device_type =
+ (13 << SPI_DEV_TYPE_SIZE_LBN)
+ | (2 << SPI_DEV_TYPE_ADDR_LEN_LBN)
+ | (5 << SPI_DEV_TYPE_BLOCK_SIZE_LBN);
+ }
+
+ falcon_spi_device_init(efx, &efx->spi_eeprom,
+ EE_SPI_EEPROM, eeprom_device_type);
+ }
+
+ EFX_LOG(efx, "flash is %s, EEPROM is %s\n",
+ (has_flash ? "present" : "absent"),
+ (has_eeprom ? "present" : "absent"));
+}
+
int falcon_probe_nic(struct efx_nic *efx)
{
struct falcon_nic_data *nic_data;
@@ -2467,6 +2801,8 @@ int falcon_probe_nic(struct efx_nic *efx)
(unsigned long long)efx->irq_status.dma_addr,
efx->irq_status.addr, virt_to_phys(efx->irq_status.addr));
+ falcon_probe_spi_devices(efx);
+
/* Read in the non-volatile configuration */
rc = falcon_probe_nvconfig(efx);
if (rc)
@@ -2486,6 +2822,7 @@ int falcon_probe_nic(struct efx_nic *efx)
return 0;
fail5:
+ falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
fail4:
fail3:
@@ -2573,19 +2910,14 @@ int falcon_init_nic(struct efx_nic *efx)
EFX_INVERT_OWORD(temp);
falcon_write(efx, &temp, FATAL_INTR_REG_KER);
- /* Set number of RSS queues for receive path. */
- falcon_read(efx, &temp, RX_FILTER_CTL_REG);
- if (falcon_rev(efx) >= FALCON_REV_B0)
- EFX_SET_OWORD_FIELD(temp, NUM_KER, 0);
- else
- EFX_SET_OWORD_FIELD(temp, NUM_KER, efx->rss_queues - 1);
if (EFX_WORKAROUND_7244(efx)) {
+ falcon_read(efx, &temp, RX_FILTER_CTL_REG);
EFX_SET_OWORD_FIELD(temp, UDP_FULL_SRCH_LIMIT, 8);
EFX_SET_OWORD_FIELD(temp, UDP_WILD_SRCH_LIMIT, 8);
EFX_SET_OWORD_FIELD(temp, TCP_FULL_SRCH_LIMIT, 8);
EFX_SET_OWORD_FIELD(temp, TCP_WILD_SRCH_LIMIT, 8);
+ falcon_write(efx, &temp, RX_FILTER_CTL_REG);
}
- falcon_write(efx, &temp, RX_FILTER_CTL_REG);
falcon_setup_rss_indir_table(efx);
@@ -2641,8 +2973,8 @@ int falcon_init_nic(struct efx_nic *efx)
rx_xoff_thresh_bytes : efx->type->rx_xoff_thresh);
EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_MAC_TH, thresh / 256);
/* RX control FIFO thresholds [32 entries] */
- EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 25);
- EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 20);
+ EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XON_TX_TH, 20);
+ EFX_SET_OWORD_FIELD_VER(efx, temp, RX_XOFF_TX_TH, 25);
falcon_write(efx, &temp, RX_CFG_REG_KER);
/* Set destination of both TX and RX Flush events */
@@ -2662,6 +2994,7 @@ void falcon_remove_nic(struct efx_nic *efx)
rc = i2c_del_adapter(&efx->i2c_adap);
BUG_ON(rc);
+ falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
falcon_reset_hw(efx, RESET_TYPE_ALL);
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 492f9bc..30d61e4 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -40,24 +40,24 @@ extern struct efx_nic_type falcon_b_nic_type;
/* TX data path */
extern int falcon_probe_tx(struct efx_tx_queue *tx_queue);
-extern int falcon_init_tx(struct efx_tx_queue *tx_queue);
+extern void falcon_init_tx(struct efx_tx_queue *tx_queue);
extern void falcon_fini_tx(struct efx_tx_queue *tx_queue);
extern void falcon_remove_tx(struct efx_tx_queue *tx_queue);
extern void falcon_push_buffers(struct efx_tx_queue *tx_queue);
/* RX data path */
extern int falcon_probe_rx(struct efx_rx_queue *rx_queue);
-extern int falcon_init_rx(struct efx_rx_queue *rx_queue);
+extern void falcon_init_rx(struct efx_rx_queue *rx_queue);
extern void falcon_fini_rx(struct efx_rx_queue *rx_queue);
extern void falcon_remove_rx(struct efx_rx_queue *rx_queue);
extern void falcon_notify_rx_desc(struct efx_rx_queue *rx_queue);
/* Event data path */
extern int falcon_probe_eventq(struct efx_channel *channel);
-extern int falcon_init_eventq(struct efx_channel *channel);
+extern void falcon_init_eventq(struct efx_channel *channel);
extern void falcon_fini_eventq(struct efx_channel *channel);
extern void falcon_remove_eventq(struct efx_channel *channel);
-extern int falcon_process_eventq(struct efx_channel *channel, int *rx_quota);
+extern int falcon_process_eventq(struct efx_channel *channel, int rx_quota);
extern void falcon_eventq_read_ack(struct efx_channel *channel);
/* Ports */
@@ -65,7 +65,7 @@ extern int falcon_probe_port(struct efx_nic *efx);
extern void falcon_remove_port(struct efx_nic *efx);
/* MAC/PHY */
-extern int falcon_xaui_link_ok(struct efx_nic *efx);
+extern bool falcon_xaui_link_ok(struct efx_nic *efx);
extern int falcon_dma_stats(struct efx_nic *efx,
unsigned int done_offset);
extern void falcon_drain_tx_fifo(struct efx_nic *efx);
@@ -93,6 +93,12 @@ extern void falcon_update_nic_stats(struct efx_nic *efx);
extern void falcon_set_multicast_hash(struct efx_nic *efx);
extern int falcon_reset_xaui(struct efx_nic *efx);
+/* Tests */
+struct falcon_nvconfig;
+extern int falcon_read_nvram(struct efx_nic *efx,
+ struct falcon_nvconfig *nvconfig);
+extern int falcon_test_registers(struct efx_nic *efx);
+
/**************************************************************************
*
* Falcon MAC stats
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 6d00311..e319fd6 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -92,6 +92,17 @@
/* SPI host data register */
#define EE_SPI_HDATA_REG_KER 0x0120
+/* SPI/VPD config register */
+#define EE_VPD_CFG_REG_KER 0x0140
+#define EE_VPD_EN_LBN 0
+#define EE_VPD_EN_WIDTH 1
+#define EE_VPD_EN_AD9_MODE_LBN 1
+#define EE_VPD_EN_AD9_MODE_WIDTH 1
+#define EE_EE_CLOCK_DIV_LBN 112
+#define EE_EE_CLOCK_DIV_WIDTH 7
+#define EE_SF_CLOCK_DIV_LBN 120
+#define EE_SF_CLOCK_DIV_WIDTH 7
+
/* PCIE CORE ACCESS REG */
#define PCIE_CORE_ADDR_PCIE_DEVICE_CTRL_STAT 0x68
#define PCIE_CORE_ADDR_PCIE_LINK_CTRL_STAT 0x70
@@ -115,6 +126,9 @@
#define STRAP_PCIE_LBN 0
#define STRAP_PCIE_WIDTH 1
+#define BOOTED_USING_NVDEVICE_LBN 3
+#define BOOTED_USING_NVDEVICE_WIDTH 1
+
/* GPIO control register */
#define GPIO_CTL_REG_KER 0x0210
#define GPIO_OUTPUTS_LBN (16)
@@ -479,18 +493,8 @@
#define MAC_MCAST_HASH_REG0_KER 0xca0
#define MAC_MCAST_HASH_REG1_KER 0xcb0
-/* GMAC registers */
-#define FALCON_GMAC_REGBANK 0xe00
-#define FALCON_GMAC_REGBANK_SIZE 0x200
-#define FALCON_GMAC_REG_SIZE 0x10
-
-/* XMAC registers */
-#define FALCON_XMAC_REGBANK 0x1200
-#define FALCON_XMAC_REGBANK_SIZE 0x200
-#define FALCON_XMAC_REG_SIZE 0x10
-
/* XGMAC address register low */
-#define XM_ADR_LO_REG_MAC 0x00
+#define XM_ADR_LO_REG 0x1200
#define XM_ADR_3_LBN 24
#define XM_ADR_3_WIDTH 8
#define XM_ADR_2_LBN 16
@@ -501,14 +505,14 @@
#define XM_ADR_0_WIDTH 8
/* XGMAC address register high */
-#define XM_ADR_HI_REG_MAC 0x01
+#define XM_ADR_HI_REG 0x1210
#define XM_ADR_5_LBN 8
#define XM_ADR_5_WIDTH 8
#define XM_ADR_4_LBN 0
#define XM_ADR_4_WIDTH 8
/* XGMAC global configuration */
-#define XM_GLB_CFG_REG_MAC 0x02
+#define XM_GLB_CFG_REG 0x1220
#define XM_RX_STAT_EN_LBN 11
#define XM_RX_STAT_EN_WIDTH 1
#define XM_TX_STAT_EN_LBN 10
@@ -521,7 +525,7 @@
#define XM_CORE_RST_WIDTH 1
/* XGMAC transmit configuration */
-#define XM_TX_CFG_REG_MAC 0x03
+#define XM_TX_CFG_REG 0x1230
#define XM_IPG_LBN 16
#define XM_IPG_WIDTH 4
#define XM_FCNTL_LBN 10
@@ -536,7 +540,7 @@
#define XM_TXEN_WIDTH 1
/* XGMAC receive configuration */
-#define XM_RX_CFG_REG_MAC 0x04
+#define XM_RX_CFG_REG 0x1240
#define XM_PASS_CRC_ERR_LBN 25
#define XM_PASS_CRC_ERR_WIDTH 1
#define XM_ACPT_ALL_MCAST_LBN 11
@@ -549,7 +553,7 @@
#define XM_RXEN_WIDTH 1
/* XGMAC management interrupt mask register */
-#define XM_MGT_INT_MSK_REG_MAC_B0 0x5
+#define XM_MGT_INT_MSK_REG_B0 0x1250
#define XM_MSK_PRMBLE_ERR_LBN 2
#define XM_MSK_PRMBLE_ERR_WIDTH 1
#define XM_MSK_RMTFLT_LBN 1
@@ -558,29 +562,29 @@
#define XM_MSK_LCLFLT_WIDTH 1
/* XGMAC flow control register */
-#define XM_FC_REG_MAC 0x7
+#define XM_FC_REG 0x1270
#define XM_PAUSE_TIME_LBN 16
#define XM_PAUSE_TIME_WIDTH 16
#define XM_DIS_FCNTL_LBN 0
#define XM_DIS_FCNTL_WIDTH 1
/* XGMAC pause time count register */
-#define XM_PAUSE_TIME_REG_MAC 0x9
+#define XM_PAUSE_TIME_REG 0x1290
/* XGMAC transmit parameter register */
-#define XM_TX_PARAM_REG_MAC 0x0d
+#define XM_TX_PARAM_REG 0x012d0
#define XM_TX_JUMBO_MODE_LBN 31
#define XM_TX_JUMBO_MODE_WIDTH 1
#define XM_MAX_TX_FRM_SIZE_LBN 16
#define XM_MAX_TX_FRM_SIZE_WIDTH 14
/* XGMAC receive parameter register */
-#define XM_RX_PARAM_REG_MAC 0x0e
+#define XM_RX_PARAM_REG 0x12e0
#define XM_MAX_RX_FRM_SIZE_LBN 0
#define XM_MAX_RX_FRM_SIZE_WIDTH 14
/* XGMAC management interrupt status register */
-#define XM_MGT_INT_REG_MAC_B0 0x0f
+#define XM_MGT_INT_REG_B0 0x12f0
#define XM_PRMBLE_ERR 2
#define XM_PRMBLE_WIDTH 1
#define XM_RMTFLT_LBN 1
@@ -589,7 +593,7 @@
#define XM_LCLFLT_WIDTH 1
/* XGXS/XAUI powerdown/reset register */
-#define XX_PWR_RST_REG_MAC 0x10
+#define XX_PWR_RST_REG 0x1300
#define XX_PWRDND_EN_LBN 15
#define XX_PWRDND_EN_WIDTH 1
@@ -619,7 +623,7 @@
#define XX_RST_XX_EN_WIDTH 1
/* XGXS/XAUI powerdown/reset control register */
-#define XX_SD_CTL_REG_MAC 0x11
+#define XX_SD_CTL_REG 0x1310
#define XX_HIDRVD_LBN 15
#define XX_HIDRVD_WIDTH 1
#define XX_LODRVD_LBN 14
@@ -645,7 +649,7 @@
#define XX_LPBKA_LBN 0
#define XX_LPBKA_WIDTH 1
-#define XX_TXDRV_CTL_REG_MAC 0x12
+#define XX_TXDRV_CTL_REG 0x1320
#define XX_DEQD_LBN 28
#define XX_DEQD_WIDTH 4
#define XX_DEQC_LBN 24
@@ -664,7 +668,7 @@
#define XX_DTXA_WIDTH 4
/* XAUI XGXS core status register */
-#define XX_CORE_STAT_REG_MAC 0x16
+#define XX_CORE_STAT_REG 0x1360
#define XX_FORCE_SIG_LBN 24
#define XX_FORCE_SIG_WIDTH 8
#define XX_FORCE_SIG_DECODE_FORCED 0xff
@@ -1127,7 +1131,28 @@ struct falcon_nvconfig_board_v2 {
__le16 board_revision;
} __packed;
-#define NVCONFIG_BASE 0x300
+/* Board configuration v3 extra information */
+struct falcon_nvconfig_board_v3 {
+ __le32 spi_device_type[2];
+} __packed;
+
+/* Bit numbers for spi_device_type */
+#define SPI_DEV_TYPE_SIZE_LBN 0
+#define SPI_DEV_TYPE_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_ADDR_LEN_LBN 6
+#define SPI_DEV_TYPE_ADDR_LEN_WIDTH 2
+#define SPI_DEV_TYPE_ERASE_CMD_LBN 8
+#define SPI_DEV_TYPE_ERASE_CMD_WIDTH 8
+#define SPI_DEV_TYPE_ERASE_SIZE_LBN 16
+#define SPI_DEV_TYPE_ERASE_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_BLOCK_SIZE_LBN 24
+#define SPI_DEV_TYPE_BLOCK_SIZE_WIDTH 5
+#define SPI_DEV_TYPE_FIELD(type, field) \
+ (((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field)))
+
+#define NVCONFIG_OFFSET 0x300
+#define NVCONFIG_END 0x400
+
#define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C
struct falcon_nvconfig {
efx_oword_t ee_vpd_cfg_reg; /* 0x300 */
@@ -1144,6 +1169,8 @@ struct falcon_nvconfig {
__le16 board_struct_ver;
__le16 board_checksum;
struct falcon_nvconfig_board_v2 board_v2;
+ efx_oword_t ee_base_page_reg; /* 0x3B0 */
+ struct falcon_nvconfig_board_v3 board_v3;
} __packed;
#endif /* EFX_FALCON_HWDEFS_H */
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 55c0d97..0d9f68f 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -23,56 +23,24 @@
/**************************************************************************
*
- * MAC register access
- *
- **************************************************************************/
-
-/* Offset of an XMAC register within Falcon */
-#define FALCON_XMAC_REG(mac_reg) \
- (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))
-
-void falcon_xmac_writel(struct efx_nic *efx,
- efx_dword_t *value, unsigned int mac_reg)
-{
- efx_oword_t temp;
-
- EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA));
- falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg));
-}
-
-void falcon_xmac_readl(struct efx_nic *efx,
- efx_dword_t *value, unsigned int mac_reg)
-{
- efx_oword_t temp;
-
- falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg));
- EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA));
-}
-
-/**************************************************************************
- *
* MAC operations
*
*************************************************************************/
static int falcon_reset_xmac(struct efx_nic *efx)
{
- efx_dword_t reg;
+ efx_oword_t reg;
int count;
- EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1);
- falcon_xmac_writel(efx, ®, XM_GLB_CFG_REG_MAC);
+ EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
+ falcon_write(efx, ®, XM_GLB_CFG_REG);
for (count = 0; count < 10000; count++) { /* wait upto 100ms */
- falcon_xmac_readl(efx, ®, XM_GLB_CFG_REG_MAC);
- if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0)
+ falcon_read(efx, ®, XM_GLB_CFG_REG);
+ if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
return 0;
udelay(10);
}
- /* This often fails when DSP is disabled, ignore it */
- if (sfe4001_phy_flash_cfg != 0)
- return 0;
-
EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
return -ETIMEDOUT;
}
@@ -80,25 +48,25 @@ static int falcon_reset_xmac(struct efx_nic *efx)
/* Configure the XAUI driver that is an output from Falcon */
static void falcon_setup_xaui(struct efx_nic *efx)
{
- efx_dword_t sdctl, txdrv;
+ efx_oword_t sdctl, txdrv;
/* Move the XAUI into low power, unless there is no PHY, in
* which case the XAUI will have to drive a cable. */
if (efx->phy_type == PHY_TYPE_NONE)
return;
- falcon_xmac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC);
- EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
- EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
- falcon_xmac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC);
-
- EFX_POPULATE_DWORD_8(txdrv,
+ falcon_read(efx, &sdctl, XX_SD_CTL_REG);
+ EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
+ EFX_SET_OWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
+ falcon_write(efx, &sdctl, XX_SD_CTL_REG);
+
+ EFX_POPULATE_OWORD_8(txdrv,
XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
@@ -107,67 +75,67 @@ static void falcon_setup_xaui(struct efx_nic *efx)
XX_DTXC, XX_TXDRV_DTX_DEFAULT,
XX_DTXB, XX_TXDRV_DTX_DEFAULT,
XX_DTXA, XX_TXDRV_DTX_DEFAULT);
- falcon_xmac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC);
+ falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
}
static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
{
- efx_dword_t reg;
-
- EFX_ZERO_DWORD(reg);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ efx_oword_t reg;
+
+ EFX_ZERO_OWORD(reg);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
}
static int _falcon_reset_xaui_a(struct efx_nic *efx)
{
- efx_dword_t reg;
+ efx_oword_t reg;
falcon_hold_xaui_in_rst(efx);
- falcon_xmac_readl(efx, ®, XX_PWR_RST_REG_MAC);
+ falcon_read(efx, ®, XX_PWR_RST_REG);
/* Follow the RAMBUS XAUI data reset sequencing
* Channels A and B first: power down, reset PLL, reset, clear
*/
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 0);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
- EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
- EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0);
- EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 0);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
/* Channels C and D: power down, reset PLL, reset, clear */
- EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0);
- EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 0);
+ EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
- EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
- EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0);
- EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 0);
+ EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 0);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
/* Setup XAUI */
@@ -175,8 +143,8 @@ static int _falcon_reset_xaui_a(struct efx_nic *efx)
udelay(10);
/* Take XGXS out of reset */
- EFX_ZERO_DWORD(reg);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ EFX_ZERO_OWORD(reg);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
return 0;
@@ -184,16 +152,16 @@ static int _falcon_reset_xaui_a(struct efx_nic *efx)
static int _falcon_reset_xaui_b(struct efx_nic *efx)
{
- efx_dword_t reg;
+ efx_oword_t reg;
int count;
EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
/* Give some time for the link to establish */
for (count = 0; count < 1000; count++) { /* wait upto 10ms */
- falcon_xmac_readl(efx, ®, XX_PWR_RST_REG_MAC);
- if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
+ falcon_read(efx, ®, XX_PWR_RST_REG);
+ if (EFX_OWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
falcon_setup_xaui(efx);
return 0;
}
@@ -217,41 +185,41 @@ int falcon_reset_xaui(struct efx_nic *efx)
return rc;
}
-static int falcon_xgmii_status(struct efx_nic *efx)
+static bool falcon_xgmii_status(struct efx_nic *efx)
{
- efx_dword_t reg;
+ efx_oword_t reg;
if (falcon_rev(efx) < FALCON_REV_B0)
- return 1;
+ return true;
/* The ISR latches, so clear it and re-read */
- falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0);
- falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0);
+ falcon_read(efx, ®, XM_MGT_INT_REG_B0);
+ falcon_read(efx, ®, XM_MGT_INT_REG_B0);
- if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
- EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
+ if (EFX_OWORD_FIELD(reg, XM_LCLFLT) ||
+ EFX_OWORD_FIELD(reg, XM_RMTFLT)) {
EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
+static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
{
- efx_dword_t reg;
+ efx_oword_t reg;
if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
return;
/* Flush the ISR */
if (enable)
- falcon_xmac_readl(efx, ®, XM_MGT_INT_REG_MAC_B0);
+ falcon_read(efx, ®, XM_MGT_INT_REG_B0);
- EFX_POPULATE_DWORD_2(reg,
+ EFX_POPULATE_OWORD_2(reg,
XM_MSK_RMTFLT, !enable,
XM_MSK_LCLFLT, !enable);
- falcon_xmac_writel(efx, ®, XM_MGT_INT_MSK_REG_MAC_B0);
+ falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0);
}
int falcon_init_xmac(struct efx_nic *efx)
@@ -274,7 +242,7 @@ int falcon_init_xmac(struct efx_nic *efx)
if (rc)
goto fail2;
- falcon_mask_status_intr(efx, 1);
+ falcon_mask_status_intr(efx, true);
return 0;
fail2:
@@ -283,34 +251,34 @@ int falcon_init_xmac(struct efx_nic *efx)
return rc;
}
-int falcon_xaui_link_ok(struct efx_nic *efx)
+bool falcon_xaui_link_ok(struct efx_nic *efx)
{
- efx_dword_t reg;
- int align_done, sync_status, link_ok = 0;
+ efx_oword_t reg;
+ bool align_done, link_ok = false;
+ int sync_status;
if (LOOPBACK_INTERNAL(efx))
- return 1;
+ return true;
/* Read link status */
- falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC);
+ falcon_read(efx, ®, XX_CORE_STAT_REG);
- align_done = EFX_DWORD_FIELD(reg, XX_ALIGN_DONE);
- sync_status = EFX_DWORD_FIELD(reg, XX_SYNC_STAT);
+ align_done = EFX_OWORD_FIELD(reg, XX_ALIGN_DONE);
+ sync_status = EFX_OWORD_FIELD(reg, XX_SYNC_STAT);
if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED))
- link_ok = 1;
+ link_ok = true;
/* Clear link status ready for next read */
- EFX_SET_DWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
- EFX_SET_DWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
- EFX_SET_DWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
- falcon_xmac_writel(efx, ®, XX_CORE_STAT_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
+ EFX_SET_OWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
+ EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
+ falcon_write(efx, ®, XX_CORE_STAT_REG);
/* If the link is up, then check the phy side of the xaui link
* (error conditions from the wire side propoagate back through
* the phy to the xaui side). */
if (efx->link_up && link_ok) {
- int has_phyxs = efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS);
- if (has_phyxs)
+ if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
}
@@ -325,15 +293,15 @@ int falcon_xaui_link_ok(struct efx_nic *efx)
static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
{
unsigned int max_frame_len;
- efx_dword_t reg;
- int rx_fc = (efx->flow_control & EFX_FC_RX) ? 1 : 0;
+ efx_oword_t reg;
+ bool rx_fc = !!(efx->flow_control & EFX_FC_RX);
/* Configure MAC - cut-thru mode is hard wired on */
EFX_POPULATE_DWORD_3(reg,
XM_RX_JUMBO_MODE, 1,
XM_TX_STAT_EN, 1,
XM_RX_STAT_EN, 1);
- falcon_xmac_writel(efx, ®, XM_GLB_CFG_REG_MAC);
+ falcon_write(efx, ®, XM_GLB_CFG_REG);
/* Configure TX */
EFX_POPULATE_DWORD_6(reg,
@@ -343,7 +311,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
XM_TXCRC, 1,
XM_FCNTL, 1,
XM_IPG, 0x3);
- falcon_xmac_writel(efx, ®, XM_TX_CFG_REG_MAC);
+ falcon_write(efx, ®, XM_TX_CFG_REG);
/* Configure RX */
EFX_POPULATE_DWORD_5(reg,
@@ -352,21 +320,21 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
XM_ACPT_ALL_MCAST, 1,
XM_ACPT_ALL_UCAST, efx->promiscuous,
XM_PASS_CRC_ERR, 1);
- falcon_xmac_writel(efx, ®, XM_RX_CFG_REG_MAC);
+ falcon_write(efx, ®, XM_RX_CFG_REG);
/* Set frame length */
max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
EFX_POPULATE_DWORD_1(reg, XM_MAX_RX_FRM_SIZE, max_frame_len);
- falcon_xmac_writel(efx, ®, XM_RX_PARAM_REG_MAC);
+ falcon_write(efx, ®, XM_RX_PARAM_REG);
EFX_POPULATE_DWORD_2(reg,
XM_MAX_TX_FRM_SIZE, max_frame_len,
XM_TX_JUMBO_MODE, 1);
- falcon_xmac_writel(efx, ®, XM_TX_PARAM_REG_MAC);
+ falcon_write(efx, ®, XM_TX_PARAM_REG);
EFX_POPULATE_DWORD_2(reg,
XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
- XM_DIS_FCNTL, rx_fc ? 0 : 1);
- falcon_xmac_writel(efx, ®, XM_FC_REG_MAC);
+ XM_DIS_FCNTL, !rx_fc);
+ falcon_write(efx, ®, XM_FC_REG);
/* Set MAC address */
EFX_POPULATE_DWORD_4(reg,
@@ -374,83 +342,75 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
XM_ADR_1, efx->net_dev->dev_addr[1],
XM_ADR_2, efx->net_dev->dev_addr[2],
XM_ADR_3, efx->net_dev->dev_addr[3]);
- falcon_xmac_writel(efx, ®, XM_ADR_LO_REG_MAC);
+ falcon_write(efx, ®, XM_ADR_LO_REG);
EFX_POPULATE_DWORD_2(reg,
XM_ADR_4, efx->net_dev->dev_addr[4],
XM_ADR_5, efx->net_dev->dev_addr[5]);
- falcon_xmac_writel(efx, ®, XM_ADR_HI_REG_MAC);
+ falcon_write(efx, ®, XM_ADR_HI_REG);
}
static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
{
- efx_dword_t reg;
- int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
- int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
- int xgmii_loopback =
- (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
+ efx_oword_t reg;
+ bool xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS);
+ bool xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI);
+ bool xgmii_loopback = (efx->loopback_mode == LOOPBACK_XGMII);
/* XGXS block is flaky and will need to be reset if moving
* into our out of XGMII, XGXS or XAUI loopbacks. */
if (EFX_WORKAROUND_5147(efx)) {
- int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
- int reset_xgxs;
+ bool old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
+ bool reset_xgxs;
- falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC);
- old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
- old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
+ falcon_read(efx, ®, XX_CORE_STAT_REG);
+ old_xgxs_loopback = EFX_OWORD_FIELD(reg, XX_XGXS_LB_EN);
+ old_xgmii_loopback = EFX_OWORD_FIELD(reg, XX_XGMII_LB_EN);
- falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC);
- old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
+ falcon_read(efx, ®, XX_SD_CTL_REG);
+ old_xaui_loopback = EFX_OWORD_FIELD(reg, XX_LPBKA);
/* The PHY driver may have turned XAUI off */
reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
(xaui_loopback != old_xaui_loopback) ||
(xgmii_loopback != old_xgmii_loopback));
- if (reset_xgxs) {
- falcon_xmac_readl(efx, ®, XX_PWR_RST_REG_MAC);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
- udelay(1);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
- EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
- udelay(1);
- }
+
+ if (reset_xgxs)
+ falcon_reset_xaui(efx);
}
- falcon_xmac_readl(efx, ®, XX_CORE_STAT_REG_MAC);
- EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
+ falcon_read(efx, ®, XX_CORE_STAT_REG);
+ EFX_SET_OWORD_FIELD(reg, XX_FORCE_SIG,
(xgxs_loopback || xaui_loopback) ?
XX_FORCE_SIG_DECODE_FORCED : 0);
- EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
- EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
- falcon_xmac_writel(efx, ®, XX_CORE_STAT_REG_MAC);
-
- falcon_xmac_readl(efx, ®, XX_SD_CTL_REG_MAC);
- EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
- EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
- EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
- EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
- falcon_xmac_writel(efx, ®, XX_SD_CTL_REG_MAC);
+ EFX_SET_OWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
+ EFX_SET_OWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
+ falcon_write(efx, ®, XX_CORE_STAT_REG);
+
+ falcon_read(efx, ®, XX_SD_CTL_REG);
+ EFX_SET_OWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
+ EFX_SET_OWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
+ EFX_SET_OWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
+ EFX_SET_OWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
+ falcon_write(efx, ®, XX_SD_CTL_REG);
}
/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
* to come back up. Bash it until it comes back up */
-static int falcon_check_xaui_link_up(struct efx_nic *efx)
+static bool falcon_check_xaui_link_up(struct efx_nic *efx)
{
int max_tries, tries;
tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
max_tries = tries;
if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
- (efx->phy_type == PHY_TYPE_NONE))
- return 0;
+ (efx->phy_type == PHY_TYPE_NONE) ||
+ efx_phy_mode_disabled(efx->phy_mode))
+ return false;
while (tries) {
if (falcon_xaui_link_ok(efx))
- return 1;
+ return true;
EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n",
__func__, tries);
@@ -461,18 +421,22 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx)
EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n",
max_tries);
- return 0;
+ return false;
}
void falcon_reconfigure_xmac(struct efx_nic *efx)
{
- int xaui_link_ok;
+ bool xaui_link_ok;
- falcon_mask_status_intr(efx, 0);
+ falcon_mask_status_intr(efx, false);
falcon_deconfigure_mac_wrapper(efx);
- efx->tx_disabled = LOOPBACK_INTERNAL(efx);
+ /* Reconfigure the PHY, disabling transmit in mac level loopback. */
+ if (LOOPBACK_INTERNAL(efx))
+ efx->phy_mode |= PHY_MODE_TX_DISABLED;
+ else
+ efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
efx->phy_op->reconfigure(efx);
falcon_reconfigure_xgxs_core(efx);
@@ -484,7 +448,7 @@ void falcon_reconfigure_xmac(struct efx_nic *efx)
xaui_link_ok = falcon_check_xaui_link_up(efx);
if (xaui_link_ok && efx->link_up)
- falcon_mask_status_intr(efx, 1);
+ falcon_mask_status_intr(efx, true);
}
void falcon_fini_xmac(struct efx_nic *efx)
@@ -554,21 +518,23 @@ void falcon_update_stats_xmac(struct efx_nic *efx)
/* Update derived statistics */
mac_stats->tx_good_bytes =
- (mac_stats->tx_bytes - mac_stats->tx_bad_bytes);
+ (mac_stats->tx_bytes - mac_stats->tx_bad_bytes -
+ mac_stats->tx_control * 64);
mac_stats->rx_bad_bytes =
- (mac_stats->rx_bytes - mac_stats->rx_good_bytes);
+ (mac_stats->rx_bytes - mac_stats->rx_good_bytes -
+ mac_stats->rx_control * 64);
}
int falcon_check_xmac(struct efx_nic *efx)
{
- unsigned xaui_link_ok;
+ bool xaui_link_ok;
int rc;
if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
- (efx->phy_type == PHY_TYPE_NONE))
+ efx_phy_mode_disabled(efx->phy_mode))
return 0;
- falcon_mask_status_intr(efx, 0);
+ falcon_mask_status_intr(efx, false);
xaui_link_ok = falcon_xaui_link_ok(efx);
if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok)
@@ -579,7 +545,7 @@ int falcon_check_xmac(struct efx_nic *efx)
/* Unmask interrupt if everything was (and still is) ok */
if (xaui_link_ok && efx->link_up)
- falcon_mask_status_intr(efx, 1);
+ falcon_mask_status_intr(efx, true);
return rc;
}
@@ -620,7 +586,7 @@ int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control)
{
- int reset;
+ bool reset;
if (flow_control & EFX_FC_AUTO) {
EFX_LOG(efx, "10G does not support flow control "
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h
index edd07d4..a31571c 100644
--- a/drivers/net/sfc/mac.h
+++ b/drivers/net/sfc/mac.h
@@ -13,10 +13,6 @@
#include "net_driver.h"
-extern void falcon_xmac_writel(struct efx_nic *efx,
- efx_dword_t *value, unsigned int mac_reg);
-extern void falcon_xmac_readl(struct efx_nic *efx,
- efx_dword_t *value, unsigned int mac_reg);
extern int falcon_init_xmac(struct efx_nic *efx);
extern void falcon_reconfigure_xmac(struct efx_nic *efx);
extern void falcon_update_stats_xmac(struct efx_nic *efx);
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index c4f540e..003e48d 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -159,20 +159,21 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
return 0;
}
-int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
{
int phy_id = efx->mii.phy_id;
int status;
- int ok = 1;
+ bool ok = true;
int mmd = 0;
- int good;
/* If the port is in loopback, then we should only consider a subset
* of mmd's */
if (LOOPBACK_INTERNAL(efx))
- return 1;
+ return true;
else if (efx->loopback_mode == LOOPBACK_NETWORK)
- return 0;
+ return false;
+ else if (efx_phy_mode_disabled(efx->phy_mode))
+ return false;
else if (efx->loopback_mode == LOOPBACK_PHYXS)
mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS |
MDIO_MMDREG_DEVS0_PCS |
@@ -192,8 +193,7 @@ int mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
status = mdio_clause45_read(efx, phy_id,
mmd, MDIO_MMDREG_STAT1);
- good = status & (1 << MDIO_MMDREG_STAT1_LINK_LBN);
- ok = ok && good;
+ ok = ok && (status & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
}
mmd_mask = (mmd_mask >> 1);
mmd++;
@@ -208,7 +208,7 @@ void mdio_clause45_transmit_disable(struct efx_nic *efx)
ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
MDIO_MMDREG_TXDIS);
- if (efx->tx_disabled)
+ if (efx->phy_mode & PHY_MODE_TX_DISABLED)
ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
else
ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index cb99f3f..19c42ea 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -199,18 +199,19 @@ static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
return (id_hi << 16) | (id_low);
}
-static inline int mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
+static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
{
- int i, sync, lane_status;
+ int i, lane_status;
+ bool sync;
for (i = 0; i < 2; ++i)
lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
MDIO_MMD_PHYXS,
MDIO_PHYXS_LANE_STATE);
- sync = (lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN)) != 0;
+ sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
if (!sync)
- EFX_INFO(efx, "XGXS lane status: %x\n", lane_status);
+ EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
return sync;
}
@@ -230,8 +231,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
unsigned int mmd_mask, unsigned int fatal_mask);
/* Check the link status of specified mmds in bit mask */
-extern int mdio_clause45_links_ok(struct efx_nic *efx,
- unsigned int mmd_mask);
+extern bool mdio_clause45_links_ok(struct efx_nic *efx,
+ unsigned int mmd_mask);
/* Generic transmit disable support though PMAPMD */
extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 219c74a..567df00 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -88,9 +88,12 @@ do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0)
**************************************************************************/
#define EFX_MAX_CHANNELS 32
-#define EFX_MAX_TX_QUEUES 1
#define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
+#define EFX_TX_QUEUE_OFFLOAD_CSUM 0
+#define EFX_TX_QUEUE_NO_CSUM 1
+#define EFX_TX_QUEUE_COUNT 2
+
/**
* struct efx_special_buffer - An Efx special buffer
* @addr: CPU base address of the buffer
@@ -127,7 +130,6 @@ struct efx_special_buffer {
* This field is zero when the queue slot is empty.
* @continuation: True if this fragment is not the end of a packet.
* @unmap_single: True if pci_unmap_single should be used.
- * @unmap_addr: DMA address to unmap
* @unmap_len: Length of this fragment to unmap
*/
struct efx_tx_buffer {
@@ -135,9 +137,8 @@ struct efx_tx_buffer {
struct efx_tso_header *tsoh;
dma_addr_t dma_addr;
unsigned short len;
- unsigned char continuation;
- unsigned char unmap_single;
- dma_addr_t unmap_addr;
+ bool continuation;
+ bool unmap_single;
unsigned short unmap_len;
};
@@ -156,13 +157,12 @@ struct efx_tx_buffer {
*
* @efx: The associated Efx NIC
* @queue: DMA queue number
- * @used: Queue is used by net driver
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
- * @stopped: Stopped flag.
+ * @stopped: Stopped count.
* Set if this TX queue is currently stopping its port.
* @insert_count: Current insert pointer
* This is the number of buffers that have been added to the
@@ -188,7 +188,6 @@ struct efx_tx_queue {
/* Members which don't change on the fast path */
struct efx_nic *efx ____cacheline_aligned_in_smp;
int queue;
- int used;
struct efx_channel *channel;
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
@@ -232,7 +231,6 @@ struct efx_rx_buffer {
* struct efx_rx_queue - An Efx RX queue
* @efx: The associated Efx NIC
* @queue: DMA queue number
- * @used: Queue is used by net driver
* @channel: The associated channel
* @buffer: The software buffer ring
* @rxd: The hardware descriptor ring
@@ -266,7 +264,6 @@ struct efx_rx_buffer {
struct efx_rx_queue {
struct efx_nic *efx;
int queue;
- int used;
struct efx_channel *channel;
struct efx_rx_buffer *buffer;
struct efx_special_buffer rxd;
@@ -325,12 +322,10 @@ enum efx_rx_alloc_method {
* queue.
*
* @efx: Associated Efx NIC
- * @evqnum: Event queue number
* @channel: Channel instance number
* @used_flags: Channel is used by net driver
* @enabled: Channel enabled indicator
* @irq: IRQ number (MSI and MSI-X only)
- * @has_interrupt: Channel has an interrupt
* @irq_moderation: IRQ moderation value (in us)
* @napi_dev: Net device used with NAPI
* @napi_str: NAPI control structure
@@ -357,17 +352,14 @@ enum efx_rx_alloc_method {
*/
struct efx_channel {
struct efx_nic *efx;
- int evqnum;
int channel;
int used_flags;
- int enabled;
+ bool enabled;
int irq;
- unsigned int has_interrupt;
unsigned int irq_moderation;
struct net_device *napi_dev;
struct napi_struct napi_str;
- struct work_struct reset_work;
- int work_pending;
+ bool work_pending;
struct efx_special_buffer eventq;
unsigned int eventq_read_ptr;
unsigned int last_eventq_read_ptr;
@@ -390,7 +382,7 @@ struct efx_channel {
* access with prefetches.
*/
struct efx_rx_buffer *rx_pkt;
- int rx_pkt_csummed;
+ bool rx_pkt_csummed;
};
@@ -403,8 +395,8 @@ struct efx_channel {
*/
struct efx_blinker {
int led_num;
- int state;
- int resubmit;
+ bool state;
+ bool resubmit;
struct timer_list timer;
};
@@ -432,8 +424,8 @@ struct efx_board {
* have a separate init callback that happens later than
* board init. */
int (*init_leds)(struct efx_nic *efx);
- void (*set_fault_led) (struct efx_nic *efx, int state);
- void (*blink) (struct efx_nic *efx, int start);
+ void (*set_fault_led) (struct efx_nic *efx, bool state);
+ void (*blink) (struct efx_nic *efx, bool start);
void (*fini) (struct efx_nic *nic);
struct efx_blinker blinker;
struct i2c_client *hwmon_client, *ioexp_client;
@@ -467,8 +459,7 @@ enum nic_state {
STATE_INIT = 0,
STATE_RUNNING = 1,
STATE_FINI = 2,
- STATE_RESETTING = 3, /* rtnl_lock always held */
- STATE_DISABLED = 4,
+ STATE_DISABLED = 3,
STATE_MAX,
};
@@ -523,10 +514,28 @@ struct efx_phy_operations {
void (*clear_interrupt) (struct efx_nic *efx);
int (*check_hw) (struct efx_nic *efx);
void (*reset_xaui) (struct efx_nic *efx);
+ int (*test) (struct efx_nic *efx);
int mmds;
unsigned loopbacks;
};
+/**
+ * @enum efx_phy_mode - PHY operating mode flags
+ * @PHY_MODE_NORMAL: on and should pass traffic
+ * @PHY_MODE_TX_DISABLED: on with TX disabled
+ * @PHY_MODE_SPECIAL: on but will not pass traffic
+ */
+enum efx_phy_mode {
+ PHY_MODE_NORMAL = 0,
+ PHY_MODE_TX_DISABLED = 1,
+ PHY_MODE_SPECIAL = 8,
+};
+
+static inline bool efx_phy_mode_disabled(enum efx_phy_mode mode)
+{
+ return !!(mode & ~PHY_MODE_TX_DISABLED);
+}
+
/*
* Efx extended statistics
*
@@ -632,7 +641,7 @@ union efx_multicast_hash {
* @tx_queue: TX DMA queues
* @rx_queue: RX DMA queues
* @channel: Channels
- * @rss_queues: Number of RSS queues
+ * @n_rx_queues: Number of RX queues
* @rx_buffer_len: RX buffer length
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer
* @irq_status: Interrupt status buffer
@@ -640,15 +649,20 @@ union efx_multicast_hash {
* This register is written with the SMP processor ID whenever an
* interrupt is handled. It is used by falcon_test_interrupt()
* to verify that an interrupt has occurred.
+ * @spi_flash: SPI flash device
+ * This field will be %NULL if no flash device is present.
+ * @spi_eeprom: SPI EEPROM device
+ * This field will be %NULL if no EEPROM device is present.
* @n_rx_nodesc_drop_cnt: RX no descriptor drop count
* @nic_data: Hardware dependant state
- * @mac_lock: MAC access lock. Protects @port_enabled, efx_monitor() and
- * efx_reconfigure_port()
+ * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
+ * @port_inhibited, efx_monitor() and efx_reconfigure_port()
* @port_enabled: Port enabled indicator.
* Serialises efx_stop_all(), efx_start_all() and efx_monitor() and
* efx_reconfigure_work with kernel interfaces. Safe to read under any
* one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
* be held to modify it.
+ * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
* @port_initialized: Port initialized?
* @net_dev: Operating system network device. Consider holding the rtnl lock
* @rx_checksum_enabled: RX checksumming enabled
@@ -658,14 +672,16 @@ union efx_multicast_hash {
* can provide. Generic code converts these into a standard
* &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
- * @stats_lock: Statistics update lock
+ * @stats_lock: Statistics update lock. Serialises statistics fetches
+ * @stats_enabled: Temporarily disable statistics fetches.
+ * Serialised by @stats_lock
* @mac_address: Permanent MAC address
* @phy_type: PHY type
* @phy_lock: PHY access lock
* @phy_op: PHY interface
* @phy_data: PHY private data (including PHY-specific stats)
* @mii: PHY interface
- * @tx_disabled: PHY transmitter turned off
+ * @phy_mode: PHY operating mode. Serialised by @mac_lock.
* @link_up: Link status
* @link_options: Link options (MII/GMII format)
* @n_link_state_changes: Number of times the link has changed state
@@ -700,27 +716,31 @@ struct efx_nic {
enum nic_state state;
enum reset_type reset_pending;
- struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES];
+ struct efx_tx_queue tx_queue[EFX_TX_QUEUE_COUNT];
struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
struct efx_channel channel[EFX_MAX_CHANNELS];
- int rss_queues;
+ int n_rx_queues;
unsigned int rx_buffer_len;
unsigned int rx_buffer_order;
struct efx_buffer irq_status;
volatile signed int last_irq_cpu;
+ struct efx_spi_device *spi_flash;
+ struct efx_spi_device *spi_eeprom;
+
unsigned n_rx_nodesc_drop_cnt;
struct falcon_nic_data *nic_data;
struct mutex mac_lock;
- int port_enabled;
+ bool port_enabled;
+ bool port_inhibited;
- int port_initialized;
+ bool port_initialized;
struct net_device *net_dev;
- int rx_checksum_enabled;
+ bool rx_checksum_enabled;
atomic_t netif_stop_count;
spinlock_t netif_stop_lock;
@@ -728,6 +748,7 @@ struct efx_nic {
struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
spinlock_t stats_lock;
+ bool stats_enabled;
unsigned char mac_address[ETH_ALEN];
@@ -736,13 +757,13 @@ struct efx_nic {
struct efx_phy_operations *phy_op;
void *phy_data;
struct mii_if_info mii;
- unsigned tx_disabled;
+ enum efx_phy_mode phy_mode;
- int link_up;
+ bool link_up;
unsigned int link_options;
unsigned int n_link_state_changes;
- int promiscuous;
+ bool promiscuous;
union efx_multicast_hash multicast_hash;
enum efx_fc_type flow_control;
struct work_struct reconfigure_work;
@@ -829,50 +850,33 @@ struct efx_nic_type {
continue; \
else
-/* Iterate over all used channels with interrupts */
-#define efx_for_each_channel_with_interrupt(_channel, _efx) \
- for (_channel = &_efx->channel[0]; \
- _channel < &_efx->channel[EFX_MAX_CHANNELS]; \
- _channel++) \
- if (!(_channel->used_flags && _channel->has_interrupt)) \
- continue; \
- else
-
/* Iterate over all used TX queues */
#define efx_for_each_tx_queue(_tx_queue, _efx) \
for (_tx_queue = &_efx->tx_queue[0]; \
- _tx_queue < &_efx->tx_queue[EFX_MAX_TX_QUEUES]; \
- _tx_queue++) \
- if (!_tx_queue->used) \
- continue; \
- else
+ _tx_queue < &_efx->tx_queue[EFX_TX_QUEUE_COUNT]; \
+ _tx_queue++)
/* Iterate over all TX queues belonging to a channel */
#define efx_for_each_channel_tx_queue(_tx_queue, _channel) \
for (_tx_queue = &_channel->efx->tx_queue[0]; \
- _tx_queue < &_channel->efx->tx_queue[EFX_MAX_TX_QUEUES]; \
+ _tx_queue < &_channel->efx->tx_queue[EFX_TX_QUEUE_COUNT]; \
_tx_queue++) \
- if ((!_tx_queue->used) || \
- (_tx_queue->channel != _channel)) \
+ if (_tx_queue->channel != _channel) \
continue; \
else
/* Iterate over all used RX queues */
#define efx_for_each_rx_queue(_rx_queue, _efx) \
for (_rx_queue = &_efx->rx_queue[0]; \
- _rx_queue < &_efx->rx_queue[EFX_MAX_RX_QUEUES]; \
- _rx_queue++) \
- if (!_rx_queue->used) \
- continue; \
- else
+ _rx_queue < &_efx->rx_queue[_efx->n_rx_queues]; \
+ _rx_queue++)
/* Iterate over all RX queues belonging to a channel */
#define efx_for_each_channel_rx_queue(_rx_queue, _channel) \
- for (_rx_queue = &_channel->efx->rx_queue[0]; \
- _rx_queue < &_channel->efx->rx_queue[EFX_MAX_RX_QUEUES]; \
- _rx_queue++) \
- if ((!_rx_queue->used) || \
- (_rx_queue->channel != _channel)) \
+ for (_rx_queue = &_channel->efx->rx_queue[_channel->channel]; \
+ _rx_queue; \
+ _rx_queue = NULL) \
+ if (_rx_queue->channel != _channel) \
continue; \
else
@@ -886,13 +890,13 @@ static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue,
}
/* Set bit in a little-endian bitfield */
-static inline void set_bit_le(int nr, unsigned char *addr)
+static inline void set_bit_le(unsigned nr, unsigned char *addr)
{
addr[nr / 8] |= (1 << (nr % 8));
}
/* Clear bit in a little-endian bitfield */
-static inline void clear_bit_le(int nr, unsigned char *addr)
+static inline void clear_bit_le(unsigned nr, unsigned char *addr)
{
addr[nr / 8] &= ~(1 << (nr % 8));
}
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 9d02c84..f746536 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -15,15 +15,7 @@
*/
extern struct efx_phy_operations falcon_tenxpress_phy_ops;
-enum tenxpress_state {
- TENXPRESS_STATUS_OFF = 0,
- TENXPRESS_STATUS_OTEMP = 1,
- TENXPRESS_STATUS_NORMAL = 2,
-};
-
-extern void tenxpress_set_state(struct efx_nic *efx,
- enum tenxpress_state state);
-extern void tenxpress_phy_blink(struct efx_nic *efx, int blink);
+extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
extern void tenxpress_crc_err(struct efx_nic *efx);
/****************************************************************************
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 0d27dd3..0f805da 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -212,8 +212,8 @@ void efx_lro_fini(struct net_lro_mgr *lro_mgr)
* and populates a struct efx_rx_buffer with the relevant
* information. Return a negative error code or 0 on success.
*/
-static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue,
- struct efx_rx_buffer *rx_buf)
+static int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue,
+ struct efx_rx_buffer *rx_buf)
{
struct efx_nic *efx = rx_queue->efx;
struct net_device *net_dev = efx->net_dev;
@@ -252,8 +252,8 @@ static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue,
* and populates a struct efx_rx_buffer with the relevant
* information. Return a negative error code or 0 on success.
*/
-static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue,
- struct efx_rx_buffer *rx_buf)
+static int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue,
+ struct efx_rx_buffer *rx_buf)
{
struct efx_nic *efx = rx_queue->efx;
int bytes, space, offset;
@@ -319,8 +319,8 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue,
* and populates a struct efx_rx_buffer with the relevant
* information.
*/
-static inline int efx_init_rx_buffer(struct efx_rx_queue *rx_queue,
- struct efx_rx_buffer *new_rx_buf)
+static int efx_init_rx_buffer(struct efx_rx_queue *rx_queue,
+ struct efx_rx_buffer *new_rx_buf)
{
int rc = 0;
@@ -340,8 +340,8 @@ static inline int efx_init_rx_buffer(struct efx_rx_queue *rx_queue,
return rc;
}
-static inline void efx_unmap_rx_buffer(struct efx_nic *efx,
- struct efx_rx_buffer *rx_buf)
+static void efx_unmap_rx_buffer(struct efx_nic *efx,
+ struct efx_rx_buffer *rx_buf)
{
if (rx_buf->page) {
EFX_BUG_ON_PARANOID(rx_buf->skb);
@@ -357,8 +357,8 @@ static inline void efx_unmap_rx_buffer(struct efx_nic *efx,
}
}
-static inline void efx_free_rx_buffer(struct efx_nic *efx,
- struct efx_rx_buffer *rx_buf)
+static void efx_free_rx_buffer(struct efx_nic *efx,
+ struct efx_rx_buffer *rx_buf)
{
if (rx_buf->page) {
__free_pages(rx_buf->page, efx->rx_buffer_order);
@@ -369,8 +369,8 @@ static inline void efx_free_rx_buffer(struct efx_nic *efx,
}
}
-static inline void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
- struct efx_rx_buffer *rx_buf)
+static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
+ struct efx_rx_buffer *rx_buf)
{
efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
efx_free_rx_buffer(rx_queue->efx, rx_buf);
@@ -506,10 +506,10 @@ void efx_rx_work(struct work_struct *data)
efx_schedule_slow_fill(rx_queue, 1);
}
-static inline void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
- struct efx_rx_buffer *rx_buf,
- int len, int *discard,
- int *leak_packet)
+static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
+ struct efx_rx_buffer *rx_buf,
+ int len, bool *discard,
+ bool *leak_packet)
{
struct efx_nic *efx = rx_queue->efx;
unsigned max_len = rx_buf->len - efx->type->rx_buffer_padding;
@@ -520,7 +520,7 @@ static inline void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
/* The packet must be discarded, but this is only a fatal error
* if the caller indicated it was
*/
- *discard = 1;
+ *discard = true;
if ((len > rx_buf->len) && EFX_WORKAROUND_8071(efx)) {
EFX_ERR_RL(efx, " RX queue %d seriously overlength "
@@ -546,8 +546,8 @@ static inline void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
* Handles driverlink veto, and passes the fragment up via
* the appropriate LRO method
*/
-static inline void efx_rx_packet_lro(struct efx_channel *channel,
- struct efx_rx_buffer *rx_buf)
+static void efx_rx_packet_lro(struct efx_channel *channel,
+ struct efx_rx_buffer *rx_buf)
{
struct net_lro_mgr *lro_mgr = &channel->lro_mgr;
void *priv = channel;
@@ -574,9 +574,9 @@ static inline void efx_rx_packet_lro(struct efx_channel *channel,
}
/* Allocate and construct an SKB around a struct page.*/
-static inline struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
- struct efx_nic *efx,
- int hdr_len)
+static struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
+ struct efx_nic *efx,
+ int hdr_len)
{
struct sk_buff *skb;
@@ -621,11 +621,11 @@ static inline struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
}
void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
- unsigned int len, int checksummed, int discard)
+ unsigned int len, bool checksummed, bool discard)
{
struct efx_nic *efx = rx_queue->efx;
struct efx_rx_buffer *rx_buf;
- int leak_packet = 0;
+ bool leak_packet = false;
rx_buf = efx_rx_buffer(rx_queue, index);
EFX_BUG_ON_PARANOID(!rx_buf->data);
@@ -683,11 +683,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
/* Handle a received packet. Second half: Touches packet payload. */
void __efx_rx_packet(struct efx_channel *channel,
- struct efx_rx_buffer *rx_buf, int checksummed)
+ struct efx_rx_buffer *rx_buf, bool checksummed)
{
struct efx_nic *efx = channel->efx;
struct sk_buff *skb;
- int lro = efx->net_dev->features & NETIF_F_LRO;
+ bool lro = !!(efx->net_dev->features & NETIF_F_LRO);
/* If we're in loopback test, then pass the packet directly to the
* loopback layer, and free the rx_buf here
@@ -789,27 +789,18 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
/* Allocate RX buffers */
rxq_size = (efx->type->rxd_ring_mask + 1) * sizeof(*rx_queue->buffer);
rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL);
- if (!rx_queue->buffer) {
- rc = -ENOMEM;
- goto fail1;
- }
+ if (!rx_queue->buffer)
+ return -ENOMEM;
rc = falcon_probe_rx(rx_queue);
- if (rc)
- goto fail2;
-
- return 0;
-
- fail2:
- kfree(rx_queue->buffer);
- rx_queue->buffer = NULL;
- fail1:
- rx_queue->used = 0;
-
+ if (rc) {
+ kfree(rx_queue->buffer);
+ rx_queue->buffer = NULL;
+ }
return rc;
}
-int efx_init_rx_queue(struct efx_rx_queue *rx_queue)
+void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
unsigned int max_fill, trigger, limit;
@@ -833,7 +824,7 @@ int efx_init_rx_queue(struct efx_rx_queue *rx_queue)
rx_queue->fast_fill_limit = limit;
/* Set up RX descriptor ring */
- return falcon_init_rx(rx_queue);
+ falcon_init_rx(rx_queue);
}
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
@@ -872,7 +863,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue)
kfree(rx_queue->buffer);
rx_queue->buffer = NULL;
- rx_queue->used = 0;
}
void efx_flush_lro(struct efx_channel *channel)
diff --git a/drivers/net/sfc/rx.h b/drivers/net/sfc/rx.h
index f35e377..0e88a9d 100644
--- a/drivers/net/sfc/rx.h
+++ b/drivers/net/sfc/rx.h
@@ -14,7 +14,7 @@
int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
-int efx_init_rx_queue(struct efx_rx_queue *rx_queue);
+void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx);
@@ -24,6 +24,6 @@ void efx_rx_strategy(struct efx_channel *channel);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
void efx_rx_work(struct work_struct *data);
void __efx_rx_packet(struct efx_channel *channel,
- struct efx_rx_buffer *rx_buf, int checksummed);
+ struct efx_rx_buffer *rx_buf, bool checksummed);
#endif /* EFX_RX_H */
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 3b2de9f..362956e 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -27,6 +27,9 @@
#include "boards.h"
#include "workarounds.h"
#include "mac.h"
+#include "spi.h"
+#include "falcon_io.h"
+#include "mdio_10g.h"
/*
* Loopback test packet structure
@@ -51,7 +54,7 @@ static const char *payload_msg =
"Hello world! This is an Efx loopback test in progress!";
/**
- * efx_selftest_state - persistent state during a selftest
+ * efx_loopback_state - persistent state during a loopback selftest
* @flush: Drop all packets in efx_loopback_rx_packet
* @packet_count: Number of packets being used in this test
* @skbs: An array of skbs transmitted
@@ -59,10 +62,14 @@ static const char *payload_msg =
* @rx_bad: RX bad packet count
* @payload: Payload used in tests
*/
-struct efx_selftest_state {
- int flush;
+struct efx_loopback_state {
+ bool flush;
int packet_count;
struct sk_buff **skbs;
+
+ /* Checksums are being offloaded */
+ bool offload_csum;
+
atomic_t rx_good;
atomic_t rx_bad;
struct efx_loopback_payload payload;
@@ -70,21 +77,65 @@ struct efx_selftest_state {
/**************************************************************************
*
- * Configurable values
+ * MII, NVRAM and register tests
*
**************************************************************************/
-/* Level of loopback testing
- *
- * The maximum packet burst length is 16**(n-1), i.e.
- *
- * - Level 0 : no packets
- * - Level 1 : 1 packet
- * - Level 2 : 17 packets (1 * 1 packet, 1 * 16 packets)
- * - Level 3 : 273 packets (1 * 1 packet, 1 * 16 packet, 1 * 256 packets)
- *
- */
-static unsigned int loopback_test_level = 3;
+static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
+{
+ int rc = 0;
+ u16 physid1, physid2;
+ struct mii_if_info *mii = &efx->mii;
+ struct net_device *net_dev = efx->net_dev;
+
+ if (efx->phy_type == PHY_TYPE_NONE)
+ return 0;
+
+ mutex_lock(&efx->mac_lock);
+ tests->mii = -1;
+
+ physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
+ physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+
+ if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
+ (physid2 == 0x0000) || (physid2 == 0xffff)) {
+ EFX_ERR(efx, "no MII PHY present with ID %d\n",
+ mii->phy_id);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
+ if (rc)
+ goto out;
+
+out:
+ mutex_unlock(&efx->mac_lock);
+ tests->mii = rc ? -1 : 1;
+ return rc;
+}
+
+static int efx_test_nvram(struct efx_nic *efx, struct efx_self_tests *tests)
+{
+ int rc;
+
+ rc = falcon_read_nvram(efx, NULL);
+ tests->nvram = rc ? -1 : 1;
+ return rc;
+}
+
+static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
+{
+ int rc;
+
+ /* Not supported on A-series silicon */
+ if (falcon_rev(efx) < FALCON_REV_B0)
+ return 0;
+
+ rc = falcon_test_registers(efx);
+ tests->registers = rc ? -1 : 1;
+ return rc;
+}
/**************************************************************************
*
@@ -107,7 +158,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
/* ACK each interrupting event queue. Receiving an interrupt due to
* traffic before a test event is raised is considered a pass */
- efx_for_each_channel_with_interrupt(channel, efx) {
+ efx_for_each_channel(channel, efx) {
if (channel->work_pending)
efx_process_channel_now(channel);
if (efx->last_irq_cpu >= 0)
@@ -132,41 +183,6 @@ static int efx_test_interrupts(struct efx_nic *efx,
return 0;
}
-/* Test generation and receipt of non-interrupting events */
-static int efx_test_eventq(struct efx_channel *channel,
- struct efx_self_tests *tests)
-{
- unsigned int magic;
-
- /* Channel specific code, limited to 20 bits */
- magic = (0x00010150 + channel->channel);
- EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n",
- channel->channel, magic);
-
- tests->eventq_dma[channel->channel] = -1;
- tests->eventq_int[channel->channel] = 1; /* fake pass */
- tests->eventq_poll[channel->channel] = 1; /* fake pass */
-
- /* Reset flag and zero magic word */
- channel->efx->last_irq_cpu = -1;
- channel->eventq_magic = 0;
- smp_wmb();
-
- falcon_generate_test_event(channel, magic);
- udelay(1);
-
- efx_process_channel_now(channel);
- if (channel->eventq_magic != magic) {
- EFX_ERR(channel->efx, "channel %d failed to see test event\n",
- channel->channel);
- return -ETIMEDOUT;
- } else {
- tests->eventq_dma[channel->channel] = 1;
- }
-
- return 0;
-}
-
/* Test generation and receipt of interrupting events */
static int efx_test_eventq_irq(struct efx_channel *channel,
struct efx_self_tests *tests)
@@ -230,39 +246,18 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
return 0;
}
-/**************************************************************************
- *
- * PHY testing
- *
- **************************************************************************/
-
-/* Check PHY presence by reading the PHY ID registers */
-static int efx_test_phy(struct efx_nic *efx,
- struct efx_self_tests *tests)
+static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests)
{
- u16 physid1, physid2;
- struct mii_if_info *mii = &efx->mii;
- struct net_device *net_dev = efx->net_dev;
+ int rc;
- if (efx->phy_type == PHY_TYPE_NONE)
+ if (!efx->phy_op->test)
return 0;
- EFX_LOG(efx, "testing PHY presence\n");
- tests->phy_ok = -1;
-
- physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
- physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
-
- if ((physid1 != 0x0000) && (physid1 != 0xffff) &&
- (physid2 != 0x0000) && (physid2 != 0xffff)) {
- EFX_LOG(efx, "found MII PHY %d ID 0x%x:%x\n",
- mii->phy_id, physid1, physid2);
- tests->phy_ok = 1;
- return 0;
- }
-
- EFX_ERR(efx, "no MII PHY present with ID %d\n", mii->phy_id);
- return -ENODEV;
+ mutex_lock(&efx->mac_lock);
+ rc = efx->phy_op->test(efx);
+ mutex_unlock(&efx->mac_lock);
+ tests->phy = rc ? -1 : 1;
+ return rc;
}
/**************************************************************************
@@ -278,7 +273,7 @@ static int efx_test_phy(struct efx_nic *efx,
void efx_loopback_rx_packet(struct efx_nic *efx,
const char *buf_ptr, int pkt_len)
{
- struct efx_selftest_state *state = efx->loopback_selftest;
+ struct efx_loopback_state *state = efx->loopback_selftest;
struct efx_loopback_payload *received;
struct efx_loopback_payload *payload;
@@ -289,11 +284,12 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
return;
payload = &state->payload;
-
+
received = (struct efx_loopback_payload *) buf_ptr;
received->ip.saddr = payload->ip.saddr;
- received->ip.check = payload->ip.check;
-
+ if (state->offload_csum)
+ received->ip.check = payload->ip.check;
+
/* Check that header exists */
if (pkt_len < sizeof(received->header)) {
EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
@@ -362,7 +358,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
/* Initialise an efx_selftest_state for a new iteration */
static void efx_iterate_state(struct efx_nic *efx)
{
- struct efx_selftest_state *state = efx->loopback_selftest;
+ struct efx_loopback_state *state = efx->loopback_selftest;
struct net_device *net_dev = efx->net_dev;
struct efx_loopback_payload *payload = &state->payload;
@@ -395,17 +391,17 @@ static void efx_iterate_state(struct efx_nic *efx)
smp_wmb();
}
-static int efx_tx_loopback(struct efx_tx_queue *tx_queue)
+static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- struct efx_selftest_state *state = efx->loopback_selftest;
+ struct efx_loopback_state *state = efx->loopback_selftest;
struct efx_loopback_payload *payload;
struct sk_buff *skb;
int i, rc;
/* Transmit N copies of buffer */
for (i = 0; i < state->packet_count; i++) {
- /* Allocate an skb, holding an extra reference for
+ /* Allocate an skb, holding an extra reference for
* transmit completion counting */
skb = alloc_skb(sizeof(state->payload), GFP_KERNEL);
if (!skb)
@@ -444,11 +440,25 @@ static int efx_tx_loopback(struct efx_tx_queue *tx_queue)
return 0;
}
-static int efx_rx_loopback(struct efx_tx_queue *tx_queue,
- struct efx_loopback_self_tests *lb_tests)
+static int efx_poll_loopback(struct efx_nic *efx)
+{
+ struct efx_loopback_state *state = efx->loopback_selftest;
+ struct efx_channel *channel;
+
+ /* NAPI polling is not enabled, so process channels
+ * synchronously */
+ efx_for_each_channel(channel, efx) {
+ if (channel->work_pending)
+ efx_process_channel_now(channel);
+ }
+ return atomic_read(&state->rx_good) == state->packet_count;
+}
+
+static int efx_end_loopback(struct efx_tx_queue *tx_queue,
+ struct efx_loopback_self_tests *lb_tests)
{
struct efx_nic *efx = tx_queue->efx;
- struct efx_selftest_state *state = efx->loopback_selftest;
+ struct efx_loopback_state *state = efx->loopback_selftest;
struct sk_buff *skb;
int tx_done = 0, rx_good, rx_bad;
int i, rc = 0;
@@ -507,11 +517,10 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
struct efx_loopback_self_tests *lb_tests)
{
struct efx_nic *efx = tx_queue->efx;
- struct efx_selftest_state *state = efx->loopback_selftest;
- struct efx_channel *channel;
- int i, rc = 0;
+ struct efx_loopback_state *state = efx->loopback_selftest;
+ int i, begin_rc, end_rc;
- for (i = 0; i < loopback_test_level; i++) {
+ for (i = 0; i < 3; i++) {
/* Determine how many packets to send */
state->packet_count = (efx->type->txd_ring_mask + 1) / 3;
state->packet_count = min(1 << (i << 2), state->packet_count);
@@ -519,30 +528,31 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
state->packet_count, GFP_KERNEL);
if (!state->skbs)
return -ENOMEM;
- state->flush = 0;
+ state->flush = false;
EFX_LOG(efx, "TX queue %d testing %s loopback with %d "
"packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
state->packet_count);
efx_iterate_state(efx);
- rc = efx_tx_loopback(tx_queue);
-
- /* NAPI polling is not enabled, so process channels synchronously */
- schedule_timeout_uninterruptible(HZ / 50);
- efx_for_each_channel_with_interrupt(channel, efx) {
- if (channel->work_pending)
- efx_process_channel_now(channel);
+ begin_rc = efx_begin_loopback(tx_queue);
+
+ /* This will normally complete very quickly, but be
+ * prepared to wait up to 100 ms. */
+ msleep(1);
+ if (!efx_poll_loopback(efx)) {
+ msleep(100);
+ efx_poll_loopback(efx);
}
- rc |= efx_rx_loopback(tx_queue, lb_tests);
+ end_rc = efx_end_loopback(tx_queue, lb_tests);
kfree(state->skbs);
- if (rc) {
+ if (begin_rc || end_rc) {
/* Wait a while to ensure there are no packets
* floating around after a failure. */
schedule_timeout_uninterruptible(HZ / 10);
- return rc;
+ return begin_rc ? begin_rc : end_rc;
}
}
@@ -550,49 +560,36 @@ efx_test_loopback(struct efx_tx_queue *tx_queue,
"of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
state->packet_count);
- return rc;
+ return 0;
}
-static int efx_test_loopbacks(struct efx_nic *efx,
+static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd,
struct efx_self_tests *tests,
unsigned int loopback_modes)
{
- struct efx_selftest_state *state = efx->loopback_selftest;
- struct ethtool_cmd ecmd, ecmd_loopback;
+ enum efx_loopback_mode mode;
+ struct efx_loopback_state *state;
struct efx_tx_queue *tx_queue;
- enum efx_loopback_mode old_mode, mode;
- int count, rc = 0, link_up;
-
- rc = efx_ethtool_get_settings(efx->net_dev, &ecmd);
- if (rc) {
- EFX_ERR(efx, "could not get GMII settings\n");
- return rc;
- }
- old_mode = efx->loopback_mode;
-
- /* Disable autonegotiation for the purposes of loopback */
- memcpy(&ecmd_loopback, &ecmd, sizeof(ecmd_loopback));
- if (ecmd_loopback.autoneg == AUTONEG_ENABLE) {
- ecmd_loopback.autoneg = AUTONEG_DISABLE;
- ecmd_loopback.duplex = DUPLEX_FULL;
- ecmd_loopback.speed = SPEED_10000;
- }
+ bool link_up;
+ int count, rc = 0;
- rc = efx_ethtool_set_settings(efx->net_dev, &ecmd_loopback);
- if (rc) {
- EFX_ERR(efx, "could not disable autonegotiation\n");
- goto out;
- }
- tests->loopback_speed = ecmd_loopback.speed;
- tests->loopback_full_duplex = ecmd_loopback.duplex;
+ /* Set the port loopback_selftest member. From this point on
+ * all received packets will be dropped. Mark the state as
+ * "flushing" so all inflight packets are dropped */
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+ BUG_ON(efx->loopback_selftest);
+ state->flush = true;
+ efx->loopback_selftest = state;
/* Test all supported loopback modes */
- for (mode = LOOPBACK_NONE; mode < LOOPBACK_TEST_MAX; mode++) {
+ for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) {
if (!(loopback_modes & (1 << mode)))
continue;
/* Move the port into the specified loopback mode. */
- state->flush = 1;
+ state->flush = true;
efx->loopback_mode = mode;
efx_reconfigure_port(efx);
@@ -616,7 +613,7 @@ static int efx_test_loopbacks(struct efx_nic *efx,
*/
link_up = efx->link_up;
if (!falcon_xaui_link_ok(efx))
- link_up = 0;
+ link_up = false;
} while ((++count < 20) && !link_up);
@@ -634,18 +631,21 @@ static int efx_test_loopbacks(struct efx_nic *efx,
/* Test every TX queue */
efx_for_each_tx_queue(tx_queue, efx) {
- rc |= efx_test_loopback(tx_queue,
- &tests->loopback[mode]);
+ state->offload_csum = (tx_queue->queue ==
+ EFX_TX_QUEUE_OFFLOAD_CSUM);
+ rc = efx_test_loopback(tx_queue,
+ &tests->loopback[mode]);
if (rc)
goto out;
}
}
out:
- /* Take out of loopback and restore PHY settings */
- state->flush = 1;
- efx->loopback_mode = old_mode;
- efx_ethtool_set_settings(efx->net_dev, &ecmd);
+ /* Remove the flush. The caller will remove the loopback setting */
+ state->flush = true;
+ efx->loopback_selftest = NULL;
+ wmb();
+ kfree(state);
return rc;
}
@@ -661,23 +661,27 @@ static int efx_test_loopbacks(struct efx_nic *efx,
int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests)
{
struct efx_channel *channel;
- int rc = 0;
+ int rc, rc2 = 0;
+
+ rc = efx_test_mii(efx, tests);
+ if (rc && !rc2)
+ rc2 = rc;
- EFX_LOG(efx, "performing online self-tests\n");
+ rc = efx_test_nvram(efx, tests);
+ if (rc && !rc2)
+ rc2 = rc;
+
+ rc = efx_test_interrupts(efx, tests);
+ if (rc && !rc2)
+ rc2 = rc;
- rc |= efx_test_interrupts(efx, tests);
efx_for_each_channel(channel, efx) {
- if (channel->has_interrupt)
- rc |= efx_test_eventq_irq(channel, tests);
- else
- rc |= efx_test_eventq(channel, tests);
+ rc = efx_test_eventq_irq(channel, tests);
+ if (rc && !rc2)
+ rc2 = rc;
}
- rc |= efx_test_phy(efx, tests);
-
- if (rc)
- EFX_ERR(efx, "failed online self-tests\n");
- return rc;
+ return rc2;
}
/* Offline (i.e. disruptive) testing
@@ -685,35 +689,66 @@ int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests)
int efx_offline_test(struct efx_nic *efx,
struct efx_self_tests *tests, unsigned int loopback_modes)
{
- struct efx_selftest_state *state;
- int rc = 0;
-
- EFX_LOG(efx, "performing offline self-tests\n");
+ enum efx_loopback_mode loopback_mode = efx->loopback_mode;
+ int phy_mode = efx->phy_mode;
+ struct ethtool_cmd ecmd, ecmd_test;
+ int rc, rc2 = 0;
+
+ /* force the carrier state off so the kernel doesn't transmit during
+ * the loopback test, and the watchdog timeout doesn't fire. Also put
+ * falcon into loopback for the register test.
+ */
+ mutex_lock(&efx->mac_lock);
+ efx->port_inhibited = true;
+ if (efx->loopback_modes)
+ efx->loopback_mode = __ffs(efx->loopback_modes);
+ __efx_reconfigure_port(efx);
+ mutex_unlock(&efx->mac_lock);
+
+ /* free up all consumers of SRAM (including all the queues) */
+ efx_reset_down(efx, &ecmd);
+
+ rc = efx_test_chip(efx, tests);
+ if (rc && !rc2)
+ rc2 = rc;
+
+ /* reset the chip to recover from the register test */
+ rc = falcon_reset_hw(efx, RESET_TYPE_ALL);
+
+ /* Modify the saved ecmd so that when efx_reset_up() restores the phy
+ * state, AN is disabled, and the phy is powered, and out of loopback */
+ memcpy(&ecmd_test, &ecmd, sizeof(ecmd_test));
+ if (ecmd_test.autoneg == AUTONEG_ENABLE) {
+ ecmd_test.autoneg = AUTONEG_DISABLE;
+ ecmd_test.duplex = DUPLEX_FULL;
+ ecmd_test.speed = SPEED_10000;
+ }
+ efx->loopback_mode = LOOPBACK_NONE;
- /* Create a selftest_state structure to hold state for the test */
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (state == NULL) {
- rc = -ENOMEM;
- goto out;
+ rc = efx_reset_up(efx, &ecmd_test, rc == 0);
+ if (rc) {
+ EFX_ERR(efx, "Unable to recover from chip test\n");
+ efx_schedule_reset(efx, RESET_TYPE_DISABLE);
+ return rc;
}
- /* Set the port loopback_selftest member. From this point on
- * all received packets will be dropped. Mark the state as
- * "flushing" so all inflight packets are dropped */
- BUG_ON(efx->loopback_selftest);
- state->flush = 1;
- efx->loopback_selftest = state;
+ tests->loopback_speed = ecmd_test.speed;
+ tests->loopback_full_duplex = ecmd_test.duplex;
- rc = efx_test_loopbacks(efx, tests, loopback_modes);
+ rc = efx_test_phy(efx, tests);
+ if (rc && !rc2)
+ rc2 = rc;
- efx->loopback_selftest = NULL;
- wmb();
- kfree(state);
+ rc = efx_test_loopbacks(efx, ecmd_test, tests, loopback_modes);
+ if (rc && !rc2)
+ rc2 = rc;
- out:
- if (rc)
- EFX_ERR(efx, "failed offline self-tests\n");
+ /* restore the PHY to the previous state */
+ efx->loopback_mode = loopback_mode;
+ efx->phy_mode = phy_mode;
+ efx->port_inhibited = false;
+ efx_ethtool_set_settings(efx->net_dev, &ecmd);
- return rc;
+ return rc2;
}
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index f6999c2..fc15df1 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -18,8 +18,8 @@
*/
struct efx_loopback_self_tests {
- int tx_sent[EFX_MAX_TX_QUEUES];
- int tx_done[EFX_MAX_TX_QUEUES];
+ int tx_sent[EFX_TX_QUEUE_COUNT];
+ int tx_done[EFX_TX_QUEUE_COUNT];
int rx_good;
int rx_bad;
};
@@ -29,14 +29,19 @@ struct efx_loopback_self_tests {
* indicates failure.
*/
struct efx_self_tests {
+ /* online tests */
+ int mii;
+ int nvram;
int interrupt;
int eventq_dma[EFX_MAX_CHANNELS];
int eventq_int[EFX_MAX_CHANNELS];
int eventq_poll[EFX_MAX_CHANNELS];
- int phy_ok;
+ /* offline tests */
+ int registers;
+ int phy;
int loopback_speed;
int loopback_full_duplex;
- struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX];
+ struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1];
};
extern void efx_loopback_rx_packet(struct efx_nic *efx,
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index b278495..b7005da 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -13,11 +13,13 @@
* the PHY
*/
#include <linux/delay.h>
+#include "net_driver.h"
#include "efx.h"
#include "phy.h"
#include "boards.h"
#include "falcon.h"
#include "falcon_hwdefs.h"
+#include "falcon_io.h"
#include "mac.h"
/**************************************************************************
@@ -120,111 +122,63 @@ static void sfe4001_poweroff(struct efx_nic *efx)
i2c_smbus_read_byte_data(hwmon_client, RSL);
}
-static void sfe4001_fini(struct efx_nic *efx)
-{
- EFX_INFO(efx, "%s\n", __func__);
-
- sfe4001_poweroff(efx);
- i2c_unregister_device(efx->board_info.ioexp_client);
- i2c_unregister_device(efx->board_info.hwmon_client);
-}
-
-/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected
- * to the FLASH_CFG_1 input on the DSP. We must keep it high at power-
- * up to allow writing the flash (done through MDIO from userland).
- */
-unsigned int sfe4001_phy_flash_cfg;
-module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444);
-MODULE_PARM_DESC(phy_flash_cfg,
- "Force PHY to enter flash configuration mode");
-
-/* This board uses an I2C expander to provider power to the PHY, which needs to
- * be turned on before the PHY can be used.
- * Context: Process context, rtnl lock held
- */
-int sfe4001_init(struct efx_nic *efx)
+static int sfe4001_poweron(struct efx_nic *efx)
{
- struct i2c_client *hwmon_client, *ioexp_client;
- unsigned int count;
+ struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
+ struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
+ unsigned int i, j;
int rc;
u8 out;
- efx_dword_t reg;
-
- hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
- if (!hwmon_client)
- return -EIO;
- efx->board_info.hwmon_client = hwmon_client;
-
- ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
- if (!ioexp_client) {
- rc = -EIO;
- goto fail_hwmon;
- }
- efx->board_info.ioexp_client = ioexp_client;
-
- /* 10Xpress has fixed-function LED pins, so there is no board-specific
- * blink code. */
- efx->board_info.blink = tenxpress_phy_blink;
+ efx_oword_t reg;
/* Ensure that XGXS and XAUI SerDes are held in reset */
- EFX_POPULATE_DWORD_7(reg, XX_PWRDNA_EN, 1,
+ EFX_POPULATE_OWORD_7(reg, XX_PWRDNA_EN, 1,
XX_PWRDNB_EN, 1,
XX_RSTPLLAB_EN, 1,
XX_RESETA_EN, 1,
XX_RESETB_EN, 1,
XX_RSTXGXSRX_EN, 1,
XX_RSTXGXSTX_EN, 1);
- falcon_xmac_writel(efx, ®, XX_PWR_RST_REG_MAC);
+ falcon_write(efx, ®, XX_PWR_RST_REG);
udelay(10);
- efx->board_info.fini = sfe4001_fini;
-
- /* Set DSP over-temperature alert threshold */
- EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
- rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
- xgphy_max_temperature);
- if (rc)
- goto fail_ioexp;
-
- /* Read it back and verify */
- rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
- if (rc < 0)
- goto fail_ioexp;
- if (rc != xgphy_max_temperature) {
- rc = -EFAULT;
- goto fail_ioexp;
- }
-
/* Clear any previous over-temperature alert */
rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
if (rc < 0)
- goto fail_ioexp;
+ return rc;
/* Enable port 0 and port 1 outputs on IO expander */
rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
if (rc)
- goto fail_ioexp;
+ return rc;
rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
0xff & ~(1 << P1_SPARE_LBN));
if (rc)
goto fail_on;
- /* Turn all power off then wait 1 sec. This ensures PHY is reset */
+ /* If PHY power is on, turn it all off and wait 1 second to
+ * ensure a full reset.
+ */
+ rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
+ if (rc < 0)
+ goto fail_on;
out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
(0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
(0 << P0_EN_1V0X_LBN));
- rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
- if (rc)
- goto fail_on;
+ if (rc != out) {
+ EFX_INFO(efx, "power-cycling PHY\n");
+ rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
+ if (rc)
+ goto fail_on;
+ schedule_timeout_uninterruptible(HZ);
+ }
- schedule_timeout_uninterruptible(HZ);
- count = 0;
- do {
+ for (i = 0; i < 20; ++i) {
/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
(1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
(1 << P0_X_TRST_LBN));
- if (sfe4001_phy_flash_cfg)
+ if (efx->phy_mode & PHY_MODE_SPECIAL)
out |= 1 << P0_EN_3V3X_LBN;
rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
@@ -238,35 +192,145 @@ int sfe4001_init(struct efx_nic *efx)
if (rc)
goto fail_on;
- EFX_INFO(efx, "waiting for power (attempt %d)...\n", count);
+ EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i);
+
+ /* In flash config mode, DSP does not turn on AFE, so
+ * just wait 1 second.
+ */
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ schedule_timeout_uninterruptible(HZ);
+ return 0;
+ }
+
+ for (j = 0; j < 10; ++j) {
+ msleep(100);
+
+ /* Check DSP has asserted AFE power line */
+ rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
+ if (rc < 0)
+ goto fail_on;
+ if (rc & (1 << P1_AFE_PWD_LBN))
+ return 0;
+ }
+ }
- schedule_timeout_uninterruptible(HZ);
+ EFX_INFO(efx, "timed out waiting for DSP boot\n");
+ rc = -ETIMEDOUT;
+fail_on:
+ sfe4001_poweroff(efx);
+ return rc;
+}
- /* Check DSP is powered */
- rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
- if (rc < 0)
- goto fail_on;
- if (rc & (1 << P1_AFE_PWD_LBN))
- goto done;
+/* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin
+ * using the 3V3X output of the IO-expander. Allow the user to set
+ * this when the device is stopped, and keep it stopped then.
+ */
- /* DSP doesn't look powered in flash config mode */
- if (sfe4001_phy_flash_cfg)
- goto done;
- } while (++count < 20);
+static ssize_t show_phy_flash_cfg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+ return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
+}
- EFX_INFO(efx, "timed out waiting for power\n");
- rc = -ETIMEDOUT;
- goto fail_on;
+static ssize_t set_phy_flash_cfg(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
+ enum efx_phy_mode old_mode, new_mode;
+ int err;
+
+ rtnl_lock();
+ old_mode = efx->phy_mode;
+ if (count == 0 || *buf == '0')
+ new_mode = old_mode & ~PHY_MODE_SPECIAL;
+ else
+ new_mode = PHY_MODE_SPECIAL;
+ if (old_mode == new_mode) {
+ err = 0;
+ } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
+ err = -EBUSY;
+ } else {
+ efx->phy_mode = new_mode;
+ err = sfe4001_poweron(efx);
+ efx_reconfigure_port(efx);
+ }
+ rtnl_unlock();
+
+ return err ? err : count;
+}
+
+static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
+
+static void sfe4001_fini(struct efx_nic *efx)
+{
+ EFX_INFO(efx, "%s\n", __func__);
+
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+ sfe4001_poweroff(efx);
+ i2c_unregister_device(efx->board_info.ioexp_client);
+ i2c_unregister_device(efx->board_info.hwmon_client);
+}
+
+/* This board uses an I2C expander to provider power to the PHY, which needs to
+ * be turned on before the PHY can be used.
+ * Context: Process context, rtnl lock held
+ */
+int sfe4001_init(struct efx_nic *efx)
+{
+ struct i2c_client *hwmon_client;
+ int rc;
+
+ hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
+ if (!hwmon_client)
+ return -EIO;
+ efx->board_info.hwmon_client = hwmon_client;
+
+ /* Set DSP over-temperature alert threshold */
+ EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
+ rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
+ xgphy_max_temperature);
+ if (rc)
+ goto fail_ioexp;
+
+ /* Read it back and verify */
+ rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
+ if (rc < 0)
+ goto fail_ioexp;
+ if (rc != xgphy_max_temperature) {
+ rc = -EFAULT;
+ goto fail_ioexp;
+ }
+
+ efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
+ if (!efx->board_info.ioexp_client) {
+ rc = -EIO;
+ goto fail_hwmon;
+ }
+
+ /* 10Xpress has fixed-function LED pins, so there is no board-specific
+ * blink code. */
+ efx->board_info.blink = tenxpress_phy_blink;
+
+ efx->board_info.fini = sfe4001_fini;
+
+ rc = sfe4001_poweron(efx);
+ if (rc)
+ goto fail_ioexp;
+
+ rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
+ if (rc)
+ goto fail_on;
-done:
EFX_INFO(efx, "PHY is powered on\n");
return 0;
fail_on:
sfe4001_poweroff(efx);
fail_ioexp:
- i2c_unregister_device(ioexp_client);
+ i2c_unregister_device(efx->board_info.ioexp_client);
fail_hwmon:
- i2c_unregister_device(hwmon_client);
+ i2c_unregister_device(hwmon_client);
return rc;
}
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h
index 34412f3..feef619 100644
--- a/drivers/net/sfc/spi.h
+++ b/drivers/net/sfc/spi.h
@@ -19,53 +19,48 @@
*
*************************************************************************/
-/*
- * Commands common to all known devices.
- *
+#define SPI_WRSR 0x01 /* Write status register */
+#define SPI_WRITE 0x02 /* Write data to memory array */
+#define SPI_READ 0x03 /* Read data from memory array */
+#define SPI_WRDI 0x04 /* Reset write enable latch */
+#define SPI_RDSR 0x05 /* Read status register */
+#define SPI_WREN 0x06 /* Set write enable latch */
+
+#define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */
+#define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */
+#define SPI_STATUS_BP1 0x08 /* Block protection bit 1 */
+#define SPI_STATUS_BP0 0x04 /* Block protection bit 0 */
+#define SPI_STATUS_WEN 0x02 /* State of the write enable latch */
+#define SPI_STATUS_NRDY 0x01 /* Device busy flag */
+
+/**
+ * struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device
+ * @efx: The Efx controller that owns this device
+ * @device_id: Controller's id for the device
+ * @size: Size (in bytes)
+ * @addr_len: Number of address bytes in read/write commands
+ * @munge_address: Flag whether addresses should be munged.
+ * Some devices with 9-bit addresses (e.g. AT25040A EEPROM)
+ * use bit 3 of the command byte as address bit A8, rather
+ * than having a two-byte address. If this flag is set, then
+ * commands should be munged in this way.
+ * @block_size: Write block size (in bytes).
+ * Write commands are limited to blocks with this size and alignment.
+ * @read: Read function for the device
+ * @write: Write function for the device
*/
-
-/* Write status register */
-#define SPI_WRSR 0x01
-
-/* Write data to memory array */
-#define SPI_WRITE 0x02
-
-/* Read data from memory array */
-#define SPI_READ 0x03
-
-/* Reset write enable latch */
-#define SPI_WRDI 0x04
-
-/* Read status register */
-#define SPI_RDSR 0x05
-
-/* Set write enable latch */
-#define SPI_WREN 0x06
-
-/* SST: Enable write to status register */
-#define SPI_SST_EWSR 0x50
-
-/*
- * Status register bits. Not all bits are supported on all devices.
- *
- */
-
-/* Write-protect pin enabled */
-#define SPI_STATUS_WPEN 0x80
-
-/* Block protection bit 2 */
-#define SPI_STATUS_BP2 0x10
-
-/* Block protection bit 1 */
-#define SPI_STATUS_BP1 0x08
-
-/* Block protection bit 0 */
-#define SPI_STATUS_BP0 0x04
-
-/* State of the write enable latch */
-#define SPI_STATUS_WEN 0x02
-
-/* Device busy flag */
-#define SPI_STATUS_NRDY 0x01
+struct efx_spi_device {
+ struct efx_nic *efx;
+ int device_id;
+ unsigned int size;
+ unsigned int addr_len;
+ unsigned int munge_address:1;
+ unsigned int block_size;
+};
+
+int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
+ size_t len, size_t *retlen, u8 *buffer);
+int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
+ size_t len, size_t *retlen, const u8 *buffer);
#endif /* EFX_SPI_H */
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index c014606..8412dbe 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -65,25 +65,10 @@
#define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
-/* Self test (BIST) control register */
-#define PMA_PMD_BIST_CTRL_REG (0xc014)
-#define PMA_PMD_BIST_BER_LBN (2) /* Run BER test */
-#define PMA_PMD_BIST_CONT_LBN (1) /* Run continuous BIST until cleared */
-#define PMA_PMD_BIST_SINGLE_LBN (0) /* Run 1 BIST iteration (self clears) */
-/* Self test status register */
-#define PMA_PMD_BIST_STAT_REG (0xc015)
-#define PMA_PMD_BIST_ENX_LBN (3)
-#define PMA_PMD_BIST_PMA_LBN (2)
-#define PMA_PMD_BIST_RXD_LBN (1)
-#define PMA_PMD_BIST_AFE_LBN (0)
-
/* Special Software reset register */
#define PMA_PMD_EXT_CTRL_REG 49152
#define PMA_PMD_EXT_SSR_LBN 15
-#define BIST_MAX_DELAY (1000)
-#define BIST_POLL_DELAY (10)
-
/* Misc register defines */
#define PCS_CLOCK_CTRL_REG 0xd801
#define PLL312_RST_N_LBN 2
@@ -119,27 +104,12 @@ MODULE_PARM_DESC(crc_error_reset_threshold,
"Max number of CRC errors before XAUI reset");
struct tenxpress_phy_data {
- enum tenxpress_state state;
enum efx_loopback_mode loopback_mode;
atomic_t bad_crc_count;
- int tx_disabled;
+ enum efx_phy_mode phy_mode;
int bad_lp_tries;
};
-static int tenxpress_state_is(struct efx_nic *efx, int state)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- return (phy_data != NULL) && (state == phy_data->state);
-}
-
-void tenxpress_set_state(struct efx_nic *efx,
- enum tenxpress_state state)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- if (phy_data != NULL)
- phy_data->state = state;
-}
-
void tenxpress_crc_err(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
@@ -214,15 +184,12 @@ static int tenxpress_phy_init(struct efx_nic *efx)
if (!phy_data)
return -ENOMEM;
efx->phy_data = phy_data;
+ phy_data->phy_mode = efx->phy_mode;
- tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL);
-
- if (!sfe4001_phy_flash_cfg) {
- rc = mdio_clause45_wait_reset_mmds(efx,
- TENXPRESS_REQUIRED_DEVS);
- if (rc < 0)
- goto fail;
- }
+ rc = mdio_clause45_wait_reset_mmds(efx,
+ TENXPRESS_REQUIRED_DEVS);
+ if (rc < 0)
+ goto fail;
rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
if (rc < 0)
@@ -274,7 +241,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
return 0;
}
-static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp)
+static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp)
{
struct tenxpress_phy_data *pd = efx->phy_data;
int reg;
@@ -311,15 +278,15 @@ static void tenxpress_set_bad_lp(struct efx_nic *efx, int bad_lp)
* into a non-10GBT port and if so warn the user that they won't get
* link any time soon as we are 10GBT only, unless caller specified
* not to do this check (it isn't useful in loopback) */
-static int tenxpress_link_ok(struct efx_nic *efx, int check_lp)
+static bool tenxpress_link_ok(struct efx_nic *efx, bool check_lp)
{
- int ok = mdio_clause45_links_ok(efx, TENXPRESS_REQUIRED_DEVS);
+ bool ok = mdio_clause45_links_ok(efx, TENXPRESS_REQUIRED_DEVS);
if (ok) {
- tenxpress_set_bad_lp(efx, 0);
+ tenxpress_set_bad_lp(efx, false);
} else if (check_lp) {
/* Are we plugged into the wrong sort of link? */
- int bad_lp = 0;
+ bool bad_lp = false;
int phy_id = efx->mii.phy_id;
int an_stat = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_AN_STATUS);
@@ -332,7 +299,7 @@ static int tenxpress_link_ok(struct efx_nic *efx, int check_lp)
* bit has the advantage of not clearing when autoneg
* restarts. */
if (!(xphy_stat & (1 << PMA_PMD_XSTAT_FLP_LBN))) {
- tenxpress_set_bad_lp(efx, 0);
+ tenxpress_set_bad_lp(efx, false);
return ok;
}
@@ -367,16 +334,19 @@ static void tenxpress_phyxs_loopback(struct efx_nic *efx)
static void tenxpress_phy_reconfigure(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
- int loop_change = LOOPBACK_OUT_OF(phy_data, efx,
- TENXPRESS_LOOPBACKS);
+ bool loop_change = LOOPBACK_OUT_OF(phy_data, efx,
+ TENXPRESS_LOOPBACKS);
- if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL))
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ phy_data->phy_mode = efx->phy_mode;
return;
+ }
/* When coming out of transmit disable, coming out of low power
* mode, or moving out of any PHY internal loopback mode,
* perform a special software reset */
- if ((phy_data->tx_disabled && !efx->tx_disabled) ||
+ if ((efx->phy_mode == PHY_MODE_NORMAL &&
+ phy_data->phy_mode != PHY_MODE_NORMAL) ||
loop_change) {
tenxpress_special_reset(efx);
falcon_reset_xaui(efx);
@@ -386,9 +356,9 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
mdio_clause45_phy_reconfigure(efx);
tenxpress_phyxs_loopback(efx);
- phy_data->tx_disabled = efx->tx_disabled;
phy_data->loopback_mode = efx->loopback_mode;
- efx->link_up = tenxpress_link_ok(efx, 0);
+ phy_data->phy_mode = efx->phy_mode;
+ efx->link_up = tenxpress_link_ok(efx, false);
efx->link_options = GM_LPA_10000FULL;
}
@@ -402,16 +372,15 @@ static void tenxpress_phy_clear_interrupt(struct efx_nic *efx)
static int tenxpress_phy_check_hw(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
- int phy_up = tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL);
- int link_ok;
+ bool link_ok;
- link_ok = phy_up && tenxpress_link_ok(efx, 1);
+ link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL &&
+ tenxpress_link_ok(efx, true));
if (link_ok != efx->link_up)
falcon_xmac_sim_phy_event(efx);
- /* Nothing to check if we've already shut down the PHY */
- if (!phy_up)
+ if (phy_data->phy_mode != PHY_MODE_NORMAL)
return 0;
if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
@@ -444,7 +413,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
/* Set the RX and TX LEDs and Link LED flashing. The other LEDs
* (which probably aren't wired anyway) are left in AUTO mode */
-void tenxpress_phy_blink(struct efx_nic *efx, int blink)
+void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
{
int reg;
@@ -507,6 +476,12 @@ static void tenxpress_reset_xaui(struct efx_nic *efx)
udelay(10);
}
+static int tenxpress_phy_test(struct efx_nic *efx)
+{
+ /* BIST is automatically run after a special software reset */
+ return tenxpress_special_reset(efx);
+}
+
struct efx_phy_operations falcon_tenxpress_phy_ops = {
.init = tenxpress_phy_init,
.reconfigure = tenxpress_phy_reconfigure,
@@ -514,6 +489,7 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
.fini = tenxpress_phy_fini,
.clear_interrupt = tenxpress_phy_clear_interrupt,
.reset_xaui = tenxpress_reset_xaui,
+ .test = tenxpress_phy_test,
.mmds = TENXPRESS_REQUIRED_DEVS,
.loopbacks = TENXPRESS_LOOPBACKS,
};
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 5e8374a..cdee7c2 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -47,7 +47,7 @@ void efx_stop_queue(struct efx_nic *efx)
* We want to be able to nest calls to netif_stop_queue(), since each
* channel can have an individual stop on the queue.
*/
-inline void efx_wake_queue(struct efx_nic *efx)
+void efx_wake_queue(struct efx_nic *efx)
{
local_bh_disable();
if (atomic_dec_and_lock(&efx->netif_stop_count,
@@ -59,19 +59,21 @@ inline void efx_wake_queue(struct efx_nic *efx)
local_bh_enable();
}
-static inline void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
- struct efx_tx_buffer *buffer)
+static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
+ struct efx_tx_buffer *buffer)
{
if (buffer->unmap_len) {
struct pci_dev *pci_dev = tx_queue->efx->pci_dev;
+ dma_addr_t unmap_addr = (buffer->dma_addr + buffer->len -
+ buffer->unmap_len);
if (buffer->unmap_single)
- pci_unmap_single(pci_dev, buffer->unmap_addr,
- buffer->unmap_len, PCI_DMA_TODEVICE);
+ pci_unmap_single(pci_dev, unmap_addr, buffer->unmap_len,
+ PCI_DMA_TODEVICE);
else
- pci_unmap_page(pci_dev, buffer->unmap_addr,
- buffer->unmap_len, PCI_DMA_TODEVICE);
+ pci_unmap_page(pci_dev, unmap_addr, buffer->unmap_len,
+ PCI_DMA_TODEVICE);
buffer->unmap_len = 0;
- buffer->unmap_single = 0;
+ buffer->unmap_single = false;
}
if (buffer->skb) {
@@ -103,13 +105,13 @@ struct efx_tso_header {
};
static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
- const struct sk_buff *skb);
+ struct sk_buff *skb);
static void efx_fini_tso(struct efx_tx_queue *tx_queue);
static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue,
struct efx_tso_header *tsoh);
-static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue,
- struct efx_tx_buffer *buffer)
+static void efx_tsoh_free(struct efx_tx_queue *tx_queue,
+ struct efx_tx_buffer *buffer)
{
if (buffer->tsoh) {
if (likely(!buffer->tsoh->unmap_len)) {
@@ -136,8 +138,8 @@ static inline void efx_tsoh_free(struct efx_tx_queue *tx_queue,
* Returns NETDEV_TX_OK or NETDEV_TX_BUSY
* You must hold netif_tx_lock() to call this function.
*/
-static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
- const struct sk_buff *skb)
+static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
+ struct sk_buff *skb)
{
struct efx_nic *efx = tx_queue->efx;
struct pci_dev *pci_dev = efx->pci_dev;
@@ -148,7 +150,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
unsigned int len, unmap_len = 0, fill_level, insert_ptr, misalign;
dma_addr_t dma_addr, unmap_addr = 0;
unsigned int dma_len;
- unsigned unmap_single;
+ bool unmap_single;
int q_space, i = 0;
int rc = NETDEV_TX_OK;
@@ -167,7 +169,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
* since this is more efficient on machines with sparse
* memory.
*/
- unmap_single = 1;
+ unmap_single = true;
dma_addr = pci_map_single(pci_dev, skb->data, len, PCI_DMA_TODEVICE);
/* Process all fragments */
@@ -213,7 +215,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
EFX_BUG_ON_PARANOID(buffer->tsoh);
EFX_BUG_ON_PARANOID(buffer->skb);
EFX_BUG_ON_PARANOID(buffer->len);
- EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+ EFX_BUG_ON_PARANOID(!buffer->continuation);
EFX_BUG_ON_PARANOID(buffer->unmap_len);
dma_len = (((~dma_addr) & efx->type->tx_dma_mask) + 1);
@@ -233,7 +235,6 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
} while (len);
/* Transfer ownership of the unmapping to the final buffer */
- buffer->unmap_addr = unmap_addr;
buffer->unmap_single = unmap_single;
buffer->unmap_len = unmap_len;
unmap_len = 0;
@@ -247,14 +248,14 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
page_offset = fragment->page_offset;
i++;
/* Map for DMA */
- unmap_single = 0;
+ unmap_single = false;
dma_addr = pci_map_page(pci_dev, page, page_offset, len,
PCI_DMA_TODEVICE);
}
/* Transfer ownership of the skb to the final buffer */
buffer->skb = skb;
- buffer->continuation = 0;
+ buffer->continuation = false;
/* Pass off to hardware */
falcon_push_buffers(tx_queue);
@@ -287,9 +288,14 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
}
/* Free the fragment we were mid-way through pushing */
- if (unmap_len)
- pci_unmap_page(pci_dev, unmap_addr, unmap_len,
- PCI_DMA_TODEVICE);
+ if (unmap_len) {
+ if (unmap_single)
+ pci_unmap_single(pci_dev, unmap_addr, unmap_len,
+ PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(pci_dev, unmap_addr, unmap_len,
+ PCI_DMA_TODEVICE);
+ }
return rc;
}
@@ -299,8 +305,8 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
* This removes packets from the TX queue, up to and including the
* specified index.
*/
-static inline void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
- unsigned int index)
+static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
+ unsigned int index)
{
struct efx_nic *efx = tx_queue->efx;
unsigned int stop_index, read_ptr;
@@ -320,7 +326,7 @@ static inline void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
}
efx_dequeue_buffer(tx_queue, buffer);
- buffer->continuation = 1;
+ buffer->continuation = true;
buffer->len = 0;
++tx_queue->read_count;
@@ -367,8 +373,15 @@ inline int efx_xmit(struct efx_nic *efx,
*/
int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
{
- struct efx_nic *efx = net_dev->priv;
- return efx_xmit(efx, &efx->tx_queue[0], skb);
+ struct efx_nic *efx = netdev_priv(net_dev);
+ struct efx_tx_queue *tx_queue;
+
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
+ tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
+ else
+ tx_queue = &efx->tx_queue[EFX_TX_QUEUE_NO_CSUM];
+
+ return efx_xmit(efx, tx_queue, skb);
}
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
@@ -412,30 +425,25 @@ int efx_probe_tx_queue(struct efx_tx_queue *tx_queue)
/* Allocate software ring */
txq_size = (efx->type->txd_ring_mask + 1) * sizeof(*tx_queue->buffer);
tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
- if (!tx_queue->buffer) {
- rc = -ENOMEM;
- goto fail1;
- }
+ if (!tx_queue->buffer)
+ return -ENOMEM;
for (i = 0; i <= efx->type->txd_ring_mask; ++i)
- tx_queue->buffer[i].continuation = 1;
+ tx_queue->buffer[i].continuation = true;
/* Allocate hardware ring */
rc = falcon_probe_tx(tx_queue);
if (rc)
- goto fail2;
+ goto fail;
return 0;
- fail2:
+ fail:
kfree(tx_queue->buffer);
tx_queue->buffer = NULL;
- fail1:
- tx_queue->used = 0;
-
return rc;
}
-int efx_init_tx_queue(struct efx_tx_queue *tx_queue)
+void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
{
EFX_LOG(tx_queue->efx, "initialising TX queue %d\n", tx_queue->queue);
@@ -446,7 +454,7 @@ int efx_init_tx_queue(struct efx_tx_queue *tx_queue)
BUG_ON(tx_queue->stopped);
/* Set up TX descriptor ring */
- return falcon_init_tx(tx_queue);
+ falcon_init_tx(tx_queue);
}
void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
@@ -461,7 +469,7 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
buffer = &tx_queue->buffer[tx_queue->read_count &
tx_queue->efx->type->txd_ring_mask];
efx_dequeue_buffer(tx_queue, buffer);
- buffer->continuation = 1;
+ buffer->continuation = true;
buffer->len = 0;
++tx_queue->read_count;
@@ -494,7 +502,6 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
kfree(tx_queue->buffer);
tx_queue->buffer = NULL;
- tx_queue->used = 0;
}
@@ -533,47 +540,37 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
/**
* struct tso_state - TSO state for an SKB
- * @remaining_len: Bytes of data we've yet to segment
+ * @out_len: Remaining length in current segment
* @seqnum: Current sequence number
+ * @ipv4_id: Current IPv4 ID, host endian
* @packet_space: Remaining space in current packet
- * @ifc: Input fragment cursor.
- * Where we are in the current fragment of the incoming SKB. These
- * values get updated in place when we split a fragment over
- * multiple packets.
- * @p: Parameters.
- * These values are set once at the start of the TSO send and do
- * not get changed as the routine progresses.
+ * @dma_addr: DMA address of current position
+ * @in_len: Remaining length in current SKB fragment
+ * @unmap_len: Length of SKB fragment
+ * @unmap_addr: DMA address of SKB fragment
+ * @unmap_single: DMA single vs page mapping flag
+ * @header_len: Number of bytes of header
+ * @full_packet_size: Number of bytes to put in each outgoing segment
*
* The state used during segmentation. It is put into this data structure
* just to make it easy to pass into inline functions.
*/
struct tso_state {
- unsigned remaining_len;
+ /* Output position */
+ unsigned out_len;
unsigned seqnum;
+ unsigned ipv4_id;
unsigned packet_space;
- struct {
- /* DMA address of current position */
- dma_addr_t dma_addr;
- /* Remaining length */
- unsigned int len;
- /* DMA address and length of the whole fragment */
- unsigned int unmap_len;
- dma_addr_t unmap_addr;
- struct page *page;
- unsigned page_off;
- } ifc;
-
- struct {
- /* The number of bytes of header */
- unsigned int header_length;
-
- /* The number of bytes to put in each outgoing segment. */
- int full_packet_size;
-
- /* Current IPv4 ID, host endian. */
- unsigned ipv4_id;
- } p;
+ /* Input position */
+ dma_addr_t dma_addr;
+ unsigned in_len;
+ unsigned unmap_len;
+ dma_addr_t unmap_addr;
+ bool unmap_single;
+
+ unsigned header_len;
+ int full_packet_size;
};
@@ -581,11 +578,24 @@ struct tso_state {
* Verify that our various assumptions about sk_buffs and the conditions
* under which TSO will be attempted hold true.
*/
-static inline void efx_tso_check_safe(const struct sk_buff *skb)
+static void efx_tso_check_safe(struct sk_buff *skb)
{
- EFX_BUG_ON_PARANOID(skb->protocol != htons(ETH_P_IP));
+ __be16 protocol = skb->protocol;
+
EFX_BUG_ON_PARANOID(((struct ethhdr *)skb->data)->h_proto !=
- skb->protocol);
+ protocol);
+ if (protocol == htons(ETH_P_8021Q)) {
+ /* Find the encapsulated protocol; reset network header
+ * and transport header based on that. */
+ struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+ protocol = veh->h_vlan_encapsulated_proto;
+ skb_set_network_header(skb, sizeof(*veh));
+ if (protocol == htons(ETH_P_IP))
+ skb_set_transport_header(skb, sizeof(*veh) +
+ 4 * ip_hdr(skb)->ihl);
+ }
+
+ EFX_BUG_ON_PARANOID(protocol != htons(ETH_P_IP));
EFX_BUG_ON_PARANOID(ip_hdr(skb)->protocol != IPPROTO_TCP);
EFX_BUG_ON_PARANOID((PTR_DIFF(tcp_hdr(skb), skb->data)
+ (tcp_hdr(skb)->doff << 2u)) >
@@ -685,18 +695,14 @@ efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh)
* @tx_queue: Efx TX queue
* @dma_addr: DMA address of fragment
* @len: Length of fragment
- * @skb: Only non-null for end of last segment
- * @end_of_packet: True if last fragment in a packet
- * @unmap_addr: DMA address of fragment for unmapping
- * @unmap_len: Only set this in last segment of a fragment
+ * @final_buffer: The final buffer inserted into the queue
*
* Push descriptors onto the TX queue. Return 0 on success or 1 if
* @tx_queue full.
*/
static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
dma_addr_t dma_addr, unsigned len,
- const struct sk_buff *skb, int end_of_packet,
- dma_addr_t unmap_addr, unsigned unmap_len)
+ struct efx_tx_buffer **final_buffer)
{
struct efx_tx_buffer *buffer;
struct efx_nic *efx = tx_queue->efx;
@@ -724,8 +730,10 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
fill_level = (tx_queue->insert_count
- tx_queue->old_read_count);
q_space = efx->type->txd_ring_mask - 1 - fill_level;
- if (unlikely(q_space-- <= 0))
+ if (unlikely(q_space-- <= 0)) {
+ *final_buffer = NULL;
return 1;
+ }
smp_mb();
--tx_queue->stopped;
}
@@ -742,7 +750,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
EFX_BUG_ON_PARANOID(buffer->len);
EFX_BUG_ON_PARANOID(buffer->unmap_len);
EFX_BUG_ON_PARANOID(buffer->skb);
- EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+ EFX_BUG_ON_PARANOID(!buffer->continuation);
EFX_BUG_ON_PARANOID(buffer->tsoh);
buffer->dma_addr = dma_addr;
@@ -765,10 +773,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
EFX_BUG_ON_PARANOID(!len);
buffer->len = len;
- buffer->skb = skb;
- buffer->continuation = !end_of_packet;
- buffer->unmap_addr = unmap_addr;
- buffer->unmap_len = unmap_len;
+ *final_buffer = buffer;
return 0;
}
@@ -780,8 +785,8 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue,
* a single fragment, and we know it doesn't cross a page boundary. It
* also allows us to not worry about end-of-packet etc.
*/
-static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue,
- struct efx_tso_header *tsoh, unsigned len)
+static void efx_tso_put_header(struct efx_tx_queue *tx_queue,
+ struct efx_tso_header *tsoh, unsigned len)
{
struct efx_tx_buffer *buffer;
@@ -791,7 +796,7 @@ static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue,
EFX_BUG_ON_PARANOID(buffer->len);
EFX_BUG_ON_PARANOID(buffer->unmap_len);
EFX_BUG_ON_PARANOID(buffer->skb);
- EFX_BUG_ON_PARANOID(buffer->continuation != 1);
+ EFX_BUG_ON_PARANOID(!buffer->continuation);
EFX_BUG_ON_PARANOID(buffer->tsoh);
buffer->len = len;
buffer->dma_addr = tsoh->dma_addr;
@@ -805,6 +810,7 @@ static inline void efx_tso_put_header(struct efx_tx_queue *tx_queue,
static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
{
struct efx_tx_buffer *buffer;
+ dma_addr_t unmap_addr;
/* Work backwards until we hit the original insert pointer value */
while (tx_queue->insert_count != tx_queue->write_count) {
@@ -814,11 +820,18 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
efx_tsoh_free(tx_queue, buffer);
EFX_BUG_ON_PARANOID(buffer->skb);
buffer->len = 0;
- buffer->continuation = 1;
+ buffer->continuation = true;
if (buffer->unmap_len) {
- pci_unmap_page(tx_queue->efx->pci_dev,
- buffer->unmap_addr,
- buffer->unmap_len, PCI_DMA_TODEVICE);
+ unmap_addr = (buffer->dma_addr + buffer->len -
+ buffer->unmap_len);
+ if (buffer->unmap_single)
+ pci_unmap_single(tx_queue->efx->pci_dev,
+ unmap_addr, buffer->unmap_len,
+ PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(tx_queue->efx->pci_dev,
+ unmap_addr, buffer->unmap_len,
+ PCI_DMA_TODEVICE);
buffer->unmap_len = 0;
}
}
@@ -826,50 +839,57 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
/* Parse the SKB header and initialise state. */
-static inline void tso_start(struct tso_state *st, const struct sk_buff *skb)
+static void tso_start(struct tso_state *st, const struct sk_buff *skb)
{
/* All ethernet/IP/TCP headers combined size is TCP header size
* plus offset of TCP header relative to start of packet.
*/
- st->p.header_length = ((tcp_hdr(skb)->doff << 2u)
- + PTR_DIFF(tcp_hdr(skb), skb->data));
- st->p.full_packet_size = (st->p.header_length
- + skb_shinfo(skb)->gso_size);
+ st->header_len = ((tcp_hdr(skb)->doff << 2u)
+ + PTR_DIFF(tcp_hdr(skb), skb->data));
+ st->full_packet_size = st->header_len + skb_shinfo(skb)->gso_size;
- st->p.ipv4_id = ntohs(ip_hdr(skb)->id);
+ st->ipv4_id = ntohs(ip_hdr(skb)->id);
st->seqnum = ntohl(tcp_hdr(skb)->seq);
EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg);
EFX_BUG_ON_PARANOID(tcp_hdr(skb)->syn);
EFX_BUG_ON_PARANOID(tcp_hdr(skb)->rst);
- st->packet_space = st->p.full_packet_size;
- st->remaining_len = skb->len - st->p.header_length;
+ st->packet_space = st->full_packet_size;
+ st->out_len = skb->len - st->header_len;
+ st->unmap_len = 0;
+ st->unmap_single = false;
}
-
-/**
- * tso_get_fragment - record fragment details and map for DMA
- * @st: TSO state
- * @efx: Efx NIC
- * @data: Pointer to fragment data
- * @len: Length of fragment
- *
- * Record fragment details and map for DMA. Return 0 on success, or
- * -%ENOMEM if DMA mapping fails.
- */
-static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx,
- int len, struct page *page, int page_off)
+static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx,
+ skb_frag_t *frag)
{
+ st->unmap_addr = pci_map_page(efx->pci_dev, frag->page,
+ frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
+ if (likely(!pci_dma_mapping_error(efx->pci_dev, st->unmap_addr))) {
+ st->unmap_single = false;
+ st->unmap_len = frag->size;
+ st->in_len = frag->size;
+ st->dma_addr = st->unmap_addr;
+ return 0;
+ }
+ return -ENOMEM;
+}
- st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off,
- len, PCI_DMA_TODEVICE);
- if (likely(!pci_dma_mapping_error(efx->pci_dev, st->ifc.unmap_addr))) {
- st->ifc.unmap_len = len;
- st->ifc.len = len;
- st->ifc.dma_addr = st->ifc.unmap_addr;
- st->ifc.page = page;
- st->ifc.page_off = page_off;
+static int tso_get_head_fragment(struct tso_state *st, struct efx_nic *efx,
+ const struct sk_buff *skb)
+{
+ int hl = st->header_len;
+ int len = skb_headlen(skb) - hl;
+
+ st->unmap_addr = pci_map_single(efx->pci_dev, skb->data + hl,
+ len, PCI_DMA_TODEVICE);
+ if (likely(!pci_dma_mapping_error(efx->pci_dev, st->unmap_addr))) {
+ st->unmap_single = true;
+ st->unmap_len = len;
+ st->in_len = len;
+ st->dma_addr = st->unmap_addr;
return 0;
}
return -ENOMEM;
@@ -886,36 +906,45 @@ static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx,
* of fragment or end-of-packet. Return 0 on success, 1 if not enough
* space in @tx_queue.
*/
-static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue,
- const struct sk_buff *skb,
- struct tso_state *st)
+static int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue,
+ const struct sk_buff *skb,
+ struct tso_state *st)
{
-
+ struct efx_tx_buffer *buffer;
int n, end_of_packet, rc;
- if (st->ifc.len == 0)
+ if (st->in_len == 0)
return 0;
if (st->packet_space == 0)
return 0;
- EFX_BUG_ON_PARANOID(st->ifc.len <= 0);
+ EFX_BUG_ON_PARANOID(st->in_len <= 0);
EFX_BUG_ON_PARANOID(st->packet_space <= 0);
- n = min(st->ifc.len, st->packet_space);
+ n = min(st->in_len, st->packet_space);
st->packet_space -= n;
- st->remaining_len -= n;
- st->ifc.len -= n;
- st->ifc.page_off += n;
- end_of_packet = st->remaining_len == 0 || st->packet_space == 0;
-
- rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n,
- st->remaining_len ? NULL : skb,
- end_of_packet, st->ifc.unmap_addr,
- st->ifc.len ? 0 : st->ifc.unmap_len);
-
- st->ifc.dma_addr += n;
+ st->out_len -= n;
+ st->in_len -= n;
+
+ rc = efx_tx_queue_insert(tx_queue, st->dma_addr, n, &buffer);
+ if (likely(rc == 0)) {
+ if (st->out_len == 0)
+ /* Transfer ownership of the skb */
+ buffer->skb = skb;
+
+ end_of_packet = st->out_len == 0 || st->packet_space == 0;
+ buffer->continuation = !end_of_packet;
+
+ if (st->in_len == 0) {
+ /* Transfer ownership of the pci mapping */
+ buffer->unmap_len = st->unmap_len;
+ buffer->unmap_single = st->unmap_single;
+ st->unmap_len = 0;
+ }
+ }
+ st->dma_addr += n;
return rc;
}
@@ -929,9 +958,9 @@ static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue,
* Generate a new header and prepare for the new packet. Return 0 on
* success, or -1 if failed to alloc header.
*/
-static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
- const struct sk_buff *skb,
- struct tso_state *st)
+static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
+ const struct sk_buff *skb,
+ struct tso_state *st)
{
struct efx_tso_header *tsoh;
struct iphdr *tsoh_iph;
@@ -940,7 +969,7 @@ static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
u8 *header;
/* Allocate a DMA-mapped header buffer. */
- if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) {
+ if (likely(TSOH_SIZE(st->header_len) <= TSOH_STD_SIZE)) {
if (tx_queue->tso_headers_free == NULL) {
if (efx_tsoh_block_alloc(tx_queue))
return -1;
@@ -951,7 +980,7 @@ static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
tsoh->unmap_len = 0;
} else {
tx_queue->tso_long_headers++;
- tsoh = efx_tsoh_heap_alloc(tx_queue, st->p.header_length);
+ tsoh = efx_tsoh_heap_alloc(tx_queue, st->header_len);
if (unlikely(!tsoh))
return -1;
}
@@ -961,33 +990,32 @@ static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
tsoh_iph = (struct iphdr *)(header + SKB_IPV4_OFF(skb));
/* Copy and update the headers. */
- memcpy(header, skb->data, st->p.header_length);
+ memcpy(header, skb->data, st->header_len);
tsoh_th->seq = htonl(st->seqnum);
st->seqnum += skb_shinfo(skb)->gso_size;
- if (st->remaining_len > skb_shinfo(skb)->gso_size) {
+ if (st->out_len > skb_shinfo(skb)->gso_size) {
/* This packet will not finish the TSO burst. */
- ip_length = st->p.full_packet_size - ETH_HDR_LEN(skb);
+ ip_length = st->full_packet_size - ETH_HDR_LEN(skb);
tsoh_th->fin = 0;
tsoh_th->psh = 0;
} else {
/* This packet will be the last in the TSO burst. */
- ip_length = (st->p.header_length - ETH_HDR_LEN(skb)
- + st->remaining_len);
+ ip_length = st->header_len - ETH_HDR_LEN(skb) + st->out_len;
tsoh_th->fin = tcp_hdr(skb)->fin;
tsoh_th->psh = tcp_hdr(skb)->psh;
}
tsoh_iph->tot_len = htons(ip_length);
/* Linux leaves suitable gaps in the IP ID space for us to fill. */
- tsoh_iph->id = htons(st->p.ipv4_id);
- st->p.ipv4_id++;
+ tsoh_iph->id = htons(st->ipv4_id);
+ st->ipv4_id++;
st->packet_space = skb_shinfo(skb)->gso_size;
++tx_queue->tso_packets;
/* Form a descriptor for this header. */
- efx_tso_put_header(tx_queue, tsoh, st->p.header_length);
+ efx_tso_put_header(tx_queue, tsoh, st->header_len);
return 0;
}
@@ -1005,11 +1033,11 @@ static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue,
* %NETDEV_TX_OK or %NETDEV_TX_BUSY.
*/
static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
- const struct sk_buff *skb)
+ struct sk_buff *skb)
{
+ struct efx_nic *efx = tx_queue->efx;
int frag_i, rc, rc2 = NETDEV_TX_OK;
struct tso_state state;
- skb_frag_t *f;
/* Verify TSO is safe - these checks should never fail. */
efx_tso_check_safe(skb);
@@ -1021,29 +1049,16 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
/* Assume that skb header area contains exactly the headers, and
* all payload is in the frag list.
*/
- if (skb_headlen(skb) == state.p.header_length) {
+ if (skb_headlen(skb) == state.header_len) {
/* Grab the first payload fragment. */
EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags < 1);
frag_i = 0;
- f = &skb_shinfo(skb)->frags[frag_i];
- rc = tso_get_fragment(&state, tx_queue->efx,
- f->size, f->page, f->page_offset);
+ rc = tso_get_fragment(&state, efx,
+ skb_shinfo(skb)->frags + frag_i);
if (rc)
goto mem_err;
} else {
- /* It may look like this code fragment assumes that the
- * skb->data portion does not cross a page boundary, but
- * that is not the case. It is guaranteed to be direct
- * mapped memory, and therefore is physically contiguous,
- * and so DMA will work fine. kmap_atomic() on this region
- * will just return the direct mapping, so that will work
- * too.
- */
- int page_off = (unsigned long)skb->data & (PAGE_SIZE - 1);
- int hl = state.p.header_length;
- rc = tso_get_fragment(&state, tx_queue->efx,
- skb_headlen(skb) - hl,
- virt_to_page(skb->data), page_off + hl);
+ rc = tso_get_head_fragment(&state, efx, skb);
if (rc)
goto mem_err;
frag_i = -1;
@@ -1058,13 +1073,12 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
goto stop;
/* Move onto the next fragment? */
- if (state.ifc.len == 0) {
+ if (state.in_len == 0) {
if (++frag_i >= skb_shinfo(skb)->nr_frags)
/* End of payload reached. */
break;
- f = &skb_shinfo(skb)->frags[frag_i];
- rc = tso_get_fragment(&state, tx_queue->efx,
- f->size, f->page, f->page_offset);
+ rc = tso_get_fragment(&state, efx,
+ skb_shinfo(skb)->frags + frag_i);
if (rc)
goto mem_err;
}
@@ -1082,8 +1096,7 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
return NETDEV_TX_OK;
mem_err:
- EFX_ERR(tx_queue->efx, "Out of memory for TSO headers, or PCI mapping"
- " error\n");
+ EFX_ERR(efx, "Out of memory for TSO headers, or PCI mapping error\n");
dev_kfree_skb_any((struct sk_buff *)skb);
goto unwind;
@@ -1092,9 +1105,19 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
/* Stop the queue if it wasn't stopped before. */
if (tx_queue->stopped == 1)
- efx_stop_queue(tx_queue->efx);
+ efx_stop_queue(efx);
unwind:
+ /* Free the DMA mapping we were in the process of writing out */
+ if (state.unmap_len) {
+ if (state.unmap_single)
+ pci_unmap_single(efx->pci_dev, state.unmap_addr,
+ state.unmap_len, PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(efx->pci_dev, state.unmap_addr,
+ state.unmap_len, PCI_DMA_TODEVICE);
+ }
+
efx_enqueue_unwind(tx_queue);
return rc2;
}
diff --git a/drivers/net/sfc/tx.h b/drivers/net/sfc/tx.h
index 1526a73..5e1cc23 100644
--- a/drivers/net/sfc/tx.h
+++ b/drivers/net/sfc/tx.h
@@ -15,7 +15,7 @@
int efx_probe_tx_queue(struct efx_tx_queue *tx_queue);
void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
-int efx_init_tx_queue(struct efx_tx_queue *tx_queue);
+void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 35ab19c..a824f59 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -20,8 +20,6 @@
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
-/* SNAP frames have TOBE_DISC set */
-#define EFX_WORKAROUND_5475 EFX_WORKAROUND_ALWAYS
/* RX PCIe double split performance issue */
#define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
/* TX pkt parser problem with <= 16 byte TXes */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index f3684ad..f6edecc 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -40,7 +40,7 @@ void xfp_set_led(struct efx_nic *p, int led, int mode)
}
struct xfp_phy_data {
- int tx_disabled;
+ enum efx_phy_mode phy_mode;
};
#define XFP_MAX_RESET_TIME 500
@@ -93,7 +93,7 @@ static int xfp_phy_init(struct efx_nic *efx)
" %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
MDIO_ID_REV(devid));
- phy_data->tx_disabled = efx->tx_disabled;
+ phy_data->phy_mode = efx->phy_mode;
rc = xfp_reset_phy(efx);
@@ -136,13 +136,14 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
struct xfp_phy_data *phy_data = efx->phy_data;
/* Reset the PHY when moving from tx off to tx on */
- if (phy_data->tx_disabled && !efx->tx_disabled)
+ if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
+ (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
xfp_reset_phy(efx);
mdio_clause45_transmit_disable(efx);
mdio_clause45_phy_reconfigure(efx);
- phy_data->tx_disabled = efx->tx_disabled;
+ phy_data->phy_mode = efx->phy_mode;
efx->link_up = xfp_link_ok(efx);
efx->link_options = GM_LPA_10000FULL;
}
@@ -151,7 +152,7 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
static void xfp_phy_fini(struct efx_nic *efx)
{
/* Clobber the LED if it was blinking */
- efx->board_info.blink(efx, 0);
+ efx->board_info.blink(efx, false);
/* Free the context block */
kfree(efx->phy_data);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index e24b25c..3805b93 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3732,27 +3732,63 @@ static int sky2_get_eeprom_len(struct net_device *dev)
return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
}
-static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
+static int sky2_vpd_wait(const struct sky2_hw *hw, int cap, u16 busy)
{
- u32 val;
+ unsigned long start = jiffies;
- sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+ while ( (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F) == busy) {
+ /* Can take up to 10.6 ms for write */
+ if (time_after(jiffies, start + HZ/4)) {
+ dev_err(&hw->pdev->dev, PFX "VPD cycle timed out");
+ return -ETIMEDOUT;
+ }
+ mdelay(1);
+ }
- do {
- offset = sky2_pci_read16(hw, cap + PCI_VPD_ADDR);
- } while (!(offset & PCI_VPD_ADDR_F));
+ return 0;
+}
+
+static int sky2_vpd_read(struct sky2_hw *hw, int cap, void *data,
+ u16 offset, size_t length)
+{
+ int rc = 0;
+
+ while (length > 0) {
+ u32 val;
+
+ sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+ rc = sky2_vpd_wait(hw, cap, 0);
+ if (rc)
+ break;
- val = sky2_pci_read32(hw, cap + PCI_VPD_DATA);
- return val;
+ val = sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+
+ memcpy(data, &val, min(sizeof(val), length));
+ offset += sizeof(u32);
+ data += sizeof(u32);
+ length -= sizeof(u32);
+ }
+
+ return rc;
}
-static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
+static int sky2_vpd_write(struct sky2_hw *hw, int cap, const void *data,
+ u16 offset, unsigned int length)
{
- sky2_pci_write16(hw, cap + PCI_VPD_DATA, val);
- sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
- do {
- offset = sky2_pci_read16(hw, cap + PCI_VPD_ADDR);
- } while (offset & PCI_VPD_ADDR_F);
+ unsigned int i;
+ int rc = 0;
+
+ for (i = 0; i < length; i += sizeof(u32)) {
+ u32 val = *(u32 *)(data + i);
+
+ sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
+ sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+
+ rc = sky2_vpd_wait(hw, cap, PCI_VPD_ADDR_F);
+ if (rc)
+ break;
+ }
+ return rc;
}
static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
@@ -3760,24 +3796,13 @@ static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
{
struct sky2_port *sky2 = netdev_priv(dev);
int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
- int length = eeprom->len;
- u16 offset = eeprom->offset;
if (!cap)
return -EINVAL;
eeprom->magic = SKY2_EEPROM_MAGIC;
- while (length > 0) {
- u32 val = sky2_vpd_read(sky2->hw, cap, offset);
- int n = min_t(int, length, sizeof(val));
-
- memcpy(data, &val, n);
- length -= n;
- data += n;
- offset += n;
- }
- return 0;
+ return sky2_vpd_read(sky2->hw, cap, data, eeprom->offset, eeprom->len);
}
static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
@@ -3785,8 +3810,6 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
{
struct sky2_port *sky2 = netdev_priv(dev);
int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
- int length = eeprom->len;
- u16 offset = eeprom->offset;
if (!cap)
return -EINVAL;
@@ -3794,21 +3817,11 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
if (eeprom->magic != SKY2_EEPROM_MAGIC)
return -EINVAL;
- while (length > 0) {
- u32 val;
- int n = min_t(int, length, sizeof(val));
-
- if (n < sizeof(val))
- val = sky2_vpd_read(sky2->hw, cap, offset);
- memcpy(&val, data, n);
-
- sky2_vpd_write(sky2->hw, cap, offset, val);
+ /* Partial writes not supported */
+ if ((eeprom->offset & 3) || (eeprom->len & 3))
+ return -EINVAL;
- length -= n;
- data += n;
- offset += n;
- }
- return 0;
+ return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
}
@@ -4178,6 +4191,69 @@ static int __devinit pci_wake_enabled(struct pci_dev *dev)
return value & PCI_PM_CTRL_PME_ENABLE;
}
+/*
+ * Read and parse the first part of Vital Product Data
+ */
+#define VPD_SIZE 128
+#define VPD_MAGIC 0x82
+
+static void __devinit sky2_vpd_info(struct sky2_hw *hw)
+{
+ int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD);
+ const u8 *p;
+ u8 *vpd_buf = NULL;
+ u16 len;
+ static struct vpd_tag {
+ char tag[2];
+ char *label;
+ } vpd_tags[] = {
+ { "PN", "Part Number" },
+ { "EC", "Engineering Level" },
+ { "MN", "Manufacturer" },
+ };
+
+ if (!cap)
+ goto out;
+
+ vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL);
+ if (!vpd_buf)
+ goto out;
+
+ if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE))
+ goto out;
+
+ if (vpd_buf[0] != VPD_MAGIC)
+ goto out;
+ len = vpd_buf[1];
+ if (len == 0 || len > VPD_SIZE - 4)
+ goto out;
+ p = vpd_buf + 3;
+ dev_info(&hw->pdev->dev, "%.*s\n", len, p);
+ p += len;
+
+ while (p < vpd_buf + VPD_SIZE - 4) {
+ int i;
+
+ if (!memcmp("RW", p, 2)) /* end marker */
+ break;
+
+ len = p[2];
+ if (len > (p - vpd_buf) - 4)
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+ if (!memcmp(vpd_tags[i].tag, p, 2)) {
+ printk(KERN_DEBUG " %s: %.*s\n",
+ vpd_tags[i].label, len, p + 3);
+ break;
+ }
+ }
+ p += len + 3;
+ }
+out:
+ kfree(vpd_buf);
+}
+
/* This driver supports yukon2 chipset only */
static const char *sky2_name(u8 chipid, char *buf, int sz)
{
@@ -4276,13 +4352,13 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
if (err)
goto err_out_iounmap;
- dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-2 %s rev %d\n",
- DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0),
- pdev->irq, sky2_name(hw->chip_id, buf1, sizeof(buf1)),
- hw->chip_rev);
+ dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
+ sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
sky2_reset(hw);
+ sky2_vpd_info(hw);
+
dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
if (!dev) {
err = -ENOMEM;
@@ -4533,6 +4609,8 @@ static struct pci_driver sky2_driver = {
static int __init sky2_init_module(void)
{
+ pr_info(PFX "driver version " DRV_VERSION "\n");
+
sky2_debug_init();
return pci_register_driver(&sky2_driver);
}
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 47d84cd..59d1673 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -119,7 +119,6 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/spinlock.h>
-#include <linux/version.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 96dff04..5b78700 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -914,7 +914,7 @@ static void alloc_rbufs(struct net_device *dev)
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(rp->rx_buf_sz);
+ struct sk_buff *skb = netdev_alloc_skb(dev, rp->rx_buf_sz);
rp->rx_skbuff[i] = skb;
if (skb == NULL)
break;
@@ -1473,8 +1473,8 @@ static int rhine_rx(struct net_device *dev, int limit)
/* Check if the packet is long enough to accept without
copying to a minimally-sized skbuff. */
if (pkt_len < rx_copybreak &&
- (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
- skb_reserve(skb, 2); /* 16 byte align the IP header */
+ (skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN)) != NULL) {
+ skb_reserve(skb, NET_IP_ALIGN); /* 16 byte align the IP header */
pci_dma_sync_single_for_cpu(rp->pdev,
rp->rx_skbuff_dma[entry],
rp->rx_buf_sz,
@@ -1518,7 +1518,7 @@ static int rhine_rx(struct net_device *dev, int limit)
struct sk_buff *skb;
entry = rp->dirty_rx % RX_RING_SIZE;
if (rp->rx_skbuff[entry] == NULL) {
- skb = dev_alloc_skb(rp->rx_buf_sz);
+ skb = netdev_alloc_skb(dev, rp->rx_buf_sz);
rp->rx_skbuff[entry] = skb;
if (skb == NULL)
break; /* Better luck next round. */
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-03 14:37 Jeff Garzik
@ 2008-09-03 22:08 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-09-03 22:08 UTC (permalink / raw)
To: jeff; +Cc: netdev, linux-kernel
From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 3 Sep 2008 10:37:45 -0400
> Please pull from 'davem-next' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
Pulled, thanks Jeff.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [git patches] net driver updates for .28
@ 2008-09-14 2:22 Jeff Garzik
2008-09-20 7:09 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Jeff Garzik @ 2008-09-14 2:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev, LKML
Please pull from 'davem-next' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
to receive the following updates:
drivers/net/3c505.c | 4 +-
drivers/net/Kconfig | 14 +-
drivers/net/arcnet/arcnet.c | 18 +-
drivers/net/arcnet/com20020.c | 16 +-
drivers/net/ax88796.c | 14 +-
drivers/net/bfin_mac.c | 8 +-
drivers/net/bonding/bond_main.c | 6 +
drivers/net/bonding/bonding.h | 2 +-
drivers/net/cxgb3/cxgb3_offload.c | 8 +-
drivers/net/cxgb3/sge.c | 35 -
drivers/net/e100.c | 2 +-
drivers/net/ehea/ehea.h | 4 +-
drivers/net/ehea/ehea_main.c | 26 +-
drivers/net/enc28j60.c | 56 +-
drivers/net/ibm_newemac/phy.c | 2 +-
drivers/net/ixgb/ixgb.h | 2 +-
drivers/net/ixgbe/ixgbe.h | 72 +-
drivers/net/ixgbe/ixgbe_82598.c | 628 +++++++++++++---
drivers/net/ixgbe/ixgbe_common.c | 972 ++++++++++++++++---------
drivers/net/ixgbe/ixgbe_common.h | 62 +-
drivers/net/ixgbe/ixgbe_ethtool.c | 303 ++++----
drivers/net/ixgbe/ixgbe_main.c | 1318 +++++++++++++++++++---------------
drivers/net/ixgbe/ixgbe_phy.c | 244 +++----
drivers/net/ixgbe/ixgbe_phy.h | 63 ++-
drivers/net/ixgbe/ixgbe_type.h | 528 +++++++++-----
drivers/net/meth.c | 2 +-
drivers/net/mipsnet.c | 2 +-
drivers/net/myri10ge/myri10ge.c | 381 +++++++++--
drivers/net/netx-eth.c | 2 +-
drivers/net/netxen/netxen_nic.h | 2 +-
drivers/net/netxen/netxen_nic_main.c | 20 +-
drivers/net/pci-skeleton.c | 4 +-
drivers/net/r6040.c | 4 +-
drivers/net/r8169.c | 2 +-
drivers/net/s2io.c | 40 +-
drivers/net/sfc/efx.c | 18 +-
drivers/net/sfc/falcon.c | 260 ++++----
drivers/net/sfc/falcon.h | 1 +
drivers/net/sfc/falcon_hwdefs.h | 1 -
drivers/net/sfc/falcon_io.h | 1 -
drivers/net/sfc/falcon_xmac.c | 88 +---
drivers/net/sfc/net_driver.h | 8 +-
drivers/net/sfc/sfe4001.c | 12 -
drivers/net/sfc/tenxpress.c | 69 +--
drivers/net/sfc/tx.c | 2 +-
drivers/net/sfc/workarounds.h | 2 -
drivers/net/sfc/xfp_phy.c | 1 -
drivers/net/smc911x.c | 68 +-
drivers/net/smc91x.c | 40 +-
drivers/net/sundance.c | 95 ++-
drivers/net/tehuti.h | 8 +-
drivers/net/tsi108_eth.c | 6 +-
drivers/net/ucc_geth.c | 116 ++--
drivers/net/usb/hso.c | 326 ++++++---
drivers/net/usb/mcs7830.c | 2 +-
drivers/net/usb/pegasus.c | 20 +-
drivers/net/via-velocity.h | 2 +-
drivers/net/wan/cycx_drv.c | 6 +-
drivers/net/wan/cycx_x25.c | 12 +-
drivers/net/wan/dscc4.c | 2 +-
drivers/net/wan/pc300_tty.c | 2 +-
include/linux/pci_ids.h | 10 +
62 files changed, 3684 insertions(+), 2360 deletions(-)
Alexander Duyck (3):
ixgbe: correctly add and remove napi queues
ixgbe: whitespace/formatting cleanup
ixgbe: make compilation with LRO optional
Ben Hutchings (11):
sfc: Add check for memory allocation failure in falcon_probe_nic()
sfc: Fix memory BAR release call on error path
sfc: Remove workaround for old firmware bug
sfc: Serialise tenxpress_special_reset() with statistics fetches
sfc: Make queue flushes more reliable
sfc: Stop generating bogus events in tenxpress_check_hw()
sfc: Insert read memory barrier after checking MAC statistics flag
sfc: Disable interrupts after a fatal interrupt occurs until reset
sfc: Remove obsolete comment about PCI modes
sfc: Use CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS where appropriate
sfc: Fix type of FALCON_SPI_MAX_LEN
Brice Goglin (5):
myri10ge: Stop scaring people when DCA is built but absent
myri10ge: Rename DCA-related firmware counters
myri10ge: Add Toeplitz-hashing related routines
myri10ge: Add multiqueue TX support
myri10ge: use DCA if DCA is compiled as a module
Dan Nicholson (1):
sundance: set carrier status on link change events
Denis Joseph Barrow (1):
[netdrvr] usb/hso: throttle to prevent loss of serial data
Dhananjay Phadke (2):
netxen: add pci ids
netxen: enable msi-x for quad-gig boards
Divy Le Ray (1):
cxgb3 - remove duplicate tests in lro
Florian Fainelli (1):
r6040: fix bad usage of udelay
Francois Romieu (1):
r8169: select MII in Kconfig
Hannes Hering (1):
ehea: Enable DLPAR memory remove
Harvey Harrison (1):
drivers/net: replace __FUNCTION__ with __func__
Jeff Kirsher (2):
ixgbe: fix pci_resource allocation as in other drivers
ixgbe: bump version
Jesse Brandeburg (23):
ixgbe: fix bug where using wake queue instead of start
ixgbe: fix dca defines to not have spaces
ixgbe: fix multicast address update
ixgbe: Update watchdog thread to accomodate longerlink_up events
ixgbe: link change interrupt was not causing link event
ixgbe: fix bug with shared interrupts
ixgbe: limit small mtu to minimum for ipv4 support
ixgbe: fix ethtool register dump
ixgbe: fix ethtool disable csum for ipv6
ixgbe: fix initial interrupt throttle settings
ixgbe: fix bug with lots of tx queues
ixgbe: recycle pages in packet split mode
ixgbe: add device support for XF LR adapters
ixgbe: fix ring reallocation in ethtool
ixgbe: lro stats were not counted on first ethtool -Scall
ixgbe: add clean rx many routine
ixgbe: update to latest common code module
ixgbe: refresh the ixgbe_down function
ixgbe: move set_num_queues and call it after msix failure
ixgbe: cleanup defines
ixgbe: lower stack space usage
ixgbe: xmit frame refactor
ixgbe: fix DCA dependency in Kconfig
Magnus Damm (1):
smc911x: remove duplicate debug printout
Peter P Waskiewicz (1):
ixgbe: Whitespace, copyright update and version number change patch
Sebastien Dugue (1):
ehea: fix mutex and spinlock use
Stephen Hemminger (1):
bonding: add more ethtool support
Steve Hodgson (2):
sfc: Don't use EFX_OWORD_FIELD on an event (64-bit, quad-word)
sfc: Don't include net_driver.h from falcon_io.h
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index fdfb2b2..a424869 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -130,12 +130,12 @@ static const char filename[] = __FILE__;
static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
#define TIMEOUT_MSG(lineno) \
- printk(timeout_msg, filename,__FUNCTION__,(lineno))
+ printk(timeout_msg, filename,__func__,(lineno))
static const char invalid_pcb_msg[] =
"*** invalid pcb length %d at %s:%s (line %d) ***\n";
#define INVALID_PCB_MSG(len) \
- printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
+ printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4a11296..91bcaa1 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2046,6 +2046,7 @@ config R8169
tristate "Realtek 8169 gigabit ethernet support"
depends on PCI
select CRC32
+ select MII
---help---
Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
@@ -2380,7 +2381,7 @@ config EHEA
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
- select INET_LRO
+ select INTEL_IOATDMA
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2396,6 +2397,16 @@ config IXGBE
To compile this driver as a module, choose M here. The module
will be called ixgbe.
+config IXGBE_LRO
+ bool "Use software LRO"
+ depends on IXGBE && INET
+ select INET_LRO
+ default y
+ ---help---
+ Say Y here if you want to use large receive offload.
+
+ If in doubt, say N.
+
config IXGB
tristate "Intel(R) PRO/10GbE support"
depends on PCI
@@ -2432,6 +2443,7 @@ config MYRI10GE
select FW_LOADER
select CRC32
select INET_LRO
+ select INTEL_IOATDMA
---help---
This driver supports Myricom Myri-10G Dual Protocol interface in
Ethernet mode. If the eeprom on your board is not recent enough,
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index bdc4c0b..a5b0769 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -442,24 +442,24 @@ static int arcnet_open(struct net_device *dev)
BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
"DOS networking programs!\n");
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (ASTATUS() & RESETflag) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear);
}
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* make sure we're ready to receive IRQ's. */
AINTMASK(0);
udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
*/
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask = NORXflag | RECONflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
netif_start_queue(dev);
@@ -670,14 +670,14 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
freeskb = 0;
}
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
/* make sure we didn't ignore a TX IRQ while we were in here */
AINTMASK(0);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask |= TXFREEflag|EXCNAKflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
spin_unlock_irqrestore(&lp->lock, flags);
if (freeskb) {
@@ -798,7 +798,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
diagstatus = (status >> 8) & 0xFF;
BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
- __FILE__,__LINE__,__FUNCTION__,status);
+ __FILE__,__LINE__,__func__,status);
didsomething = 0;
/*
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 8b51313..70124a9 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -238,15 +238,15 @@ static int com20020_reset(struct net_device *dev, int really_reset)
u_char inbyte;
BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
- __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
+ __FILE__,__LINE__,__func__,dev,lp,dev->name);
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
dev->name, ASTATUS());
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
/* power-up defaults */
SETCONF;
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (really_reset) {
/* reset the card */
@@ -254,22 +254,22 @@ static int com20020_reset(struct net_device *dev, int really_reset)
mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
}
/* clear flags & end reset */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
/* verify that the ARCnet signature byte is present */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (inbyte != TESTvalue) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
return 1;
}
/* enable extended (512-byte) packets */
ACOMMAND(CONFIGcmd | EXTconf);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* done! return success. */
return 0;
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index a886a4b..4207d6e 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -153,7 +153,7 @@ static void ax_reset_8390(struct net_device *dev)
while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
if (jiffies - reset_start_time > 2*HZ/100) {
dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
- __FUNCTION__, dev->name);
+ __func__, dev->name);
break;
}
}
@@ -173,7 +173,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
if (ei_status.dmaing) {
dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -215,7 +215,7 @@ static void ax_block_input(struct net_device *dev, int count,
dev_err(&ax->dev->dev,
"%s: DMAing conflict in %s "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -260,7 +260,7 @@ static void ax_block_output(struct net_device *dev, int count,
if (ei_status.dmaing) {
dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
"[DMAstat:%d][irqlock:%d]\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -396,7 +396,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
{
if (phy_debug)
pr_debug("%s: dev %p, %04x, %04x, %d\n",
- __FUNCTION__, dev, phy_addr, reg, opc);
+ __func__, dev, phy_addr, reg, opc);
ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
@@ -422,7 +422,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg)
spin_unlock_irqrestore(&ei_local->page_lock, flags);
if (phy_debug)
- pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+ pr_debug("%s: %04x.%04x => read %04x\n", __func__,
phy_addr, reg, result);
return result;
@@ -436,7 +436,7 @@ ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
unsigned long flags;
dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
- __FUNCTION__, dev, phy_addr, reg, value);
+ __func__, dev, phy_addr, reg, value);
spin_lock_irqsave(&ei->page_lock, flags);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 3db7db1..df896e2 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -811,7 +811,7 @@ static void bfin_mac_enable(void)
{
u32 opmode;
- pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__);
+ pr_debug("%s: %s\n", DRV_NAME, __func__);
/* Set RX DMA */
bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
@@ -847,7 +847,7 @@ static void bfin_mac_enable(void)
/* Our watchdog timed out. Called by the networking layer */
static void bfin_mac_timeout(struct net_device *dev)
{
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
bfin_mac_disable();
@@ -949,7 +949,7 @@ static int bfin_mac_open(struct net_device *dev)
{
struct bfin_mac_local *lp = netdev_priv(dev);
int retval;
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -989,7 +989,7 @@ static int bfin_mac_open(struct net_device *dev)
static int bfin_mac_close(struct net_device *dev)
{
struct bfin_mac_local *lp = netdev_priv(dev);
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index babe461..8e2be24 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4493,6 +4493,12 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
static const struct ethtool_ops bond_ethtool_ops = {
.get_drvinfo = bond_ethtool_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .get_tso = ethtool_op_get_tso,
+ .get_ufo = ethtool_op_get_ufo,
+ .get_flags = ethtool_op_get_flags,
};
/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index fb730ec..f7b40ed 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -32,7 +32,7 @@
#ifdef BONDING_DEBUG
#define dprintk(fmt, args...) \
printk(KERN_DEBUG \
- DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
+ DRV_NAME ": %s() %d: " fmt, __func__, __LINE__ , ## args )
#else
#define dprintk(fmt, args...)
#endif /* BONDING_DEBUG */
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index c5b3de1..0f6fd63 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1018,7 +1018,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
if (!skb) {
- printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__);
+ printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
return;
}
skb->priority = CPL_PRIORITY_CONTROL;
@@ -1049,14 +1049,14 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
return;
if (!is_offloading(newdev)) {
printk(KERN_WARNING "%s: Redirect to non-offload "
- "device ignored.\n", __FUNCTION__);
+ "device ignored.\n", __func__);
return;
}
tdev = dev2t3cdev(olddev);
BUG_ON(!tdev);
if (tdev != dev2t3cdev(newdev)) {
printk(KERN_WARNING "%s: Redirect to different "
- "offload device ignored.\n", __FUNCTION__);
+ "offload device ignored.\n", __func__);
return;
}
@@ -1064,7 +1064,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
e = t3_l2t_get(tdev, new->neighbour, newdev);
if (!e) {
printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
- __FUNCTION__);
+ __func__);
return;
}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 1b0861d..f78a42c 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1937,38 +1937,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
}
-#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
- TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
- TCP_FLAG_SYN | TCP_FLAG_FIN)
-#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
-
-/**
- * lro_segment_ok - check if a TCP segment is eligible for LRO
- * @tcph: the TCP header of the packet
- *
- * Returns true if a TCP packet is eligible for LRO. This requires that
- * the packet have only the ACK flag set and no TCP options besides
- * time stamps.
- */
-static inline int lro_segment_ok(const struct tcphdr *tcph)
-{
- int optlen;
-
- if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
- return 0;
-
- optlen = (tcph->doff << 2) - sizeof(*tcph);
- if (optlen) {
- const u32 *opt = (const u32 *)(tcph + 1);
-
- if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
- *opt != htonl(TSTAMP_WORD) || !opt[2])
- return 0;
- }
- return 1;
-}
-
static int t3_get_lro_header(void **eh, void **iph, void **tcph,
u64 *hdr_flags, void *priv)
{
@@ -1981,9 +1949,6 @@ static int t3_get_lro_header(void **eh, void **iph, void **tcph,
*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
- if (!lro_segment_ok(*tcph))
- return -1;
-
*hdr_flags = LRO_IPV4 | LRO_TCP;
return 0;
}
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 453115a..7d7dfa5 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -191,7 +191,7 @@ MODULE_PARM_DESC(use_io, "Force use of i/o access mode");
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
- __FUNCTION__ , ## args))
+ __func__ , ## args))
#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index e01926b..5524271 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,13 +40,13 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0092"
+#define DRV_VERSION "EHEA_0093"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
#define DLPAR_MEM_ADD 2
#define DLPAR_MEM_REM 4
-#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD)
+#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD | DLPAR_MEM_REM)
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index b70c531..c765ec6 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -219,9 +219,11 @@ static void ehea_update_firmware_handles(void)
}
out_update:
+ mutex_lock(&ehea_fw_handles.lock);
kfree(ehea_fw_handles.arr);
ehea_fw_handles.arr = arr;
ehea_fw_handles.num_entries = i;
+ mutex_unlock(&ehea_fw_handles.lock);
}
static void ehea_update_bcmc_registrations(void)
@@ -293,9 +295,11 @@ static void ehea_update_bcmc_registrations(void)
}
out_update:
+ spin_lock(&ehea_bcmc_regs.lock);
kfree(ehea_bcmc_regs.arr);
ehea_bcmc_regs.arr = arr;
ehea_bcmc_regs.num_entries = i;
+ spin_unlock(&ehea_bcmc_regs.lock);
}
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
@@ -1770,8 +1774,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
- spin_lock(&ehea_bcmc_regs.lock);
-
/* Deregister old MAC in pHYP */
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1792,7 +1794,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
out_upregs:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
out_free:
kfree(cb0);
out:
@@ -1954,8 +1955,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
- spin_lock(&ehea_bcmc_regs.lock);
-
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
goto out;
@@ -1985,7 +1984,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
return;
}
@@ -2466,8 +2464,6 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2504,8 +2500,6 @@ static int ehea_up(struct net_device *dev)
}
}
- spin_lock(&ehea_bcmc_regs.lock);
-
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret) {
ret = -EIO;
@@ -2527,10 +2521,8 @@ out:
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2580,9 +2572,6 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
- spin_lock(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -2591,7 +2580,6 @@ static int ehea_down(struct net_device *dev)
port->state = EHEA_PORT_DOWN;
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ret = ehea_clean_all_portres(port);
if (ret)
@@ -2599,7 +2587,6 @@ static int ehea_down(struct net_device *dev)
dev->name, ret);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -3378,7 +3365,6 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
- mutex_lock(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3462,7 +3448,6 @@ out_free_ad:
out:
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -3481,8 +3466,6 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
- mutex_lock(&ehea_fw_handles.lock);
-
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
@@ -3492,7 +3475,6 @@ static int __devexit ehea_remove(struct of_device *dev)
kfree(adapter);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return 0;
}
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index aa0bf6e..e1b441e 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -110,7 +110,7 @@ spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
}
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
return ret;
}
@@ -131,7 +131,7 @@ static int spi_write_buf(struct enc28j60_net *priv, int len,
ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1);
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
}
return ret;
}
@@ -156,7 +156,7 @@ static u8 spi_read_op(struct enc28j60_net *priv, u8 op,
ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen);
if (ret)
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
else
val = rx_buf[slen - 1];
@@ -176,14 +176,14 @@ static int spi_write_op(struct enc28j60_net *priv, u8 op,
ret = spi_write(priv->spi, priv->spi_transfer_buf, 2);
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
return ret;
}
static void enc28j60_soft_reset(struct enc28j60_net *priv)
{
if (netif_msg_hw(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
spi_write_op(priv, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
/* Errata workaround #1, CLKRDY check is unreliable,
@@ -357,7 +357,7 @@ static void enc28j60_mem_read(struct enc28j60_net *priv,
reg = nolock_regw_read(priv, ERDPTL);
if (reg != addr)
printk(KERN_DEBUG DRV_NAME ": %s() error writing ERDPT "
- "(0x%04x - 0x%04x)\n", __FUNCTION__, reg, addr);
+ "(0x%04x - 0x%04x)\n", __func__, reg, addr);
}
#endif
spi_read_buf(priv, len, data);
@@ -380,7 +380,7 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
if (reg != TXSTART_INIT)
printk(KERN_DEBUG DRV_NAME
": %s() ERWPT:0x%04x != 0x%04x\n",
- __FUNCTION__, reg, TXSTART_INIT);
+ __func__, reg, TXSTART_INIT);
}
#endif
/* Set the TXND pointer to correspond to the packet size given */
@@ -390,13 +390,13 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME
": %s() after control byte ERWPT:0x%04x\n",
- __FUNCTION__, nolock_regw_read(priv, EWRPTL));
+ __func__, nolock_regw_read(priv, EWRPTL));
/* copy the packet into the transmit buffer */
spi_write_buf(priv, len, data);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME
": %s() after write packet ERWPT:0x%04x, len=%d\n",
- __FUNCTION__, nolock_regw_read(priv, EWRPTL), len);
+ __func__, nolock_regw_read(priv, EWRPTL), len);
mutex_unlock(&priv->lock);
}
@@ -495,7 +495,7 @@ static int enc28j60_set_hw_macaddr(struct net_device *ndev)
if (netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME
": %s() Hardware must be disabled to set "
- "Mac address\n", __FUNCTION__);
+ "Mac address\n", __func__);
ret = -EBUSY;
}
mutex_unlock(&priv->lock);
@@ -575,7 +575,7 @@ static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
if (start > 0x1FFF || end > 0x1FFF || start > end) {
if (netif_msg_drv(priv))
printk(KERN_ERR DRV_NAME ": %s(%d, %d) RXFIFO "
- "bad parameters!\n", __FUNCTION__, start, end);
+ "bad parameters!\n", __func__, start, end);
return;
}
/* set receive buffer start + end */
@@ -591,7 +591,7 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
if (start > 0x1FFF || end > 0x1FFF || start > end) {
if (netif_msg_drv(priv))
printk(KERN_ERR DRV_NAME ": %s(%d, %d) TXFIFO "
- "bad parameters!\n", __FUNCTION__, start, end);
+ "bad parameters!\n", __func__, start, end);
return;
}
/* set transmit buffer start + end */
@@ -630,7 +630,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
u8 reg;
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __FUNCTION__,
+ printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __func__,
priv->full_duplex ? "FullDuplex" : "HalfDuplex");
mutex_lock(&priv->lock);
@@ -661,7 +661,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
if (reg == 0x00 || reg == 0xff) {
if (netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() Invalid RevId %d\n",
- __FUNCTION__, reg);
+ __func__, reg);
return 0;
}
@@ -724,7 +724,7 @@ static void enc28j60_hw_enable(struct enc28j60_net *priv)
/* enable interrupts */
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
- __FUNCTION__);
+ __func__);
enc28j60_phy_write(priv, PHIE, PHIE_PGEIE | PHIE_PLNKIE);
@@ -888,7 +888,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
if (netif_msg_rx_err(priv))
dev_err(&ndev->dev,
"%s() Invalid packet address!! 0x%04x\n",
- __FUNCTION__, priv->next_pk_ptr);
+ __func__, priv->next_pk_ptr);
/* packet address corrupted: reset RX logic */
mutex_lock(&priv->lock);
nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
@@ -917,7 +917,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
rxstat |= rsv[4];
if (netif_msg_rx_status(priv))
- enc28j60_dump_rsv(priv, __FUNCTION__, next_packet, len, rxstat);
+ enc28j60_dump_rsv(priv, __func__, next_packet, len, rxstat);
if (!RSV_GETBIT(rxstat, RSV_RXOK)) {
if (netif_msg_rx_err(priv))
@@ -941,7 +941,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
len, skb_put(skb, len));
if (netif_msg_pktdata(priv))
- dump_packet(__FUNCTION__, skb->len, skb->data);
+ dump_packet(__func__, skb->len, skb->data);
skb->protocol = eth_type_trans(skb, ndev);
/* update statistics */
ndev->stats.rx_packets++;
@@ -958,7 +958,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
erxrdpt = erxrdpt_workaround(next_packet, RXSTART_INIT, RXEND_INIT);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT:0x%04x\n",
- __FUNCTION__, erxrdpt);
+ __func__, erxrdpt);
mutex_lock(&priv->lock);
nolock_regw_write(priv, ERXRDPTL, erxrdpt);
@@ -968,7 +968,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
reg = nolock_regw_read(priv, ERXRDPTL);
if (reg != erxrdpt)
printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT verify "
- "error (0x%04x - 0x%04x)\n", __FUNCTION__,
+ "error (0x%04x - 0x%04x)\n", __func__,
reg, erxrdpt);
}
#endif
@@ -1006,7 +1006,7 @@ static int enc28j60_get_free_rxfifo(struct enc28j60_net *priv)
mutex_unlock(&priv->lock);
if (netif_msg_rx_status(priv))
printk(KERN_DEBUG DRV_NAME ": %s() free_space = %d\n",
- __FUNCTION__, free_space);
+ __func__, free_space);
return free_space;
}
@@ -1022,7 +1022,7 @@ static void enc28j60_check_link_status(struct net_device *ndev)
reg = enc28j60_phy_read(priv, PHSTAT2);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() PHSTAT1: %04x, "
- "PHSTAT2: %04x\n", __FUNCTION__,
+ "PHSTAT2: %04x\n", __func__,
enc28j60_phy_read(priv, PHSTAT1), reg);
duplex = reg & PHSTAT2_DPXSTAT;
@@ -1095,7 +1095,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
int intflags, loop;
if (netif_msg_intr(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
/* disable further interrupts */
locked_reg_bfclr(priv, EIE, EIE_INTIE);
@@ -1198,7 +1198,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
/* re-enable interrupts */
locked_reg_bfset(priv, EIE, EIE_INTIE);
if (netif_msg_intr(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __func__);
}
/*
@@ -1213,7 +1213,7 @@ static void enc28j60_hw_tx(struct enc28j60_net *priv)
": Tx Packet Len:%d\n", priv->tx_skb->len);
if (netif_msg_pktdata(priv))
- dump_packet(__FUNCTION__,
+ dump_packet(__func__,
priv->tx_skb->len, priv->tx_skb->data);
enc28j60_packet_write(priv, priv->tx_skb->len, priv->tx_skb->data);
@@ -1254,7 +1254,7 @@ static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_tx_queued(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
/* If some error occurs while trying to transmit this
* packet, you should return '1' from this function.
@@ -1325,7 +1325,7 @@ static int enc28j60_net_open(struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
if (!is_valid_ether_addr(dev->dev_addr)) {
if (netif_msg_ifup(priv)) {
@@ -1363,7 +1363,7 @@ static int enc28j60_net_close(struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
enc28j60_hw_disable(priv);
enc28j60_lowpower(priv, true);
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index 37bfeea..9164abb 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -321,7 +321,7 @@ static struct mii_phy_def bcm5248_phy_def = {
static int m88e1111_init(struct mii_phy *phy)
{
- pr_debug("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+ pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
phy_write(phy, 0x14, 0x0ce3);
phy_write(phy, 0x18, 0x4101);
phy_write(phy, 0x09, 0x0e00);
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 804698f..d85717e 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -85,7 +85,7 @@ struct ixgb_adapter;
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __FUNCTION__ , ## args))
+ __func__ , ## args))
/* TX/RX descriptor defines */
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 90b5383..b25022f 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -32,7 +31,12 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
+
+#ifdef CONFIG_IXGBE_LRO
#include <linux/inet_lro.h>
+#define IXGBE_MAX_LRO_AGGREGATE 32
+#define IXGBE_MAX_LRO_DESCRIPTORS 8
+#endif
#include "ixgbe_type.h"
#include "ixgbe_common.h"
@@ -41,13 +45,11 @@
#include <linux/dca.h>
#endif
-#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args)
-
#define PFX "ixgbe: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __FUNCTION__ , ## args)))
+ __func__ , ## args)))
/* TX/RX descriptor defines */
#define IXGBE_DEFAULT_TXD 1024
@@ -58,15 +60,6 @@
#define IXGBE_MAX_RXD 4096
#define IXGBE_MIN_RXD 64
-#define IXGBE_DEFAULT_RXQ 1
-#define IXGBE_MAX_RXQ 1
-#define IXGBE_MIN_RXQ 1
-
-#define IXGBE_DEFAULT_ITR_RX_USECS 125 /* 8k irqs/sec */
-#define IXGBE_DEFAULT_ITR_TX_USECS 250 /* 4k irqs/sec */
-#define IXGBE_MIN_ITR_USECS 100 /* 500k irqs/sec */
-#define IXGBE_MAX_ITR_USECS 10000 /* 100 irqs/sec */
-
/* flow control */
#define IXGBE_DEFAULT_FCRTL 0x10000
#define IXGBE_MIN_FCRTL 0x40
@@ -88,9 +81,6 @@
#define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
-/* How many Tx Descriptors do we need to call netif_wake_queue? */
-#define IXGBE_TX_QUEUE_WAKE 16
-
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IXGBE_RX_BUFFER_WRITE 16 /* Must be power of 2 */
@@ -101,9 +91,6 @@
#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
-#define IXGBE_MAX_LRO_DESCRIPTORS 8
-#define IXGBE_MAX_LRO_AGGREGATE 32
-
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -119,6 +106,7 @@ struct ixgbe_rx_buffer {
dma_addr_t dma;
struct page *page;
dma_addr_t page_dma;
+ unsigned int page_offset;
};
struct ixgbe_queue_stats {
@@ -154,17 +142,16 @@ struct ixgbe_ring {
/* cpu for tx queue */
int cpu;
#endif
+#ifdef CONFIG_IXGBE_LRO
struct net_lro_mgr lro_mgr;
bool lro_used;
+#endif
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 */
+ u16 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;
- u16 itr_register;
- char name[IFNAMSIZ + 5];
u16 work_limit; /* max work per interrupt */
u16 rx_buf_len;
};
@@ -191,8 +178,8 @@ struct ixgbe_q_vector {
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;
+ u8 tx_itr;
+ u8 rx_itr;
u32 eitr;
};
@@ -240,7 +227,9 @@ struct ixgbe_adapter {
/* TX */
struct ixgbe_ring *tx_ring; /* One per active queue */
+ int num_tx_queues;
u64 restart_queue;
+ u64 hw_csum_tx_good;
u64 lsc_int;
u64 hw_tso_ctxt;
u64 hw_tso6_ctxt;
@@ -249,12 +238,10 @@ struct ixgbe_adapter {
/* RX */
struct ixgbe_ring *rx_ring; /* One per active queue */
- u64 hw_csum_tx_good;
+ int num_rx_queues;
u64 hw_csum_rx_error;
u64 hw_csum_rx_good;
u64 non_eop_descs;
- int num_tx_queues;
- int num_rx_queues;
int num_msix_vectors;
struct ixgbe_ring_feature ring_feature[3];
struct msix_entry *msix_entries;
@@ -301,14 +288,23 @@ struct ixgbe_adapter {
struct ixgbe_hw_stats stats;
/* Interrupt Throttle Rate */
- u32 rx_eitr;
- u32 tx_eitr;
+ u32 eitr_param;
unsigned long state;
u64 tx_busy;
+#ifndef IXGBE_NO_INET_LRO
u64 lro_aggregated;
u64 lro_flushed;
u64 lro_no_desc;
+#endif
+ unsigned int tx_ring_count;
+ unsigned int rx_ring_count;
+
+ u32 link_speed;
+ bool link_up;
+ unsigned long link_check_timeout;
+
+ struct work_struct watchdog_task;
};
enum ixbge_state_t {
@@ -330,11 +326,11 @@ extern int ixgbe_up(struct ixgbe_adapter *adapter);
extern void ixgbe_down(struct ixgbe_adapter *adapter);
extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
extern void ixgbe_reset(struct ixgbe_adapter *adapter);
-extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
-extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rxdr);
-extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *txdr);
+extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index ba09063..7cddcfb 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -39,68 +38,59 @@
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
-static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *autoneg);
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
- u32 *speed, bool *autoneg);
-static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up);
-static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
-
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+/**
+ */
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
- hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
- hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE;
- hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE;
- hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES;
-
- /* PHY ops are filled in by default properly for Fiber only */
- if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
- hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
- hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
- hw->mac.ops.get_link_settings =
- &ixgbe_get_copper_link_settings_82598;
-
- /* Call PHY identify routine to get the phy type */
- ixgbe_identify_phy(hw);
-
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
- hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
- hw->phy.ops.setup_link_speed =
- &ixgbe_setup_tnx_phy_link_speed;
- break;
- default:
- break;
- }
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_phy_info *phy = &hw->phy;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy_generic(hw);
+
+ /* PHY Init */
+ switch (phy->type) {
+ default:
+ break;
}
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82598;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82598;
+ }
+
+ mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+
return 0;
}
/**
- * ixgbe_get_link_settings_82598 - Determines default link settings
+ * ixgbe_get_link_capabilities_82598 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @autoneg: boolean auto-negotiation value
*
- * Determines the default link settings by reading the AUTOC register.
+ * Determines the link capabilities by reading the AUTOC register.
**/
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *autoneg)
+static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
{
s32 status = 0;
s32 autoc_reg;
@@ -149,15 +139,16 @@ static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
}
/**
- * ixgbe_get_copper_link_settings_82598 - Determines default link settings
+ * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @autoneg: boolean auto-negotiation value
*
- * Determines the default link settings by reading the AUTOC register.
+ * Determines the link capabilities by reading the AUTOC register.
**/
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
- u32 *speed, bool *autoneg)
+s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
{
s32 status = IXGBE_ERR_LINK_SETUP;
u16 speed_ability;
@@ -165,9 +156,9 @@ static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = ixgbe_read_phy_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &speed_ability);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &speed_ability);
if (status == 0) {
if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
@@ -195,11 +186,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598EB_CX4:
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ case IXGBE_DEV_ID_82598EB_XF_LR:
media_type = ixgbe_media_type_fiber;
break;
- case IXGBE_DEV_ID_82598AT_DUAL_PORT:
- media_type = ixgbe_media_type_copper;
- break;
default:
media_type = ixgbe_media_type_unknown;
break;
@@ -209,6 +198,122 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_setup_fc_82598 - Configure flow control settings
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Configures the flow control settings based on SW configuration. This
+ * function is used for 802.3x flow control configuration only.
+ **/
+s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ u32 frctl_reg;
+ u32 rmcs_reg;
+
+ if (packetbuf_num < 0 || packetbuf_num > 7) {
+ hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+ " 0-7\n", packetbuf_num);
+ }
+
+ frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+
+ rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
+
+ /*
+ * 10 gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.type == ixgbe_fc_default)
+ hw->fc.type = ixgbe_fc_full;
+
+ /*
+ * We want to save off the original Flow Control configuration just in
+ * case we get disconnected and then reconnected into a different hub
+ * or switch with different Flow Control capabilities.
+ */
+ hw->fc.original_type = hw->fc.type;
+
+ /*
+ * The possible values of the "flow_control" parameter are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames but not
+ * send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but we do not
+ * support receiving pause frames)
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+ * other: Invalid.
+ */
+ switch (hw->fc.type) {
+ case ixgbe_fc_none:
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled,
+ * and Tx Flow control is disabled.
+ */
+ frctl_reg |= IXGBE_FCTRL_RFCE;
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is disabled,
+ * by a software over-ride.
+ */
+ rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+ break;
+ case ixgbe_fc_full:
+ /*
+ * Flow control (both Rx and Tx) is enabled by a software
+ * over-ride.
+ */
+ frctl_reg |= IXGBE_FCTRL_RFCE;
+ rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+ break;
+ default:
+ /* We should never get here. The value should be 0-3. */
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ break;
+ }
+
+ /* Enable 802.3x based flow control settings. */
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+ IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+
+ /*
+ * Check for invalid software configuration, zeros are completely
+ * invalid for all parameters used past this point, and if we enable
+ * flow control with zero water marks, we blast flow control packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Flow control structure initialized incorrectly\n");
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
+ }
+
+ /*
+ * We need to set up the Receive Threshold high and low water
+ * marks as well as (optionally) enabling the transmission of
+ * XON frames.
+ */
+ if (hw->fc.type & ixgbe_fc_tx_pause) {
+ if (hw->fc.send_xon) {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+ (hw->fc.low_water | IXGBE_FCRTL_XONE));
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+ hw->fc.low_water);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
+ (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+ return 0;
+}
+
+/**
* ixgbe_setup_mac_link_82598 - Configures MAC link settings
* @hw: pointer to hardware structure
*
@@ -252,8 +357,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
}
if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
- hw_dbg(hw,
- "Autonegotiation did not complete.\n");
+ hw_dbg(hw, "Autonegotiation did not complete.\n");
}
}
}
@@ -263,8 +367,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
- hw->fc.type = hw->fc.original_type;
- ixgbe_setup_fc(hw, 0);
+ hw->fc.original_type = hw->fc.type;
+ ixgbe_setup_fc_82598(hw, 0);
/* Add delay to filter out noises during initial link setup */
msleep(50);
@@ -277,20 +381,35 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @link_up: true is link is up, false otherwise
+ * @link_up_wait_to_complete: bool used to wait for link up or not
*
* Reads the links register to determine if link is up and the current speed
**/
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
+static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed, bool *link_up,
+ bool link_up_wait_to_complete)
{
u32 links_reg;
+ u32 i;
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
-
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = true;
- else
- *link_up = false;
+ if (link_up_wait_to_complete) {
+ for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+ if (links_reg & IXGBE_LINKS_UP) {
+ *link_up = true;
+ break;
+ } else {
+ *link_up = false;
+ }
+ msleep(100);
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ }
+ } else {
+ if (links_reg & IXGBE_LINKS_UP)
+ *link_up = true;
+ else
+ *link_up = false;
+ }
if (links_reg & IXGBE_LINKS_SPEED)
*speed = IXGBE_LINK_SPEED_10GB_FULL;
@@ -300,6 +419,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
return 0;
}
+
/**
* ixgbe_setup_mac_link_speed_82598 - Set MAC link speed
* @hw: pointer to hardware structure
@@ -310,18 +430,18 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
- u32 speed, bool autoneg,
- bool autoneg_wait_to_complete)
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
{
s32 status = 0;
/* If speed is 10G, then check for CX4 or XAUI. */
if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
- (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4)))
+ (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg))
+ } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
- else if (autoneg) {
+ } else if (autoneg) {
/* BX mode - Autonegotiate 1G */
if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
@@ -340,7 +460,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
}
return status;
@@ -358,18 +478,17 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
/* Restart autonegotiation on PHY */
- if (hw->phy.ops.setup_link)
- status = hw->phy.ops.setup_link(hw);
+ status = hw->phy.ops.setup_link(hw);
- /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+ /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
/* Set up MAC */
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
return status;
}
@@ -383,23 +502,23 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
*
* Sets the link speed in the AUTOC register in the MAC and restarts link.
**/
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
{
- s32 status = 0;
+ s32 status;
/* Setup the PHY according to input speed */
- if (hw->phy.ops.setup_link_speed)
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
/* Set up MAC */
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
return status;
}
@@ -408,7 +527,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
* ixgbe_reset_hw_82598 - Performs hardware reset
* @hw: pointer to hardware structure
*
- * Resets the hardware by reseting the transmit and receive units, masks and
+ * Resets the hardware by resetting the transmit and receive units, masks and
* clears all interrupts, performing a PHY reset, and performing a link (MAC)
* reset.
**/
@@ -422,35 +541,44 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
u8 analog_val;
/* Call adapter stop to disable tx/rx and clear interrupts */
- ixgbe_stop_adapter(hw);
+ hw->mac.ops.stop_adapter(hw);
/*
- * Power up the Atlas TX lanes if they are currently powered down.
- * Atlas TX lanes are powered down for MAC loopback tests, but
+ * Power up the Atlas Tx lanes if they are currently powered down.
+ * Atlas Tx lanes are powered down for MAC loopback tests, but
* they are not automatically restored on reset.
*/
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
- /* Enable TX Atlas so packets can be transmitted again */
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+ /* Enable Tx Atlas so packets can be transmitted again */
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+ analog_val);
}
/* Reset PHY */
- ixgbe_reset_phy(hw);
+ if (hw->phy.reset_disable == false)
+ hw->phy.ops.reset(hw);
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
@@ -503,29 +631,311 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
} else {
hw->mac.link_attach_type =
- (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
+ (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
hw->mac.link_settings_loaded = true;
}
/* Store the permanent mac address */
- ixgbe_get_mac_addr(hw, hw->mac.perm_addr);
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
return status;
}
+/**
+ * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq set index
+ **/
+s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+ rar_high &= ~IXGBE_RAH_VIND_MASK;
+ rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq clear index (not used in 82598, but elsewhere)
+ **/
+static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+ if (rar_high & IXGBE_RAH_VIND_MASK) {
+ rar_high &= ~IXGBE_RAH_VIND_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+ }
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_set_vfta_82598 - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VFTA
+ * @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on)
+{
+ u32 regindex;
+ u32 bitindex;
+ u32 bits;
+ u32 vftabyte;
+
+ if (vlan > 4095)
+ return IXGBE_ERR_PARAM;
+
+ /* Determine 32-bit word position in array */
+ regindex = (vlan >> 5) & 0x7F; /* upper seven bits */
+
+ /* Determine the location of the (VMD) queue index */
+ vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
+ bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
+
+ /* Set the nibble for VMD queue index */
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
+ bits &= (~(0x0F << bitindex));
+ bits |= (vind << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
+
+ /* Determine the location of the bit for this VLAN id */
+ bitindex = vlan & 0x1F; /* lower five bits */
+
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+ if (vlan_on)
+ /* Turn on this VLAN id */
+ bits |= (1 << bitindex);
+ else
+ /* Turn off this VLAN id */
+ bits &= ~(1 << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vfta_82598 - Clear VLAN filter table
+ * @hw: pointer to hardware structure
+ *
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
+{
+ u32 offset;
+ u32 vlanbyte;
+
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+ for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
+ 0);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_start_82598 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ **/
+static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
+{
+ ixgbe_link_speed speed = 0;
+ bool link_up = 0;
+ u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ /*
+ * Link must be up to auto-blink the LEDs on the 82598EB MAC;
+ * force it if link is down.
+ */
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+ if (!link_up) {
+ autoc_reg |= IXGBE_AUTOC_FLU;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ msleep(10);
+ }
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg |= IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ **/
+static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
+{
+ u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ autoc_reg &= ~IXGBE_AUTOC_FLU;
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg &= ~IXGBE_LED_BLINK(index);
+ led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
+ * @hw: pointer to hardware structure
+ * @reg: analog register to read
+ * @val: read value
+ *
+ * Performs read operation to Atlas analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+ u32 atlas_ctl;
+
+ IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
+ IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+ atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
+ *val = (u8)atlas_ctl;
+
+ return 0;
+}
+
+/**
+ * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
+ * @hw: pointer to hardware structure
+ * @reg: atlas register to write
+ * @val: value to write
+ *
+ * Performs write operation to Atlas analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+ u32 atlas_ctl;
+
+ atlas_ctl = (reg << 8) | val;
+ IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+{
+ s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598EB_CX4:
+ case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ break;
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
+
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+
+ return physical_layer;
+}
+
static struct ixgbe_mac_operations mac_ops_82598 = {
- .reset = &ixgbe_reset_hw_82598,
+ .init_hw = &ixgbe_init_hw_generic,
+ .reset_hw = &ixgbe_reset_hw_82598,
+ .start_hw = &ixgbe_start_hw_generic,
+ .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82598,
+ .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+ .get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .stop_adapter = &ixgbe_stop_adapter_generic,
+ .read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
+ .write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
- .check_link = &ixgbe_check_mac_link_82598,
.setup_link_speed = &ixgbe_setup_mac_link_speed_82598,
- .get_link_settings = &ixgbe_get_link_settings_82598,
+ .check_link = &ixgbe_check_mac_link_82598,
+ .get_link_capabilities = &ixgbe_get_link_capabilities_82598,
+ .led_on = &ixgbe_led_on_generic,
+ .led_off = &ixgbe_led_off_generic,
+ .blink_led_start = &ixgbe_blink_led_start_82598,
+ .blink_led_stop = &ixgbe_blink_led_stop_82598,
+ .set_rar = &ixgbe_set_rar_generic,
+ .clear_rar = &ixgbe_clear_rar_generic,
+ .set_vmdq = &ixgbe_set_vmdq_82598,
+ .clear_vmdq = &ixgbe_clear_vmdq_82598,
+ .init_rx_addrs = &ixgbe_init_rx_addrs_generic,
+ .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic,
+ .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic,
+ .enable_mc = &ixgbe_enable_mc_generic,
+ .disable_mc = &ixgbe_disable_mc_generic,
+ .clear_vfta = &ixgbe_clear_vfta_82598,
+ .set_vfta = &ixgbe_set_vfta_82598,
+ .setup_fc = &ixgbe_setup_fc_82598,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
+ .init_params = &ixgbe_init_eeprom_params_generic,
+ .read = &ixgbe_read_eeprom_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .update_checksum = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82598 = {
+ .identify = &ixgbe_identify_phy_generic,
+ /* .identify_sfp = &ixgbe_identify_sfp_module_generic, */
+ .reset = &ixgbe_reset_phy_generic,
+ .read_reg = &ixgbe_read_phy_reg_generic,
+ .write_reg = &ixgbe_write_phy_reg_generic,
+ .setup_link = &ixgbe_setup_phy_link_generic,
+ .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
};
struct ixgbe_info ixgbe_82598_info = {
.mac = ixgbe_mac_82598EB,
.get_invariants = &ixgbe_get_invariants_82598,
.mac_ops = &mac_ops_82598,
+ .eeprom_ops = &eeprom_ops_82598,
+ .phy_ops = &phy_ops_82598,
};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 9c0d0a1..f67c684 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -33,20 +32,28 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw);
-
static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw);
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+ u16 count);
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw);
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
/**
- * ixgbe_start_hw - Prepare hardware for TX/RX
+ * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
*
* Starts the hardware by filling the bus info structure and media type, clears
@@ -54,7 +61,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
* table, VLAN filter table, calls routine to set up link and flow control
* settings, and leaves transmit and receive units disabled and uninitialized
**/
-s32 ixgbe_start_hw(struct ixgbe_hw *hw)
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
{
u32 ctrl_ext;
@@ -62,22 +69,22 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
hw->phy.media_type = hw->mac.ops.get_media_type(hw);
/* Identify the PHY */
- ixgbe_identify_phy(hw);
+ hw->phy.ops.identify(hw);
/*
* Store MAC address from RAR0, clear receive address registers, and
* clear the multicast table
*/
- ixgbe_init_rx_addrs(hw);
+ hw->mac.ops.init_rx_addrs(hw);
/* Clear the VLAN filter table */
- ixgbe_clear_vfta(hw);
+ hw->mac.ops.clear_vfta(hw);
/* Set up link */
hw->mac.ops.setup_link(hw);
/* Clear statistics registers */
- ixgbe_clear_hw_cntrs(hw);
+ hw->mac.ops.clear_hw_cntrs(hw);
/* Set No Snoop Disable */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -92,34 +99,34 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
}
/**
- * ixgbe_init_hw - Generic hardware initialization
+ * ixgbe_init_hw_generic - Generic hardware initialization
* @hw: pointer to hardware structure
*
- * Initialize the hardware by reseting the hardware, filling the bus info
+ * Initialize the hardware by resetting the hardware, filling the bus info
* structure and media type, clears all on chip counters, initializes receive
* address registers, multicast table, VLAN filter table, calls routine to set
* up link and flow control settings, and leaves transmit and receive units
* disabled and uninitialized
**/
-s32 ixgbe_init_hw(struct ixgbe_hw *hw)
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
{
/* Reset the hardware */
- hw->mac.ops.reset(hw);
+ hw->mac.ops.reset_hw(hw);
/* Start the HW */
- ixgbe_start_hw(hw);
+ hw->mac.ops.start_hw(hw);
return 0;
}
/**
- * ixgbe_clear_hw_cntrs - Generic clear hardware counters
+ * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
* @hw: pointer to hardware structure
*
* Clears all hardware statistics counters by reading them from the hardware
* Statistics counters are clear on read.
**/
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
{
u16 i = 0;
@@ -191,7 +198,36 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
}
/**
- * ixgbe_get_mac_addr - Generic get MAC address
+ * ixgbe_read_pba_num_generic - Reads part number from EEPROM
+ * @hw: pointer to hardware structure
+ * @pba_num: stores the part number from the EEPROM
+ *
+ * Reads the part number from the EEPROM.
+ **/
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
+{
+ s32 ret_val;
+ u16 data;
+
+ ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ *pba_num = (u32)(data << 16);
+
+ ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ *pba_num |= data;
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_mac_addr_generic - Generic get MAC address
* @hw: pointer to hardware structure
* @mac_addr: Adapter MAC address
*
@@ -199,7 +235,7 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
* A reset of the adapter must be performed prior to calling this function
* in order for the MAC address to have been loaded from the EEPROM into RAR0
**/
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
{
u32 rar_high;
u32 rar_low;
@@ -217,30 +253,8 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
return 0;
}
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
-{
- s32 ret_val;
- u16 data;
-
- ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM0_PTR, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *part_num = (u32)(data << 16);
-
- ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM1_PTR, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *part_num |= data;
-
- return 0;
-}
-
/**
- * ixgbe_stop_adapter - Generic stop TX/RX units
+ * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
* @hw: pointer to hardware structure
*
* Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
@@ -248,7 +262,7 @@ s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
* the shared code and drivers to determine if the adapter is in a stopped
* state and should not touch the hardware.
**/
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
{
u32 number_of_queues;
u32 reg_val;
@@ -264,6 +278,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
reg_val &= ~(IXGBE_RXCTRL_RXEN);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
+ IXGBE_WRITE_FLUSH(hw);
msleep(2);
/* Clear interrupt mask to stop from interrupts being generated */
@@ -273,7 +288,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
IXGBE_READ_REG(hw, IXGBE_EICR);
/* Disable the transmit unit. Each queue must be disabled. */
- number_of_queues = hw->mac.num_tx_queues;
+ number_of_queues = hw->mac.max_tx_queues;
for (i = 0; i < number_of_queues; i++) {
reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
if (reg_val & IXGBE_TXDCTL_ENABLE) {
@@ -282,15 +297,22 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
}
}
+ /*
+ * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+ * access and verify no pending requests
+ */
+ if (ixgbe_disable_pcie_master(hw) != 0)
+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+
return 0;
}
/**
- * ixgbe_led_on - Turns on the software controllable LEDs.
+ * ixgbe_led_on_generic - Turns on the software controllable LEDs.
* @hw: pointer to hardware structure
* @index: led number to turn on
**/
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
{
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
@@ -304,11 +326,11 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
}
/**
- * ixgbe_led_off - Turns off the software controllable LEDs.
+ * ixgbe_led_off_generic - Turns off the software controllable LEDs.
* @hw: pointer to hardware structure
* @index: led number to turn off
**/
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
{
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
@@ -321,15 +343,14 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
return 0;
}
-
/**
- * ixgbe_init_eeprom - Initialize EEPROM params
+ * ixgbe_init_eeprom_params_generic - Initialize EEPROM params
* @hw: pointer to hardware structure
*
* Initializes the EEPROM parameters ixgbe_eeprom_info within the
* ixgbe_hw struct in order to set up EEPROM access.
**/
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
{
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
u32 eec;
@@ -337,6 +358,9 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
if (eeprom->type == ixgbe_eeprom_uninitialized) {
eeprom->type = ixgbe_eeprom_none;
+ /* Set default semaphore delay to 10ms which is a well
+ * tested value */
+ eeprom->semaphore_delay = 10;
/*
* Check for EEPROM present first.
@@ -369,18 +393,85 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
}
/**
- * ixgbe_read_eeprom - Read EEPROM word using EERD
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
+ *
+ * Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status;
+ u16 word_in;
+ u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ /* Prepare the EEPROM for reading */
+ status = ixgbe_acquire_eeprom(hw);
+
+ if (status == 0) {
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ if (status == 0) {
+ ixgbe_standby_eeprom(hw);
+
+ /*
+ * Some SPI eeproms use the 8th address bit embedded in the
+ * opcode
+ */
+ if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ *data = (word_in >> 8) | (word_in << 8);
+
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_generic - Read EEPROM word using EERD
* @hw: pointer to hardware structure
* @offset: offset of word in the EEPROM to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
u32 eerd;
s32 status;
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) +
IXGBE_EEPROM_READ_REG_START;
@@ -389,10 +480,11 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
if (status == 0)
*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_READ_REG_DATA);
+ IXGBE_EEPROM_READ_REG_DATA);
else
hw_dbg(hw, "Eeprom read timed out\n");
+out:
return status;
}
@@ -420,6 +512,58 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ *
+ * Prepares EEPROM for access using bit-bang method. This function should
+ * be called before issuing a command to the EEPROM.
+ **/
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u32 eec;
+ u32 i;
+
+ if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
+ status = IXGBE_ERR_SWFW_SYNC;
+
+ if (status == 0) {
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /* Request EEPROM Access */
+ eec |= IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+ for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ if (eec & IXGBE_EEC_GNT)
+ break;
+ udelay(5);
+ }
+
+ /* Release if grant not acquired */
+ if (!(eec & IXGBE_EEC_GNT)) {
+ eec &= ~IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ hw_dbg(hw, "Could not acquire EEPROM grant\n");
+
+ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ /* Setup EEPROM for Read/Write */
+ if (status == 0) {
+ /* Clear CS and SK */
+ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+ }
+ return status;
+}
+
+/**
* ixgbe_get_eeprom_semaphore - Get hardware semaphore
* @hw: pointer to hardware structure
*
@@ -475,7 +619,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
*/
if (i >= timeout) {
hw_dbg(hw, "Driver can't access the Eeprom - Semaphore "
- "not granted.\n");
+ "not granted.\n");
ixgbe_release_eeprom_semaphore(hw);
status = IXGBE_ERR_EEPROM;
}
@@ -503,6 +647,217 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_ready_eeprom - Polls for EEPROM ready
+ * @hw: pointer to hardware structure
+ **/
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u16 i;
+ u8 spi_stat_reg;
+
+ /*
+ * Read "Status Register" repeatedly until the LSB is cleared. The
+ * EEPROM will signal that the command has been completed by clearing
+ * bit 0 of the internal status register. If it's not cleared within
+ * 5 milliseconds, then error out.
+ */
+ for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
+ ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
+ spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
+ if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
+ break;
+
+ udelay(5);
+ ixgbe_standby_eeprom(hw);
+ };
+
+ /*
+ * On some parts, SPI write time could vary from 0-20mSec on 3.3V
+ * devices (and only 0-5mSec on 5V devices)
+ */
+ if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
+ hw_dbg(hw, "SPI EEPROM Status error\n");
+ status = IXGBE_ERR_EEPROM;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
+{
+ u32 eec;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /* Toggle CS to flush commands */
+ eec |= IXGBE_EEC_CS;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+ eec &= ~IXGBE_EEC_CS;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
+ * @hw: pointer to hardware structure
+ * @data: data to send to the EEPROM
+ * @count: number of bits to shift out
+ **/
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+ u16 count)
+{
+ u32 eec;
+ u32 mask;
+ u32 i;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /*
+ * Mask is used to shift "count" bits of "data" out to the EEPROM
+ * one bit at a time. Determine the starting bit based on count
+ */
+ mask = 0x01 << (count - 1);
+
+ for (i = 0; i < count; i++) {
+ /*
+ * A "1" is shifted out to the EEPROM by setting bit "DI" to a
+ * "1", and then raising and then lowering the clock (the SK
+ * bit controls the clock input to the EEPROM). A "0" is
+ * shifted out to the EEPROM by setting "DI" to "0" and then
+ * raising and then lowering the clock.
+ */
+ if (data & mask)
+ eec |= IXGBE_EEC_DI;
+ else
+ eec &= ~IXGBE_EEC_DI;
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+
+ udelay(1);
+
+ ixgbe_raise_eeprom_clk(hw, &eec);
+ ixgbe_lower_eeprom_clk(hw, &eec);
+
+ /*
+ * Shift mask to signify next bit of data to shift in to the
+ * EEPROM
+ */
+ mask = mask >> 1;
+ };
+
+ /* We leave the "DI" bit set to "0" when we leave this routine. */
+ eec &= ~IXGBE_EEC_DI;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
+ * @hw: pointer to hardware structure
+ **/
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
+{
+ u32 eec;
+ u32 i;
+ u16 data = 0;
+
+ /*
+ * In order to read a register from the EEPROM, we need to shift
+ * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
+ * the clock input to the EEPROM (setting the SK bit), and then reading
+ * the value of the "DO" bit. During this "shifting in" process the
+ * "DI" bit should always be clear.
+ */
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
+
+ for (i = 0; i < count; i++) {
+ data = data << 1;
+ ixgbe_raise_eeprom_clk(hw, &eec);
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec &= ~(IXGBE_EEC_DI);
+ if (eec & IXGBE_EEC_DO)
+ data |= 1;
+
+ ixgbe_lower_eeprom_clk(hw, &eec);
+ }
+
+ return data;
+}
+
+/**
+ * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eec: EEC register's current value
+ **/
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+ /*
+ * Raise the clock input to the EEPROM
+ * (setting the SK bit), then delay
+ */
+ *eec = *eec | IXGBE_EEC_SK;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eecd: EECD's current value
+ **/
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+ /*
+ * Lower the clock input to the EEPROM (clearing the SK bit), then
+ * delay
+ */
+ *eec = *eec & ~IXGBE_EEC_SK;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_release_eeprom - Release EEPROM, release semaphores
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
+{
+ u32 eec;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec |= IXGBE_EEC_CS; /* Pull CS high */
+ eec &= ~IXGBE_EEC_SK; /* Lower SCK */
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+
+ udelay(1);
+
+ /* Stop requesting EEPROM access */
+ eec &= ~IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+}
+
+/**
* ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
* @hw: pointer to hardware structure
**/
@@ -517,7 +872,7 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
/* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (ixgbe_read_eeprom(hw, i, &word) != 0) {
+ if (hw->eeprom.ops.read(hw, i, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -526,15 +881,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
/* Include all data from pointers except for the fw pointer */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
- ixgbe_read_eeprom(hw, i, &pointer);
+ hw->eeprom.ops.read(hw, i, &pointer);
/* Make sure the pointer seems valid */
if (pointer != 0xFFFF && pointer != 0) {
- ixgbe_read_eeprom(hw, pointer, &length);
+ hw->eeprom.ops.read(hw, pointer, &length);
if (length != 0xFFFF && length != 0) {
for (j = pointer+1; j <= pointer+length; j++) {
- ixgbe_read_eeprom(hw, j, &word);
+ hw->eeprom.ops.read(hw, j, &word);
checksum += word;
}
}
@@ -547,14 +902,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
}
/**
- * ixgbe_validate_eeprom_checksum - Validate EEPROM checksum
+ * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
* @hw: pointer to hardware structure
* @checksum_val: calculated checksum
*
* Performs checksum calculation and validates the EEPROM checksum. If the
* caller does not need checksum_val, the value can be NULL.
**/
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+ u16 *checksum_val)
{
s32 status;
u16 checksum;
@@ -565,12 +921,12 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
- status = ixgbe_read_eeprom(hw, 0, &checksum);
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status == 0) {
checksum = ixgbe_calc_eeprom_checksum(hw);
- ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+ hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
/*
* Verify read checksum from EEPROM is the same as
@@ -590,6 +946,33 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
}
/**
+ * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u16 checksum;
+
+ /*
+ * Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+ if (status == 0) {
+ checksum = ixgbe_calc_eeprom_checksum(hw);
+ status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
+ checksum);
+ } else {
+ hw_dbg(hw, "EEPROM read failed\n");
+ }
+
+ return status;
+}
+
+/**
* ixgbe_validate_mac_addr - Validate MAC address
* @mac_addr: pointer to MAC address.
*
@@ -607,58 +990,137 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
status = IXGBE_ERR_INVALID_MAC_ADDR;
/* Reject the zero address */
else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
- mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
+ mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
status = IXGBE_ERR_INVALID_MAC_ADDR;
return status;
}
/**
- * ixgbe_set_rar - Set RX address register
+ * ixgbe_set_rar_generic - Set Rx address register
* @hw: pointer to hardware structure
- * @addr: Address to put into receive address register
* @index: Receive address register to write
- * @vind: Vind to set RAR to
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq "set" or "pool" index
* @enable_addr: set flag that address is active
*
* Puts an ethernet address into a receive address register.
**/
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
- u32 enable_addr)
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr)
{
u32 rar_low, rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
- /*
- * HW expects these in little endian so we reverse the byte order from
- * network order (big endian) to little endian
- */
- rar_low = ((u32)addr[0] |
- ((u32)addr[1] << 8) |
- ((u32)addr[2] << 16) |
- ((u32)addr[3] << 24));
+ /* setup VMDq pool selection before this RAR gets enabled */
+ hw->mac.ops.set_vmdq(hw, index, vmdq);
- rar_high = ((u32)addr[4] |
- ((u32)addr[5] << 8) |
- ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK));
+ /* Make sure we are using a valid rar index range */
+ if (index < rar_entries) {
+ /*
+ * HW expects these in little endian so we reverse the byte
+ * order from network order (big endian) to little endian
+ */
+ rar_low = ((u32)addr[0] |
+ ((u32)addr[1] << 8) |
+ ((u32)addr[2] << 16) |
+ ((u32)addr[3] << 24));
+ /*
+ * Some parts put the VMDq setting in the extra RAH bits,
+ * so save everything except the lower 16 bits that hold part
+ * of the address and the address valid bit.
+ */
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+ rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
- if (enable_addr != 0)
- rar_high |= IXGBE_RAH_AV;
+ if (enable_addr != 0)
+ rar_high |= IXGBE_RAH_AV;
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", index);
+ }
return 0;
}
/**
- * ixgbe_init_rx_addrs - Initializes receive address filters.
+ * ixgbe_clear_rar_generic - Remove Rx address register
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
+ *
+ * Clears an ethernet address from a receive address register.
+ **/
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ /* Make sure we are using a valid rar index range */
+ if (index < rar_entries) {
+ /*
+ * Some parts put the VMDq setting in the extra RAH bits,
+ * so save everything except the lower 16 bits that hold part
+ * of the address and the address valid bit.
+ */
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", index);
+ }
+
+ /* clear VMDq pool/queue selection for this RAR */
+ hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
+
+ return 0;
+}
+
+/**
+ * ixgbe_enable_rar - Enable Rx address register
+ * @hw: pointer to hardware structure
+ * @index: index into the RAR table
+ *
+ * Enables the select receive address register.
+ **/
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high |= IXGBE_RAH_AV;
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ * ixgbe_disable_rar - Disable Rx address register
+ * @hw: pointer to hardware structure
+ * @index: index into the RAR table
+ *
+ * Disables the select receive address register.
+ **/
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= (~IXGBE_RAH_AV);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
* @hw: pointer to hardware structure
*
* Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
+ * of the receive address registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
**/
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
{
u32 i;
u32 rar_entries = hw->mac.num_rar_entries;
@@ -671,29 +1133,30 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
if (ixgbe_validate_mac_addr(hw->mac.addr) ==
IXGBE_ERR_INVALID_MAC_ADDR) {
/* Get the MAC address from the RAR0 for later reference */
- ixgbe_get_mac_addr(hw, hw->mac.addr);
+ hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
+ hw->mac.addr[0], hw->mac.addr[1],
+ hw->mac.addr[2]);
hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
+ hw->mac.addr[4], hw->mac.addr[5]);
} else {
/* Setup the receive address. */
hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");
hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
+ hw->mac.addr[0], hw->mac.addr[1],
+ hw->mac.addr[2]);
hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
+ hw->mac.addr[4], hw->mac.addr[5]);
- ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
}
+ hw->addr_ctrl.overflow_promisc = 0;
hw->addr_ctrl.rar_used_count = 1;
/* Zero out the other receive addresses. */
- hw_dbg(hw, "Clearing RAR[1-15]\n");
+ hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1);
for (i = 1; i < rar_entries; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -708,6 +1171,9 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
+ if (hw->mac.ops.init_uta_tables)
+ hw->mac.ops.init_uta_tables(hw);
+
return 0;
}
@@ -718,7 +1184,7 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
*
* Adds it to unused receive address register or goes into promiscuous mode.
**/
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
{
u32 rar_entries = hw->mac.num_rar_entries;
u32 rar;
@@ -733,7 +1199,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
if (hw->addr_ctrl.rar_used_count < rar_entries) {
rar = hw->addr_ctrl.rar_used_count -
hw->addr_ctrl.mc_addr_in_rar_count;
- ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
hw->addr_ctrl.rar_used_count++;
} else {
@@ -744,7 +1210,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
}
/**
- * ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses
+ * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
* @hw: pointer to hardware structure
* @addr_list: the list of new addresses
* @addr_count: number of addresses
@@ -757,7 +1223,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
* Drivers using secondary unicast addresses must set user_set_promisc when
* manually putting the device into promiscuous mode.
**/
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
u32 addr_count, ixgbe_mc_addr_itr next)
{
u8 *addr;
@@ -787,7 +1253,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
for (i = 0; i < addr_count; i++) {
hw_dbg(hw, " Adding the secondary addresses:\n");
addr = next(hw, &addr_list, &vmdq);
- ixgbe_add_uc_addr(hw, addr);
+ ixgbe_add_uc_addr(hw, addr, vmdq);
}
if (hw->addr_ctrl.overflow_promisc) {
@@ -808,7 +1274,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
}
}
- hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n");
+ hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n");
return 0;
}
@@ -821,7 +1287,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
* bit-vector to set in the multicast table. The hardware uses 12 bits, from
* incoming rx multicast addresses, to determine the bit-vector to check in
* the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- * by the MO field of the MCSTCTRL. The MO field is set during initalization
+ * by the MO field of the MCSTCTRL. The MO field is set during initialization
* to mc_filter_type.
**/
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
@@ -829,19 +1295,19 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
u32 vector = 0;
switch (hw->mac.mc_filter_type) {
- case 0: /* use bits [47:36] of the address */
+ case 0: /* use bits [47:36] of the address */
vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
break;
- case 1: /* use bits [46:35] of the address */
+ case 1: /* use bits [46:35] of the address */
vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
break;
- case 2: /* use bits [45:34] of the address */
+ case 2: /* use bits [45:34] of the address */
vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
break;
- case 3: /* use bits [43:32] of the address */
+ case 3: /* use bits [43:32] of the address */
vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
break;
- default: /* Invalid mc_filter_type */
+ default: /* Invalid mc_filter_type */
hw_dbg(hw, "MC filter type param set incorrectly\n");
break;
}
@@ -896,20 +1362,21 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
{
u32 rar_entries = hw->mac.num_rar_entries;
+ u32 rar;
hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
- mc_addr[0], mc_addr[1], mc_addr[2],
- mc_addr[3], mc_addr[4], mc_addr[5]);
+ mc_addr[0], mc_addr[1], mc_addr[2],
+ mc_addr[3], mc_addr[4], mc_addr[5]);
/*
* Place this multicast address in the RAR if there is room,
* else put it in the MTA
*/
if (hw->addr_ctrl.rar_used_count < rar_entries) {
- ixgbe_set_rar(hw, hw->addr_ctrl.rar_used_count,
- mc_addr, 0, IXGBE_RAH_AV);
- hw_dbg(hw, "Added a multicast address to RAR[%d]\n",
- hw->addr_ctrl.rar_used_count);
+ /* use RAR from the end up for multicast */
+ rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1;
+ hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV);
+ hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar);
hw->addr_ctrl.rar_used_count++;
hw->addr_ctrl.mc_addr_in_rar_count++;
} else {
@@ -920,19 +1387,19 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
}
/**
- * ixgbe_update_mc_addr_list - Updates MAC list of multicast addresses
+ * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
* @hw: pointer to hardware structure
* @mc_addr_list: the list of new multicast addresses
* @mc_addr_count: number of addresses
* @next: iterator function to walk the multicast address list
*
* The given list replaces any existing list. Clears the MC addrs from receive
- * address registers and the multicast table. Uses unsed receive address
+ * address registers and the multicast table. Uses unused receive address
* registers for the first multicast addresses, and hashes the rest into the
* multicast table.
**/
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next)
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count, ixgbe_mc_addr_itr next)
{
u32 i;
u32 rar_entries = hw->mac.num_rar_entries;
@@ -948,7 +1415,8 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
hw->addr_ctrl.mta_in_use = 0;
/* Zero out the other receive addresses. */
- hw_dbg(hw, "Clearing RAR[1-15]\n");
+ hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count,
+ rar_entries - 1);
for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -968,190 +1436,55 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
/* Enable mta */
if (hw->addr_ctrl.mta_in_use > 0)
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
- IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
+ IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
- hw_dbg(hw, "ixgbe_update_mc_addr_list Complete\n");
+ hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n");
return 0;
}
/**
- * ixgbe_clear_vfta - Clear VLAN filter table
+ * ixgbe_enable_mc_generic - Enable multicast address in RAR
* @hw: pointer to hardware structure
*
- * Clears the VLAN filer table, and the VMDq index associated with the filter
+ * Enables multicast address in RAR and the use of the multicast hash table.
**/
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
{
- u32 offset;
- u32 vlanbyte;
+ u32 i;
+ u32 rar_entries = hw->mac.num_rar_entries;
+ struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+ if (a->mc_addr_in_rar_count > 0)
+ for (i = (rar_entries - a->mc_addr_in_rar_count);
+ i < rar_entries; i++)
+ ixgbe_enable_rar(hw, i);
- for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
- 0);
+ if (a->mta_in_use > 0)
+ IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
+ hw->mac.mc_filter_type);
return 0;
}
/**
- * ixgbe_set_vfta - Set VLAN filter table
+ * ixgbe_disable_mc_generic - Disable multicast address in RAR
* @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFTA
- * @vlan_on: boolean flag to turn on/off VLAN in VFTA
*
- * Turn on/off specified VLAN in the VLAN filter table.
+ * Disables multicast address in RAR and the use of the multicast hash table.
**/
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on)
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
{
- u32 VftaIndex;
- u32 BitOffset;
- u32 VftaReg;
- u32 VftaByte;
-
- /* Determine 32-bit word position in array */
- VftaIndex = (vlan >> 5) & 0x7F; /* upper seven bits */
-
- /* Determine the location of the (VMD) queue index */
- VftaByte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
- BitOffset = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
-
- /* Set the nibble for VMD queue index */
- VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex));
- VftaReg &= (~(0x0F << BitOffset));
- VftaReg |= (vind << BitOffset);
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex), VftaReg);
-
- /* Determine the location of the bit for this VLAN id */
- BitOffset = vlan & 0x1F; /* lower five bits */
-
- VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTA(VftaIndex));
- if (vlan_on)
- /* Turn on this VLAN id */
- VftaReg |= (1 << BitOffset);
- else
- /* Turn off this VLAN id */
- VftaReg &= ~(1 << BitOffset);
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(VftaIndex), VftaReg);
-
- return 0;
-}
-
-/**
- * ixgbe_setup_fc - Configure flow control settings
- * @hw: pointer to hardware structure
- * @packetbuf_num: packet buffer number (0-7)
- *
- * Configures the flow control settings based on SW configuration.
- * This function is used for 802.3x flow control configuration only.
- **/
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
-{
- u32 frctl_reg;
- u32 rmcs_reg;
-
- if (packetbuf_num < 0 || packetbuf_num > 7)
- hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
- "is 0-7\n", packetbuf_num);
-
- frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
-
- rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
- rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
-
- /*
- * 10 gig parts do not have a word in the EEPROM to determine the
- * default flow control setting, so we explicitly set it to full.
- */
- if (hw->fc.type == ixgbe_fc_default)
- hw->fc.type = ixgbe_fc_full;
-
- /*
- * We want to save off the original Flow Control configuration just in
- * case we get disconnected and then reconnected into a different hub
- * or switch with different Flow Control capabilities.
- */
- hw->fc.type = hw->fc.original_type;
-
- /*
- * The possible values of the "flow_control" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames but not
- * send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we do not
- * support receiving pause frames)
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- * other: Invalid.
- */
- switch (hw->fc.type) {
- case ixgbe_fc_none:
- break;
- case ixgbe_fc_rx_pause:
- /*
- * RX Flow control is enabled,
- * and TX Flow control is disabled.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
- break;
- case ixgbe_fc_tx_pause:
- /*
- * TX Flow control is enabled, and RX Flow control is disabled,
- * by a software over-ride.
- */
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- case ixgbe_fc_full:
- /*
- * Flow control (both RX and TX) is enabled by a software
- * over-ride.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- default:
- /* We should never get here. The value should be 0-3. */
- hw_dbg(hw, "Flow control param set incorrectly\n");
- break;
- }
+ u32 i;
+ u32 rar_entries = hw->mac.num_rar_entries;
+ struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
- /* Enable 802.3x based flow control settings. */
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
- IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+ if (a->mc_addr_in_rar_count > 0)
+ for (i = (rar_entries - a->mc_addr_in_rar_count);
+ i < rar_entries; i++)
+ ixgbe_disable_rar(hw, i);
- /*
- * Check for invalid software configuration, zeros are completely
- * invalid for all parameters used past this point, and if we enable
- * flow control with zero water marks, we blast flow control packets.
- */
- if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Flow control structure initialized incorrectly\n");
- return IXGBE_ERR_INVALID_LINK_SETTINGS;
- }
-
- /*
- * We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- if (hw->fc.type & ixgbe_fc_tx_pause) {
- if (hw->fc.send_xon) {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- (hw->fc.low_water | IXGBE_FCRTL_XONE));
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- hw->fc.low_water);
- }
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
- (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+ if (a->mta_in_use > 0)
+ IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
return 0;
}
@@ -1167,13 +1500,24 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
**/
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
{
- u32 ctrl;
- s32 i;
+ u32 i;
+ u32 reg_val;
+ u32 number_of_queues;
s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
- ctrl |= IXGBE_CTRL_GIO_DIS;
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+ /* Disable the receive unit by stopping each queue */
+ number_of_queues = hw->mac.max_rx_queues;
+ for (i = 0; i < number_of_queues; i++) {
+ reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+ if (reg_val & IXGBE_RXDCTL_ENABLE) {
+ reg_val &= ~IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
+ }
+ }
+
+ reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ reg_val |= IXGBE_CTRL_GIO_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
@@ -1188,11 +1532,11 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
/**
- * ixgbe_acquire_swfw_sync - Aquire SWFW semaphore
+ * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
* @hw: pointer to hardware structure
- * @mask: Mask to specify wich semaphore to acquire
+ * @mask: Mask to specify which semaphore to acquire
*
- * Aquires the SWFW semaphore throught the GSSR register for the specified
+ * Acquires the SWFW semaphore thought the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash)
**/
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1234,9 +1578,9 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
/**
* ixgbe_release_swfw_sync - Release SWFW semaphore
* @hw: pointer to hardware structure
- * @mask: Mask to specify wich semaphore to release
+ * @mask: Mask to specify which semaphore to release
*
- * Releases the SWFW semaphore throught the GSSR register for the specified
+ * Releases the SWFW semaphore thought the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash)
**/
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1253,45 +1597,3 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
ixgbe_release_eeprom_semaphore(hw);
}
-/**
- * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to read
- * @val: read value
- *
- * Performs write operation to analog register specified.
- **/
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
- u32 atlas_ctl;
-
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
- IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
- atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
- *val = (u8)atlas_ctl;
-
- return 0;
-}
-
-/**
- * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: atlas register to write
- * @val: value to write
- *
- * Performs write operation to Atlas analog register specified.
- **/
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
- u32 atlas_ctl;
-
- atlas_ctl = (reg << 8) | val;
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
-
- return 0;
-}
-
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index c75ecba..192f8d0 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -31,36 +30,45 @@
#include "ixgbe_type.h"
-s32 ixgbe_init_hw(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw(struct ixgbe_hw *hw);
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr);
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw);
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num);
-
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw);
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
-
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
- u32 enable_addr);
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
-s32 ixgbe_validate_mac_addr(u8 *mac_addr);
-
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
+
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data);
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+ u16 *checksum_val);
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr);
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count,
+ ixgbe_mc_addr_itr func);
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
+ u32 addr_count, ixgbe_mc_addr_itr func);
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_validate_mac_addr(u8 *mac_addr);
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask);
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 61c000e..f7aefb5 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -48,7 +47,7 @@ struct ixgbe_stats {
};
#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \
- offsetof(struct ixgbe_adapter, m)
+ offsetof(struct ixgbe_adapter, m)
static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_packets", IXGBE_STAT(net_stats.rx_packets)},
{"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
@@ -90,19 +89,22 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_header_split", IXGBE_STAT(rx_hdr_split)},
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
+#ifdef CONFIG_IXGBE_LRO
{"lro_aggregated", IXGBE_STAT(lro_aggregated)},
{"lro_flushed", IXGBE_STAT(lro_flushed)},
+#endif
};
#define IXGBE_QUEUE_STATS_LEN \
- ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
- ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
- (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
+ ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
+ ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
+ (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
+#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
static int ixgbe_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+ struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -114,7 +116,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
if (hw->phy.media_type == ixgbe_media_type_copper) {
ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_TP | SUPPORTED_Autoneg);
+ SUPPORTED_TP | SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
@@ -126,14 +128,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
+ ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
+ ecmd->autoneg = AUTONEG_DISABLE;
}
- adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up);
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (link_up) {
ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
- SPEED_10000 : SPEED_1000;
+ SPEED_10000 : SPEED_1000;
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
@@ -144,7 +147,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
}
static int ixgbe_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+ struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -164,7 +167,7 @@ static int ixgbe_set_settings(struct net_device *netdev,
}
static void ixgbe_get_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -182,7 +185,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
}
static int ixgbe_set_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -241,7 +244,7 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
if (data)
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
else
- netdev->features &= ~NETIF_F_IP_CSUM;
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
return 0;
}
@@ -281,7 +284,7 @@ static int ixgbe_get_regs_len(struct net_device *netdev)
#define IXGBE_GET_STAT(_A_, _R_) _A_->stats._R_
static void ixgbe_get_regs(struct net_device *netdev,
- struct ethtool_regs *regs, void *p)
+ struct ethtool_regs *regs, void *p)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -315,7 +318,9 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC);
/* Interrupt */
- regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICR);
+ /* don't read EICR because it can clear interrupt causes, instead
+ * read EICS which is a shadow but doesn't clear EICR */
+ regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICS);
regs_buff[19] = IXGBE_READ_REG(hw, IXGBE_EICS);
regs_buff[20] = IXGBE_READ_REG(hw, IXGBE_EIMS);
regs_buff[21] = IXGBE_READ_REG(hw, IXGBE_EIMC);
@@ -325,7 +330,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[25] = IXGBE_READ_REG(hw, IXGBE_IVAR(0));
regs_buff[26] = IXGBE_READ_REG(hw, IXGBE_MSIXT);
regs_buff[27] = IXGBE_READ_REG(hw, IXGBE_MSIXPBA);
- regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL);
+ regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL(0));
regs_buff[29] = IXGBE_READ_REG(hw, IXGBE_GPIE);
/* Flow Control */
@@ -371,7 +376,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[482 + i] = IXGBE_READ_REG(hw, IXGBE_RAL(i));
for (i = 0; i < 16; i++)
regs_buff[498 + i] = IXGBE_READ_REG(hw, IXGBE_RAH(i));
- regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE);
+ regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0));
regs_buff[515] = IXGBE_READ_REG(hw, IXGBE_FCTRL);
regs_buff[516] = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
regs_buff[517] = IXGBE_READ_REG(hw, IXGBE_MCSTCTRL);
@@ -419,7 +424,6 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
- /* DCE */
regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
@@ -539,21 +543,17 @@ static void ixgbe_get_regs(struct net_device *netdev,
/* Diagnostic */
regs_buff[1071] = IXGBE_READ_REG(hw, IXGBE_RDSTATCTL);
for (i = 0; i < 8; i++)
- regs_buff[1072] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
+ regs_buff[1072 + i] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
regs_buff[1080] = IXGBE_READ_REG(hw, IXGBE_RDHMPN);
- regs_buff[1081] = IXGBE_READ_REG(hw, IXGBE_RIC_DW0);
- regs_buff[1082] = IXGBE_READ_REG(hw, IXGBE_RIC_DW1);
- regs_buff[1083] = IXGBE_READ_REG(hw, IXGBE_RIC_DW2);
- regs_buff[1084] = IXGBE_READ_REG(hw, IXGBE_RIC_DW3);
+ for (i = 0; i < 4; i++)
+ regs_buff[1081 + i] = IXGBE_READ_REG(hw, IXGBE_RIC_DW(i));
regs_buff[1085] = IXGBE_READ_REG(hw, IXGBE_RDPROBE);
regs_buff[1086] = IXGBE_READ_REG(hw, IXGBE_TDSTATCTL);
for (i = 0; i < 8; i++)
- regs_buff[1087] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
+ regs_buff[1087 + i] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
regs_buff[1095] = IXGBE_READ_REG(hw, IXGBE_TDHMPN);
- regs_buff[1096] = IXGBE_READ_REG(hw, IXGBE_TIC_DW0);
- regs_buff[1097] = IXGBE_READ_REG(hw, IXGBE_TIC_DW1);
- regs_buff[1098] = IXGBE_READ_REG(hw, IXGBE_TIC_DW2);
- regs_buff[1099] = IXGBE_READ_REG(hw, IXGBE_TIC_DW3);
+ for (i = 0; i < 4; i++)
+ regs_buff[1096 + i] = IXGBE_READ_REG(hw, IXGBE_TIC_DW(i));
regs_buff[1100] = IXGBE_READ_REG(hw, IXGBE_TDPROBE);
regs_buff[1101] = IXGBE_READ_REG(hw, IXGBE_TXBUFCTRL);
regs_buff[1102] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA0);
@@ -566,7 +566,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[1109] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA2);
regs_buff[1110] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA3);
for (i = 0; i < 8; i++)
- regs_buff[1111] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
+ regs_buff[1111 + i] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
regs_buff[1119] = IXGBE_READ_REG(hw, IXGBE_RFVAL);
regs_buff[1120] = IXGBE_READ_REG(hw, IXGBE_MDFTC1);
regs_buff[1121] = IXGBE_READ_REG(hw, IXGBE_MDFTC2);
@@ -585,7 +585,7 @@ static int ixgbe_get_eeprom_len(struct net_device *netdev)
}
static int ixgbe_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
+ struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -608,8 +608,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
return -ENOMEM;
for (i = 0; i < eeprom_len; i++) {
- if ((ret_val = ixgbe_read_eeprom(hw, first_word + i,
- &eeprom_buff[i])))
+ if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
+ &eeprom_buff[i])))
break;
}
@@ -624,7 +624,7 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
}
static void ixgbe_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
+ struct ethtool_drvinfo *drvinfo)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -637,7 +637,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
}
static void ixgbe_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
+ struct ethtool_ringparam *ring)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_ring *tx_ring = adapter->tx_ring;
@@ -654,15 +654,12 @@ static void ixgbe_get_ringparam(struct net_device *netdev,
}
static int ixgbe_set_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
+ struct ethtool_ringparam *ring)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_tx_buffer *old_buf;
- struct ixgbe_rx_buffer *old_rx_buf;
- void *old_desc;
+ struct ixgbe_ring *temp_ring;
int i, err;
- u32 new_rx_count, new_tx_count, old_size;
- dma_addr_t old_dma;
+ u32 new_rx_count, new_tx_count;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -681,6 +678,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
return 0;
}
+ if (adapter->num_tx_queues > adapter->num_rx_queues)
+ temp_ring = vmalloc(adapter->num_tx_queues *
+ sizeof(struct ixgbe_ring));
+ else
+ temp_ring = vmalloc(adapter->num_rx_queues *
+ sizeof(struct ixgbe_ring));
+ if (!temp_ring)
+ return -ENOMEM;
+
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
@@ -693,66 +699,61 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
* to the tx and rx ring structs.
*/
if (new_tx_count != adapter->tx_ring->count) {
+ memcpy(temp_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
for (i = 0; i < adapter->num_tx_queues; i++) {
- /* Save existing descriptor ring */
- old_buf = adapter->tx_ring[i].tx_buffer_info;
- old_desc = adapter->tx_ring[i].desc;
- old_size = adapter->tx_ring[i].size;
- old_dma = adapter->tx_ring[i].dma;
- /* Try to allocate a new one */
- adapter->tx_ring[i].tx_buffer_info = NULL;
- adapter->tx_ring[i].desc = NULL;
- adapter->tx_ring[i].count = new_tx_count;
- err = ixgbe_setup_tx_resources(adapter,
- &adapter->tx_ring[i]);
+ temp_ring[i].count = new_tx_count;
+ err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
if (err) {
- /* Restore the old one so at least
- the adapter still works, even if
- we failed the request */
- adapter->tx_ring[i].tx_buffer_info = old_buf;
- adapter->tx_ring[i].desc = old_desc;
- adapter->tx_ring[i].size = old_size;
- adapter->tx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ ixgbe_free_tx_resources(adapter,
+ &temp_ring[i]);
+ }
goto err_setup;
}
- /* Free the old buffer manually */
- vfree(old_buf);
- pci_free_consistent(adapter->pdev, old_size,
- old_desc, old_dma);
}
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+
+ memcpy(adapter->tx_ring, temp_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
+ adapter->tx_ring_count = new_tx_count;
}
if (new_rx_count != adapter->rx_ring->count) {
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ memcpy(temp_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbe_ring));
- old_rx_buf = adapter->rx_ring[i].rx_buffer_info;
- old_desc = adapter->rx_ring[i].desc;
- old_size = adapter->rx_ring[i].size;
- old_dma = adapter->rx_ring[i].dma;
-
- adapter->rx_ring[i].rx_buffer_info = NULL;
- adapter->rx_ring[i].desc = NULL;
- adapter->rx_ring[i].dma = 0;
- adapter->rx_ring[i].count = new_rx_count;
- err = ixgbe_setup_rx_resources(adapter,
- &adapter->rx_ring[i]);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ temp_ring[i].count = new_rx_count;
+ err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
if (err) {
- adapter->rx_ring[i].rx_buffer_info = old_rx_buf;
- adapter->rx_ring[i].desc = old_desc;
- adapter->rx_ring[i].size = old_size;
- adapter->rx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ ixgbe_free_rx_resources(adapter,
+ &temp_ring[i]);
+ }
goto err_setup;
}
-
- vfree(old_rx_buf);
- pci_free_consistent(adapter->pdev, old_size, old_desc,
- old_dma);
}
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+
+ memcpy(adapter->rx_ring, temp_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbe_ring));
+
+ adapter->rx_ring_count = new_rx_count;
}
+ /* success! */
err = 0;
err_setup:
- if (netif_running(adapter->netdev))
+ if (netif_running(netdev))
ixgbe_up(adapter);
clear_bit(__IXGBE_RESETTING, &adapter->state);
@@ -770,20 +771,31 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
}
static void ixgbe_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, u64 *data)
+ struct ethtool_stats *stats, u64 *data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u64 *queue_stat;
int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
int j, k;
int i;
+
+#ifdef CONFIG_IXGBE_LRO
u64 aggregated = 0, flushed = 0, no_desc = 0;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
+ flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
+ no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
+ }
+ adapter->lro_aggregated = aggregated;
+ adapter->lro_flushed = flushed;
+ adapter->lro_no_desc = no_desc;
+#endif
ixgbe_update_stats(adapter);
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset;
data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < adapter->num_tx_queues; j++) {
queue_stat = (u64 *)&adapter->tx_ring[j].stats;
@@ -792,24 +804,18 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
i += k;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
- aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[j].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc;
queue_stat = (u64 *)&adapter->rx_ring[j].stats;
for (k = 0; k < stat_count; k++)
data[i + k] = queue_stat[k];
i += k;
}
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
}
static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
- u8 *data)
+ u8 *data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u8 *p = data;
+ char *p = (char *)data;
int i;
switch (stringset) {
@@ -831,14 +837,14 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
-/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
+ /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
break;
}
}
static void ixgbe_get_wol(struct net_device *netdev,
- struct ethtool_wolinfo *wol)
+ struct ethtool_wolinfo *wol)
{
wol->supported = 0;
wol->wolopts = 0;
@@ -859,16 +865,17 @@ static int ixgbe_nway_reset(struct net_device *netdev)
static int ixgbe_phys_id(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 led_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_LEDCTL);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
u32 i;
if (!data || data > 300)
data = 300;
for (i = 0; i < (data * 1000); i += 400) {
- ixgbe_led_on(&adapter->hw, IXGBE_LED_ON);
+ hw->mac.ops.led_on(hw, IXGBE_LED_ON);
msleep_interruptible(200);
- ixgbe_led_off(&adapter->hw, IXGBE_LED_ON);
+ hw->mac.ops.led_off(hw, IXGBE_LED_ON);
msleep_interruptible(200);
}
@@ -879,67 +886,75 @@ static int ixgbe_phys_id(struct net_device *netdev, u32 data)
}
static int ixgbe_get_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
+ struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
- ec->rx_coalesce_usecs = adapter->rx_eitr;
- else
- ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
-
- if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
- ec->tx_coalesce_usecs = adapter->tx_eitr;
- else
- ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
-
ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;
+
+ /* only valid if in constant ITR mode */
+ switch (adapter->itr_setting) {
+ case 0:
+ /* throttling disabled */
+ ec->rx_coalesce_usecs = 0;
+ break;
+ case 1:
+ /* dynamic ITR mode */
+ ec->rx_coalesce_usecs = 1;
+ break;
+ default:
+ /* fixed interrupt rate mode */
+ ec->rx_coalesce_usecs = 1000000/adapter->eitr_param;
+ break;
+ }
return 0;
}
static int ixgbe_set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
+ struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
- ((ec->rx_coalesce_usecs != 0) &&
- (ec->rx_coalesce_usecs != 1) &&
- (ec->rx_coalesce_usecs != 3) &&
- (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
- return -EINVAL;
- if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
- ((ec->tx_coalesce_usecs != 0) &&
- (ec->tx_coalesce_usecs != 1) &&
- (ec->tx_coalesce_usecs != 3) &&
- (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
- return -EINVAL;
-
- /* convert to rate of irq's per second */
- if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
- adapter->rx_eitr = ec->rx_coalesce_usecs;
- else
- adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
-
- if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
- adapter->tx_eitr = ec->rx_coalesce_usecs;
- else
- adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
if (ec->tx_max_coalesced_frames_irq)
- adapter->tx_ring[0].work_limit =
- ec->tx_max_coalesced_frames_irq;
+ adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
+
+ if (ec->rx_coalesce_usecs > 1) {
+ /* store the value in ints/second */
+ adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
+
+ /* static value of interrupt rate */
+ adapter->itr_setting = adapter->eitr_param;
+ /* clear the lower bit */
+ adapter->itr_setting &= ~1;
+ } else if (ec->rx_coalesce_usecs == 1) {
+ /* 1 means dynamic mode */
+ adapter->eitr_param = 20000;
+ adapter->itr_setting = 1;
+ } else {
+ /* any other value means disable eitr, which is best
+ * served by setting the interrupt rate very high */
+ adapter->eitr_param = 3000000;
+ adapter->itr_setting = 0;
+ }
- if (netif_running(netdev)) {
- ixgbe_down(adapter);
- ixgbe_up(adapter);
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ if (q_vector->txr_count && !q_vector->rxr_count)
+ q_vector->eitr = (adapter->eitr_param >> 1);
+ else
+ /* rx only or mixed */
+ q_vector->eitr = adapter->eitr_param;
+ IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
return 0;
}
-static struct ethtool_ops ixgbe_ethtool_ops = {
+static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
.set_settings = ixgbe_set_settings,
.get_drvinfo = ixgbe_get_drvinfo,
@@ -966,7 +981,7 @@ static struct ethtool_ops ixgbe_ethtool_ops = {
.set_tso = ixgbe_set_tso,
.get_strings = ixgbe_get_strings,
.phys_id = ixgbe_phys_id,
- .get_sset_count = ixgbe_get_sset_count,
+ .get_sset_count = ixgbe_get_sset_count,
.get_ethtool_stats = ixgbe_get_ethtool_stats,
.get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 362541a..807be05 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -46,15 +45,14 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
- "Intel(R) 10 Gigabit PCI Express Network Driver";
+ "Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "1.3.18-k4"
+#define DRV_VERSION "1.3.30-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
-static const char ixgbe_copyright[] =
- "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
- [board_82598] = &ixgbe_82598_info,
+ [board_82598] = &ixgbe_82598_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -74,15 +72,17 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR),
+ board_82598 },
/* required last entry */
{0, }
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
- void *p);
+ void *p);
static struct notifier_block dca_notifier = {
.notifier_call = ixgbe_notify_dca,
.next = NULL,
@@ -104,7 +104,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware take over control of h/w */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
}
static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
@@ -114,24 +114,11 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware know the driver has taken over */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
-}
-
-#ifdef DEBUG
-/**
- * ixgbe_get_hw_dev_name - return device name string
- * used by hardware layer to print debugging information
- **/
-char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw)
-{
- struct ixgbe_adapter *adapter = hw->back;
- struct net_device *netdev = adapter->netdev;
- return netdev->name;
+ ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
-#endif
static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
- u8 msix_vector)
+ u8 msix_vector)
{
u32 ivar, index;
@@ -144,12 +131,12 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
}
static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
- struct ixgbe_tx_buffer
- *tx_buffer_info)
+ struct ixgbe_tx_buffer
+ *tx_buffer_info)
{
if (tx_buffer_info->dma) {
pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
- tx_buffer_info->length, PCI_DMA_TODEVICE);
+ tx_buffer_info->length, PCI_DMA_TODEVICE);
tx_buffer_info->dma = 0;
}
if (tx_buffer_info->skb) {
@@ -160,8 +147,8 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
}
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- unsigned int eop)
+ struct ixgbe_ring *tx_ring,
+ unsigned int eop)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 head, tail;
@@ -196,14 +183,14 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
return false;
}
-#define IXGBE_MAX_TXD_PWR 14
-#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
+#define IXGBE_MAX_TXD_PWR 14
+#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
(((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
+ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
#define GET_TX_HEAD_FROM_RING(ring) (\
*(volatile u32 *) \
@@ -309,9 +296,9 @@ done_cleaning:
return (total_packets ? true : false);
}
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 rxctrl;
int cpu = get_cpu();
@@ -330,7 +317,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txctrl;
int cpu = get_cpu();
@@ -406,13 +393,14 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_desc: rx descriptor
**/
static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
- struct sk_buff *skb, u8 status,
- struct ixgbe_ring *ring,
+ struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
union ixgbe_adv_rx_desc *rx_desc)
{
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
+#ifdef CONFIG_IXGBE_LRO
if (adapter->netdev->features & NETIF_F_LRO &&
skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (adapter->vlgrp && is_vlan)
@@ -423,6 +411,7 @@ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
ring->lro_used = true;
} else {
+#endif
if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan)
vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
@@ -434,7 +423,9 @@ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
else
netif_rx(skb);
}
+#ifdef CONFIG_IXGBE_LRO
}
+#endif
}
/**
@@ -480,7 +471,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
struct ixgbe_ring *rx_ring,
int cleaned_count)
{
- struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
@@ -493,20 +483,29 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
while (cleaned_count--) {
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
- if (!bi->page &&
+ if (!bi->page_dma &&
(adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
- bi->page = alloc_page(GFP_ATOMIC);
if (!bi->page) {
- adapter->alloc_rx_page_failed++;
- goto no_buffers;
+ bi->page = alloc_page(GFP_ATOMIC);
+ if (!bi->page) {
+ adapter->alloc_rx_page_failed++;
+ goto no_buffers;
+ }
+ bi->page_offset = 0;
+ } else {
+ /* use a half page if we're re-using */
+ bi->page_offset ^= (PAGE_SIZE / 2);
}
- bi->page_dma = pci_map_page(pdev, bi->page, 0,
- PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
+
+ bi->page_dma = pci_map_page(pdev, bi->page,
+ bi->page_offset,
+ (PAGE_SIZE / 2),
+ PCI_DMA_FROMDEVICE);
}
if (!bi->skb) {
- struct sk_buff *skb = netdev_alloc_skb(netdev, bufsz);
+ struct sk_buff *skb = netdev_alloc_skb(adapter->netdev,
+ bufsz);
if (!skb) {
adapter->alloc_rx_buff_failed++;
@@ -567,10 +566,9 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
}
static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int *work_done, int work_to_do)
+ struct ixgbe_ring *rx_ring,
+ int *work_done, int work_to_do)
{
- struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -596,7 +594,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
- IXGBE_RXDADV_HDRBUFLEN_SHIFT;
+ IXGBE_RXDADV_HDRBUFLEN_SHIFT;
if (hdr_info & IXGBE_RXDADV_SPH)
adapter->rx_hdr_split++;
if (len > IXGBE_RX_HDR_SIZE)
@@ -613,18 +611,25 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
if (len && !skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- rx_ring->rx_buf_len + NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
+ rx_ring->rx_buf_len + NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
skb_put(skb, len);
}
if (upper_len) {
pci_unmap_page(pdev, rx_buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
rx_buffer_info->page_dma = 0;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
- rx_buffer_info->page, 0, upper_len);
- rx_buffer_info->page = NULL;
+ rx_buffer_info->page,
+ rx_buffer_info->page_offset,
+ upper_len);
+
+ if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
+ (page_count(rx_buffer_info->page) != 1))
+ rx_buffer_info->page = NULL;
+ else
+ get_page(rx_buffer_info->page);
skb->len += upper_len;
skb->data_len += upper_len;
@@ -647,6 +652,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
rx_buffer_info->skb = next_buffer->skb;
rx_buffer_info->dma = next_buffer->dma;
next_buffer->skb = skb;
+ next_buffer->dma = 0;
adapter->non_eop_descs++;
goto next_desc;
}
@@ -662,9 +668,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
total_rx_bytes += skb->len;
total_rx_packets++;
- skb->protocol = eth_type_trans(skb, netdev);
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
- netdev->last_rx = jiffies;
+ adapter->netdev->last_rx = jiffies;
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -682,10 +688,12 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
+#ifdef CONFIG_IXGBE_LRO
if (rx_ring->lro_used) {
lro_flush_all(&rx_ring->lro_mgr);
rx_ring->lro_used = false;
}
+#endif
rx_ring->next_to_clean = i;
cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
@@ -724,43 +732,43 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vector = &adapter->q_vector[v_idx];
/* XXX for_each_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
- adapter->num_rx_queues);
+ adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx].reg_idx;
ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
- adapter->num_rx_queues,
- r_idx + 1);
+ adapter->num_rx_queues,
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->txr_idx,
- adapter->num_tx_queues);
+ adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx].reg_idx;
ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
- adapter->num_tx_queues,
- r_idx + 1);
+ adapter->num_tx_queues,
+ r_idx + 1);
}
- /* if this is a tx only vector use half the irq (tx) rate */
+ /* if this is a tx only vector halve the interrupt rate */
if (q_vector->txr_count && !q_vector->rxr_count)
- q_vector->eitr = adapter->tx_eitr;
+ q_vector->eitr = (adapter->eitr_param >> 1);
else
- /* rx only or mixed */
- q_vector->eitr = adapter->rx_eitr;
+ /* rx only */
+ q_vector->eitr = adapter->eitr_param;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
- /* set up to autoclear timer, lsc, and the vectors */
+ /* set up to autoclear timer, and the vectors */
mask = IXGBE_EIMS_ENABLE_MASK;
- mask &= ~IXGBE_EIMS_OTHER;
+ mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
}
@@ -790,8 +798,8 @@ enum latency_range {
* parameter (see ixgbe_param.c)
**/
static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
- u32 eitr, u8 itr_setting,
- int packets, int bytes)
+ u32 eitr, u8 itr_setting,
+ int packets, int bytes)
{
unsigned int retval = itr_setting;
u32 timepassed_us;
@@ -838,40 +846,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
u32 new_itr;
u8 current_itr, ret_itr;
int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
- sizeof(struct ixgbe_q_vector);
+ sizeof(struct ixgbe_q_vector);
struct ixgbe_ring *rx_ring, *tx_ring;
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->tx_eitr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
- q_vector->tx_eitr = ((q_vector->tx_eitr > ret_itr) ?
- q_vector->tx_eitr - 1 : ret_itr);
+ q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
+ q_vector->tx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = &(adapter->rx_ring[r_idx]);
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->rx_eitr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
- q_vector->rx_eitr = ((q_vector->rx_eitr > ret_itr) ?
- q_vector->rx_eitr - 1 : ret_itr);
+ q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
+ q_vector->rx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
- current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
+ current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
@@ -895,13 +903,27 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
/* must write high and low 16 bits to reset counter */
DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
- itr_reg);
+ itr_reg);
IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
}
return;
}
+
+static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ adapter->lsc_int++;
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
+ schedule_work(&adapter->watchdog_task);
+ }
+}
+
static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
{
struct net_device *netdev = data;
@@ -909,11 +931,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
- if (eicr & IXGBE_EICR_LSC) {
- adapter->lsc_int++;
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies);
- }
+ if (eicr & IXGBE_EICR_LSC)
+ ixgbe_check_lsc(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -934,7 +953,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_tx_dca(adapter, tx_ring);
#endif
@@ -942,7 +961,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
tx_ring->total_packets = 0;
ixgbe_clean_tx_irq(adapter, tx_ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
return IRQ_HANDLED;
@@ -959,16 +978,24 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *rx_ring;
int r_idx;
+ int i;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ rx_ring = &(adapter->rx_ring[r_idx]);
+ rx_ring->total_bytes = 0;
+ rx_ring->total_packets = 0;
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
+ }
+
if (!q_vector->rxr_count)
return IRQ_HANDLED;
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
- rx_ring->total_bytes = 0;
- rx_ring->total_packets = 0;
netif_rx_schedule(adapter->netdev, &q_vector->napi);
return IRQ_HANDLED;
@@ -987,19 +1014,21 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
* @napi: napi struct with our devices info in it
* @budget: amount of work driver is allowed to do this pass, in packets
*
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
**/
static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *rx_ring;
+ struct ixgbe_ring *rx_ring = NULL;
int work_done = 0;
long r_idx;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
@@ -1009,7 +1038,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
netif_rx_complete(adapter->netdev, napi);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+ if (adapter->itr_setting & 3)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
@@ -1018,8 +1047,57 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
return work_done;
}
+/**
+ * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function will clean more than one rx queue associated with a
+ * q_vector.
+ **/
+static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
+{
+ struct ixgbe_q_vector *q_vector =
+ container_of(napi, struct ixgbe_q_vector, napi);
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_ring *rx_ring = NULL;
+ int work_done = 0, i;
+ long r_idx;
+ u16 enable_mask = 0;
+
+ /* attempt to distribute budget to each queue fairly, but don't allow
+ * the budget to go below 1 because we'll exit polling */
+ budget /= (q_vector->rxr_count ?: 1);
+ budget = max(budget, 1);
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ rx_ring = &(adapter->rx_ring[r_idx]);
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_rx_dca(adapter, rx_ring);
+#endif
+ ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ enable_mask |= rx_ring->v_idx;
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
+ }
+
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ rx_ring = &(adapter->rx_ring[r_idx]);
+ /* If all Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ netif_rx_complete(adapter->netdev, napi);
+ if (adapter->itr_setting & 3)
+ ixgbe_set_itr_msix(q_vector);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+ return 0;
+ }
+
+ return work_done;
+}
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
a->q_vector[v_idx].adapter = a;
set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
@@ -1028,7 +1106,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
a->q_vector[v_idx].adapter = a;
set_bit(r_idx, a->q_vector[v_idx].txr_idx);
@@ -1048,7 +1126,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
* mapping configurations in here.
**/
static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int v_start = 0;
int rxr_idx = 0, txr_idx = 0;
@@ -1125,28 +1203,28 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
goto out;
#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
- (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
- &ixgbe_msix_clean_many)
+ (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
+ &ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
handler = SET_HANDLER(&adapter->q_vector[vector]);
sprintf(adapter->name[vector], "%s:v%d-%s",
- netdev->name, vector,
- (handler == &ixgbe_msix_clean_rx) ? "Rx" :
- ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
+ netdev->name, vector,
+ (handler == &ixgbe_msix_clean_rx) ? "Rx" :
+ ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
err = request_irq(adapter->msix_entries[vector].vector,
- handler, 0, adapter->name[vector],
- &(adapter->q_vector[vector]));
+ handler, 0, adapter->name[vector],
+ &(adapter->q_vector[vector]));
if (err) {
DPRINTK(PROBE, ERR,
- "request_irq failed for MSIX interrupt "
- "Error: %d\n", err);
+ "request_irq failed for MSIX interrupt "
+ "Error: %d\n", err);
goto free_queue_irqs;
}
}
sprintf(adapter->name[vector], "%s:lsc", netdev->name);
err = request_irq(adapter->msix_entries[vector].vector,
- &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+ &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
if (err) {
DPRINTK(PROBE, ERR,
"request_irq for msix_lsc failed: %d\n", err);
@@ -1158,7 +1236,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- &(adapter->q_vector[i]));
+ &(adapter->q_vector[i]));
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -1176,16 +1254,16 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
- q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr,
- q_vector->tx_eitr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
- q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr,
- q_vector->rx_eitr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
+ q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr,
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
- current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
+ current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
@@ -1230,19 +1308,19 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
-
/* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
- if (!eicr)
+ if (!eicr) {
+ /* shared interrupt alert!
+ * make sure interrupts are enabled because the read will
+ * have disabled interrupts due to EIAM */
+ ixgbe_irq_enable(adapter);
return IRQ_NONE; /* Not our interrupt */
-
- if (eicr & IXGBE_EICR_LSC) {
- adapter->lsc_int++;
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies);
}
+ if (eicr & IXGBE_EICR_LSC)
+ ixgbe_check_lsc(adapter);
if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
adapter->tx_ring[0].total_packets = 0;
@@ -1285,10 +1363,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
err = ixgbe_request_msix_irqs(adapter);
} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
- netdev->name, netdev);
+ netdev->name, netdev);
} else {
err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
- netdev->name, netdev);
+ netdev->name, netdev);
}
if (err)
@@ -1312,7 +1390,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- &(adapter->q_vector[i]));
+ &(adapter->q_vector[i]));
}
ixgbe_reset_q_vectors(adapter);
@@ -1359,7 +1437,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
- EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr));
+ EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
@@ -1445,8 +1523,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
srrctl |= ((IXGBE_RX_HDR_SIZE <<
- IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
- IXGBE_SRRCTL_BSIZEHDR_MASK);
+ IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+ IXGBE_SRRCTL_BSIZEHDR_MASK);
} else {
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
@@ -1460,10 +1538,11 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
+#ifdef CONFIG_IXGBE_LRO
/**
* ixgbe_get_skb_hdr - helper function for LRO header processing
* @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to tcp header structure
+ * @iphdr: pointer to ip header structure
* @tcph: pointer to tcp header structure
* @hdr_flags: pointer to header flags
* @priv: private data
@@ -1487,8 +1566,9 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
return 0;
}
+#endif /* CONFIG_IXGBE_LRO */
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
/**
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
@@ -1514,10 +1594,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
int rx_buf_len;
/* Decide whether to use packet split mode or not */
- if (netdev->mtu > ETH_DATA_LEN)
- adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
- else
- adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+ adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
@@ -1561,6 +1638,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].head = IXGBE_RDH(j);
adapter->rx_ring[i].tail = IXGBE_RDT(j);
adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+#ifdef CONFIG_IXGBE_LRO
/* Intitial LRO Settings */
adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
@@ -1571,6 +1649,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+#endif
ixgbe_configure_srrctl(adapter, j);
}
@@ -1638,7 +1717,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
static void ixgbe_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+ struct vlan_group *grp)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u32 ctrl;
@@ -1662,14 +1741,16 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
/* add VID to filter table */
- ixgbe_set_vfta(&adapter->hw, vid, 0, true);
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
}
static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_disable(adapter);
@@ -1680,7 +1761,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
ixgbe_irq_enable(adapter);
/* remove VID from filter table */
- ixgbe_set_vfta(&adapter->hw, vid, 0, false);
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
}
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
@@ -1756,15 +1837,15 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
addr_count = netdev->uc_count;
if (addr_count)
addr_list = netdev->uc_list->dmi_addr;
- ixgbe_update_uc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr);
+ hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
/* reprogram multicast list */
addr_count = netdev->mc_count;
if (addr_count)
addr_list = netdev->mc_list->dmi_addr;
- ixgbe_update_mc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr);
+ hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
}
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -1778,10 +1859,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
q_vectors = 1;
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct napi_struct *napi;
q_vector = &adapter->q_vector[q_idx];
if (!q_vector->rxr_count)
continue;
- napi_enable(&q_vector->napi);
+ napi = &q_vector->napi;
+ if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) &&
+ (q_vector->rxr_count > 1))
+ napi->poll = &ixgbe_clean_rxonly_many;
+
+ napi_enable(napi);
}
}
@@ -1816,7 +1903,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
ixgbe_configure_rx(adapter);
for (i = 0; i < adapter->num_rx_queues; i++)
ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i],
- (adapter->rx_ring[i].count - 1));
+ (adapter->rx_ring[i].count - 1));
}
static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
@@ -1834,7 +1921,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
(adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
- IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
+ IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
} else {
/* MSI only */
gpie = 0;
@@ -1897,6 +1984,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
mod_timer(&adapter->watchdog_timer, jiffies);
return 0;
}
@@ -1921,58 +2010,22 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
void ixgbe_reset(struct ixgbe_adapter *adapter)
{
- if (ixgbe_init_hw(&adapter->hw))
- DPRINTK(PROBE, ERR, "Hardware Error\n");
+ struct ixgbe_hw *hw = &adapter->hw;
+ if (hw->mac.ops.init_hw(hw))
+ dev_err(&adapter->pdev->dev, "Hardware Error\n");
/* reprogram the RAR[0] in case user changed it. */
- ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
}
-#ifdef CONFIG_PM
-static int ixgbe_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "ixgbe: Cannot enable PCI device from " \
- "suspend\n");
- return err;
- }
- pci_set_master(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- if (netif_running(netdev)) {
- err = ixgbe_request_irq(adapter);
- if (err)
- return err;
- }
-
- ixgbe_reset(adapter);
-
- if (netif_running(netdev))
- ixgbe_up(adapter);
-
- netif_device_attach(netdev);
-
- return 0;
-}
-#endif
-
/**
* ixgbe_clean_rx_ring - Free Rx Buffers per Queue
* @adapter: board private structure
* @rx_ring: ring to free buffers from
**/
static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
@@ -1986,8 +2039,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- rx_ring->rx_buf_len,
- PCI_DMA_FROMDEVICE);
+ rx_ring->rx_buf_len,
+ PCI_DMA_FROMDEVICE);
rx_buffer_info->dma = 0;
}
if (rx_buffer_info->skb) {
@@ -1996,12 +2049,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
}
if (!rx_buffer_info->page)
continue;
- pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
rx_buffer_info->page_dma = 0;
-
put_page(rx_buffer_info->page);
rx_buffer_info->page = NULL;
+ rx_buffer_info->page_offset = 0;
}
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
@@ -2023,7 +2076,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
* @tx_ring: ring to be cleaned
**/
static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned long size;
@@ -2076,33 +2129,43 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter)
void ixgbe_down(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl;
+ u32 txdctl;
+ int i, j;
/* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state);
/* disable receives */
- rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL,
- rxctrl & ~IXGBE_RXCTRL_RXEN);
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
netif_tx_disable(netdev);
- /* disable transmits in the hardware */
-
- /* flush both disables */
- IXGBE_WRITE_FLUSH(&adapter->hw);
+ IXGBE_WRITE_FLUSH(hw);
msleep(10);
+ netif_tx_stop_all_queues(netdev);
+
ixgbe_irq_disable(adapter);
ixgbe_napi_disable_all(adapter);
+
del_timer_sync(&adapter->watchdog_timer);
+ cancel_work_sync(&adapter->watchdog_task);
+
+ /* disable transmits in the hardware now that interrupts are off */
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ j = adapter->tx_ring[i].reg_idx;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
+ (txdctl & ~IXGBE_TXDCTL_ENABLE));
+ }
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&adapter->pdev->dev);
@@ -2114,56 +2177,18 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
/* since we reset the hardware DCA settings were cleared */
if (dca_add_requester(&adapter->pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
* in the CB driver */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
ixgbe_setup_dca(adapter);
}
#endif
}
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
-
- netif_device_detach(netdev);
-
- if (netif_running(netdev)) {
- ixgbe_down(adapter);
- ixgbe_free_irq(adapter);
- }
-
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-#endif
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- ixgbe_release_hw_control(adapter);
-
- pci_disable_device(pdev);
-
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static void ixgbe_shutdown(struct pci_dev *pdev)
-{
- ixgbe_suspend(pdev, PMSG_SUSPEND);
-}
-
/**
* ixgbe_poll - NAPI Rx polling callback
* @napi: structure for representing this polling device
@@ -2174,11 +2199,11 @@ static void ixgbe_shutdown(struct pci_dev *pdev)
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector = container_of(napi,
- struct ixgbe_q_vector, napi);
+ struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- int tx_cleaned = 0, work_done = 0;
+ int tx_cleaned, work_done = 0;
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
ixgbe_update_tx_dca(adapter, adapter->tx_ring);
ixgbe_update_rx_dca(adapter, adapter->rx_ring);
@@ -2194,12 +2219,11 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
netif_rx_complete(adapter->netdev, napi);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+ if (adapter->itr_setting & 3)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable(adapter);
}
-
return work_done;
}
@@ -2225,8 +2249,48 @@ static void ixgbe_reset_task(struct work_struct *work)
ixgbe_reinit_locked(adapter);
}
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+ int nrq = 1, ntq = 1;
+ int feature_mask = 0, rss_i, rss_m;
+
+ /* Number of supported queues */
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
+ rss_i = adapter->ring_feature[RING_F_RSS].indices;
+ rss_m = 0;
+ feature_mask |= IXGBE_FLAG_RSS_ENABLED;
+
+ switch (adapter->flags & feature_mask) {
+ case (IXGBE_FLAG_RSS_ENABLED):
+ rss_m = 0xF;
+ nrq = rss_i;
+ ntq = rss_i;
+ break;
+ case 0:
+ default:
+ rss_i = 0;
+ rss_m = 0;
+ nrq = 1;
+ ntq = 1;
+ break;
+ }
+
+ adapter->ring_feature[RING_F_RSS].indices = rss_i;
+ adapter->ring_feature[RING_F_RSS].mask = rss_m;
+ break;
+ default:
+ nrq = 1;
+ ntq = 1;
+ break;
+ }
+
+ adapter->num_rx_queues = nrq;
+ adapter->num_tx_queues = ntq;
+}
+
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int err, vector_threshold;
@@ -2245,7 +2309,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
*/
while (vectors >= vector_threshold) {
err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- vectors);
+ vectors);
if (!err) /* Success in acquiring all requested vectors. */
break;
else if (err < 0)
@@ -2264,54 +2328,13 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- adapter->num_tx_queues = 1;
- adapter->num_rx_queues = 1;
+ ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
adapter->num_msix_vectors = vectors;
}
}
-static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
-{
- int nrq, ntq;
- int feature_mask = 0, rss_i, rss_m;
-
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- rss_m = 0;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
-
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED):
- rss_m = 0xF;
- nrq = rss_i;
- ntq = rss_i;
- break;
- case 0:
- default:
- rss_i = 0;
- rss_m = 0;
- nrq = 1;
- ntq = 1;
- break;
- }
-
- adapter->ring_feature[RING_F_RSS].indices = rss_i;
- adapter->ring_feature[RING_F_RSS].mask = rss_m;
- break;
- default:
- nrq = 1;
- ntq = 1;
- break;
- }
-
- adapter->num_rx_queues = nrq;
- adapter->num_tx_queues = ntq;
-}
-
/**
* ixgbe_cache_ring_register - Descriptor ring to register mapping
* @adapter: board private structure to initialize
@@ -2321,9 +2344,6 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
**/
static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
{
- /* TODO: Remove all uses of the indices in the cases where multiple
- * features are OR'd together, if the feature set makes sense.
- */
int feature_mask = 0, rss_i;
int i, txr_idx, rxr_idx;
@@ -2364,21 +2384,22 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
int i;
adapter->tx_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!adapter->tx_ring)
goto err_tx_ring_allocation;
adapter->rx_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!adapter->rx_ring)
goto err_rx_ring_allocation;
for (i = 0; i < adapter->num_tx_queues; i++) {
- adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;
+ adapter->tx_ring[i].count = adapter->tx_ring_count;
adapter->tx_ring[i].queue_index = i;
}
+
for (i = 0; i < adapter->num_rx_queues; i++) {
- adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD;
+ adapter->rx_ring[i].count = adapter->rx_ring_count;
adapter->rx_ring[i].queue_index = i;
}
@@ -2400,25 +2421,19 @@ err_tx_ring_allocation:
* capabilities of the hardware and the kernel.
**/
static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
- *adapter)
+ *adapter)
{
int err = 0;
int vector, v_budget;
/*
- * Set the default interrupt throttle rate.
- */
- adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS);
- adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS);
-
- /*
* It's easy to be greedy for MSI-X vectors, but it really
* doesn't do us much good if we have a lot more vectors
* than CPU's. So let's be conservative and only ask for
* (roughly) twice the number of vectors as there are CPU's.
*/
v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
- (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+ (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
/*
* At the same time, hardware can only support a maximum of
@@ -2432,7 +2447,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
/* A failure in MSI-X entry allocation isn't fatal, but it does
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
- sizeof(struct msix_entry), GFP_KERNEL);
+ sizeof(struct msix_entry), GFP_KERNEL);
if (!adapter->msix_entries) {
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
ixgbe_set_num_queues(adapter);
@@ -2441,7 +2456,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
err = ixgbe_alloc_queues(adapter);
if (err) {
DPRINTK(PROBE, ERR, "Unable to allocate memory "
- "for queues\n");
+ "for queues\n");
goto out;
}
@@ -2462,7 +2477,7 @@ try_msi:
adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
} else {
DPRINTK(HW, DEBUG, "Unable to allocate MSI interrupt, "
- "falling back to legacy. Error: %d\n", err);
+ "falling back to legacy. Error: %d\n", err);
/* reset err */
err = 0;
}
@@ -2518,9 +2533,9 @@ static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
}
DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
- "Tx Queue count = %u\n",
- (adapter->num_rx_queues > 1) ? "Enabled" :
- "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
+ "Tx Queue count = %u\n",
+ (adapter->num_rx_queues > 1) ? "Enabled" :
+ "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
set_bit(__IXGBE_DOWN, &adapter->state);
@@ -2547,15 +2562,19 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
unsigned int rss;
+ /* PCI config space info */
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->revision_id = pdev->revision;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_device_id = pdev->subsystem_device;
+
/* Set capability flags */
rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
- /* Enable Dynamic interrupt throttling by default */
- adapter->rx_eitr = 1;
- adapter->tx_eitr = 1;
-
/* default flow control settings */
hw->fc.original_type = ixgbe_fc_none;
hw->fc.type = ixgbe_fc_none;
@@ -2566,18 +2585,21 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/* select 10G link by default */
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- if (hw->mac.ops.reset(hw)) {
- dev_err(&pdev->dev, "HW Init failed\n");
- return -EIO;
- }
- if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
- false)) {
- dev_err(&pdev->dev, "Link Speed setup failed\n");
- return -EIO;
- }
+
+ /* enable itr by default in dynamic mode */
+ adapter->itr_setting = 1;
+ adapter->eitr_param = 20000;
+
+ /* set defaults for eitr in MegaBytes */
+ adapter->eitr_low = 10;
+ adapter->eitr_high = 20;
+
+ /* set default ring sizes */
+ adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
+ adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
/* initialize eeprom parameters */
- if (ixgbe_init_eeprom(hw)) {
+ if (ixgbe_init_eeprom_params_generic(hw)) {
dev_err(&pdev->dev, "EEPROM initialization failed\n");
return -EIO;
}
@@ -2633,6 +2655,31 @@ err:
}
/**
+ * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (!err)
+ continue;
+ DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i);
+ break;
+ }
+
+ return err;
+}
+
+/**
* ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
* @rx_ring: rx descriptor ring (for a specific queue) to setup
@@ -2640,22 +2687,23 @@ err:
* Returns 0 on success, negative on failure
**/
int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
+#ifdef CONFIG_IXGBE_LRO
size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
rx_ring->lro_mgr.lro_arr = vmalloc(size);
if (!rx_ring->lro_mgr.lro_arr)
return -ENOMEM;
memset(rx_ring->lro_mgr.lro_arr, 0, size);
-
+#endif
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
rx_ring->rx_buffer_info = vmalloc(size);
if (!rx_ring->rx_buffer_info) {
DPRINTK(PROBE, ERR,
- "vmalloc allocation failed for the rx desc ring\n");
+ "vmalloc allocation failed for the rx desc ring\n");
goto alloc_failed;
}
memset(rx_ring->rx_buffer_info, 0, size);
@@ -2668,7 +2716,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
if (!rx_ring->desc) {
DPRINTK(PROBE, ERR,
- "Memory allocation failed for the rx desc ring\n");
+ "Memory allocation failed for the rx desc ring\n");
vfree(rx_ring->rx_buffer_info);
goto alloc_failed;
}
@@ -2679,20 +2727,48 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
return 0;
alloc_failed:
+#ifdef CONFIG_IXGBE_LRO
vfree(rx_ring->lro_mgr.lro_arr);
rx_ring->lro_mgr.lro_arr = NULL;
+#endif
return -ENOMEM;
}
/**
+ * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (!err)
+ continue;
+ DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i);
+ break;
+ }
+
+ return err;
+}
+
+/**
* ixgbe_free_tx_resources - Free Tx Resources per Queue
* @adapter: board private structure
* @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
-static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -2727,13 +2803,15 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
*
* Free all receive software resources
**/
-static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
+#ifdef CONFIG_IXGBE_LRO
vfree(rx_ring->lro_mgr.lro_arr);
rx_ring->lro_mgr.lro_arr = NULL;
+#endif
ixgbe_clean_rx_ring(adapter, rx_ring);
@@ -2760,59 +2838,6 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
- if (err) {
- DPRINTK(PROBE, ERR,
- "Allocation for Tx Queue %u failed\n", i);
- break;
- }
- }
-
- return err;
-}
-
-/**
- * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-
-static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
- if (err) {
- DPRINTK(PROBE, ERR,
- "Allocation for Rx Queue %u failed\n", i);
- break;
- }
- }
-
- return err;
-}
-
-/**
* ixgbe_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
* @new_mtu: new value for maximum frame size
@@ -2824,12 +2849,12 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
- if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) ||
- (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
+ /* MTU < 68 is an error and causes problems on some kernels */
+ if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
return -EINVAL;
DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n",
- netdev->mtu, new_mtu);
+ netdev->mtu, new_mtu);
/* must set new MTU before calling down or up */
netdev->mtu = new_mtu;
@@ -2924,6 +2949,135 @@ static int ixgbe_close(struct net_device *netdev)
}
/**
+ * ixgbe_napi_add_all - prep napi structs for use
+ * @adapter: private struct
+ * helper function to napi_add each possible q_vector->napi
+ */
+static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+{
+ int q_idx, q_vectors;
+ int (*poll)(struct napi_struct *, int);
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ poll = &ixgbe_clean_rxonly;
+ /* Only enable as many vectors as we have rx queues. */
+ q_vectors = adapter->num_rx_queues;
+ } else {
+ poll = &ixgbe_poll;
+ /* only one q_vector for legacy modes */
+ q_vectors = 1;
+ }
+
+ for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+ netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
+ }
+}
+
+static void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
+{
+ int q_idx;
+ int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+ /* legacy and MSI only use one vector */
+ if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
+ q_vectors = 1;
+
+ for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+ if (!q_vector->rxr_count)
+ continue;
+ netif_napi_del(&q_vector->napi);
+ }
+}
+
+#ifdef CONFIG_PM
+static int ixgbe_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ u32 err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
+ "suspend\n");
+ return err;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ err = ixgbe_init_interrupt_scheme(adapter);
+ if (err) {
+ printk(KERN_ERR "ixgbe: Cannot initialize interrupts for "
+ "device\n");
+ return err;
+ }
+
+ ixgbe_napi_add_all(adapter);
+ ixgbe_reset(adapter);
+
+ if (netif_running(netdev)) {
+ err = ixgbe_open(adapter->netdev);
+ if (err)
+ return err;
+ }
+
+ netif_device_attach(netdev);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+ int retval = 0;
+#endif
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev)) {
+ ixgbe_down(adapter);
+ ixgbe_free_irq(adapter);
+ ixgbe_free_all_tx_resources(adapter);
+ ixgbe_free_all_rx_resources(adapter);
+ }
+ ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_napi_del_all(adapter);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+
+#ifdef CONFIG_PM
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+#endif
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ ixgbe_release_hw_control(adapter);
+
+ pci_disable_device(pdev);
+
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static void ixgbe_shutdown(struct pci_dev *pdev)
+{
+ ixgbe_suspend(pdev, PMSG_SUSPEND);
+}
+
+/**
* ixgbe_update_stats - Update the board statistics counters.
* @adapter: board private structure
**/
@@ -2996,7 +3150,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
/* Rx Errors */
adapter->net_stats.rx_errors = adapter->stats.crcerrs +
- adapter->stats.rlec;
+ adapter->stats.rlec;
adapter->net_stats.rx_dropped = 0;
adapter->net_stats.rx_length_errors = adapter->stats.rlec;
adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
@@ -3010,27 +3164,74 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
static void ixgbe_watchdog(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
- struct net_device *netdev = adapter->netdev;
- bool link_up;
- u32 link_speed = 0;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ /* Do the watchdog outside of interrupt context due to the lovely
+ * delays that some of the newer hardware requires */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ /* Cause software interrupt to ensure rx rings are cleaned */
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ u32 eics =
+ (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
+ IXGBE_WRITE_REG(hw, IXGBE_EICS, eics);
+ } else {
+ /* For legacy and MSI interrupts don't set any bits that
+ * are enabled for EIAM, because this operation would
+ * set *both* EIMS and EICS for any bit in EIAM */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ }
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + 2 * HZ));
+ }
- adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
+ schedule_work(&adapter->watchdog_task);
+}
+
+/**
+ * ixgbe_watchdog_task - worker thread to bring link up
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_watchdog_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ watchdog_task);
+ struct net_device *netdev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 link_speed = adapter->link_speed;
+ bool link_up = adapter->link_up;
+
+ adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
+
+ if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+ if (link_up ||
+ time_after(jiffies, (adapter->link_check_timeout +
+ IXGBE_TRY_LINK_TIMEOUT))) {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+ }
+ adapter->link_up = link_up;
+ adapter->link_speed = link_speed;
+ }
if (link_up) {
if (!netif_carrier_ok(netdev)) {
- u32 frctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- u32 rmcs = IXGBE_READ_REG(&adapter->hw, IXGBE_RMCS);
+ u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
#define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
#define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
DPRINTK(LINK, INFO, "NIC Link is Up %s, "
- "Flow Control: %s\n",
- (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
- "10 Gbps" :
- (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
- "1 Gbps" : "unknown speed")),
- ((FLOW_RX && FLOW_TX) ? "RX/TX" :
- (FLOW_RX ? "RX" :
- (FLOW_TX ? "TX" : "None"))));
+ "Flow Control: %s\n",
+ (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+ "10 Gbps" :
+ (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+ "1 Gbps" : "unknown speed")),
+ ((FLOW_RX && FLOW_TX) ? "RX/TX" :
+ (FLOW_RX ? "RX" :
+ (FLOW_TX ? "TX" : "None"))));
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
@@ -3039,6 +3240,8 @@ static void ixgbe_watchdog(unsigned long data)
adapter->detect_tx_hung = true;
}
} else {
+ adapter->link_up = false;
+ adapter->link_speed = 0;
if (netif_carrier_ok(netdev)) {
DPRINTK(LINK, INFO, "NIC Link is Down\n");
netif_carrier_off(netdev);
@@ -3047,36 +3250,19 @@ static void ixgbe_watchdog(unsigned long data)
}
ixgbe_update_stats(adapter);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
- /* Cause software interrupt to ensure rx rings are cleaned */
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- u32 eics =
- (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics);
- } else {
- /* for legacy and MSI interrupts don't set any bits that
- * are enabled for EIAM, because this operation would
- * set *both* EIMS and EICS for any bit in EIAM */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
- (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
- }
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 2 * HZ));
- }
+ adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
}
static int ixgbe_tso(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring, struct sk_buff *skb,
- u32 tx_flags, u8 *hdr_len)
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
int err;
struct ixgbe_tx_buffer *tx_buffer_info;
- u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
- u32 mss_l4len_idx = 0, l4len;
+ u32 vlan_macip_lens = 0, type_tucmd_mlhl;
+ u32 mss_l4len_idx, l4len;
if (skb_is_gso(skb)) {
if (skb_header_cloned(skb)) {
@@ -3092,16 +3278,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
iph->tot_len = 0;
iph->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
+ iph->daddr, 0,
+ IPPROTO_TCP,
+ 0);
adapter->hw_tso_ctxt++;
} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
ipv6_hdr(skb)->payload_len = 0;
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
adapter->hw_tso6_ctxt++;
}
@@ -3115,7 +3301,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= ((skb_network_offset(skb)) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
*hdr_len += skb_network_offset(skb);
vlan_macip_lens |=
(skb_transport_header(skb) - skb_network_header(skb));
@@ -3125,8 +3311,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
context_desc->seqnum_seed = 0;
/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
- type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->protocol == htons(ETH_P_IP))
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
@@ -3134,7 +3320,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
/* MSS L4LEN IDX */
- mss_l4len_idx |=
+ mss_l4len_idx =
(skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT);
/* use index 1 for TSO */
@@ -3155,8 +3341,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
}
static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -3173,16 +3359,16 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= (skb_network_offset(skb) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
if (skb->ip_summed == CHECKSUM_PARTIAL)
vlan_macip_lens |= (skb_transport_header(skb) -
- skb_network_header(skb));
+ skb_network_header(skb));
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = 0;
type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
switch (skb->protocol) {
@@ -3190,16 +3376,14 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
-
case __constant_htons(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
-
default:
if (unlikely(net_ratelimit())) {
DPRINTK(PROBE, WARNING,
@@ -3216,6 +3400,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
+
adapter->hw_csum_tx_good++;
i++;
if (i == tx_ring->count)
@@ -3224,12 +3409,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
return true;
}
+
return false;
}
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, unsigned int first)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, unsigned int first)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned int len = skb->len;
@@ -3247,8 +3433,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
tx_buffer_info->length = size;
tx_buffer_info->dma = pci_map_single(adapter->pdev,
- skb->data + offset,
- size, PCI_DMA_TODEVICE);
+ skb->data + offset,
+ size, PCI_DMA_TODEVICE);
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -3273,9 +3459,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
tx_buffer_info->length = size;
tx_buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size, PCI_DMA_TODEVICE);
+ frag->page,
+ offset,
+ size,
+ PCI_DMA_TODEVICE);
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -3298,8 +3485,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
}
static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- int tx_flags, int count, u32 paylen, u8 hdr_len)
+ struct ixgbe_ring *tx_ring,
+ int tx_flags, int count, u32 paylen, u8 hdr_len)
{
union ixgbe_adv_tx_desc *tx_desc = NULL;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -3318,17 +3505,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
/* use index 1 context for tso */
olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
if (tx_flags & IXGBE_TX_FLAGS_IPV4)
olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
} else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
@@ -3338,9 +3525,8 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
tx_desc->read.cmd_type_len =
- cpu_to_le32(cmd_type_len | tx_buffer_info->length);
+ cpu_to_le32(cmd_type_len | tx_buffer_info->length);
tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
-
i++;
if (i == tx_ring->count)
i = 0;
@@ -3361,7 +3547,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
}
static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3377,61 +3563,52 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
return -EBUSY;
/* A reprieve! - use start_queue because it doesn't call schedule */
- netif_wake_subqueue(netdev, tx_ring->queue_index);
+ netif_start_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
return 0;
}
static int ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
return 0;
return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
}
-
static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_ring *tx_ring;
- unsigned int len = skb->len;
unsigned int first;
unsigned int tx_flags = 0;
u8 hdr_len = 0;
int r_idx = 0, tso;
- unsigned int mss = 0;
int count = 0;
unsigned int f;
- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
- len -= skb->data_len;
+
r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
tx_ring = &adapter->tx_ring[r_idx];
-
- if (skb->len <= 0) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+ if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ tx_flags |= vlan_tx_tag_get(skb);
+ tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
+ tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
- mss = skb_shinfo(skb)->gso_size;
-
- if (mss)
- count++;
- else if (skb->ip_summed == CHECKSUM_PARTIAL)
+ /* three things can cause us to need a context descriptor */
+ if (skb_is_gso(skb) ||
+ (skb->ip_summed == CHECKSUM_PARTIAL) ||
+ (tx_flags & IXGBE_TX_FLAGS_VLAN))
count++;
- count += TXD_USE_COUNT(len);
- for (f = 0; f < nr_frags; f++)
+ count += TXD_USE_COUNT(skb_headlen(skb));
+ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
adapter->tx_busy++;
return NETDEV_TX_BUSY;
}
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
- tx_flags |= IXGBE_TX_FLAGS_VLAN;
- tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT);
- }
if (skb->protocol == htons(ETH_P_IP))
tx_flags |= IXGBE_TX_FLAGS_IPV4;
@@ -3445,12 +3622,12 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (tso)
tx_flags |= IXGBE_TX_FLAGS_TSO;
else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
- (skb->ip_summed == CHECKSUM_PARTIAL))
+ (skb->ip_summed == CHECKSUM_PARTIAL))
tx_flags |= IXGBE_TX_FLAGS_CSUM;
ixgbe_tx_queue(adapter, tx_ring, tx_flags,
- ixgbe_tx_map(adapter, tx_ring, skb, first),
- skb->len, hdr_len);
+ ixgbe_tx_map(adapter, tx_ring, skb, first),
+ skb->len, hdr_len);
netdev->trans_start = jiffies;
@@ -3484,15 +3661,16 @@ static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
static int ixgbe_set_mac(struct net_device *netdev, void *p)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
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);
+ memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
- ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
return 0;
}
@@ -3516,28 +3694,19 @@ static void ixgbe_netpoll(struct net_device *netdev)
#endif
/**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- * helper function to napi_add each possible q_vector->napi
- */
-static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+ * ixgbe_link_config - set up initial link with default speed and duplex
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_link_config(struct ixgbe_hw *hw)
{
- int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- int (*poll)(struct napi_struct *, int);
+ u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- poll = &ixgbe_clean_rxonly;
- } else {
- poll = &ixgbe_poll;
- /* only one q_vector for legacy modes */
- q_vectors = 1;
- }
+ /* must always autoneg for both 1G and 10G link */
+ hw->mac.autoneg = true;
- for (i = 0; i < q_vectors; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
- netif_napi_add(adapter->netdev, &q_vector->napi,
- (*poll), 64);
- }
+ return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
}
/**
@@ -3552,17 +3721,16 @@ static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
* and a hardware reset occur.
**/
static int __devinit ixgbe_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
struct net_device *netdev;
struct ixgbe_adapter *adapter = NULL;
struct ixgbe_hw *hw;
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
- unsigned long mmio_start, mmio_len;
static int cards_found;
int i, err, pci_using_dac;
u16 link_status, link_speed, link_width;
- u32 part_num;
+ u32 part_num, eec;
err = pci_enable_device(pdev);
if (err)
@@ -3577,7 +3745,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
dev_err(&pdev->dev, "No usable DMA "
- "configuration, aborting\n");
+ "configuration, aborting\n");
goto err_dma;
}
}
@@ -3610,10 +3778,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->back = adapter;
adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
- mmio_start = pci_resource_start(pdev, 0);
- mmio_len = pci_resource_len(pdev, 0);
-
- hw->hw_addr = ioremap(mmio_start, mmio_len);
+ hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
if (!hw->hw_addr) {
err = -EIO;
goto err_ioremap;
@@ -3643,22 +3809,23 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
#endif
strcpy(netdev->name, pci_name(pdev));
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
-
adapter->bd_number = cards_found;
- /* PCI config space info */
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- hw->revision_id = pdev->revision;
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_device_id = pdev->subsystem_device;
-
/* Setup hw api */
memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
hw->mac.type = ii->mac;
+ /* EEPROM */
+ memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
+ if (!(eec & (1 << 8)))
+ hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
+
+ /* PHY */
+ memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
+ /* phy->sfp_type = ixgbe_sfp_type_unknown; */
+
err = ii->get_invariants(hw);
if (err)
goto err_hw_init;
@@ -3668,16 +3835,25 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+ /* reset_hw fills in the perm_addr as well */
+ err = hw->mac.ops.reset_hw(hw);
+ if (err) {
+ dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
+ goto err_sw_init;
+ }
+
netdev->features = NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ NETIF_F_IP_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
+#ifdef CONFIG_IXGBE_LRO
netdev->features |= NETIF_F_LRO;
+#endif
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
@@ -3688,7 +3864,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_HIGHDMA;
/* make sure the EEPROM is good */
- if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
+ if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom;
@@ -3697,7 +3873,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len);
- if (ixgbe_validate_mac_addr(netdev->dev_addr)) {
+ if (ixgbe_validate_mac_addr(netdev->perm_addr)) {
+ dev_err(&pdev->dev, "invalid MAC address\n");
err = -EIO;
goto err_eeprom;
}
@@ -3707,6 +3884,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
+ INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
err = ixgbe_init_interrupt_scheme(adapter);
if (err)
@@ -3717,32 +3895,39 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
link_speed = link_status & IXGBE_PCI_LINK_SPEED;
link_width = link_status & IXGBE_PCI_LINK_WIDTH;
dev_info(&pdev->dev, "(PCI Express:%s:%s) "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
- (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
- "Unknown"),
- ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
- (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
- (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
- (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
- "Unknown"),
- netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
- netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
- ixgbe_read_part_num(hw, &part_num);
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
+ (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
+ "Unknown"),
+ ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+ "Unknown"),
+ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+ ixgbe_read_pba_num_generic(hw, &part_num);
dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type,
- (part_num >> 8), (part_num & 0xff));
+ hw->mac.type, hw->phy.type,
+ (part_num >> 8), (part_num & 0xff));
if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
- "this card is not sufficient for optimal "
- "performance.\n");
+ "this card is not sufficient for optimal "
+ "performance.\n");
dev_warn(&pdev->dev, "For optimal performance a x8 "
- "PCI-Express slot is required.\n");
+ "PCI-Express slot is required.\n");
}
/* reset the hardware with the new settings */
- ixgbe_start_hw(hw);
+ hw->mac.ops.start_hw(hw);
+
+ /* link_config depends on start_hw being called at least once */
+ err = ixgbe_link_config(hw);
+ if (err) {
+ dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
+ goto err_register;
+ }
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
@@ -3754,7 +3939,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_register;
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
@@ -3804,7 +3989,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
flush_scheduled_work();
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&pdev->dev);
@@ -3822,6 +4007,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
DPRINTK(PROBE, INFO, "complete\n");
+ ixgbe_napi_del_all(adapter);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
@@ -3839,7 +4025,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
* this device has been detected.
*/
static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+ pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev->priv;
@@ -3850,7 +4036,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
ixgbe_down(adapter);
pci_disable_device(pdev);
- /* Request a slot slot reset. */
+ /* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -3867,7 +4053,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
if (pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR,
- "Cannot re-enable PCI device after reset.\n");
+ "Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
pci_set_master(pdev);
@@ -3901,7 +4087,6 @@ static void ixgbe_io_resume(struct pci_dev *pdev)
}
netif_device_attach(netdev);
-
}
static struct pci_error_handlers ixgbe_err_handler = {
@@ -3937,13 +4122,14 @@ static int __init ixgbe_init_module(void)
printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
dca_register_notify(&dca_notifier);
#endif
ret = pci_register_driver(&ixgbe_driver);
return ret;
}
+
module_init(ixgbe_init_module);
/**
@@ -3954,20 +4140,20 @@ module_init(ixgbe_init_module);
**/
static void __exit ixgbe_exit_module(void)
{
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
dca_unregister_notify(&dca_notifier);
#endif
pci_unregister_driver(&ixgbe_driver);
}
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
- void *p)
+ void *p)
{
int ret_val;
ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
- __ixgbe_notify_dca);
+ __ixgbe_notify_dca);
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 8002931..764035a 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -33,32 +32,36 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
+static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data);
/**
- * ixgbe_identify_phy - Get physical layer module
+ * ixgbe_identify_phy_generic - Get physical layer module
* @hw: pointer to hardware structure
*
* Determines the physical layer module found on the current adapter.
**/
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw)
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
u32 phy_addr;
- for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
- if (ixgbe_validate_phy_addr(hw, phy_addr)) {
- hw->phy.addr = phy_addr;
- ixgbe_get_phy_id(hw);
- hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
- status = 0;
- break;
+ if (hw->phy.type == ixgbe_phy_unknown) {
+ for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
+ if (ixgbe_validate_phy_addr(hw, phy_addr)) {
+ hw->phy.addr = phy_addr;
+ ixgbe_get_phy_id(hw);
+ hw->phy.type =
+ ixgbe_get_phy_type_from_id(hw->phy.id);
+ status = 0;
+ break;
+ }
}
+ } else {
+ status = 0;
}
+
return status;
}
@@ -73,10 +76,8 @@ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
bool valid = false;
hw->phy.addr = phy_addr;
- ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id);
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
if (phy_id != 0xFFFF && phy_id != 0x0)
valid = true;
@@ -95,21 +96,18 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
u16 phy_id_high = 0;
u16 phy_id_low = 0;
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_high);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &phy_id_high);
if (status == 0) {
hw->phy.id = (u32)(phy_id_high << 16);
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_LOW,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_low);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &phy_id_low);
hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
}
-
return status;
}
@@ -123,9 +121,6 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
enum ixgbe_phy_type phy_type;
switch (phy_id) {
- case TN1010_PHY_ID:
- phy_type = ixgbe_phy_tn;
- break;
case QT2022_PHY_ID:
phy_type = ixgbe_phy_qt;
break;
@@ -138,32 +133,31 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
}
/**
- * ixgbe_reset_phy - Performs a PHY reset
+ * ixgbe_reset_phy_generic - Performs a PHY reset
* @hw: pointer to hardware structure
**/
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw)
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
{
/*
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
*/
- return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- IXGBE_MDIO_PHY_XS_RESET);
+ return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
+ IXGBE_MDIO_PHY_XS_DEV_TYPE,
+ IXGBE_MDIO_PHY_XS_RESET);
}
/**
- * ixgbe_read_phy_reg - Reads a value from a specified PHY register
+ * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit address of PHY register to read
* @phy_data: Pointer to read data from PHY register
**/
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data)
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data)
{
u32 command;
u32 i;
- u32 timeout = 10;
u32 data;
s32 status = 0;
u16 gssr;
@@ -179,9 +173,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
if (status == 0) {
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -190,7 +184,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* The MDI Command bit will clear when the operation is
* complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -210,9 +204,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* command
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -221,7 +215,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* completed. The MDI Command bit will clear when the
* operation is complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -231,8 +225,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
}
if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw,
- "PHY read command didn't complete\n");
+ hw_dbg(hw, "PHY read command didn't complete\n");
status = IXGBE_ERR_PHY;
} else {
/*
@@ -247,22 +240,22 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
ixgbe_release_swfw_sync(hw, gssr);
}
+
return status;
}
/**
- * ixgbe_write_phy_reg - Writes a value to specified PHY register
+ * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit PHY register to write
* @device_type: 5 bit device type
* @phy_data: Data to write to the PHY register
**/
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data)
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data)
{
u32 command;
u32 i;
- u32 timeout = 10;
s32 status = 0;
u16 gssr;
@@ -280,9 +273,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -291,19 +284,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* The MDI Command bit will clear when the operation is
* complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
- hw_dbg(hw, "PHY address cmd didn't complete\n");
+ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
break;
- }
}
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+ hw_dbg(hw, "PHY address cmd didn't complete\n");
status = IXGBE_ERR_PHY;
+ }
if (status == 0) {
/*
@@ -311,9 +304,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* command
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -322,20 +315,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* completed. The MDI Command bit will clear when the
* operation is complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
- hw_dbg(hw, "PHY write command did not "
- "complete.\n");
+ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
break;
- }
}
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+ hw_dbg(hw, "PHY address cmd didn't complete\n");
status = IXGBE_ERR_PHY;
+ }
}
ixgbe_release_swfw_sync(hw, gssr);
@@ -345,67 +337,54 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
}
/**
- * ixgbe_setup_tnx_phy_link - Set and restart autoneg
+ * ixgbe_setup_phy_link_generic - Set and restart autoneg
* @hw: pointer to hardware structure
*
* Restart autonegotiation and PHY and waits for completion.
**/
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_NOT_IMPLEMENTED;
u32 time_out;
u32 max_time_out = 10;
- u16 autoneg_speed_selection_register = 0x10;
- u16 autoneg_restart_mask = 0x0200;
- u16 autoneg_complete_mask = 0x0020;
- u16 autoneg_reg = 0;
+ u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
/*
* Set advertisement settings in PHY based on autoneg_advertised
* settings. If autoneg_advertised = 0, then advertise default values
- * txn devices cannot be "forced" to a autoneg 10G and fail. But can
+ * tnx devices cannot be "forced" to a autoneg 10G and fail. But can
* for a 1G.
*/
- ixgbe_read_phy_reg(hw,
- autoneg_speed_selection_register,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
else
autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
- ixgbe_write_phy_reg(hw,
- autoneg_speed_selection_register,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
-
+ hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
/* Restart PHY autonegotiation and wait for completion */
- ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
- autoneg_reg |= autoneg_restart_mask;
+ autoneg_reg |= IXGBE_MII_RESTART;
- ixgbe_write_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
+ hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
/* Wait for autonegotiation to finish */
for (time_out = 0; time_out < max_time_out; time_out++) {
udelay(10);
/* Restart PHY autonegotiation and wait for completion */
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_reg);
- autoneg_reg &= autoneg_complete_mask;
- if (autoneg_reg == autoneg_complete_mask) {
+ autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
+ if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
status = 0;
break;
}
@@ -418,64 +397,17 @@ s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
}
/**
- * ixgbe_check_tnx_phy_link - Determine link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads the VS1 register to determine if link is up and the current speed for
- * the PHY.
- **/
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 phy_link = 0;
- u16 phy_speed = 0;
- u16 phy_data = 0;
-
- /* Initialize speed and link to default case */
- *link_up = false;
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
- *link_up = true;
- if (phy_speed ==
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- break;
- } else {
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- &phy_data);
- phy_link = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
- phy_speed = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
- }
- }
-
- return status;
-}
-
-/**
- * ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities
+ * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
* @autoneg: true if autonegotiation enabled
**/
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
{
+
/*
* Clear autoneg_advertised and set new values based on input link
* speed.
@@ -484,11 +416,13 @@ s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
/* Setup link based on the new speed settings */
- ixgbe_setup_tnx_phy_link(hw);
+ hw->phy.ops.setup_link(hw);
return 0;
}
+
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index aa3ea72..9bfe3f2 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -30,20 +29,52 @@
#define _IXGBE_PHY_H_
#include "ixgbe_type.h"
+#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
-s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
- bool autoneg_wait_to_complete);
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw);
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw);
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data);
-
-/* PHY specific */
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
- bool autoneg_wait_to_complete);
+/* EEPROM byte offsets */
+#define IXGBE_SFF_IDENTIFIER 0x0
+#define IXGBE_SFF_IDENTIFIER_SFP 0x3
+#define IXGBE_SFF_VENDOR_OUI_BYTE0 0x25
+#define IXGBE_SFF_VENDOR_OUI_BYTE1 0x26
+#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27
+#define IXGBE_SFF_1GBE_COMP_CODES 0x6
+#define IXGBE_SFF_10GBE_COMP_CODES 0x3
+#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9
+
+/* Bitmasks */
+#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80
+#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
+#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
+#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
+#define IXGBE_I2C_EEPROM_READ_MASK 0x100
+#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
+#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
+#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1
+#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
+#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
+
+/* Bit-shift macros */
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4
+
+/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
+#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
+#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
+#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
+
+
+s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data);
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data);
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
#endif /* _IXGBE_PHY_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 3e9c483..c6f8fa1 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -37,9 +36,9 @@
/* Device IDs */
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
-#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8
#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
+#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -70,11 +69,11 @@
#define IXGBE_EIMC 0x00888
#define IXGBE_EIAC 0x00810
#define IXGBE_EIAM 0x00890
-#define IXGBE_EITR(_i) (0x00820 + ((_i) * 4)) /* 0x820-0x86c */
-#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */
#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */
-#define IXGBE_PBACL 0x11068
+#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
#define IXGBE_GPIE 0x00898
/* Flow Control Registers */
@@ -86,20 +85,33 @@
#define IXGBE_TFCS 0x0CE00
/* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (0x01000 + ((_i) * 0x40)) /* 64 of each (0-63)*/
-#define IXGBE_RDBAH(_i) (0x01004 + ((_i) * 0x40))
-#define IXGBE_RDLEN(_i) (0x01008 + ((_i) * 0x40))
-#define IXGBE_RDH(_i) (0x01010 + ((_i) * 0x40))
-#define IXGBE_RDT(_i) (0x01018 + ((_i) * 0x40))
-#define IXGBE_RXDCTL(_i) (0x01028 + ((_i) * 0x40))
-#define IXGBE_RSCCTL(_i) (0x0102C + ((_i) * 0x40))
-#define IXGBE_SRRCTL(_i) (0x02100 + ((_i) * 4))
- /* array of 16 (0x02100-0x0213C) */
-#define IXGBE_DCA_RXCTRL(_i) (0x02200 + ((_i) * 4))
- /* array of 16 (0x02200-0x0223C) */
-#define IXGBE_RDRXCTL 0x02F00
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+/*
+ * Split and Replication Receive Control Registers
+ * 00-15 : 0x02100 + n*4
+ * 16-64 : 0x01014 + n*0x40
+ * 64-127: 0x0D014 + (n-64)*0x40
+ */
+#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \
+ (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \
+ (0x0D014 + ((_i - 64) * 0x40))))
+/*
+ * Rx DCA Control Register:
+ * 00-15 : 0x02200 + n*4
+ * 16-64 : 0x0100C + n*0x40
+ * 64-127: 0x0D00C + (n-64)*0x40
+ */
+#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \
+ (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
+ (0x0D00C + ((_i - 64) * 0x40))))
+#define IXGBE_RDRXCTL 0x02F00
#define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4))
- /* 8 of these 0x03C00 - 0x03C1C */
+ /* 8 of these 0x03C00 - 0x03C1C */
#define IXGBE_RXCTRL 0x03000
#define IXGBE_DROPEN 0x03D04
#define IXGBE_RXPBSIZE_SHIFT 10
@@ -107,29 +119,32 @@
/* Receive Registers */
#define IXGBE_RXCSUM 0x05000
#define IXGBE_RFCTL 0x05008
+#define IXGBE_DRECCCTL 0x02F08
+#define IXGBE_DRECCCTL_DISABLE 0
+/* Multicast Table Array - 128 entries */
#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
- /* Multicast Table Array - 128 entries */
-#define IXGBE_RAL(_i) (0x05400 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_RAH(_i) (0x05404 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_PSRTYPE 0x05480
- /* 0x5480-0x54BC Packet split receive type */
+#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+/* Packet split receive type */
+#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+/* array of 4096 1-bit vlan filters */
#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4))
- /* array of 4096 1-bit vlan filters */
+/*array of 4096 4-bit vlan vmdq indices */
#define IXGBE_VFTAVIND(_j, _i) (0x0A200 + ((_j) * 0x200) + ((_i) * 4))
- /*array of 4096 4-bit vlan vmdq indicies */
#define IXGBE_FCTRL 0x05080
#define IXGBE_VLNCTRL 0x05088
#define IXGBE_MCSTCTRL 0x05090
#define IXGBE_MRQC 0x05818
-#define IXGBE_VMD_CTL 0x0581C
#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIRVP 0x05AC0
+#define IXGBE_VMD_CTL 0x0581C
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
+
/* Transmit DMA registers */
-#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40))/* 32 of these (0-31)*/
+#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
#define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40))
#define IXGBE_TDH(_i) (0x06010 + ((_i) * 0x40))
@@ -138,11 +153,10 @@
#define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40))
#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
#define IXGBE_DTXCTL 0x07E00
-#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4))
- /* there are 16 of these (0-15) */
+
+#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
#define IXGBE_TIPG 0x0CB00
-#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) *0x04))
- /* there are 8 of these */
+#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */
#define IXGBE_MNGTXMAP 0x0CD10
#define IXGBE_TIPG_FIBER_DEFAULT 3
#define IXGBE_TXPBSIZE_SHIFT 10
@@ -154,6 +168,7 @@
#define IXGBE_IPAV 0x05838
#define IXGBE_IP4AT 0x05840 /* IPv4 table 0x5840-0x5858 */
#define IXGBE_IP6AT 0x05880 /* IPv6 table 0x5880-0x588F */
+
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
#define IXGBE_FHFT 0x09000 /* Flex host filter table 9000-93FC */
@@ -170,6 +185,8 @@
#define IXGBE_TDPT2TCCR(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+
+
/* Stats registers */
#define IXGBE_CRCERRS 0x04000
#define IXGBE_ILLERRC 0x04004
@@ -224,7 +241,7 @@
#define IXGBE_XEC 0x04120
#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (0x07300 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
@@ -275,23 +292,17 @@
#define IXGBE_DCA_CTRL 0x11074
/* Diagnostic Registers */
-#define IXGBE_RDSTATCTL 0x02C20
-#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
-#define IXGBE_RDHMPN 0x02F08
-#define IXGBE_RIC_DW0 0x02F10
-#define IXGBE_RIC_DW1 0x02F14
-#define IXGBE_RIC_DW2 0x02F18
-#define IXGBE_RIC_DW3 0x02F1C
-#define IXGBE_RDPROBE 0x02F20
-#define IXGBE_TDSTATCTL 0x07C20
-#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
-#define IXGBE_TDHMPN 0x07F08
-#define IXGBE_TIC_DW0 0x07F10
-#define IXGBE_TIC_DW1 0x07F14
-#define IXGBE_TIC_DW2 0x07F18
-#define IXGBE_TIC_DW3 0x07F1C
-#define IXGBE_TDPROBE 0x07F20
-#define IXGBE_TXBUFCTRL 0x0C600
+#define IXGBE_RDSTATCTL 0x02C20
+#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
+#define IXGBE_RDHMPN 0x02F08
+#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4))
+#define IXGBE_RDPROBE 0x02F20
+#define IXGBE_TDSTATCTL 0x07C20
+#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
+#define IXGBE_TDHMPN 0x07F08
+#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4))
+#define IXGBE_TDPROBE 0x07F20
+#define IXGBE_TXBUFCTRL 0x0C600
#define IXGBE_TXBUFDATA0 0x0C610
#define IXGBE_TXBUFDATA1 0x0C614
#define IXGBE_TXBUFDATA2 0x0C618
@@ -392,7 +403,7 @@
#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
-#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
+#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */
/* MSCA Bit Masks */
@@ -416,10 +427,10 @@
#define IXGBE_MSCA_MDI_IN_PROG_EN 0x80000000 /* MDI in progress enable */
/* MSRWD bit masks */
-#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF
-#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
-#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000
-#define IXGBE_MSRWD_READ_DATA_SHIFT 16
+#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF
+#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
+#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000
+#define IXGBE_MSRWD_READ_DATA_SHIFT 16
/* Atlas registers */
#define IXGBE_ATLAS_PDN_LPBK 0x24
@@ -434,6 +445,7 @@
#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0
#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0
+
/* Device Type definitions for new protocol MDIO commands */
#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
@@ -441,6 +453,8 @@
#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */
+#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */
+
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL 0x0 /* VS1 Control Reg */
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS 0x1 /* VS1 Status Reg */
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS 0x0008 /* 1 = Link Up */
@@ -454,23 +468,39 @@
#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */
#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Abilty Reg */
+#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Address Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
+
+/* MII clause 22/28 definitions */
+#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800
+
+#define IXGBE_MII_SPEED_SELECTION_REG 0x10
+#define IXGBE_MII_RESTART 0x200
+#define IXGBE_MII_AUTONEG_COMPLETE 0x20
+#define IXGBE_MII_AUTONEG_REG 0x0
+
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
/* PHY IDs*/
-#define TN1010_PHY_ID 0x00A19410
#define QT2022_PHY_ID 0x0043A400
+/* PHY Types */
+#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
+
/* General purpose Interrupt Enable */
-#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
-#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
-#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
-#define IXGBE_GPIE_EIAME 0x40000000
-#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
+#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
+#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */
+#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
+#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
+#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
+#define IXGBE_GPIE_EIAME 0x40000000
+#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
/* Transmit Flow Control status */
#define IXGBE_TFCS_TXOFF 0x00000001
@@ -531,7 +561,7 @@
#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */
/* RMCS Bit Masks */
-#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recylce Mode enable */
+#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recycle Mode enable */
/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
#define IXGBE_RMCS_RAC 0x00000004
#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
@@ -539,12 +569,15 @@
#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+
/* Interrupt register bitmasks */
/* Extended Interrupt Cause Read */
#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */
#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
-#define IXGBE_EICR_MNG 0x00400000 /* Managability Event Interrupt */
+#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
+#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
+#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
@@ -552,11 +585,12 @@
/* Extended Interrupt Cause Set */
#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
-#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
-#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
+#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
+#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
+#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
+#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
@@ -564,7 +598,9 @@
#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
+#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */
#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
@@ -573,18 +609,20 @@
#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
-#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Error */
+#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
+#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */
#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
-#define IXGBE_EIMS_ENABLE_MASK (\
- IXGBE_EIMS_RTX_QUEUE | \
- IXGBE_EIMS_LSC | \
- IXGBE_EIMS_TCP_TIMER | \
- IXGBE_EIMS_OTHER)
+#define IXGBE_EIMS_ENABLE_MASK ( \
+ IXGBE_EIMS_RTX_QUEUE | \
+ IXGBE_EIMS_LSC | \
+ IXGBE_EIMS_TCP_TIMER | \
+ IXGBE_EIMS_OTHER)
-/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
+/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define IXGBE_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
#define IXGBE_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
#define IXGBE_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
@@ -621,6 +659,7 @@
#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */
#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */
+
#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
/* STATUS Bit Masks */
@@ -668,16 +707,16 @@
#define IXGBE_AUTOC_AN_RESTART 0x00001000
#define IXGBE_AUTOC_FLU 0x00000001
#define IXGBE_AUTOC_LMS_SHIFT 13
-#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-
-#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
+#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
+#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
@@ -703,6 +742,7 @@
#define IXGBE_LINKS_TL_FAULT 0x00001000
#define IXGBE_LINKS_SIGNAL 0x00000F00
+#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
/* SW Semaphore Register bitmasks */
@@ -757,6 +797,11 @@
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+/* Legacy EEPROM word offsets */
+#define IXGBE_ISCSI_BOOT_CAPS 0x0033
+#define IXGBE_ISCSI_SETUP_PORT_0 0x0030
+#define IXGBE_ISCSI_SETUP_PORT_1 0x0034
+
/* EEPROM Commands - SPI */
#define IXGBE_EEPROM_MAX_RETRY_SPI 5000 /* Max wait 5ms for RDY signal */
#define IXGBE_EEPROM_STATUS_RDY_SPI 0x01
@@ -764,7 +809,7 @@
#define IXGBE_EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
#define IXGBE_EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = addr bit-8 */
#define IXGBE_EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Ena latch */
-/* EEPROM reset Write Enbale latch */
+/* EEPROM reset Write Enable latch */
#define IXGBE_EEPROM_WRDI_OPCODE_SPI 0x04
#define IXGBE_EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status reg */
#define IXGBE_EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status reg */
@@ -803,22 +848,20 @@
/* Number of 100 microseconds we wait for PCI Express master disable */
#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
-/* PHY Types */
-#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
-
/* Check whether address is multicast. This is little-endian specific check.*/
#define IXGBE_IS_MULTICAST(Address) \
- (bool)(((u8 *)(Address))[0] & ((u8)0x01))
+ (bool)(((u8 *)(Address))[0] & ((u8)0x01))
/* Check whether an address is broadcast. */
#define IXGBE_IS_BROADCAST(Address) \
- ((((u8 *)(Address))[0] == ((u8)0xff)) && \
- (((u8 *)(Address))[1] == ((u8)0xff)))
+ ((((u8 *)(Address))[0] == ((u8)0xff)) && \
+ (((u8 *)(Address))[1] == ((u8)0xff)))
/* RAH */
#define IXGBE_RAH_VIND_MASK 0x003C0000
#define IXGBE_RAH_VIND_SHIFT 18
#define IXGBE_RAH_AV 0x80000000
+#define IXGBE_CLEAR_VMDQ_ALL 0xFFFFFFFF
/* Header split receive */
#define IXGBE_RFCTL_ISCSI_DIS 0x00000001
@@ -847,7 +890,7 @@
#define IXGBE_MAX_FRAME_SZ 0x40040000
#define IXGBE_TDWBAL_HEAD_WB_ENABLE 0x1 /* Tx head write-back enable */
-#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq. # write-back enable */
+#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq# write-back enable */
/* Receive Config masks */
#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
@@ -860,7 +903,7 @@
#define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */
#define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */
#define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */
-/* Receive Priority Flow Control Enbale */
+/* Receive Priority Flow Control Enable */
#define IXGBE_FCTRL_RPFCE 0x00004000
#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
@@ -890,9 +933,8 @@
/* Receive Descriptor bit definitions */
#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */
#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */
-#define IXGBE_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */
#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */
@@ -908,7 +950,7 @@
#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */
#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */
#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
-#define IXGBE_RXDADV_HBO 0x00800000
+#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */
#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
#define IXGBE_RXDADV_ERR_PE 0x08000000 /* Packet Error */
@@ -922,15 +964,17 @@
#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */
#define IXGBE_RXD_CFI_SHIFT 12
+
/* SRRCTL bit definitions */
-#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
-#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
-#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
-#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
+#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
+#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
+#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
+#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
#define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define IXGBE_SRRCTL_DESCTYPE_MASK 0x0E000000
#define IXGBE_RXDPS_HDRSTAT_HDRSP 0x00008000
#define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
@@ -964,21 +1008,20 @@
#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
-
/* Masks to determine if packets should be dropped due to frame errors */
-#define IXGBE_RXD_ERR_FRAME_ERR_MASK (\
- IXGBE_RXD_ERR_CE | \
- IXGBE_RXD_ERR_LE | \
- IXGBE_RXD_ERR_PE | \
- IXGBE_RXD_ERR_OSE | \
- IXGBE_RXD_ERR_USE)
-
-#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK (\
- IXGBE_RXDADV_ERR_CE | \
- IXGBE_RXDADV_ERR_LE | \
- IXGBE_RXDADV_ERR_PE | \
- IXGBE_RXDADV_ERR_OSE | \
- IXGBE_RXDADV_ERR_USE)
+#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
+ IXGBE_RXD_ERR_CE | \
+ IXGBE_RXD_ERR_LE | \
+ IXGBE_RXD_ERR_PE | \
+ IXGBE_RXD_ERR_OSE | \
+ IXGBE_RXD_ERR_USE)
+
+#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \
+ IXGBE_RXDADV_ERR_CE | \
+ IXGBE_RXDADV_ERR_LE | \
+ IXGBE_RXDADV_ERR_PE | \
+ IXGBE_RXDADV_ERR_OSE | \
+ IXGBE_RXDADV_ERR_USE)
/* Multicast bit mask */
#define IXGBE_MCSTCTRL_MFE 0x4
@@ -994,6 +1037,7 @@
#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */
#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
+
/* Transmit Descriptor - Legacy */
struct ixgbe_legacy_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -1008,8 +1052,8 @@ struct ixgbe_legacy_tx_desc {
union {
__le32 data;
struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
+ u8 status; /* Descriptor status */
+ u8 css; /* Checksum start */
__le16 vlan;
} fields;
} upper;
@@ -1018,7 +1062,7 @@ struct ixgbe_legacy_tx_desc {
/* Transmit Descriptor - Advanced */
union ixgbe_adv_tx_desc {
struct {
- __le64 buffer_addr; /* Address of descriptor's data buf */
+ __le64 buffer_addr; /* Address of descriptor's data buf */
__le32 cmd_type_len;
__le32 olinfo_status;
} read;
@@ -1050,8 +1094,8 @@ union ixgbe_adv_rx_desc {
union {
__le32 data;
struct {
- __le16 pkt_info; /* RSS type, Packet type */
- __le16 hdr_info; /* Split Header, header len */
+ __le16 pkt_info; /* RSS, Pkt type */
+ __le16 hdr_info; /* Splithdr, hdrlen */
} hs_rss;
} lo_dword;
union {
@@ -1079,49 +1123,69 @@ struct ixgbe_adv_tx_context_desc {
};
/* Adv Transmit Descriptor Config Masks */
-#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buffer length(bytes) */
+#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */
#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */
-#define IXGBE_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */
#define IXGBE_ADVTXD_DCMD_RS IXGBE_TXD_CMD_RS /* Report Status */
-#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
+#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
#define IXGBE_ADVTXD_DCMD_DEXT IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */
#define IXGBE_ADVTXD_DCMD_VLE IXGBE_TXD_CMD_VLE /* VLAN pkt enable */
#define IXGBE_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define IXGBE_ADVTXD_STAT_DD IXGBE_TXD_STAT_DD /* Descriptor Done */
-#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
+#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED pres in WB */
#define IXGBE_ADVTXD_STAT_RSV 0x0000000C /* STA Reserved */
#define IXGBE_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
+#define IXGBE_ADVTXD_CC 0x00000080 /* Check Context */
#define IXGBE_ADVTXD_POPTS_SHIFT 8 /* Adv desc POPTS shift */
#define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
+ IXGBE_ADVTXD_POPTS_SHIFT)
#define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
-#define IXGBE_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit-RDMA DDP hdr */
-#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
-#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */
-#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
-#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
-#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
-#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
-#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
-#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
-#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
-#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
-#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
-#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
-
+ IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */
+#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
+#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
+#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
+#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
+#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
+#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
+#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
+#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/
+#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
+#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+
+/* Autonegotiation advertised speeds */
+typedef u32 ixgbe_autoneg_advertised;
/* Link speed */
+typedef u32 ixgbe_link_speed;
#define IXGBE_LINK_SPEED_UNKNOWN 0
#define IXGBE_LINK_SPEED_100_FULL 0x0008
#define IXGBE_LINK_SPEED_1GB_FULL 0x0020
#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
+#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
+ IXGBE_LINK_SPEED_10GB_FULL)
+
+/* Physical layer type */
+typedef u32 ixgbe_physical_layer;
+#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
+#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
+#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
+#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004
+#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
+#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080
+#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
+#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
+#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
enum ixgbe_eeprom_type {
@@ -1138,16 +1202,38 @@ enum ixgbe_mac_type {
enum ixgbe_phy_type {
ixgbe_phy_unknown = 0,
- ixgbe_phy_tn,
ixgbe_phy_qt,
- ixgbe_phy_xaui
+ ixgbe_phy_xaui,
+ ixgbe_phy_tw_tyco,
+ ixgbe_phy_tw_unknown,
+ ixgbe_phy_sfp_avago,
+ ixgbe_phy_sfp_ftl,
+ ixgbe_phy_sfp_unknown,
+ ixgbe_phy_generic
+};
+
+/*
+ * SFP+ module type IDs:
+ *
+ * ID Module Type
+ * =============
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ */
+enum ixgbe_sfp_type {
+ ixgbe_sfp_type_da_cu = 0,
+ ixgbe_sfp_type_sr = 1,
+ ixgbe_sfp_type_lr = 2,
+ ixgbe_sfp_type_unknown = 0xFFFF
};
enum ixgbe_media_type {
ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber,
ixgbe_media_type_copper,
- ixgbe_media_type_backplane
+ ixgbe_media_type_backplane,
+ ixgbe_media_type_virtual
};
/* Flow Control Settings */
@@ -1245,59 +1331,114 @@ struct ixgbe_hw;
typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
u32 *vmdq);
+/* Function pointer table */
+struct ixgbe_eeprom_operations {
+ s32 (*init_params)(struct ixgbe_hw *);
+ s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+ s32 (*write)(struct ixgbe_hw *, u16, u16);
+ s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
+ s32 (*update_checksum)(struct ixgbe_hw *);
+};
+
struct ixgbe_mac_operations {
- s32 (*reset)(struct ixgbe_hw *);
+ s32 (*init_hw)(struct ixgbe_hw *);
+ s32 (*reset_hw)(struct ixgbe_hw *);
+ s32 (*start_hw)(struct ixgbe_hw *);
+ s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+ s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+ s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+ s32 (*stop_adapter)(struct ixgbe_hw *);
+ s32 (*get_bus_info)(struct ixgbe_hw *);
+ s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
+ s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+
+ /* Link */
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
- s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+ bool);
+ s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
+ s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
+ bool *);
+
+ /* LED */
+ s32 (*led_on)(struct ixgbe_hw *, u32);
+ s32 (*led_off)(struct ixgbe_hw *, u32);
+ s32 (*blink_led_start)(struct ixgbe_hw *, u32);
+ s32 (*blink_led_stop)(struct ixgbe_hw *, u32);
+
+ /* RAR, Multicast, VLAN */
+ s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32);
+ s32 (*clear_rar)(struct ixgbe_hw *, u32);
+ s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
+ s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
+ s32 (*init_rx_addrs)(struct ixgbe_hw *);
+ s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+ ixgbe_mc_addr_itr);
+ s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+ ixgbe_mc_addr_itr);
+ s32 (*enable_mc)(struct ixgbe_hw *);
+ s32 (*disable_mc)(struct ixgbe_hw *);
+ s32 (*clear_vfta)(struct ixgbe_hw *);
+ s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+ s32 (*init_uta_tables)(struct ixgbe_hw *);
+
+ /* Flow Control */
+ s32 (*setup_fc)(struct ixgbe_hw *, s32);
};
struct ixgbe_phy_operations {
+ s32 (*identify)(struct ixgbe_hw *);
+ s32 (*identify_sfp)(struct ixgbe_hw *);
+ s32 (*reset)(struct ixgbe_hw *);
+ s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
+ s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
-};
-
-struct ixgbe_mac_info {
- struct ixgbe_mac_operations ops;
- enum ixgbe_mac_type type;
- u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- s32 mc_filter_type;
- u32 mcft_size;
- u32 vft_size;
- u32 num_rar_entries;
- u32 num_rx_queues;
- u32 num_tx_queues;
- u32 link_attach_type;
- u32 link_mode_select;
- bool link_settings_loaded;
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+ bool);
+ s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
+ s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
+ s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
+ s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
};
struct ixgbe_eeprom_info {
- enum ixgbe_eeprom_type type;
- u16 word_size;
- u16 address_bits;
+ struct ixgbe_eeprom_operations ops;
+ enum ixgbe_eeprom_type type;
+ u32 semaphore_delay;
+ u16 word_size;
+ u16 address_bits;
};
-struct ixgbe_phy_info {
- struct ixgbe_phy_operations ops;
-
- enum ixgbe_phy_type type;
- u32 addr;
- u32 id;
- u32 revision;
- enum ixgbe_media_type media_type;
- u32 autoneg_advertised;
- bool autoneg_wait_to_complete;
+struct ixgbe_mac_info {
+ struct ixgbe_mac_operations ops;
+ enum ixgbe_mac_type type;
+ u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ s32 mc_filter_type;
+ u32 mcft_size;
+ u32 vft_size;
+ u32 num_rar_entries;
+ u32 max_tx_queues;
+ u32 max_rx_queues;
+ u32 link_attach_type;
+ u32 link_mode_select;
+ bool link_settings_loaded;
+ bool autoneg;
+ bool autoneg_failed;
};
-struct ixgbe_info {
- enum ixgbe_mac_type mac;
- s32 (*get_invariants)(struct ixgbe_hw *);
- struct ixgbe_mac_operations *mac_ops;
+struct ixgbe_phy_info {
+ struct ixgbe_phy_operations ops;
+ enum ixgbe_phy_type type;
+ u32 addr;
+ u32 id;
+ enum ixgbe_sfp_type sfp_type;
+ u32 revision;
+ enum ixgbe_media_type media_type;
+ bool reset_disable;
+ ixgbe_autoneg_advertised autoneg_advertised;
+ bool autoneg_wait_to_complete;
};
struct ixgbe_hw {
@@ -1316,6 +1457,15 @@ struct ixgbe_hw {
bool adapter_stopped;
};
+struct ixgbe_info {
+ enum ixgbe_mac_type mac;
+ s32 (*get_invariants)(struct ixgbe_hw *);
+ struct ixgbe_mac_operations *mac_ops;
+ struct ixgbe_eeprom_operations *eeprom_ops;
+ struct ixgbe_phy_operations *phy_ops;
+};
+
+
/* Error Codes */
#define IXGBE_ERR_EEPROM -1
#define IXGBE_ERR_EEPROM_CHECKSUM -2
@@ -1334,6 +1484,8 @@ struct ixgbe_hw {
#define IXGBE_ERR_RESET_FAILED -15
#define IXGBE_ERR_SWFW_SYNC -16
#define IXGBE_ERR_PHY_ADDR_INVALID -17
+#define IXGBE_ERR_I2C -18
+#define IXGBE_ERR_SFP_NOT_SUPPORTED -19
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 0a97c26..a1e22ed 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -41,7 +41,7 @@
#endif
#if MFE_DEBUG>=1
-#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __FUNCTION__ , ## args)
+#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args)
#define MFE_RX_DEBUG 2
#else
#define DPRINTK(str,args...)
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 6d343ef..4e7a5fa 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -203,7 +203,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
out_badirq:
printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
- dev->name, __FUNCTION__, irq);
+ dev->name, __func__, irq);
return ret;
}
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index d6524db..195c397 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -102,6 +102,9 @@ MODULE_LICENSE("Dual BSD/GPL");
#define MYRI10GE_ALLOC_SIZE ((1 << MYRI10GE_ALLOC_ORDER) * PAGE_SIZE)
#define MYRI10GE_MAX_FRAGS_PER_FRAME (MYRI10GE_MAX_ETHER_MTU/MYRI10GE_ALLOC_SIZE + 1)
+#define MYRI10GE_MAX_SLICES 32
+#define MYRI10GE_TOEPLITZ_HASH (MXGEFW_RSS_HASH_TYPE_TCP_IPV4|MXGEFW_RSS_HASH_TYPE_IPV4)
+
struct myri10ge_rx_buffer_state {
struct page *page;
int page_offset;
@@ -138,6 +141,8 @@ struct myri10ge_rx_buf {
struct myri10ge_tx_buf {
struct mcp_kreq_ether_send __iomem *lanai; /* lanai ptr for sendq */
+ __be32 __iomem *send_go; /* "go" doorbell ptr */
+ __be32 __iomem *send_stop; /* "stop" doorbell ptr */
struct mcp_kreq_ether_send *req_list; /* host shadow of sendq */
char *req_bytes;
struct myri10ge_tx_buffer_state *info;
@@ -149,6 +154,7 @@ struct myri10ge_tx_buf {
int done ____cacheline_aligned; /* transmit slots completed */
int pkt_done; /* packets completed */
int wake_queue;
+ int queue_active;
};
struct myri10ge_rx_done {
@@ -183,7 +189,7 @@ struct myri10ge_slice_state {
dma_addr_t fw_stats_bus;
int watchdog_tx_done;
int watchdog_tx_req;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
int cached_dca_tag;
int cpu;
__be32 __iomem *dca_tag;
@@ -215,7 +221,7 @@ struct myri10ge_priv {
int msi_enabled;
int msix_enabled;
struct msix_entry *msix_vectors;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
int dca_enabled;
#endif
u32 link_state;
@@ -250,6 +256,8 @@ struct myri10ge_priv {
u32 read_write_dma;
u32 link_changes;
u32 msg_enable;
+ u32 *toeplitz_hash_table;
+ u8 rss_key[32];
};
static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -418,6 +426,12 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
return -ENOSYS;
} else if (result == MXGEFW_CMD_ERROR_UNALIGNED) {
return -E2BIG;
+ } else if (result == MXGEFW_CMD_ERROR_RANGE &&
+ cmd == MXGEFW_CMD_ENABLE_RSS_QUEUES &&
+ (data->
+ data1 & MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES) !=
+ 0) {
+ return -ERANGE;
} else {
dev_err(&mgp->pdev->dev,
"command %d failed, result = %d\n",
@@ -891,7 +905,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
struct myri10ge_slice_state *ss;
int i, status;
size_t bytes;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
unsigned long dca_tag_off;
#endif
@@ -947,9 +961,24 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
*/
cmd.data0 = mgp->num_slices;
- cmd.data1 = 1; /* use MSI-X */
+ cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
+ if (mgp->dev->real_num_tx_queues > 1)
+ cmd.data1 |= MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ENABLE_RSS_QUEUES,
&cmd, 0);
+
+ /* Firmware older than 1.4.32 only supports multiple
+ * RX queues, so if we get an error, first retry using a
+ * single TX queue before giving up */
+ if (status != 0 && mgp->dev->real_num_tx_queues > 1) {
+ mgp->dev->real_num_tx_queues = 1;
+ cmd.data0 = mgp->num_slices;
+ cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
+ status = myri10ge_send_cmd(mgp,
+ MXGEFW_CMD_ENABLE_RSS_QUEUES,
+ &cmd, 0);
+ }
+
if (status != 0) {
dev_err(&mgp->pdev->dev,
"failed to set number of slices\n");
@@ -986,7 +1015,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
dca_tag_off = cmd.data0;
for (i = 0; i < mgp->num_slices; i++) {
@@ -1025,7 +1054,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
return status;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
static void
myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
{
@@ -1060,8 +1089,9 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
}
err = dca_add_requester(&pdev->dev);
if (err) {
- dev_err(&pdev->dev,
- "dca_add_requester() failed, err=%d\n", err);
+ if (err != -ENODEV)
+ dev_err(&pdev->dev,
+ "dca_add_requester() failed, err=%d\n", err);
return;
}
mgp->dca_enabled = 1;
@@ -1316,6 +1346,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
{
struct pci_dev *pdev = ss->mgp->pdev;
struct myri10ge_tx_buf *tx = &ss->tx;
+ struct netdev_queue *dev_queue;
struct sk_buff *skb;
int idx, len;
@@ -1349,11 +1380,31 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
PCI_DMA_TODEVICE);
}
}
+
+ dev_queue = netdev_get_tx_queue(ss->dev, ss - ss->mgp->ss);
+ /*
+ * Make a minimal effort to prevent the NIC from polling an
+ * idle tx queue. If we can't get the lock we leave the queue
+ * active. In this case, either a thread was about to start
+ * using the queue anyway, or we lost a race and the NIC will
+ * waste some of its resources polling an inactive queue for a
+ * while.
+ */
+
+ if ((ss->mgp->dev->real_num_tx_queues > 1) &&
+ __netif_tx_trylock(dev_queue)) {
+ if (tx->req == tx->done) {
+ tx->queue_active = 0;
+ put_be32(htonl(1), tx->send_stop);
+ }
+ __netif_tx_unlock(dev_queue);
+ }
+
/* start the queue if we've stopped it */
- if (netif_queue_stopped(ss->dev)
+ if (netif_tx_queue_stopped(dev_queue)
&& tx->req - tx->done < (tx->mask >> 1)) {
tx->wake_queue++;
- netif_wake_queue(ss->dev);
+ netif_tx_wake_queue(dev_queue);
}
}
@@ -1457,7 +1508,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
struct net_device *netdev = ss->mgp->dev;
int work_done;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
if (ss->mgp->dca_enabled)
myri10ge_update_dca(ss);
#endif
@@ -1481,9 +1532,9 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
u32 send_done_count;
int i;
- /* an interrupt on a non-zero slice is implicitly valid
- * since MSI-X irqs are not shared */
- if (ss != mgp->ss) {
+ /* an interrupt on a non-zero receive-only slice is implicitly
+ * valid since MSI-X irqs are not shared */
+ if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
netif_rx_schedule(ss->dev, &ss->napi);
return (IRQ_HANDLED);
}
@@ -1525,7 +1576,9 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
barrier();
}
- myri10ge_check_statblock(mgp);
+ /* Only slice 0 updates stats */
+ if (ss == mgp->ss)
+ myri10ge_check_statblock(mgp);
put_be32(htonl(3), ss->irq_claim + 1);
return (IRQ_HANDLED);
@@ -1686,8 +1739,8 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
"tx_boundary", "WC", "irq", "MSI", "MSIX",
"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
"serial_number", "watchdog_resets",
-#ifdef CONFIG_DCA
- "dca_capable", "dca_enabled",
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+ "dca_capable_firmware", "dca_device_present",
#endif
"link_changes", "link_up", "dropped_link_overflow",
"dropped_link_error_or_filtered",
@@ -1765,7 +1818,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)mgp->read_write_dma;
data[i++] = (unsigned int)mgp->serial_number;
data[i++] = (unsigned int)mgp->watchdog_resets;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
data[i++] = (unsigned int)(mgp->dca_enabled);
#endif
@@ -1883,6 +1936,7 @@ static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
/* ensure req_list entries are aligned to 8 bytes */
ss->tx.req_list = (struct mcp_kreq_ether_send *)
ALIGN((unsigned long)ss->tx.req_bytes, 8);
+ ss->tx.queue_active = 0;
bytes = rx_ring_entries * sizeof(*ss->rx_small.shadow);
ss->rx_small.shadow = kzalloc(bytes, GFP_KERNEL);
@@ -2193,6 +2247,169 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
return 0;
}
+static int myri10ge_init_toeplitz(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_cmd cmd;
+ int i, b, s, t, j;
+ int status;
+ u32 k[8];
+ u32 tmp;
+ u8 *key;
+
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RSS_KEY_OFFSET, &cmd, 0);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to get rss key\n", mgp->dev->name);
+ return -EIO;
+ }
+ memcpy_fromio(mgp->rss_key, mgp->sram + cmd.data0,
+ sizeof(mgp->rss_key));
+
+ mgp->toeplitz_hash_table = kmalloc(sizeof(u32) * 12 * 256, GFP_KERNEL);
+ if (mgp->toeplitz_hash_table == NULL)
+ return -ENOMEM;
+ key = (u8 *) mgp->rss_key;
+ t = 0;
+ for (b = 0; b < 12; b++) {
+ for (s = 0; s < 8; s++) {
+ /* Bits: b*8+s, ..., b*8+s+31 */
+ k[s] = 0;
+ for (j = 0; j < 32; j++) {
+ int bit = b * 8 + s + j;
+ bit = 0x1 & (key[bit / 8] >> (7 - (bit & 0x7)));
+ k[s] |= bit << (31 - j);
+ }
+ }
+
+ for (i = 0; i <= 0xff; i++) {
+ tmp = 0;
+ if (i & (1 << 7)) {
+ tmp ^= k[0];
+ }
+ if (i & (1 << 6)) {
+ tmp ^= k[1];
+ }
+ if (i & (1 << 5)) {
+ tmp ^= k[2];
+ }
+ if (i & (1 << 4)) {
+ tmp ^= k[3];
+ }
+ if (i & (1 << 3)) {
+ tmp ^= k[4];
+ }
+ if (i & (1 << 2)) {
+ tmp ^= k[5];
+ }
+ if (i & (1 << 1)) {
+ tmp ^= k[6];
+ }
+ if (i & (1 << 0)) {
+ tmp ^= k[7];
+ }
+ mgp->toeplitz_hash_table[t++] = tmp;
+ }
+ }
+ return 0;
+}
+
+static inline u16
+myri10ge_toeplitz_select_queue(struct net_device *dev, struct iphdr *ip)
+{
+ struct myri10ge_priv *mgp = netdev_priv(dev);
+ struct tcphdr *hdr;
+ u32 saddr, daddr;
+ u32 hash;
+ u32 *table = mgp->toeplitz_hash_table;
+ u16 src, dst;
+
+ /*
+ * Note hashing order is reversed from how it is done
+ * in the NIC, so as to generate the same hash value
+ * for the connection to try to keep connections CPU local
+ */
+
+ /* hash on IPv4 src/dst address */
+ saddr = ntohl(ip->saddr);
+ daddr = ntohl(ip->daddr);
+ hash = table[(256 * 0) + ((daddr >> 24) & 0xff)];
+ hash ^= table[(256 * 1) + ((daddr >> 16) & 0xff)];
+ hash ^= table[(256 * 2) + ((daddr >> 8) & 0xff)];
+ hash ^= table[(256 * 3) + ((daddr) & 0xff)];
+ hash ^= table[(256 * 4) + ((saddr >> 24) & 0xff)];
+ hash ^= table[(256 * 5) + ((saddr >> 16) & 0xff)];
+ hash ^= table[(256 * 6) + ((saddr >> 8) & 0xff)];
+ hash ^= table[(256 * 7) + ((saddr) & 0xff)];
+ /* hash on TCP port, if required */
+ if ((myri10ge_rss_hash & MXGEFW_RSS_HASH_TYPE_TCP_IPV4) &&
+ ip->protocol == IPPROTO_TCP) {
+ hdr = (struct tcphdr *)(((u8 *) ip) + (ip->ihl << 2));
+ src = ntohs(hdr->source);
+ dst = ntohs(hdr->dest);
+
+ hash ^= table[(256 * 8) + ((dst >> 8) & 0xff)];
+ hash ^= table[(256 * 9) + ((dst) & 0xff)];
+ hash ^= table[(256 * 10) + ((src >> 8) & 0xff)];
+ hash ^= table[(256 * 11) + ((src) & 0xff)];
+ }
+ return (u16) (hash & (dev->real_num_tx_queues - 1));
+}
+
+static u16
+myri10ge_simple_select_queue(struct net_device *dev, struct iphdr *ip)
+{
+ struct udphdr *hdr;
+ u32 hash_val = 0;
+
+ if (ip->protocol != IPPROTO_TCP && ip->protocol != IPPROTO_UDP)
+ return (0);
+ hdr = (struct udphdr *)(((u8 *) ip) + (ip->ihl << 2));
+
+ /*
+ * Use the second byte of the *destination* address for
+ * MXGEFW_RSS_HASH_TYPE_SRC_PORT, so as to match NIC's hashing
+ */
+ hash_val = ntohs(hdr->dest) & 0xff;
+ if (myri10ge_rss_hash == MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT)
+ hash_val += ntohs(hdr->source) & 0xff;
+
+ return (u16) (hash_val & (dev->real_num_tx_queues - 1));
+}
+
+static u16 myri10ge_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ struct iphdr *ip;
+ struct vlan_hdr *vh;
+
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ ip = ip_hdr(skb);
+ } else if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+ vh = (struct vlan_hdr *)skb->data;
+ if ((vh->h_vlan_encapsulated_proto !=
+ __constant_htons(ETH_P_IP)))
+ return 0;
+ ip = (struct iphdr *)skb->data + sizeof(*vh);
+ } else {
+ return 0;
+ }
+
+ switch (myri10ge_rss_hash) {
+ case MXGEFW_RSS_HASH_TYPE_IPV4:
+ /* fallthru */
+ case MXGEFW_RSS_HASH_TYPE_TCP_IPV4:
+ /* fallthru */
+ case (MXGEFW_RSS_HASH_TYPE_IPV4 | MXGEFW_RSS_HASH_TYPE_TCP_IPV4):
+ return (myri10ge_toeplitz_select_queue(dev, ip));
+ break;
+ case MXGEFW_RSS_HASH_TYPE_SRC_PORT:
+ /* fallthru */
+ case MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT:
+ return (myri10ge_simple_select_queue(dev, ip));
+ default:
+ return (0);
+ }
+}
+
static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
{
struct myri10ge_cmd cmd;
@@ -2200,11 +2417,14 @@ static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
int status;
ss = &mgp->ss[slice];
- cmd.data0 = 0; /* single slice for now */
- status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
- ss->tx.lanai = (struct mcp_kreq_ether_send __iomem *)
- (mgp->sram + cmd.data0);
-
+ status = 0;
+ if (slice == 0 || (mgp->dev->real_num_tx_queues > 1)) {
+ cmd.data0 = slice;
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET,
+ &cmd, 0);
+ ss->tx.lanai = (struct mcp_kreq_ether_send __iomem *)
+ (mgp->sram + cmd.data0);
+ }
cmd.data0 = slice;
status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET,
&cmd, 0);
@@ -2216,6 +2436,10 @@ static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)
(mgp->sram + cmd.data0);
+ ss->tx.send_go = (__iomem __be32 *)
+ (mgp->sram + MXGEFW_ETH_SEND_GO + 64 * slice);
+ ss->tx.send_stop = (__iomem __be32 *)
+ (mgp->sram + MXGEFW_ETH_SEND_STOP + 64 * slice);
return status;
}
@@ -2229,7 +2453,7 @@ static int myri10ge_set_stats(struct myri10ge_priv *mgp, int slice)
ss = &mgp->ss[slice];
cmd.data0 = MYRI10GE_LOWPART_TO_U32(ss->fw_stats_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(ss->fw_stats_bus);
- cmd.data2 = sizeof(struct mcp_irq_data);
+ cmd.data2 = sizeof(struct mcp_irq_data) | (slice << 16);
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
if (status == -ENOSYS) {
dma_addr_t bus = ss->fw_stats_bus;
@@ -2270,7 +2494,9 @@ static int myri10ge_open(struct net_device *dev)
if (mgp->num_slices > 1) {
cmd.data0 = mgp->num_slices;
- cmd.data1 = 1; /* use MSI-X */
+ cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
+ if (mgp->dev->real_num_tx_queues > 1)
+ cmd.data1 |= MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ENABLE_RSS_QUEUES,
&cmd, 0);
if (status != 0) {
@@ -2291,6 +2517,7 @@ static int myri10ge_open(struct net_device *dev)
printk(KERN_ERR
"myri10ge: %s: failed to setup rss tables\n",
dev->name);
+ goto abort_with_nothing;
}
/* just enable an identity mapping */
@@ -2298,6 +2525,20 @@ static int myri10ge_open(struct net_device *dev)
for (i = 0; i < mgp->num_slices; i++)
__raw_writeb(i, &itable[i]);
+ if (mgp->dev->real_num_tx_queues > 1) {
+ if (myri10ge_rss_hash & MYRI10GE_TOEPLITZ_HASH) {
+ /* grab the rss key for use in hashing transmits */
+ status = myri10ge_init_toeplitz(mgp);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to init toeplitz table\n",
+ dev->name);
+ goto abort_with_nothing;
+ }
+ }
+ mgp->dev->select_queue = myri10ge_select_queue;
+ }
+
cmd.data0 = 1;
cmd.data1 = myri10ge_rss_hash;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_RSS_ENABLE,
@@ -2306,7 +2547,7 @@ static int myri10ge_open(struct net_device *dev)
printk(KERN_ERR
"myri10ge: %s: failed to enable slices\n",
dev->name);
- goto abort_with_nothing;
+ goto abort_with_toeplitz;
}
}
@@ -2361,7 +2602,11 @@ static int myri10ge_open(struct net_device *dev)
status = myri10ge_allocate_rings(ss);
if (status != 0)
goto abort_with_rings;
- if (slice == 0)
+
+ /* only firmware which supports multiple TX queues
+ * supports setting up the tx stats on non-zero
+ * slices */
+ if (slice == 0 || mgp->dev->real_num_tx_queues > 1)
status = myri10ge_set_stats(mgp, slice);
if (status) {
printk(KERN_ERR
@@ -2427,7 +2672,8 @@ static int myri10ge_open(struct net_device *dev)
mgp->running = MYRI10GE_ETH_RUNNING;
mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ;
add_timer(&mgp->watchdog_timer);
- netif_wake_queue(dev);
+ netif_tx_wake_all_queues(dev);
+
return 0;
abort_with_rings:
@@ -2436,6 +2682,11 @@ abort_with_rings:
myri10ge_free_irq(mgp);
+abort_with_toeplitz:
+ if (mgp->toeplitz_hash_table != NULL) {
+ kfree(mgp->toeplitz_hash_table);
+ mgp->toeplitz_hash_table = NULL;
+ }
abort_with_nothing:
mgp->running = MYRI10GE_ETH_STOPPED;
return -ENOMEM;
@@ -2454,13 +2705,15 @@ static int myri10ge_close(struct net_device *dev)
if (mgp->ss[0].tx.req_bytes == NULL)
return 0;
+ dev->select_queue = NULL;
del_timer_sync(&mgp->watchdog_timer);
mgp->running = MYRI10GE_ETH_STOPPING;
for (i = 0; i < mgp->num_slices; i++) {
napi_disable(&mgp->ss[i].napi);
}
netif_carrier_off(dev);
- netif_stop_queue(dev);
+
+ netif_tx_stop_all_queues(dev);
old_down_cnt = mgp->down_cnt;
mb();
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0);
@@ -2477,6 +2730,11 @@ static int myri10ge_close(struct net_device *dev)
for (i = 0; i < mgp->num_slices; i++)
myri10ge_free_rings(&mgp->ss[i]);
+ if (mgp->toeplitz_hash_table != NULL) {
+ kfree(mgp->toeplitz_hash_table);
+ mgp->toeplitz_hash_table = NULL;
+ }
+
mgp->running = MYRI10GE_ETH_STOPPED;
return 0;
}
@@ -2565,18 +2823,23 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
struct mcp_kreq_ether_send *req;
struct myri10ge_tx_buf *tx;
struct skb_frag_struct *frag;
+ struct netdev_queue *netdev_queue;
dma_addr_t bus;
u32 low;
__be32 high_swapped;
unsigned int len;
int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
- u16 pseudo_hdr_offset, cksum_offset;
+ u16 pseudo_hdr_offset, cksum_offset, queue;
int cum_len, seglen, boundary, rdma_count;
u8 flags, odd_flag;
- /* always transmit through slot 0 */
- ss = mgp->ss;
+ queue = skb_get_queue_mapping(skb);
+ queue &= (mgp->num_slices - 1);
+
+ ss = &mgp->ss[queue];
+ netdev_queue = netdev_get_tx_queue(mgp->dev, queue);
tx = &ss->tx;
+
again:
req = tx->req_list;
avail = tx->mask - 1 - (tx->req - tx->done);
@@ -2592,7 +2855,7 @@ again:
if ((unlikely(avail < max_segments))) {
/* we are out of transmit resources */
tx->stop_queue++;
- netif_stop_queue(dev);
+ netif_tx_stop_queue(netdev_queue);
return 1;
}
@@ -2785,10 +3048,16 @@ again:
idx = ((count - 1) + tx->req) & tx->mask;
tx->info[idx].last = 1;
myri10ge_submit_req(tx, tx->req_list, count);
+ /* if using multiple tx queues, make sure NIC polls the
+ * current slice */
+ if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) {
+ tx->queue_active = 1;
+ put_be32(htonl(1), tx->send_go);
+ }
tx->pkt_start++;
if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
tx->stop_queue++;
- netif_stop_queue(dev);
+ netif_tx_stop_queue(netdev_queue);
}
dev->trans_start = jiffies;
return 0;
@@ -3366,20 +3635,21 @@ static void myri10ge_watchdog(struct work_struct *work)
for (i = 0; i < mgp->num_slices; i++) {
tx = &mgp->ss[i].tx;
printk(KERN_INFO
- "myri10ge: %s: (%d): %d %d %d %d %d\n",
- mgp->dev->name, i, tx->req, tx->done,
- tx->pkt_start, tx->pkt_done,
+ "myri10ge: %s: (%d): %d %d %d %d %d %d\n",
+ mgp->dev->name, i, tx->queue_active, tx->req,
+ tx->done, tx->pkt_start, tx->pkt_done,
(int)ntohl(mgp->ss[i].fw_stats->
send_done_count));
msleep(2000);
printk(KERN_INFO
- "myri10ge: %s: (%d): %d %d %d %d %d\n",
- mgp->dev->name, i, tx->req, tx->done,
- tx->pkt_start, tx->pkt_done,
+ "myri10ge: %s: (%d): %d %d %d %d %d %d\n",
+ mgp->dev->name, i, tx->queue_active, tx->req,
+ tx->done, tx->pkt_start, tx->pkt_done,
(int)ntohl(mgp->ss[i].fw_stats->
send_done_count));
}
}
+
rtnl_lock();
myri10ge_close(mgp->dev);
status = myri10ge_load_firmware(mgp, 1);
@@ -3434,10 +3704,14 @@ static void myri10ge_watchdog_timer(unsigned long arg)
/* nic seems like it might be stuck.. */
if (rx_pause_cnt != mgp->watchdog_pause) {
if (net_ratelimit())
- printk(KERN_WARNING "myri10ge %s:"
+ printk(KERN_WARNING
+ "myri10ge %s slice %d:"
"TX paused, check link partner\n",
- mgp->dev->name);
+ mgp->dev->name, i);
} else {
+ printk(KERN_WARNING
+ "myri10ge %s slice %d stuck:",
+ mgp->dev->name, i);
reset_needed = 1;
}
}
@@ -3623,6 +3897,9 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
mgp->num_slices);
if (status == 0) {
pci_disable_msix(pdev);
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ mgp->features |= NETIF_F_MULTI_QUEUE;
+#endif
return;
}
if (status > 0)
@@ -3652,7 +3929,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int status = -ENXIO;
int dac_enabled;
- netdev = alloc_etherdev(sizeof(*mgp));
+ netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
if (netdev == NULL) {
dev_err(dev, "Could not allocate ethernet device\n");
return -ENOMEM;
@@ -3757,13 +4034,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "failed to alloc slice state\n");
goto abort_with_firmware;
}
-
+ netdev->real_num_tx_queues = mgp->num_slices;
status = myri10ge_reset(mgp);
if (status != 0) {
dev_err(&pdev->dev, "failed reset\n");
goto abort_with_slices;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
myri10ge_setup_dca(mgp);
#endif
pci_set_drvdata(pdev, mgp);
@@ -3781,6 +4058,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->set_multicast_list = myri10ge_set_multicast_list;
netdev->set_mac_address = myri10ge_set_mac_address;
netdev->features = mgp->features;
+
if (dac_enabled)
netdev->features |= NETIF_F_HIGHDMA;
@@ -3866,7 +4144,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
netdev = mgp->dev;
unregister_netdev(netdev);
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
myri10ge_teardown_dca(mgp);
#endif
myri10ge_dummy_rdma(mgp, 0);
@@ -3911,7 +4189,7 @@ static struct pci_driver myri10ge_driver = {
#endif
};
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
static int
myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
{
@@ -3936,16 +4214,17 @@ static __init int myri10ge_init_module(void)
printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name,
MYRI10GE_VERSION_STR);
- if (myri10ge_rss_hash > MXGEFW_RSS_HASH_TYPE_SRC_PORT ||
- myri10ge_rss_hash < MXGEFW_RSS_HASH_TYPE_IPV4) {
+ if (myri10ge_rss_hash > MXGEFW_RSS_HASH_TYPE_MAX) {
printk(KERN_ERR
"%s: Illegal rssh hash type %d, defaulting to source port\n",
myri10ge_driver.name, myri10ge_rss_hash);
myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
dca_register_notify(&myri10ge_dca_notifier);
#endif
+ if (myri10ge_max_slices > MYRI10GE_MAX_SLICES)
+ myri10ge_max_slices = MYRI10GE_MAX_SLICES;
return pci_register_driver(&myri10ge_driver);
}
@@ -3954,7 +4233,7 @@ module_init(myri10ge_init_module);
static __exit void myri10ge_cleanup_module(void)
{
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
dca_unregister_notify(&myri10ge_dca_notifier);
#endif
pci_unregister_driver(&myri10ge_driver);
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 3f9af75..b9bed82 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -189,7 +189,7 @@ netx_eth_interrupt(int irq, void *dev_id)
if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
printk("%s: unexpected status: 0x%08x\n",
- __FUNCTION__, status);
+ __func__, status);
fill_level =
readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 244ab49..f8e601c 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -742,7 +742,7 @@ extern char netxen_nic_driver_name[];
} while (0)
#else
#define DPRINTK(klevel, fmt, args...) do { \
- printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
+ printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
(adapter != NULL && adapter->netdev != NULL) ? \
adapter->netdev->name : NULL, \
## args); } while(0)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 008fd66..6ef3f0d 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -77,18 +77,18 @@ static irqreturn_t netxen_msi_intr(int irq, void *data);
/* PCI Device ID Table */
#define ENTRY(device) \
- {PCI_DEVICE(0x4040, (device)), \
+ {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
- ENTRY(0x0001),
- ENTRY(0x0002),
- ENTRY(0x0003),
- ENTRY(0x0004),
- ENTRY(0x0005),
- ENTRY(0x0024),
- ENTRY(0x0025),
- ENTRY(0x0100),
+ ENTRY(PCI_DEVICE_ID_NX2031_10GXSR),
+ ENTRY(PCI_DEVICE_ID_NX2031_10GCX4),
+ ENTRY(PCI_DEVICE_ID_NX2031_4GCU),
+ ENTRY(PCI_DEVICE_ID_NX2031_IMEZ),
+ ENTRY(PCI_DEVICE_ID_NX2031_HMEZ),
+ ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT),
+ ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT2),
+ ENTRY(PCI_DEVICE_ID_NX3031),
{0,}
};
@@ -241,7 +241,7 @@ static void netxen_check_options(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_REF_QG:
case NETXEN_BRDTYPE_P3_4_GB:
case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->msix_supported = 0;
+ adapter->msix_supported = !!use_msi_x;
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
break;
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 53451c3..0a575fe 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -119,7 +119,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n";
#ifdef NETDRV_DEBUG
/* note: prints function name for you */
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
#else
# define DPRINTK(fmt, args...)
#endif
@@ -130,7 +130,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n";
# define assert(expr) \
if(!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr,__FILE__,__func__,__LINE__); \
}
#endif
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 5d86281..025f526 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -370,7 +370,7 @@ static void r6040_init_mac_regs(struct net_device *dev)
/* Reset internal state machine */
iowrite16(2, ioaddr + MAC_SM);
iowrite16(0, ioaddr + MAC_SM);
- udelay(5000);
+ mdelay(5);
/* MAC Bus Control Register */
iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
@@ -806,7 +806,7 @@ static void r6040_mac_address(struct net_device *dev)
iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */
iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */
iowrite16(0, ioaddr + MAC_SM);
- udelay(5000);
+ mdelay(5);
/* Restore MAC Address */
adrp = (u16 *) dev->dev_addr;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 1822491..0b7fe84 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -36,7 +36,7 @@
#define assert(expr) \
if (!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr,__FILE__,__func__,__LINE__); \
}
#define dprintk(fmt, args...) \
do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 243db33..fd24de5 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3136,7 +3136,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
if (skb == NULL) {
spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
DBG_PRINT(ERR_DBG, "%s: Null skb ",
- __FUNCTION__);
+ __func__);
DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
return;
}
@@ -3496,7 +3496,7 @@ static void s2io_reset(struct s2io_nic * sp)
unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
- __FUNCTION__, sp->dev->name);
+ __func__, sp->dev->name);
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
@@ -3518,7 +3518,7 @@ static void s2io_reset(struct s2io_nic * sp)
}
if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) {
- DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __func__);
}
pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
@@ -3768,7 +3768,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, msix_index)) {
- DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
continue;
}
}
@@ -3789,7 +3789,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
val64 = (s2BIT(15) | vBIT(msix_index, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, msix_index)) {
- DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
continue;
}
addr = readq(&bar0->xmsi_address);
@@ -3812,7 +3812,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
GFP_KERNEL);
if (!nic->entries) {
DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
- __FUNCTION__);
+ __func__);
nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
return -ENOMEM;
}
@@ -3826,7 +3826,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
GFP_KERNEL);
if (!nic->s2io_entries) {
DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
- __FUNCTION__);
+ __func__);
nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
kfree(nic->entries);
nic->mac_control.stats_info->sw_stat.mem_freed
@@ -6746,7 +6746,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
ret = s2io_card_up(sp);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
- __FUNCTION__);
+ __func__);
return ret;
}
s2io_wake_all_tx_queue(sp);
@@ -7530,7 +7530,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
default:
DBG_PRINT(ERR_DBG,
"%s: Samadhana!!\n",
- __FUNCTION__);
+ __func__);
BUG();
}
}
@@ -7781,7 +7781,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return -ENOMEM;
}
if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+ DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __func__, ret);
pci_disable_device(pdev);
return -ENODEV;
}
@@ -7998,7 +7998,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (sp->device_type & XFRAME_II_DEVICE) {
mode = s2io_verify_pci_mode(sp);
if (mode < 0) {
- DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "%s: ", __func__);
DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
ret = -EBADSLT;
goto set_swap_failed;
@@ -8299,7 +8299,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) {
DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n",
- __FUNCTION__);
+ __func__);
return -1;
}
@@ -8330,7 +8330,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
static int check_for_socket_match(struct lro *lro, struct iphdr *ip,
struct tcphdr *tcp)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) ||
(lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest))
return -1;
@@ -8345,7 +8345,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
static void initiate_new_session(struct lro *lro, u8 *l2h,
struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
lro->l2h = l2h;
lro->iph = ip;
lro->tcph = tcp;
@@ -8375,7 +8375,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
struct tcphdr *tcp = lro->tcph;
__sum16 nchk;
struct stat_block *statinfo = sp->mac_control.stats_info;
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
/* Update L3 header */
ip->tot_len = htons(lro->total_len);
@@ -8403,7 +8403,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
static void aggregate_new_rx(struct lro *lro, struct iphdr *ip,
struct tcphdr *tcp, u32 l4_pyld)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
lro->total_len += l4_pyld;
lro->frags_len += l4_pyld;
lro->tcp_next_seq += l4_pyld;
@@ -8427,7 +8427,7 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
{
u8 *ptr;
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
if (!tcp_pyld_len) {
/* Runt frame or a pure ack */
@@ -8509,7 +8509,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) {
DBG_PRINT(INFO_DBG, "%s:Out of order. expected "
- "0x%x, actual 0x%x\n", __FUNCTION__,
+ "0x%x, actual 0x%x\n", __func__,
(*lro)->tcp_next_seq,
ntohl(tcph->seq));
@@ -8549,7 +8549,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
if (ret == 0) { /* sessions exceeded */
DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n",
- __FUNCTION__);
+ __func__);
*lro = NULL;
return ret;
}
@@ -8571,7 +8571,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
break;
default:
DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n",
- __FUNCTION__);
+ __func__);
break;
}
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 0d47d6f..06ea71c 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -445,10 +445,17 @@ static void efx_fini_channels(struct efx_nic *efx)
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
+ int rc;
EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);
+ rc = falcon_flush_queues(efx);
+ if (rc)
+ EFX_ERR(efx, "failed to flush queues\n");
+ else
+ EFX_LOG(efx, "successfully flushed all queues\n");
+
efx_for_each_channel(channel, efx) {
EFX_LOG(channel->efx, "shut down chan %d\n", channel->channel);
@@ -456,13 +463,6 @@ static void efx_fini_channels(struct efx_nic *efx)
efx_fini_rx_queue(rx_queue);
efx_for_each_channel_tx_queue(tx_queue, channel)
efx_fini_tx_queue(tx_queue);
- }
-
- /* Do the event queues last so that we can handle flush events
- * for all DMA queues. */
- efx_for_each_channel(channel, efx) {
- EFX_LOG(channel->efx, "shut down evq %d\n", channel->channel);
-
efx_fini_eventq(channel);
}
}
@@ -780,7 +780,7 @@ static int efx_init_io(struct efx_nic *efx)
return 0;
fail4:
- release_mem_region(efx->membase_phys, efx->type->mem_map_size);
+ pci_release_region(efx->pci_dev, efx->type->mem_bar);
fail3:
efx->membase_phys = 0;
fail2:
@@ -1092,7 +1092,6 @@ static void efx_stop_all(struct efx_nic *efx)
/* Isolate the MAC from the TX and RX engines, so that queue
* flushes will complete in a timely fashion. */
- falcon_deconfigure_mac_wrapper(efx);
falcon_drain_tx_fifo(efx);
/* Stop the kernel transmit interface late, so the watchdog
@@ -1750,7 +1749,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
.check_hw = efx_port_dummy_op_int,
.fini = efx_port_dummy_op_void,
.clear_interrupt = efx_port_dummy_op_void,
- .reset_xaui = efx_port_dummy_op_void,
};
static struct efx_board efx_dummy_board_info = {
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index e0c0b23..31ed1f4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -108,10 +108,10 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
/* Max number of internal errors. After this resets will not be performed */
#define FALCON_MAX_INT_ERRORS 4
-/* Maximum period that we wait for flush events. If the flush event
- * doesn't arrive in this period of time then we check if the queue
- * was disabled anyway. */
-#define FALCON_FLUSH_TIMEOUT 10 /* 10ms */
+/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
+ */
+#define FALCON_FLUSH_INTERVAL 10
+#define FALCON_FLUSH_POLL_COUNT 100
/**************************************************************************
*
@@ -452,6 +452,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
efx_oword_t tx_desc_ptr;
struct efx_nic *efx = tx_queue->efx;
+ tx_queue->flushed = false;
+
/* Pin TX descriptor ring */
falcon_init_special_buffer(efx, &tx_queue->txd);
@@ -492,60 +494,16 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
}
}
-static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
+static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- struct efx_channel *channel = &efx->channel[0];
efx_oword_t tx_flush_descq;
- unsigned int read_ptr, i;
/* Post a flush command */
EFX_POPULATE_OWORD_2(tx_flush_descq,
TX_FLUSH_DESCQ_CMD, 1,
TX_FLUSH_DESCQ, tx_queue->queue);
falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER);
- msleep(FALCON_FLUSH_TIMEOUT);
-
- if (EFX_WORKAROUND_7803(efx))
- return 0;
-
- /* Look for a flush completed event */
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
- efx_qword_t *event = falcon_event(channel, read_ptr);
- int ev_code, ev_sub_code, ev_queue;
- if (!falcon_event_present(event))
- break;
-
- ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_TX_DESCQ_ID);
- if ((ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) &&
- (ev_queue == tx_queue->queue)) {
- EFX_LOG(efx, "tx queue %d flush command succesful\n",
- tx_queue->queue);
- return 0;
- }
-
- read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
-
- if (EFX_WORKAROUND_11557(efx)) {
- efx_oword_t reg;
- bool enabled;
-
- falcon_read_table(efx, ®, efx->type->txd_ptr_tbl_base,
- tx_queue->queue);
- enabled = EFX_OWORD_FIELD(reg, TX_DESCQ_EN);
- if (!enabled) {
- EFX_LOG(efx, "tx queue %d disabled without a "
- "flush event seen\n", tx_queue->queue);
- return 0;
- }
- }
-
- EFX_ERR(efx, "tx queue %d flush command timed out\n", tx_queue->queue);
- return -ETIMEDOUT;
}
void falcon_fini_tx(struct efx_tx_queue *tx_queue)
@@ -553,9 +511,8 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue)
struct efx_nic *efx = tx_queue->efx;
efx_oword_t tx_desc_ptr;
- /* Stop the hardware using the queue */
- if (falcon_flush_tx_queue(tx_queue))
- EFX_ERR(efx, "failed to flush tx queue %d\n", tx_queue->queue);
+ /* The queue should have been flushed */
+ WARN_ON(!tx_queue->flushed);
/* Remove TX descriptor ring from card */
EFX_ZERO_OWORD(tx_desc_ptr);
@@ -643,6 +600,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
rx_queue->queue, rx_queue->rxd.index,
rx_queue->rxd.index + rx_queue->rxd.entries - 1);
+ rx_queue->flushed = false;
+
/* Pin RX descriptor ring */
falcon_init_special_buffer(efx, &rx_queue->rxd);
@@ -663,11 +622,9 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
rx_queue->queue);
}
-static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
+static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- struct efx_channel *channel = &efx->channel[0];
- unsigned int read_ptr, i;
efx_oword_t rx_flush_descq;
/* Post a flush command */
@@ -675,76 +632,15 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
RX_FLUSH_DESCQ_CMD, 1,
RX_FLUSH_DESCQ, rx_queue->queue);
falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER);
- msleep(FALCON_FLUSH_TIMEOUT);
-
- if (EFX_WORKAROUND_7803(efx))
- return 0;
-
- /* Look for a flush completed event */
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
- efx_qword_t *event = falcon_event(channel, read_ptr);
- int ev_code, ev_sub_code, ev_queue;
- bool ev_failed;
- if (!falcon_event_present(event))
- break;
-
- ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_DESCQ_ID);
- ev_failed = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_FLUSH_FAIL);
-
- if ((ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) &&
- (ev_queue == rx_queue->queue)) {
- if (ev_failed) {
- EFX_INFO(efx, "rx queue %d flush command "
- "failed\n", rx_queue->queue);
- return -EAGAIN;
- } else {
- EFX_LOG(efx, "rx queue %d flush command "
- "succesful\n", rx_queue->queue);
- return 0;
- }
- }
-
- read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
-
- if (EFX_WORKAROUND_11557(efx)) {
- efx_oword_t reg;
- bool enabled;
-
- falcon_read_table(efx, ®, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
- enabled = EFX_OWORD_FIELD(reg, RX_DESCQ_EN);
- if (!enabled) {
- EFX_LOG(efx, "rx queue %d disabled without a "
- "flush event seen\n", rx_queue->queue);
- return 0;
- }
- }
-
- EFX_ERR(efx, "rx queue %d flush command timed out\n", rx_queue->queue);
- return -ETIMEDOUT;
}
void falcon_fini_rx(struct efx_rx_queue *rx_queue)
{
efx_oword_t rx_desc_ptr;
struct efx_nic *efx = rx_queue->efx;
- int i, rc;
- /* Try and flush the rx queue. This may need to be repeated */
- for (i = 0; i < 5; i++) {
- rc = falcon_flush_rx_queue(rx_queue);
- if (rc == -EAGAIN)
- continue;
- break;
- }
- if (rc) {
- EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue);
- efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
- }
+ /* The queue should already have been flushed */
+ WARN_ON(!rx_queue->flushed);
/* Remove RX descriptor ring from card */
EFX_ZERO_OWORD(rx_desc_ptr);
@@ -1007,7 +903,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
is_phy_event = true;
if ((falcon_rev(efx) >= FALCON_REV_B0) &&
- EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0))
+ EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0))
is_phy_event = true;
if (is_phy_event) {
@@ -1255,6 +1151,121 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
falcon_generate_event(channel, &test_event);
}
+/**************************************************************************
+ *
+ * Flush handling
+ *
+ **************************************************************************/
+
+
+static void falcon_poll_flush_events(struct efx_nic *efx)
+{
+ struct efx_channel *channel = &efx->channel[0];
+ struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue *rx_queue;
+ unsigned int read_ptr, i;
+
+ read_ptr = channel->eventq_read_ptr;
+ for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+ efx_qword_t *event = falcon_event(channel, read_ptr);
+ int ev_code, ev_sub_code, ev_queue;
+ bool ev_failed;
+ if (!falcon_event_present(event))
+ break;
+
+ ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
+ if (ev_code != DRIVER_EV_DECODE)
+ continue;
+
+ ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
+ switch (ev_sub_code) {
+ case TX_DESCQ_FLS_DONE_EV_DECODE:
+ ev_queue = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_TX_DESCQ_ID);
+ if (ev_queue < EFX_TX_QUEUE_COUNT) {
+ tx_queue = efx->tx_queue + ev_queue;
+ tx_queue->flushed = true;
+ }
+ break;
+ case RX_DESCQ_FLS_DONE_EV_DECODE:
+ ev_queue = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_RX_DESCQ_ID);
+ ev_failed = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_RX_FLUSH_FAIL);
+ if (ev_queue < efx->n_rx_queues) {
+ rx_queue = efx->rx_queue + ev_queue;
+
+ /* retry the rx flush */
+ if (ev_failed)
+ falcon_flush_rx_queue(rx_queue);
+ else
+ rx_queue->flushed = true;
+ }
+ break;
+ }
+
+ read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
+ }
+}
+
+/* Handle tx and rx flushes at the same time, since they run in
+ * parallel in the hardware and there's no reason for us to
+ * serialise them */
+int falcon_flush_queues(struct efx_nic *efx)
+{
+ struct efx_rx_queue *rx_queue;
+ struct efx_tx_queue *tx_queue;
+ int i;
+ bool outstanding;
+
+ /* Issue flush requests */
+ efx_for_each_tx_queue(tx_queue, efx) {
+ tx_queue->flushed = false;
+ falcon_flush_tx_queue(tx_queue);
+ }
+ efx_for_each_rx_queue(rx_queue, efx) {
+ rx_queue->flushed = false;
+ falcon_flush_rx_queue(rx_queue);
+ }
+
+ /* Poll the evq looking for flush completions. Since we're not pushing
+ * any more rx or tx descriptors at this point, we're in no danger of
+ * overflowing the evq whilst we wait */
+ for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) {
+ msleep(FALCON_FLUSH_INTERVAL);
+ falcon_poll_flush_events(efx);
+
+ /* Check if every queue has been succesfully flushed */
+ outstanding = false;
+ efx_for_each_tx_queue(tx_queue, efx)
+ outstanding |= !tx_queue->flushed;
+ efx_for_each_rx_queue(rx_queue, efx)
+ outstanding |= !rx_queue->flushed;
+ if (!outstanding)
+ return 0;
+ }
+
+ /* Mark the queues as all flushed. We're going to return failure
+ * leading to a reset, or fake up success anyway. "flushed" now
+ * indicates that we tried to flush. */
+ efx_for_each_tx_queue(tx_queue, efx) {
+ if (!tx_queue->flushed)
+ EFX_ERR(efx, "tx queue %d flush command timed out\n",
+ tx_queue->queue);
+ tx_queue->flushed = true;
+ }
+ efx_for_each_rx_queue(rx_queue, efx) {
+ if (!rx_queue->flushed)
+ EFX_ERR(efx, "rx queue %d flush command timed out\n",
+ rx_queue->queue);
+ rx_queue->flushed = true;
+ }
+
+ if (EFX_WORKAROUND_7803(efx))
+ return 0;
+
+ return -ETIMEDOUT;
+}
/**************************************************************************
*
@@ -1363,10 +1374,11 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg));
}
- /* Disable DMA bus mastering on both devices */
+ /* Disable both devices */
pci_disable_device(efx->pci_dev);
if (FALCON_IS_DUAL_FUNC(efx))
pci_disable_device(nic_data->pci_dev2);
+ falcon_disable_interrupts(efx);
if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
@@ -1593,7 +1605,7 @@ void falcon_fini_interrupt(struct efx_nic *efx)
**************************************************************************
*/
-#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
+#define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t))
/* Wait for SPI command completion */
static int falcon_spi_wait(struct efx_nic *efx)
@@ -1942,8 +1954,10 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
/* Wait for transfer to complete */
for (i = 0; i < 400; i++) {
- if (*(volatile u32 *)dma_done == FALCON_STATS_DONE)
+ if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) {
+ rmb(); /* Ensure the stats are valid. */
return 0;
+ }
udelay(10);
}
@@ -2758,6 +2772,8 @@ int falcon_probe_nic(struct efx_nic *efx)
/* Allocate storage for hardware specific data */
nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
+ if (!nic_data)
+ return -ENOMEM;
efx->nic_data = nic_data;
/* Determine number of ports etc. */
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 30d61e4..be025ba 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -86,6 +86,7 @@ extern void falcon_fini_interrupt(struct efx_nic *efx);
extern int falcon_probe_nic(struct efx_nic *efx);
extern int falcon_probe_resources(struct efx_nic *efx);
extern int falcon_init_nic(struct efx_nic *efx);
+extern int falcon_flush_queues(struct efx_nic *efx);
extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
extern void falcon_remove_resources(struct efx_nic *efx);
extern void falcon_remove_nic(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index e319fd6..5d584b0 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -117,7 +117,6 @@
#define SF_PRST_WIDTH 1
#define EE_PRST_LBN 8
#define EE_PRST_WIDTH 1
-/* See pic_mode_t for decoding of this field */
/* These bit definitions are extrapolated from the list of numerical
* values for STRAP_PINS.
*/
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h
index 6670cdf..c16da31 100644
--- a/drivers/net/sfc/falcon_io.h
+++ b/drivers/net/sfc/falcon_io.h
@@ -13,7 +13,6 @@
#include <linux/io.h>
#include <linux/spinlock.h>
-#include "net_driver.h"
/**************************************************************************
*
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 0d9f68f..d401231 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -78,79 +78,7 @@ static void falcon_setup_xaui(struct efx_nic *efx)
falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
}
-static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
-{
- efx_oword_t reg;
-
- EFX_ZERO_OWORD(reg);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-}
-
-static int _falcon_reset_xaui_a(struct efx_nic *efx)
-{
- efx_oword_t reg;
-
- falcon_hold_xaui_in_rst(efx);
- falcon_read(efx, ®, XX_PWR_RST_REG);
-
- /* Follow the RAMBUS XAUI data reset sequencing
- * Channels A and B first: power down, reset PLL, reset, clear
- */
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- /* Channels C and D: power down, reset PLL, reset, clear */
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- /* Setup XAUI */
- falcon_setup_xaui(efx);
- udelay(10);
-
- /* Take XGXS out of reset */
- EFX_ZERO_OWORD(reg);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- return 0;
-}
-
-static int _falcon_reset_xaui_b(struct efx_nic *efx)
+int falcon_reset_xaui(struct efx_nic *efx)
{
efx_oword_t reg;
int count;
@@ -171,20 +99,6 @@ static int _falcon_reset_xaui_b(struct efx_nic *efx)
return -ETIMEDOUT;
}
-int falcon_reset_xaui(struct efx_nic *efx)
-{
- int rc;
-
- if (EFX_WORKAROUND_9388(efx)) {
- falcon_hold_xaui_in_rst(efx);
- efx->phy_op->reset_xaui(efx);
- rc = _falcon_reset_xaui_a(efx);
- } else {
- rc = _falcon_reset_xaui_b(efx);
- }
- return rc;
-}
-
static bool falcon_xgmii_status(struct efx_nic *efx)
{
efx_oword_t reg;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 567df00..cdb11fa 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -160,6 +160,7 @@ struct efx_tx_buffer {
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
+ * @flushed: Used when handling queue flushing
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
* @stopped: Stopped count.
@@ -192,6 +193,7 @@ struct efx_tx_queue {
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
struct efx_special_buffer txd;
+ bool flushed;
/* Members used mainly on the completion path */
unsigned int read_count ____cacheline_aligned_in_smp;
@@ -260,6 +262,7 @@ struct efx_rx_buffer {
* the remaining space in the allocation.
* @buf_dma_addr: Page's DMA address.
* @buf_data: Page's host address.
+ * @flushed: Use when handling queue flushing
*/
struct efx_rx_queue {
struct efx_nic *efx;
@@ -285,6 +288,7 @@ struct efx_rx_queue {
struct page *buf_page;
dma_addr_t buf_dma_addr;
char *buf_data;
+ bool flushed;
};
/**
@@ -470,7 +474,7 @@ enum nic_state {
* This is the equivalent of NET_IP_ALIGN [which controls the alignment
* of the skb->head for hardware DMA].
*/
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
#define EFX_PAGE_IP_ALIGN 0
#else
#define EFX_PAGE_IP_ALIGN NET_IP_ALIGN
@@ -503,7 +507,6 @@ enum efx_fc_type {
* @clear_interrupt: Clear down interrupt
* @blink: Blink LEDs
* @check_hw: Check hardware
- * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset)
* @mmds: MMD presence mask
* @loopbacks: Supported loopback modes mask
*/
@@ -513,7 +516,6 @@ struct efx_phy_operations {
void (*reconfigure) (struct efx_nic *efx);
void (*clear_interrupt) (struct efx_nic *efx);
int (*check_hw) (struct efx_nic *efx);
- void (*reset_xaui) (struct efx_nic *efx);
int (*test) (struct efx_nic *efx);
int mmds;
unsigned loopbacks;
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index b7005da..fe4e3fd 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -129,18 +129,6 @@ static int sfe4001_poweron(struct efx_nic *efx)
unsigned int i, j;
int rc;
u8 out;
- efx_oword_t reg;
-
- /* Ensure that XGXS and XAUI SerDes are held in reset */
- EFX_POPULATE_OWORD_7(reg, XX_PWRDNA_EN, 1,
- XX_PWRDNB_EN, 1,
- XX_RSTPLLAB_EN, 1,
- XX_RESETA_EN, 1,
- XX_RESETB_EN, 1,
- XX_RSTXGXSRX_EN, 1,
- XX_RSTXGXSTX_EN, 1);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
/* Clear any previous over-temperature alert */
rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 8412dbe..d507c93 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -146,8 +146,6 @@ static int tenxpress_phy_check(struct efx_nic *efx)
return 0;
}
-static void tenxpress_reset_xaui(struct efx_nic *efx);
-
static int tenxpress_init(struct efx_nic *efx)
{
int rc, reg;
@@ -216,7 +214,10 @@ static int tenxpress_special_reset(struct efx_nic *efx)
{
int rc, reg;
- EFX_TRACE(efx, "%s\n", __func__);
+ /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
+ * a special software reset can glitch the XGMAC sufficiently for stats
+ * requests to fail. Since we don't ofen special_reset, just lock. */
+ spin_lock(&efx->stats_lock);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -225,20 +226,22 @@ static int tenxpress_special_reset(struct efx_nic *efx)
mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
PMA_PMD_EXT_CTRL_REG, reg);
- msleep(200);
+ mdelay(200);
/* Wait for the blocks to come out of reset */
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- return rc;
+ goto unlock;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- return rc;
+ goto unlock;
- return 0;
+unlock:
+ spin_unlock(&efx->stats_lock);
+ return rc;
}
static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp)
@@ -374,8 +377,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
struct tenxpress_phy_data *phy_data = efx->phy_data;
bool link_ok;
- link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL &&
- tenxpress_link_ok(efx, true));
+ link_ok = tenxpress_link_ok(efx, true);
if (link_ok != efx->link_up)
falcon_xmac_sim_phy_event(efx);
@@ -428,54 +430,6 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
PMA_PMD_LED_OVERR_REG, reg);
}
-static void tenxpress_reset_xaui(struct efx_nic *efx)
-{
- int phy = efx->mii.phy_id;
- int clk_ctrl, test_select, soft_rst2;
-
- /* Real work is done on clock_ctrl other resets are thought to be
- * optional but make the reset more reliable
- */
-
- /* Read */
- clk_ctrl = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG);
- test_select = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG);
- soft_rst2 = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG);
-
- /* Put in reset */
- test_select &= ~(1 << CLK312_EN_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG, test_select);
-
- soft_rst2 &= ~((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG, soft_rst2);
-
- clk_ctrl &= ~(1 << PLL312_RST_N_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG, clk_ctrl);
- udelay(10);
-
- /* Remove reset */
- clk_ctrl |= (1 << PLL312_RST_N_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG, clk_ctrl);
- udelay(10);
-
- soft_rst2 |= ((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG, soft_rst2);
- udelay(10);
-
- test_select |= (1 << CLK312_EN_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG, test_select);
- udelay(10);
-}
-
static int tenxpress_phy_test(struct efx_nic *efx)
{
/* BIST is automatically run after a special software reset */
@@ -488,7 +442,6 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
.check_hw = tenxpress_phy_check_hw,
.fini = tenxpress_phy_fini,
.clear_interrupt = tenxpress_phy_clear_interrupt,
- .reset_xaui = tenxpress_reset_xaui,
.test = tenxpress_phy_test,
.mmds = TENXPRESS_REQUIRED_DEVS,
.loopbacks = TENXPRESS_LOOPBACKS,
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index cdee7c2..da3e9ff 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -516,7 +516,7 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
/* Number of bytes inserted at the start of a TSO header buffer,
* similar to NET_IP_ALIGN.
*/
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
#define TSOH_OFFSET 0
#else
#define TSOH_OFFSET NET_IP_ALIGN
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index a824f59..fa7b49d 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -24,8 +24,6 @@
#define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* XGXS and XAUI reset sequencing in SW */
-#define EFX_WORKAROUND_9388 EFX_WORKAROUND_ALWAYS
/* Low rate CRC errors require XAUI reset */
#define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index f6edecc..276151d 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -165,7 +165,6 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
.check_hw = xfp_phy_check_hw,
.fini = xfp_phy_fini,
.clear_interrupt = xfp_phy_clear_interrupt,
- .reset_xaui = efx_port_dummy_op_void,
.mmds = XFP_REQUIRED_DEVS,
.loopbacks = XFP_LOOPBACKS,
};
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index c587162..02cc064 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -183,7 +183,7 @@ static void smc911x_reset(struct net_device *dev)
unsigned int reg, timeout=0, resets=1;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* Take out of PM setting first */
if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) {
@@ -272,7 +272,7 @@ static void smc911x_enable(struct net_device *dev)
unsigned mask, cfg, cr;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
SMC_SET_MAC_ADDR(lp, dev->dev_addr);
@@ -329,7 +329,7 @@ static void smc911x_shutdown(struct net_device *dev)
unsigned cr;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __func__);
/* Disable IRQ's */
SMC_SET_INT_EN(lp, 0);
@@ -348,7 +348,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev)
struct smc911x_local *lp = netdev_priv(dev);
unsigned int fifo_count, timeout, reg;
- DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __func__);
fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF;
if (fifo_count <= 4) {
/* Manually dump the packet data */
@@ -382,7 +382,7 @@ static inline void smc911x_rcv(struct net_device *dev)
unsigned char *data;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
status = SMC_GET_RX_STS_FIFO(lp);
DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n",
dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff);
@@ -460,7 +460,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
unsigned char *buf;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__);
BUG_ON(lp->pending_tx_skb == NULL);
skb = lp->pending_tx_skb;
@@ -524,7 +524,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
BUG_ON(lp->pending_tx_skb != NULL);
@@ -596,7 +596,7 @@ static void smc911x_tx(struct net_device *dev)
unsigned int tx_status;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
/* Collect the TX status */
while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
@@ -647,7 +647,7 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
SMC_GET_MII(lp, phyreg, phyaddr, phydata);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
return phydata;
}
@@ -661,7 +661,7 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
struct smc911x_local *lp = netdev_priv(dev);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SET_MII(lp, phyreg, phyaddr, phydata);
}
@@ -676,7 +676,7 @@ static void smc911x_phy_detect(struct net_device *dev)
int phyaddr;
unsigned int cfg, id1, id2;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
lp->phy_type = 0;
@@ -746,7 +746,7 @@ static int smc911x_phy_fixed(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int bmcr;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* Enter Link Disable state */
SMC_GET_PHY_BMCR(lp, phyaddr, bmcr);
@@ -793,7 +793,7 @@ static int smc911x_phy_reset(struct net_device *dev, int phy)
unsigned long flags;
unsigned int reg;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
reg = SMC_GET_PMT_CTRL(lp);
@@ -852,7 +852,7 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
int phyaddr = lp->mii.phy_id;
unsigned int bmcr, cr;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
/* duplex state has changed */
@@ -892,7 +892,7 @@ static void smc911x_phy_configure(struct work_struct *work)
int status;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
/*
* We should not be called if phy_type is zero.
@@ -985,7 +985,7 @@ static void smc911x_phy_interrupt(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int status;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
if (lp->phy_type == 0)
return;
@@ -1013,7 +1013,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
unsigned int rx_overrun=0, cr, pkts;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
@@ -1174,8 +1174,6 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
spin_unlock_irqrestore(&lp->lock, flags);
- DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
-
return IRQ_HANDLED;
}
@@ -1188,7 +1186,7 @@ smc911x_tx_dma_irq(int dma, void *data)
struct sk_buff *skb = lp->current_tx_skb;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name);
/* Clear the DMA interrupt sources */
@@ -1224,7 +1222,7 @@ smc911x_rx_dma_irq(int dma, void *data)
unsigned long flags;
unsigned int pkts;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
/* Clear the DMA interrupt sources */
SMC_DMA_ACK_IRQ(dev, dma);
@@ -1272,7 +1270,7 @@ static void smc911x_timeout(struct net_device *dev)
int status, mask;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
status = SMC_GET_INT(lp);
@@ -1310,7 +1308,7 @@ static void smc911x_set_multicast_list(struct net_device *dev)
unsigned int mcr, update_multicast = 0;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
SMC_GET_MAC_CR(lp, mcr);
@@ -1412,7 +1410,7 @@ smc911x_open(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -1420,7 +1418,7 @@ smc911x_open(struct net_device *dev)
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
- PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+ PRINTK("%s: no valid ethernet hw addr\n", __func__);
return -EINVAL;
}
@@ -1449,7 +1447,7 @@ static int smc911x_close(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
@@ -1483,7 +1481,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
int ret, status;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
cmd->maxtxpkt = 1;
cmd->maxrxpkt = 1;
@@ -1621,7 +1619,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) {
if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) {
PRINTK("%s: %s timeout waiting for EEPROM to respond\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
return -EFAULT;
}
mdelay(1);
@@ -1629,7 +1627,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
}
if (timeout == 0) {
PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
return -ETIMEDOUT;
}
return 0;
@@ -1742,7 +1740,7 @@ static int __init smc911x_findirq(struct net_device *dev)
int timeout = 20;
unsigned long cookie;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
cookie = probe_irq_on();
@@ -1808,7 +1806,7 @@ static int __init smc911x_probe(struct net_device *dev)
const char *version_string;
unsigned long irq_flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* First, see if the endian word is recognized */
val = SMC_GET_BYTE_TEST(lp);
@@ -2058,7 +2056,7 @@ static int smc911x_drv_probe(struct platform_device *pdev)
unsigned int *addr;
int ret;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
@@ -2129,7 +2127,7 @@ static int smc911x_drv_remove(struct platform_device *pdev)
struct smc911x_local *lp = netdev_priv(ndev);
struct resource *res;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
@@ -2159,7 +2157,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
struct net_device *ndev = platform_get_drvdata(dev);
struct smc911x_local *lp = netdev_priv(ndev);
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
if (ndev) {
if (netif_running(ndev)) {
netif_device_detach(ndev);
@@ -2177,7 +2175,7 @@ static int smc911x_drv_resume(struct platform_device *dev)
{
struct net_device *ndev = platform_get_drvdata(dev);
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
if (ndev) {
struct smc911x_local *lp = netdev_priv(ndev);
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 24768c1..aa69937 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -270,7 +270,7 @@ static void smc_reset(struct net_device *dev)
unsigned int ctl, cfg;
struct sk_buff *pending_skb;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/* Disable all interrupts, block TX tasklet */
spin_lock_irq(&lp->lock);
@@ -363,7 +363,7 @@ static void smc_enable(struct net_device *dev)
void __iomem *ioaddr = lp->base;
int mask;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/* see the header file for options in TCR/RCR DEFAULT */
SMC_SELECT_BANK(lp, 0);
@@ -397,7 +397,7 @@ static void smc_shutdown(struct net_device *dev)
void __iomem *ioaddr = lp->base;
struct sk_buff *pending_skb;
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
/* no more interrupts for me */
spin_lock_irq(&lp->lock);
@@ -430,7 +430,7 @@ static inline void smc_rcv(struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int packet_number, status, packet_len;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
packet_number = SMC_GET_RXFIFO(lp);
if (unlikely(packet_number & RXFIFO_REMPTY)) {
@@ -577,7 +577,7 @@ static void smc_hardware_send_pkt(unsigned long data)
unsigned int packet_no, len;
unsigned char *buf;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
if (!smc_special_trylock(&lp->lock)) {
netif_stop_queue(dev);
@@ -662,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int numPages, poll_count, status;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
BUG_ON(lp->pending_tx_skb != NULL);
@@ -734,7 +734,7 @@ static void smc_tx(struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int saved_packet, packet_no, tx_status, pkt_len;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
/* If the TX FIFO is empty then nothing to do */
packet_no = SMC_GET_TXFIFO(lp);
@@ -856,7 +856,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SELECT_BANK(lp, 2);
return phydata;
@@ -883,7 +883,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SELECT_BANK(lp, 2);
}
@@ -896,7 +896,7 @@ static void smc_phy_detect(struct net_device *dev)
struct smc_local *lp = netdev_priv(dev);
int phyaddr;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
lp->phy_type = 0;
@@ -935,7 +935,7 @@ static int smc_phy_fixed(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int bmcr, cfg1;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
/* Enter Link Disable state */
cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
@@ -1168,7 +1168,7 @@ static void smc_phy_interrupt(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int phy18;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
if (lp->phy_type == 0)
return;
@@ -1236,7 +1236,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
int status, mask, timeout, card_stats;
int saved_pointer;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
spin_lock(&lp->lock);
@@ -1358,7 +1358,7 @@ static void smc_timeout(struct net_device *dev)
void __iomem *ioaddr = lp->base;
int status, mask, eph_st, meminfo, fifo;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
spin_lock_irq(&lp->lock);
status = SMC_GET_INT(lp);
@@ -1402,7 +1402,7 @@ static void smc_set_multicast_list(struct net_device *dev)
unsigned char multicast_table[8];
int update_multicast = 0;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
if (dev->flags & IFF_PROMISC) {
DBG(2, "%s: RCR_PRMS\n", dev->name);
@@ -1505,7 +1505,7 @@ smc_open(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -1513,7 +1513,7 @@ smc_open(struct net_device *dev)
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
- PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+ PRINTK("%s: no valid ethernet hw addr\n", __func__);
return -EINVAL;
}
@@ -1557,7 +1557,7 @@ static int smc_close(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
@@ -1700,7 +1700,7 @@ static int __init smc_findirq(struct smc_local *lp)
int timeout = 20;
unsigned long cookie;
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
cookie = probe_irq_on();
@@ -1778,7 +1778,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
const char *version_string;
DECLARE_MAC_BUF(mac);
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
/* First, see if the high byte is 0x33 */
val = SMC_CURRENT_BANK(lp);
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 7d5561b..f860ea1 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -409,6 +409,7 @@ static int change_mtu(struct net_device *dev, int new_mtu);
static int eeprom_read(void __iomem *ioaddr, int location);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int mdio_wait_link(struct net_device *dev, int wait);
static int netdev_open(struct net_device *dev);
static void check_duplex(struct net_device *dev);
static void netdev_timer(unsigned long data);
@@ -785,6 +786,24 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
return;
}
+static int mdio_wait_link(struct net_device *dev, int wait)
+{
+ int bmsr;
+ int phy_id;
+ struct netdev_private *np;
+
+ np = netdev_priv(dev);
+ phy_id = np->phys[0];
+
+ do {
+ bmsr = mdio_read(dev, phy_id, MII_BMSR);
+ if (bmsr & 0x0004)
+ return 0;
+ mdelay(1);
+ } while (--wait > 0);
+ return -1;
+}
+
static int netdev_open(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
@@ -1393,41 +1412,51 @@ static void netdev_error(struct net_device *dev, int intr_status)
int speed;
if (intr_status & LinkChange) {
- if (np->an_enable) {
- mii_advertise = mdio_read (dev, np->phys[0], MII_ADVERTISE);
- mii_lpa= mdio_read (dev, np->phys[0], MII_LPA);
- mii_advertise &= mii_lpa;
- printk (KERN_INFO "%s: Link changed: ", dev->name);
- if (mii_advertise & ADVERTISE_100FULL) {
- np->speed = 100;
- printk ("100Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_100HALF) {
- np->speed = 100;
- printk ("100Mbps, half duplex\n");
- } else if (mii_advertise & ADVERTISE_10FULL) {
- np->speed = 10;
- printk ("10Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_10HALF) {
- np->speed = 10;
- printk ("10Mbps, half duplex\n");
- } else
- printk ("\n");
+ if (mdio_wait_link(dev, 10) == 0) {
+ printk(KERN_INFO "%s: Link up\n", dev->name);
+ if (np->an_enable) {
+ mii_advertise = mdio_read(dev, np->phys[0],
+ MII_ADVERTISE);
+ mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
+ mii_advertise &= mii_lpa;
+ printk(KERN_INFO "%s: Link changed: ",
+ dev->name);
+ if (mii_advertise & ADVERTISE_100FULL) {
+ np->speed = 100;
+ printk("100Mbps, full duplex\n");
+ } else if (mii_advertise & ADVERTISE_100HALF) {
+ np->speed = 100;
+ printk("100Mbps, half duplex\n");
+ } else if (mii_advertise & ADVERTISE_10FULL) {
+ np->speed = 10;
+ printk("10Mbps, full duplex\n");
+ } else if (mii_advertise & ADVERTISE_10HALF) {
+ np->speed = 10;
+ printk("10Mbps, half duplex\n");
+ } else
+ printk("\n");
+ } else {
+ mii_ctl = mdio_read(dev, np->phys[0], MII_BMCR);
+ speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
+ np->speed = speed;
+ printk(KERN_INFO "%s: Link changed: %dMbps ,",
+ dev->name, speed);
+ printk("%s duplex.\n",
+ (mii_ctl & BMCR_FULLDPLX) ?
+ "full" : "half");
+ }
+ check_duplex(dev);
+ if (np->flowctrl && np->mii_if.full_duplex) {
+ iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
+ ioaddr + MulticastFilter1+2);
+ iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
+ ioaddr + MACCtrl0);
+ }
+ netif_carrier_on(dev);
} else {
- mii_ctl = mdio_read (dev, np->phys[0], MII_BMCR);
- speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
- np->speed = speed;
- printk (KERN_INFO "%s: Link changed: %dMbps ,",
- dev->name, speed);
- printk ("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
- "full" : "half");
- }
- check_duplex (dev);
- if (np->flowctrl && np->mii_if.full_duplex) {
- iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
- ioaddr + MulticastFilter1+2);
- iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
- ioaddr + MACCtrl0);
+ printk(KERN_INFO "%s: Link down\n", dev->name);
+ netif_carrier_off(dev);
}
}
if (intr_status & StatsMax) {
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index 7db48f1..efaf84d 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -539,22 +539,22 @@ struct txd_desc {
#define ERR(fmt, args...) printk(KERN_ERR fmt, ## args)
#define DBG2(fmt, args...) \
- printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+ printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args)
#define BDX_ASSERT(x) BUG_ON(x)
#ifdef DEBUG
#define ENTER do { \
- printk(KERN_ERR "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); \
+ printk(KERN_ERR "%s:%-5d: ENTER\n", __func__, __LINE__); \
} while (0)
#define RET(args...) do { \
- printk(KERN_ERR "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__); \
+ printk(KERN_ERR "%s:%-5d: RETURN\n", __func__, __LINE__); \
return args; } while (0)
#define DBG(fmt, args...) \
- printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+ printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args)
#else
#define ENTER do { } while (0)
#define RET(args...) return args
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 43fde99..eb1da6f 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -263,7 +263,7 @@ static inline void tsi108_write_tbi(struct tsi108_prv_data *data,
return;
udelay(10);
}
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
}
static int mii_speed(struct mii_if_info *mii)
@@ -1059,7 +1059,7 @@ static void tsi108_stop_ethernet(struct net_device *dev)
return;
udelay(10);
}
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
}
static void tsi108_reset_ether(struct tsi108_prv_data * data)
@@ -1244,7 +1244,7 @@ static void tsi108_init_phy(struct net_device *dev)
udelay(10);
}
if (i == 0)
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
if (data->phy_type == TSI108_PHY_BCM54XX) {
tsi108_write_mii(data, 0x09, 0x0300);
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 8f944e5..c87747b 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -400,7 +400,7 @@ static struct enet_addr_container *get_enet_addr_container(void)
enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL);
if (!enet_addr_cont) {
ugeth_err("%s: No memory for enet_addr_container object.",
- __FUNCTION__);
+ __func__);
return NULL;
}
@@ -427,7 +427,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
if (!(paddr_num < NUM_OF_PADDRS)) {
- ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__);
+ ugeth_warn("%s: Illegal paddr_num.", __func__);
return -EINVAL;
}
@@ -447,7 +447,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
if (!(paddr_num < NUM_OF_PADDRS)) {
- ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+ ugeth_warn("%s: Illagel paddr_num.", __func__);
return -EINVAL;
}
@@ -1441,7 +1441,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
u32 upsmr, maccfg2, tbiBaseAddress;
u16 value;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
ug_info = ugeth->ug_info;
ug_regs = ugeth->ug_regs;
@@ -1504,7 +1504,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
- __FUNCTION__);
+ __func__);
return ret_val;
}
@@ -1744,7 +1744,7 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ ugeth_err("%s: ucc_num out of range.", __func__);
return -EINVAL;
}
@@ -1773,7 +1773,7 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ ugeth_err("%s: ucc_num out of range.", __func__);
return -EINVAL;
}
@@ -2062,7 +2062,7 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth
ugeth_warn
("%s: multicast address added to paddr will have no "
"effect - is this what you wanted?",
- __FUNCTION__);
+ __func__);
ugeth->indAddrRegUsed[paddr_num] = 1; /* mark this paddr as used */
/* store address in our database */
@@ -2278,7 +2278,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
struct phy_device *phydev = ugeth->phydev;
u32 tempval;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
/* Disable the controller */
ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
@@ -2315,7 +2315,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: Bad memory partition value.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2327,7 +2327,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2338,7 +2338,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: Tx BD ring length must be no smaller than 2.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2349,21 +2349,21 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: max_rx_buf_length must be non-zero multiple of 128.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
/* num Tx queues */
if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+ ugeth_err("%s: number of tx queues too large.", __func__);
return -EINVAL;
}
/* num Rx queues */
if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+ ugeth_err("%s: number of rx queues too large.", __func__);
return -EINVAL;
}
@@ -2374,7 +2374,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ugeth_err
("%s: VLAN priority table entry must not be"
" larger than number of Rx queues.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2386,7 +2386,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ugeth_err
("%s: IP priority table entry must not be"
" larger than number of Rx queues.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2394,7 +2394,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (ug_info->cam && !ug_info->ecamptr) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2404,7 +2404,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err("%s: Number of station addresses greater than 1 "
"not allowed in extended parsing mode.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2418,7 +2418,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* Initialize the general fast UCC block. */
if (ucc_fast_init(uf_info, &ugeth->uccf)) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+ ugeth_err("%s: Failed to init uccf.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2448,7 +2448,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
u8 __iomem *endOfRing;
u8 numThreadsRxNumerical, numThreadsTxNumerical;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
uccf = ugeth->uccf;
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
@@ -2474,7 +2474,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
default:
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Bad number of Rx threads value.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2499,7 +2499,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
default:
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Bad number of Tx threads value.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2553,7 +2553,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: IPGIFG initialization parameter too large.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -2571,7 +2571,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Half Duplex initialization parameter too large.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -2626,7 +2626,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for Tx bd rings.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2662,7 +2662,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for Rx bd rings.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2678,7 +2678,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ugeth->tx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Could not allocate tx_skbuff",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2710,7 +2710,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ugeth->rx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Could not allocate rx_skbuff",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2744,7 +2744,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2767,7 +2767,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2797,7 +2797,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2841,7 +2841,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_scheduler.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2892,7 +2892,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_tx_fw_statistics_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2932,7 +2932,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2954,7 +2954,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2978,7 +2978,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_rx_fw_statistics_pram.", __FUNCTION__);
+ " p_rx_fw_statistics_pram.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3001,7 +3001,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_rx_irq_coalescing_tbl.", __FUNCTION__);
+ " p_rx_irq_coalescing_tbl.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3070,7 +3070,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3147,7 +3147,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (!ug_info->extendedFilteringChainPointer) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Null Extended Filtering Chain Pointer.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3161,7 +3161,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_exf_glbl_param.", __FUNCTION__);
+ " p_exf_glbl_param.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3209,7 +3209,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for"
- " p_UccInitEnetParamShadows.", __FUNCTION__);
+ " p_UccInitEnetParamShadows.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3244,7 +3244,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Invalid largest External Lookup Key Size.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3271,7 +3271,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->riscRx, 1)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3287,7 +3287,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->riscTx, 0)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3297,7 +3297,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill Rx bds with buffers.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3309,7 +3309,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3360,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
dev->stats.tx_errors++;
@@ -3386,7 +3386,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 bd_status;
u8 txQ = 0;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
spin_lock_irq(&ugeth->lock);
@@ -3459,7 +3459,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
u8 *bdBuffer;
struct net_device *dev;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
dev = ugeth->dev;
@@ -3481,7 +3481,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
(bd_status & R_ERRORS_FATAL)) {
if (netif_msg_rx_err(ugeth))
ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
- __FUNCTION__, __LINE__, (u32) skb);
+ __func__, __LINE__, (u32) skb);
if (skb)
dev_kfree_skb_any(skb);
@@ -3507,7 +3507,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
skb = get_new_skb(ugeth, bd);
if (!skb) {
if (netif_msg_rx_err(ugeth))
- ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+ ugeth_warn("%s: No Rx Data Buffer", __func__);
dev->stats.rx_dropped++;
break;
}
@@ -3613,7 +3613,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
register u32 tx_mask;
u8 i;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
uccf = ugeth->uccf;
ug_info = ugeth->ug_info;
@@ -3683,13 +3683,13 @@ static int ucc_geth_open(struct net_device *dev)
struct ucc_geth_private *ugeth = netdev_priv(dev);
int err;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
/* Test station address */
if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Multicast address used for station address"
- " - is this what you wanted?", __FUNCTION__);
+ " - is this what you wanted?", __func__);
return -EINVAL;
}
@@ -3772,7 +3772,7 @@ static int ucc_geth_close(struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
napi_disable(&ugeth->napi);
@@ -3840,7 +3840,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
};
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
prop = of_get_property(np, "cell-index", NULL);
if (!prop) {
@@ -3857,7 +3857,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
if (ug_info == NULL) {
if (netif_msg_probe(&debug))
ugeth_err("%s: [%d] Missing additional data!",
- __FUNCTION__, ucc_num);
+ __func__, ucc_num);
return -ENODEV;
}
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 6e42b5a..78001f1 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -92,9 +92,6 @@
#define HSO_NET_TX_TIMEOUT (HZ*10)
-/* Serial port defines and structs. */
-#define HSO_SERIAL_FLAG_RX_SENT 0
-
#define HSO_SERIAL_MAGIC 0x48534f31
/* Number of ttys to handle */
@@ -179,6 +176,12 @@ struct hso_net {
unsigned long flags;
};
+enum rx_ctrl_state{
+ RX_IDLE,
+ RX_SENT,
+ RX_PENDING
+};
+
struct hso_serial {
struct hso_device *parent;
int magic;
@@ -205,7 +208,7 @@ struct hso_serial {
struct usb_endpoint_descriptor *in_endp;
struct usb_endpoint_descriptor *out_endp;
- unsigned long flags;
+ enum rx_ctrl_state rx_state;
u8 rts_state;
u8 dtr_state;
unsigned tx_urb_used:1;
@@ -216,6 +219,15 @@ struct hso_serial {
spinlock_t serial_lock;
int (*write_data) (struct hso_serial *serial);
+ /* Hacks required to get flow control
+ * working on the serial receive buffers
+ * so as not to drop characters on the floor.
+ */
+ int curr_rx_urb_idx;
+ u16 curr_rx_urb_offset;
+ u8 rx_urb_filled[MAX_RX_URBS];
+ struct tasklet_struct unthrottle_tasklet;
+ struct work_struct retry_unthrottle_workqueue;
};
struct hso_device {
@@ -271,7 +283,7 @@ struct hso_device {
static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void ctrl_callback(struct urb *urb);
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
static void hso_kick_transmit(struct hso_serial *serial);
/* Helper functions */
static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
@@ -287,6 +299,8 @@ static int hso_start_net_device(struct hso_device *hso_dev);
static void hso_free_shared_int(struct hso_shared_int *shared_int);
static int hso_stop_net_device(struct hso_device *hso_dev);
static void hso_serial_ref_free(struct kref *ref);
+static void hso_std_serial_read_bulk_callback(struct urb *urb);
+static int hso_mux_serial_read(struct hso_serial *serial);
static void async_get_intf(struct work_struct *data);
static void async_put_intf(struct work_struct *data);
static int hso_put_activity(struct hso_device *hso_dev);
@@ -458,6 +472,17 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
}
static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
+static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
+{
+ int idx;
+
+ for (idx = 0; idx < serial->num_rx_urbs; idx++)
+ if (serial->rx_urb[idx] == urb)
+ return idx;
+ dev_err(serial->parent->dev, "hso_urb_to_index failed\n");
+ return -1;
+}
+
/* converts mux value to a port spec value */
static u32 hso_mux_to_port(int mux)
{
@@ -1039,6 +1064,158 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
return;
}
+static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
+{
+ int result;
+#ifdef CONFIG_HSO_AUTOPM
+ usb_mark_last_busy(urb->dev);
+#endif
+ /* We are done with this URB, resubmit it. Prep the USB to wait for
+ * another frame */
+ usb_fill_bulk_urb(urb, serial->parent->usb,
+ usb_rcvbulkpipe(serial->parent->usb,
+ serial->in_endp->
+ bEndpointAddress & 0x7F),
+ urb->transfer_buffer, serial->rx_data_length,
+ hso_std_serial_read_bulk_callback, serial);
+ /* Give this to the USB subsystem so it can tell us when more data
+ * arrives. */
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n",
+ __func__, result);
+ }
+}
+
+
+
+
+static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
+{
+ int count;
+ struct urb *curr_urb;
+
+ while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) {
+ curr_urb = serial->rx_urb[serial->curr_rx_urb_idx];
+ count = put_rxbuf_data(curr_urb, serial);
+ if (count == -1)
+ return;
+ if (count == 0) {
+ serial->curr_rx_urb_idx++;
+ if (serial->curr_rx_urb_idx >= serial->num_rx_urbs)
+ serial->curr_rx_urb_idx = 0;
+ hso_resubmit_rx_bulk_urb(serial, curr_urb);
+ }
+ }
+}
+
+static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
+{
+ int count = 0;
+ struct urb *urb;
+
+ urb = serial->rx_urb[0];
+ if (serial->open_count > 0) {
+ count = put_rxbuf_data(urb, serial);
+ if (count == -1)
+ return;
+ }
+ /* Re issue a read as long as we receive data. */
+
+ if (count == 0 && ((urb->actual_length != 0) ||
+ (serial->rx_state == RX_PENDING))) {
+ serial->rx_state = RX_SENT;
+ hso_mux_serial_read(serial);
+ } else
+ serial->rx_state = RX_IDLE;
+}
+
+
+/* read callback for Diag and CS port */
+static void hso_std_serial_read_bulk_callback(struct urb *urb)
+{
+ struct hso_serial *serial = urb->context;
+ int status = urb->status;
+
+ /* sanity check */
+ if (!serial) {
+ D1("serial == NULL");
+ return;
+ } else if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+
+ D4("\n--- Got serial_read_bulk callback %02x ---", status);
+ D1("Actual length = %d\n", urb->actual_length);
+ DUMP1(urb->transfer_buffer, urb->actual_length);
+
+ /* Anyone listening? */
+ if (serial->open_count == 0)
+ return;
+
+ if (status == 0) {
+ if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
+ u32 rest;
+ u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+ rest =
+ urb->actual_length %
+ serial->in_endp->wMaxPacketSize;
+ if (((rest == 5) || (rest == 6))
+ && !memcmp(((u8 *) urb->transfer_buffer) +
+ urb->actual_length - 4, crc_check, 4)) {
+ urb->actual_length -= 4;
+ }
+ }
+ /* Valid data, handle RX data */
+ spin_lock(&serial->serial_lock);
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
+ put_rxbuf_data_and_resubmit_bulk_urb(serial);
+ spin_unlock(&serial->serial_lock);
+ } else if (status == -ENOENT || status == -ECONNRESET) {
+ /* Unlinked - check for throttled port. */
+ D2("Port %d, successfully unlinked urb", serial->minor);
+ spin_lock(&serial->serial_lock);
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
+ hso_resubmit_rx_bulk_urb(serial, urb);
+ spin_unlock(&serial->serial_lock);
+ } else {
+ D2("Port %d, status = %d for read urb", serial->minor, status);
+ return;
+ }
+}
+
+/*
+ * This needs to be a tasklet otherwise we will
+ * end up recursively calling this function.
+ */
+void hso_unthrottle_tasklet(struct hso_serial *serial)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ if ((serial->parent->port_spec & HSO_INTF_MUX))
+ put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+ else
+ put_rxbuf_data_and_resubmit_bulk_urb(serial);
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+}
+
+static void hso_unthrottle(struct tty_struct *tty)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+
+ tasklet_hi_schedule(&serial->unthrottle_tasklet);
+}
+
+void hso_unthrottle_workfunc(struct work_struct *work)
+{
+ struct hso_serial *serial =
+ container_of(work, struct hso_serial,
+ retry_unthrottle_workqueue);
+ hso_unthrottle_tasklet(serial);
+}
+
/* open the requested serial port */
static int hso_serial_open(struct tty_struct *tty, struct file *filp)
{
@@ -1064,13 +1241,18 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = serial;
serial->tty = tty;
- /* check for port allready opened, if not set the termios */
+ /* check for port already opened, if not set the termios */
serial->open_count++;
if (serial->open_count == 1) {
tty->low_latency = 1;
- serial->flags = 0;
+ serial->rx_state = RX_IDLE;
/* Force default termio settings */
_hso_serial_set_termios(tty, NULL);
+ tasklet_init(&serial->unthrottle_tasklet,
+ (void (*)(unsigned long))hso_unthrottle_tasklet,
+ (unsigned long)serial);
+ INIT_WORK(&serial->retry_unthrottle_workqueue,
+ hso_unthrottle_workfunc);
result = hso_start_serial_device(serial->parent, GFP_KERNEL);
if (result) {
hso_stop_serial_device(serial->parent);
@@ -1117,9 +1299,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
}
if (!usb_gone)
hso_stop_serial_device(serial->parent);
+ tasklet_kill(&serial->unthrottle_tasklet);
+ cancel_work_sync(&serial->retry_unthrottle_workqueue);
}
+
if (!usb_gone)
usb_autopm_put_interface(serial->parent->interface);
+
mutex_unlock(&serial->parent->mutex);
}
@@ -1422,15 +1608,21 @@ static void intr_callback(struct urb *urb)
(1 << i));
if (serial != NULL) {
D1("Pending read interrupt on port %d\n", i);
- if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT,
- &serial->flags)) {
+ spin_lock(&serial->serial_lock);
+ if (serial->rx_state == RX_IDLE) {
/* Setup and send a ctrl req read on
* port i */
- hso_mux_serial_read(serial);
+ if (!serial->rx_urb_filled[0]) {
+ serial->rx_state = RX_SENT;
+ hso_mux_serial_read(serial);
+ } else
+ serial->rx_state = RX_PENDING;
+
} else {
D1("Already pending a read on "
"port %d\n", i);
}
+ spin_unlock(&serial->serial_lock);
}
}
}
@@ -1532,16 +1724,10 @@ static void ctrl_callback(struct urb *urb)
if (req->bRequestType ==
(USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
/* response to a read command */
- if (serial->open_count > 0) {
- /* handle RX data the normal way */
- put_rxbuf_data(urb, serial);
- }
-
- /* Re issue a read as long as we receive data. */
- if (urb->actual_length != 0)
- hso_mux_serial_read(serial);
- else
- clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
+ serial->rx_urb_filled[0] = 1;
+ spin_lock(&serial->serial_lock);
+ put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+ spin_unlock(&serial->serial_lock);
} else {
hso_put_activity(serial->parent);
if (serial->tty)
@@ -1552,91 +1738,42 @@ static void ctrl_callback(struct urb *urb)
}
/* handle RX data for serial port */
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
{
struct tty_struct *tty = serial->tty;
-
+ int write_length_remaining = 0;
+ int curr_write_len;
/* Sanity check */
if (urb == NULL || serial == NULL) {
D1("serial = NULL");
- return;
+ return -2;
}
/* Push data to tty */
- if (tty && urb->actual_length) {
+ if (tty) {
+ write_length_remaining = urb->actual_length -
+ serial->curr_rx_urb_offset;
D1("data to push to tty");
- tty_insert_flip_string(tty, urb->transfer_buffer,
- urb->actual_length);
- tty_flip_buffer_push(tty);
- }
-}
-
-/* read callback for Diag and CS port */
-static void hso_std_serial_read_bulk_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- int result;
- int status = urb->status;
-
- /* sanity check */
- if (!serial) {
- D1("serial == NULL");
- return;
- } else if (status) {
- log_usb_status(status, __func__);
- return;
- }
-
- D4("\n--- Got serial_read_bulk callback %02x ---", status);
- D1("Actual length = %d\n", urb->actual_length);
- DUMP1(urb->transfer_buffer, urb->actual_length);
-
- /* Anyone listening? */
- if (serial->open_count == 0)
- return;
-
- if (status == 0) {
- if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
- u32 rest;
- u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
- rest =
- urb->actual_length %
- serial->in_endp->wMaxPacketSize;
- if (((rest == 5) || (rest == 6))
- && !memcmp(((u8 *) urb->transfer_buffer) +
- urb->actual_length - 4, crc_check, 4)) {
- urb->actual_length -= 4;
- }
+ while (write_length_remaining) {
+ if (test_bit(TTY_THROTTLED, &tty->flags))
+ return -1;
+ curr_write_len = tty_insert_flip_string
+ (tty, urb->transfer_buffer +
+ serial->curr_rx_urb_offset,
+ write_length_remaining);
+ serial->curr_rx_urb_offset += curr_write_len;
+ write_length_remaining -= curr_write_len;
+ tty_flip_buffer_push(tty);
}
- /* Valid data, handle RX data */
- put_rxbuf_data(urb, serial);
- } else if (status == -ENOENT || status == -ECONNRESET) {
- /* Unlinked - check for throttled port. */
- D2("Port %d, successfully unlinked urb", serial->minor);
- } else {
- D2("Port %d, status = %d for read urb", serial->minor, status);
- return;
}
-
- usb_mark_last_busy(urb->dev);
-
- /* We are done with this URB, resubmit it. Prep the USB to wait for
- * another frame */
- usb_fill_bulk_urb(urb, serial->parent->usb,
- usb_rcvbulkpipe(serial->parent->usb,
- serial->in_endp->
- bEndpointAddress & 0x7F),
- urb->transfer_buffer, serial->rx_data_length,
- hso_std_serial_read_bulk_callback, serial);
- /* Give this to the USB subsystem so it can tell us when more data
- * arrives. */
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result) {
- dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d",
- __func__, result);
+ if (write_length_remaining == 0) {
+ serial->curr_rx_urb_offset = 0;
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
}
+ return write_length_remaining;
}
+
/* Base driver functions */
static void hso_log_port(struct hso_device *hso_dev)
@@ -1794,9 +1931,13 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
return -ENODEV;
for (i = 0; i < serial->num_rx_urbs; i++) {
- if (serial->rx_urb[i])
+ if (serial->rx_urb[i]) {
usb_kill_urb(serial->rx_urb[i]);
+ serial->rx_urb_filled[i] = 0;
+ }
}
+ serial->curr_rx_urb_idx = 0;
+ serial->curr_rx_urb_offset = 0;
if (serial->tx_urb)
usb_kill_urb(serial->tx_urb);
@@ -2740,6 +2881,7 @@ static const struct tty_operations hso_serial_ops = {
.chars_in_buffer = hso_serial_chars_in_buffer,
.tiocmget = hso_serial_tiocmget,
.tiocmset = hso_serial_tiocmset,
+ .unthrottle = hso_unthrottle
};
static struct usb_driver hso_driver = {
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index ca9d00c..b514350 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -118,7 +118,7 @@ static void mcs7830_async_cmd_callback(struct urb *urb)
if (urb->status < 0)
printk(KERN_DEBUG "%s() failed with %d\n",
- __FUNCTION__, urb->status);
+ __func__, urb->status);
kfree(req);
usb_free_urb(urb);
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 8c19307..38b90e7 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -119,7 +119,7 @@ static void ctrl_callback(struct urb *urb)
default:
if (netif_msg_drv(pegasus) && printk_ratelimit())
dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, urb->status);
+ __func__, urb->status);
}
pegasus->flags &= ~ETH_REGS_CHANGED;
wake_up(&pegasus->ctrl_wait);
@@ -136,7 +136,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
if (!buffer) {
if (netif_msg_drv(pegasus))
dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
add_wait_queue(&pegasus->ctrl_wait, &wait);
@@ -224,7 +224,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus))
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -246,7 +246,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
if (!tmp) {
if (netif_msg_drv(pegasus))
dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
memcpy(tmp, &data, 1);
@@ -277,7 +277,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus) && printk_ratelimit())
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -310,7 +310,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus))
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
}
return ret;
@@ -341,7 +341,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
}
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return ret;
}
@@ -378,7 +378,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
@@ -415,7 +415,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
@@ -463,7 +463,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
return ret;
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
#endif /* PEGASUS_WRITE_EEPROM */
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 1b95b04..29a3309 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1381,7 +1381,7 @@ enum velocity_msg_level {
#define ASSERT(x) { \
if (!(x)) { \
printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
- __FUNCTION__, __LINE__);\
+ __func__, __LINE__);\
BUG(); \
}\
}
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index d14e667..a5ddc6c 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -407,7 +407,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
if (cfm->version != CFM_VERSION) {
printk(KERN_ERR "%s:%s: firmware format %u rejected! "
"Expecting %u.\n",
- modname, __FUNCTION__, cfm->version, CFM_VERSION);
+ modname, __func__, cfm->version, CFM_VERSION);
return -EINVAL;
}
@@ -420,7 +420,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
*/
if (cksum != cfm->checksum) {
printk(KERN_ERR "%s:%s: firmware corrupted!\n",
- modname, __FUNCTION__);
+ modname, __func__);
printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n",
len - (int)sizeof(struct cycx_firmware) - 1,
cfm->info.codesize);
@@ -432,7 +432,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
/* If everything is ok, set reset, data and code pointers */
img_hdr = (struct cycx_fw_header *)&cfm->image;
#ifdef FIRMWARE_DEBUG
- printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname);
+ printk(KERN_INFO "%s:%s: image sizes\n", __func__, modname);
printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size);
printk(KERN_INFO " data=%lu\n", img_hdr->data_size);
printk(KERN_INFO " code=%lu\n", img_hdr->code_size);
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index d3b28b0..5a7303d 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -874,7 +874,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
- __FUNCTION__, lcn, loc, rem);
+ __func__, lcn, loc, rem);
dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
if (!dev) {
@@ -902,7 +902,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
- card->devname, __FUNCTION__, lcn, key);
+ card->devname, __func__, lcn, key);
dev = cycx_x25_get_dev_by_lcn(wandev, -key);
if (!dev) {
@@ -929,7 +929,7 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
- card->devname, __FUNCTION__, lcn);
+ card->devname, __func__, lcn);
dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
if (!dev) {
/* Invalid channel, discard packet */
@@ -950,7 +950,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card,
u8 lcn;
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
+ dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
if (dev) {
@@ -1381,7 +1381,7 @@ static void cycx_x25_chan_timer(unsigned long d)
cycx_x25_chan_disconnect(dev);
else
printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
- chan->card->devname, __FUNCTION__, dev->name);
+ chan->card->devname, __func__, dev->name);
}
/* Set logical channel state. */
@@ -1485,7 +1485,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
unsigned char *ptr;
if ((skb = dev_alloc_skb(1)) == NULL) {
- printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+ printk(KERN_ERR "%s: out of memory\n", __func__);
return;
}
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index f5d55ad..5f1ccb2 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -647,7 +647,7 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
skb = dpriv->rx_skbuff[dpriv->rx_current++%RX_RING_SIZE];
if (!skb) {
- printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
+ printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __func__);
goto refill;
}
pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2));
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 4518d0a..4917a94 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -548,7 +548,7 @@ static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
{
st_cpc_tty_area *cpc_tty;
- CPC_TTY_DBG("%s: set:%x clear:%x\n", __FUNCTION__, set, clear);
+ CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear);
if (!tty || !tty->driver_data ) {
CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f1624b3..97dfb11 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2244,6 +2244,16 @@
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
+#define PCI_VENDOR_ID_NETXEN 0x4040
+#define PCI_DEVICE_ID_NX2031_10GXSR 0x0001
+#define PCI_DEVICE_ID_NX2031_10GCX4 0x0002
+#define PCI_DEVICE_ID_NX2031_4GCU 0x0003
+#define PCI_DEVICE_ID_NX2031_IMEZ 0x0004
+#define PCI_DEVICE_ID_NX2031_HMEZ 0x0005
+#define PCI_DEVICE_ID_NX2031_XG_MGMT 0x0024
+#define PCI_DEVICE_ID_NX2031_XG_MGMT2 0x0025
+#define PCI_DEVICE_ID_NX3031 0x0100
+
#define PCI_VENDOR_ID_AKS 0x416c
#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-14 2:22 [git patches] net driver updates for .28 Jeff Garzik
@ 2008-09-20 7:09 ` David Miller
2008-09-20 7:28 ` Brice Goglin
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2008-09-20 7:09 UTC (permalink / raw)
To: jeff; +Cc: netdev, linux-kernel, brice
From: Jeff Garzik <jeff@garzik.org>
Date: Sat, 13 Sep 2008 22:22:36 -0400
> Please pull from 'davem-next' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
>
> to receive the following updates:
Jeff, I pulled this and I was going to push back out but I couldn't
because there are two or three changes in here I think have major
problems.
First, the two myri10ge patches that do the Toeplitz TX hashing
stuff.
--------------------
myri10ge: Add Toeplitz-hashing related routines
myri10ge uses a Toeplitz hashing. Add the corresponding select_queue()
method without using it yet.
Signed-off-by: Brice Goglin <brice@myri.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
myri10ge: Add multiqueue TX support
Add multiqueue TX support to myri10ge, using Toeplitz hashing.
Signed-off-by: Brice Goglin <brice@myri.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
--------------------
No, that is crap. I didn't create the ->select_tx_queue() callback so
that each and every damn multiqueue driver will override the generic
TX hash function in order to try and make the TX hashing match the RX
hashing.
That's not what it's for.
The callback exists for things like wireless where the queues have
a meaning other than flow seperation.
We (specifically Herbert Xu and myself) know that for routing and
firewalling applications matching the TX queue to the same hashing
namespace of the RX multiqueueing is desirable for best performance.
But we will do that generically by allowing the driver on the receive
side to record the RX hash used (or alternatively, if the exact RSS
hash isn't obtainable, the RX queue index itself) and on TX we will
use this information to select the TX queue properly.
Next, a bad IXGBE change:
--------------------
ixgbe: make compilation with LRO optional
The current ixgbe forces LRO to always be enabled. This patch makes this
optional due to the fact so that LRO can be disabled in cases where it is
not desirable such as routing or bridging.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
--------------------
Ummm, no. This is completely unnecessary and it's another thing we
don't want every damn driver doing. It is almost as bad as making
NAPI configurable.
If the user enables forwarding or bridging, the kernel automatically
disable LRO on the appropriate interfaces.
Jeff, please rebuild your tree with those three patches removed and I'll
repull. Those patches were near or at the end of the group of changes
for their effected drivers, so there should be absolutely zero conflicts
or merge windows when you do this tree rebuild.
Thanks!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-20 7:09 ` David Miller
@ 2008-09-20 7:28 ` Brice Goglin
2008-09-20 10:33 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Brice Goglin @ 2008-09-20 7:28 UTC (permalink / raw)
To: David Miller; +Cc: jeff, netdev, linux-kernel
David Miller wrote:
> No, that is crap. I didn't create the ->select_tx_queue() callback so
> that each and every damn multiqueue driver will override the generic
> TX hash function in order to try and make the TX hashing match the RX
> hashing.
>
> That's not what it's for.
>
> The callback exists for things like wireless where the queues have
> a meaning other than flow seperation.
>
> We (specifically Herbert Xu and myself) know that for routing and
> firewalling applications matching the TX queue to the same hashing
> namespace of the RX multiqueueing is desirable for best performance.
>
> But we will do that generically by allowing the driver on the receive
> side to record the RX hash used (or alternatively, if the exact RSS
> hash isn't obtainable, the RX queue index itself) and on TX we will
> use this information to select the TX queue properly.
>
Ok, I'll resend without the select_queue stuff. But you should really
document the above explanation. The only documentation we found was
"Devices or device layers can set this to control the queue selection
performed by dev_pick_tx()." in the git-log...
Brice
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-20 7:28 ` Brice Goglin
@ 2008-09-20 10:33 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-09-20 10:33 UTC (permalink / raw)
To: brice; +Cc: jeff, netdev, linux-kernel
From: Brice Goglin <brice@myri.com>
Date: Sat, 20 Sep 2008 09:28:24 +0200
> Ok, I'll resend without the select_queue stuff. But you should really
> document the above explanation. The only documentation we found was
> "Devices or device layers can set this to control the queue selection
> performed by dev_pick_tx()." in the git-log...
Sure.
On your part, I would suggest that when you run into a problem that
many other multiqueue drivers will likely face, that you bring it up
here for discussion instead of implementing localized solutions :-)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [git patches] net driver updates for .28
@ 2008-09-24 23:07 Jeff Garzik
2008-09-24 23:21 ` David Miller
2008-09-25 6:55 ` Sebastien Dugue
0 siblings, 2 replies; 11+ messages in thread
From: Jeff Garzik @ 2008-09-24 23:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, LKML, torvalds, Andrew Morton
Locking fixes, oops fix, and memory corruption fix all postponed until
2.6.28 as requested... under protest. Linux users shouldn't have to
wait for simple, straightforward, tested fixes to problems of that
severity.
Please pull from 'davem-next' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
to receive the following updates:
MAINTAINERS | 4 +-
drivers/net/3c505.c | 4 +-
drivers/net/8139too.c | 3 +-
drivers/net/Kconfig | 3 +
drivers/net/arcnet/arcnet.c | 18 +-
drivers/net/arcnet/com20020.c | 16 +-
drivers/net/atl1e/atl1e_main.c | 2 -
drivers/net/au1000_eth.c | 3 +-
drivers/net/ax88796.c | 14 +-
drivers/net/bfin_mac.c | 8 +-
drivers/net/bonding/bond_alb.c | 24 +
drivers/net/bonding/bond_main.c | 6 +
drivers/net/bonding/bonding.h | 2 +-
drivers/net/cs89x0.c | 2 -
drivers/net/cxgb3/cxgb3_offload.c | 8 +-
drivers/net/cxgb3/sge.c | 35 -
drivers/net/e100.c | 2 +-
drivers/net/ehea/ehea.h | 4 +-
drivers/net/ehea/ehea_main.c | 26 +-
drivers/net/ehea/ehea_phyp.c | 2 +-
drivers/net/ehea/ehea_qmr.c | 3 +-
drivers/net/enc28j60.c | 56 +-
drivers/net/ibm_newemac/phy.c | 2 +-
drivers/net/ixgb/ixgb.h | 2 +-
drivers/net/ixgbe/ixgbe.h | 60 +-
drivers/net/ixgbe/ixgbe_82598.c | 628 ++++++++++++++---
drivers/net/ixgbe/ixgbe_common.c | 972 +++++++++++++++++---------
drivers/net/ixgbe/ixgbe_common.h | 62 +-
drivers/net/ixgbe/ixgbe_ethtool.c | 298 ++++----
drivers/net/ixgbe/ixgbe_main.c | 1299 +++++++++++++++++++---------------
drivers/net/ixgbe/ixgbe_phy.c | 244 +++----
drivers/net/ixgbe/ixgbe_phy.h | 63 ++-
drivers/net/ixgbe/ixgbe_type.h | 528 +++++++++-----
drivers/net/meth.c | 2 +-
drivers/net/mipsnet.c | 2 +-
drivers/net/mlx4/alloc.c | 1 +
drivers/net/myri10ge/myri10ge.c | 33 +-
drivers/net/ne.c | 9 +-
drivers/net/netx-eth.c | 2 +-
drivers/net/netxen/netxen_nic.h | 2 +-
drivers/net/netxen/netxen_nic_main.c | 20 +-
drivers/net/pci-skeleton.c | 4 +-
drivers/net/r6040.c | 4 +-
drivers/net/r8169.c | 27 +-
drivers/net/s2io.c | 58 +-
drivers/net/s2io.h | 1 +
drivers/net/sfc/efx.c | 18 +-
drivers/net/sfc/falcon.c | 260 ++++----
drivers/net/sfc/falcon.h | 1 +
drivers/net/sfc/falcon_hwdefs.h | 1 -
drivers/net/sfc/falcon_io.h | 1 -
drivers/net/sfc/falcon_xmac.c | 88 +---
drivers/net/sfc/net_driver.h | 8 +-
drivers/net/sfc/sfe4001.c | 12 -
drivers/net/sfc/tenxpress.c | 69 +--
drivers/net/sfc/tx.c | 2 +-
drivers/net/sfc/workarounds.h | 2 -
drivers/net/sfc/xfp_phy.c | 1 -
drivers/net/skfp/pmf.c | 29 +-
drivers/net/smc911x.c | 68 +-
drivers/net/smc91x.c | 43 +-
drivers/net/smc91x.h | 2 +
drivers/net/sundance.c | 95 ++-
drivers/net/tehuti.h | 8 +-
drivers/net/tsi108_eth.c | 6 +-
drivers/net/tulip/de2104x.c | 1 -
drivers/net/ucc_geth.c | 116 ++--
drivers/net/usb/hso.c | 335 +++++++---
drivers/net/usb/mcs7830.c | 2 +-
drivers/net/usb/pegasus.c | 20 +-
drivers/net/via-velocity.h | 2 +-
drivers/net/wan/cycx_drv.c | 6 +-
drivers/net/wan/cycx_x25.c | 12 +-
drivers/net/wan/dscc4.c | 2 +-
drivers/net/wan/hdlc_x25.c | 8 +-
drivers/net/wan/pc300_tty.c | 2 +-
include/linux/pci_ids.h | 10 +
77 files changed, 3422 insertions(+), 2376 deletions(-)
Adrian Bunk (1):
[netdrvr/usb] hso_create_bulk_serial_device(): fix a double free
Alexander Duyck (2):
ixgbe: correctly add and remove napi queues
ixgbe: whitespace/formatting cleanup
Andrew Morton (1):
drivers/net/mlx4/alloc.c needs mm.h
Ben Hutchings (11):
sfc: Add check for memory allocation failure in falcon_probe_nic()
sfc: Fix memory BAR release call on error path
sfc: Remove workaround for old firmware bug
sfc: Serialise tenxpress_special_reset() with statistics fetches
sfc: Make queue flushes more reliable
sfc: Stop generating bogus events in tenxpress_check_hw()
sfc: Insert read memory barrier after checking MAC statistics flag
sfc: Disable interrupts after a fatal interrupt occurs until reset
sfc: Remove obsolete comment about PCI modes
sfc: Use CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS where appropriate
sfc: Fix type of FALCON_SPI_MAX_LEN
Breno Leitao (1):
s2io: Fix enabling VLAN tag stripping at driver initialization
Brice Goglin (3):
myri10ge: Stop scaring people when DCA is built but absent
myri10ge: Rename DCA-related firmware counters
myri10ge: use DCA if DCA is compiled as a module
Chris Snook (1):
MAINTAINERS: add Atheros maintainer for atlx
Dan Nicholson (1):
sundance: set carrier status on link change events
David Fries (1):
[netdrvr] ne: Fix suspend and resume for ISA PnP cards.
Denis Joseph Barrow (1):
[netdrvr] usb/hso: throttle to prevent loss of serial data
Dhananjay Phadke (2):
netxen: add pci ids
netxen: enable msi-x for quad-gig boards
Divy Le Ray (1):
cxgb3 - remove duplicate tests in lro
Florian Fainelli (1):
r6040: fix bad usage of udelay
Francois Romieu (2):
r8169: fix RxMissed register access
r8169: select MII in Kconfig
Hannes Hering (2):
ehea: Fix DLPAR memory handling
ehea: Enable DLPAR memory remove
Harvey Harrison (1):
drivers/net: replace __FUNCTION__ with __func__
Jeff Kirsher (2):
ixgbe: fix pci_resource allocation as in other drivers
ixgbe: bump version
Jesse Brandeburg (23):
ixgbe: fix bug where using wake queue instead of start
ixgbe: fix dca defines to not have spaces
ixgbe: fix multicast address update
ixgbe: Update watchdog thread to accomodate longerlink_up events
ixgbe: link change interrupt was not causing link event
ixgbe: fix bug with shared interrupts
ixgbe: limit small mtu to minimum for ipv4 support
ixgbe: fix ethtool register dump
ixgbe: fix ethtool disable csum for ipv6
ixgbe: fix initial interrupt throttle settings
ixgbe: fix bug with lots of tx queues
ixgbe: recycle pages in packet split mode
ixgbe: add device support for XF LR adapters
ixgbe: fix ring reallocation in ethtool
ixgbe: lro stats were not counted on first ethtool -Scall
ixgbe: add clean rx many routine
ixgbe: update to latest common code module
ixgbe: refresh the ixgbe_down function
ixgbe: move set_num_queues and call it after msix failure
ixgbe: cleanup defines
ixgbe: lower stack space usage
ixgbe: xmit frame refactor
ixgbe: fix DCA dependency in Kconfig
Krzysztof Halasa (1):
wan/hdlc_x25.c: fix a NULL dereference
Magnus Damm (3):
smc91x: fix nowait printout
smc91x: SMC_IO_SHIFT platform data support for default case
smc911x: remove duplicate debug printout
Martin Gebert (1):
[netdrvr] au1000_eth: Spinlock initialisation fix
Mats Erik Andersson (1):
8139too: [cosmetic] fix incorrect register for flash-rom
Matthew Wilcox (1):
[netdrvr] atl1e: Don't take the mdio_lock in atl1e_probe
Peter P Waskiewicz (1):
ixgbe: Whitespace, copyright update and version number change patch
Sebastien Dugue (2):
ehea: fix phyp debugging typo
ehea: fix mutex and spinlock use
Stephen Hemminger (1):
bonding: add more ethtool support
Steve Hodgson (2):
sfc: Don't use EFX_OWORD_FIELD on an event (64-bit, quad-word)
sfc: Don't include net_driver.h from falcon_io.h
Takashi Iwai (1):
drivers/net/skfp/pmf.c: Use offsetof() macro
Thomas Bogendoerfer (1):
tulip: Fix dead 21041 ethernet after ifconfig down
Vlad Yasevich (1):
bonding: Do not tx-balance some IPv6 packets on ALB/TLB bonds
Yoichi Yuasa (1):
cs89x0: fix warning release_irq label
diff --git a/MAINTAINERS b/MAINTAINERS
index 106684e..c29b420 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -750,11 +750,13 @@ P: Ville Syrjala
M: syrjala@sci.fi
S: Maintained
-ATL1 ETHERNET DRIVER
+ATLX ETHERNET DRIVERS
P: Jay Cliburn
M: jcliburn@gmail.com
P: Chris Snook
M: csnook@redhat.com
+P: Jie Yang
+M: jie.yang@atheros.com
L: atl1-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/atl1
W: http://atl1.sourceforge.net
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index fdfb2b2..a424869 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -130,12 +130,12 @@ static const char filename[] = __FILE__;
static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
#define TIMEOUT_MSG(lineno) \
- printk(timeout_msg, filename,__FUNCTION__,(lineno))
+ printk(timeout_msg, filename,__func__,(lineno))
static const char invalid_pcb_msg[] =
"*** invalid pcb length %d at %s:%s (line %d) ***\n";
#define INVALID_PCB_MSG(len) \
- printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
+ printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index f6ca997..32e66f0 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -309,7 +309,7 @@ enum RTL8139_registers {
Cfg9346 = 0x50,
Config0 = 0x51,
Config1 = 0x52,
- FlashReg = 0x54,
+ TimerInt = 0x54,
MediaStatus = 0x58,
Config3 = 0x59,
Config4 = 0x5A, /* absent on RTL-8139A */
@@ -325,6 +325,7 @@ enum RTL8139_registers {
FIFOTMS = 0x70, /* FIFO Control and test. */
CSCR = 0x74, /* Chip Status and Configuration Register. */
PARA78 = 0x78,
+ FlashReg = 0xD4, /* Communication with Flash ROM, four bytes. */
PARA7c = 0x7c, /* Magic transceiver parameter register. */
Config5 = 0xD8, /* absent on RTL-8139A */
};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 69c81da..031b95b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2057,6 +2057,7 @@ config R8169
tristate "Realtek 8169 gigabit ethernet support"
depends on PCI
select CRC32
+ select MII
---help---
Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
@@ -2411,6 +2412,7 @@ config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
select INET_LRO
+ select INTEL_IOATDMA
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2462,6 +2464,7 @@ config MYRI10GE
select FW_LOADER
select CRC32
select INET_LRO
+ select INTEL_IOATDMA
---help---
This driver supports Myricom Myri-10G Dual Protocol interface in
Ethernet mode. If the eeprom on your board is not recent enough,
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index bdc4c0b..a5b0769 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -442,24 +442,24 @@ static int arcnet_open(struct net_device *dev)
BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
"DOS networking programs!\n");
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (ASTATUS() & RESETflag) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear);
}
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* make sure we're ready to receive IRQ's. */
AINTMASK(0);
udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
*/
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask = NORXflag | RECONflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
netif_start_queue(dev);
@@ -670,14 +670,14 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
freeskb = 0;
}
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
/* make sure we didn't ignore a TX IRQ while we were in here */
AINTMASK(0);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask |= TXFREEflag|EXCNAKflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
spin_unlock_irqrestore(&lp->lock, flags);
if (freeskb) {
@@ -798,7 +798,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
diagstatus = (status >> 8) & 0xFF;
BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
- __FILE__,__LINE__,__FUNCTION__,status);
+ __FILE__,__LINE__,__func__,status);
didsomething = 0;
/*
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 8b51313..70124a9 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -238,15 +238,15 @@ static int com20020_reset(struct net_device *dev, int really_reset)
u_char inbyte;
BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
- __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
+ __FILE__,__LINE__,__func__,dev,lp,dev->name);
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
dev->name, ASTATUS());
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
/* power-up defaults */
SETCONF;
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (really_reset) {
/* reset the card */
@@ -254,22 +254,22 @@ static int com20020_reset(struct net_device *dev, int really_reset)
mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
}
/* clear flags & end reset */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
/* verify that the ARCnet signature byte is present */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (inbyte != TESTvalue) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
return 1;
}
/* enable extended (512-byte) packets */
ACOMMAND(CONFIGcmd | EXTconf);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* done! return success. */
return 0;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 7685b99..9b60352 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -2390,9 +2390,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
}
/* Init GPHY as early as possible due to power saving issue */
- spin_lock(&adapter->mdio_lock);
atl1e_phy_init(&adapter->hw);
- spin_unlock(&adapter->mdio_lock);
/* reset the controller to
* put the device in a known good starting state */
err = atl1e_reset_hw(&adapter->hw);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 5ee1b05..92c16c3 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -653,6 +653,8 @@ static struct net_device * au1000_probe(int port_num)
aup = dev->priv;
+ spin_lock_init(&aup->lock);
+
/* Allocate the data buffers */
/* Snooping works fine with eth on all au1xxx */
aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
@@ -753,7 +755,6 @@ static struct net_device * au1000_probe(int port_num)
aup->tx_db_inuse[i] = pDB;
}
- spin_lock_init(&aup->lock);
dev->base_addr = base;
dev->irq = irq;
dev->open = au1000_open;
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index a886a4b..4207d6e 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -153,7 +153,7 @@ static void ax_reset_8390(struct net_device *dev)
while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
if (jiffies - reset_start_time > 2*HZ/100) {
dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
- __FUNCTION__, dev->name);
+ __func__, dev->name);
break;
}
}
@@ -173,7 +173,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
if (ei_status.dmaing) {
dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -215,7 +215,7 @@ static void ax_block_input(struct net_device *dev, int count,
dev_err(&ax->dev->dev,
"%s: DMAing conflict in %s "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -260,7 +260,7 @@ static void ax_block_output(struct net_device *dev, int count,
if (ei_status.dmaing) {
dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
"[DMAstat:%d][irqlock:%d]\n",
- dev->name, __FUNCTION__,
+ dev->name, __func__,
ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -396,7 +396,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
{
if (phy_debug)
pr_debug("%s: dev %p, %04x, %04x, %d\n",
- __FUNCTION__, dev, phy_addr, reg, opc);
+ __func__, dev, phy_addr, reg, opc);
ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
@@ -422,7 +422,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg)
spin_unlock_irqrestore(&ei_local->page_lock, flags);
if (phy_debug)
- pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+ pr_debug("%s: %04x.%04x => read %04x\n", __func__,
phy_addr, reg, result);
return result;
@@ -436,7 +436,7 @@ ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
unsigned long flags;
dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
- __FUNCTION__, dev, phy_addr, reg, value);
+ __func__, dev, phy_addr, reg, value);
spin_lock_irqsave(&ei->page_lock, flags);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 3db7db1..df896e2 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -811,7 +811,7 @@ static void bfin_mac_enable(void)
{
u32 opmode;
- pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__);
+ pr_debug("%s: %s\n", DRV_NAME, __func__);
/* Set RX DMA */
bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
@@ -847,7 +847,7 @@ static void bfin_mac_enable(void)
/* Our watchdog timed out. Called by the networking layer */
static void bfin_mac_timeout(struct net_device *dev)
{
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
bfin_mac_disable();
@@ -949,7 +949,7 @@ static int bfin_mac_open(struct net_device *dev)
{
struct bfin_mac_local *lp = netdev_priv(dev);
int retval;
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -989,7 +989,7 @@ static int bfin_mac_open(struct net_device *dev)
static int bfin_mac_close(struct net_device *dev)
{
struct bfin_mac_local *lp = netdev_priv(dev);
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+ pr_debug("%s: %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 3d39278..ade5f3f 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -38,6 +38,7 @@
#include <linux/in.h>
#include <net/ipx.h>
#include <net/arp.h>
+#include <net/ipv6.h>
#include <asm/byteorder.h>
#include "bonding.h"
#include "bond_alb.h"
@@ -81,6 +82,7 @@
#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC
static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01};
static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
#pragma pack(1)
@@ -1290,6 +1292,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
u32 hash_index = 0;
const u8 *hash_start = NULL;
int res = 1;
+ struct ipv6hdr *ip6hdr;
skb_reset_mac_header(skb);
eth_data = eth_hdr(skb);
@@ -1319,11 +1322,32 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
break;
case ETH_P_IPV6:
+ /* IPv6 doesn't really use broadcast mac address, but leave
+ * that here just in case.
+ */
if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
do_tx_balance = 0;
break;
}
+ /* IPv6 uses all-nodes multicast as an equivalent to
+ * broadcasts in IPv4.
+ */
+ if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) {
+ do_tx_balance = 0;
+ break;
+ }
+
+ /* Additianally, DAD probes should not be tx-balanced as that
+ * will lead to false positives for duplicate addresses and
+ * prevent address configuration from working.
+ */
+ ip6hdr = ipv6_hdr(skb);
+ if (ipv6_addr_any(&ip6hdr->saddr)) {
+ do_tx_balance = 0;
+ break;
+ }
+
hash_start = (char *)&(ipv6_hdr(skb)->daddr);
hash_size = sizeof(ipv6_hdr(skb)->daddr);
break;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index babe461..8e2be24 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4493,6 +4493,12 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
static const struct ethtool_ops bond_ethtool_ops = {
.get_drvinfo = bond_ethtool_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .get_tso = ethtool_op_get_tso,
+ .get_ufo = ethtool_op_get_ufo,
+ .get_flags = ethtool_op_get_flags,
};
/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index fb730ec..f7b40ed 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -32,7 +32,7 @@
#ifdef BONDING_DEBUG
#define dprintk(fmt, args...) \
printk(KERN_DEBUG \
- DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
+ DRV_NAME ": %s() %d: " fmt, __func__, __LINE__ , ## args )
#else
#define dprintk(fmt, args...)
#endif /* BONDING_DEBUG */
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index ea6144a..b0b6676 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -1397,9 +1397,7 @@ net_open(struct net_device *dev)
release_dma:
#if ALLOW_DMA
free_dma(dev->dma);
-#endif
release_irq:
-#if ALLOW_DMA
release_dma_buff(lp);
#endif
writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index c5b3de1..0f6fd63 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1018,7 +1018,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
if (!skb) {
- printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__);
+ printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
return;
}
skb->priority = CPL_PRIORITY_CONTROL;
@@ -1049,14 +1049,14 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
return;
if (!is_offloading(newdev)) {
printk(KERN_WARNING "%s: Redirect to non-offload "
- "device ignored.\n", __FUNCTION__);
+ "device ignored.\n", __func__);
return;
}
tdev = dev2t3cdev(olddev);
BUG_ON(!tdev);
if (tdev != dev2t3cdev(newdev)) {
printk(KERN_WARNING "%s: Redirect to different "
- "offload device ignored.\n", __FUNCTION__);
+ "offload device ignored.\n", __func__);
return;
}
@@ -1064,7 +1064,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
e = t3_l2t_get(tdev, new->neighbour, newdev);
if (!e) {
printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
- __FUNCTION__);
+ __func__);
return;
}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 6990c0d..89efd04 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1937,38 +1937,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
}
-#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
- TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
- TCP_FLAG_SYN | TCP_FLAG_FIN)
-#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
-
-/**
- * lro_segment_ok - check if a TCP segment is eligible for LRO
- * @tcph: the TCP header of the packet
- *
- * Returns true if a TCP packet is eligible for LRO. This requires that
- * the packet have only the ACK flag set and no TCP options besides
- * time stamps.
- */
-static inline int lro_segment_ok(const struct tcphdr *tcph)
-{
- int optlen;
-
- if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
- return 0;
-
- optlen = (tcph->doff << 2) - sizeof(*tcph);
- if (optlen) {
- const u32 *opt = (const u32 *)(tcph + 1);
-
- if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
- *opt != htonl(TSTAMP_WORD) || !opt[2])
- return 0;
- }
- return 1;
-}
-
static int t3_get_lro_header(void **eh, void **iph, void **tcph,
u64 *hdr_flags, void *priv)
{
@@ -1981,9 +1949,6 @@ static int t3_get_lro_header(void **eh, void **iph, void **tcph,
*iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
*tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
- if (!lro_segment_ok(*tcph))
- return -1;
-
*hdr_flags = LRO_IPV4 | LRO_TCP;
return 0;
}
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 453115a..7d7dfa5 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -191,7 +191,7 @@ MODULE_PARM_DESC(use_io, "Force use of i/o access mode");
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
- __FUNCTION__ , ## args))
+ __func__ , ## args))
#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index e01926b..5524271 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,13 +40,13 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0092"
+#define DRV_VERSION "EHEA_0093"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
#define DLPAR_MEM_ADD 2
#define DLPAR_MEM_REM 4
-#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD)
+#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD | DLPAR_MEM_REM)
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index b70c531..c765ec6 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -219,9 +219,11 @@ static void ehea_update_firmware_handles(void)
}
out_update:
+ mutex_lock(&ehea_fw_handles.lock);
kfree(ehea_fw_handles.arr);
ehea_fw_handles.arr = arr;
ehea_fw_handles.num_entries = i;
+ mutex_unlock(&ehea_fw_handles.lock);
}
static void ehea_update_bcmc_registrations(void)
@@ -293,9 +295,11 @@ static void ehea_update_bcmc_registrations(void)
}
out_update:
+ spin_lock(&ehea_bcmc_regs.lock);
kfree(ehea_bcmc_regs.arr);
ehea_bcmc_regs.arr = arr;
ehea_bcmc_regs.num_entries = i;
+ spin_unlock(&ehea_bcmc_regs.lock);
}
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
@@ -1770,8 +1774,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
- spin_lock(&ehea_bcmc_regs.lock);
-
/* Deregister old MAC in pHYP */
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1792,7 +1794,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
out_upregs:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
out_free:
kfree(cb0);
out:
@@ -1954,8 +1955,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
- spin_lock(&ehea_bcmc_regs.lock);
-
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
goto out;
@@ -1985,7 +1984,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
return;
}
@@ -2466,8 +2464,6 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2504,8 +2500,6 @@ static int ehea_up(struct net_device *dev)
}
}
- spin_lock(&ehea_bcmc_regs.lock);
-
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret) {
ret = -EIO;
@@ -2527,10 +2521,8 @@ out:
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2580,9 +2572,6 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
- spin_lock(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -2591,7 +2580,6 @@ static int ehea_down(struct net_device *dev)
port->state = EHEA_PORT_DOWN;
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ret = ehea_clean_all_portres(port);
if (ret)
@@ -2599,7 +2587,6 @@ static int ehea_down(struct net_device *dev)
dev->name, ret);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -3378,7 +3365,6 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
- mutex_lock(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3462,7 +3448,6 @@ out_free_ad:
out:
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -3481,8 +3466,6 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
- mutex_lock(&ehea_fw_handles.lock);
-
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
@@ -3492,7 +3475,6 @@ static int __devexit ehea_remove(struct of_device *dev)
kfree(adapter);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return 0;
}
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index 156eb63..2a33a61 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -535,7 +535,7 @@ u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr)
cb_logaddr, /* R5 */
0, 0, 0, 0, 0); /* R6-R10 */
#ifdef DEBUG
- ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
+ ehea_dump(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
#endif
return hret;
}
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 140f05b..db8a925 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -595,7 +595,8 @@ static int ehea_create_busmap_callback(unsigned long pfn,
end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
mr_len = *(unsigned long *)arg;
- ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
+ if (!ehea_bmap)
+ ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
if (!ehea_bmap)
return -ENOMEM;
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index aa0bf6e..e1b441e 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -110,7 +110,7 @@ spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
}
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
return ret;
}
@@ -131,7 +131,7 @@ static int spi_write_buf(struct enc28j60_net *priv, int len,
ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1);
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
}
return ret;
}
@@ -156,7 +156,7 @@ static u8 spi_read_op(struct enc28j60_net *priv, u8 op,
ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen);
if (ret)
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
else
val = rx_buf[slen - 1];
@@ -176,14 +176,14 @@ static int spi_write_op(struct enc28j60_net *priv, u8 op,
ret = spi_write(priv->spi, priv->spi_transfer_buf, 2);
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
return ret;
}
static void enc28j60_soft_reset(struct enc28j60_net *priv)
{
if (netif_msg_hw(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
spi_write_op(priv, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
/* Errata workaround #1, CLKRDY check is unreliable,
@@ -357,7 +357,7 @@ static void enc28j60_mem_read(struct enc28j60_net *priv,
reg = nolock_regw_read(priv, ERDPTL);
if (reg != addr)
printk(KERN_DEBUG DRV_NAME ": %s() error writing ERDPT "
- "(0x%04x - 0x%04x)\n", __FUNCTION__, reg, addr);
+ "(0x%04x - 0x%04x)\n", __func__, reg, addr);
}
#endif
spi_read_buf(priv, len, data);
@@ -380,7 +380,7 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
if (reg != TXSTART_INIT)
printk(KERN_DEBUG DRV_NAME
": %s() ERWPT:0x%04x != 0x%04x\n",
- __FUNCTION__, reg, TXSTART_INIT);
+ __func__, reg, TXSTART_INIT);
}
#endif
/* Set the TXND pointer to correspond to the packet size given */
@@ -390,13 +390,13 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME
": %s() after control byte ERWPT:0x%04x\n",
- __FUNCTION__, nolock_regw_read(priv, EWRPTL));
+ __func__, nolock_regw_read(priv, EWRPTL));
/* copy the packet into the transmit buffer */
spi_write_buf(priv, len, data);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME
": %s() after write packet ERWPT:0x%04x, len=%d\n",
- __FUNCTION__, nolock_regw_read(priv, EWRPTL), len);
+ __func__, nolock_regw_read(priv, EWRPTL), len);
mutex_unlock(&priv->lock);
}
@@ -495,7 +495,7 @@ static int enc28j60_set_hw_macaddr(struct net_device *ndev)
if (netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME
": %s() Hardware must be disabled to set "
- "Mac address\n", __FUNCTION__);
+ "Mac address\n", __func__);
ret = -EBUSY;
}
mutex_unlock(&priv->lock);
@@ -575,7 +575,7 @@ static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
if (start > 0x1FFF || end > 0x1FFF || start > end) {
if (netif_msg_drv(priv))
printk(KERN_ERR DRV_NAME ": %s(%d, %d) RXFIFO "
- "bad parameters!\n", __FUNCTION__, start, end);
+ "bad parameters!\n", __func__, start, end);
return;
}
/* set receive buffer start + end */
@@ -591,7 +591,7 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
if (start > 0x1FFF || end > 0x1FFF || start > end) {
if (netif_msg_drv(priv))
printk(KERN_ERR DRV_NAME ": %s(%d, %d) TXFIFO "
- "bad parameters!\n", __FUNCTION__, start, end);
+ "bad parameters!\n", __func__, start, end);
return;
}
/* set transmit buffer start + end */
@@ -630,7 +630,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
u8 reg;
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __FUNCTION__,
+ printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __func__,
priv->full_duplex ? "FullDuplex" : "HalfDuplex");
mutex_lock(&priv->lock);
@@ -661,7 +661,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
if (reg == 0x00 || reg == 0xff) {
if (netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() Invalid RevId %d\n",
- __FUNCTION__, reg);
+ __func__, reg);
return 0;
}
@@ -724,7 +724,7 @@ static void enc28j60_hw_enable(struct enc28j60_net *priv)
/* enable interrupts */
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
- __FUNCTION__);
+ __func__);
enc28j60_phy_write(priv, PHIE, PHIE_PGEIE | PHIE_PLNKIE);
@@ -888,7 +888,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
if (netif_msg_rx_err(priv))
dev_err(&ndev->dev,
"%s() Invalid packet address!! 0x%04x\n",
- __FUNCTION__, priv->next_pk_ptr);
+ __func__, priv->next_pk_ptr);
/* packet address corrupted: reset RX logic */
mutex_lock(&priv->lock);
nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
@@ -917,7 +917,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
rxstat |= rsv[4];
if (netif_msg_rx_status(priv))
- enc28j60_dump_rsv(priv, __FUNCTION__, next_packet, len, rxstat);
+ enc28j60_dump_rsv(priv, __func__, next_packet, len, rxstat);
if (!RSV_GETBIT(rxstat, RSV_RXOK)) {
if (netif_msg_rx_err(priv))
@@ -941,7 +941,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
len, skb_put(skb, len));
if (netif_msg_pktdata(priv))
- dump_packet(__FUNCTION__, skb->len, skb->data);
+ dump_packet(__func__, skb->len, skb->data);
skb->protocol = eth_type_trans(skb, ndev);
/* update statistics */
ndev->stats.rx_packets++;
@@ -958,7 +958,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
erxrdpt = erxrdpt_workaround(next_packet, RXSTART_INIT, RXEND_INIT);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT:0x%04x\n",
- __FUNCTION__, erxrdpt);
+ __func__, erxrdpt);
mutex_lock(&priv->lock);
nolock_regw_write(priv, ERXRDPTL, erxrdpt);
@@ -968,7 +968,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
reg = nolock_regw_read(priv, ERXRDPTL);
if (reg != erxrdpt)
printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT verify "
- "error (0x%04x - 0x%04x)\n", __FUNCTION__,
+ "error (0x%04x - 0x%04x)\n", __func__,
reg, erxrdpt);
}
#endif
@@ -1006,7 +1006,7 @@ static int enc28j60_get_free_rxfifo(struct enc28j60_net *priv)
mutex_unlock(&priv->lock);
if (netif_msg_rx_status(priv))
printk(KERN_DEBUG DRV_NAME ": %s() free_space = %d\n",
- __FUNCTION__, free_space);
+ __func__, free_space);
return free_space;
}
@@ -1022,7 +1022,7 @@ static void enc28j60_check_link_status(struct net_device *ndev)
reg = enc28j60_phy_read(priv, PHSTAT2);
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() PHSTAT1: %04x, "
- "PHSTAT2: %04x\n", __FUNCTION__,
+ "PHSTAT2: %04x\n", __func__,
enc28j60_phy_read(priv, PHSTAT1), reg);
duplex = reg & PHSTAT2_DPXSTAT;
@@ -1095,7 +1095,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
int intflags, loop;
if (netif_msg_intr(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
/* disable further interrupts */
locked_reg_bfclr(priv, EIE, EIE_INTIE);
@@ -1198,7 +1198,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
/* re-enable interrupts */
locked_reg_bfset(priv, EIE, EIE_INTIE);
if (netif_msg_intr(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __func__);
}
/*
@@ -1213,7 +1213,7 @@ static void enc28j60_hw_tx(struct enc28j60_net *priv)
": Tx Packet Len:%d\n", priv->tx_skb->len);
if (netif_msg_pktdata(priv))
- dump_packet(__FUNCTION__,
+ dump_packet(__func__,
priv->tx_skb->len, priv->tx_skb->data);
enc28j60_packet_write(priv, priv->tx_skb->len, priv->tx_skb->data);
@@ -1254,7 +1254,7 @@ static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_tx_queued(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
/* If some error occurs while trying to transmit this
* packet, you should return '1' from this function.
@@ -1325,7 +1325,7 @@ static int enc28j60_net_open(struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
if (!is_valid_ether_addr(dev->dev_addr)) {
if (netif_msg_ifup(priv)) {
@@ -1363,7 +1363,7 @@ static int enc28j60_net_close(struct net_device *dev)
struct enc28j60_net *priv = netdev_priv(dev);
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+ printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
enc28j60_hw_disable(priv);
enc28j60_lowpower(priv, true);
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index 37bfeea..9164abb 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -321,7 +321,7 @@ static struct mii_phy_def bcm5248_phy_def = {
static int m88e1111_init(struct mii_phy *phy)
{
- pr_debug("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+ pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
phy_write(phy, 0x14, 0x0ce3);
phy_write(phy, 0x18, 0x4101);
phy_write(phy, 0x09, 0x0e00);
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 804698f..d85717e 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -85,7 +85,7 @@ struct ixgb_adapter;
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __FUNCTION__ , ## args))
+ __func__ , ## args))
/* TX/RX descriptor defines */
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 90b5383..2198b77 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -41,13 +40,11 @@
#include <linux/dca.h>
#endif
-#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args)
-
#define PFX "ixgbe: "
#define DPRINTK(nlevel, klevel, fmt, args...) \
((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
- __FUNCTION__ , ## args)))
+ __func__ , ## args)))
/* TX/RX descriptor defines */
#define IXGBE_DEFAULT_TXD 1024
@@ -58,15 +55,6 @@
#define IXGBE_MAX_RXD 4096
#define IXGBE_MIN_RXD 64
-#define IXGBE_DEFAULT_RXQ 1
-#define IXGBE_MAX_RXQ 1
-#define IXGBE_MIN_RXQ 1
-
-#define IXGBE_DEFAULT_ITR_RX_USECS 125 /* 8k irqs/sec */
-#define IXGBE_DEFAULT_ITR_TX_USECS 250 /* 4k irqs/sec */
-#define IXGBE_MIN_ITR_USECS 100 /* 500k irqs/sec */
-#define IXGBE_MAX_ITR_USECS 10000 /* 100 irqs/sec */
-
/* flow control */
#define IXGBE_DEFAULT_FCRTL 0x10000
#define IXGBE_MIN_FCRTL 0x40
@@ -88,9 +76,6 @@
#define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
-/* How many Tx Descriptors do we need to call netif_wake_queue? */
-#define IXGBE_TX_QUEUE_WAKE 16
-
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IXGBE_RX_BUFFER_WRITE 16 /* Must be power of 2 */
@@ -119,6 +104,7 @@ struct ixgbe_rx_buffer {
dma_addr_t dma;
struct page *page;
dma_addr_t page_dma;
+ unsigned int page_offset;
};
struct ixgbe_queue_stats {
@@ -157,14 +143,11 @@ struct ixgbe_ring {
struct net_lro_mgr lro_mgr;
bool lro_used;
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 */
+ u16 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;
- u16 itr_register;
- char name[IFNAMSIZ + 5];
u16 work_limit; /* max work per interrupt */
u16 rx_buf_len;
};
@@ -191,8 +174,8 @@ struct ixgbe_q_vector {
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;
+ u8 tx_itr;
+ u8 rx_itr;
u32 eitr;
};
@@ -240,7 +223,9 @@ struct ixgbe_adapter {
/* TX */
struct ixgbe_ring *tx_ring; /* One per active queue */
+ int num_tx_queues;
u64 restart_queue;
+ u64 hw_csum_tx_good;
u64 lsc_int;
u64 hw_tso_ctxt;
u64 hw_tso6_ctxt;
@@ -249,12 +234,10 @@ struct ixgbe_adapter {
/* RX */
struct ixgbe_ring *rx_ring; /* One per active queue */
- u64 hw_csum_tx_good;
+ int num_rx_queues;
u64 hw_csum_rx_error;
u64 hw_csum_rx_good;
u64 non_eop_descs;
- int num_tx_queues;
- int num_rx_queues;
int num_msix_vectors;
struct ixgbe_ring_feature ring_feature[3];
struct msix_entry *msix_entries;
@@ -301,14 +284,21 @@ struct ixgbe_adapter {
struct ixgbe_hw_stats stats;
/* Interrupt Throttle Rate */
- u32 rx_eitr;
- u32 tx_eitr;
+ u32 eitr_param;
unsigned long state;
u64 tx_busy;
u64 lro_aggregated;
u64 lro_flushed;
u64 lro_no_desc;
+ unsigned int tx_ring_count;
+ unsigned int rx_ring_count;
+
+ u32 link_speed;
+ bool link_up;
+ unsigned long link_check_timeout;
+
+ struct work_struct watchdog_task;
};
enum ixbge_state_t {
@@ -330,11 +320,11 @@ extern int ixgbe_up(struct ixgbe_adapter *adapter);
extern void ixgbe_down(struct ixgbe_adapter *adapter);
extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
extern void ixgbe_reset(struct ixgbe_adapter *adapter);
-extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
-extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rxdr);
-extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *txdr);
+extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index ba09063..7cddcfb 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -39,68 +38,59 @@
#define IXGBE_82598_MC_TBL_SIZE 128
#define IXGBE_82598_VFT_TBL_SIZE 128
-static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *autoneg);
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
- u32 *speed, bool *autoneg);
-static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up);
-static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete);
-static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
-
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+/**
+ */
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
- hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
- hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE;
- hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE;
- hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES;
-
- /* PHY ops are filled in by default properly for Fiber only */
- if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
- hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
- hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
- hw->mac.ops.get_link_settings =
- &ixgbe_get_copper_link_settings_82598;
-
- /* Call PHY identify routine to get the phy type */
- ixgbe_identify_phy(hw);
-
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
- hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
- hw->phy.ops.setup_link_speed =
- &ixgbe_setup_tnx_phy_link_speed;
- break;
- default:
- break;
- }
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_phy_info *phy = &hw->phy;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy_generic(hw);
+
+ /* PHY Init */
+ switch (phy->type) {
+ default:
+ break;
}
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82598;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82598;
+ }
+
+ mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+
return 0;
}
/**
- * ixgbe_get_link_settings_82598 - Determines default link settings
+ * ixgbe_get_link_capabilities_82598 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @autoneg: boolean auto-negotiation value
*
- * Determines the default link settings by reading the AUTOC register.
+ * Determines the link capabilities by reading the AUTOC register.
**/
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *autoneg)
+static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
{
s32 status = 0;
s32 autoc_reg;
@@ -149,15 +139,16 @@ static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
}
/**
- * ixgbe_get_copper_link_settings_82598 - Determines default link settings
+ * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @autoneg: boolean auto-negotiation value
*
- * Determines the default link settings by reading the AUTOC register.
+ * Determines the link capabilities by reading the AUTOC register.
**/
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
- u32 *speed, bool *autoneg)
+s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
{
s32 status = IXGBE_ERR_LINK_SETUP;
u16 speed_ability;
@@ -165,9 +156,9 @@ static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
*speed = 0;
*autoneg = true;
- status = ixgbe_read_phy_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &speed_ability);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &speed_ability);
if (status == 0) {
if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
@@ -195,11 +186,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598EB_CX4:
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ case IXGBE_DEV_ID_82598EB_XF_LR:
media_type = ixgbe_media_type_fiber;
break;
- case IXGBE_DEV_ID_82598AT_DUAL_PORT:
- media_type = ixgbe_media_type_copper;
- break;
default:
media_type = ixgbe_media_type_unknown;
break;
@@ -209,6 +198,122 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_setup_fc_82598 - Configure flow control settings
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Configures the flow control settings based on SW configuration. This
+ * function is used for 802.3x flow control configuration only.
+ **/
+s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ u32 frctl_reg;
+ u32 rmcs_reg;
+
+ if (packetbuf_num < 0 || packetbuf_num > 7) {
+ hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+ " 0-7\n", packetbuf_num);
+ }
+
+ frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+
+ rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
+
+ /*
+ * 10 gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.type == ixgbe_fc_default)
+ hw->fc.type = ixgbe_fc_full;
+
+ /*
+ * We want to save off the original Flow Control configuration just in
+ * case we get disconnected and then reconnected into a different hub
+ * or switch with different Flow Control capabilities.
+ */
+ hw->fc.original_type = hw->fc.type;
+
+ /*
+ * The possible values of the "flow_control" parameter are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames but not
+ * send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but we do not
+ * support receiving pause frames)
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+ * other: Invalid.
+ */
+ switch (hw->fc.type) {
+ case ixgbe_fc_none:
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled,
+ * and Tx Flow control is disabled.
+ */
+ frctl_reg |= IXGBE_FCTRL_RFCE;
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is disabled,
+ * by a software over-ride.
+ */
+ rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+ break;
+ case ixgbe_fc_full:
+ /*
+ * Flow control (both Rx and Tx) is enabled by a software
+ * over-ride.
+ */
+ frctl_reg |= IXGBE_FCTRL_RFCE;
+ rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+ break;
+ default:
+ /* We should never get here. The value should be 0-3. */
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ break;
+ }
+
+ /* Enable 802.3x based flow control settings. */
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+ IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+
+ /*
+ * Check for invalid software configuration, zeros are completely
+ * invalid for all parameters used past this point, and if we enable
+ * flow control with zero water marks, we blast flow control packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Flow control structure initialized incorrectly\n");
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
+ }
+
+ /*
+ * We need to set up the Receive Threshold high and low water
+ * marks as well as (optionally) enabling the transmission of
+ * XON frames.
+ */
+ if (hw->fc.type & ixgbe_fc_tx_pause) {
+ if (hw->fc.send_xon) {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+ (hw->fc.low_water | IXGBE_FCRTL_XONE));
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+ hw->fc.low_water);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
+ (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+ return 0;
+}
+
+/**
* ixgbe_setup_mac_link_82598 - Configures MAC link settings
* @hw: pointer to hardware structure
*
@@ -252,8 +357,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
}
if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
- hw_dbg(hw,
- "Autonegotiation did not complete.\n");
+ hw_dbg(hw, "Autonegotiation did not complete.\n");
}
}
}
@@ -263,8 +367,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
- hw->fc.type = hw->fc.original_type;
- ixgbe_setup_fc(hw, 0);
+ hw->fc.original_type = hw->fc.type;
+ ixgbe_setup_fc_82598(hw, 0);
/* Add delay to filter out noises during initial link setup */
msleep(50);
@@ -277,20 +381,35 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* @hw: pointer to hardware structure
* @speed: pointer to link speed
* @link_up: true is link is up, false otherwise
+ * @link_up_wait_to_complete: bool used to wait for link up or not
*
* Reads the links register to determine if link is up and the current speed
**/
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
+static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed, bool *link_up,
+ bool link_up_wait_to_complete)
{
u32 links_reg;
+ u32 i;
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
-
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = true;
- else
- *link_up = false;
+ if (link_up_wait_to_complete) {
+ for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+ if (links_reg & IXGBE_LINKS_UP) {
+ *link_up = true;
+ break;
+ } else {
+ *link_up = false;
+ }
+ msleep(100);
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ }
+ } else {
+ if (links_reg & IXGBE_LINKS_UP)
+ *link_up = true;
+ else
+ *link_up = false;
+ }
if (links_reg & IXGBE_LINKS_SPEED)
*speed = IXGBE_LINK_SPEED_10GB_FULL;
@@ -300,6 +419,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
return 0;
}
+
/**
* ixgbe_setup_mac_link_speed_82598 - Set MAC link speed
* @hw: pointer to hardware structure
@@ -310,18 +430,18 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
- u32 speed, bool autoneg,
- bool autoneg_wait_to_complete)
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
{
s32 status = 0;
/* If speed is 10G, then check for CX4 or XAUI. */
if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
- (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4)))
+ (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg))
+ } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
- else if (autoneg) {
+ } else if (autoneg) {
/* BX mode - Autonegotiate 1G */
if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
@@ -340,7 +460,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
}
return status;
@@ -358,18 +478,17 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
/* Restart autonegotiation on PHY */
- if (hw->phy.ops.setup_link)
- status = hw->phy.ops.setup_link(hw);
+ status = hw->phy.ops.setup_link(hw);
- /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+ /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
/* Set up MAC */
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
return status;
}
@@ -383,23 +502,23 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
*
* Sets the link speed in the AUTOC register in the MAC and restarts link.
**/
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
{
- s32 status = 0;
+ s32 status;
/* Setup the PHY according to input speed */
- if (hw->phy.ops.setup_link_speed)
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
/* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
/* Set up MAC */
- hw->mac.ops.setup_link(hw);
+ ixgbe_setup_mac_link_82598(hw);
return status;
}
@@ -408,7 +527,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
* ixgbe_reset_hw_82598 - Performs hardware reset
* @hw: pointer to hardware structure
*
- * Resets the hardware by reseting the transmit and receive units, masks and
+ * Resets the hardware by resetting the transmit and receive units, masks and
* clears all interrupts, performing a PHY reset, and performing a link (MAC)
* reset.
**/
@@ -422,35 +541,44 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
u8 analog_val;
/* Call adapter stop to disable tx/rx and clear interrupts */
- ixgbe_stop_adapter(hw);
+ hw->mac.ops.stop_adapter(hw);
/*
- * Power up the Atlas TX lanes if they are currently powered down.
- * Atlas TX lanes are powered down for MAC loopback tests, but
+ * Power up the Atlas Tx lanes if they are currently powered down.
+ * Atlas Tx lanes are powered down for MAC loopback tests, but
* they are not automatically restored on reset.
*/
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
- /* Enable TX Atlas so packets can be transmitted again */
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+ /* Enable Tx Atlas so packets can be transmitted again */
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+ analog_val);
- ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &analog_val);
+ hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+ &analog_val);
analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
- ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, analog_val);
+ hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+ analog_val);
}
/* Reset PHY */
- ixgbe_reset_phy(hw);
+ if (hw->phy.reset_disable == false)
+ hw->phy.ops.reset(hw);
/*
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
@@ -503,29 +631,311 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
} else {
hw->mac.link_attach_type =
- (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
+ (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
hw->mac.link_settings_loaded = true;
}
/* Store the permanent mac address */
- ixgbe_get_mac_addr(hw, hw->mac.perm_addr);
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
return status;
}
+/**
+ * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq set index
+ **/
+s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+ rar_high &= ~IXGBE_RAH_VIND_MASK;
+ rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq clear index (not used in 82598, but elsewhere)
+ **/
+static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+ if (rar_high & IXGBE_RAH_VIND_MASK) {
+ rar_high &= ~IXGBE_RAH_VIND_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+ }
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_set_vfta_82598 - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VFTA
+ * @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on)
+{
+ u32 regindex;
+ u32 bitindex;
+ u32 bits;
+ u32 vftabyte;
+
+ if (vlan > 4095)
+ return IXGBE_ERR_PARAM;
+
+ /* Determine 32-bit word position in array */
+ regindex = (vlan >> 5) & 0x7F; /* upper seven bits */
+
+ /* Determine the location of the (VMD) queue index */
+ vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
+ bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
+
+ /* Set the nibble for VMD queue index */
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
+ bits &= (~(0x0F << bitindex));
+ bits |= (vind << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
+
+ /* Determine the location of the bit for this VLAN id */
+ bitindex = vlan & 0x1F; /* lower five bits */
+
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+ if (vlan_on)
+ /* Turn on this VLAN id */
+ bits |= (1 << bitindex);
+ else
+ /* Turn off this VLAN id */
+ bits &= ~(1 << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vfta_82598 - Clear VLAN filter table
+ * @hw: pointer to hardware structure
+ *
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
+{
+ u32 offset;
+ u32 vlanbyte;
+
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+ for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
+ 0);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_start_82598 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ **/
+static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
+{
+ ixgbe_link_speed speed = 0;
+ bool link_up = 0;
+ u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ /*
+ * Link must be up to auto-blink the LEDs on the 82598EB MAC;
+ * force it if link is down.
+ */
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+ if (!link_up) {
+ autoc_reg |= IXGBE_AUTOC_FLU;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ msleep(10);
+ }
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg |= IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ **/
+static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
+{
+ u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ autoc_reg &= ~IXGBE_AUTOC_FLU;
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg &= ~IXGBE_LED_BLINK(index);
+ led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
+ * @hw: pointer to hardware structure
+ * @reg: analog register to read
+ * @val: read value
+ *
+ * Performs read operation to Atlas analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+ u32 atlas_ctl;
+
+ IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
+ IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+ atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
+ *val = (u8)atlas_ctl;
+
+ return 0;
+}
+
+/**
+ * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
+ * @hw: pointer to hardware structure
+ * @reg: atlas register to write
+ * @val: value to write
+ *
+ * Performs write operation to Atlas analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+ u32 atlas_ctl;
+
+ atlas_ctl = (reg << 8) | val;
+ IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+{
+ s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598EB_CX4:
+ case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+ break;
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
+
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+
+ return physical_layer;
+}
+
static struct ixgbe_mac_operations mac_ops_82598 = {
- .reset = &ixgbe_reset_hw_82598,
+ .init_hw = &ixgbe_init_hw_generic,
+ .reset_hw = &ixgbe_reset_hw_82598,
+ .start_hw = &ixgbe_start_hw_generic,
+ .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82598,
+ .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+ .get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .stop_adapter = &ixgbe_stop_adapter_generic,
+ .read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
+ .write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
- .check_link = &ixgbe_check_mac_link_82598,
.setup_link_speed = &ixgbe_setup_mac_link_speed_82598,
- .get_link_settings = &ixgbe_get_link_settings_82598,
+ .check_link = &ixgbe_check_mac_link_82598,
+ .get_link_capabilities = &ixgbe_get_link_capabilities_82598,
+ .led_on = &ixgbe_led_on_generic,
+ .led_off = &ixgbe_led_off_generic,
+ .blink_led_start = &ixgbe_blink_led_start_82598,
+ .blink_led_stop = &ixgbe_blink_led_stop_82598,
+ .set_rar = &ixgbe_set_rar_generic,
+ .clear_rar = &ixgbe_clear_rar_generic,
+ .set_vmdq = &ixgbe_set_vmdq_82598,
+ .clear_vmdq = &ixgbe_clear_vmdq_82598,
+ .init_rx_addrs = &ixgbe_init_rx_addrs_generic,
+ .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic,
+ .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic,
+ .enable_mc = &ixgbe_enable_mc_generic,
+ .disable_mc = &ixgbe_disable_mc_generic,
+ .clear_vfta = &ixgbe_clear_vfta_82598,
+ .set_vfta = &ixgbe_set_vfta_82598,
+ .setup_fc = &ixgbe_setup_fc_82598,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
+ .init_params = &ixgbe_init_eeprom_params_generic,
+ .read = &ixgbe_read_eeprom_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .update_checksum = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82598 = {
+ .identify = &ixgbe_identify_phy_generic,
+ /* .identify_sfp = &ixgbe_identify_sfp_module_generic, */
+ .reset = &ixgbe_reset_phy_generic,
+ .read_reg = &ixgbe_read_phy_reg_generic,
+ .write_reg = &ixgbe_write_phy_reg_generic,
+ .setup_link = &ixgbe_setup_phy_link_generic,
+ .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
};
struct ixgbe_info ixgbe_82598_info = {
.mac = ixgbe_mac_82598EB,
.get_invariants = &ixgbe_get_invariants_82598,
.mac_ops = &mac_ops_82598,
+ .eeprom_ops = &eeprom_ops_82598,
+ .phy_ops = &phy_ops_82598,
};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 9c0d0a1..f67c684 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -33,20 +32,28 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw);
-
static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw);
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+ u16 count);
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw);
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
/**
- * ixgbe_start_hw - Prepare hardware for TX/RX
+ * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
*
* Starts the hardware by filling the bus info structure and media type, clears
@@ -54,7 +61,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
* table, VLAN filter table, calls routine to set up link and flow control
* settings, and leaves transmit and receive units disabled and uninitialized
**/
-s32 ixgbe_start_hw(struct ixgbe_hw *hw)
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
{
u32 ctrl_ext;
@@ -62,22 +69,22 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
hw->phy.media_type = hw->mac.ops.get_media_type(hw);
/* Identify the PHY */
- ixgbe_identify_phy(hw);
+ hw->phy.ops.identify(hw);
/*
* Store MAC address from RAR0, clear receive address registers, and
* clear the multicast table
*/
- ixgbe_init_rx_addrs(hw);
+ hw->mac.ops.init_rx_addrs(hw);
/* Clear the VLAN filter table */
- ixgbe_clear_vfta(hw);
+ hw->mac.ops.clear_vfta(hw);
/* Set up link */
hw->mac.ops.setup_link(hw);
/* Clear statistics registers */
- ixgbe_clear_hw_cntrs(hw);
+ hw->mac.ops.clear_hw_cntrs(hw);
/* Set No Snoop Disable */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -92,34 +99,34 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
}
/**
- * ixgbe_init_hw - Generic hardware initialization
+ * ixgbe_init_hw_generic - Generic hardware initialization
* @hw: pointer to hardware structure
*
- * Initialize the hardware by reseting the hardware, filling the bus info
+ * Initialize the hardware by resetting the hardware, filling the bus info
* structure and media type, clears all on chip counters, initializes receive
* address registers, multicast table, VLAN filter table, calls routine to set
* up link and flow control settings, and leaves transmit and receive units
* disabled and uninitialized
**/
-s32 ixgbe_init_hw(struct ixgbe_hw *hw)
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
{
/* Reset the hardware */
- hw->mac.ops.reset(hw);
+ hw->mac.ops.reset_hw(hw);
/* Start the HW */
- ixgbe_start_hw(hw);
+ hw->mac.ops.start_hw(hw);
return 0;
}
/**
- * ixgbe_clear_hw_cntrs - Generic clear hardware counters
+ * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
* @hw: pointer to hardware structure
*
* Clears all hardware statistics counters by reading them from the hardware
* Statistics counters are clear on read.
**/
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
{
u16 i = 0;
@@ -191,7 +198,36 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
}
/**
- * ixgbe_get_mac_addr - Generic get MAC address
+ * ixgbe_read_pba_num_generic - Reads part number from EEPROM
+ * @hw: pointer to hardware structure
+ * @pba_num: stores the part number from the EEPROM
+ *
+ * Reads the part number from the EEPROM.
+ **/
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
+{
+ s32 ret_val;
+ u16 data;
+
+ ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ *pba_num = (u32)(data << 16);
+
+ ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ *pba_num |= data;
+
+ return 0;
+}
+
+/**
+ * ixgbe_get_mac_addr_generic - Generic get MAC address
* @hw: pointer to hardware structure
* @mac_addr: Adapter MAC address
*
@@ -199,7 +235,7 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
* A reset of the adapter must be performed prior to calling this function
* in order for the MAC address to have been loaded from the EEPROM into RAR0
**/
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
{
u32 rar_high;
u32 rar_low;
@@ -217,30 +253,8 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
return 0;
}
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
-{
- s32 ret_val;
- u16 data;
-
- ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM0_PTR, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *part_num = (u32)(data << 16);
-
- ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM1_PTR, &data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *part_num |= data;
-
- return 0;
-}
-
/**
- * ixgbe_stop_adapter - Generic stop TX/RX units
+ * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
* @hw: pointer to hardware structure
*
* Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
@@ -248,7 +262,7 @@ s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
* the shared code and drivers to determine if the adapter is in a stopped
* state and should not touch the hardware.
**/
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
{
u32 number_of_queues;
u32 reg_val;
@@ -264,6 +278,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
reg_val &= ~(IXGBE_RXCTRL_RXEN);
IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
+ IXGBE_WRITE_FLUSH(hw);
msleep(2);
/* Clear interrupt mask to stop from interrupts being generated */
@@ -273,7 +288,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
IXGBE_READ_REG(hw, IXGBE_EICR);
/* Disable the transmit unit. Each queue must be disabled. */
- number_of_queues = hw->mac.num_tx_queues;
+ number_of_queues = hw->mac.max_tx_queues;
for (i = 0; i < number_of_queues; i++) {
reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
if (reg_val & IXGBE_TXDCTL_ENABLE) {
@@ -282,15 +297,22 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
}
}
+ /*
+ * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+ * access and verify no pending requests
+ */
+ if (ixgbe_disable_pcie_master(hw) != 0)
+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+
return 0;
}
/**
- * ixgbe_led_on - Turns on the software controllable LEDs.
+ * ixgbe_led_on_generic - Turns on the software controllable LEDs.
* @hw: pointer to hardware structure
* @index: led number to turn on
**/
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
{
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
@@ -304,11 +326,11 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
}
/**
- * ixgbe_led_off - Turns off the software controllable LEDs.
+ * ixgbe_led_off_generic - Turns off the software controllable LEDs.
* @hw: pointer to hardware structure
* @index: led number to turn off
**/
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
{
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
@@ -321,15 +343,14 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
return 0;
}
-
/**
- * ixgbe_init_eeprom - Initialize EEPROM params
+ * ixgbe_init_eeprom_params_generic - Initialize EEPROM params
* @hw: pointer to hardware structure
*
* Initializes the EEPROM parameters ixgbe_eeprom_info within the
* ixgbe_hw struct in order to set up EEPROM access.
**/
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
{
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
u32 eec;
@@ -337,6 +358,9 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
if (eeprom->type == ixgbe_eeprom_uninitialized) {
eeprom->type = ixgbe_eeprom_none;
+ /* Set default semaphore delay to 10ms which is a well
+ * tested value */
+ eeprom->semaphore_delay = 10;
/*
* Check for EEPROM present first.
@@ -369,18 +393,85 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
}
/**
- * ixgbe_read_eeprom - Read EEPROM word using EERD
+ * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be read
+ * @data: read 16 bit value from EEPROM
+ *
+ * Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status;
+ u16 word_in;
+ u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ /* Prepare the EEPROM for reading */
+ status = ixgbe_acquire_eeprom(hw);
+
+ if (status == 0) {
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ if (status == 0) {
+ ixgbe_standby_eeprom(hw);
+
+ /*
+ * Some SPI eeproms use the 8th address bit embedded in the
+ * opcode
+ */
+ if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ *data = (word_in >> 8) | (word_in << 8);
+
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_read_eeprom_generic - Read EEPROM word using EERD
* @hw: pointer to hardware structure
* @offset: offset of word in the EEPROM to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
u32 eerd;
s32 status;
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) +
IXGBE_EEPROM_READ_REG_START;
@@ -389,10 +480,11 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
if (status == 0)
*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
- IXGBE_EEPROM_READ_REG_DATA);
+ IXGBE_EEPROM_READ_REG_DATA);
else
hw_dbg(hw, "Eeprom read timed out\n");
+out:
return status;
}
@@ -420,6 +512,58 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
+ * @hw: pointer to hardware structure
+ *
+ * Prepares EEPROM for access using bit-bang method. This function should
+ * be called before issuing a command to the EEPROM.
+ **/
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u32 eec;
+ u32 i;
+
+ if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
+ status = IXGBE_ERR_SWFW_SYNC;
+
+ if (status == 0) {
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /* Request EEPROM Access */
+ eec |= IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+ for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ if (eec & IXGBE_EEC_GNT)
+ break;
+ udelay(5);
+ }
+
+ /* Release if grant not acquired */
+ if (!(eec & IXGBE_EEC_GNT)) {
+ eec &= ~IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ hw_dbg(hw, "Could not acquire EEPROM grant\n");
+
+ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ /* Setup EEPROM for Read/Write */
+ if (status == 0) {
+ /* Clear CS and SK */
+ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+ }
+ return status;
+}
+
+/**
* ixgbe_get_eeprom_semaphore - Get hardware semaphore
* @hw: pointer to hardware structure
*
@@ -475,7 +619,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
*/
if (i >= timeout) {
hw_dbg(hw, "Driver can't access the Eeprom - Semaphore "
- "not granted.\n");
+ "not granted.\n");
ixgbe_release_eeprom_semaphore(hw);
status = IXGBE_ERR_EEPROM;
}
@@ -503,6 +647,217 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_ready_eeprom - Polls for EEPROM ready
+ * @hw: pointer to hardware structure
+ **/
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u16 i;
+ u8 spi_stat_reg;
+
+ /*
+ * Read "Status Register" repeatedly until the LSB is cleared. The
+ * EEPROM will signal that the command has been completed by clearing
+ * bit 0 of the internal status register. If it's not cleared within
+ * 5 milliseconds, then error out.
+ */
+ for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
+ ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
+ spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
+ if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
+ break;
+
+ udelay(5);
+ ixgbe_standby_eeprom(hw);
+ };
+
+ /*
+ * On some parts, SPI write time could vary from 0-20mSec on 3.3V
+ * devices (and only 0-5mSec on 5V devices)
+ */
+ if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
+ hw_dbg(hw, "SPI EEPROM Status error\n");
+ status = IXGBE_ERR_EEPROM;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
+{
+ u32 eec;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /* Toggle CS to flush commands */
+ eec |= IXGBE_EEC_CS;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+ eec &= ~IXGBE_EEC_CS;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
+ * @hw: pointer to hardware structure
+ * @data: data to send to the EEPROM
+ * @count: number of bits to shift out
+ **/
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+ u16 count)
+{
+ u32 eec;
+ u32 mask;
+ u32 i;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ /*
+ * Mask is used to shift "count" bits of "data" out to the EEPROM
+ * one bit at a time. Determine the starting bit based on count
+ */
+ mask = 0x01 << (count - 1);
+
+ for (i = 0; i < count; i++) {
+ /*
+ * A "1" is shifted out to the EEPROM by setting bit "DI" to a
+ * "1", and then raising and then lowering the clock (the SK
+ * bit controls the clock input to the EEPROM). A "0" is
+ * shifted out to the EEPROM by setting "DI" to "0" and then
+ * raising and then lowering the clock.
+ */
+ if (data & mask)
+ eec |= IXGBE_EEC_DI;
+ else
+ eec &= ~IXGBE_EEC_DI;
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+
+ udelay(1);
+
+ ixgbe_raise_eeprom_clk(hw, &eec);
+ ixgbe_lower_eeprom_clk(hw, &eec);
+
+ /*
+ * Shift mask to signify next bit of data to shift in to the
+ * EEPROM
+ */
+ mask = mask >> 1;
+ };
+
+ /* We leave the "DI" bit set to "0" when we leave this routine. */
+ eec &= ~IXGBE_EEC_DI;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
+ * @hw: pointer to hardware structure
+ **/
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
+{
+ u32 eec;
+ u32 i;
+ u16 data = 0;
+
+ /*
+ * In order to read a register from the EEPROM, we need to shift
+ * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
+ * the clock input to the EEPROM (setting the SK bit), and then reading
+ * the value of the "DO" bit. During this "shifting in" process the
+ * "DI" bit should always be clear.
+ */
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
+
+ for (i = 0; i < count; i++) {
+ data = data << 1;
+ ixgbe_raise_eeprom_clk(hw, &eec);
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec &= ~(IXGBE_EEC_DI);
+ if (eec & IXGBE_EEC_DO)
+ data |= 1;
+
+ ixgbe_lower_eeprom_clk(hw, &eec);
+ }
+
+ return data;
+}
+
+/**
+ * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eec: EEC register's current value
+ **/
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+ /*
+ * Raise the clock input to the EEPROM
+ * (setting the SK bit), then delay
+ */
+ *eec = *eec | IXGBE_EEC_SK;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
+ * @hw: pointer to hardware structure
+ * @eecd: EECD's current value
+ **/
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+ /*
+ * Lower the clock input to the EEPROM (clearing the SK bit), then
+ * delay
+ */
+ *eec = *eec & ~IXGBE_EEC_SK;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+}
+
+/**
+ * ixgbe_release_eeprom - Release EEPROM, release semaphores
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
+{
+ u32 eec;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+ eec |= IXGBE_EEC_CS; /* Pull CS high */
+ eec &= ~IXGBE_EEC_SK; /* Lower SCK */
+
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+
+ udelay(1);
+
+ /* Stop requesting EEPROM access */
+ eec &= ~IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+}
+
+/**
* ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
* @hw: pointer to hardware structure
**/
@@ -517,7 +872,7 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
/* Include 0x0-0x3F in the checksum */
for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
- if (ixgbe_read_eeprom(hw, i, &word) != 0) {
+ if (hw->eeprom.ops.read(hw, i, &word) != 0) {
hw_dbg(hw, "EEPROM read failed\n");
break;
}
@@ -526,15 +881,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
/* Include all data from pointers except for the fw pointer */
for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
- ixgbe_read_eeprom(hw, i, &pointer);
+ hw->eeprom.ops.read(hw, i, &pointer);
/* Make sure the pointer seems valid */
if (pointer != 0xFFFF && pointer != 0) {
- ixgbe_read_eeprom(hw, pointer, &length);
+ hw->eeprom.ops.read(hw, pointer, &length);
if (length != 0xFFFF && length != 0) {
for (j = pointer+1; j <= pointer+length; j++) {
- ixgbe_read_eeprom(hw, j, &word);
+ hw->eeprom.ops.read(hw, j, &word);
checksum += word;
}
}
@@ -547,14 +902,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
}
/**
- * ixgbe_validate_eeprom_checksum - Validate EEPROM checksum
+ * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
* @hw: pointer to hardware structure
* @checksum_val: calculated checksum
*
* Performs checksum calculation and validates the EEPROM checksum. If the
* caller does not need checksum_val, the value can be NULL.
**/
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+ u16 *checksum_val)
{
s32 status;
u16 checksum;
@@ -565,12 +921,12 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
- status = ixgbe_read_eeprom(hw, 0, &checksum);
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
if (status == 0) {
checksum = ixgbe_calc_eeprom_checksum(hw);
- ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+ hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
/*
* Verify read checksum from EEPROM is the same as
@@ -590,6 +946,33 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
}
/**
+ * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u16 checksum;
+
+ /*
+ * Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+ if (status == 0) {
+ checksum = ixgbe_calc_eeprom_checksum(hw);
+ status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
+ checksum);
+ } else {
+ hw_dbg(hw, "EEPROM read failed\n");
+ }
+
+ return status;
+}
+
+/**
* ixgbe_validate_mac_addr - Validate MAC address
* @mac_addr: pointer to MAC address.
*
@@ -607,58 +990,137 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
status = IXGBE_ERR_INVALID_MAC_ADDR;
/* Reject the zero address */
else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
- mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
+ mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
status = IXGBE_ERR_INVALID_MAC_ADDR;
return status;
}
/**
- * ixgbe_set_rar - Set RX address register
+ * ixgbe_set_rar_generic - Set Rx address register
* @hw: pointer to hardware structure
- * @addr: Address to put into receive address register
* @index: Receive address register to write
- * @vind: Vind to set RAR to
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq "set" or "pool" index
* @enable_addr: set flag that address is active
*
* Puts an ethernet address into a receive address register.
**/
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
- u32 enable_addr)
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr)
{
u32 rar_low, rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
- /*
- * HW expects these in little endian so we reverse the byte order from
- * network order (big endian) to little endian
- */
- rar_low = ((u32)addr[0] |
- ((u32)addr[1] << 8) |
- ((u32)addr[2] << 16) |
- ((u32)addr[3] << 24));
+ /* setup VMDq pool selection before this RAR gets enabled */
+ hw->mac.ops.set_vmdq(hw, index, vmdq);
- rar_high = ((u32)addr[4] |
- ((u32)addr[5] << 8) |
- ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK));
+ /* Make sure we are using a valid rar index range */
+ if (index < rar_entries) {
+ /*
+ * HW expects these in little endian so we reverse the byte
+ * order from network order (big endian) to little endian
+ */
+ rar_low = ((u32)addr[0] |
+ ((u32)addr[1] << 8) |
+ ((u32)addr[2] << 16) |
+ ((u32)addr[3] << 24));
+ /*
+ * Some parts put the VMDq setting in the extra RAH bits,
+ * so save everything except the lower 16 bits that hold part
+ * of the address and the address valid bit.
+ */
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+ rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
- if (enable_addr != 0)
- rar_high |= IXGBE_RAH_AV;
+ if (enable_addr != 0)
+ rar_high |= IXGBE_RAH_AV;
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
- IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", index);
+ }
return 0;
}
/**
- * ixgbe_init_rx_addrs - Initializes receive address filters.
+ * ixgbe_clear_rar_generic - Remove Rx address register
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
+ *
+ * Clears an ethernet address from a receive address register.
+ **/
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ /* Make sure we are using a valid rar index range */
+ if (index < rar_entries) {
+ /*
+ * Some parts put the VMDq setting in the extra RAH bits,
+ * so save everything except the lower 16 bits that hold part
+ * of the address and the address valid bit.
+ */
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", index);
+ }
+
+ /* clear VMDq pool/queue selection for this RAR */
+ hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
+
+ return 0;
+}
+
+/**
+ * ixgbe_enable_rar - Enable Rx address register
+ * @hw: pointer to hardware structure
+ * @index: index into the RAR table
+ *
+ * Enables the select receive address register.
+ **/
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high |= IXGBE_RAH_AV;
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ * ixgbe_disable_rar - Disable Rx address register
+ * @hw: pointer to hardware structure
+ * @index: index into the RAR table
+ *
+ * Disables the select receive address register.
+ **/
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
+{
+ u32 rar_high;
+
+ rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+ rar_high &= (~IXGBE_RAH_AV);
+ IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ * ixgbe_init_rx_addrs_generic - Initializes receive address filters.
* @hw: pointer to hardware structure
*
* Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
+ * of the receive address registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
**/
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
{
u32 i;
u32 rar_entries = hw->mac.num_rar_entries;
@@ -671,29 +1133,30 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
if (ixgbe_validate_mac_addr(hw->mac.addr) ==
IXGBE_ERR_INVALID_MAC_ADDR) {
/* Get the MAC address from the RAR0 for later reference */
- ixgbe_get_mac_addr(hw, hw->mac.addr);
+ hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
+ hw->mac.addr[0], hw->mac.addr[1],
+ hw->mac.addr[2]);
hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
+ hw->mac.addr[4], hw->mac.addr[5]);
} else {
/* Setup the receive address. */
hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");
hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",
- hw->mac.addr[0], hw->mac.addr[1],
- hw->mac.addr[2]);
+ hw->mac.addr[0], hw->mac.addr[1],
+ hw->mac.addr[2]);
hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
- hw->mac.addr[4], hw->mac.addr[5]);
+ hw->mac.addr[4], hw->mac.addr[5]);
- ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
}
+ hw->addr_ctrl.overflow_promisc = 0;
hw->addr_ctrl.rar_used_count = 1;
/* Zero out the other receive addresses. */
- hw_dbg(hw, "Clearing RAR[1-15]\n");
+ hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1);
for (i = 1; i < rar_entries; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -708,6 +1171,9 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
for (i = 0; i < hw->mac.mcft_size; i++)
IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
+ if (hw->mac.ops.init_uta_tables)
+ hw->mac.ops.init_uta_tables(hw);
+
return 0;
}
@@ -718,7 +1184,7 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
*
* Adds it to unused receive address register or goes into promiscuous mode.
**/
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
{
u32 rar_entries = hw->mac.num_rar_entries;
u32 rar;
@@ -733,7 +1199,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
if (hw->addr_ctrl.rar_used_count < rar_entries) {
rar = hw->addr_ctrl.rar_used_count -
hw->addr_ctrl.mc_addr_in_rar_count;
- ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
hw->addr_ctrl.rar_used_count++;
} else {
@@ -744,7 +1210,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
}
/**
- * ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses
+ * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
* @hw: pointer to hardware structure
* @addr_list: the list of new addresses
* @addr_count: number of addresses
@@ -757,7 +1223,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
* Drivers using secondary unicast addresses must set user_set_promisc when
* manually putting the device into promiscuous mode.
**/
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
u32 addr_count, ixgbe_mc_addr_itr next)
{
u8 *addr;
@@ -787,7 +1253,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
for (i = 0; i < addr_count; i++) {
hw_dbg(hw, " Adding the secondary addresses:\n");
addr = next(hw, &addr_list, &vmdq);
- ixgbe_add_uc_addr(hw, addr);
+ ixgbe_add_uc_addr(hw, addr, vmdq);
}
if (hw->addr_ctrl.overflow_promisc) {
@@ -808,7 +1274,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
}
}
- hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n");
+ hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n");
return 0;
}
@@ -821,7 +1287,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
* bit-vector to set in the multicast table. The hardware uses 12 bits, from
* incoming rx multicast addresses, to determine the bit-vector to check in
* the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- * by the MO field of the MCSTCTRL. The MO field is set during initalization
+ * by the MO field of the MCSTCTRL. The MO field is set during initialization
* to mc_filter_type.
**/
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
@@ -829,19 +1295,19 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
u32 vector = 0;
switch (hw->mac.mc_filter_type) {
- case 0: /* use bits [47:36] of the address */
+ case 0: /* use bits [47:36] of the address */
vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
break;
- case 1: /* use bits [46:35] of the address */
+ case 1: /* use bits [46:35] of the address */
vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
break;
- case 2: /* use bits [45:34] of the address */
+ case 2: /* use bits [45:34] of the address */
vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
break;
- case 3: /* use bits [43:32] of the address */
+ case 3: /* use bits [43:32] of the address */
vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
break;
- default: /* Invalid mc_filter_type */
+ default: /* Invalid mc_filter_type */
hw_dbg(hw, "MC filter type param set incorrectly\n");
break;
}
@@ -896,20 +1362,21 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
{
u32 rar_entries = hw->mac.num_rar_entries;
+ u32 rar;
hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
- mc_addr[0], mc_addr[1], mc_addr[2],
- mc_addr[3], mc_addr[4], mc_addr[5]);
+ mc_addr[0], mc_addr[1], mc_addr[2],
+ mc_addr[3], mc_addr[4], mc_addr[5]);
/*
* Place this multicast address in the RAR if there is room,
* else put it in the MTA
*/
if (hw->addr_ctrl.rar_used_count < rar_entries) {
- ixgbe_set_rar(hw, hw->addr_ctrl.rar_used_count,
- mc_addr, 0, IXGBE_RAH_AV);
- hw_dbg(hw, "Added a multicast address to RAR[%d]\n",
- hw->addr_ctrl.rar_used_count);
+ /* use RAR from the end up for multicast */
+ rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1;
+ hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV);
+ hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar);
hw->addr_ctrl.rar_used_count++;
hw->addr_ctrl.mc_addr_in_rar_count++;
} else {
@@ -920,19 +1387,19 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
}
/**
- * ixgbe_update_mc_addr_list - Updates MAC list of multicast addresses
+ * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
* @hw: pointer to hardware structure
* @mc_addr_list: the list of new multicast addresses
* @mc_addr_count: number of addresses
* @next: iterator function to walk the multicast address list
*
* The given list replaces any existing list. Clears the MC addrs from receive
- * address registers and the multicast table. Uses unsed receive address
+ * address registers and the multicast table. Uses unused receive address
* registers for the first multicast addresses, and hashes the rest into the
* multicast table.
**/
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next)
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count, ixgbe_mc_addr_itr next)
{
u32 i;
u32 rar_entries = hw->mac.num_rar_entries;
@@ -948,7 +1415,8 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
hw->addr_ctrl.mta_in_use = 0;
/* Zero out the other receive addresses. */
- hw_dbg(hw, "Clearing RAR[1-15]\n");
+ hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count,
+ rar_entries - 1);
for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -968,190 +1436,55 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
/* Enable mta */
if (hw->addr_ctrl.mta_in_use > 0)
IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
- IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
+ IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
- hw_dbg(hw, "ixgbe_update_mc_addr_list Complete\n");
+ hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n");
return 0;
}
/**
- * ixgbe_clear_vfta - Clear VLAN filter table
+ * ixgbe_enable_mc_generic - Enable multicast address in RAR
* @hw: pointer to hardware structure
*
- * Clears the VLAN filer table, and the VMDq index associated with the filter
+ * Enables multicast address in RAR and the use of the multicast hash table.
**/
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
{
- u32 offset;
- u32 vlanbyte;
+ u32 i;
+ u32 rar_entries = hw->mac.num_rar_entries;
+ struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+ if (a->mc_addr_in_rar_count > 0)
+ for (i = (rar_entries - a->mc_addr_in_rar_count);
+ i < rar_entries; i++)
+ ixgbe_enable_rar(hw, i);
- for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
- for (offset = 0; offset < hw->mac.vft_size; offset++)
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
- 0);
+ if (a->mta_in_use > 0)
+ IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
+ hw->mac.mc_filter_type);
return 0;
}
/**
- * ixgbe_set_vfta - Set VLAN filter table
+ * ixgbe_disable_mc_generic - Disable multicast address in RAR
* @hw: pointer to hardware structure
- * @vlan: VLAN id to write to VLAN filter
- * @vind: VMDq output index that maps queue to VLAN id in VFTA
- * @vlan_on: boolean flag to turn on/off VLAN in VFTA
*
- * Turn on/off specified VLAN in the VLAN filter table.
+ * Disables multicast address in RAR and the use of the multicast hash table.
**/
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind,
- bool vlan_on)
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
{
- u32 VftaIndex;
- u32 BitOffset;
- u32 VftaReg;
- u32 VftaByte;
-
- /* Determine 32-bit word position in array */
- VftaIndex = (vlan >> 5) & 0x7F; /* upper seven bits */
-
- /* Determine the location of the (VMD) queue index */
- VftaByte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
- BitOffset = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */
-
- /* Set the nibble for VMD queue index */
- VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex));
- VftaReg &= (~(0x0F << BitOffset));
- VftaReg |= (vind << BitOffset);
- IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex), VftaReg);
-
- /* Determine the location of the bit for this VLAN id */
- BitOffset = vlan & 0x1F; /* lower five bits */
-
- VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTA(VftaIndex));
- if (vlan_on)
- /* Turn on this VLAN id */
- VftaReg |= (1 << BitOffset);
- else
- /* Turn off this VLAN id */
- VftaReg &= ~(1 << BitOffset);
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(VftaIndex), VftaReg);
-
- return 0;
-}
-
-/**
- * ixgbe_setup_fc - Configure flow control settings
- * @hw: pointer to hardware structure
- * @packetbuf_num: packet buffer number (0-7)
- *
- * Configures the flow control settings based on SW configuration.
- * This function is used for 802.3x flow control configuration only.
- **/
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
-{
- u32 frctl_reg;
- u32 rmcs_reg;
-
- if (packetbuf_num < 0 || packetbuf_num > 7)
- hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
- "is 0-7\n", packetbuf_num);
-
- frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
-
- rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
- rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
-
- /*
- * 10 gig parts do not have a word in the EEPROM to determine the
- * default flow control setting, so we explicitly set it to full.
- */
- if (hw->fc.type == ixgbe_fc_default)
- hw->fc.type = ixgbe_fc_full;
-
- /*
- * We want to save off the original Flow Control configuration just in
- * case we get disconnected and then reconnected into a different hub
- * or switch with different Flow Control capabilities.
- */
- hw->fc.type = hw->fc.original_type;
-
- /*
- * The possible values of the "flow_control" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames but not
- * send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we do not
- * support receiving pause frames)
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- * other: Invalid.
- */
- switch (hw->fc.type) {
- case ixgbe_fc_none:
- break;
- case ixgbe_fc_rx_pause:
- /*
- * RX Flow control is enabled,
- * and TX Flow control is disabled.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
- break;
- case ixgbe_fc_tx_pause:
- /*
- * TX Flow control is enabled, and RX Flow control is disabled,
- * by a software over-ride.
- */
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- case ixgbe_fc_full:
- /*
- * Flow control (both RX and TX) is enabled by a software
- * over-ride.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
- rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
- break;
- default:
- /* We should never get here. The value should be 0-3. */
- hw_dbg(hw, "Flow control param set incorrectly\n");
- break;
- }
+ u32 i;
+ u32 rar_entries = hw->mac.num_rar_entries;
+ struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
- /* Enable 802.3x based flow control settings. */
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
- IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+ if (a->mc_addr_in_rar_count > 0)
+ for (i = (rar_entries - a->mc_addr_in_rar_count);
+ i < rar_entries; i++)
+ ixgbe_disable_rar(hw, i);
- /*
- * Check for invalid software configuration, zeros are completely
- * invalid for all parameters used past this point, and if we enable
- * flow control with zero water marks, we blast flow control packets.
- */
- if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Flow control structure initialized incorrectly\n");
- return IXGBE_ERR_INVALID_LINK_SETTINGS;
- }
-
- /*
- * We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- if (hw->fc.type & ixgbe_fc_tx_pause) {
- if (hw->fc.send_xon) {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- (hw->fc.low_water | IXGBE_FCRTL_XONE));
- } else {
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
- hw->fc.low_water);
- }
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
- (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
- }
-
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+ if (a->mta_in_use > 0)
+ IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
return 0;
}
@@ -1167,13 +1500,24 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
**/
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
{
- u32 ctrl;
- s32 i;
+ u32 i;
+ u32 reg_val;
+ u32 number_of_queues;
s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
- ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
- ctrl |= IXGBE_CTRL_GIO_DIS;
- IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+ /* Disable the receive unit by stopping each queue */
+ number_of_queues = hw->mac.max_rx_queues;
+ for (i = 0; i < number_of_queues; i++) {
+ reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+ if (reg_val & IXGBE_RXDCTL_ENABLE) {
+ reg_val &= ~IXGBE_RXDCTL_ENABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
+ }
+ }
+
+ reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ reg_val |= IXGBE_CTRL_GIO_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
@@ -1188,11 +1532,11 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
/**
- * ixgbe_acquire_swfw_sync - Aquire SWFW semaphore
+ * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
* @hw: pointer to hardware structure
- * @mask: Mask to specify wich semaphore to acquire
+ * @mask: Mask to specify which semaphore to acquire
*
- * Aquires the SWFW semaphore throught the GSSR register for the specified
+ * Acquires the SWFW semaphore thought the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash)
**/
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1234,9 +1578,9 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
/**
* ixgbe_release_swfw_sync - Release SWFW semaphore
* @hw: pointer to hardware structure
- * @mask: Mask to specify wich semaphore to release
+ * @mask: Mask to specify which semaphore to release
*
- * Releases the SWFW semaphore throught the GSSR register for the specified
+ * Releases the SWFW semaphore thought the GSSR register for the specified
* function (CSR, PHY0, PHY1, EEPROM, Flash)
**/
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1253,45 +1597,3 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
ixgbe_release_eeprom_semaphore(hw);
}
-/**
- * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: analog register to read
- * @val: read value
- *
- * Performs write operation to analog register specified.
- **/
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
- u32 atlas_ctl;
-
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
- IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
- atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
- *val = (u8)atlas_ctl;
-
- return 0;
-}
-
-/**
- * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
- * @hw: pointer to hardware structure
- * @reg: atlas register to write
- * @val: value to write
- *
- * Performs write operation to Atlas analog register specified.
- **/
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
- u32 atlas_ctl;
-
- atlas_ctl = (reg << 8) | val;
- IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
- IXGBE_WRITE_FLUSH(hw);
- udelay(10);
-
- return 0;
-}
-
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index c75ecba..192f8d0 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -31,36 +30,45 @@
#include "ixgbe_type.h"
-s32 ixgbe_init_hw(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw(struct ixgbe_hw *hw);
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr);
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw);
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num);
-
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw);
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
-
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
- u32 enable_addr);
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list,
- u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
-s32 ixgbe_validate_mac_addr(u8 *mac_addr);
-
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
+
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+ u16 *data);
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+ u16 *checksum_val);
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr);
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count,
+ ixgbe_mc_addr_itr func);
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
+ u32 addr_count, ixgbe_mc_addr_itr func);
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_validate_mac_addr(u8 *mac_addr);
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask);
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 61c000e..81a9c4b 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -48,7 +47,7 @@ struct ixgbe_stats {
};
#define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \
- offsetof(struct ixgbe_adapter, m)
+ offsetof(struct ixgbe_adapter, m)
static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_packets", IXGBE_STAT(net_stats.rx_packets)},
{"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
@@ -95,14 +94,15 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
};
#define IXGBE_QUEUE_STATS_LEN \
- ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
- ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
- (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
+ ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
+ ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
+ (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
+#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
static int ixgbe_get_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+ struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -114,7 +114,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
if (hw->phy.media_type == ixgbe_media_type_copper) {
ecmd->supported |= (SUPPORTED_1000baseT_Full |
- SUPPORTED_TP | SUPPORTED_Autoneg);
+ SUPPORTED_TP | SUPPORTED_Autoneg);
ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
@@ -126,14 +126,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
+ ADVERTISED_FIBRE);
ecmd->port = PORT_FIBRE;
+ ecmd->autoneg = AUTONEG_DISABLE;
}
- adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up);
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (link_up) {
ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
- SPEED_10000 : SPEED_1000;
+ SPEED_10000 : SPEED_1000;
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
@@ -144,7 +145,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
}
static int ixgbe_set_settings(struct net_device *netdev,
- struct ethtool_cmd *ecmd)
+ struct ethtool_cmd *ecmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -164,7 +165,7 @@ static int ixgbe_set_settings(struct net_device *netdev,
}
static void ixgbe_get_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -182,7 +183,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
}
static int ixgbe_set_pauseparam(struct net_device *netdev,
- struct ethtool_pauseparam *pause)
+ struct ethtool_pauseparam *pause)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -241,7 +242,7 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
if (data)
netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
else
- netdev->features &= ~NETIF_F_IP_CSUM;
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
return 0;
}
@@ -281,7 +282,7 @@ static int ixgbe_get_regs_len(struct net_device *netdev)
#define IXGBE_GET_STAT(_A_, _R_) _A_->stats._R_
static void ixgbe_get_regs(struct net_device *netdev,
- struct ethtool_regs *regs, void *p)
+ struct ethtool_regs *regs, void *p)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -315,7 +316,9 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC);
/* Interrupt */
- regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICR);
+ /* don't read EICR because it can clear interrupt causes, instead
+ * read EICS which is a shadow but doesn't clear EICR */
+ regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICS);
regs_buff[19] = IXGBE_READ_REG(hw, IXGBE_EICS);
regs_buff[20] = IXGBE_READ_REG(hw, IXGBE_EIMS);
regs_buff[21] = IXGBE_READ_REG(hw, IXGBE_EIMC);
@@ -325,7 +328,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[25] = IXGBE_READ_REG(hw, IXGBE_IVAR(0));
regs_buff[26] = IXGBE_READ_REG(hw, IXGBE_MSIXT);
regs_buff[27] = IXGBE_READ_REG(hw, IXGBE_MSIXPBA);
- regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL);
+ regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL(0));
regs_buff[29] = IXGBE_READ_REG(hw, IXGBE_GPIE);
/* Flow Control */
@@ -371,7 +374,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[482 + i] = IXGBE_READ_REG(hw, IXGBE_RAL(i));
for (i = 0; i < 16; i++)
regs_buff[498 + i] = IXGBE_READ_REG(hw, IXGBE_RAH(i));
- regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE);
+ regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0));
regs_buff[515] = IXGBE_READ_REG(hw, IXGBE_FCTRL);
regs_buff[516] = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
regs_buff[517] = IXGBE_READ_REG(hw, IXGBE_MCSTCTRL);
@@ -419,7 +422,6 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
- /* DCE */
regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
@@ -539,21 +541,17 @@ static void ixgbe_get_regs(struct net_device *netdev,
/* Diagnostic */
regs_buff[1071] = IXGBE_READ_REG(hw, IXGBE_RDSTATCTL);
for (i = 0; i < 8; i++)
- regs_buff[1072] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
+ regs_buff[1072 + i] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
regs_buff[1080] = IXGBE_READ_REG(hw, IXGBE_RDHMPN);
- regs_buff[1081] = IXGBE_READ_REG(hw, IXGBE_RIC_DW0);
- regs_buff[1082] = IXGBE_READ_REG(hw, IXGBE_RIC_DW1);
- regs_buff[1083] = IXGBE_READ_REG(hw, IXGBE_RIC_DW2);
- regs_buff[1084] = IXGBE_READ_REG(hw, IXGBE_RIC_DW3);
+ for (i = 0; i < 4; i++)
+ regs_buff[1081 + i] = IXGBE_READ_REG(hw, IXGBE_RIC_DW(i));
regs_buff[1085] = IXGBE_READ_REG(hw, IXGBE_RDPROBE);
regs_buff[1086] = IXGBE_READ_REG(hw, IXGBE_TDSTATCTL);
for (i = 0; i < 8; i++)
- regs_buff[1087] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
+ regs_buff[1087 + i] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
regs_buff[1095] = IXGBE_READ_REG(hw, IXGBE_TDHMPN);
- regs_buff[1096] = IXGBE_READ_REG(hw, IXGBE_TIC_DW0);
- regs_buff[1097] = IXGBE_READ_REG(hw, IXGBE_TIC_DW1);
- regs_buff[1098] = IXGBE_READ_REG(hw, IXGBE_TIC_DW2);
- regs_buff[1099] = IXGBE_READ_REG(hw, IXGBE_TIC_DW3);
+ for (i = 0; i < 4; i++)
+ regs_buff[1096 + i] = IXGBE_READ_REG(hw, IXGBE_TIC_DW(i));
regs_buff[1100] = IXGBE_READ_REG(hw, IXGBE_TDPROBE);
regs_buff[1101] = IXGBE_READ_REG(hw, IXGBE_TXBUFCTRL);
regs_buff[1102] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA0);
@@ -566,7 +564,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[1109] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA2);
regs_buff[1110] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA3);
for (i = 0; i < 8; i++)
- regs_buff[1111] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
+ regs_buff[1111 + i] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
regs_buff[1119] = IXGBE_READ_REG(hw, IXGBE_RFVAL);
regs_buff[1120] = IXGBE_READ_REG(hw, IXGBE_MDFTC1);
regs_buff[1121] = IXGBE_READ_REG(hw, IXGBE_MDFTC2);
@@ -585,7 +583,7 @@ static int ixgbe_get_eeprom_len(struct net_device *netdev)
}
static int ixgbe_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, u8 *bytes)
+ struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -608,8 +606,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
return -ENOMEM;
for (i = 0; i < eeprom_len; i++) {
- if ((ret_val = ixgbe_read_eeprom(hw, first_word + i,
- &eeprom_buff[i])))
+ if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
+ &eeprom_buff[i])))
break;
}
@@ -624,7 +622,7 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
}
static void ixgbe_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
+ struct ethtool_drvinfo *drvinfo)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -637,7 +635,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
}
static void ixgbe_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
+ struct ethtool_ringparam *ring)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_ring *tx_ring = adapter->tx_ring;
@@ -654,15 +652,12 @@ static void ixgbe_get_ringparam(struct net_device *netdev,
}
static int ixgbe_set_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
+ struct ethtool_ringparam *ring)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_tx_buffer *old_buf;
- struct ixgbe_rx_buffer *old_rx_buf;
- void *old_desc;
+ struct ixgbe_ring *temp_ring;
int i, err;
- u32 new_rx_count, new_tx_count, old_size;
- dma_addr_t old_dma;
+ u32 new_rx_count, new_tx_count;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -681,6 +676,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
return 0;
}
+ if (adapter->num_tx_queues > adapter->num_rx_queues)
+ temp_ring = vmalloc(adapter->num_tx_queues *
+ sizeof(struct ixgbe_ring));
+ else
+ temp_ring = vmalloc(adapter->num_rx_queues *
+ sizeof(struct ixgbe_ring));
+ if (!temp_ring)
+ return -ENOMEM;
+
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
@@ -693,66 +697,61 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
* to the tx and rx ring structs.
*/
if (new_tx_count != adapter->tx_ring->count) {
+ memcpy(temp_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
for (i = 0; i < adapter->num_tx_queues; i++) {
- /* Save existing descriptor ring */
- old_buf = adapter->tx_ring[i].tx_buffer_info;
- old_desc = adapter->tx_ring[i].desc;
- old_size = adapter->tx_ring[i].size;
- old_dma = adapter->tx_ring[i].dma;
- /* Try to allocate a new one */
- adapter->tx_ring[i].tx_buffer_info = NULL;
- adapter->tx_ring[i].desc = NULL;
- adapter->tx_ring[i].count = new_tx_count;
- err = ixgbe_setup_tx_resources(adapter,
- &adapter->tx_ring[i]);
+ temp_ring[i].count = new_tx_count;
+ err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
if (err) {
- /* Restore the old one so at least
- the adapter still works, even if
- we failed the request */
- adapter->tx_ring[i].tx_buffer_info = old_buf;
- adapter->tx_ring[i].desc = old_desc;
- adapter->tx_ring[i].size = old_size;
- adapter->tx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ ixgbe_free_tx_resources(adapter,
+ &temp_ring[i]);
+ }
goto err_setup;
}
- /* Free the old buffer manually */
- vfree(old_buf);
- pci_free_consistent(adapter->pdev, old_size,
- old_desc, old_dma);
}
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+
+ memcpy(adapter->tx_ring, temp_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
+ adapter->tx_ring_count = new_tx_count;
}
if (new_rx_count != adapter->rx_ring->count) {
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ memcpy(temp_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbe_ring));
- old_rx_buf = adapter->rx_ring[i].rx_buffer_info;
- old_desc = adapter->rx_ring[i].desc;
- old_size = adapter->rx_ring[i].size;
- old_dma = adapter->rx_ring[i].dma;
-
- adapter->rx_ring[i].rx_buffer_info = NULL;
- adapter->rx_ring[i].desc = NULL;
- adapter->rx_ring[i].dma = 0;
- adapter->rx_ring[i].count = new_rx_count;
- err = ixgbe_setup_rx_resources(adapter,
- &adapter->rx_ring[i]);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ temp_ring[i].count = new_rx_count;
+ err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
if (err) {
- adapter->rx_ring[i].rx_buffer_info = old_rx_buf;
- adapter->rx_ring[i].desc = old_desc;
- adapter->rx_ring[i].size = old_size;
- adapter->rx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ ixgbe_free_rx_resources(adapter,
+ &temp_ring[i]);
+ }
goto err_setup;
}
-
- vfree(old_rx_buf);
- pci_free_consistent(adapter->pdev, old_size, old_desc,
- old_dma);
}
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+
+ memcpy(adapter->rx_ring, temp_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbe_ring));
+
+ adapter->rx_ring_count = new_rx_count;
}
+ /* success! */
err = 0;
err_setup:
- if (netif_running(adapter->netdev))
+ if (netif_running(netdev))
ixgbe_up(adapter);
clear_bit(__IXGBE_RESETTING, &adapter->state);
@@ -770,7 +769,7 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
}
static void ixgbe_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, u64 *data)
+ struct ethtool_stats *stats, u64 *data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u64 *queue_stat;
@@ -778,12 +777,20 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
int j, k;
int i;
u64 aggregated = 0, flushed = 0, no_desc = 0;
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
+ flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
+ no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
+ }
+ adapter->lro_aggregated = aggregated;
+ adapter->lro_flushed = flushed;
+ adapter->lro_no_desc = no_desc;
ixgbe_update_stats(adapter);
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset;
data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < adapter->num_tx_queues; j++) {
queue_stat = (u64 *)&adapter->tx_ring[j].stats;
@@ -792,24 +799,18 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
i += k;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
- aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[j].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc;
queue_stat = (u64 *)&adapter->rx_ring[j].stats;
for (k = 0; k < stat_count; k++)
data[i + k] = queue_stat[k];
i += k;
}
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
}
static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
- u8 *data)
+ u8 *data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u8 *p = data;
+ char *p = (char *)data;
int i;
switch (stringset) {
@@ -831,14 +832,14 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
sprintf(p, "rx_queue_%u_bytes", i);
p += ETH_GSTRING_LEN;
}
-/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
+ /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
break;
}
}
static void ixgbe_get_wol(struct net_device *netdev,
- struct ethtool_wolinfo *wol)
+ struct ethtool_wolinfo *wol)
{
wol->supported = 0;
wol->wolopts = 0;
@@ -859,16 +860,17 @@ static int ixgbe_nway_reset(struct net_device *netdev)
static int ixgbe_phys_id(struct net_device *netdev, u32 data)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 led_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_LEDCTL);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
u32 i;
if (!data || data > 300)
data = 300;
for (i = 0; i < (data * 1000); i += 400) {
- ixgbe_led_on(&adapter->hw, IXGBE_LED_ON);
+ hw->mac.ops.led_on(hw, IXGBE_LED_ON);
msleep_interruptible(200);
- ixgbe_led_off(&adapter->hw, IXGBE_LED_ON);
+ hw->mac.ops.led_off(hw, IXGBE_LED_ON);
msleep_interruptible(200);
}
@@ -879,67 +881,75 @@ static int ixgbe_phys_id(struct net_device *netdev, u32 data)
}
static int ixgbe_get_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
+ struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
- ec->rx_coalesce_usecs = adapter->rx_eitr;
- else
- ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
-
- if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
- ec->tx_coalesce_usecs = adapter->tx_eitr;
- else
- ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
-
ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;
+
+ /* only valid if in constant ITR mode */
+ switch (adapter->itr_setting) {
+ case 0:
+ /* throttling disabled */
+ ec->rx_coalesce_usecs = 0;
+ break;
+ case 1:
+ /* dynamic ITR mode */
+ ec->rx_coalesce_usecs = 1;
+ break;
+ default:
+ /* fixed interrupt rate mode */
+ ec->rx_coalesce_usecs = 1000000/adapter->eitr_param;
+ break;
+ }
return 0;
}
static int ixgbe_set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *ec)
+ struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
- ((ec->rx_coalesce_usecs != 0) &&
- (ec->rx_coalesce_usecs != 1) &&
- (ec->rx_coalesce_usecs != 3) &&
- (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
- return -EINVAL;
- if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
- ((ec->tx_coalesce_usecs != 0) &&
- (ec->tx_coalesce_usecs != 1) &&
- (ec->tx_coalesce_usecs != 3) &&
- (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
- return -EINVAL;
-
- /* convert to rate of irq's per second */
- if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
- adapter->rx_eitr = ec->rx_coalesce_usecs;
- else
- adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
-
- if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
- adapter->tx_eitr = ec->rx_coalesce_usecs;
- else
- adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
if (ec->tx_max_coalesced_frames_irq)
- adapter->tx_ring[0].work_limit =
- ec->tx_max_coalesced_frames_irq;
+ adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
+
+ if (ec->rx_coalesce_usecs > 1) {
+ /* store the value in ints/second */
+ adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
+
+ /* static value of interrupt rate */
+ adapter->itr_setting = adapter->eitr_param;
+ /* clear the lower bit */
+ adapter->itr_setting &= ~1;
+ } else if (ec->rx_coalesce_usecs == 1) {
+ /* 1 means dynamic mode */
+ adapter->eitr_param = 20000;
+ adapter->itr_setting = 1;
+ } else {
+ /* any other value means disable eitr, which is best
+ * served by setting the interrupt rate very high */
+ adapter->eitr_param = 3000000;
+ adapter->itr_setting = 0;
+ }
- if (netif_running(netdev)) {
- ixgbe_down(adapter);
- ixgbe_up(adapter);
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+ if (q_vector->txr_count && !q_vector->rxr_count)
+ q_vector->eitr = (adapter->eitr_param >> 1);
+ else
+ /* rx only or mixed */
+ q_vector->eitr = adapter->eitr_param;
+ IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
return 0;
}
-static struct ethtool_ops ixgbe_ethtool_ops = {
+static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
.set_settings = ixgbe_set_settings,
.get_drvinfo = ixgbe_get_drvinfo,
@@ -966,7 +976,7 @@ static struct ethtool_ops ixgbe_ethtool_ops = {
.set_tso = ixgbe_set_tso,
.get_strings = ixgbe_get_strings,
.phys_id = ixgbe_phys_id,
- .get_sset_count = ixgbe_get_sset_count,
+ .get_sset_count = ixgbe_get_sset_count,
.get_ethtool_stats = ixgbe_get_ethtool_stats,
.get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 362541a..ca17af4 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -46,15 +45,14 @@
char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
- "Intel(R) 10 Gigabit PCI Express Network Driver";
+ "Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "1.3.18-k4"
+#define DRV_VERSION "1.3.30-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
-static const char ixgbe_copyright[] =
- "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
- [board_82598] = &ixgbe_82598_info,
+ [board_82598] = &ixgbe_82598_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -74,15 +72,17 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR),
+ board_82598 },
/* required last entry */
{0, }
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
- void *p);
+ void *p);
static struct notifier_block dca_notifier = {
.notifier_call = ixgbe_notify_dca,
.next = NULL,
@@ -104,7 +104,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware take over control of h/w */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
}
static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
@@ -114,24 +114,11 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
/* Let firmware know the driver has taken over */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
- ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
+ ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
-#ifdef DEBUG
-/**
- * ixgbe_get_hw_dev_name - return device name string
- * used by hardware layer to print debugging information
- **/
-char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw)
-{
- struct ixgbe_adapter *adapter = hw->back;
- struct net_device *netdev = adapter->netdev;
- return netdev->name;
-}
-#endif
-
static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
- u8 msix_vector)
+ u8 msix_vector)
{
u32 ivar, index;
@@ -144,12 +131,12 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
}
static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
- struct ixgbe_tx_buffer
- *tx_buffer_info)
+ struct ixgbe_tx_buffer
+ *tx_buffer_info)
{
if (tx_buffer_info->dma) {
pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
- tx_buffer_info->length, PCI_DMA_TODEVICE);
+ tx_buffer_info->length, PCI_DMA_TODEVICE);
tx_buffer_info->dma = 0;
}
if (tx_buffer_info->skb) {
@@ -160,8 +147,8 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
}
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- unsigned int eop)
+ struct ixgbe_ring *tx_ring,
+ unsigned int eop)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 head, tail;
@@ -196,14 +183,14 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
return false;
}
-#define IXGBE_MAX_TXD_PWR 14
-#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
+#define IXGBE_MAX_TXD_PWR 14
+#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
(((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
+ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
#define GET_TX_HEAD_FROM_RING(ring) (\
*(volatile u32 *) \
@@ -309,9 +296,9 @@ done_cleaning:
return (total_packets ? true : false);
}
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
u32 rxctrl;
int cpu = get_cpu();
@@ -330,7 +317,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
}
static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
u32 txctrl;
int cpu = get_cpu();
@@ -406,8 +393,8 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_desc: rx descriptor
**/
static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
- struct sk_buff *skb, u8 status,
- struct ixgbe_ring *ring,
+ struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
union ixgbe_adv_rx_desc *rx_desc)
{
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
@@ -480,7 +467,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
struct ixgbe_ring *rx_ring,
int cleaned_count)
{
- struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
@@ -493,20 +479,29 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
while (cleaned_count--) {
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
- if (!bi->page &&
+ if (!bi->page_dma &&
(adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
- bi->page = alloc_page(GFP_ATOMIC);
if (!bi->page) {
- adapter->alloc_rx_page_failed++;
- goto no_buffers;
+ bi->page = alloc_page(GFP_ATOMIC);
+ if (!bi->page) {
+ adapter->alloc_rx_page_failed++;
+ goto no_buffers;
+ }
+ bi->page_offset = 0;
+ } else {
+ /* use a half page if we're re-using */
+ bi->page_offset ^= (PAGE_SIZE / 2);
}
- bi->page_dma = pci_map_page(pdev, bi->page, 0,
- PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
+
+ bi->page_dma = pci_map_page(pdev, bi->page,
+ bi->page_offset,
+ (PAGE_SIZE / 2),
+ PCI_DMA_FROMDEVICE);
}
if (!bi->skb) {
- struct sk_buff *skb = netdev_alloc_skb(netdev, bufsz);
+ struct sk_buff *skb = netdev_alloc_skb(adapter->netdev,
+ bufsz);
if (!skb) {
adapter->alloc_rx_buff_failed++;
@@ -567,10 +562,9 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
}
static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring,
- int *work_done, int work_to_do)
+ struct ixgbe_ring *rx_ring,
+ int *work_done, int work_to_do)
{
- struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -596,7 +590,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
- IXGBE_RXDADV_HDRBUFLEN_SHIFT;
+ IXGBE_RXDADV_HDRBUFLEN_SHIFT;
if (hdr_info & IXGBE_RXDADV_SPH)
adapter->rx_hdr_split++;
if (len > IXGBE_RX_HDR_SIZE)
@@ -613,18 +607,25 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
if (len && !skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- rx_ring->rx_buf_len + NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
+ rx_ring->rx_buf_len + NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
skb_put(skb, len);
}
if (upper_len) {
pci_unmap_page(pdev, rx_buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
rx_buffer_info->page_dma = 0;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
- rx_buffer_info->page, 0, upper_len);
- rx_buffer_info->page = NULL;
+ rx_buffer_info->page,
+ rx_buffer_info->page_offset,
+ upper_len);
+
+ if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
+ (page_count(rx_buffer_info->page) != 1))
+ rx_buffer_info->page = NULL;
+ else
+ get_page(rx_buffer_info->page);
skb->len += upper_len;
skb->data_len += upper_len;
@@ -647,6 +648,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
rx_buffer_info->skb = next_buffer->skb;
rx_buffer_info->dma = next_buffer->dma;
next_buffer->skb = skb;
+ next_buffer->dma = 0;
adapter->non_eop_descs++;
goto next_desc;
}
@@ -662,9 +664,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
total_rx_bytes += skb->len;
total_rx_packets++;
- skb->protocol = eth_type_trans(skb, netdev);
+ skb->protocol = eth_type_trans(skb, adapter->netdev);
ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
- netdev->last_rx = jiffies;
+ adapter->netdev->last_rx = jiffies;
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -724,43 +726,43 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vector = &adapter->q_vector[v_idx];
/* XXX for_each_bit(...) */
r_idx = find_first_bit(q_vector->rxr_idx,
- adapter->num_rx_queues);
+ adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx].reg_idx;
ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
- adapter->num_rx_queues,
- r_idx + 1);
+ adapter->num_rx_queues,
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->txr_idx,
- adapter->num_tx_queues);
+ adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx].reg_idx;
ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
- adapter->num_tx_queues,
- r_idx + 1);
+ adapter->num_tx_queues,
+ r_idx + 1);
}
- /* if this is a tx only vector use half the irq (tx) rate */
+ /* if this is a tx only vector halve the interrupt rate */
if (q_vector->txr_count && !q_vector->rxr_count)
- q_vector->eitr = adapter->tx_eitr;
+ q_vector->eitr = (adapter->eitr_param >> 1);
else
- /* rx only or mixed */
- q_vector->eitr = adapter->rx_eitr;
+ /* rx only */
+ q_vector->eitr = adapter->eitr_param;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
- /* set up to autoclear timer, lsc, and the vectors */
+ /* set up to autoclear timer, and the vectors */
mask = IXGBE_EIMS_ENABLE_MASK;
- mask &= ~IXGBE_EIMS_OTHER;
+ mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
}
@@ -790,8 +792,8 @@ enum latency_range {
* parameter (see ixgbe_param.c)
**/
static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
- u32 eitr, u8 itr_setting,
- int packets, int bytes)
+ u32 eitr, u8 itr_setting,
+ int packets, int bytes)
{
unsigned int retval = itr_setting;
u32 timepassed_us;
@@ -838,40 +840,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
u32 new_itr;
u8 current_itr, ret_itr;
int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
- sizeof(struct ixgbe_q_vector);
+ sizeof(struct ixgbe_q_vector);
struct ixgbe_ring *rx_ring, *tx_ring;
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->tx_eitr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
- q_vector->tx_eitr = ((q_vector->tx_eitr > ret_itr) ?
- q_vector->tx_eitr - 1 : ret_itr);
+ q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
+ q_vector->tx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = &(adapter->rx_ring[r_idx]);
ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
- q_vector->rx_eitr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
/* if the result for this queue would decrease interrupt
* rate for this vector then use that result */
- q_vector->rx_eitr = ((q_vector->rx_eitr > ret_itr) ?
- q_vector->rx_eitr - 1 : ret_itr);
+ q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
+ q_vector->rx_itr - 1 : ret_itr);
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
- r_idx + 1);
+ r_idx + 1);
}
- current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
+ current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
@@ -895,13 +897,27 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
/* must write high and low 16 bits to reset counter */
DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
- itr_reg);
+ itr_reg);
IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
}
return;
}
+
+static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ adapter->lsc_int++;
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
+ schedule_work(&adapter->watchdog_task);
+ }
+}
+
static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
{
struct net_device *netdev = data;
@@ -909,11 +925,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
- if (eicr & IXGBE_EICR_LSC) {
- adapter->lsc_int++;
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies);
- }
+ if (eicr & IXGBE_EICR_LSC)
+ ixgbe_check_lsc(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -934,7 +947,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_tx_dca(adapter, tx_ring);
#endif
@@ -942,7 +955,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
tx_ring->total_packets = 0;
ixgbe_clean_tx_irq(adapter, tx_ring);
r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
- r_idx + 1);
+ r_idx + 1);
}
return IRQ_HANDLED;
@@ -959,16 +972,24 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *rx_ring;
int r_idx;
+ int i;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ rx_ring = &(adapter->rx_ring[r_idx]);
+ rx_ring->total_bytes = 0;
+ rx_ring->total_packets = 0;
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
+ }
+
if (!q_vector->rxr_count)
return IRQ_HANDLED;
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
- rx_ring->total_bytes = 0;
- rx_ring->total_packets = 0;
netif_rx_schedule(adapter->netdev, &q_vector->napi);
return IRQ_HANDLED;
@@ -987,19 +1008,21 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
* @napi: napi struct with our devices info in it
* @budget: amount of work driver is allowed to do this pass, in packets
*
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
**/
static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
- container_of(napi, struct ixgbe_q_vector, napi);
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_ring *rx_ring;
+ struct ixgbe_ring *rx_ring = NULL;
int work_done = 0;
long r_idx;
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
@@ -1009,7 +1032,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
netif_rx_complete(adapter->netdev, napi);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+ if (adapter->itr_setting & 3)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
@@ -1018,8 +1041,57 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
return work_done;
}
+/**
+ * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function will clean more than one rx queue associated with a
+ * q_vector.
+ **/
+static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
+{
+ struct ixgbe_q_vector *q_vector =
+ container_of(napi, struct ixgbe_q_vector, napi);
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_ring *rx_ring = NULL;
+ int work_done = 0, i;
+ long r_idx;
+ u16 enable_mask = 0;
+
+ /* attempt to distribute budget to each queue fairly, but don't allow
+ * the budget to go below 1 because we'll exit polling */
+ budget /= (q_vector->rxr_count ?: 1);
+ budget = max(budget, 1);
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ for (i = 0; i < q_vector->rxr_count; i++) {
+ rx_ring = &(adapter->rx_ring[r_idx]);
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+ ixgbe_update_rx_dca(adapter, rx_ring);
+#endif
+ ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ enable_mask |= rx_ring->v_idx;
+ r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+ r_idx + 1);
+ }
+
+ r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+ rx_ring = &(adapter->rx_ring[r_idx]);
+ /* If all Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ netif_rx_complete(adapter->netdev, napi);
+ if (adapter->itr_setting & 3)
+ ixgbe_set_itr_msix(q_vector);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+ return 0;
+ }
+
+ return work_done;
+}
static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
a->q_vector[v_idx].adapter = a;
set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
@@ -1028,7 +1100,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
}
static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
- int r_idx)
+ int r_idx)
{
a->q_vector[v_idx].adapter = a;
set_bit(r_idx, a->q_vector[v_idx].txr_idx);
@@ -1048,7 +1120,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
* mapping configurations in here.
**/
static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int v_start = 0;
int rxr_idx = 0, txr_idx = 0;
@@ -1125,28 +1197,28 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
goto out;
#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
- (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
- &ixgbe_msix_clean_many)
+ (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
+ &ixgbe_msix_clean_many)
for (vector = 0; vector < q_vectors; vector++) {
handler = SET_HANDLER(&adapter->q_vector[vector]);
sprintf(adapter->name[vector], "%s:v%d-%s",
- netdev->name, vector,
- (handler == &ixgbe_msix_clean_rx) ? "Rx" :
- ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
+ netdev->name, vector,
+ (handler == &ixgbe_msix_clean_rx) ? "Rx" :
+ ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
err = request_irq(adapter->msix_entries[vector].vector,
- handler, 0, adapter->name[vector],
- &(adapter->q_vector[vector]));
+ handler, 0, adapter->name[vector],
+ &(adapter->q_vector[vector]));
if (err) {
DPRINTK(PROBE, ERR,
- "request_irq failed for MSIX interrupt "
- "Error: %d\n", err);
+ "request_irq failed for MSIX interrupt "
+ "Error: %d\n", err);
goto free_queue_irqs;
}
}
sprintf(adapter->name[vector], "%s:lsc", netdev->name);
err = request_irq(adapter->msix_entries[vector].vector,
- &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+ &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
if (err) {
DPRINTK(PROBE, ERR,
"request_irq for msix_lsc failed: %d\n", err);
@@ -1158,7 +1230,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
free_queue_irqs:
for (i = vector - 1; i >= 0; i--)
free_irq(adapter->msix_entries[--vector].vector,
- &(adapter->q_vector[i]));
+ &(adapter->q_vector[i]));
adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
@@ -1176,16 +1248,16 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
- q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr,
- q_vector->tx_eitr,
- tx_ring->total_packets,
- tx_ring->total_bytes);
- q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr,
- q_vector->rx_eitr,
- rx_ring->total_packets,
- rx_ring->total_bytes);
+ q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr,
+ q_vector->tx_itr,
+ tx_ring->total_packets,
+ tx_ring->total_bytes);
+ q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr,
+ q_vector->rx_itr,
+ rx_ring->total_packets,
+ rx_ring->total_bytes);
- current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
+ current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
@@ -1230,19 +1302,19 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
-
/* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
- if (!eicr)
+ if (!eicr) {
+ /* shared interrupt alert!
+ * make sure interrupts are enabled because the read will
+ * have disabled interrupts due to EIAM */
+ ixgbe_irq_enable(adapter);
return IRQ_NONE; /* Not our interrupt */
-
- if (eicr & IXGBE_EICR_LSC) {
- adapter->lsc_int++;
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies);
}
+ if (eicr & IXGBE_EICR_LSC)
+ ixgbe_check_lsc(adapter);
if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
adapter->tx_ring[0].total_packets = 0;
@@ -1285,10 +1357,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
err = ixgbe_request_msix_irqs(adapter);
} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
- netdev->name, netdev);
+ netdev->name, netdev);
} else {
err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
- netdev->name, netdev);
+ netdev->name, netdev);
}
if (err)
@@ -1312,7 +1384,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
i--;
for (; i >= 0; i--) {
free_irq(adapter->msix_entries[i].vector,
- &(adapter->q_vector[i]));
+ &(adapter->q_vector[i]));
}
ixgbe_reset_q_vectors(adapter);
@@ -1359,7 +1431,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
- EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr));
+ EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
@@ -1445,8 +1517,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
srrctl |= ((IXGBE_RX_HDR_SIZE <<
- IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
- IXGBE_SRRCTL_BSIZEHDR_MASK);
+ IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+ IXGBE_SRRCTL_BSIZEHDR_MASK);
} else {
srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
@@ -1463,7 +1535,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
/**
* ixgbe_get_skb_hdr - helper function for LRO header processing
* @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to tcp header structure
+ * @iphdr: pointer to ip header structure
* @tcph: pointer to tcp header structure
* @hdr_flags: pointer to header flags
* @priv: private data
@@ -1488,7 +1560,7 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
}
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
/**
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
@@ -1514,10 +1586,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
int rx_buf_len;
/* Decide whether to use packet split mode or not */
- if (netdev->mtu > ETH_DATA_LEN)
- adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
- else
- adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+ adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
@@ -1638,7 +1707,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
static void ixgbe_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+ struct vlan_group *grp)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u32 ctrl;
@@ -1662,14 +1731,16 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
/* add VID to filter table */
- ixgbe_set_vfta(&adapter->hw, vid, 0, true);
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
}
static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_disable(adapter);
@@ -1680,7 +1751,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
ixgbe_irq_enable(adapter);
/* remove VID from filter table */
- ixgbe_set_vfta(&adapter->hw, vid, 0, false);
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
}
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
@@ -1756,15 +1827,15 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
addr_count = netdev->uc_count;
if (addr_count)
addr_list = netdev->uc_list->dmi_addr;
- ixgbe_update_uc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr);
+ hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
/* reprogram multicast list */
addr_count = netdev->mc_count;
if (addr_count)
addr_list = netdev->mc_list->dmi_addr;
- ixgbe_update_mc_addr_list(hw, addr_list, addr_count,
- ixgbe_addr_list_itr);
+ hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
+ ixgbe_addr_list_itr);
}
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -1778,10 +1849,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
q_vectors = 1;
for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct napi_struct *napi;
q_vector = &adapter->q_vector[q_idx];
if (!q_vector->rxr_count)
continue;
- napi_enable(&q_vector->napi);
+ napi = &q_vector->napi;
+ if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) &&
+ (q_vector->rxr_count > 1))
+ napi->poll = &ixgbe_clean_rxonly_many;
+
+ napi_enable(napi);
}
}
@@ -1816,7 +1893,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
ixgbe_configure_rx(adapter);
for (i = 0; i < adapter->num_rx_queues; i++)
ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i],
- (adapter->rx_ring[i].count - 1));
+ (adapter->rx_ring[i].count - 1));
}
static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
@@ -1834,7 +1911,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
(adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
- IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
+ IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
} else {
/* MSI only */
gpie = 0;
@@ -1897,6 +1974,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
mod_timer(&adapter->watchdog_timer, jiffies);
return 0;
}
@@ -1921,58 +2000,22 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
void ixgbe_reset(struct ixgbe_adapter *adapter)
{
- if (ixgbe_init_hw(&adapter->hw))
- DPRINTK(PROBE, ERR, "Hardware Error\n");
+ struct ixgbe_hw *hw = &adapter->hw;
+ if (hw->mac.ops.init_hw(hw))
+ dev_err(&adapter->pdev->dev, "Hardware Error\n");
/* reprogram the RAR[0] in case user changed it. */
- ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
}
-#ifdef CONFIG_PM
-static int ixgbe_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- u32 err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "ixgbe: Cannot enable PCI device from " \
- "suspend\n");
- return err;
- }
- pci_set_master(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- if (netif_running(netdev)) {
- err = ixgbe_request_irq(adapter);
- if (err)
- return err;
- }
-
- ixgbe_reset(adapter);
-
- if (netif_running(netdev))
- ixgbe_up(adapter);
-
- netif_device_attach(netdev);
-
- return 0;
-}
-#endif
-
/**
* ixgbe_clean_rx_ring - Free Rx Buffers per Queue
* @adapter: board private structure
* @rx_ring: ring to free buffers from
**/
static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
@@ -1986,8 +2029,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_buffer_info = &rx_ring->rx_buffer_info[i];
if (rx_buffer_info->dma) {
pci_unmap_single(pdev, rx_buffer_info->dma,
- rx_ring->rx_buf_len,
- PCI_DMA_FROMDEVICE);
+ rx_ring->rx_buf_len,
+ PCI_DMA_FROMDEVICE);
rx_buffer_info->dma = 0;
}
if (rx_buffer_info->skb) {
@@ -1996,12 +2039,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
}
if (!rx_buffer_info->page)
continue;
- pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
+ pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
rx_buffer_info->page_dma = 0;
-
put_page(rx_buffer_info->page);
rx_buffer_info->page = NULL;
+ rx_buffer_info->page_offset = 0;
}
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
@@ -2023,7 +2066,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
* @tx_ring: ring to be cleaned
**/
static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+ struct ixgbe_ring *tx_ring)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned long size;
@@ -2076,33 +2119,43 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter)
void ixgbe_down(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
u32 rxctrl;
+ u32 txdctl;
+ int i, j;
/* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state);
/* disable receives */
- rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL,
- rxctrl & ~IXGBE_RXCTRL_RXEN);
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
netif_tx_disable(netdev);
- /* disable transmits in the hardware */
-
- /* flush both disables */
- IXGBE_WRITE_FLUSH(&adapter->hw);
+ IXGBE_WRITE_FLUSH(hw);
msleep(10);
+ netif_tx_stop_all_queues(netdev);
+
ixgbe_irq_disable(adapter);
ixgbe_napi_disable_all(adapter);
+
del_timer_sync(&adapter->watchdog_timer);
+ cancel_work_sync(&adapter->watchdog_task);
+
+ /* disable transmits in the hardware now that interrupts are off */
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ j = adapter->tx_ring[i].reg_idx;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
+ (txdctl & ~IXGBE_TXDCTL_ENABLE));
+ }
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&adapter->pdev->dev);
@@ -2114,56 +2167,18 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
/* since we reset the hardware DCA settings were cleared */
if (dca_add_requester(&adapter->pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
* in the CB driver */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
ixgbe_setup_dca(adapter);
}
#endif
}
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM
- int retval = 0;
-#endif
-
- netif_device_detach(netdev);
-
- if (netif_running(netdev)) {
- ixgbe_down(adapter);
- ixgbe_free_irq(adapter);
- }
-
-#ifdef CONFIG_PM
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-#endif
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- ixgbe_release_hw_control(adapter);
-
- pci_disable_device(pdev);
-
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static void ixgbe_shutdown(struct pci_dev *pdev)
-{
- ixgbe_suspend(pdev, PMSG_SUSPEND);
-}
-
/**
* ixgbe_poll - NAPI Rx polling callback
* @napi: structure for representing this polling device
@@ -2174,11 +2189,11 @@ static void ixgbe_shutdown(struct pci_dev *pdev)
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector = container_of(napi,
- struct ixgbe_q_vector, napi);
+ struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- int tx_cleaned = 0, work_done = 0;
+ int tx_cleaned, work_done = 0;
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
ixgbe_update_tx_dca(adapter, adapter->tx_ring);
ixgbe_update_rx_dca(adapter, adapter->rx_ring);
@@ -2194,12 +2209,11 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
netif_rx_complete(adapter->netdev, napi);
- if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+ if (adapter->itr_setting & 3)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable(adapter);
}
-
return work_done;
}
@@ -2225,8 +2239,48 @@ static void ixgbe_reset_task(struct work_struct *work)
ixgbe_reinit_locked(adapter);
}
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+ int nrq = 1, ntq = 1;
+ int feature_mask = 0, rss_i, rss_m;
+
+ /* Number of supported queues */
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
+ rss_i = adapter->ring_feature[RING_F_RSS].indices;
+ rss_m = 0;
+ feature_mask |= IXGBE_FLAG_RSS_ENABLED;
+
+ switch (adapter->flags & feature_mask) {
+ case (IXGBE_FLAG_RSS_ENABLED):
+ rss_m = 0xF;
+ nrq = rss_i;
+ ntq = rss_i;
+ break;
+ case 0:
+ default:
+ rss_i = 0;
+ rss_m = 0;
+ nrq = 1;
+ ntq = 1;
+ break;
+ }
+
+ adapter->ring_feature[RING_F_RSS].indices = rss_i;
+ adapter->ring_feature[RING_F_RSS].mask = rss_m;
+ break;
+ default:
+ nrq = 1;
+ ntq = 1;
+ break;
+ }
+
+ adapter->num_rx_queues = nrq;
+ adapter->num_tx_queues = ntq;
+}
+
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
- int vectors)
+ int vectors)
{
int err, vector_threshold;
@@ -2245,7 +2299,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
*/
while (vectors >= vector_threshold) {
err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- vectors);
+ vectors);
if (!err) /* Success in acquiring all requested vectors. */
break;
else if (err < 0)
@@ -2264,54 +2318,13 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
- adapter->num_tx_queues = 1;
- adapter->num_rx_queues = 1;
+ ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
adapter->num_msix_vectors = vectors;
}
}
-static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
-{
- int nrq, ntq;
- int feature_mask = 0, rss_i, rss_m;
-
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- rss_m = 0;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
-
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED):
- rss_m = 0xF;
- nrq = rss_i;
- ntq = rss_i;
- break;
- case 0:
- default:
- rss_i = 0;
- rss_m = 0;
- nrq = 1;
- ntq = 1;
- break;
- }
-
- adapter->ring_feature[RING_F_RSS].indices = rss_i;
- adapter->ring_feature[RING_F_RSS].mask = rss_m;
- break;
- default:
- nrq = 1;
- ntq = 1;
- break;
- }
-
- adapter->num_rx_queues = nrq;
- adapter->num_tx_queues = ntq;
-}
-
/**
* ixgbe_cache_ring_register - Descriptor ring to register mapping
* @adapter: board private structure to initialize
@@ -2321,9 +2334,6 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
**/
static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
{
- /* TODO: Remove all uses of the indices in the cases where multiple
- * features are OR'd together, if the feature set makes sense.
- */
int feature_mask = 0, rss_i;
int i, txr_idx, rxr_idx;
@@ -2364,21 +2374,22 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
int i;
adapter->tx_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!adapter->tx_ring)
goto err_tx_ring_allocation;
adapter->rx_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
if (!adapter->rx_ring)
goto err_rx_ring_allocation;
for (i = 0; i < adapter->num_tx_queues; i++) {
- adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;
+ adapter->tx_ring[i].count = adapter->tx_ring_count;
adapter->tx_ring[i].queue_index = i;
}
+
for (i = 0; i < adapter->num_rx_queues; i++) {
- adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD;
+ adapter->rx_ring[i].count = adapter->rx_ring_count;
adapter->rx_ring[i].queue_index = i;
}
@@ -2400,25 +2411,19 @@ err_tx_ring_allocation:
* capabilities of the hardware and the kernel.
**/
static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
- *adapter)
+ *adapter)
{
int err = 0;
int vector, v_budget;
/*
- * Set the default interrupt throttle rate.
- */
- adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS);
- adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS);
-
- /*
* It's easy to be greedy for MSI-X vectors, but it really
* doesn't do us much good if we have a lot more vectors
* than CPU's. So let's be conservative and only ask for
* (roughly) twice the number of vectors as there are CPU's.
*/
v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
- (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+ (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
/*
* At the same time, hardware can only support a maximum of
@@ -2432,7 +2437,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
/* A failure in MSI-X entry allocation isn't fatal, but it does
* mean we disable MSI-X capabilities of the adapter. */
adapter->msix_entries = kcalloc(v_budget,
- sizeof(struct msix_entry), GFP_KERNEL);
+ sizeof(struct msix_entry), GFP_KERNEL);
if (!adapter->msix_entries) {
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
ixgbe_set_num_queues(adapter);
@@ -2441,7 +2446,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
err = ixgbe_alloc_queues(adapter);
if (err) {
DPRINTK(PROBE, ERR, "Unable to allocate memory "
- "for queues\n");
+ "for queues\n");
goto out;
}
@@ -2462,7 +2467,7 @@ try_msi:
adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
} else {
DPRINTK(HW, DEBUG, "Unable to allocate MSI interrupt, "
- "falling back to legacy. Error: %d\n", err);
+ "falling back to legacy. Error: %d\n", err);
/* reset err */
err = 0;
}
@@ -2518,9 +2523,9 @@ static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
}
DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
- "Tx Queue count = %u\n",
- (adapter->num_rx_queues > 1) ? "Enabled" :
- "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
+ "Tx Queue count = %u\n",
+ (adapter->num_rx_queues > 1) ? "Enabled" :
+ "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
set_bit(__IXGBE_DOWN, &adapter->state);
@@ -2547,15 +2552,19 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
unsigned int rss;
+ /* PCI config space info */
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->revision_id = pdev->revision;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_device_id = pdev->subsystem_device;
+
/* Set capability flags */
rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
- /* Enable Dynamic interrupt throttling by default */
- adapter->rx_eitr = 1;
- adapter->tx_eitr = 1;
-
/* default flow control settings */
hw->fc.original_type = ixgbe_fc_none;
hw->fc.type = ixgbe_fc_none;
@@ -2566,18 +2575,21 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/* select 10G link by default */
hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- if (hw->mac.ops.reset(hw)) {
- dev_err(&pdev->dev, "HW Init failed\n");
- return -EIO;
- }
- if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
- false)) {
- dev_err(&pdev->dev, "Link Speed setup failed\n");
- return -EIO;
- }
+
+ /* enable itr by default in dynamic mode */
+ adapter->itr_setting = 1;
+ adapter->eitr_param = 20000;
+
+ /* set defaults for eitr in MegaBytes */
+ adapter->eitr_low = 10;
+ adapter->eitr_high = 20;
+
+ /* set default ring sizes */
+ adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
+ adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
/* initialize eeprom parameters */
- if (ixgbe_init_eeprom(hw)) {
+ if (ixgbe_init_eeprom_params_generic(hw)) {
dev_err(&pdev->dev, "EEPROM initialization failed\n");
return -EIO;
}
@@ -2633,6 +2645,31 @@ err:
}
/**
+ * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (!err)
+ continue;
+ DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i);
+ break;
+ }
+
+ return err;
+}
+
+/**
* ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
* @adapter: board private structure
* @rx_ring: rx descriptor ring (for a specific queue) to setup
@@ -2640,7 +2677,7 @@ err:
* Returns 0 on success, negative on failure
**/
int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size;
@@ -2655,7 +2692,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
rx_ring->rx_buffer_info = vmalloc(size);
if (!rx_ring->rx_buffer_info) {
DPRINTK(PROBE, ERR,
- "vmalloc allocation failed for the rx desc ring\n");
+ "vmalloc allocation failed for the rx desc ring\n");
goto alloc_failed;
}
memset(rx_ring->rx_buffer_info, 0, size);
@@ -2668,7 +2705,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
if (!rx_ring->desc) {
DPRINTK(PROBE, ERR,
- "Memory allocation failed for the rx desc ring\n");
+ "Memory allocation failed for the rx desc ring\n");
vfree(rx_ring->rx_buffer_info);
goto alloc_failed;
}
@@ -2685,14 +2722,40 @@ alloc_failed:
}
/**
+ * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not). It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
+{
+ int i, err = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (!err)
+ continue;
+ DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i);
+ break;
+ }
+
+ return err;
+}
+
+/**
* ixgbe_free_tx_resources - Free Tx Resources per Queue
* @adapter: board private structure
* @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
-static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring)
+void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *tx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -2727,8 +2790,8 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
*
* Free all receive software resources
**/
-static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *rx_ring)
+void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
@@ -2760,59 +2823,6 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_tx_queues; i++) {
- err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
- if (err) {
- DPRINTK(PROBE, ERR,
- "Allocation for Tx Queue %u failed\n", i);
- break;
- }
- }
-
- return err;
-}
-
-/**
- * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not). It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-
-static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
-{
- int i, err = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
- if (err) {
- DPRINTK(PROBE, ERR,
- "Allocation for Rx Queue %u failed\n", i);
- break;
- }
- }
-
- return err;
-}
-
-/**
* ixgbe_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
* @new_mtu: new value for maximum frame size
@@ -2824,12 +2834,12 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
- if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) ||
- (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
+ /* MTU < 68 is an error and causes problems on some kernels */
+ if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
return -EINVAL;
DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n",
- netdev->mtu, new_mtu);
+ netdev->mtu, new_mtu);
/* must set new MTU before calling down or up */
netdev->mtu = new_mtu;
@@ -2924,6 +2934,135 @@ static int ixgbe_close(struct net_device *netdev)
}
/**
+ * ixgbe_napi_add_all - prep napi structs for use
+ * @adapter: private struct
+ * helper function to napi_add each possible q_vector->napi
+ */
+static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+{
+ int q_idx, q_vectors;
+ int (*poll)(struct napi_struct *, int);
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ poll = &ixgbe_clean_rxonly;
+ /* Only enable as many vectors as we have rx queues. */
+ q_vectors = adapter->num_rx_queues;
+ } else {
+ poll = &ixgbe_poll;
+ /* only one q_vector for legacy modes */
+ q_vectors = 1;
+ }
+
+ for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+ netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
+ }
+}
+
+static void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
+{
+ int q_idx;
+ int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+ /* legacy and MSI only use one vector */
+ if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
+ q_vectors = 1;
+
+ for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+ struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+ if (!q_vector->rxr_count)
+ continue;
+ netif_napi_del(&q_vector->napi);
+ }
+}
+
+#ifdef CONFIG_PM
+static int ixgbe_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ u32 err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
+ "suspend\n");
+ return err;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ err = ixgbe_init_interrupt_scheme(adapter);
+ if (err) {
+ printk(KERN_ERR "ixgbe: Cannot initialize interrupts for "
+ "device\n");
+ return err;
+ }
+
+ ixgbe_napi_add_all(adapter);
+ ixgbe_reset(adapter);
+
+ if (netif_running(netdev)) {
+ err = ixgbe_open(adapter->netdev);
+ if (err)
+ return err;
+ }
+
+ netif_device_attach(netdev);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+ int retval = 0;
+#endif
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev)) {
+ ixgbe_down(adapter);
+ ixgbe_free_irq(adapter);
+ ixgbe_free_all_tx_resources(adapter);
+ ixgbe_free_all_rx_resources(adapter);
+ }
+ ixgbe_reset_interrupt_capability(adapter);
+ ixgbe_napi_del_all(adapter);
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+
+#ifdef CONFIG_PM
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+#endif
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ ixgbe_release_hw_control(adapter);
+
+ pci_disable_device(pdev);
+
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static void ixgbe_shutdown(struct pci_dev *pdev)
+{
+ ixgbe_suspend(pdev, PMSG_SUSPEND);
+}
+
+/**
* ixgbe_update_stats - Update the board statistics counters.
* @adapter: board private structure
**/
@@ -2996,7 +3135,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
/* Rx Errors */
adapter->net_stats.rx_errors = adapter->stats.crcerrs +
- adapter->stats.rlec;
+ adapter->stats.rlec;
adapter->net_stats.rx_dropped = 0;
adapter->net_stats.rx_length_errors = adapter->stats.rlec;
adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
@@ -3010,27 +3149,74 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
static void ixgbe_watchdog(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
- struct net_device *netdev = adapter->netdev;
- bool link_up;
- u32 link_speed = 0;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ /* Do the watchdog outside of interrupt context due to the lovely
+ * delays that some of the newer hardware requires */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ /* Cause software interrupt to ensure rx rings are cleaned */
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ u32 eics =
+ (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
+ IXGBE_WRITE_REG(hw, IXGBE_EICS, eics);
+ } else {
+ /* For legacy and MSI interrupts don't set any bits that
+ * are enabled for EIAM, because this operation would
+ * set *both* EIMS and EICS for any bit in EIAM */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ }
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + 2 * HZ));
+ }
- adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
+ schedule_work(&adapter->watchdog_task);
+}
+
+/**
+ * ixgbe_watchdog_task - worker thread to bring link up
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_watchdog_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ watchdog_task);
+ struct net_device *netdev = adapter->netdev;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 link_speed = adapter->link_speed;
+ bool link_up = adapter->link_up;
+
+ adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
+
+ if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+ if (link_up ||
+ time_after(jiffies, (adapter->link_check_timeout +
+ IXGBE_TRY_LINK_TIMEOUT))) {
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+ }
+ adapter->link_up = link_up;
+ adapter->link_speed = link_speed;
+ }
if (link_up) {
if (!netif_carrier_ok(netdev)) {
- u32 frctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- u32 rmcs = IXGBE_READ_REG(&adapter->hw, IXGBE_RMCS);
+ u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
#define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
#define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
DPRINTK(LINK, INFO, "NIC Link is Up %s, "
- "Flow Control: %s\n",
- (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
- "10 Gbps" :
- (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
- "1 Gbps" : "unknown speed")),
- ((FLOW_RX && FLOW_TX) ? "RX/TX" :
- (FLOW_RX ? "RX" :
- (FLOW_TX ? "TX" : "None"))));
+ "Flow Control: %s\n",
+ (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+ "10 Gbps" :
+ (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+ "1 Gbps" : "unknown speed")),
+ ((FLOW_RX && FLOW_TX) ? "RX/TX" :
+ (FLOW_RX ? "RX" :
+ (FLOW_TX ? "TX" : "None"))));
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
@@ -3039,6 +3225,8 @@ static void ixgbe_watchdog(unsigned long data)
adapter->detect_tx_hung = true;
}
} else {
+ adapter->link_up = false;
+ adapter->link_speed = 0;
if (netif_carrier_ok(netdev)) {
DPRINTK(LINK, INFO, "NIC Link is Down\n");
netif_carrier_off(netdev);
@@ -3047,36 +3235,19 @@ static void ixgbe_watchdog(unsigned long data)
}
ixgbe_update_stats(adapter);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
- /* Cause software interrupt to ensure rx rings are cleaned */
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- u32 eics =
- (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics);
- } else {
- /* for legacy and MSI interrupts don't set any bits that
- * are enabled for EIAM, because this operation would
- * set *both* EIMS and EICS for any bit in EIAM */
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
- (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
- }
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 2 * HZ));
- }
+ adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
}
static int ixgbe_tso(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring, struct sk_buff *skb,
- u32 tx_flags, u8 *hdr_len)
+ struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
int err;
struct ixgbe_tx_buffer *tx_buffer_info;
- u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
- u32 mss_l4len_idx = 0, l4len;
+ u32 vlan_macip_lens = 0, type_tucmd_mlhl;
+ u32 mss_l4len_idx, l4len;
if (skb_is_gso(skb)) {
if (skb_header_cloned(skb)) {
@@ -3092,16 +3263,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
iph->tot_len = 0;
iph->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
+ iph->daddr, 0,
+ IPPROTO_TCP,
+ 0);
adapter->hw_tso_ctxt++;
} else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
ipv6_hdr(skb)->payload_len = 0;
tcp_hdr(skb)->check =
~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
adapter->hw_tso6_ctxt++;
}
@@ -3115,7 +3286,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= ((skb_network_offset(skb)) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
*hdr_len += skb_network_offset(skb);
vlan_macip_lens |=
(skb_transport_header(skb) - skb_network_header(skb));
@@ -3125,8 +3296,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
context_desc->seqnum_seed = 0;
/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
- type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->protocol == htons(ETH_P_IP))
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
@@ -3134,7 +3305,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
/* MSS L4LEN IDX */
- mss_l4len_idx |=
+ mss_l4len_idx =
(skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT);
/* use index 1 for TSO */
@@ -3155,8 +3326,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
}
static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
{
struct ixgbe_adv_tx_context_desc *context_desc;
unsigned int i;
@@ -3173,16 +3344,16 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
vlan_macip_lens |=
(tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
vlan_macip_lens |= (skb_network_offset(skb) <<
- IXGBE_ADVTXD_MACLEN_SHIFT);
+ IXGBE_ADVTXD_MACLEN_SHIFT);
if (skb->ip_summed == CHECKSUM_PARTIAL)
vlan_macip_lens |= (skb_transport_header(skb) -
- skb_network_header(skb));
+ skb_network_header(skb));
context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
context_desc->seqnum_seed = 0;
type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
- IXGBE_ADVTXD_DTYP_CTXT);
+ IXGBE_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
switch (skb->protocol) {
@@ -3190,16 +3361,14 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
-
case __constant_htons(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
- IXGBE_ADVTXD_TUCMD_L4T_TCP;
+ IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
-
default:
if (unlikely(net_ratelimit())) {
DPRINTK(PROBE, WARNING,
@@ -3216,6 +3385,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
+
adapter->hw_csum_tx_good++;
i++;
if (i == tx_ring->count)
@@ -3224,12 +3394,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
return true;
}
+
return false;
}
static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- struct sk_buff *skb, unsigned int first)
+ struct ixgbe_ring *tx_ring,
+ struct sk_buff *skb, unsigned int first)
{
struct ixgbe_tx_buffer *tx_buffer_info;
unsigned int len = skb->len;
@@ -3247,8 +3418,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
tx_buffer_info->length = size;
tx_buffer_info->dma = pci_map_single(adapter->pdev,
- skb->data + offset,
- size, PCI_DMA_TODEVICE);
+ skb->data + offset,
+ size, PCI_DMA_TODEVICE);
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -3273,9 +3444,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
tx_buffer_info->length = size;
tx_buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size, PCI_DMA_TODEVICE);
+ frag->page,
+ offset,
+ size,
+ PCI_DMA_TODEVICE);
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
@@ -3298,8 +3470,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
}
static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
- struct ixgbe_ring *tx_ring,
- int tx_flags, int count, u32 paylen, u8 hdr_len)
+ struct ixgbe_ring *tx_ring,
+ int tx_flags, int count, u32 paylen, u8 hdr_len)
{
union ixgbe_adv_tx_desc *tx_desc = NULL;
struct ixgbe_tx_buffer *tx_buffer_info;
@@ -3318,17 +3490,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
/* use index 1 context for tso */
olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
if (tx_flags & IXGBE_TX_FLAGS_IPV4)
olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
} else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
- IXGBE_ADVTXD_POPTS_SHIFT;
+ IXGBE_ADVTXD_POPTS_SHIFT;
olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
@@ -3338,9 +3510,8 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
tx_desc->read.cmd_type_len =
- cpu_to_le32(cmd_type_len | tx_buffer_info->length);
+ cpu_to_le32(cmd_type_len | tx_buffer_info->length);
tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
-
i++;
if (i == tx_ring->count)
i = 0;
@@ -3361,7 +3532,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
}
static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3377,61 +3548,52 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
return -EBUSY;
/* A reprieve! - use start_queue because it doesn't call schedule */
- netif_wake_subqueue(netdev, tx_ring->queue_index);
+ netif_start_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
return 0;
}
static int ixgbe_maybe_stop_tx(struct net_device *netdev,
- struct ixgbe_ring *tx_ring, int size)
+ struct ixgbe_ring *tx_ring, int size)
{
if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
return 0;
return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
}
-
static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_ring *tx_ring;
- unsigned int len = skb->len;
unsigned int first;
unsigned int tx_flags = 0;
u8 hdr_len = 0;
int r_idx = 0, tso;
- unsigned int mss = 0;
int count = 0;
unsigned int f;
- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
- len -= skb->data_len;
+
r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
tx_ring = &adapter->tx_ring[r_idx];
-
- if (skb->len <= 0) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+ if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ tx_flags |= vlan_tx_tag_get(skb);
+ tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
+ tx_flags |= IXGBE_TX_FLAGS_VLAN;
}
- mss = skb_shinfo(skb)->gso_size;
-
- if (mss)
- count++;
- else if (skb->ip_summed == CHECKSUM_PARTIAL)
+ /* three things can cause us to need a context descriptor */
+ if (skb_is_gso(skb) ||
+ (skb->ip_summed == CHECKSUM_PARTIAL) ||
+ (tx_flags & IXGBE_TX_FLAGS_VLAN))
count++;
- count += TXD_USE_COUNT(len);
- for (f = 0; f < nr_frags; f++)
+ count += TXD_USE_COUNT(skb_headlen(skb));
+ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
adapter->tx_busy++;
return NETDEV_TX_BUSY;
}
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
- tx_flags |= IXGBE_TX_FLAGS_VLAN;
- tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT);
- }
if (skb->protocol == htons(ETH_P_IP))
tx_flags |= IXGBE_TX_FLAGS_IPV4;
@@ -3445,12 +3607,12 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (tso)
tx_flags |= IXGBE_TX_FLAGS_TSO;
else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
- (skb->ip_summed == CHECKSUM_PARTIAL))
+ (skb->ip_summed == CHECKSUM_PARTIAL))
tx_flags |= IXGBE_TX_FLAGS_CSUM;
ixgbe_tx_queue(adapter, tx_ring, tx_flags,
- ixgbe_tx_map(adapter, tx_ring, skb, first),
- skb->len, hdr_len);
+ ixgbe_tx_map(adapter, tx_ring, skb, first),
+ skb->len, hdr_len);
netdev->trans_start = jiffies;
@@ -3484,15 +3646,16 @@ static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
static int ixgbe_set_mac(struct net_device *netdev, void *p)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
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);
+ memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
- ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
return 0;
}
@@ -3516,28 +3679,19 @@ static void ixgbe_netpoll(struct net_device *netdev)
#endif
/**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- * helper function to napi_add each possible q_vector->napi
- */
-static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+ * ixgbe_link_config - set up initial link with default speed and duplex
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_link_config(struct ixgbe_hw *hw)
{
- int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- int (*poll)(struct napi_struct *, int);
+ u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- poll = &ixgbe_clean_rxonly;
- } else {
- poll = &ixgbe_poll;
- /* only one q_vector for legacy modes */
- q_vectors = 1;
- }
+ /* must always autoneg for both 1G and 10G link */
+ hw->mac.autoneg = true;
- for (i = 0; i < q_vectors; i++) {
- struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
- netif_napi_add(adapter->netdev, &q_vector->napi,
- (*poll), 64);
- }
+ return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
}
/**
@@ -3552,17 +3706,16 @@ static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
* and a hardware reset occur.
**/
static int __devinit ixgbe_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
struct net_device *netdev;
struct ixgbe_adapter *adapter = NULL;
struct ixgbe_hw *hw;
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
- unsigned long mmio_start, mmio_len;
static int cards_found;
int i, err, pci_using_dac;
u16 link_status, link_speed, link_width;
- u32 part_num;
+ u32 part_num, eec;
err = pci_enable_device(pdev);
if (err)
@@ -3577,7 +3730,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
dev_err(&pdev->dev, "No usable DMA "
- "configuration, aborting\n");
+ "configuration, aborting\n");
goto err_dma;
}
}
@@ -3610,10 +3763,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->back = adapter;
adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
- mmio_start = pci_resource_start(pdev, 0);
- mmio_len = pci_resource_len(pdev, 0);
-
- hw->hw_addr = ioremap(mmio_start, mmio_len);
+ hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
if (!hw->hw_addr) {
err = -EIO;
goto err_ioremap;
@@ -3643,22 +3794,23 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
#endif
strcpy(netdev->name, pci_name(pdev));
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
-
adapter->bd_number = cards_found;
- /* PCI config space info */
- hw->vendor_id = pdev->vendor;
- hw->device_id = pdev->device;
- hw->revision_id = pdev->revision;
- hw->subsystem_vendor_id = pdev->subsystem_vendor;
- hw->subsystem_device_id = pdev->subsystem_device;
-
/* Setup hw api */
memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
hw->mac.type = ii->mac;
+ /* EEPROM */
+ memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
+ if (!(eec & (1 << 8)))
+ hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
+
+ /* PHY */
+ memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
+ /* phy->sfp_type = ixgbe_sfp_type_unknown; */
+
err = ii->get_invariants(hw);
if (err)
goto err_hw_init;
@@ -3668,11 +3820,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+ /* reset_hw fills in the perm_addr as well */
+ err = hw->mac.ops.reset_hw(hw);
+ if (err) {
+ dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
+ goto err_sw_init;
+ }
+
netdev->features = NETIF_F_SG |
- NETIF_F_IP_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
+ NETIF_F_IP_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
@@ -3688,7 +3847,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_HIGHDMA;
/* make sure the EEPROM is good */
- if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
+ if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom;
@@ -3697,7 +3856,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len);
- if (ixgbe_validate_mac_addr(netdev->dev_addr)) {
+ if (ixgbe_validate_mac_addr(netdev->perm_addr)) {
+ dev_err(&pdev->dev, "invalid MAC address\n");
err = -EIO;
goto err_eeprom;
}
@@ -3707,6 +3867,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
adapter->watchdog_timer.data = (unsigned long)adapter;
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
+ INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
err = ixgbe_init_interrupt_scheme(adapter);
if (err)
@@ -3717,32 +3878,39 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
link_speed = link_status & IXGBE_PCI_LINK_SPEED;
link_width = link_status & IXGBE_PCI_LINK_WIDTH;
dev_info(&pdev->dev, "(PCI Express:%s:%s) "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
- (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
- "Unknown"),
- ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
- (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
- (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
- (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
- "Unknown"),
- netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
- netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
- ixgbe_read_part_num(hw, &part_num);
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
+ (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
+ "Unknown"),
+ ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
+ (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+ "Unknown"),
+ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+ ixgbe_read_pba_num_generic(hw, &part_num);
dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type,
- (part_num >> 8), (part_num & 0xff));
+ hw->mac.type, hw->phy.type,
+ (part_num >> 8), (part_num & 0xff));
if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
- "this card is not sufficient for optimal "
- "performance.\n");
+ "this card is not sufficient for optimal "
+ "performance.\n");
dev_warn(&pdev->dev, "For optimal performance a x8 "
- "PCI-Express slot is required.\n");
+ "PCI-Express slot is required.\n");
}
/* reset the hardware with the new settings */
- ixgbe_start_hw(hw);
+ hw->mac.ops.start_hw(hw);
+
+ /* link_config depends on start_hw being called at least once */
+ err = ixgbe_link_config(hw);
+ if (err) {
+ dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
+ goto err_register;
+ }
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
@@ -3754,7 +3922,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_register;
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
@@ -3804,7 +3972,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
flush_scheduled_work();
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&pdev->dev);
@@ -3822,6 +3990,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
DPRINTK(PROBE, INFO, "complete\n");
+ ixgbe_napi_del_all(adapter);
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
@@ -3839,7 +4008,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
* this device has been detected.
*/
static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
+ pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev->priv;
@@ -3850,7 +4019,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
ixgbe_down(adapter);
pci_disable_device(pdev);
- /* Request a slot slot reset. */
+ /* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -3867,7 +4036,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
if (pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR,
- "Cannot re-enable PCI device after reset.\n");
+ "Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
pci_set_master(pdev);
@@ -3901,7 +4070,6 @@ static void ixgbe_io_resume(struct pci_dev *pdev)
}
netif_device_attach(netdev);
-
}
static struct pci_error_handlers ixgbe_err_handler = {
@@ -3937,13 +4105,14 @@ static int __init ixgbe_init_module(void)
printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
dca_register_notify(&dca_notifier);
#endif
ret = pci_register_driver(&ixgbe_driver);
return ret;
}
+
module_init(ixgbe_init_module);
/**
@@ -3954,20 +4123,20 @@ module_init(ixgbe_init_module);
**/
static void __exit ixgbe_exit_module(void)
{
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
dca_unregister_notify(&dca_notifier);
#endif
pci_unregister_driver(&ixgbe_driver);
}
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
- void *p)
+ void *p)
{
int ret_val;
ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
- __ixgbe_notify_dca);
+ __ixgbe_notify_dca);
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 8002931..764035a 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -33,32 +32,36 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
+static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data);
/**
- * ixgbe_identify_phy - Get physical layer module
+ * ixgbe_identify_phy_generic - Get physical layer module
* @hw: pointer to hardware structure
*
* Determines the physical layer module found on the current adapter.
**/
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw)
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
u32 phy_addr;
- for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
- if (ixgbe_validate_phy_addr(hw, phy_addr)) {
- hw->phy.addr = phy_addr;
- ixgbe_get_phy_id(hw);
- hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
- status = 0;
- break;
+ if (hw->phy.type == ixgbe_phy_unknown) {
+ for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
+ if (ixgbe_validate_phy_addr(hw, phy_addr)) {
+ hw->phy.addr = phy_addr;
+ ixgbe_get_phy_id(hw);
+ hw->phy.type =
+ ixgbe_get_phy_type_from_id(hw->phy.id);
+ status = 0;
+ break;
+ }
}
+ } else {
+ status = 0;
}
+
return status;
}
@@ -73,10 +76,8 @@ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
bool valid = false;
hw->phy.addr = phy_addr;
- ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id);
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
if (phy_id != 0xFFFF && phy_id != 0x0)
valid = true;
@@ -95,21 +96,18 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
u16 phy_id_high = 0;
u16 phy_id_low = 0;
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_HIGH,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_high);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &phy_id_high);
if (status == 0) {
hw->phy.id = (u32)(phy_id_high << 16);
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_PHY_ID_LOW,
- IXGBE_MDIO_PMA_PMD_DEV_TYPE,
- &phy_id_low);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &phy_id_low);
hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
}
-
return status;
}
@@ -123,9 +121,6 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
enum ixgbe_phy_type phy_type;
switch (phy_id) {
- case TN1010_PHY_ID:
- phy_type = ixgbe_phy_tn;
- break;
case QT2022_PHY_ID:
phy_type = ixgbe_phy_qt;
break;
@@ -138,32 +133,31 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
}
/**
- * ixgbe_reset_phy - Performs a PHY reset
+ * ixgbe_reset_phy_generic - Performs a PHY reset
* @hw: pointer to hardware structure
**/
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw)
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
{
/*
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
*/
- return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
- IXGBE_MDIO_PHY_XS_DEV_TYPE,
- IXGBE_MDIO_PHY_XS_RESET);
+ return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
+ IXGBE_MDIO_PHY_XS_DEV_TYPE,
+ IXGBE_MDIO_PHY_XS_RESET);
}
/**
- * ixgbe_read_phy_reg - Reads a value from a specified PHY register
+ * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit address of PHY register to read
* @phy_data: Pointer to read data from PHY register
**/
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data)
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data)
{
u32 command;
u32 i;
- u32 timeout = 10;
u32 data;
s32 status = 0;
u16 gssr;
@@ -179,9 +173,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
if (status == 0) {
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -190,7 +184,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* The MDI Command bit will clear when the operation is
* complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -210,9 +204,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* command
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -221,7 +215,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* completed. The MDI Command bit will clear when the
* operation is complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -231,8 +225,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
}
if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
- hw_dbg(hw,
- "PHY read command didn't complete\n");
+ hw_dbg(hw, "PHY read command didn't complete\n");
status = IXGBE_ERR_PHY;
} else {
/*
@@ -247,22 +240,22 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
ixgbe_release_swfw_sync(hw, gssr);
}
+
return status;
}
/**
- * ixgbe_write_phy_reg - Writes a value to specified PHY register
+ * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit PHY register to write
* @device_type: 5 bit device type
* @phy_data: Data to write to the PHY register
**/
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 phy_data)
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data)
{
u32 command;
u32 i;
- u32 timeout = 10;
s32 status = 0;
u16 gssr;
@@ -280,9 +273,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
/* Setup and write the address cycle command */
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -291,19 +284,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* The MDI Command bit will clear when the operation is
* complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
- hw_dbg(hw, "PHY address cmd didn't complete\n");
+ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
break;
- }
}
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+ hw_dbg(hw, "PHY address cmd didn't complete\n");
status = IXGBE_ERR_PHY;
+ }
if (status == 0) {
/*
@@ -311,9 +304,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* command
*/
command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) |
- (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
- (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
- (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
+ (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+ (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+ (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -322,20 +315,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
* completed. The MDI Command bit will clear when the
* operation is complete
*/
- for (i = 0; i < timeout; i++) {
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
udelay(10);
command = IXGBE_READ_REG(hw, IXGBE_MSCA);
- if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
- hw_dbg(hw, "PHY write command did not "
- "complete.\n");
+ if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
break;
- }
}
- if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+ hw_dbg(hw, "PHY address cmd didn't complete\n");
status = IXGBE_ERR_PHY;
+ }
}
ixgbe_release_swfw_sync(hw, gssr);
@@ -345,67 +337,54 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
}
/**
- * ixgbe_setup_tnx_phy_link - Set and restart autoneg
+ * ixgbe_setup_phy_link_generic - Set and restart autoneg
* @hw: pointer to hardware structure
*
* Restart autonegotiation and PHY and waits for completion.
**/
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
{
s32 status = IXGBE_NOT_IMPLEMENTED;
u32 time_out;
u32 max_time_out = 10;
- u16 autoneg_speed_selection_register = 0x10;
- u16 autoneg_restart_mask = 0x0200;
- u16 autoneg_complete_mask = 0x0020;
- u16 autoneg_reg = 0;
+ u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
/*
* Set advertisement settings in PHY based on autoneg_advertised
* settings. If autoneg_advertised = 0, then advertise default values
- * txn devices cannot be "forced" to a autoneg 10G and fail. But can
+ * tnx devices cannot be "forced" to a autoneg 10G and fail. But can
* for a 1G.
*/
- ixgbe_read_phy_reg(hw,
- autoneg_speed_selection_register,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
else
autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
- ixgbe_write_phy_reg(hw,
- autoneg_speed_selection_register,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
-
+ hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
/* Restart PHY autonegotiation and wait for completion */
- ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
- autoneg_reg |= autoneg_restart_mask;
+ autoneg_reg |= IXGBE_MII_RESTART;
- ixgbe_write_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_CONTROL,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- autoneg_reg);
+ hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
/* Wait for autonegotiation to finish */
for (time_out = 0; time_out < max_time_out; time_out++) {
udelay(10);
/* Restart PHY autonegotiation and wait for completion */
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_AUTO_NEG_STATUS,
- IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
- &autoneg_reg);
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_reg);
- autoneg_reg &= autoneg_complete_mask;
- if (autoneg_reg == autoneg_complete_mask) {
+ autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
+ if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
status = 0;
break;
}
@@ -418,64 +397,17 @@ s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
}
/**
- * ixgbe_check_tnx_phy_link - Determine link and speed status
- * @hw: pointer to hardware structure
- *
- * Reads the VS1 register to determine if link is up and the current speed for
- * the PHY.
- **/
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
-{
- s32 status = 0;
- u32 time_out;
- u32 max_time_out = 10;
- u16 phy_link = 0;
- u16 phy_speed = 0;
- u16 phy_data = 0;
-
- /* Initialize speed and link to default case */
- *link_up = false;
- *speed = IXGBE_LINK_SPEED_10GB_FULL;
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- for (time_out = 0; time_out < max_time_out; time_out++) {
- udelay(10);
- if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
- *link_up = true;
- if (phy_speed ==
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
- *speed = IXGBE_LINK_SPEED_1GB_FULL;
- break;
- } else {
- status = ixgbe_read_phy_reg(hw,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
- IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
- &phy_data);
- phy_link = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
- phy_speed = phy_data &
- IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
- }
- }
-
- return status;
-}
-
-/**
- * ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities
+ * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
* @autoneg: true if autonegotiation enabled
**/
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
- bool autoneg,
- bool autoneg_wait_to_complete)
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
{
+
/*
* Clear autoneg_advertised and set new values based on input link
* speed.
@@ -484,11 +416,13 @@ s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
/* Setup link based on the new speed settings */
- ixgbe_setup_tnx_phy_link(hw);
+ hw->phy.ops.setup_link(hw);
return 0;
}
+
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index aa3ea72..9bfe3f2 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -30,20 +29,52 @@
#define _IXGBE_PHY_H_
#include "ixgbe_type.h"
+#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
-s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
- bool autoneg_wait_to_complete);
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw);
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw);
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
- u32 device_type, u16 *phy_data);
-
-/* PHY specific */
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
- bool autoneg_wait_to_complete);
+/* EEPROM byte offsets */
+#define IXGBE_SFF_IDENTIFIER 0x0
+#define IXGBE_SFF_IDENTIFIER_SFP 0x3
+#define IXGBE_SFF_VENDOR_OUI_BYTE0 0x25
+#define IXGBE_SFF_VENDOR_OUI_BYTE1 0x26
+#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27
+#define IXGBE_SFF_1GBE_COMP_CODES 0x6
+#define IXGBE_SFF_10GBE_COMP_CODES 0x3
+#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9
+
+/* Bitmasks */
+#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80
+#define IXGBE_SFF_1GBASESX_CAPABLE 0x1
+#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
+#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
+#define IXGBE_I2C_EEPROM_READ_MASK 0x100
+#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
+#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
+#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1
+#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
+#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
+
+/* Bit-shift macros */
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4
+
+/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
+#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
+#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
+#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
+
+
+s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data);
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data);
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
#endif /* _IXGBE_PHY_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 3e9c483..c6f8fa1 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
the file called "COPYING".
Contact Information:
- Linux NICS <linux.nics@intel.com>
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
@@ -37,9 +36,9 @@
/* Device IDs */
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
-#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8
#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
+#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -70,11 +69,11 @@
#define IXGBE_EIMC 0x00888
#define IXGBE_EIAC 0x00810
#define IXGBE_EIAM 0x00890
-#define IXGBE_EITR(_i) (0x00820 + ((_i) * 4)) /* 0x820-0x86c */
-#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */
#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */
-#define IXGBE_PBACL 0x11068
+#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
#define IXGBE_GPIE 0x00898
/* Flow Control Registers */
@@ -86,20 +85,33 @@
#define IXGBE_TFCS 0x0CE00
/* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (0x01000 + ((_i) * 0x40)) /* 64 of each (0-63)*/
-#define IXGBE_RDBAH(_i) (0x01004 + ((_i) * 0x40))
-#define IXGBE_RDLEN(_i) (0x01008 + ((_i) * 0x40))
-#define IXGBE_RDH(_i) (0x01010 + ((_i) * 0x40))
-#define IXGBE_RDT(_i) (0x01018 + ((_i) * 0x40))
-#define IXGBE_RXDCTL(_i) (0x01028 + ((_i) * 0x40))
-#define IXGBE_RSCCTL(_i) (0x0102C + ((_i) * 0x40))
-#define IXGBE_SRRCTL(_i) (0x02100 + ((_i) * 4))
- /* array of 16 (0x02100-0x0213C) */
-#define IXGBE_DCA_RXCTRL(_i) (0x02200 + ((_i) * 4))
- /* array of 16 (0x02200-0x0223C) */
-#define IXGBE_RDRXCTL 0x02F00
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+/*
+ * Split and Replication Receive Control Registers
+ * 00-15 : 0x02100 + n*4
+ * 16-64 : 0x01014 + n*0x40
+ * 64-127: 0x0D014 + (n-64)*0x40
+ */
+#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \
+ (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \
+ (0x0D014 + ((_i - 64) * 0x40))))
+/*
+ * Rx DCA Control Register:
+ * 00-15 : 0x02200 + n*4
+ * 16-64 : 0x0100C + n*0x40
+ * 64-127: 0x0D00C + (n-64)*0x40
+ */
+#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \
+ (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
+ (0x0D00C + ((_i - 64) * 0x40))))
+#define IXGBE_RDRXCTL 0x02F00
#define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4))
- /* 8 of these 0x03C00 - 0x03C1C */
+ /* 8 of these 0x03C00 - 0x03C1C */
#define IXGBE_RXCTRL 0x03000
#define IXGBE_DROPEN 0x03D04
#define IXGBE_RXPBSIZE_SHIFT 10
@@ -107,29 +119,32 @@
/* Receive Registers */
#define IXGBE_RXCSUM 0x05000
#define IXGBE_RFCTL 0x05008
+#define IXGBE_DRECCCTL 0x02F08
+#define IXGBE_DRECCCTL_DISABLE 0
+/* Multicast Table Array - 128 entries */
#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
- /* Multicast Table Array - 128 entries */
-#define IXGBE_RAL(_i) (0x05400 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_RAH(_i) (0x05404 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_PSRTYPE 0x05480
- /* 0x5480-0x54BC Packet split receive type */
+#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+/* Packet split receive type */
+#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+/* array of 4096 1-bit vlan filters */
#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4))
- /* array of 4096 1-bit vlan filters */
+/*array of 4096 4-bit vlan vmdq indices */
#define IXGBE_VFTAVIND(_j, _i) (0x0A200 + ((_j) * 0x200) + ((_i) * 4))
- /*array of 4096 4-bit vlan vmdq indicies */
#define IXGBE_FCTRL 0x05080
#define IXGBE_VLNCTRL 0x05088
#define IXGBE_MCSTCTRL 0x05090
#define IXGBE_MRQC 0x05818
-#define IXGBE_VMD_CTL 0x0581C
#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIRVP 0x05AC0
+#define IXGBE_VMD_CTL 0x0581C
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
+
/* Transmit DMA registers */
-#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40))/* 32 of these (0-31)*/
+#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
#define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40))
#define IXGBE_TDH(_i) (0x06010 + ((_i) * 0x40))
@@ -138,11 +153,10 @@
#define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40))
#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
#define IXGBE_DTXCTL 0x07E00
-#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4))
- /* there are 16 of these (0-15) */
+
+#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
#define IXGBE_TIPG 0x0CB00
-#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) *0x04))
- /* there are 8 of these */
+#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */
#define IXGBE_MNGTXMAP 0x0CD10
#define IXGBE_TIPG_FIBER_DEFAULT 3
#define IXGBE_TXPBSIZE_SHIFT 10
@@ -154,6 +168,7 @@
#define IXGBE_IPAV 0x05838
#define IXGBE_IP4AT 0x05840 /* IPv4 table 0x5840-0x5858 */
#define IXGBE_IP6AT 0x05880 /* IPv6 table 0x5880-0x588F */
+
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
#define IXGBE_FHFT 0x09000 /* Flex host filter table 9000-93FC */
@@ -170,6 +185,8 @@
#define IXGBE_TDPT2TCCR(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+
+
/* Stats registers */
#define IXGBE_CRCERRS 0x04000
#define IXGBE_ILLERRC 0x04004
@@ -224,7 +241,7 @@
#define IXGBE_XEC 0x04120
#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (0x07300 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
@@ -275,23 +292,17 @@
#define IXGBE_DCA_CTRL 0x11074
/* Diagnostic Registers */
-#define IXGBE_RDSTATCTL 0x02C20
-#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
-#define IXGBE_RDHMPN 0x02F08
-#define IXGBE_RIC_DW0 0x02F10
-#define IXGBE_RIC_DW1 0x02F14
-#define IXGBE_RIC_DW2 0x02F18
-#define IXGBE_RIC_DW3 0x02F1C
-#define IXGBE_RDPROBE 0x02F20
-#define IXGBE_TDSTATCTL 0x07C20
-#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
-#define IXGBE_TDHMPN 0x07F08
-#define IXGBE_TIC_DW0 0x07F10
-#define IXGBE_TIC_DW1 0x07F14
-#define IXGBE_TIC_DW2 0x07F18
-#define IXGBE_TIC_DW3 0x07F1C
-#define IXGBE_TDPROBE 0x07F20
-#define IXGBE_TXBUFCTRL 0x0C600
+#define IXGBE_RDSTATCTL 0x02C20
+#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
+#define IXGBE_RDHMPN 0x02F08
+#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4))
+#define IXGBE_RDPROBE 0x02F20
+#define IXGBE_TDSTATCTL 0x07C20
+#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
+#define IXGBE_TDHMPN 0x07F08
+#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4))
+#define IXGBE_TDPROBE 0x07F20
+#define IXGBE_TXBUFCTRL 0x0C600
#define IXGBE_TXBUFDATA0 0x0C610
#define IXGBE_TXBUFDATA1 0x0C614
#define IXGBE_TXBUFDATA2 0x0C618
@@ -392,7 +403,7 @@
#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
-#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
+#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */
/* MSCA Bit Masks */
@@ -416,10 +427,10 @@
#define IXGBE_MSCA_MDI_IN_PROG_EN 0x80000000 /* MDI in progress enable */
/* MSRWD bit masks */
-#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF
-#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
-#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000
-#define IXGBE_MSRWD_READ_DATA_SHIFT 16
+#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF
+#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
+#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000
+#define IXGBE_MSRWD_READ_DATA_SHIFT 16
/* Atlas registers */
#define IXGBE_ATLAS_PDN_LPBK 0x24
@@ -434,6 +445,7 @@
#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0
#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0
+
/* Device Type definitions for new protocol MDIO commands */
#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
@@ -441,6 +453,8 @@
#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */
+#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */
+
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL 0x0 /* VS1 Control Reg */
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS 0x1 /* VS1 Status Reg */
#define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS 0x0008 /* 1 = Link Up */
@@ -454,23 +468,39 @@
#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */
#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/
#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Abilty Reg */
+#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Address Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
+
+/* MII clause 22/28 definitions */
+#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800
+
+#define IXGBE_MII_SPEED_SELECTION_REG 0x10
+#define IXGBE_MII_RESTART 0x200
+#define IXGBE_MII_AUTONEG_COMPLETE 0x20
+#define IXGBE_MII_AUTONEG_REG 0x0
+
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
/* PHY IDs*/
-#define TN1010_PHY_ID 0x00A19410
#define QT2022_PHY_ID 0x0043A400
+/* PHY Types */
+#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
+
/* General purpose Interrupt Enable */
-#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
-#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
-#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
-#define IXGBE_GPIE_EIAME 0x40000000
-#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
+#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
+#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */
+#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
+#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
+#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
+#define IXGBE_GPIE_EIAME 0x40000000
+#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
/* Transmit Flow Control status */
#define IXGBE_TFCS_TXOFF 0x00000001
@@ -531,7 +561,7 @@
#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */
/* RMCS Bit Masks */
-#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recylce Mode enable */
+#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recycle Mode enable */
/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
#define IXGBE_RMCS_RAC 0x00000004
#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
@@ -539,12 +569,15 @@
#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+
/* Interrupt register bitmasks */
/* Extended Interrupt Cause Read */
#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */
#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
-#define IXGBE_EICR_MNG 0x00400000 /* Managability Event Interrupt */
+#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
+#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
+#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
@@ -552,11 +585,12 @@
/* Extended Interrupt Cause Set */
#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
-#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
-#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
+#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
+#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
+#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
+#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
@@ -564,7 +598,9 @@
#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
+#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */
#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
@@ -573,18 +609,20 @@
#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
-#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Error */
+#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
+#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */
#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
#define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */
-#define IXGBE_EIMS_ENABLE_MASK (\
- IXGBE_EIMS_RTX_QUEUE | \
- IXGBE_EIMS_LSC | \
- IXGBE_EIMS_TCP_TIMER | \
- IXGBE_EIMS_OTHER)
+#define IXGBE_EIMS_ENABLE_MASK ( \
+ IXGBE_EIMS_RTX_QUEUE | \
+ IXGBE_EIMS_LSC | \
+ IXGBE_EIMS_TCP_TIMER | \
+ IXGBE_EIMS_OTHER)
-/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
+/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define IXGBE_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
#define IXGBE_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
#define IXGBE_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
@@ -621,6 +659,7 @@
#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */
#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */
+
#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
/* STATUS Bit Masks */
@@ -668,16 +707,16 @@
#define IXGBE_AUTOC_AN_RESTART 0x00001000
#define IXGBE_AUTOC_FLU 0x00000001
#define IXGBE_AUTOC_LMS_SHIFT 13
-#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-
-#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
+#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
+#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
@@ -703,6 +742,7 @@
#define IXGBE_LINKS_TL_FAULT 0x00001000
#define IXGBE_LINKS_SIGNAL 0x00000F00
+#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
/* SW Semaphore Register bitmasks */
@@ -757,6 +797,11 @@
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+/* Legacy EEPROM word offsets */
+#define IXGBE_ISCSI_BOOT_CAPS 0x0033
+#define IXGBE_ISCSI_SETUP_PORT_0 0x0030
+#define IXGBE_ISCSI_SETUP_PORT_1 0x0034
+
/* EEPROM Commands - SPI */
#define IXGBE_EEPROM_MAX_RETRY_SPI 5000 /* Max wait 5ms for RDY signal */
#define IXGBE_EEPROM_STATUS_RDY_SPI 0x01
@@ -764,7 +809,7 @@
#define IXGBE_EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
#define IXGBE_EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = addr bit-8 */
#define IXGBE_EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Ena latch */
-/* EEPROM reset Write Enbale latch */
+/* EEPROM reset Write Enable latch */
#define IXGBE_EEPROM_WRDI_OPCODE_SPI 0x04
#define IXGBE_EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status reg */
#define IXGBE_EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status reg */
@@ -803,22 +848,20 @@
/* Number of 100 microseconds we wait for PCI Express master disable */
#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
-/* PHY Types */
-#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0
-
/* Check whether address is multicast. This is little-endian specific check.*/
#define IXGBE_IS_MULTICAST(Address) \
- (bool)(((u8 *)(Address))[0] & ((u8)0x01))
+ (bool)(((u8 *)(Address))[0] & ((u8)0x01))
/* Check whether an address is broadcast. */
#define IXGBE_IS_BROADCAST(Address) \
- ((((u8 *)(Address))[0] == ((u8)0xff)) && \
- (((u8 *)(Address))[1] == ((u8)0xff)))
+ ((((u8 *)(Address))[0] == ((u8)0xff)) && \
+ (((u8 *)(Address))[1] == ((u8)0xff)))
/* RAH */
#define IXGBE_RAH_VIND_MASK 0x003C0000
#define IXGBE_RAH_VIND_SHIFT 18
#define IXGBE_RAH_AV 0x80000000
+#define IXGBE_CLEAR_VMDQ_ALL 0xFFFFFFFF
/* Header split receive */
#define IXGBE_RFCTL_ISCSI_DIS 0x00000001
@@ -847,7 +890,7 @@
#define IXGBE_MAX_FRAME_SZ 0x40040000
#define IXGBE_TDWBAL_HEAD_WB_ENABLE 0x1 /* Tx head write-back enable */
-#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq. # write-back enable */
+#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq# write-back enable */
/* Receive Config masks */
#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
@@ -860,7 +903,7 @@
#define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */
#define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */
#define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */
-/* Receive Priority Flow Control Enbale */
+/* Receive Priority Flow Control Enable */
#define IXGBE_FCTRL_RPFCE 0x00004000
#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
@@ -890,9 +933,8 @@
/* Receive Descriptor bit definitions */
#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */
#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */
-#define IXGBE_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */
#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
#define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */
@@ -908,7 +950,7 @@
#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */
#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */
#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
-#define IXGBE_RXDADV_HBO 0x00800000
+#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */
#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
#define IXGBE_RXDADV_ERR_PE 0x08000000 /* Packet Error */
@@ -922,15 +964,17 @@
#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */
#define IXGBE_RXD_CFI_SHIFT 12
+
/* SRRCTL bit definitions */
-#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
-#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
-#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
-#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
+#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
+#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
+#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
+#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
#define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
#define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define IXGBE_SRRCTL_DESCTYPE_MASK 0x0E000000
#define IXGBE_RXDPS_HDRSTAT_HDRSP 0x00008000
#define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
@@ -964,21 +1008,20 @@
#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
-
/* Masks to determine if packets should be dropped due to frame errors */
-#define IXGBE_RXD_ERR_FRAME_ERR_MASK (\
- IXGBE_RXD_ERR_CE | \
- IXGBE_RXD_ERR_LE | \
- IXGBE_RXD_ERR_PE | \
- IXGBE_RXD_ERR_OSE | \
- IXGBE_RXD_ERR_USE)
-
-#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK (\
- IXGBE_RXDADV_ERR_CE | \
- IXGBE_RXDADV_ERR_LE | \
- IXGBE_RXDADV_ERR_PE | \
- IXGBE_RXDADV_ERR_OSE | \
- IXGBE_RXDADV_ERR_USE)
+#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
+ IXGBE_RXD_ERR_CE | \
+ IXGBE_RXD_ERR_LE | \
+ IXGBE_RXD_ERR_PE | \
+ IXGBE_RXD_ERR_OSE | \
+ IXGBE_RXD_ERR_USE)
+
+#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \
+ IXGBE_RXDADV_ERR_CE | \
+ IXGBE_RXDADV_ERR_LE | \
+ IXGBE_RXDADV_ERR_PE | \
+ IXGBE_RXDADV_ERR_OSE | \
+ IXGBE_RXDADV_ERR_USE)
/* Multicast bit mask */
#define IXGBE_MCSTCTRL_MFE 0x4
@@ -994,6 +1037,7 @@
#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */
#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
+
/* Transmit Descriptor - Legacy */
struct ixgbe_legacy_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -1008,8 +1052,8 @@ struct ixgbe_legacy_tx_desc {
union {
__le32 data;
struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
+ u8 status; /* Descriptor status */
+ u8 css; /* Checksum start */
__le16 vlan;
} fields;
} upper;
@@ -1018,7 +1062,7 @@ struct ixgbe_legacy_tx_desc {
/* Transmit Descriptor - Advanced */
union ixgbe_adv_tx_desc {
struct {
- __le64 buffer_addr; /* Address of descriptor's data buf */
+ __le64 buffer_addr; /* Address of descriptor's data buf */
__le32 cmd_type_len;
__le32 olinfo_status;
} read;
@@ -1050,8 +1094,8 @@ union ixgbe_adv_rx_desc {
union {
__le32 data;
struct {
- __le16 pkt_info; /* RSS type, Packet type */
- __le16 hdr_info; /* Split Header, header len */
+ __le16 pkt_info; /* RSS, Pkt type */
+ __le16 hdr_info; /* Splithdr, hdrlen */
} hs_rss;
} lo_dword;
union {
@@ -1079,49 +1123,69 @@ struct ixgbe_adv_tx_context_desc {
};
/* Adv Transmit Descriptor Config Masks */
-#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buffer length(bytes) */
+#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */
#define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */
-#define IXGBE_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */
#define IXGBE_ADVTXD_DCMD_RS IXGBE_TXD_CMD_RS /* Report Status */
-#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
+#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
#define IXGBE_ADVTXD_DCMD_DEXT IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */
#define IXGBE_ADVTXD_DCMD_VLE IXGBE_TXD_CMD_VLE /* VLAN pkt enable */
#define IXGBE_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define IXGBE_ADVTXD_STAT_DD IXGBE_TXD_STAT_DD /* Descriptor Done */
-#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
+#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED pres in WB */
#define IXGBE_ADVTXD_STAT_RSV 0x0000000C /* STA Reserved */
#define IXGBE_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
+#define IXGBE_ADVTXD_CC 0x00000080 /* Check Context */
#define IXGBE_ADVTXD_POPTS_SHIFT 8 /* Adv desc POPTS shift */
#define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
+ IXGBE_ADVTXD_POPTS_SHIFT)
#define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
- IXGBE_ADVTXD_POPTS_SHIFT)
-#define IXGBE_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit-RDMA DDP hdr */
-#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
-#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */
-#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
-#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
-#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
-#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
-#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
-#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
-#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
-#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
-#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
-#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
-
+ IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */
+#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
+#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
+#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
+#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
+#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
+#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
+#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
+#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/
+#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
+#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+
+/* Autonegotiation advertised speeds */
+typedef u32 ixgbe_autoneg_advertised;
/* Link speed */
+typedef u32 ixgbe_link_speed;
#define IXGBE_LINK_SPEED_UNKNOWN 0
#define IXGBE_LINK_SPEED_100_FULL 0x0008
#define IXGBE_LINK_SPEED_1GB_FULL 0x0020
#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
+#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
+ IXGBE_LINK_SPEED_10GB_FULL)
+
+/* Physical layer type */
+typedef u32 ixgbe_physical_layer;
+#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
+#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
+#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
+#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004
+#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
+#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080
+#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
+#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
+#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
enum ixgbe_eeprom_type {
@@ -1138,16 +1202,38 @@ enum ixgbe_mac_type {
enum ixgbe_phy_type {
ixgbe_phy_unknown = 0,
- ixgbe_phy_tn,
ixgbe_phy_qt,
- ixgbe_phy_xaui
+ ixgbe_phy_xaui,
+ ixgbe_phy_tw_tyco,
+ ixgbe_phy_tw_unknown,
+ ixgbe_phy_sfp_avago,
+ ixgbe_phy_sfp_ftl,
+ ixgbe_phy_sfp_unknown,
+ ixgbe_phy_generic
+};
+
+/*
+ * SFP+ module type IDs:
+ *
+ * ID Module Type
+ * =============
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ */
+enum ixgbe_sfp_type {
+ ixgbe_sfp_type_da_cu = 0,
+ ixgbe_sfp_type_sr = 1,
+ ixgbe_sfp_type_lr = 2,
+ ixgbe_sfp_type_unknown = 0xFFFF
};
enum ixgbe_media_type {
ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber,
ixgbe_media_type_copper,
- ixgbe_media_type_backplane
+ ixgbe_media_type_backplane,
+ ixgbe_media_type_virtual
};
/* Flow Control Settings */
@@ -1245,59 +1331,114 @@ struct ixgbe_hw;
typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
u32 *vmdq);
+/* Function pointer table */
+struct ixgbe_eeprom_operations {
+ s32 (*init_params)(struct ixgbe_hw *);
+ s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+ s32 (*write)(struct ixgbe_hw *, u16, u16);
+ s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
+ s32 (*update_checksum)(struct ixgbe_hw *);
+};
+
struct ixgbe_mac_operations {
- s32 (*reset)(struct ixgbe_hw *);
+ s32 (*init_hw)(struct ixgbe_hw *);
+ s32 (*reset_hw)(struct ixgbe_hw *);
+ s32 (*start_hw)(struct ixgbe_hw *);
+ s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+ s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+ s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+ s32 (*stop_adapter)(struct ixgbe_hw *);
+ s32 (*get_bus_info)(struct ixgbe_hw *);
+ s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
+ s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+
+ /* Link */
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
- s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+ bool);
+ s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
+ s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
+ bool *);
+
+ /* LED */
+ s32 (*led_on)(struct ixgbe_hw *, u32);
+ s32 (*led_off)(struct ixgbe_hw *, u32);
+ s32 (*blink_led_start)(struct ixgbe_hw *, u32);
+ s32 (*blink_led_stop)(struct ixgbe_hw *, u32);
+
+ /* RAR, Multicast, VLAN */
+ s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32);
+ s32 (*clear_rar)(struct ixgbe_hw *, u32);
+ s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
+ s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
+ s32 (*init_rx_addrs)(struct ixgbe_hw *);
+ s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+ ixgbe_mc_addr_itr);
+ s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+ ixgbe_mc_addr_itr);
+ s32 (*enable_mc)(struct ixgbe_hw *);
+ s32 (*disable_mc)(struct ixgbe_hw *);
+ s32 (*clear_vfta)(struct ixgbe_hw *);
+ s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+ s32 (*init_uta_tables)(struct ixgbe_hw *);
+
+ /* Flow Control */
+ s32 (*setup_fc)(struct ixgbe_hw *, s32);
};
struct ixgbe_phy_operations {
+ s32 (*identify)(struct ixgbe_hw *);
+ s32 (*identify_sfp)(struct ixgbe_hw *);
+ s32 (*reset)(struct ixgbe_hw *);
+ s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
+ s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
-};
-
-struct ixgbe_mac_info {
- struct ixgbe_mac_operations ops;
- enum ixgbe_mac_type type;
- u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- s32 mc_filter_type;
- u32 mcft_size;
- u32 vft_size;
- u32 num_rar_entries;
- u32 num_rx_queues;
- u32 num_tx_queues;
- u32 link_attach_type;
- u32 link_mode_select;
- bool link_settings_loaded;
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+ bool);
+ s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
+ s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
+ s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
+ s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
};
struct ixgbe_eeprom_info {
- enum ixgbe_eeprom_type type;
- u16 word_size;
- u16 address_bits;
+ struct ixgbe_eeprom_operations ops;
+ enum ixgbe_eeprom_type type;
+ u32 semaphore_delay;
+ u16 word_size;
+ u16 address_bits;
};
-struct ixgbe_phy_info {
- struct ixgbe_phy_operations ops;
-
- enum ixgbe_phy_type type;
- u32 addr;
- u32 id;
- u32 revision;
- enum ixgbe_media_type media_type;
- u32 autoneg_advertised;
- bool autoneg_wait_to_complete;
+struct ixgbe_mac_info {
+ struct ixgbe_mac_operations ops;
+ enum ixgbe_mac_type type;
+ u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ s32 mc_filter_type;
+ u32 mcft_size;
+ u32 vft_size;
+ u32 num_rar_entries;
+ u32 max_tx_queues;
+ u32 max_rx_queues;
+ u32 link_attach_type;
+ u32 link_mode_select;
+ bool link_settings_loaded;
+ bool autoneg;
+ bool autoneg_failed;
};
-struct ixgbe_info {
- enum ixgbe_mac_type mac;
- s32 (*get_invariants)(struct ixgbe_hw *);
- struct ixgbe_mac_operations *mac_ops;
+struct ixgbe_phy_info {
+ struct ixgbe_phy_operations ops;
+ enum ixgbe_phy_type type;
+ u32 addr;
+ u32 id;
+ enum ixgbe_sfp_type sfp_type;
+ u32 revision;
+ enum ixgbe_media_type media_type;
+ bool reset_disable;
+ ixgbe_autoneg_advertised autoneg_advertised;
+ bool autoneg_wait_to_complete;
};
struct ixgbe_hw {
@@ -1316,6 +1457,15 @@ struct ixgbe_hw {
bool adapter_stopped;
};
+struct ixgbe_info {
+ enum ixgbe_mac_type mac;
+ s32 (*get_invariants)(struct ixgbe_hw *);
+ struct ixgbe_mac_operations *mac_ops;
+ struct ixgbe_eeprom_operations *eeprom_ops;
+ struct ixgbe_phy_operations *phy_ops;
+};
+
+
/* Error Codes */
#define IXGBE_ERR_EEPROM -1
#define IXGBE_ERR_EEPROM_CHECKSUM -2
@@ -1334,6 +1484,8 @@ struct ixgbe_hw {
#define IXGBE_ERR_RESET_FAILED -15
#define IXGBE_ERR_SWFW_SYNC -16
#define IXGBE_ERR_PHY_ADDR_INVALID -17
+#define IXGBE_ERR_I2C -18
+#define IXGBE_ERR_SFP_NOT_SUPPORTED -19
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 0a97c26..a1e22ed 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -41,7 +41,7 @@
#endif
#if MFE_DEBUG>=1
-#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __FUNCTION__ , ## args)
+#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args)
#define MFE_RX_DEBUG 2
#else
#define DPRINTK(str,args...)
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 6d343ef..4e7a5fa 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -203,7 +203,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
out_badirq:
printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
- dev->name, __FUNCTION__, irq);
+ dev->name, __func__, irq);
return ret;
}
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index 096bca5..b411b79 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -33,6 +33,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/mm.h>
#include <linux/bitmap.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index d6524db..005f2aa 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -183,7 +183,7 @@ struct myri10ge_slice_state {
dma_addr_t fw_stats_bus;
int watchdog_tx_done;
int watchdog_tx_req;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
int cached_dca_tag;
int cpu;
__be32 __iomem *dca_tag;
@@ -215,7 +215,7 @@ struct myri10ge_priv {
int msi_enabled;
int msix_enabled;
struct msix_entry *msix_vectors;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
int dca_enabled;
#endif
u32 link_state;
@@ -891,7 +891,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
struct myri10ge_slice_state *ss;
int i, status;
size_t bytes;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
unsigned long dca_tag_off;
#endif
@@ -986,7 +986,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
dca_tag_off = cmd.data0;
for (i = 0; i < mgp->num_slices; i++) {
@@ -1025,7 +1025,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
return status;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
static void
myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
{
@@ -1060,8 +1060,9 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
}
err = dca_add_requester(&pdev->dev);
if (err) {
- dev_err(&pdev->dev,
- "dca_add_requester() failed, err=%d\n", err);
+ if (err != -ENODEV)
+ dev_err(&pdev->dev,
+ "dca_add_requester() failed, err=%d\n", err);
return;
}
mgp->dca_enabled = 1;
@@ -1457,7 +1458,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
struct net_device *netdev = ss->mgp->dev;
int work_done;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
if (ss->mgp->dca_enabled)
myri10ge_update_dca(ss);
#endif
@@ -1686,8 +1687,8 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
"tx_boundary", "WC", "irq", "MSI", "MSIX",
"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
"serial_number", "watchdog_resets",
-#ifdef CONFIG_DCA
- "dca_capable", "dca_enabled",
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+ "dca_capable_firmware", "dca_device_present",
#endif
"link_changes", "link_up", "dropped_link_overflow",
"dropped_link_error_or_filtered",
@@ -1765,7 +1766,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)mgp->read_write_dma;
data[i++] = (unsigned int)mgp->serial_number;
data[i++] = (unsigned int)mgp->watchdog_resets;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
data[i++] = (unsigned int)(mgp->dca_enabled);
#endif
@@ -3763,7 +3764,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "failed reset\n");
goto abort_with_slices;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
myri10ge_setup_dca(mgp);
#endif
pci_set_drvdata(pdev, mgp);
@@ -3866,7 +3867,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
netdev = mgp->dev;
unregister_netdev(netdev);
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
myri10ge_teardown_dca(mgp);
#endif
myri10ge_dummy_rdma(mgp, 0);
@@ -3911,7 +3912,7 @@ static struct pci_driver myri10ge_driver = {
#endif
};
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
static int
myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
{
@@ -3943,7 +3944,7 @@ static __init int myri10ge_init_module(void)
myri10ge_driver.name, myri10ge_rss_hash);
myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
}
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
dca_register_notify(&myri10ge_dca_notifier);
#endif
@@ -3954,7 +3955,7 @@ module_init(myri10ge_init_module);
static __exit void myri10ge_cleanup_module(void)
{
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
dca_unregister_notify(&myri10ge_dca_notifier);
#endif
pci_unregister_driver(&myri10ge_driver);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index fa3ceca..7959990 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -844,8 +844,12 @@ static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
struct net_device *dev = platform_get_drvdata(pdev);
- if (netif_running(dev))
+ if (netif_running(dev)) {
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
netif_device_detach(dev);
+ if (idev)
+ pnp_stop_dev(idev);
+ }
return 0;
}
@@ -854,6 +858,9 @@ static int ne_drv_resume(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
if (netif_running(dev)) {
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+ if (idev)
+ pnp_start_dev(idev);
ne_reset_8390(dev);
NS8390p_init(dev, 1);
netif_device_attach(dev);
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 3f9af75..b9bed82 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -189,7 +189,7 @@ netx_eth_interrupt(int irq, void *dev_id)
if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
printk("%s: unexpected status: 0x%08x\n",
- __FUNCTION__, status);
+ __func__, status);
fill_level =
readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 244ab49..f8e601c 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -742,7 +742,7 @@ extern char netxen_nic_driver_name[];
} while (0)
#else
#define DPRINTK(klevel, fmt, args...) do { \
- printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
+ printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
(adapter != NULL && adapter->netdev != NULL) ? \
adapter->netdev->name : NULL, \
## args); } while(0)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 008fd66..6ef3f0d 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -77,18 +77,18 @@ static irqreturn_t netxen_msi_intr(int irq, void *data);
/* PCI Device ID Table */
#define ENTRY(device) \
- {PCI_DEVICE(0x4040, (device)), \
+ {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
.class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
- ENTRY(0x0001),
- ENTRY(0x0002),
- ENTRY(0x0003),
- ENTRY(0x0004),
- ENTRY(0x0005),
- ENTRY(0x0024),
- ENTRY(0x0025),
- ENTRY(0x0100),
+ ENTRY(PCI_DEVICE_ID_NX2031_10GXSR),
+ ENTRY(PCI_DEVICE_ID_NX2031_10GCX4),
+ ENTRY(PCI_DEVICE_ID_NX2031_4GCU),
+ ENTRY(PCI_DEVICE_ID_NX2031_IMEZ),
+ ENTRY(PCI_DEVICE_ID_NX2031_HMEZ),
+ ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT),
+ ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT2),
+ ENTRY(PCI_DEVICE_ID_NX3031),
{0,}
};
@@ -241,7 +241,7 @@ static void netxen_check_options(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_REF_QG:
case NETXEN_BRDTYPE_P3_4_GB:
case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->msix_supported = 0;
+ adapter->msix_supported = !!use_msi_x;
adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
break;
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 53451c3..0a575fe 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -119,7 +119,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n";
#ifdef NETDRV_DEBUG
/* note: prints function name for you */
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
#else
# define DPRINTK(fmt, args...)
#endif
@@ -130,7 +130,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n";
# define assert(expr) \
if(!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr,__FILE__,__func__,__LINE__); \
}
#endif
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 5d86281..025f526 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -370,7 +370,7 @@ static void r6040_init_mac_regs(struct net_device *dev)
/* Reset internal state machine */
iowrite16(2, ioaddr + MAC_SM);
iowrite16(0, ioaddr + MAC_SM);
- udelay(5000);
+ mdelay(5);
/* MAC Bus Control Register */
iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
@@ -806,7 +806,7 @@ static void r6040_mac_address(struct net_device *dev)
iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */
iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */
iowrite16(0, ioaddr + MAC_SM);
- udelay(5000);
+ mdelay(5);
/* Restore MAC Address */
adrp = (u16 *) dev->dev_addr;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 1822491..fb899c6 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -36,7 +36,7 @@
#define assert(expr) \
if (!(expr)) { \
printk( "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr,__FILE__,__func__,__LINE__); \
}
#define dprintk(fmt, args...) \
do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
@@ -2286,8 +2286,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_R8(IntrMask);
- RTL_W32(RxMissed, 0);
-
rtl_set_rx_mode(dev);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -2412,8 +2410,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_R8(IntrMask);
- RTL_W32(RxMissed, 0);
-
rtl_set_rx_mode(dev);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -3191,6 +3187,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
return work_done;
}
+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+ return;
+
+ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
+ RTL_W32(RxMissed, 0);
+}
+
static void rtl8169_down(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3208,9 +3215,7 @@ core_down:
rtl8169_asic_down(ioaddr);
- /* Update the error counts. */
- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
@@ -3332,8 +3337,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
if (netif_running(dev)) {
spin_lock_irqsave(&tp->lock, flags);
- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irqrestore(&tp->lock, flags);
}
@@ -3358,8 +3362,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
rtl8169_asic_down(ioaddr);
- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 243db33..6a1375f 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -371,9 +371,6 @@ static void s2io_vlan_rx_register(struct net_device *dev,
flags[i]);
}
-/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
-static int vlan_strip_flag;
-
/* Unregister the vlan */
static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
{
@@ -2303,7 +2300,7 @@ static int start_nic(struct s2io_nic *nic)
val64 = readq(&bar0->rx_pa_cfg);
val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
writeq(val64, &bar0->rx_pa_cfg);
- vlan_strip_flag = 0;
+ nic->vlan_strip_flag = 0;
}
/*
@@ -3136,7 +3133,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
if (skb == NULL) {
spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
DBG_PRINT(ERR_DBG, "%s: Null skb ",
- __FUNCTION__);
+ __func__);
DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
return;
}
@@ -3496,7 +3493,7 @@ static void s2io_reset(struct s2io_nic * sp)
unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
- __FUNCTION__, sp->dev->name);
+ __func__, sp->dev->name);
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
@@ -3518,7 +3515,7 @@ static void s2io_reset(struct s2io_nic * sp)
}
if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) {
- DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __func__);
}
pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
@@ -3768,7 +3765,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, msix_index)) {
- DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
continue;
}
}
@@ -3789,7 +3786,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
val64 = (s2BIT(15) | vBIT(msix_index, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, msix_index)) {
- DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
continue;
}
addr = readq(&bar0->xmsi_address);
@@ -3812,7 +3809,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
GFP_KERNEL);
if (!nic->entries) {
DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
- __FUNCTION__);
+ __func__);
nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
return -ENOMEM;
}
@@ -3826,7 +3823,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
GFP_KERNEL);
if (!nic->s2io_entries) {
DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
- __FUNCTION__);
+ __func__);
nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
kfree(nic->entries);
nic->mac_control.stats_info->sw_stat.mem_freed
@@ -5010,7 +5007,7 @@ static void s2io_set_multicast(struct net_device *dev)
val64 = readq(&bar0->rx_pa_cfg);
val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
writeq(val64, &bar0->rx_pa_cfg);
- vlan_strip_flag = 0;
+ sp->vlan_strip_flag = 0;
}
val64 = readq(&bar0->mac_cfg);
@@ -5032,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev)
val64 = readq(&bar0->rx_pa_cfg);
val64 |= RX_PA_CFG_STRIP_VLAN_TAG;
writeq(val64, &bar0->rx_pa_cfg);
- vlan_strip_flag = 1;
+ sp->vlan_strip_flag = 1;
}
val64 = readq(&bar0->mac_cfg);
@@ -6746,7 +6743,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
ret = s2io_card_up(sp);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
- __FUNCTION__);
+ __func__);
return ret;
}
s2io_wake_all_tx_queue(sp);
@@ -7530,7 +7527,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
default:
DBG_PRINT(ERR_DBG,
"%s: Samadhana!!\n",
- __FUNCTION__);
+ __func__);
BUG();
}
}
@@ -7781,7 +7778,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
return -ENOMEM;
}
if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+ DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __func__, ret);
pci_disable_device(pdev);
return -ENODEV;
}
@@ -7998,7 +7995,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (sp->device_type & XFRAME_II_DEVICE) {
mode = s2io_verify_pci_mode(sp);
if (mode < 0) {
- DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__);
+ DBG_PRINT(ERR_DBG, "%s: ", __func__);
DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
ret = -EBADSLT;
goto set_swap_failed;
@@ -8206,6 +8203,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
/* Initialize device name */
sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name);
+ if (vlan_tag_strip)
+ sp->vlan_strip_flag = 1;
+ else
+ sp->vlan_strip_flag = 0;
+
/*
* Make Link state as off at this point, when the Link change
* interrupt comes the state will be automatically changed to
@@ -8299,7 +8301,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) {
DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n",
- __FUNCTION__);
+ __func__);
return -1;
}
@@ -8311,7 +8313,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
* If vlan stripping is disabled and the frame is VLAN tagged,
* shift the offset by the VLAN header size bytes.
*/
- if ((!vlan_strip_flag) &&
+ if ((!sp->vlan_strip_flag) &&
(rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
ip_off += HEADER_VLAN_SIZE;
} else {
@@ -8330,7 +8332,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
static int check_for_socket_match(struct lro *lro, struct iphdr *ip,
struct tcphdr *tcp)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) ||
(lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest))
return -1;
@@ -8345,7 +8347,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
static void initiate_new_session(struct lro *lro, u8 *l2h,
struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
lro->l2h = l2h;
lro->iph = ip;
lro->tcph = tcp;
@@ -8375,7 +8377,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
struct tcphdr *tcp = lro->tcph;
__sum16 nchk;
struct stat_block *statinfo = sp->mac_control.stats_info;
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
/* Update L3 header */
ip->tot_len = htons(lro->total_len);
@@ -8403,7 +8405,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
static void aggregate_new_rx(struct lro *lro, struct iphdr *ip,
struct tcphdr *tcp, u32 l4_pyld)
{
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
lro->total_len += l4_pyld;
lro->frags_len += l4_pyld;
lro->tcp_next_seq += l4_pyld;
@@ -8427,7 +8429,7 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
{
u8 *ptr;
- DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
if (!tcp_pyld_len) {
/* Runt frame or a pure ack */
@@ -8509,7 +8511,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) {
DBG_PRINT(INFO_DBG, "%s:Out of order. expected "
- "0x%x, actual 0x%x\n", __FUNCTION__,
+ "0x%x, actual 0x%x\n", __func__,
(*lro)->tcp_next_seq,
ntohl(tcph->seq));
@@ -8549,7 +8551,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
if (ret == 0) { /* sessions exceeded */
DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n",
- __FUNCTION__);
+ __func__);
*lro = NULL;
return ret;
}
@@ -8571,7 +8573,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
break;
default:
DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n",
- __FUNCTION__);
+ __func__);
break;
}
@@ -8592,7 +8594,7 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
skb->protocol = eth_type_trans(skb, dev);
if (sp->vlgrp && vlan_tag
- && (vlan_strip_flag)) {
+ && (sp->vlan_strip_flag)) {
/* Queueing the vlan frame to the upper layer */
if (sp->config.napi)
vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 6722a2f..55cb943 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -962,6 +962,7 @@ struct s2io_nic {
int task_flag;
unsigned long long start_time;
struct vlan_group *vlgrp;
+ int vlan_strip_flag;
#define MSIX_FLG 0xA5
int num_entries;
struct msix_entry *entries;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 0d47d6f..06ea71c 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -445,10 +445,17 @@ static void efx_fini_channels(struct efx_nic *efx)
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
+ int rc;
EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);
+ rc = falcon_flush_queues(efx);
+ if (rc)
+ EFX_ERR(efx, "failed to flush queues\n");
+ else
+ EFX_LOG(efx, "successfully flushed all queues\n");
+
efx_for_each_channel(channel, efx) {
EFX_LOG(channel->efx, "shut down chan %d\n", channel->channel);
@@ -456,13 +463,6 @@ static void efx_fini_channels(struct efx_nic *efx)
efx_fini_rx_queue(rx_queue);
efx_for_each_channel_tx_queue(tx_queue, channel)
efx_fini_tx_queue(tx_queue);
- }
-
- /* Do the event queues last so that we can handle flush events
- * for all DMA queues. */
- efx_for_each_channel(channel, efx) {
- EFX_LOG(channel->efx, "shut down evq %d\n", channel->channel);
-
efx_fini_eventq(channel);
}
}
@@ -780,7 +780,7 @@ static int efx_init_io(struct efx_nic *efx)
return 0;
fail4:
- release_mem_region(efx->membase_phys, efx->type->mem_map_size);
+ pci_release_region(efx->pci_dev, efx->type->mem_bar);
fail3:
efx->membase_phys = 0;
fail2:
@@ -1092,7 +1092,6 @@ static void efx_stop_all(struct efx_nic *efx)
/* Isolate the MAC from the TX and RX engines, so that queue
* flushes will complete in a timely fashion. */
- falcon_deconfigure_mac_wrapper(efx);
falcon_drain_tx_fifo(efx);
/* Stop the kernel transmit interface late, so the watchdog
@@ -1750,7 +1749,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
.check_hw = efx_port_dummy_op_int,
.fini = efx_port_dummy_op_void,
.clear_interrupt = efx_port_dummy_op_void,
- .reset_xaui = efx_port_dummy_op_void,
};
static struct efx_board efx_dummy_board_info = {
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index e0c0b23..31ed1f4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -108,10 +108,10 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
/* Max number of internal errors. After this resets will not be performed */
#define FALCON_MAX_INT_ERRORS 4
-/* Maximum period that we wait for flush events. If the flush event
- * doesn't arrive in this period of time then we check if the queue
- * was disabled anyway. */
-#define FALCON_FLUSH_TIMEOUT 10 /* 10ms */
+/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
+ */
+#define FALCON_FLUSH_INTERVAL 10
+#define FALCON_FLUSH_POLL_COUNT 100
/**************************************************************************
*
@@ -452,6 +452,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
efx_oword_t tx_desc_ptr;
struct efx_nic *efx = tx_queue->efx;
+ tx_queue->flushed = false;
+
/* Pin TX descriptor ring */
falcon_init_special_buffer(efx, &tx_queue->txd);
@@ -492,60 +494,16 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
}
}
-static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
+static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
{
struct efx_nic *efx = tx_queue->efx;
- struct efx_channel *channel = &efx->channel[0];
efx_oword_t tx_flush_descq;
- unsigned int read_ptr, i;
/* Post a flush command */
EFX_POPULATE_OWORD_2(tx_flush_descq,
TX_FLUSH_DESCQ_CMD, 1,
TX_FLUSH_DESCQ, tx_queue->queue);
falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER);
- msleep(FALCON_FLUSH_TIMEOUT);
-
- if (EFX_WORKAROUND_7803(efx))
- return 0;
-
- /* Look for a flush completed event */
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
- efx_qword_t *event = falcon_event(channel, read_ptr);
- int ev_code, ev_sub_code, ev_queue;
- if (!falcon_event_present(event))
- break;
-
- ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_TX_DESCQ_ID);
- if ((ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) &&
- (ev_queue == tx_queue->queue)) {
- EFX_LOG(efx, "tx queue %d flush command succesful\n",
- tx_queue->queue);
- return 0;
- }
-
- read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
-
- if (EFX_WORKAROUND_11557(efx)) {
- efx_oword_t reg;
- bool enabled;
-
- falcon_read_table(efx, ®, efx->type->txd_ptr_tbl_base,
- tx_queue->queue);
- enabled = EFX_OWORD_FIELD(reg, TX_DESCQ_EN);
- if (!enabled) {
- EFX_LOG(efx, "tx queue %d disabled without a "
- "flush event seen\n", tx_queue->queue);
- return 0;
- }
- }
-
- EFX_ERR(efx, "tx queue %d flush command timed out\n", tx_queue->queue);
- return -ETIMEDOUT;
}
void falcon_fini_tx(struct efx_tx_queue *tx_queue)
@@ -553,9 +511,8 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue)
struct efx_nic *efx = tx_queue->efx;
efx_oword_t tx_desc_ptr;
- /* Stop the hardware using the queue */
- if (falcon_flush_tx_queue(tx_queue))
- EFX_ERR(efx, "failed to flush tx queue %d\n", tx_queue->queue);
+ /* The queue should have been flushed */
+ WARN_ON(!tx_queue->flushed);
/* Remove TX descriptor ring from card */
EFX_ZERO_OWORD(tx_desc_ptr);
@@ -643,6 +600,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
rx_queue->queue, rx_queue->rxd.index,
rx_queue->rxd.index + rx_queue->rxd.entries - 1);
+ rx_queue->flushed = false;
+
/* Pin RX descriptor ring */
falcon_init_special_buffer(efx, &rx_queue->rxd);
@@ -663,11 +622,9 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
rx_queue->queue);
}
-static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
+static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- struct efx_channel *channel = &efx->channel[0];
- unsigned int read_ptr, i;
efx_oword_t rx_flush_descq;
/* Post a flush command */
@@ -675,76 +632,15 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
RX_FLUSH_DESCQ_CMD, 1,
RX_FLUSH_DESCQ, rx_queue->queue);
falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER);
- msleep(FALCON_FLUSH_TIMEOUT);
-
- if (EFX_WORKAROUND_7803(efx))
- return 0;
-
- /* Look for a flush completed event */
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
- efx_qword_t *event = falcon_event(channel, read_ptr);
- int ev_code, ev_sub_code, ev_queue;
- bool ev_failed;
- if (!falcon_event_present(event))
- break;
-
- ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_DESCQ_ID);
- ev_failed = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_FLUSH_FAIL);
-
- if ((ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) &&
- (ev_queue == rx_queue->queue)) {
- if (ev_failed) {
- EFX_INFO(efx, "rx queue %d flush command "
- "failed\n", rx_queue->queue);
- return -EAGAIN;
- } else {
- EFX_LOG(efx, "rx queue %d flush command "
- "succesful\n", rx_queue->queue);
- return 0;
- }
- }
-
- read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
-
- if (EFX_WORKAROUND_11557(efx)) {
- efx_oword_t reg;
- bool enabled;
-
- falcon_read_table(efx, ®, efx->type->rxd_ptr_tbl_base,
- rx_queue->queue);
- enabled = EFX_OWORD_FIELD(reg, RX_DESCQ_EN);
- if (!enabled) {
- EFX_LOG(efx, "rx queue %d disabled without a "
- "flush event seen\n", rx_queue->queue);
- return 0;
- }
- }
-
- EFX_ERR(efx, "rx queue %d flush command timed out\n", rx_queue->queue);
- return -ETIMEDOUT;
}
void falcon_fini_rx(struct efx_rx_queue *rx_queue)
{
efx_oword_t rx_desc_ptr;
struct efx_nic *efx = rx_queue->efx;
- int i, rc;
- /* Try and flush the rx queue. This may need to be repeated */
- for (i = 0; i < 5; i++) {
- rc = falcon_flush_rx_queue(rx_queue);
- if (rc == -EAGAIN)
- continue;
- break;
- }
- if (rc) {
- EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue);
- efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
- }
+ /* The queue should already have been flushed */
+ WARN_ON(!rx_queue->flushed);
/* Remove RX descriptor ring from card */
EFX_ZERO_OWORD(rx_desc_ptr);
@@ -1007,7 +903,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
is_phy_event = true;
if ((falcon_rev(efx) >= FALCON_REV_B0) &&
- EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0))
+ EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0))
is_phy_event = true;
if (is_phy_event) {
@@ -1255,6 +1151,121 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
falcon_generate_event(channel, &test_event);
}
+/**************************************************************************
+ *
+ * Flush handling
+ *
+ **************************************************************************/
+
+
+static void falcon_poll_flush_events(struct efx_nic *efx)
+{
+ struct efx_channel *channel = &efx->channel[0];
+ struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue *rx_queue;
+ unsigned int read_ptr, i;
+
+ read_ptr = channel->eventq_read_ptr;
+ for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+ efx_qword_t *event = falcon_event(channel, read_ptr);
+ int ev_code, ev_sub_code, ev_queue;
+ bool ev_failed;
+ if (!falcon_event_present(event))
+ break;
+
+ ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
+ if (ev_code != DRIVER_EV_DECODE)
+ continue;
+
+ ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
+ switch (ev_sub_code) {
+ case TX_DESCQ_FLS_DONE_EV_DECODE:
+ ev_queue = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_TX_DESCQ_ID);
+ if (ev_queue < EFX_TX_QUEUE_COUNT) {
+ tx_queue = efx->tx_queue + ev_queue;
+ tx_queue->flushed = true;
+ }
+ break;
+ case RX_DESCQ_FLS_DONE_EV_DECODE:
+ ev_queue = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_RX_DESCQ_ID);
+ ev_failed = EFX_QWORD_FIELD(*event,
+ DRIVER_EV_RX_FLUSH_FAIL);
+ if (ev_queue < efx->n_rx_queues) {
+ rx_queue = efx->rx_queue + ev_queue;
+
+ /* retry the rx flush */
+ if (ev_failed)
+ falcon_flush_rx_queue(rx_queue);
+ else
+ rx_queue->flushed = true;
+ }
+ break;
+ }
+
+ read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
+ }
+}
+
+/* Handle tx and rx flushes at the same time, since they run in
+ * parallel in the hardware and there's no reason for us to
+ * serialise them */
+int falcon_flush_queues(struct efx_nic *efx)
+{
+ struct efx_rx_queue *rx_queue;
+ struct efx_tx_queue *tx_queue;
+ int i;
+ bool outstanding;
+
+ /* Issue flush requests */
+ efx_for_each_tx_queue(tx_queue, efx) {
+ tx_queue->flushed = false;
+ falcon_flush_tx_queue(tx_queue);
+ }
+ efx_for_each_rx_queue(rx_queue, efx) {
+ rx_queue->flushed = false;
+ falcon_flush_rx_queue(rx_queue);
+ }
+
+ /* Poll the evq looking for flush completions. Since we're not pushing
+ * any more rx or tx descriptors at this point, we're in no danger of
+ * overflowing the evq whilst we wait */
+ for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) {
+ msleep(FALCON_FLUSH_INTERVAL);
+ falcon_poll_flush_events(efx);
+
+ /* Check if every queue has been succesfully flushed */
+ outstanding = false;
+ efx_for_each_tx_queue(tx_queue, efx)
+ outstanding |= !tx_queue->flushed;
+ efx_for_each_rx_queue(rx_queue, efx)
+ outstanding |= !rx_queue->flushed;
+ if (!outstanding)
+ return 0;
+ }
+
+ /* Mark the queues as all flushed. We're going to return failure
+ * leading to a reset, or fake up success anyway. "flushed" now
+ * indicates that we tried to flush. */
+ efx_for_each_tx_queue(tx_queue, efx) {
+ if (!tx_queue->flushed)
+ EFX_ERR(efx, "tx queue %d flush command timed out\n",
+ tx_queue->queue);
+ tx_queue->flushed = true;
+ }
+ efx_for_each_rx_queue(rx_queue, efx) {
+ if (!rx_queue->flushed)
+ EFX_ERR(efx, "rx queue %d flush command timed out\n",
+ rx_queue->queue);
+ rx_queue->flushed = true;
+ }
+
+ if (EFX_WORKAROUND_7803(efx))
+ return 0;
+
+ return -ETIMEDOUT;
+}
/**************************************************************************
*
@@ -1363,10 +1374,11 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg));
}
- /* Disable DMA bus mastering on both devices */
+ /* Disable both devices */
pci_disable_device(efx->pci_dev);
if (FALCON_IS_DUAL_FUNC(efx))
pci_disable_device(nic_data->pci_dev2);
+ falcon_disable_interrupts(efx);
if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
@@ -1593,7 +1605,7 @@ void falcon_fini_interrupt(struct efx_nic *efx)
**************************************************************************
*/
-#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
+#define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t))
/* Wait for SPI command completion */
static int falcon_spi_wait(struct efx_nic *efx)
@@ -1942,8 +1954,10 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
/* Wait for transfer to complete */
for (i = 0; i < 400; i++) {
- if (*(volatile u32 *)dma_done == FALCON_STATS_DONE)
+ if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) {
+ rmb(); /* Ensure the stats are valid. */
return 0;
+ }
udelay(10);
}
@@ -2758,6 +2772,8 @@ int falcon_probe_nic(struct efx_nic *efx)
/* Allocate storage for hardware specific data */
nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
+ if (!nic_data)
+ return -ENOMEM;
efx->nic_data = nic_data;
/* Determine number of ports etc. */
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 30d61e4..be025ba 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -86,6 +86,7 @@ extern void falcon_fini_interrupt(struct efx_nic *efx);
extern int falcon_probe_nic(struct efx_nic *efx);
extern int falcon_probe_resources(struct efx_nic *efx);
extern int falcon_init_nic(struct efx_nic *efx);
+extern int falcon_flush_queues(struct efx_nic *efx);
extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
extern void falcon_remove_resources(struct efx_nic *efx);
extern void falcon_remove_nic(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index e319fd6..5d584b0 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -117,7 +117,6 @@
#define SF_PRST_WIDTH 1
#define EE_PRST_LBN 8
#define EE_PRST_WIDTH 1
-/* See pic_mode_t for decoding of this field */
/* These bit definitions are extrapolated from the list of numerical
* values for STRAP_PINS.
*/
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h
index 6670cdf..c16da31 100644
--- a/drivers/net/sfc/falcon_io.h
+++ b/drivers/net/sfc/falcon_io.h
@@ -13,7 +13,6 @@
#include <linux/io.h>
#include <linux/spinlock.h>
-#include "net_driver.h"
/**************************************************************************
*
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 0d9f68f..d401231 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -78,79 +78,7 @@ static void falcon_setup_xaui(struct efx_nic *efx)
falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
}
-static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
-{
- efx_oword_t reg;
-
- EFX_ZERO_OWORD(reg);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
- EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-}
-
-static int _falcon_reset_xaui_a(struct efx_nic *efx)
-{
- efx_oword_t reg;
-
- falcon_hold_xaui_in_rst(efx);
- falcon_read(efx, ®, XX_PWR_RST_REG);
-
- /* Follow the RAMBUS XAUI data reset sequencing
- * Channels A and B first: power down, reset PLL, reset, clear
- */
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- /* Channels C and D: power down, reset PLL, reset, clear */
- EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 0);
- EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 0);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- /* Setup XAUI */
- falcon_setup_xaui(efx);
- udelay(10);
-
- /* Take XGXS out of reset */
- EFX_ZERO_OWORD(reg);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
-
- return 0;
-}
-
-static int _falcon_reset_xaui_b(struct efx_nic *efx)
+int falcon_reset_xaui(struct efx_nic *efx)
{
efx_oword_t reg;
int count;
@@ -171,20 +99,6 @@ static int _falcon_reset_xaui_b(struct efx_nic *efx)
return -ETIMEDOUT;
}
-int falcon_reset_xaui(struct efx_nic *efx)
-{
- int rc;
-
- if (EFX_WORKAROUND_9388(efx)) {
- falcon_hold_xaui_in_rst(efx);
- efx->phy_op->reset_xaui(efx);
- rc = _falcon_reset_xaui_a(efx);
- } else {
- rc = _falcon_reset_xaui_b(efx);
- }
- return rc;
-}
-
static bool falcon_xgmii_status(struct efx_nic *efx)
{
efx_oword_t reg;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 567df00..cdb11fa 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -160,6 +160,7 @@ struct efx_tx_buffer {
* @channel: The associated channel
* @buffer: The software buffer ring
* @txd: The hardware descriptor ring
+ * @flushed: Used when handling queue flushing
* @read_count: Current read pointer.
* This is the number of buffers that have been removed from both rings.
* @stopped: Stopped count.
@@ -192,6 +193,7 @@ struct efx_tx_queue {
struct efx_nic *nic;
struct efx_tx_buffer *buffer;
struct efx_special_buffer txd;
+ bool flushed;
/* Members used mainly on the completion path */
unsigned int read_count ____cacheline_aligned_in_smp;
@@ -260,6 +262,7 @@ struct efx_rx_buffer {
* the remaining space in the allocation.
* @buf_dma_addr: Page's DMA address.
* @buf_data: Page's host address.
+ * @flushed: Use when handling queue flushing
*/
struct efx_rx_queue {
struct efx_nic *efx;
@@ -285,6 +288,7 @@ struct efx_rx_queue {
struct page *buf_page;
dma_addr_t buf_dma_addr;
char *buf_data;
+ bool flushed;
};
/**
@@ -470,7 +474,7 @@ enum nic_state {
* This is the equivalent of NET_IP_ALIGN [which controls the alignment
* of the skb->head for hardware DMA].
*/
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
#define EFX_PAGE_IP_ALIGN 0
#else
#define EFX_PAGE_IP_ALIGN NET_IP_ALIGN
@@ -503,7 +507,6 @@ enum efx_fc_type {
* @clear_interrupt: Clear down interrupt
* @blink: Blink LEDs
* @check_hw: Check hardware
- * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset)
* @mmds: MMD presence mask
* @loopbacks: Supported loopback modes mask
*/
@@ -513,7 +516,6 @@ struct efx_phy_operations {
void (*reconfigure) (struct efx_nic *efx);
void (*clear_interrupt) (struct efx_nic *efx);
int (*check_hw) (struct efx_nic *efx);
- void (*reset_xaui) (struct efx_nic *efx);
int (*test) (struct efx_nic *efx);
int mmds;
unsigned loopbacks;
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index b7005da..fe4e3fd 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -129,18 +129,6 @@ static int sfe4001_poweron(struct efx_nic *efx)
unsigned int i, j;
int rc;
u8 out;
- efx_oword_t reg;
-
- /* Ensure that XGXS and XAUI SerDes are held in reset */
- EFX_POPULATE_OWORD_7(reg, XX_PWRDNA_EN, 1,
- XX_PWRDNB_EN, 1,
- XX_RSTPLLAB_EN, 1,
- XX_RESETA_EN, 1,
- XX_RESETB_EN, 1,
- XX_RSTXGXSRX_EN, 1,
- XX_RSTXGXSTX_EN, 1);
- falcon_write(efx, ®, XX_PWR_RST_REG);
- udelay(10);
/* Clear any previous over-temperature alert */
rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 8412dbe..d507c93 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -146,8 +146,6 @@ static int tenxpress_phy_check(struct efx_nic *efx)
return 0;
}
-static void tenxpress_reset_xaui(struct efx_nic *efx);
-
static int tenxpress_init(struct efx_nic *efx)
{
int rc, reg;
@@ -216,7 +214,10 @@ static int tenxpress_special_reset(struct efx_nic *efx)
{
int rc, reg;
- EFX_TRACE(efx, "%s\n", __func__);
+ /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
+ * a special software reset can glitch the XGMAC sufficiently for stats
+ * requests to fail. Since we don't ofen special_reset, just lock. */
+ spin_lock(&efx->stats_lock);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -225,20 +226,22 @@ static int tenxpress_special_reset(struct efx_nic *efx)
mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
PMA_PMD_EXT_CTRL_REG, reg);
- msleep(200);
+ mdelay(200);
/* Wait for the blocks to come out of reset */
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- return rc;
+ goto unlock;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- return rc;
+ goto unlock;
- return 0;
+unlock:
+ spin_unlock(&efx->stats_lock);
+ return rc;
}
static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp)
@@ -374,8 +377,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
struct tenxpress_phy_data *phy_data = efx->phy_data;
bool link_ok;
- link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL &&
- tenxpress_link_ok(efx, true));
+ link_ok = tenxpress_link_ok(efx, true);
if (link_ok != efx->link_up)
falcon_xmac_sim_phy_event(efx);
@@ -428,54 +430,6 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
PMA_PMD_LED_OVERR_REG, reg);
}
-static void tenxpress_reset_xaui(struct efx_nic *efx)
-{
- int phy = efx->mii.phy_id;
- int clk_ctrl, test_select, soft_rst2;
-
- /* Real work is done on clock_ctrl other resets are thought to be
- * optional but make the reset more reliable
- */
-
- /* Read */
- clk_ctrl = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG);
- test_select = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG);
- soft_rst2 = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG);
-
- /* Put in reset */
- test_select &= ~(1 << CLK312_EN_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG, test_select);
-
- soft_rst2 &= ~((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG, soft_rst2);
-
- clk_ctrl &= ~(1 << PLL312_RST_N_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG, clk_ctrl);
- udelay(10);
-
- /* Remove reset */
- clk_ctrl |= (1 << PLL312_RST_N_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_CLOCK_CTRL_REG, clk_ctrl);
- udelay(10);
-
- soft_rst2 |= ((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_SOFT_RST2_REG, soft_rst2);
- udelay(10);
-
- test_select |= (1 << CLK312_EN_LBN);
- mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
- PCS_TEST_SELECT_REG, test_select);
- udelay(10);
-}
-
static int tenxpress_phy_test(struct efx_nic *efx)
{
/* BIST is automatically run after a special software reset */
@@ -488,7 +442,6 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
.check_hw = tenxpress_phy_check_hw,
.fini = tenxpress_phy_fini,
.clear_interrupt = tenxpress_phy_clear_interrupt,
- .reset_xaui = tenxpress_reset_xaui,
.test = tenxpress_phy_test,
.mmds = TENXPRESS_REQUIRED_DEVS,
.loopbacks = TENXPRESS_LOOPBACKS,
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index cdee7c2..da3e9ff 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -516,7 +516,7 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
/* Number of bytes inserted at the start of a TSO header buffer,
* similar to NET_IP_ALIGN.
*/
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
#define TSOH_OFFSET 0
#else
#define TSOH_OFFSET NET_IP_ALIGN
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index a824f59..fa7b49d 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -24,8 +24,6 @@
#define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* XGXS and XAUI reset sequencing in SW */
-#define EFX_WORKAROUND_9388 EFX_WORKAROUND_ALWAYS
/* Low rate CRC errors require XAUI reset */
#define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index f6edecc..276151d 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -165,7 +165,6 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
.check_hw = xfp_phy_check_hw,
.fini = xfp_phy_fini,
.clear_interrupt = xfp_phy_clear_interrupt,
- .reset_xaui = efx_port_dummy_op_void,
.mmds = XFP_REQUIRED_DEVS,
.loopbacks = XFP_LOOPBACKS,
};
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
index ea85de9..79e665e 100644
--- a/drivers/net/skfp/pmf.c
+++ b/drivers/net/skfp/pmf.c
@@ -44,17 +44,10 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
int set, int local);
static int port_to_mib(struct s_smc *smc, int p);
-#define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e))
-#define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e))
-
-#define MOFFMS(e) ((int)&(((struct fddi_mib_m *)0)->e))
-#define MOFFMA(e) ((int) (((struct fddi_mib_m *)0)->e))
-
-#define MOFFAS(e) ((int)&(((struct fddi_mib_a *)0)->e))
-#define MOFFAA(e) ((int) (((struct fddi_mib_a *)0)->e))
-
-#define MOFFPS(e) ((int)&(((struct fddi_mib_p *)0)->e))
-#define MOFFPA(e) ((int) (((struct fddi_mib_p *)0)->e))
+#define MOFFSS(e) offsetof(struct fddi_mib, e)
+#define MOFFMS(e) offsetof(struct fddi_mib_m, e)
+#define MOFFAS(e) offsetof(struct fddi_mib_a, e)
+#define MOFFPS(e) offsetof(struct fddi_mib_p, e)
#define AC_G 0x01 /* Get */
@@ -87,8 +80,8 @@ static const struct s_p_tab {
{ SMT_P100D,AC_G, MOFFSS(fddiSMTOpVersionId), "S" } ,
{ SMT_P100E,AC_G, MOFFSS(fddiSMTHiVersionId), "S" } ,
{ SMT_P100F,AC_G, MOFFSS(fddiSMTLoVersionId), "S" } ,
- { SMT_P1010,AC_G, MOFFSA(fddiSMTManufacturerData), "D" } ,
- { SMT_P1011,AC_GR, MOFFSA(fddiSMTUserData), "D" } ,
+ { SMT_P1010,AC_G, MOFFSS(fddiSMTManufacturerData), "D" } ,
+ { SMT_P1011,AC_GR, MOFFSS(fddiSMTUserData), "D" } ,
{ SMT_P1012,AC_G, MOFFSS(fddiSMTMIBVersionId), "S" } ,
/* StationConfigGrp */
@@ -103,7 +96,7 @@ static const struct s_p_tab {
{ SMT_P101D,AC_GR, MOFFSS(fddiSMTTT_Notify), "wS" } ,
{ SMT_P101E,AC_GR, MOFFSS(fddiSMTStatRptPolicy), "bB" } ,
{ SMT_P101F,AC_GR, MOFFSS(fddiSMTTrace_MaxExpiration),"lL" } ,
- { SMT_P1020,AC_G, MOFFSA(fddiSMTPORTIndexes), "II" } ,
+ { SMT_P1020,AC_G, MOFFSS(fddiSMTPORTIndexes), "II" } ,
{ SMT_P1021,AC_G, MOFFSS(fddiSMTMACIndexes), "I" } ,
{ SMT_P1022,AC_G, MOFFSS(fddiSMTBypassPresent), "F" } ,
@@ -117,8 +110,8 @@ static const struct s_p_tab {
/* MIBOperationGrp */
{ SMT_P1032,AC_GROUP } ,
- { SMT_P1033,AC_G, MOFFSA(fddiSMTTimeStamp),"P" } ,
- { SMT_P1034,AC_G, MOFFSA(fddiSMTTransitionTimeStamp),"P" } ,
+ { SMT_P1033,AC_G, MOFFSS(fddiSMTTimeStamp),"P" } ,
+ { SMT_P1034,AC_G, MOFFSS(fddiSMTTransitionTimeStamp),"P" } ,
/* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */
{ SMT_P1035,AC_G, MOFFSS(fddiSMTSetCount),"4P" } ,
{ SMT_P1036,AC_G, MOFFSS(fddiSMTLastSetStationId),"8" } ,
@@ -129,7 +122,7 @@ static const struct s_p_tab {
* PRIVATE EXTENSIONS
* only accessible locally to get/set passwd
*/
- { SMT_P10F0,AC_GR, MOFFSA(fddiPRPMFPasswd), "8" } ,
+ { SMT_P10F0,AC_GR, MOFFSS(fddiPRPMFPasswd), "8" } ,
{ SMT_P10F1,AC_GR, MOFFSS(fddiPRPMFStation), "8" } ,
#ifdef ESS
{ SMT_P10F2,AC_GR, MOFFSS(fddiESSPayload), "lL" } ,
@@ -245,7 +238,7 @@ static const struct s_p_tab {
{ SMT_P400E,AC_GR, MOFFPS(fddiPORTConnectionPolicies),"bB" } ,
{ SMT_P400F,AC_G, MOFFPS(fddiPORTMacIndicated), "2" } ,
{ SMT_P4010,AC_G, MOFFPS(fddiPORTCurrentPath), "E" } ,
- { SMT_P4011,AC_GR, MOFFPA(fddiPORTRequestedPaths), "l4" } ,
+ { SMT_P4011,AC_GR, MOFFPS(fddiPORTRequestedPaths), "l4" } ,
{ SMT_P4012,AC_G, MOFFPS(fddiPORTMACPlacement), "S" } ,
{ SMT_P4013,AC_G, MOFFPS(fddiPORTAvailablePaths), "B" } ,
{ SMT_P4016,AC_G, MOFFPS(fddiPORTPMDClass), "E" } ,
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index c587162..02cc064 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -183,7 +183,7 @@ static void smc911x_reset(struct net_device *dev)
unsigned int reg, timeout=0, resets=1;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* Take out of PM setting first */
if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) {
@@ -272,7 +272,7 @@ static void smc911x_enable(struct net_device *dev)
unsigned mask, cfg, cr;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
SMC_SET_MAC_ADDR(lp, dev->dev_addr);
@@ -329,7 +329,7 @@ static void smc911x_shutdown(struct net_device *dev)
unsigned cr;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __func__);
/* Disable IRQ's */
SMC_SET_INT_EN(lp, 0);
@@ -348,7 +348,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev)
struct smc911x_local *lp = netdev_priv(dev);
unsigned int fifo_count, timeout, reg;
- DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __func__);
fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF;
if (fifo_count <= 4) {
/* Manually dump the packet data */
@@ -382,7 +382,7 @@ static inline void smc911x_rcv(struct net_device *dev)
unsigned char *data;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
status = SMC_GET_RX_STS_FIFO(lp);
DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n",
dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff);
@@ -460,7 +460,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
unsigned char *buf;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__);
BUG_ON(lp->pending_tx_skb == NULL);
skb = lp->pending_tx_skb;
@@ -524,7 +524,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
BUG_ON(lp->pending_tx_skb != NULL);
@@ -596,7 +596,7 @@ static void smc911x_tx(struct net_device *dev)
unsigned int tx_status;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
/* Collect the TX status */
while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
@@ -647,7 +647,7 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
SMC_GET_MII(lp, phyreg, phyaddr, phydata);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
return phydata;
}
@@ -661,7 +661,7 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
struct smc911x_local *lp = netdev_priv(dev);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SET_MII(lp, phyreg, phyaddr, phydata);
}
@@ -676,7 +676,7 @@ static void smc911x_phy_detect(struct net_device *dev)
int phyaddr;
unsigned int cfg, id1, id2;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
lp->phy_type = 0;
@@ -746,7 +746,7 @@ static int smc911x_phy_fixed(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int bmcr;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* Enter Link Disable state */
SMC_GET_PHY_BMCR(lp, phyaddr, bmcr);
@@ -793,7 +793,7 @@ static int smc911x_phy_reset(struct net_device *dev, int phy)
unsigned long flags;
unsigned int reg;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
reg = SMC_GET_PMT_CTRL(lp);
@@ -852,7 +852,7 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
int phyaddr = lp->mii.phy_id;
unsigned int bmcr, cr;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
/* duplex state has changed */
@@ -892,7 +892,7 @@ static void smc911x_phy_configure(struct work_struct *work)
int status;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
/*
* We should not be called if phy_type is zero.
@@ -985,7 +985,7 @@ static void smc911x_phy_interrupt(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int status;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
if (lp->phy_type == 0)
return;
@@ -1013,7 +1013,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
unsigned int rx_overrun=0, cr, pkts;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
@@ -1174,8 +1174,6 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
spin_unlock_irqrestore(&lp->lock, flags);
- DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
-
return IRQ_HANDLED;
}
@@ -1188,7 +1186,7 @@ smc911x_tx_dma_irq(int dma, void *data)
struct sk_buff *skb = lp->current_tx_skb;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name);
/* Clear the DMA interrupt sources */
@@ -1224,7 +1222,7 @@ smc911x_rx_dma_irq(int dma, void *data)
unsigned long flags;
unsigned int pkts;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
/* Clear the DMA interrupt sources */
SMC_DMA_ACK_IRQ(dev, dma);
@@ -1272,7 +1270,7 @@ static void smc911x_timeout(struct net_device *dev)
int status, mask;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
status = SMC_GET_INT(lp);
@@ -1310,7 +1308,7 @@ static void smc911x_set_multicast_list(struct net_device *dev)
unsigned int mcr, update_multicast = 0;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
SMC_GET_MAC_CR(lp, mcr);
@@ -1412,7 +1410,7 @@ smc911x_open(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -1420,7 +1418,7 @@ smc911x_open(struct net_device *dev)
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
- PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+ PRINTK("%s: no valid ethernet hw addr\n", __func__);
return -EINVAL;
}
@@ -1449,7 +1447,7 @@ static int smc911x_close(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
@@ -1483,7 +1481,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
int ret, status;
unsigned long flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
cmd->maxtxpkt = 1;
cmd->maxrxpkt = 1;
@@ -1621,7 +1619,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) {
if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) {
PRINTK("%s: %s timeout waiting for EEPROM to respond\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
return -EFAULT;
}
mdelay(1);
@@ -1629,7 +1627,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
}
if (timeout == 0) {
PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n",
- dev->name, __FUNCTION__);
+ dev->name, __func__);
return -ETIMEDOUT;
}
return 0;
@@ -1742,7 +1740,7 @@ static int __init smc911x_findirq(struct net_device *dev)
int timeout = 20;
unsigned long cookie;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
cookie = probe_irq_on();
@@ -1808,7 +1806,7 @@ static int __init smc911x_probe(struct net_device *dev)
const char *version_string;
unsigned long irq_flags;
- DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
/* First, see if the endian word is recognized */
val = SMC_GET_BYTE_TEST(lp);
@@ -2058,7 +2056,7 @@ static int smc911x_drv_probe(struct platform_device *pdev)
unsigned int *addr;
int ret;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
@@ -2129,7 +2127,7 @@ static int smc911x_drv_remove(struct platform_device *pdev)
struct smc911x_local *lp = netdev_priv(ndev);
struct resource *res;
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
platform_set_drvdata(pdev, NULL);
unregister_netdev(ndev);
@@ -2159,7 +2157,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
struct net_device *ndev = platform_get_drvdata(dev);
struct smc911x_local *lp = netdev_priv(ndev);
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
if (ndev) {
if (netif_running(ndev)) {
netif_device_detach(ndev);
@@ -2177,7 +2175,7 @@ static int smc911x_drv_resume(struct platform_device *dev)
{
struct net_device *ndev = platform_get_drvdata(dev);
- DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+ DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
if (ndev) {
struct smc911x_local *lp = netdev_priv(ndev);
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 24768c1..ef5ce88 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -270,7 +270,7 @@ static void smc_reset(struct net_device *dev)
unsigned int ctl, cfg;
struct sk_buff *pending_skb;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/* Disable all interrupts, block TX tasklet */
spin_lock_irq(&lp->lock);
@@ -363,7 +363,7 @@ static void smc_enable(struct net_device *dev)
void __iomem *ioaddr = lp->base;
int mask;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/* see the header file for options in TCR/RCR DEFAULT */
SMC_SELECT_BANK(lp, 0);
@@ -397,7 +397,7 @@ static void smc_shutdown(struct net_device *dev)
void __iomem *ioaddr = lp->base;
struct sk_buff *pending_skb;
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
/* no more interrupts for me */
spin_lock_irq(&lp->lock);
@@ -430,7 +430,7 @@ static inline void smc_rcv(struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int packet_number, status, packet_len;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
packet_number = SMC_GET_RXFIFO(lp);
if (unlikely(packet_number & RXFIFO_REMPTY)) {
@@ -577,7 +577,7 @@ static void smc_hardware_send_pkt(unsigned long data)
unsigned int packet_no, len;
unsigned char *buf;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
if (!smc_special_trylock(&lp->lock)) {
netif_stop_queue(dev);
@@ -662,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int numPages, poll_count, status;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
BUG_ON(lp->pending_tx_skb != NULL);
@@ -734,7 +734,7 @@ static void smc_tx(struct net_device *dev)
void __iomem *ioaddr = lp->base;
unsigned int saved_packet, packet_no, tx_status, pkt_len;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
/* If the TX FIFO is empty then nothing to do */
packet_no = SMC_GET_TXFIFO(lp);
@@ -856,7 +856,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SELECT_BANK(lp, 2);
return phydata;
@@ -883,7 +883,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
- __FUNCTION__, phyaddr, phyreg, phydata);
+ __func__, phyaddr, phyreg, phydata);
SMC_SELECT_BANK(lp, 2);
}
@@ -896,7 +896,7 @@ static void smc_phy_detect(struct net_device *dev)
struct smc_local *lp = netdev_priv(dev);
int phyaddr;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
lp->phy_type = 0;
@@ -935,7 +935,7 @@ static int smc_phy_fixed(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int bmcr, cfg1;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
/* Enter Link Disable state */
cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
@@ -1168,7 +1168,7 @@ static void smc_phy_interrupt(struct net_device *dev)
int phyaddr = lp->mii.phy_id;
int phy18;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
if (lp->phy_type == 0)
return;
@@ -1236,7 +1236,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
int status, mask, timeout, card_stats;
int saved_pointer;
- DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(3, "%s: %s\n", dev->name, __func__);
spin_lock(&lp->lock);
@@ -1358,7 +1358,7 @@ static void smc_timeout(struct net_device *dev)
void __iomem *ioaddr = lp->base;
int status, mask, eph_st, meminfo, fifo;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
spin_lock_irq(&lp->lock);
status = SMC_GET_INT(lp);
@@ -1402,7 +1402,7 @@ static void smc_set_multicast_list(struct net_device *dev)
unsigned char multicast_table[8];
int update_multicast = 0;
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
if (dev->flags & IFF_PROMISC) {
DBG(2, "%s: RCR_PRMS\n", dev->name);
@@ -1505,7 +1505,7 @@ smc_open(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
/*
* Check that the address is valid. If its not, refuse
@@ -1513,7 +1513,7 @@ smc_open(struct net_device *dev)
* address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
*/
if (!is_valid_ether_addr(dev->dev_addr)) {
- PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+ PRINTK("%s: no valid ethernet hw addr\n", __func__);
return -EINVAL;
}
@@ -1557,7 +1557,7 @@ static int smc_close(struct net_device *dev)
{
struct smc_local *lp = netdev_priv(dev);
- DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+ DBG(2, "%s: %s\n", dev->name, __func__);
netif_stop_queue(dev);
netif_carrier_off(dev);
@@ -1700,7 +1700,7 @@ static int __init smc_findirq(struct smc_local *lp)
int timeout = 20;
unsigned long cookie;
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
cookie = probe_irq_on();
@@ -1778,7 +1778,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
const char *version_string;
DECLARE_MAC_BUF(mac);
- DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+ DBG(2, "%s: %s\n", CARDNAME, __func__);
/* First, see if the high byte is 0x33 */
val = SMC_CURRENT_BANK(lp);
@@ -1961,7 +1961,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
if (dev->dma != (unsigned char)-1)
printk(" DMA %d", dev->dma);
- printk("%s%s\n", nowait ? " [nowait]" : "",
+ printk("%s%s\n",
+ lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "",
THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
if (!is_valid_ether_addr(dev->dev_addr)) {
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 997e7f1..edea073 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -446,6 +446,8 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define SMC_CAN_USE_32BIT 1
#define SMC_NOWAIT 1
+#define SMC_IO_SHIFT (lp->io_shift)
+
#define SMC_inb(a, r) readb((a) + (r))
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_inl(a, r) readl((a) + (r))
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 7d5561b..f860ea1 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -409,6 +409,7 @@ static int change_mtu(struct net_device *dev, int new_mtu);
static int eeprom_read(void __iomem *ioaddr, int location);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int mdio_wait_link(struct net_device *dev, int wait);
static int netdev_open(struct net_device *dev);
static void check_duplex(struct net_device *dev);
static void netdev_timer(unsigned long data);
@@ -785,6 +786,24 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
return;
}
+static int mdio_wait_link(struct net_device *dev, int wait)
+{
+ int bmsr;
+ int phy_id;
+ struct netdev_private *np;
+
+ np = netdev_priv(dev);
+ phy_id = np->phys[0];
+
+ do {
+ bmsr = mdio_read(dev, phy_id, MII_BMSR);
+ if (bmsr & 0x0004)
+ return 0;
+ mdelay(1);
+ } while (--wait > 0);
+ return -1;
+}
+
static int netdev_open(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
@@ -1393,41 +1412,51 @@ static void netdev_error(struct net_device *dev, int intr_status)
int speed;
if (intr_status & LinkChange) {
- if (np->an_enable) {
- mii_advertise = mdio_read (dev, np->phys[0], MII_ADVERTISE);
- mii_lpa= mdio_read (dev, np->phys[0], MII_LPA);
- mii_advertise &= mii_lpa;
- printk (KERN_INFO "%s: Link changed: ", dev->name);
- if (mii_advertise & ADVERTISE_100FULL) {
- np->speed = 100;
- printk ("100Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_100HALF) {
- np->speed = 100;
- printk ("100Mbps, half duplex\n");
- } else if (mii_advertise & ADVERTISE_10FULL) {
- np->speed = 10;
- printk ("10Mbps, full duplex\n");
- } else if (mii_advertise & ADVERTISE_10HALF) {
- np->speed = 10;
- printk ("10Mbps, half duplex\n");
- } else
- printk ("\n");
+ if (mdio_wait_link(dev, 10) == 0) {
+ printk(KERN_INFO "%s: Link up\n", dev->name);
+ if (np->an_enable) {
+ mii_advertise = mdio_read(dev, np->phys[0],
+ MII_ADVERTISE);
+ mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
+ mii_advertise &= mii_lpa;
+ printk(KERN_INFO "%s: Link changed: ",
+ dev->name);
+ if (mii_advertise & ADVERTISE_100FULL) {
+ np->speed = 100;
+ printk("100Mbps, full duplex\n");
+ } else if (mii_advertise & ADVERTISE_100HALF) {
+ np->speed = 100;
+ printk("100Mbps, half duplex\n");
+ } else if (mii_advertise & ADVERTISE_10FULL) {
+ np->speed = 10;
+ printk("10Mbps, full duplex\n");
+ } else if (mii_advertise & ADVERTISE_10HALF) {
+ np->speed = 10;
+ printk("10Mbps, half duplex\n");
+ } else
+ printk("\n");
+ } else {
+ mii_ctl = mdio_read(dev, np->phys[0], MII_BMCR);
+ speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
+ np->speed = speed;
+ printk(KERN_INFO "%s: Link changed: %dMbps ,",
+ dev->name, speed);
+ printk("%s duplex.\n",
+ (mii_ctl & BMCR_FULLDPLX) ?
+ "full" : "half");
+ }
+ check_duplex(dev);
+ if (np->flowctrl && np->mii_if.full_duplex) {
+ iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
+ ioaddr + MulticastFilter1+2);
+ iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
+ ioaddr + MACCtrl0);
+ }
+ netif_carrier_on(dev);
} else {
- mii_ctl = mdio_read (dev, np->phys[0], MII_BMCR);
- speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
- np->speed = speed;
- printk (KERN_INFO "%s: Link changed: %dMbps ,",
- dev->name, speed);
- printk ("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
- "full" : "half");
- }
- check_duplex (dev);
- if (np->flowctrl && np->mii_if.full_duplex) {
- iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
- ioaddr + MulticastFilter1+2);
- iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
- ioaddr + MACCtrl0);
+ printk(KERN_INFO "%s: Link down\n", dev->name);
+ netif_carrier_off(dev);
}
}
if (intr_status & StatsMax) {
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index 7db48f1..efaf84d 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -539,22 +539,22 @@ struct txd_desc {
#define ERR(fmt, args...) printk(KERN_ERR fmt, ## args)
#define DBG2(fmt, args...) \
- printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+ printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args)
#define BDX_ASSERT(x) BUG_ON(x)
#ifdef DEBUG
#define ENTER do { \
- printk(KERN_ERR "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); \
+ printk(KERN_ERR "%s:%-5d: ENTER\n", __func__, __LINE__); \
} while (0)
#define RET(args...) do { \
- printk(KERN_ERR "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__); \
+ printk(KERN_ERR "%s:%-5d: RETURN\n", __func__, __LINE__); \
return args; } while (0)
#define DBG(fmt, args...) \
- printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+ printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args)
#else
#define ENTER do { } while (0)
#define RET(args...) return args
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 43fde99..eb1da6f 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -263,7 +263,7 @@ static inline void tsi108_write_tbi(struct tsi108_prv_data *data,
return;
udelay(10);
}
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
}
static int mii_speed(struct mii_if_info *mii)
@@ -1059,7 +1059,7 @@ static void tsi108_stop_ethernet(struct net_device *dev)
return;
udelay(10);
}
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
}
static void tsi108_reset_ether(struct tsi108_prv_data * data)
@@ -1244,7 +1244,7 @@ static void tsi108_init_phy(struct net_device *dev)
udelay(10);
}
if (i == 0)
- printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+ printk(KERN_ERR "%s function time out \n", __func__);
if (data->phy_type == TSI108_PHY_BCM54XX) {
tsi108_write_mii(data, 0x09, 0x0300);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 9281d06..f54c450 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1418,7 +1418,6 @@ static int de_close (struct net_device *dev)
de_free_rings(de);
de_adapter_sleep(de);
- pci_disable_device(de->pdev);
return 0;
}
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 8f944e5..c87747b 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -400,7 +400,7 @@ static struct enet_addr_container *get_enet_addr_container(void)
enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL);
if (!enet_addr_cont) {
ugeth_err("%s: No memory for enet_addr_container object.",
- __FUNCTION__);
+ __func__);
return NULL;
}
@@ -427,7 +427,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
if (!(paddr_num < NUM_OF_PADDRS)) {
- ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__);
+ ugeth_warn("%s: Illegal paddr_num.", __func__);
return -EINVAL;
}
@@ -447,7 +447,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
if (!(paddr_num < NUM_OF_PADDRS)) {
- ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+ ugeth_warn("%s: Illagel paddr_num.", __func__);
return -EINVAL;
}
@@ -1441,7 +1441,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
u32 upsmr, maccfg2, tbiBaseAddress;
u16 value;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
ug_info = ugeth->ug_info;
ug_regs = ugeth->ug_regs;
@@ -1504,7 +1504,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
- __FUNCTION__);
+ __func__);
return ret_val;
}
@@ -1744,7 +1744,7 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ ugeth_err("%s: ucc_num out of range.", __func__);
return -EINVAL;
}
@@ -1773,7 +1773,7 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ ugeth_err("%s: ucc_num out of range.", __func__);
return -EINVAL;
}
@@ -2062,7 +2062,7 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth
ugeth_warn
("%s: multicast address added to paddr will have no "
"effect - is this what you wanted?",
- __FUNCTION__);
+ __func__);
ugeth->indAddrRegUsed[paddr_num] = 1; /* mark this paddr as used */
/* store address in our database */
@@ -2278,7 +2278,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
struct phy_device *phydev = ugeth->phydev;
u32 tempval;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
/* Disable the controller */
ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
@@ -2315,7 +2315,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: Bad memory partition value.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2327,7 +2327,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2338,7 +2338,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: Tx BD ring length must be no smaller than 2.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2349,21 +2349,21 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err
("%s: max_rx_buf_length must be non-zero multiple of 128.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
/* num Tx queues */
if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+ ugeth_err("%s: number of tx queues too large.", __func__);
return -EINVAL;
}
/* num Rx queues */
if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+ ugeth_err("%s: number of rx queues too large.", __func__);
return -EINVAL;
}
@@ -2374,7 +2374,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ugeth_err
("%s: VLAN priority table entry must not be"
" larger than number of Rx queues.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2386,7 +2386,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
ugeth_err
("%s: IP priority table entry must not be"
" larger than number of Rx queues.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
}
@@ -2394,7 +2394,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (ug_info->cam && !ug_info->ecamptr) {
if (netif_msg_probe(ugeth))
ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2404,7 +2404,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (netif_msg_probe(ugeth))
ugeth_err("%s: Number of station addresses greater than 1 "
"not allowed in extended parsing mode.",
- __FUNCTION__);
+ __func__);
return -EINVAL;
}
@@ -2418,7 +2418,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* Initialize the general fast UCC block. */
if (ucc_fast_init(uf_info, &ugeth->uccf)) {
if (netif_msg_probe(ugeth))
- ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+ ugeth_err("%s: Failed to init uccf.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2448,7 +2448,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
u8 __iomem *endOfRing;
u8 numThreadsRxNumerical, numThreadsTxNumerical;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
uccf = ugeth->uccf;
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
@@ -2474,7 +2474,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
default:
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Bad number of Rx threads value.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2499,7 +2499,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
default:
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Bad number of Tx threads value.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2553,7 +2553,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: IPGIFG initialization parameter too large.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -2571,7 +2571,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ret_val != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Half Duplex initialization parameter too large.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -2626,7 +2626,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for Tx bd rings.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2662,7 +2662,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for Rx bd rings.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2678,7 +2678,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ugeth->tx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Could not allocate tx_skbuff",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2710,7 +2710,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ugeth->rx_skbuff[j] == NULL) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Could not allocate rx_skbuff",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2744,7 +2744,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2767,7 +2767,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2797,7 +2797,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2841,7 +2841,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_scheduler.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2892,7 +2892,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_tx_fw_statistics_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2932,7 +2932,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2954,7 +2954,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2978,7 +2978,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_rx_fw_statistics_pram.", __FUNCTION__);
+ " p_rx_fw_statistics_pram.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3001,7 +3001,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_rx_irq_coalescing_tbl.", __FUNCTION__);
+ " p_rx_irq_coalescing_tbl.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3070,7 +3070,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3147,7 +3147,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (!ug_info->extendedFilteringChainPointer) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Null Extended Filtering Chain Pointer.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3161,7 +3161,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for"
- " p_exf_glbl_param.", __FUNCTION__);
+ " p_exf_glbl_param.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3209,7 +3209,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate memory for"
- " p_UccInitEnetParamShadows.", __FUNCTION__);
+ " p_UccInitEnetParamShadows.", __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3244,7 +3244,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Invalid largest External Lookup Key Size.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3271,7 +3271,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->riscRx, 1)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3287,7 +3287,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->riscTx, 0)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3297,7 +3297,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Can not fill Rx bds with buffers.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3309,7 +3309,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
ugeth_err
("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
- __FUNCTION__);
+ __func__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3360,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
dev->stats.tx_errors++;
@@ -3386,7 +3386,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 bd_status;
u8 txQ = 0;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
spin_lock_irq(&ugeth->lock);
@@ -3459,7 +3459,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
u8 *bdBuffer;
struct net_device *dev;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
dev = ugeth->dev;
@@ -3481,7 +3481,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
(bd_status & R_ERRORS_FATAL)) {
if (netif_msg_rx_err(ugeth))
ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
- __FUNCTION__, __LINE__, (u32) skb);
+ __func__, __LINE__, (u32) skb);
if (skb)
dev_kfree_skb_any(skb);
@@ -3507,7 +3507,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
skb = get_new_skb(ugeth, bd);
if (!skb) {
if (netif_msg_rx_err(ugeth))
- ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+ ugeth_warn("%s: No Rx Data Buffer", __func__);
dev->stats.rx_dropped++;
break;
}
@@ -3613,7 +3613,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
register u32 tx_mask;
u8 i;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
uccf = ugeth->uccf;
ug_info = ugeth->ug_info;
@@ -3683,13 +3683,13 @@ static int ucc_geth_open(struct net_device *dev)
struct ucc_geth_private *ugeth = netdev_priv(dev);
int err;
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
/* Test station address */
if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Multicast address used for station address"
- " - is this what you wanted?", __FUNCTION__);
+ " - is this what you wanted?", __func__);
return -EINVAL;
}
@@ -3772,7 +3772,7 @@ static int ucc_geth_close(struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
napi_disable(&ugeth->napi);
@@ -3840,7 +3840,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
};
- ugeth_vdbg("%s: IN", __FUNCTION__);
+ ugeth_vdbg("%s: IN", __func__);
prop = of_get_property(np, "cell-index", NULL);
if (!prop) {
@@ -3857,7 +3857,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
if (ug_info == NULL) {
if (netif_msg_probe(&debug))
ugeth_err("%s: [%d] Missing additional data!",
- __FUNCTION__, ucc_num);
+ __func__, ucc_num);
return -ENODEV;
}
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 6e42b5a..1164c52 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -92,9 +92,6 @@
#define HSO_NET_TX_TIMEOUT (HZ*10)
-/* Serial port defines and structs. */
-#define HSO_SERIAL_FLAG_RX_SENT 0
-
#define HSO_SERIAL_MAGIC 0x48534f31
/* Number of ttys to handle */
@@ -179,6 +176,12 @@ struct hso_net {
unsigned long flags;
};
+enum rx_ctrl_state{
+ RX_IDLE,
+ RX_SENT,
+ RX_PENDING
+};
+
struct hso_serial {
struct hso_device *parent;
int magic;
@@ -205,7 +208,7 @@ struct hso_serial {
struct usb_endpoint_descriptor *in_endp;
struct usb_endpoint_descriptor *out_endp;
- unsigned long flags;
+ enum rx_ctrl_state rx_state;
u8 rts_state;
u8 dtr_state;
unsigned tx_urb_used:1;
@@ -216,6 +219,15 @@ struct hso_serial {
spinlock_t serial_lock;
int (*write_data) (struct hso_serial *serial);
+ /* Hacks required to get flow control
+ * working on the serial receive buffers
+ * so as not to drop characters on the floor.
+ */
+ int curr_rx_urb_idx;
+ u16 curr_rx_urb_offset;
+ u8 rx_urb_filled[MAX_RX_URBS];
+ struct tasklet_struct unthrottle_tasklet;
+ struct work_struct retry_unthrottle_workqueue;
};
struct hso_device {
@@ -271,7 +283,7 @@ struct hso_device {
static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void ctrl_callback(struct urb *urb);
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
static void hso_kick_transmit(struct hso_serial *serial);
/* Helper functions */
static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
@@ -287,6 +299,8 @@ static int hso_start_net_device(struct hso_device *hso_dev);
static void hso_free_shared_int(struct hso_shared_int *shared_int);
static int hso_stop_net_device(struct hso_device *hso_dev);
static void hso_serial_ref_free(struct kref *ref);
+static void hso_std_serial_read_bulk_callback(struct urb *urb);
+static int hso_mux_serial_read(struct hso_serial *serial);
static void async_get_intf(struct work_struct *data);
static void async_put_intf(struct work_struct *data);
static int hso_put_activity(struct hso_device *hso_dev);
@@ -458,6 +472,17 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
}
static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
+static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
+{
+ int idx;
+
+ for (idx = 0; idx < serial->num_rx_urbs; idx++)
+ if (serial->rx_urb[idx] == urb)
+ return idx;
+ dev_err(serial->parent->dev, "hso_urb_to_index failed\n");
+ return -1;
+}
+
/* converts mux value to a port spec value */
static u32 hso_mux_to_port(int mux)
{
@@ -1039,6 +1064,158 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
return;
}
+static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
+{
+ int result;
+#ifdef CONFIG_HSO_AUTOPM
+ usb_mark_last_busy(urb->dev);
+#endif
+ /* We are done with this URB, resubmit it. Prep the USB to wait for
+ * another frame */
+ usb_fill_bulk_urb(urb, serial->parent->usb,
+ usb_rcvbulkpipe(serial->parent->usb,
+ serial->in_endp->
+ bEndpointAddress & 0x7F),
+ urb->transfer_buffer, serial->rx_data_length,
+ hso_std_serial_read_bulk_callback, serial);
+ /* Give this to the USB subsystem so it can tell us when more data
+ * arrives. */
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n",
+ __func__, result);
+ }
+}
+
+
+
+
+static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
+{
+ int count;
+ struct urb *curr_urb;
+
+ while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) {
+ curr_urb = serial->rx_urb[serial->curr_rx_urb_idx];
+ count = put_rxbuf_data(curr_urb, serial);
+ if (count == -1)
+ return;
+ if (count == 0) {
+ serial->curr_rx_urb_idx++;
+ if (serial->curr_rx_urb_idx >= serial->num_rx_urbs)
+ serial->curr_rx_urb_idx = 0;
+ hso_resubmit_rx_bulk_urb(serial, curr_urb);
+ }
+ }
+}
+
+static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
+{
+ int count = 0;
+ struct urb *urb;
+
+ urb = serial->rx_urb[0];
+ if (serial->open_count > 0) {
+ count = put_rxbuf_data(urb, serial);
+ if (count == -1)
+ return;
+ }
+ /* Re issue a read as long as we receive data. */
+
+ if (count == 0 && ((urb->actual_length != 0) ||
+ (serial->rx_state == RX_PENDING))) {
+ serial->rx_state = RX_SENT;
+ hso_mux_serial_read(serial);
+ } else
+ serial->rx_state = RX_IDLE;
+}
+
+
+/* read callback for Diag and CS port */
+static void hso_std_serial_read_bulk_callback(struct urb *urb)
+{
+ struct hso_serial *serial = urb->context;
+ int status = urb->status;
+
+ /* sanity check */
+ if (!serial) {
+ D1("serial == NULL");
+ return;
+ } else if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+
+ D4("\n--- Got serial_read_bulk callback %02x ---", status);
+ D1("Actual length = %d\n", urb->actual_length);
+ DUMP1(urb->transfer_buffer, urb->actual_length);
+
+ /* Anyone listening? */
+ if (serial->open_count == 0)
+ return;
+
+ if (status == 0) {
+ if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
+ u32 rest;
+ u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+ rest =
+ urb->actual_length %
+ serial->in_endp->wMaxPacketSize;
+ if (((rest == 5) || (rest == 6))
+ && !memcmp(((u8 *) urb->transfer_buffer) +
+ urb->actual_length - 4, crc_check, 4)) {
+ urb->actual_length -= 4;
+ }
+ }
+ /* Valid data, handle RX data */
+ spin_lock(&serial->serial_lock);
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
+ put_rxbuf_data_and_resubmit_bulk_urb(serial);
+ spin_unlock(&serial->serial_lock);
+ } else if (status == -ENOENT || status == -ECONNRESET) {
+ /* Unlinked - check for throttled port. */
+ D2("Port %d, successfully unlinked urb", serial->minor);
+ spin_lock(&serial->serial_lock);
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
+ hso_resubmit_rx_bulk_urb(serial, urb);
+ spin_unlock(&serial->serial_lock);
+ } else {
+ D2("Port %d, status = %d for read urb", serial->minor, status);
+ return;
+ }
+}
+
+/*
+ * This needs to be a tasklet otherwise we will
+ * end up recursively calling this function.
+ */
+void hso_unthrottle_tasklet(struct hso_serial *serial)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ if ((serial->parent->port_spec & HSO_INTF_MUX))
+ put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+ else
+ put_rxbuf_data_and_resubmit_bulk_urb(serial);
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+}
+
+static void hso_unthrottle(struct tty_struct *tty)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+
+ tasklet_hi_schedule(&serial->unthrottle_tasklet);
+}
+
+void hso_unthrottle_workfunc(struct work_struct *work)
+{
+ struct hso_serial *serial =
+ container_of(work, struct hso_serial,
+ retry_unthrottle_workqueue);
+ hso_unthrottle_tasklet(serial);
+}
+
/* open the requested serial port */
static int hso_serial_open(struct tty_struct *tty, struct file *filp)
{
@@ -1064,13 +1241,18 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = serial;
serial->tty = tty;
- /* check for port allready opened, if not set the termios */
+ /* check for port already opened, if not set the termios */
serial->open_count++;
if (serial->open_count == 1) {
tty->low_latency = 1;
- serial->flags = 0;
+ serial->rx_state = RX_IDLE;
/* Force default termio settings */
_hso_serial_set_termios(tty, NULL);
+ tasklet_init(&serial->unthrottle_tasklet,
+ (void (*)(unsigned long))hso_unthrottle_tasklet,
+ (unsigned long)serial);
+ INIT_WORK(&serial->retry_unthrottle_workqueue,
+ hso_unthrottle_workfunc);
result = hso_start_serial_device(serial->parent, GFP_KERNEL);
if (result) {
hso_stop_serial_device(serial->parent);
@@ -1117,9 +1299,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
}
if (!usb_gone)
hso_stop_serial_device(serial->parent);
+ tasklet_kill(&serial->unthrottle_tasklet);
+ cancel_work_sync(&serial->retry_unthrottle_workqueue);
}
+
if (!usb_gone)
usb_autopm_put_interface(serial->parent->interface);
+
mutex_unlock(&serial->parent->mutex);
}
@@ -1422,15 +1608,21 @@ static void intr_callback(struct urb *urb)
(1 << i));
if (serial != NULL) {
D1("Pending read interrupt on port %d\n", i);
- if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT,
- &serial->flags)) {
+ spin_lock(&serial->serial_lock);
+ if (serial->rx_state == RX_IDLE) {
/* Setup and send a ctrl req read on
* port i */
- hso_mux_serial_read(serial);
+ if (!serial->rx_urb_filled[0]) {
+ serial->rx_state = RX_SENT;
+ hso_mux_serial_read(serial);
+ } else
+ serial->rx_state = RX_PENDING;
+
} else {
D1("Already pending a read on "
"port %d\n", i);
}
+ spin_unlock(&serial->serial_lock);
}
}
}
@@ -1532,16 +1724,10 @@ static void ctrl_callback(struct urb *urb)
if (req->bRequestType ==
(USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
/* response to a read command */
- if (serial->open_count > 0) {
- /* handle RX data the normal way */
- put_rxbuf_data(urb, serial);
- }
-
- /* Re issue a read as long as we receive data. */
- if (urb->actual_length != 0)
- hso_mux_serial_read(serial);
- else
- clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
+ serial->rx_urb_filled[0] = 1;
+ spin_lock(&serial->serial_lock);
+ put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+ spin_unlock(&serial->serial_lock);
} else {
hso_put_activity(serial->parent);
if (serial->tty)
@@ -1552,91 +1738,42 @@ static void ctrl_callback(struct urb *urb)
}
/* handle RX data for serial port */
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
{
struct tty_struct *tty = serial->tty;
-
+ int write_length_remaining = 0;
+ int curr_write_len;
/* Sanity check */
if (urb == NULL || serial == NULL) {
D1("serial = NULL");
- return;
+ return -2;
}
/* Push data to tty */
- if (tty && urb->actual_length) {
+ if (tty) {
+ write_length_remaining = urb->actual_length -
+ serial->curr_rx_urb_offset;
D1("data to push to tty");
- tty_insert_flip_string(tty, urb->transfer_buffer,
- urb->actual_length);
- tty_flip_buffer_push(tty);
- }
-}
-
-/* read callback for Diag and CS port */
-static void hso_std_serial_read_bulk_callback(struct urb *urb)
-{
- struct hso_serial *serial = urb->context;
- int result;
- int status = urb->status;
-
- /* sanity check */
- if (!serial) {
- D1("serial == NULL");
- return;
- } else if (status) {
- log_usb_status(status, __func__);
- return;
- }
-
- D4("\n--- Got serial_read_bulk callback %02x ---", status);
- D1("Actual length = %d\n", urb->actual_length);
- DUMP1(urb->transfer_buffer, urb->actual_length);
-
- /* Anyone listening? */
- if (serial->open_count == 0)
- return;
-
- if (status == 0) {
- if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
- u32 rest;
- u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
- rest =
- urb->actual_length %
- serial->in_endp->wMaxPacketSize;
- if (((rest == 5) || (rest == 6))
- && !memcmp(((u8 *) urb->transfer_buffer) +
- urb->actual_length - 4, crc_check, 4)) {
- urb->actual_length -= 4;
- }
+ while (write_length_remaining) {
+ if (test_bit(TTY_THROTTLED, &tty->flags))
+ return -1;
+ curr_write_len = tty_insert_flip_string
+ (tty, urb->transfer_buffer +
+ serial->curr_rx_urb_offset,
+ write_length_remaining);
+ serial->curr_rx_urb_offset += curr_write_len;
+ write_length_remaining -= curr_write_len;
+ tty_flip_buffer_push(tty);
}
- /* Valid data, handle RX data */
- put_rxbuf_data(urb, serial);
- } else if (status == -ENOENT || status == -ECONNRESET) {
- /* Unlinked - check for throttled port. */
- D2("Port %d, successfully unlinked urb", serial->minor);
- } else {
- D2("Port %d, status = %d for read urb", serial->minor, status);
- return;
}
-
- usb_mark_last_busy(urb->dev);
-
- /* We are done with this URB, resubmit it. Prep the USB to wait for
- * another frame */
- usb_fill_bulk_urb(urb, serial->parent->usb,
- usb_rcvbulkpipe(serial->parent->usb,
- serial->in_endp->
- bEndpointAddress & 0x7F),
- urb->transfer_buffer, serial->rx_data_length,
- hso_std_serial_read_bulk_callback, serial);
- /* Give this to the USB subsystem so it can tell us when more data
- * arrives. */
- result = usb_submit_urb(urb, GFP_ATOMIC);
- if (result) {
- dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d",
- __func__, result);
+ if (write_length_remaining == 0) {
+ serial->curr_rx_urb_offset = 0;
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
}
+ return write_length_remaining;
}
+
/* Base driver functions */
static void hso_log_port(struct hso_device *hso_dev)
@@ -1794,9 +1931,13 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
return -ENODEV;
for (i = 0; i < serial->num_rx_urbs; i++) {
- if (serial->rx_urb[i])
+ if (serial->rx_urb[i]) {
usb_kill_urb(serial->rx_urb[i]);
+ serial->rx_urb_filled[i] = 0;
+ }
}
+ serial->curr_rx_urb_idx = 0;
+ serial->curr_rx_urb_offset = 0;
if (serial->tx_urb)
usb_kill_urb(serial->tx_urb);
@@ -2211,14 +2352,14 @@ static struct hso_device *hso_create_bulk_serial_device(
USB_DIR_IN);
if (!serial->in_endp) {
dev_err(&interface->dev, "Failed to find BULK IN ep\n");
- goto exit;
+ goto exit2;
}
if (!
(serial->out_endp =
hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) {
dev_err(&interface->dev, "Failed to find BULK IN ep\n");
- goto exit;
+ goto exit2;
}
serial->write_data = hso_std_serial_write_data;
@@ -2231,9 +2372,10 @@ static struct hso_device *hso_create_bulk_serial_device(
/* done, return it */
return hso_dev;
+
+exit2:
+ hso_serial_common_free(serial);
exit:
- if (hso_dev && serial)
- hso_serial_common_free(serial);
kfree(serial);
hso_free_device(hso_dev);
return NULL;
@@ -2740,6 +2882,7 @@ static const struct tty_operations hso_serial_ops = {
.chars_in_buffer = hso_serial_chars_in_buffer,
.tiocmget = hso_serial_tiocmget,
.tiocmset = hso_serial_tiocmset,
+ .unthrottle = hso_unthrottle
};
static struct usb_driver hso_driver = {
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index ca9d00c..b514350 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -118,7 +118,7 @@ static void mcs7830_async_cmd_callback(struct urb *urb)
if (urb->status < 0)
printk(KERN_DEBUG "%s() failed with %d\n",
- __FUNCTION__, urb->status);
+ __func__, urb->status);
kfree(req);
usb_free_urb(urb);
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 8c19307..38b90e7 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -119,7 +119,7 @@ static void ctrl_callback(struct urb *urb)
default:
if (netif_msg_drv(pegasus) && printk_ratelimit())
dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, urb->status);
+ __func__, urb->status);
}
pegasus->flags &= ~ETH_REGS_CHANGED;
wake_up(&pegasus->ctrl_wait);
@@ -136,7 +136,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
if (!buffer) {
if (netif_msg_drv(pegasus))
dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
add_wait_queue(&pegasus->ctrl_wait, &wait);
@@ -224,7 +224,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus))
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -246,7 +246,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
if (!tmp) {
if (netif_msg_drv(pegasus))
dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
memcpy(tmp, &data, 1);
@@ -277,7 +277,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus) && printk_ratelimit())
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -310,7 +310,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus))
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
}
return ret;
@@ -341,7 +341,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
}
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return ret;
}
@@ -378,7 +378,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
@@ -415,7 +415,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
@@ -463,7 +463,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
return ret;
fail:
if (netif_msg_drv(pegasus))
- dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+ dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
return -ETIMEDOUT;
}
#endif /* PEGASUS_WRITE_EEPROM */
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 1b95b04..29a3309 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1381,7 +1381,7 @@ enum velocity_msg_level {
#define ASSERT(x) { \
if (!(x)) { \
printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
- __FUNCTION__, __LINE__);\
+ __func__, __LINE__);\
BUG(); \
}\
}
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index d14e667..a5ddc6c 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -407,7 +407,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
if (cfm->version != CFM_VERSION) {
printk(KERN_ERR "%s:%s: firmware format %u rejected! "
"Expecting %u.\n",
- modname, __FUNCTION__, cfm->version, CFM_VERSION);
+ modname, __func__, cfm->version, CFM_VERSION);
return -EINVAL;
}
@@ -420,7 +420,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
*/
if (cksum != cfm->checksum) {
printk(KERN_ERR "%s:%s: firmware corrupted!\n",
- modname, __FUNCTION__);
+ modname, __func__);
printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n",
len - (int)sizeof(struct cycx_firmware) - 1,
cfm->info.codesize);
@@ -432,7 +432,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
/* If everything is ok, set reset, data and code pointers */
img_hdr = (struct cycx_fw_header *)&cfm->image;
#ifdef FIRMWARE_DEBUG
- printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname);
+ printk(KERN_INFO "%s:%s: image sizes\n", __func__, modname);
printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size);
printk(KERN_INFO " data=%lu\n", img_hdr->data_size);
printk(KERN_INFO " code=%lu\n", img_hdr->code_size);
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index d3b28b0..5a7303d 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -874,7 +874,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
- __FUNCTION__, lcn, loc, rem);
+ __func__, lcn, loc, rem);
dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
if (!dev) {
@@ -902,7 +902,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
- card->devname, __FUNCTION__, lcn, key);
+ card->devname, __func__, lcn, key);
dev = cycx_x25_get_dev_by_lcn(wandev, -key);
if (!dev) {
@@ -929,7 +929,7 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
- card->devname, __FUNCTION__, lcn);
+ card->devname, __func__, lcn);
dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
if (!dev) {
/* Invalid channel, discard packet */
@@ -950,7 +950,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card,
u8 lcn;
cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
- dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
+ dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
if (dev) {
@@ -1381,7 +1381,7 @@ static void cycx_x25_chan_timer(unsigned long d)
cycx_x25_chan_disconnect(dev);
else
printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
- chan->card->devname, __FUNCTION__, dev->name);
+ chan->card->devname, __func__, dev->name);
}
/* Set logical channel state. */
@@ -1485,7 +1485,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
unsigned char *ptr;
if ((skb = dev_alloc_skb(1)) == NULL) {
- printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+ printk(KERN_ERR "%s: out of memory\n", __func__);
return;
}
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index f5d55ad..5f1ccb2 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -647,7 +647,7 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
skb = dpriv->rx_skbuff[dpriv->rx_current++%RX_RING_SIZE];
if (!skb) {
- printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
+ printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __func__);
goto refill;
}
pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2));
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index 8b7e5d2..cbcbf6f 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -163,15 +163,17 @@ static void x25_close(struct net_device *dev)
static int x25_rx(struct sk_buff *skb)
{
+ struct net_device *dev = skb->dev;
+
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
- skb->dev->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return NET_RX_DROP;
}
- if (lapb_data_received(skb->dev, skb) == LAPB_OK)
+ if (lapb_data_received(dev, skb) == LAPB_OK)
return NET_RX_SUCCESS;
- skb->dev->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb_any(skb);
return NET_RX_DROP;
}
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 4518d0a..4917a94 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -548,7 +548,7 @@ static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
{
st_cpc_tty_area *cpc_tty;
- CPC_TTY_DBG("%s: set:%x clear:%x\n", __FUNCTION__, set, clear);
+ CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear);
if (!tty || !tty->driver_data ) {
CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6f4276d..a65b082 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2247,6 +2247,16 @@
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
+#define PCI_VENDOR_ID_NETXEN 0x4040
+#define PCI_DEVICE_ID_NX2031_10GXSR 0x0001
+#define PCI_DEVICE_ID_NX2031_10GCX4 0x0002
+#define PCI_DEVICE_ID_NX2031_4GCU 0x0003
+#define PCI_DEVICE_ID_NX2031_IMEZ 0x0004
+#define PCI_DEVICE_ID_NX2031_HMEZ 0x0005
+#define PCI_DEVICE_ID_NX2031_XG_MGMT 0x0024
+#define PCI_DEVICE_ID_NX2031_XG_MGMT2 0x0025
+#define PCI_DEVICE_ID_NX3031 0x0100
+
#define PCI_VENDOR_ID_AKS 0x416c
#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-24 23:07 Jeff Garzik
@ 2008-09-24 23:21 ` David Miller
2008-09-25 6:55 ` Sebastien Dugue
1 sibling, 0 replies; 11+ messages in thread
From: David Miller @ 2008-09-24 23:21 UTC (permalink / raw)
To: jeff; +Cc: netdev, linux-kernel, torvalds, akpm
From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 24 Sep 2008 19:07:10 -0400
> Please pull from 'davem-next' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-next
>
> to receive the following updates:
Pulled and pushed back out to net-next-2.6, thanks!
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-24 23:07 Jeff Garzik
2008-09-24 23:21 ` David Miller
@ 2008-09-25 6:55 ` Sebastien Dugue
2008-09-25 17:38 ` Jeff Garzik
1 sibling, 1 reply; 11+ messages in thread
From: Sebastien Dugue @ 2008-09-25 6:55 UTC (permalink / raw)
To: Jeff Garzik
Cc: David Miller, netdev, LKML, torvalds, Andrew Morton, Thomas Klein
Hi Jeff,
On Wed, 24 Sep 2008 19:07:10 -0400 Jeff Garzik <jeff@garzik.org> wrote:
> Sebastien Dugue (2):
> ehea: fix phyp debugging typo
> ehea: fix mutex and spinlock use
^^^^^^
That last one was NACKed by Thomas Klein (http://lkml.org/lkml/2008/9/15/81)
who asked for it to be reverted.
Thanks,
Sebastien.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-25 6:55 ` Sebastien Dugue
@ 2008-09-25 17:38 ` Jeff Garzik
2008-09-25 20:07 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Jeff Garzik @ 2008-09-25 17:38 UTC (permalink / raw)
To: David Miller
Cc: Sebastien Dugue, netdev, LKML, torvalds, Andrew Morton,
Thomas Klein
Sebastien Dugue wrote:
> Hi Jeff,
>
> On Wed, 24 Sep 2008 19:07:10 -0400 Jeff Garzik <jeff@garzik.org> wrote:
>
>
>> Sebastien Dugue (2):
>> ehea: fix phyp debugging typo
>
>
>> ehea: fix mutex and spinlock use
>
> ^^^^^^
>
> That last one was NACKed by Thomas Klein (http://lkml.org/lkml/2008/9/15/81)
> who asked for it to be reverted.
David, please revert 2eefbd63d0c85daa1317636474c226e236beba81 by request
of author, maintainer, and maintainer's maintainer :)
Jeff
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [git patches] net driver updates for .28
2008-09-25 17:38 ` Jeff Garzik
@ 2008-09-25 20:07 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2008-09-25 20:07 UTC (permalink / raw)
To: jeff; +Cc: sebastien.dugue, netdev, linux-kernel, torvalds, akpm, osstklei
From: Jeff Garzik <jeff@garzik.org>
Date: Thu, 25 Sep 2008 13:38:21 -0400
> David, please revert 2eefbd63d0c85daa1317636474c226e236beba81 by
> request of author, maintainer, and maintainer's maintainer :)
Done.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-09-25 20:08 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-14 2:22 [git patches] net driver updates for .28 Jeff Garzik
2008-09-20 7:09 ` David Miller
2008-09-20 7:28 ` Brice Goglin
2008-09-20 10:33 ` David Miller
-- strict thread matches above, loose matches on Subject: below --
2008-09-24 23:07 Jeff Garzik
2008-09-24 23:21 ` David Miller
2008-09-25 6:55 ` Sebastien Dugue
2008-09-25 17:38 ` Jeff Garzik
2008-09-25 20:07 ` David Miller
2008-09-03 14:37 Jeff Garzik
2008-09-03 22:08 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).