aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-26 15:09:20 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-26 15:09:20 -0800
commit924d26df6b774b85c8b4548189b20e34f904a149 (patch)
tree59e0810a0149a1f8f1d15613c50e4896993310d8 /drivers
parent66673f13c10a817e27d71434c1198a4d874e0cd3 (diff)
parentcd1f55a5b49b74e13ed9e7bc74d005803aaa0da8 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (92 commits) gianfar: Revive VLAN support vlan: Export symbols as non GPL symbols. bnx2x: tx_has_work should not wait for FW netxen: reduce memory footprint netxen: fix vlan tso/checksum offload net: Fix linux/if_frad.h's suitability for userspace. net: Move config NET_NS to from net/Kconfig to init/Kconfig isdn: Fix missing ifdef in isdn_ppp networking: document "nc" in addition to "netcat" in netconsole.txt e1000e: workaround hw errata af_key: initialize xfrm encap_oa virtio_net: Fix MAX_PACKET_LEN to support 802.1Q VLANs lcs: fix compilation for !CONFIG_IP_MULTICAST rtl8187: Add termination packet to prevent stall iwlwifi: fix rs_get_rate WARN_ON() p54usb: fix packet loss with first generation devices sctp: Fix another socket race during accept/peeloff sctp: Properly timestamp outgoing data chunks for rtx purposes sctp: Correctly start rtx timer on new packet transmissions. sctp: Fix crc32c calculations on big-endian arhes. ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c2
-rw-r--r--drivers/net/bnx2x.h11
-rw-r--r--drivers/net/bnx2x_link.c64
-rw-r--r--drivers/net/bnx2x_main.c302
-rw-r--r--drivers/net/bnx2x_reg.h2
-rw-r--r--drivers/net/cxgb3/sge.c1
-rw-r--r--drivers/net/e1000e/82571.c6
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/gianfar.c6
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c62
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h3
-rw-r--r--drivers/net/korina.c15
-rw-r--r--drivers/net/macb.c8
-rw-r--r--drivers/net/mv643xx_eth.c17
-rw-r--r--drivers/net/myri10ge/myri10ge.c15
-rw-r--r--drivers/net/netxen/netxen_nic.h12
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c5
-rw-r--r--drivers/net/netxen/netxen_nic_main.c31
-rw-r--r--drivers/net/phy/mdio_bus.c8
-rw-r--r--drivers/net/phy/smsc.c12
-rw-r--r--drivers/net/tg3.c81
-rw-r--r--drivers/net/tg3.h1
-rw-r--r--drivers/net/usb/mcs7830.c20
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/wimax/i2400m/control.c2
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c9
-rw-r--r--drivers/net/wireless/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h91
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c32
-rw-r--r--drivers/net/wireless/p54/p54common.c30
-rw-r--r--drivers/net/wireless/p54/p54usb.c41
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c1
-rw-r--r--drivers/s390/net/lcs.c8
44 files changed, 577 insertions, 375 deletions
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index a3551dd0324..aa30b5cb351 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -431,6 +431,7 @@ set_arg(void __user *b, void *val,int len)
return 0;
}
+#ifdef CONFIG_IPPP_FILTER
static int get_filter(void __user *arg, struct sock_filter **p)
{
struct sock_fprog uprog;
@@ -465,6 +466,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
*p = code;
return uprog.len;
}
+#endif /* CONFIG_IPPP_FILTER */
/*
* ippp device ioctl
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 6fcccef4cf3..15a5cf0f676 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -271,14 +271,7 @@ struct bnx2x_fastpath {
#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
-#define BNX2X_HAS_TX_WORK(fp) \
- ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
- (fp->tx_pkt_prod != fp->tx_pkt_cons))
-
-#define BNX2X_HAS_RX_WORK(fp) \
- (fp->rx_comp_cons != rx_cons_sb)
-
-#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
+#define BNX2X_HAS_WORK(fp) (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
/* MC hsi */
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index fefa6ab1306..aea26b4dc45 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
val &= ~0x810;
EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
+ /* enable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
/* enable emac for jumbo packets */
EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
(EMAC_RX_MTU_SIZE_JUMBO_ENA |
@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
u32 gp_status)
{
struct bnx2x *bp = params->bp;
-
+ u16 new_line_speed;
u8 rc = 0;
vars->link_status = 0;
@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M:
- vars->line_speed = SPEED_10;
+ new_line_speed = SPEED_10;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_10TFD;
else
@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_100M:
- vars->line_speed = SPEED_100;
+ new_line_speed = SPEED_100;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_100TXFD;
else
@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_1G:
case GP_STATUS_1G_KX:
- vars->line_speed = SPEED_1000;
+ new_line_speed = SPEED_1000;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_1000TFD;
else
@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_2_5G:
- vars->line_speed = SPEED_2500;
+ new_line_speed = SPEED_2500;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_2500TFD;
else
@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_10G_KX4:
case GP_STATUS_10G_HIG:
case GP_STATUS_10G_CX4:
- vars->line_speed = SPEED_10000;
+ new_line_speed = SPEED_10000;
vars->link_status |= LINK_10GTFD;
break;
case GP_STATUS_12G_HIG:
- vars->line_speed = SPEED_12000;
+ new_line_speed = SPEED_12000;
vars->link_status |= LINK_12GTFD;
break;
case GP_STATUS_12_5G:
- vars->line_speed = SPEED_12500;
+ new_line_speed = SPEED_12500;
vars->link_status |= LINK_12_5GTFD;
break;
case GP_STATUS_13G:
- vars->line_speed = SPEED_13000;
+ new_line_speed = SPEED_13000;
vars->link_status |= LINK_13GTFD;
break;
case GP_STATUS_15G:
- vars->line_speed = SPEED_15000;
+ new_line_speed = SPEED_15000;
vars->link_status |= LINK_15GTFD;
break;
case GP_STATUS_16G:
- vars->line_speed = SPEED_16000;
+ new_line_speed = SPEED_16000;
vars->link_status |= LINK_16GTFD;
break;
@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
}
+ /* Upon link speed change set the NIG into drain mode.
+ Comes to deals with possible FIFO glitch due to clk change
+ when speed is decreased without link down indicator */
+ if (new_line_speed != vars->line_speed) {
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+ msleep(1);
+ }
+ vars->line_speed = new_line_speed;
vars->link_status |= LINK_STATUS_SERDES_LINK;
if ((params->req_line_speed == SPEED_AUTO_NEG) &&
@@ -3571,7 +3583,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params,
(MDIO_REG_BANK_CL73_IEEEB0 +
(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
0x6041);
-
+ msleep(200);
/* set aer mmd back */
bnx2x_set_aer_mmd(params, vars);
@@ -3870,9 +3882,15 @@ static u8 bnx2x_link_initialize(struct link_params *params,
}
if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (params->req_line_speed &&
+ if ((params->req_line_speed &&
((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) {
+ (params->req_line_speed == SPEED_10))) ||
+ (!params->req_line_speed &&
+ (params->speed_cap_mask >=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+ (params->speed_cap_mask <
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ )) {
vars->phy_flags |= PHY_SGMII_FLAG;
} else {
vars->phy_flags &= ~PHY_SGMII_FLAG;
@@ -4194,6 +4212,11 @@ static u8 bnx2x_update_link_down(struct link_params *params,
/* activate nig drain */
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
/* reset BigMac */
bnx2x_bmac_rx_disable(bp, params->port);
REG_WR(bp, GRCBASE_MISC +
@@ -4238,6 +4261,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
/* update shared memory */
bnx2x_update_mng(params, vars->link_status);
+ msleep(20);
return rc;
}
/* This function should called upon link interrupt */
@@ -4276,6 +4300,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Check external link change only for non-direct */
@@ -4377,10 +4404,11 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
ext_phy_addr[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- if (fw_ver1 == 0) {
+ if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
DP(NETIF_MSG_LINK,
- "bnx2x_8073_common_init_phy port %x "
- "fw Download failed\n", port);
+ "bnx2x_8073_common_init_phy port %x:"
+ "Download failed. fw version = 0x%x\n",
+ port, fw_ver1);
return -EINVAL;
}
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 7c533797c06..d3e7775a9cc 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1,6 +1,6 @@
/* bnx2x_main.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,8 +57,8 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
-#define DRV_MODULE_VERSION "1.45.23"
-#define DRV_MODULE_RELDATE "2008/11/03"
+#define DRV_MODULE_VERSION "1.45.26"
+#define DRV_MODULE_RELDATE "2009/01/26"
#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung */
@@ -69,7 +69,7 @@ static char version[] __devinitdata =
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -733,6 +733,24 @@ static u16 bnx2x_ack_int(struct bnx2x *bp)
* fast path service functions
*/
+static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+ u16 tx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
+ return (fp->tx_pkt_cons != tx_cons_sb);
+}
+
+static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
+{
+ /* Tell compiler that consumer and producer can change */
+ barrier();
+ return (fp->tx_pkt_prod != fp->tx_pkt_cons);
+
+}
+
/* free skb in the packet ring at pos idx
* return idx of last bd freed
*/
@@ -5137,12 +5155,21 @@ static void enable_blocks_attention(struct bnx2x *bp)
}
+static void bnx2x_reset_common(struct bnx2x *bp)
+{
+ /* reset_common */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0xd3ffff7f);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
+}
+
static int bnx2x_init_common(struct bnx2x *bp)
{
u32 val, i;
DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
+ bnx2x_reset_common(bp);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
@@ -6123,8 +6150,8 @@ static void bnx2x_netif_start(struct bnx2x *bp)
static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
{
bnx2x_int_disable_sync(bp, disable_hw);
+ bnx2x_napi_disable(bp);
if (netif_running(bp->dev)) {
- bnx2x_napi_disable(bp);
netif_tx_disable(bp->dev);
bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
@@ -6144,7 +6171,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
* multicast 64-127:port0 128-191:port1
*/
config->hdr.length_6b = 2;
- config->hdr.offset = port ? 31 : 0;
+ config->hdr.offset = port ? 32 : 0;
config->hdr.client_id = BP_CL_ID(bp);
config->hdr.reserved1 = 0;
@@ -6308,7 +6335,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
u32 load_code;
- int i, rc;
+ int i, rc = 0;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return -EPERM;
@@ -6316,48 +6343,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
- /* Send LOAD_REQUEST command to MCP
- Returns the type of LOAD command:
- if it is the first port to be initialized
- common blocks should be initialized, otherwise - not
- */
- if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, aborting\n");
- return -EBUSY;
- }
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
- return -EBUSY; /* other port in diagnostic mode */
-
- } else {
- int port = BP_PORT(bp);
-
- DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]++;
- load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
- else if (load_count[1 + port] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_PORT;
- else
- load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
- }
-
- if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
- (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
- bp->port.pmf = 1;
- else
- bp->port.pmf = 0;
- DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
-
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to inta with one fp
- */
if (use_inta) {
bp->num_queues = 1;
@@ -6372,7 +6357,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
else
bp->num_queues = 1;
- if (bnx2x_enable_msix(bp)) {
+ DP(NETIF_MSG_IFUP,
+ "set number of queues to %d\n", bp->num_queues);
+
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to MSI or legacy INTx with one fp
+ */
+ rc = bnx2x_enable_msix(bp);
+ if (rc) {
/* failed to enable MSI-X */
bp->num_queues = 1;
if (use_multi)
@@ -6380,8 +6373,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
" to enable MSI-X\n");
}
}
- DP(NETIF_MSG_IFUP,
- "set number of queues to %d\n", bp->num_queues);
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
@@ -6390,30 +6381,85 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_fp(bp, i, disable_tpa) =
((bp->flags & TPA_ENABLE_FLAG) == 0);
+ for_each_queue(bp, i)
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, 128);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ fp->poll_no_work = 0;
+ fp->poll_calls = 0;
+ fp->poll_max_calls = 0;
+ fp->poll_complete = 0;
+ fp->poll_exit = 0;
+ }
+#endif
+ bnx2x_napi_enable(bp);
+
if (bp->flags & USING_MSIX_FLAG) {
rc = bnx2x_req_msix_irqs(bp);
if (rc) {
pci_disable_msix(bp->pdev);
- goto load_error;
+ goto load_error1;
}
+ printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
} else {
bnx2x_ack_int(bp);
rc = bnx2x_req_irq(bp);
if (rc) {
- BNX2X_ERR("IRQ request failed, aborting\n");
- goto load_error;
+ BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ goto load_error1;
}
}
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
+ /* Send LOAD_REQUEST command to MCP
+ Returns the type of LOAD command:
+ if it is the first port to be initialized
+ common blocks should be initialized, otherwise - not
+ */
+ if (!BP_NOMCP(bp)) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, aborting\n");
+ rc = -EBUSY;
+ goto load_error2;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ rc = -EBUSY; /* other port in diagnostic mode */
+ goto load_error2;
+ }
+
+ } else {
+ int port = BP_PORT(bp);
+
+ DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ load_count[0]++;
+ load_count[1 + port]++;
+ DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ if (load_count[0] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
+ else if (load_count[1 + port] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_PORT;
+ else
+ load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
+ }
+
+ if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
+ bp->port.pmf = 1;
+ else
+ bp->port.pmf = 0;
+ DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
/* Initialize HW */
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- goto load_int_disable;
+ goto load_error2;
}
/* Setup NIC internals and enable interrupts */
@@ -6425,7 +6471,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
- goto load_rings_free;
+ goto load_error3;
}
}
@@ -6434,7 +6480,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_setup_leading(bp);
if (rc) {
BNX2X_ERR("Setup leading failed!\n");
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1H(bp))
@@ -6447,7 +6493,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
for_each_nondefault_queue(bp, i) {
rc = bnx2x_setup_multi(bp, i);
if (rc)
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1(bp))
@@ -6463,18 +6509,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
netif_wake_queue(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
netif_start_queue(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
- if (bp->flags & USING_MSIX_FLAG)
- printk(KERN_INFO PFX "%s: using MSI-X\n",
- bp->dev->name);
break;
case LOAD_DIAG:
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
bp->state = BNX2X_STATE_DIAG;
break;
@@ -6492,20 +6538,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
return 0;
-load_netif_stop:
- bnx2x_napi_disable(bp);
-load_rings_free:
+load_error3:
+ bnx2x_int_disable_sync(bp, 1);
+ if (!BP_NOMCP(bp)) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ }
+ bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
- bnx2x_int_disable_sync(bp, 1);
+load_error2:
/* Release IRQs */
bnx2x_free_irq(bp);
-load_error:
+load_error1:
+ bnx2x_napi_disable(bp);
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
- bp->port.pmf = 0;
/* TBD we really need to reset the chip
if we want to recover from this */
@@ -6578,6 +6629,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
}
cnt--;
msleep(1);
+ rmb(); /* Refresh the dsb_sp_prod */
}
bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
@@ -6629,14 +6681,6 @@ static void bnx2x_reset_port(struct bnx2x *bp)
/* TODO: Close Doorbell port? */
}
-static void bnx2x_reset_common(struct bnx2x *bp)
-{
- /* reset_common */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffff7f);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
-}
-
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
@@ -6677,20 +6721,22 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_set_storm_rx_mode(bp);
bnx2x_netif_stop(bp, 1);
- if (!netif_running(bp->dev))
- bnx2x_napi_disable(bp);
+
del_timer_sync(&bp->timer);
SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
/* Wait until tx fast path tasks complete */
for_each_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
cnt = 1000;
smp_rmb();
- while (BNX2X_HAS_TX_WORK(fp)) {
+ while (bnx2x_has_tx_work_unload(fp)) {
bnx2x_tx_int(fp, 1000);
if (!cnt) {
@@ -6711,9 +6757,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
/* Give HW time to discard old tx messages */
msleep(1);
- /* Release IRQs */
- bnx2x_free_irq(bp);
-
if (CHIP_IS_E1(bp)) {
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
@@ -6822,6 +6865,8 @@ unload_error:
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -6874,10 +6919,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
*/
bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
- if (val == 0x7)
- REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
if (val == 0x7) {
u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
/* save our func */
@@ -6885,6 +6926,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
u32 swap_en;
u32 swap_val;
+ /* clear the UNDI indication */
+ REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
+
BNX2X_DEV_INFO("UNDI is active! reset device\n");
/* try unload UNDI on port 0 */
@@ -6910,6 +6954,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bnx2x_fw_command(bp, reset_code);
}
+ /* now it's safe to release the lock */
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+
REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
HC_REG_CONFIG_0), 0x1000);
@@ -6954,7 +7001,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bp->fw_seq =
(SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
- }
+
+ } else
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
}
}
@@ -6971,7 +7020,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
id |= ((val & 0xf) << 12);
val = REG_RD(bp, MISC_REG_CHIP_METAL);
id |= ((val & 0xff) << 4);
- REG_RD(bp, MISC_REG_BOND_ID);
+ val = REG_RD(bp, MISC_REG_BOND_ID);
id |= (val & 0xf);
bp->common.chip_id = id;
bp->link_params.chip_id = bp->common.chip_id;
@@ -8103,6 +8152,9 @@ static int bnx2x_get_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int rc;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
@@ -8705,18 +8757,17 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)