aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-29 08:29:55 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-29 08:29:55 -0800
commit219ff3ad611ecfe8a2fd29b8c50a5313c9d15383 (patch)
tree69a9ad12ed64d0966ec63bb5c4699e3effb5490f /drivers
parent547598d3a91f11b1f802bf0b122f777c3c22f26d (diff)
parent2335f8ec27e125208d8d2d3e257a82862c4977d6 (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: (79 commits) [X25]: Use proc_create() to setup ->proc_fops first [WANROUTER]: Use proc_create() to setup ->proc_fops first [8021Q]: Use proc_create() to setup ->proc_fops first [IPV4]: Use proc_create() to setup ->proc_fops first [IPV6]: Use proc_create() to setup ->proc_fops first [SCTP]: Use proc_create() to setup ->proc_fops first [PKTGEN]: Use proc_create() to setup ->proc_fops first [NEIGHBOUR]: Use proc_create() to setup ->proc_fops first [LLC]: Use proc_create() to setup ->proc_fops first [IPX]: Use proc_create() to setup ->proc_fops first [SUNRPC]: Use proc_create() to setup ->proc_fops first [ATM]: Use proc_create() to setup ->proc_fops first [SCTP]: Update AUTH structures to match declarations in draft-16. [SCTP]: Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option [SCTP]: Clean up naming conventions of sctp protocol/address family registration [APPLETALK]: Use proc_create() to setup ->proc_fops first [BNX2X]: add bnx2x to MAINTAINERS [BNX2X]: update version, remove CVS strings [BNX2X]: Fix Xmit bugs [BNX2X]: Prevent PCI queue overflow ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/connector/connector.c2
-rw-r--r--drivers/net/Kconfig6
-rw-r--r--drivers/net/bnx2x.c2663
-rw-r--r--drivers/net/bnx2x.h56
-rw-r--r--drivers/net/bnx2x_fw_defs.h2
-rw-r--r--drivers/net/bnx2x_hsi.h428
-rw-r--r--drivers/net/bnx2x_init.h12
-rw-r--r--drivers/net/bnx2x_reg.h212
-rw-r--r--drivers/net/cs89x0.c12
-rw-r--r--drivers/net/e1000e/82571.c22
-rw-r--r--drivers/net/e1000e/defines.h10
-rw-r--r--drivers/net/e1000e/e1000.h3
-rw-r--r--drivers/net/e1000e/hw.h4
-rw-r--r--drivers/net/e1000e/ich8lan.c24
-rw-r--r--drivers/net/e1000e/lib.c50
-rw-r--r--drivers/net/e1000e/netdev.c18
-rw-r--r--drivers/net/e1000e/phy.c10
-rw-r--r--drivers/net/ehea/ehea.h34
-rw-r--r--drivers/net/ehea/ehea_main.c281
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c7
-rw-r--r--drivers/net/gianfar.c14
-rw-r--r--drivers/net/igb/igb_main.c15
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c1
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c10
-rw-r--r--drivers/net/phy/mdio_bus.c4
-rw-r--r--drivers/net/ps3_gelic_wireless.c1
-rw-r--r--drivers/net/sis190.c15
-rw-r--r--drivers/net/sky2.c123
-rw-r--r--drivers/net/sky2.h27
-rw-r--r--drivers/net/tlan.c64
-rw-r--r--drivers/net/tulip/uli526x.c12
-rw-r--r--drivers/net/via-rhine.c2
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireless/b43/Kconfig1
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig1
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig2
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/libertas/decl.h1
-rw-r--r--drivers/net/wireless/libertas/main.c17
-rw-r--r--drivers/net/wireless/rndis_wlan.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c73
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c6
-rw-r--r--drivers/s390/net/claw.c39
-rw-r--r--drivers/ssb/Kconfig5
-rw-r--r--drivers/ssb/Makefile2
-rw-r--r--drivers/ssb/driver_pcicore.c2
-rw-r--r--drivers/ssb/ssb_private.h4
54 files changed, 2912 insertions, 1439 deletions
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index fea2d3ed9cb..85e2ba7fcfb 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -47,7 +47,7 @@ static LIST_HEAD(notify_list);
static struct cn_dev cdev;
-int cn_already_initialized = 0;
+static int cn_already_initialized;
/*
* msg->seq and msg->ack are used to determine message genealogy.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f337800076c..a0f0e605d63 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -90,6 +90,11 @@ config MACVLAN
This allows one to create virtual interfaces that map packets to
or from specific MAC addresses to a particular interface.
+ Macvlan devices can be added using the "ip" command from the
+ iproute2 package starting with the iproute2-2.6.23 release:
+
+ "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
+
To compile this driver as a module, choose M here: the module
will be called macvlan.
@@ -2363,6 +2368,7 @@ config GELIC_NET
config GELIC_WIRELESS
bool "PS3 Wireless support"
depends on GELIC_NET
+ select WIRELESS_EXT
help
This option adds the support for the wireless feature of PS3.
If you have the wireless-less model of PS3 or have no plan to
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c
index afc7f34b1dc..8af142ccf37 100644
--- a/drivers/net/bnx2x.c
+++ b/drivers/net/bnx2x.c
@@ -1,6 +1,6 @@
/* bnx2x.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
@@ -10,13 +10,13 @@
* Based on code from Michael Chan's bnx2 driver
* UDP CSUM errata workaround by Arik Gendelman
* Slowpath rework by Vladislav Zolotarov
- * Statistics and Link managment by Yitchak Gertner
+ * Statistics and Link management by Yitchak Gertner
*
*/
/* define this to make the driver freeze on error
* to allow getting debug info
- * (you will need to reboot afterwords)
+ * (you will need to reboot afterwards)
*/
/*#define BNX2X_STOP_ON_ERROR*/
@@ -63,22 +63,21 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
-#define DRV_MODULE_VERSION "0.40.15"
-#define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $"
-#define BNX2X_BC_VER 0x040009
+#define DRV_MODULE_VERSION "1.40.22"
+#define DRV_MODULE_RELDATE "2007/11/27"
+#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (5*HZ)
static char version[] __devinitdata =
- "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver "
+ "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver "
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>");
MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
-MODULE_INFO(cvs_version, "$Revision: #356 $");
static int use_inta;
static int poll;
@@ -94,8 +93,8 @@ module_param(debug, int, 0);
MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
MODULE_PARM_DESC(poll, "use polling (for debug)");
MODULE_PARM_DESC(onefunc, "enable only first function");
-MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)");
-MODULE_PARM_DESC(debug, "defualt debug msglevel");
+MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)");
+MODULE_PARM_DESC(debug, "default debug msglevel");
#ifdef BNX2X_MULTI
module_param(use_multi, int, 0);
@@ -298,8 +297,7 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
static int bnx2x_mc_assert(struct bnx2x *bp)
{
- int i, j;
- int rc = 0;
+ int i, j, rc = 0;
char last_idx;
const char storm[] = {"XTCU"};
const u32 intmem_base[] = {
@@ -313,8 +311,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
for (i = 0; i < 4; i++) {
last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
intmem_base[i]);
- BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
- storm[i], last_idx);
+ if (last_idx)
+ BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
+ storm[i], last_idx);
/* print the asserts */
for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
@@ -330,7 +329,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
intmem_base[i]);
if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x ="
+ BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x ="
" 0x%08x 0x%08x 0x%08x 0x%08x\n",
storm[i], j, row3, row2, row1, row0);
rc++;
@@ -341,6 +340,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
}
return rc;
}
+
static void bnx2x_fw_dump(struct bnx2x *bp)
{
u32 mark, offset;
@@ -348,21 +348,22 @@ static void bnx2x_fw_dump(struct bnx2x *bp)
int word;
mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
- printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+ mark = ((mark + 0x3) & ~0x3);
+ printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
offset + 4*word));
data[8] = 0x0;
- printk(KERN_ERR PFX "%s", (char *)data);
+ printk(KERN_CONT "%s", (char *)data);
}
for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
offset + 4*word));
data[8] = 0x0;
- printk(KERN_ERR PFX "%s", (char *)data);
+ printk(KERN_CONT "%s", (char *)data);
}
printk("\n" KERN_ERR PFX "end of fw dump\n");
}
@@ -427,10 +428,10 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
}
}
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_t_idx(%u)"
- " def_x_idx(%u) def_att_idx(%u) attn_state(%u)"
+ BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
+ " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
" spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx,
+ bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
@@ -441,7 +442,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
}
-static void bnx2x_enable_int(struct bnx2x *bp)
+static void bnx2x_int_enable(struct bnx2x *bp)
{
int port = bp->port;
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -454,18 +455,26 @@ static void bnx2x_enable_int(struct bnx2x *bp)
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
} else {
val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+ /* Errata A0.158 workaround */
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
+ val, port, addr, msix);
+
+ REG_WR(bp, addr, val);
+
val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
}
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n",
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
val, port, addr, msix);
REG_WR(bp, addr, val);
}
-static void bnx2x_disable_int(struct bnx2x *bp)
+static void bnx2x_int_disable(struct bnx2x *bp)
{
int port = bp->port;
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -484,15 +493,15 @@ static void bnx2x_disable_int(struct bnx2x *bp)
BNX2X_ERR("BUG! proper val not read from IGU!\n");
}
-static void bnx2x_disable_int_sync(struct bnx2x *bp)
+static void bnx2x_int_disable_sync(struct bnx2x *bp)
{
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
int i;
atomic_inc(&bp->intr_sem);
- /* prevent the HW from sending interrupts*/
- bnx2x_disable_int(bp);
+ /* prevent the HW from sending interrupts */
+ bnx2x_int_disable(bp);
/* make sure all ISRs are done */
if (msix) {
@@ -775,6 +784,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
mb(); /* force bnx2x_wait_ramrod to see the change */
return;
}
+
switch (command | bp->state) {
case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
DP(NETIF_MSG_IFUP, "got setup ramrod\n");
@@ -787,20 +797,20 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
fp->state = BNX2X_FP_STATE_HALTED;
break;
- case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod\n");
- bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
- break;
-
case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
- bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED;
+ DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n",
+ cid);
+ bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
break;
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
+ break;
+
default:
BNX2X_ERR("unexpected ramrod (%d) state is %x\n",
command, bp->state);
@@ -1179,12 +1189,175 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
return val;
}
+static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
+{
+ u32 cnt;
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 func = bp->port;
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is not already taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (lock_status & resource_bit) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EEXIST;
+ }
+
+ /* Try for 1 second every 5ms */
+ for (cnt = 0; cnt < 200; cnt++) {
+ /* Try to acquire the lock */
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4,
+ resource_bit);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (lock_status & resource_bit)
+ return 0;
+
+ msleep(5);
+ }
+ DP(NETIF_MSG_HW, "Timeout\n");
+ return -EAGAIN;
+}
+
+static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
+{
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 func = bp->port;
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is currently taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+ if (!(lock_status & resource_bit)) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EFAULT;
+ }
+
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit);
+ return 0;
+}
+
+static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+ /* read GPIO and mask except the float bits */
+ gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_GPIO_OUTPUT_LOW:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set CLR */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set SET */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_INPUT_HI_Z :
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
+ gpio_num, gpio_shift);
+ /* set FLOAT */
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_GPIO, gpio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
+
+ return 0;
+}
+
+static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
+{
+ u32 spio_mask = (1 << spio_num);
+ u32 spio_reg;
+
+ if ((spio_num < MISC_REGISTERS_SPIO_4) ||
+ (spio_num > MISC_REGISTERS_SPIO_7)) {
+ BNX2X_ERR("Invalid SPIO %d\n", spio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
+ /* read SPIO and mask except the float bits */
+ spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_SPIO_OUTPUT_LOW :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
+ /* clear FLOAT and set CLR */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
+ /* clear FLOAT and set SET */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_INPUT_HI_Z:
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
+ /* set FLOAT */
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_SPIO, spio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
+
+ return 0;
+}
+
static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
{
- int rc;
- u32 tmp, i;
int port = bp->port;
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u32 tmp;
+ int i, rc;
/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n",
bp->phy_addr, reg, val); */
@@ -1236,8 +1409,8 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
{
int port = bp->port;
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val, i;
- int rc;
+ u32 val;
+ int i, rc;
if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
@@ -1286,58 +1459,54 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
return rc;
}
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
+ u32 phy_addr, u32 reg, u32 addr, u32 val)
{
- int rc = 0;
- u32 tmp, i;
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
+ u32 tmp;
+ int i, rc = 0;
- /* set clause 45 mode */
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp |= EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+ tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
/* address */
- tmp = ((bp->phy_addr << 21) | (reg << 16) | addr |
+ tmp = ((phy_addr << 21) | (reg << 16) | addr |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
}
}
-
if (tmp & EMAC_MDIO_COMM_START_BUSY) {
BNX2X_ERR("write phy register failed\n");
rc = -EBUSY;
+
} else {
/* data */
- tmp = ((bp->phy_addr << 21) | (reg << 16) | val |
+ tmp = ((phy_addr << 21) | (reg << 16) | val |
EMAC_MDIO_COMM_COMMAND_WRITE_45 |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
for (i = 0; i < 50; i++) {
udelay(10);
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -1351,75 +1520,78 @@ static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
}
}
- /* unset clause 45 mode */
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+ /* unset clause 45 mode, set the MDIO clock to a faster value
+ * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+ */
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+ tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+ if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- }
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
return rc;
}
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
- u32 *ret_val)
+static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 val)
{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val, i;
- int rc = 0;
+ u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+ return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
+ reg, addr, val);
+}
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
+static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl,
+ u32 phy_addr, u32 reg, u32 addr,
+ u32 *ret_val)
+{
+ u32 val;
+ int i, rc = 0;
- /* set clause 45 mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val |= EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+ val |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
/* address */
- val = ((bp->phy_addr << 21) | (reg << 16) | addr |
+ val = ((phy_addr << 21) | (reg << 16) | addr |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
}
}
-
if (val & EMAC_MDIO_COMM_START_BUSY) {
BNX2X_ERR("read phy register failed\n");
*ret_val = 0;
rc = -EBUSY;
+
} else {
/* data */
- val = ((bp->phy_addr << 21) | (reg << 16) |
+ val = ((phy_addr << 21) | (reg << 16) |
EMAC_MDIO_COMM_COMMAND_READ_45 |
EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
for (i = 0; i < 50; i++) {
udelay(10);
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
val &= EMAC_MDIO_COMM_DATA;
break;
@@ -1436,31 +1608,39 @@ static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
*ret_val = val;
}
- /* unset clause 45 mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_CLAUSE_45;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+ /* unset clause 45 mode, set the MDIO clock to a faster value
+ * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+ */
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+ val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+ if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
val |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- }
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
return rc;
}
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 *ret_val)
+{
+ u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr,
+ reg, addr, ret_val);
+}
+
+static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg,
+ u32 addr, u32 val)
{
int i;
u32 rd_val;
might_sleep();
for (i = 0; i < 10; i++) {
- bnx2x_mdio45_write(bp, reg, addr, val);
+ bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
msleep(5);
- bnx2x_mdio45_read(bp, reg, addr, &rd_val);
+ bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val);
/* if the read value is not the same as the value we wrote,
we should write it again */
if (rd_val == val)
@@ -1471,18 +1651,81 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
}
/*
- * link managment
+ * link management
*/
+static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result)
+{
+ switch (pause_result) { /* ASYM P ASYM P */
+ case 0xb: /* 1 0 1 1 */
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
+
+ case 0xe: /* 1 1 1 0 */
+ bp->flow_ctrl = FLOW_CTRL_RX;
+ break;
+
+ case 0x5: /* 0 1 0 1 */
+ case 0x7: /* 0 1 1 1 */
+ case 0xd: /* 1 1 0 1 */
+ case 0xf: /* 1 1 1 1 */
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp)
+{
+ u32 ext_phy_addr;
+ u32 ld_pause; /* local */
+ u32 lp_pause; /* link partner */
+ u32 an_complete; /* AN complete */
+ u32 pause_result;
+ u8 ret = 0;
+
+ ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ /* read twice */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_STATUS, &an_complete);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_STATUS, &an_complete);
+
+ if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) {
+ ret = 1;
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_LP_AUTO_NEG, &lp_pause);
+ pause_result = (ld_pause &
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8;
+ pause_result |= (lp_pause &
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10;
+ DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
+ pause_result);
+ bnx2x_pause_resolve(bp, pause_result);
+ }
+ return ret;
+}
+
static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
{
- u32 ld_pause; /* local driver */
- u32 lp_pause; /* link partner */
+ u32 ld_pause; /* local driver */
+ u32 lp_pause; /* link partner */
u32 pause_result;
bp->flow_ctrl = 0;
- /* reolve from gp_status in case of AN complete and not sgmii */
+ /* resolve from gp_status in case of AN complete and not sgmii */
if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
(gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
(!(bp->phy_flags & PHY_SGMII_FLAG)) &&
@@ -1499,45 +1742,57 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
pause_result |= (lp_pause &
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+ bnx2x_pause_resolve(bp, pause_result);
+ } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) ||
+ !(bnx2x_ext_phy_resove_fc(bp))) {
+ /* forced speed */
+ if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ else
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- switch (pause_result) { /* ASYM P ASYM P */
- case 0xb: /* 1 0 1 1 */
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case 0xe: /* 1 1 1 0 */
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
+ case FLOW_CTRL_TX:
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- case 0x5: /* 0 1 0 1 */
- case 0x7: /* 0 1 1 1 */
- case 0xd: /* 1 1 0 1 */
- case 0xf: /* 1 1 1 1 */
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- break;
+ case FLOW_CTRL_RX:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_RX;
+ break;
- default:
- break;
- }
+ case FLOW_CTRL_BOTH:
+ if (bp->dev->mtu <= 4500)
+ bp->flow_ctrl = FLOW_CTRL_BOTH;
+ else
+ bp->flow_ctrl = FLOW_CTRL_TX;
+ break;
- } else { /* forced mode */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
+ case FLOW_CTRL_NONE:
+ default:
+ break;
+ }
+ } else { /* forced mode */
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+ " req_autoneg 0x%x\n",
+ bp->req_flow_ctrl, bp->req_autoneg);
+ break;
- case FLOW_CTRL_TX:
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->flow_ctrl = bp->req_flow_ctrl;
- break;
+ case FLOW_CTRL_TX:
+ case FLOW_CTRL_RX:
+ case FLOW_CTRL_BOTH:
+ bp->flow_ctrl = bp->req_flow_ctrl;
+ break;
- case FLOW_CTRL_NONE:
- default:
- break;
+ case FLOW_CTRL_NONE:
+ default:
+ break;
+ }
}
}
DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
@@ -1548,9 +1803,9 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
bp->link_status = 0;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
- DP(NETIF_MSG_LINK, "link up\n");
+ DP(NETIF_MSG_LINK, "phy link up\n");
- bp->link_up = 1;
+ bp->phy_link_up = 1;
bp->link_status |= LINK_STATUS_LINK_UP;
if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
@@ -1659,20 +1914,20 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
} else { /* link_down */
- DP(NETIF_MSG_LINK, "link down\n");
+ DP(NETIF_MSG_LINK, "phy link down\n");
- bp->link_up = 0;
+ bp->phy_link_up = 0;
bp->line_speed = 0;
bp->duplex = DUPLEX_FULL;
bp->flow_ctrl = 0;
}
- DP(NETIF_MSG_LINK, "gp_status 0x%x link_up %d\n"
+ DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n"
DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x"
" link_status 0x%x\n",
- gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl,
- bp->link_status);
+ gp_status, bp->phy_link_up, bp->line_speed, bp->duplex,
+ bp->flow_ctrl, bp->link_status);
}
static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
@@ -1680,40 +1935,40 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
int port = bp->port;
/* first reset all status
- * we asume only one line will be change at a time */
+ * we assume only one line will be change at a time */
bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_XGXS0_LINK_STATUS |
- NIG_SERDES0_LINK_STATUS |
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G));
- if (bp->link_up) {
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+ if (bp->phy_link_up) {
if (is_10g) {
/* Disable the 10G link interrupt
* by writing 1 to the status register
*/
- DP(NETIF_MSG_LINK, "10G XGXS link up\n");
+ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G);
+ NIG_STATUS_XGXS0_LINK10G);
} else if (bp->phy_flags & PHY_XGXS_FLAG) {
/* Disable the link interrupt
* by writing 1 to the relevant lane
* in the status register
*/
- DP(NETIF_MSG_LINK, "1G XGXS link up\n");
+ DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
((1 << bp->ser_lane) <<
- NIG_XGXS0_LINK_STATUS_SIZE));
+ NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
} else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes link up\n");
+ DP(NETIF_MSG_LINK, "SerDes phy link up\n");
/* Disable the link interrupt
* by writing 1 to the status register
*/
bnx2x_bits_en(bp,
NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_SERDES0_LINK_STATUS);
+ NIG_STATUS_SERDES0_LINK_STATUS);
}
} else { /* link_down */
@@ -1724,91 +1979,182 @@ static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp)
{
u32 ext_phy_type;
u32 ext_phy_addr;
- u32 local_phy;
- u32 val = 0;
+ u32 val1 = 0, val2;
u32 rx_sd, pcs_status;
if (bp->phy_flags & PHY_XGXS_FLAG) {
- local_phy = bp->phy_addr;
ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- bp->phy_addr = (u8)ext_phy_addr;
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "XGXS Direct\n");
- val = 1;
+ val1 = 1;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- val = (rx_sd & 0x1);
+ DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
+ val1 = (rx_sd & 0x1);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val);
- DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD,
- EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PCS_DEVAD,
+ EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_LINK_STATUS, &val2);
+
DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
- " pcs_status 0x%x\n", rx_sd, pcs_status);
- /* link is up if both bit 0 of pmd_rx and
- * bit 0 of pcs_status are set
+ " pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n",
+ rx_sd, pcs_status, val2, (val2 & (1<<1)));
+ /* link is up if both bit 0 of pmd_rx_sd and
+ * bit 0 of pcs_status are set, or if the autoneg bit
+ 1 is set
*/
- val = (rx_sd & pcs_status);
+ val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+ /* clear the interrupt LASI status register */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_LASI_STATUS, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the LASI */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9003, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9003, &val1);
+ DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the link status */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PCS_DEVAD,
+ EXT_PHY_KR_PCS_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+ /* Check the link status on 1.1.2 */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val2);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "KR PMA status 0x%x->0x%x\n", val2, val1);
+ val1 = ((val1 & 4) == 4);
+ /* If 1G was requested assume the link is up */
+ if (!(bp->req_autoneg & AUTONEG_SPEED) &&
+ (bp->req_line_speed == SPEED_1000))
+ val1 = 1;
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val2);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T LASI status 0x%x->0x%x\n", val2, val1);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val2);
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_KR_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T PMA status 0x%x->0x%x\n", val2, val1);
+ val1 = ((val1 & 4) == 4);
+ /* if link is up
+ * print the AN outcome of the SFX7101 PHY
+ */
+ if (val1) {
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x21, &val2);
+ DP(NETIF_MSG_LINK,
+ "SFX7101 AN status 0x%x->%s\n", val2,
+ (val2 & (1<<14)) ? "Master" : "Slave");
+ }
break;
default:
DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
bp->ext_phy_config);
- val = 0;
+ val1 = 0;
break;
}
- bp->phy_addr = local_phy;
} else { /* SerDes */
ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
switch (ext_phy_type) {
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "SerDes Direct\n");
- val = 1;
+ val1 = 1;
break;
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
DP(NETIF_MSG_LINK, "SerDes 5482\n");
- val = 1;
+ val1 = 1;
break;
default:
DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
bp->ext_phy_config);
- val = 0;
+ val1 = 0;
break;
}
}
- return val;
+ return val1;
}
static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
@@ -1819,7 +2165,7 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
u32 wb_write[2];
u32 val;
- DP(NETIF_MSG_LINK, "enableing BigMAC\n");
+ DP(NETIF_MSG_LINK, "enabling BigMAC\n");
/* reset and unreset the BigMac */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -1933,6 +2279,35 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
bp->stats_state = STATS_STATE_ENABLE;
}
+static void bnx2x_bmac_rx_disable(struct bnx2x *bp)
+{
+ int port = bp->port;
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 wb_write[2];
+
+ /* Only if the bmac is out of reset */
+ if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) {
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
+#ifdef BNX2X_DMAE_RD
+ bnx2x_read_dmae(bp, bmac_addr +
+ BIGMAC_REGISTER_BMAC_CONTROL, 2);
+ wb_write[0] = *bnx2x_sp(bp, wb_data[0]);
+ wb_write[1] = *bnx2x_sp(bp, wb_data[1]);
+#else
+ wb_write[0] = REG_RD(bp,
+ bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL);
+ wb_write[1] = REG_RD(bp,
+ bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4);
+#endif
+ wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_write, 2);
+ msleep(1);
+ }
+}
+
static void bnx2x_emac_enable(struct bnx2x *bp)
{
int port = bp->port;
@@ -1940,7 +2315,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
u32 val;
int timeout;
- DP(NETIF_MSG_LINK, "enableing EMAC\n");
+ DP(NETIF_MSG_LINK, "enabling EMAC\n");
/* reset and unreset the emac core */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
(MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
@@ -2033,7 +2408,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
EMAC_TX_MODE_EXT_PAUSE_EN);
}
- /* KEEP_VLAN_TAG, promiscous */
+ /* KEEP_VLAN_TAG, promiscuous */
val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
@@ -2161,7 +2536,6 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
u32 count = 1000;
u32 pause = 0;
-
/* disable port */
REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
@@ -2232,7 +2606,7 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
static void bnx2x_update_mng(struct bnx2x *bp)
{
if (!nomcp)
- SHMEM_WR(bp, drv_fw_mb[bp->port].link_status,
+ SHMEM_WR(bp, port_mb[bp->port].link_status,
bp->link_status);
}
@@ -2294,19 +2668,19 @@ static void bnx2x_link_down(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
}
- /* indicate link down */
+ /* indicate no mac active */
bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
- /* reset BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ /* update shared memory */
+ bnx2x_update_mng(bp);
- /* ignore drain flag interrupt */
/* activate nig drain */
NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
- /* update shared memory */
- bnx2x_update_mng(bp);
+ /* reset BigMac */
+ bnx2x_bmac_rx_disable(bp);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
/* indicate link down */
bnx2x_link_report(bp);
@@ -2317,14 +2691,15 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp);
/* This function is called upon link interrupt */
static void bnx2x_link_update(struct bnx2x *bp)
{
- u32 gp_status;
int port = bp->port;
int i;
+ u32 gp_status;
int link_10g;
- DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x,"
+ DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
" int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
- " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG),
+ " 10G %x, XGXS_LINK %x\n", port,
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
@@ -2336,7 +2711,7 @@ static void bnx2x_link_update(struct bnx2x *bp)
might_sleep();
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
/* avoid fast toggling */
- for (i = 0 ; i < 10 ; i++) {
+ for (i = 0; i < 10; i++) {
msleep(10);
bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
&gp_status);
@@ -2351,7 +2726,8 @@ static void bnx2x_link_update(struct bnx2x *bp)
bnx2x_link_int_ack(bp, link_10g);
/* link is up only if both local phy and external phy are up */
- if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) {
+ bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp));
+ if (bp->link_up) {
if (link_10g) {
bnx2x_bmac_enable(bp, 0);
bnx2x_leds_set(bp, SPEED_10000);
@@ -2427,7 +2803,9 @@ static void bnx2x_reset_unicore(struct bnx2x *bp)
}
}
- BNX2X_ERR("BUG! unicore is still in reset!\n");
+ BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n",
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+ bp->phy_addr);
}
static void bnx2x_set_swap_lanes(struct bnx2x *bp)
@@ -2475,12 +2853,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
bnx2x_mdio22_read(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- &control2);
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ &control2);
if (bp->autoneg & AUTONEG_PARALLEL) {
control2 |=
@@ -2490,8 +2868,14 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
}
bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- control2);
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ control2);
+
+ /* Disable parallel detection of HiG */
+ MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+ bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
}
}
@@ -2625,7 +3009,7 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp)
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
/* set extended capabilities */
- if (bp->advertising & ADVERTISED_2500baseT_Full)
+ if (bp->advertising & ADVERTISED_2500baseX_Full)
val |= MDIO_OVER_1G_UP1_2_5G;
if (bp->advertising & ADVERTISED_10000baseT_Full)
val |= MDIO_OVER_1G_UP1_10G;
@@ -2641,20 +3025,91 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp)
/* for AN, we are always publishing full duplex */
an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
- /* set pause */
- switch (bp->pause_mode) {
- case PAUSE_SYMMETRIC:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
- break;
- case PAUSE_ASYMMETRIC:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- break;
- case PAUSE_BOTH:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- break;
- case PAUSE_NONE:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- break;
+ /* resolve pause mode and advertisement
+ * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+ if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ }
+ break;
+
+ case FLOW_CTRL_TX:
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ break;
+
+ case FLOW_CTRL_RX:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ }
+ break;
+
+ case FLOW_CTRL_BOTH:
+ if (bp->dev->mtu <= 4500) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ }
+ break;
+
+ case FLOW_CTRL_NONE:
+ default:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ }
+ } else { /* forced mode */
+ switch (bp->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+ " req_autoneg 0x%x\n",
+ bp->req_flow_ctrl, bp->req_autoneg);
+ break;
+
+ case FLOW_CTRL_TX:
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ bp->advertising |= ADVERTISED_Asym_Pause;
+ break;
+
+ case FLOW_CTRL_RX:
+ case FLOW_CTRL_BOTH:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ bp->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+
+ case FLOW_CTRL_NONE:
+ default:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ bp->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ }
}
MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
@@ -2752,47 +3207,162 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x *bp)
static void bnx2x_link_int_enable(struct bnx2x *bp)
{
int port = bp->port;
+ u32 ext_phy_type;
+ u32 mask;
/* setting the status to report on link up
for either XGXS or SerDes */
bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_XGXS0_LINK_STATUS |
- NIG_STATUS_INTERRUPT_XGXS0_LINK10G |
- NIG_SERDES0_LINK_STATUS));
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
if (bp->phy_flags & PHY_XGXS_FLAG) {
- /* TBD -
- * in force mode (not AN) we can enable just the relevant
- * interrupt
- * Even in AN we might enable only one according to the AN
- * speed mask
- */
- bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G));
- DP(NETIF_MSG_LINK, "enable XGXS interrupt\n");
+ mask = (NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_XGXS0_LINK_STATUS);
+ DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+ ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
} else { /* SerDes */
- bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_SERDES0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enable SerDes interrupt\n");
+ mask = NIG_MASK_SERDES0_LINK_STATUS;
+ DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+ ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+ if ((ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
}
+ bnx2x_bits_en(bp,
+ NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ mask);
+ DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
+ " int_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
+ " 10G %x, XGXS_LINK %x\n", port,
+ (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
+ );
+}
+
+static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp)
+{
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 fw_ver1, fw_ver2;
+
+ /* Need to wait 200ms after reset */
+ msleep(200);
+ /* Boot port from external ROM
+ * Set ser_boot_ctl bit in the MISC_CTRL1 register
+ */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_MISC_CTRL1, 0x0001);
+
+ /* Reset internal microprocessor */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+ /* set micro reset = 0 */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_MICRO_RESET);
+ /* Reset internal microprocessor */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+ EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+ /* wait for 100ms for code download via SPI port */
+ msleep(100);
+
+ /* Clear ser_boot_ctl bit */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_MISC_CTRL1, 0x0000);
+ /* Wait 100ms */
+ msleep(100);
+
+ /* Print the PHY FW version */
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0xca19, &fw_ver1);
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0xca1a, &fw_ver2);
+ DP(NETIF_MSG_LINK,
+ "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+}
+
+static void bnx2x_bcm8072_force_10G(struct bnx2x *bp)
+{
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ /* Force KR or KX */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL,
+ 0x2040);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2,
+ 0x000b);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL,
+ 0x0000);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL,
+ 0x0000);
}
static void bnx2x_ext_phy_init(struct bnx2x *bp)
{
- int port = bp->port;
u32 ext_phy_type;
u32 ext_phy_addr;
- u32 local_phy;
+ u32 cnt;
+ u32 ctrl;
+ u32 val = 0;
if (bp->phy_flags & PHY_XGXS_FLAG) {
- local_phy = bp->phy_addr;
ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+ /* Make sure that the soft reset is off (expect for the 8072:
+ * due to the lock, it will be done inside the specific
+ * handling)
+ */
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) {
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL, &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK,
+ "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+ }
+
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
DP(NETIF_MSG_LINK, "XGXS Direct\n");
@@ -2800,49 +3370,235 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
- bp->phy_addr = ext_phy_type;
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PMD_MISC_CNTL,
0x8288);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_PHY_IDENTIFIER,
0x7fbf);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_CMU_PLL_BYPASS,
0x0100);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD,
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_WIS_DEVAD,
EXT_PHY_OPT_LASI_CNTL, 0x1);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
-
- bp->phy_addr = ext_phy_type;
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_DIGITAL_CNT,
- 0x400);
- bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+
+ if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+ /* Force speed */
+ if (bp->req_line_speed == SPEED_10000) {
+ DP(NETIF_MSG_LINK,
+ "XGXS 8706 force 10Gbps\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_PMD_DIGITAL_CNT,
+ 0x400);
+ } else {
+ /* Force 1Gbps */
+ DP(NETIF_MSG_LINK,
+ "XGXS 8706 force 1Gbps\n");
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL,
+ 0x0040);
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL2,
+ 0x000D);
+ }
+
+ /* Enable LASI */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_CNTL,
+ 0x1);
+ } else {
+ /* AUTONEG */
+ /* Allow CL37 through CL73 */
+ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_CL73,
+ 0x040c);
+
+ /* Enable Full-Duplex advertisment on CL37 */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_FD,
+ 0x0020);
+ /* Enable CL37 AN */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_CL37_AN,
+ 0x1000);
+ /* Advertise 10G/1G support */
+ if (bp->advertising &
+ ADVERTISED_1000baseT_Full)
+ val = (1<<5);
+ if (bp->advertising &
+ ADVERTISED_10000baseT_Full)
+ val |= (1<<7);
+
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_AN_ADV, val);
+ /* Enable LASI */
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_LASI_CNTL,
+ 0x1);
+
+ /* Enable clause 73 AN */
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_AUTO_NEG_DEVAD,
+ EXT_PHY_OPT_CNTL,
+ 0x1200);
+ }
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ EXT_PHY_OPT_CNTL, &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK,
+ "8072 control reg 0x%x (after %d ms)\n",
+ ctrl, cnt);
+
+ bnx2x_bcm8072_external_rom_boot(bp);
+ DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n");
+
+ /* enable LASI */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0x9000, 0x0400);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ EXT_PHY_KR_LASI_CNTL, 0x0004);
+
+ /* If this is forced speed, set to KR or KX
+ * (all other are not supported)
+ */
+ if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+ if (bp->req_line_speed == SPEED_10000) {
+ bnx2x_bcm8072_force_10G(bp);
+ DP(NETIF_MSG_LINK,
+ "Forced speed 10G on 8072\n");
+ /* unlock */
+ bnx2x_hw_unlock(bp,
+ HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+ } else
+ val = (1<<5);
+ } else {
+
+ /* Advertise 10G/1G support */
+ if (bp->advertising &
+ ADVERTISED_1000baseT_Full)
+ val = (1<<5);
+ if (bp->advertising &
+ ADVERTISED_10000baseT_Full)
+ val |= (1<<7);
+ }
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x11, val);
+ /* Add support for CL37 ( passive mode ) I */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0x8370, 0x040c);
+ /* Add support for CL37 ( passive mode ) II */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0xffe4, 0x20);
+ /* Add support for CL37 ( passive mode ) III */
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ 0xffe0, 0x1000);
+ /* Restart autoneg */
+ msleep(500);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, 0x1200);
+ DP(NETIF_MSG_LINK, "8072 Autoneg Restart: "
+ "1G %ssupported 10G %ssupported\n",
+ (val & (1<<5)) ? "" : "not ",
+ (val & (1<<7)) ? "" : "not ");
+
+ /* unlock */
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LASI indication\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_LASI_CNTL, 0x1);
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LED to blink on traffic\n");
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
+ 0xC007, (1<<3));
+
+ /* read modify write pause advertizing */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, &val);
+ val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH;
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+ if (bp->advertising & ADVERTISED_Pause)
+ val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE;
+
+ if (bp->advertising & ADVERTISED_Asym_Pause) {
+ val |=
+ EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC;
+ }
+ DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val);
+ bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_AUTO_NEG_ADVERT, val);
+ /* Restart autoneg */
+ bnx2x_mdio45_read(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, &val);
+ val |= 0x200;
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_KR_AUTO_NEG_DEVAD,
+ EXT_PHY_KR_CTRL, val);
break;
default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
+ BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n",
+ bp->ext_phy_config);
break;
}
- bp->phy_addr = local_phy;
} else { /* SerDes */
-/* ext_phy_addr = ((bp->ext_phy_config &
+/* ext_phy_addr = ((bp->ext_phy_config &
PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
*/
@@ -2854,10 +3610,6 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- NIG_MASK_MI_INT);
- DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
break;
default:
@@ -2871,8 +3623,22 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
static void bnx2x_ext_phy_reset(struct bnx2x *bp)
{
u32 ext_phy_type;
- u32 ext_phy_addr;
- u32 local_phy;
+ u32 ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+ /* The PHY reset is controled by GPIO 1
+ * Give it 1ms of reset pulse
+ */
+ if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+ (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+ }
if (bp->phy_flags & PHY_XGXS_FLAG) {
ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
@@ -2883,15 +3649,24 @@ static void bnx2x_ext_phy_reset(struct bnx2x *bp)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/6\n");
- local_phy = bp->phy_addr;
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- bp->phy_addr = (u8)ext_phy_addr;
- bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+ DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+ bnx2x_mdio45_write(bp, ext_phy_addr,
+ EXT_PHY_OPT_PMA_PMD_DEVAD,
EXT_PHY_OPT_CNTL, 0xa040);
- bp->phy_addr = local_phy;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ DP(NETIF_MSG_LINK, "XGXS 8072\n");
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+ ext_phy_addr,
+ EXT_PHY_KR_PMA_PMD_DEVAD,
+ 0, 1<<15);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
break;
default:
@@ -2930,6 +3705,7 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
+ /* Activate the external PHY */
bnx2x_ext_phy_reset(bp);
bnx2x_set_aer_mmd(bp);
@@ -2994,13 +3770,13 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
/* AN enabled */
bnx2x_set_brcm_cl37_advertisment(bp);
- /* program duplex & pause advertisment (for aneg) */
+ /* program duplex & pause advertisement (for aneg) */
bnx2x_set_ieee_aneg_advertisment(bp);
/* enable autoneg */
bnx2x_set_autoneg(bp);
- /* enalbe and restart AN */
+ /* enable and restart AN */
bnx2x_restart_autoneg(bp);
}
@@ -3010,11 +3786,11 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
bnx2x_initialize_sgmii_process(bp);
}
- /* enable the interrupt */
- bnx2x_link_int_enable(bp);
-
/* init ext phy and enable link state int */
bnx2x_ext_phy_init(bp);
+
+ /* enable the interrupt */
+ bnx2x_link_int_enable(bp);
}
static void bnx2x_phy_deassert(struct bnx2x *bp)
@@ -3073,6 +3849,11 @@ static int bnx2x_phy_init(struct bnx2x *bp)
static void bnx2x_link_reset(struct bnx2x *bp)
{
int port = bp->port;
+ u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+ /* update shared memory */
+ bp->link_status = 0;
+ bnx2x_update_mng(bp);
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
@@ -3081,21 +3862,45 @@ static void bnx2x_link_reset(struct bnx2x *bp)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- bnx2x_ext_phy_reset(bp);
+ /* activate nig drain */
+ NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* disable nig egress interface */
+ NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+ /* Stop BigMac rx */
+ bnx2x_bmac_rx_disable(bp);
+
+ /* disable emac */
+ NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
+ /* The PHY reset is controled by GPIO 1
+ * Hold it as output low
+ */
+ if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+ (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ DP(NETIF_MSG_LINK, "reset external PHY\n");
+ }
/* reset the SerDes/XGXS */
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
(0x1ff << (port*16)));
- /* reset EMAC / BMAC and disable NIG interfaces */
- NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
- NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ /* reset BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+ /* disable nig ingress interface */
+ NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
- NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+ /* set link down */
+ bp->link_up = 0;
}
#ifdef BNX2X_XGXS_LB
@@ -3158,7 +3963,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
int port = bp->port;
DP(NETIF_MSG_TIMER,
- "spe (%x:%x) command %x hw_cid %x data (%x:%x) left %x\n",
+ "spe (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
(u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
(void *)bp->spq_prod_bd - (void *)bp->spq), command,
HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
@@ -3176,6 +3981,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
bnx2x_panic();
return -EBUSY;
}
+
/* CID needs port number to be encoded int it */
bp->spq_prod_bd->hdr.conn_and_cmd_data =
cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
@@ -3282,8 +4088,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8;
u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
MISC_REG_AEU_MASK_ATTN_FUNC_0;
- u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
- NIG_REG_MASK_INTERRUPT_PORT0;
+ u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
+ NIG_REG_MASK_INTERRUPT_PORT0;
if (~bp->aeu_mask & (asserted & 0xff))
BNX2X_ERR("IGU ERROR\n");
@@ -3301,15 +4107,11 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
if (asserted & ATTN_HARD_WIRED_MASK) {
if (asserted & ATTN_NIG_FOR_FUNC) {
- u32 nig_status_port;
- u32 nig_int_addr = port ?
- NIG_REG_STATUS_INTERRUPT_PORT1 :
- NIG_REG_STATUS_INTERRUPT_PORT0;
- bp->nig_mask = REG_RD(bp, nig_mask_addr);
- REG_WR(bp, nig_mask_addr, 0);
+ /* save nig interrupt mask */
+ bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+ REG_WR(bp, nig_int_mask_addr, 0);
- nig_status_port = REG_RD(bp, nig_int_addr);
bnx2x_link_update(bp);
/* handle unicore attn? */
@@ -3362,15 +4164,132 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
/* now set back the mask */
if (asserted & ATTN_NIG_FOR_FUNC)
- REG_WR(bp, nig_mask_addr, bp->nig_mask);
+ REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
}
-static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
{
int port = bp->port;
- int index;
+ int reg_offset;
+ u32 val;
+
+ if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("SPIO5 hw attention\n");
+
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure attention */
+
+ /* The PHY reset is controled by GPIO 1 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* Low power mode is controled by GPIO 2 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* mark the failure */
+ bp->ext_phy_config &=
+ ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+ bp->ext_phy_config |=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+ SHMEM_WR(bp,
+ dev_info.port_hw_config[port].
+ external_phy_config,
+ bp->ext_phy_config);
+ /* log the failure */
+ printk(KERN_ERR PFX "Fan Failure on Network"
+ " Controller %s has caused the driver to"
+ " shutdown the card to prevent permanent"
+ " damage. Please contact Dell Support for"
+ " assistance\n", bp->dev->name);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & BNX2X_DOORQ_ASSERT) {
+
+ val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
+ BNX2X_ERR("DB hw attention 0x%x\n", val);
+ /* DORQ discard attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from DORQ\n");
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
+
+ val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
+ BNX2X_ERR("CFC hw attention 0x%x\n", val);
+ /* CFC error attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from CFC\n");
+ }
+
+ if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
+
+ val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
+ BNX2X_ERR("PXP hw attention 0x%x\n", val);
+ /* RQ_USDMDP_FIFO_OVERFLOW */
+ if (val & 0x18000)
+ BNX2X_ERR("FATAL error from PXP\n");
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
+{
+ if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
+
+ if (attn & BNX2X_MC_ASSERT_BITS) {
+
+ BNX2X_ERR("MC assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
+ bnx2x_panic();
+
+ } else if (attn & BNX2X_MCP_ASSERT) {
+
+ BNX2X_ERR("MCP assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
+ bnx2x_mc_assert(bp);
+
+ } else
+ BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
+ }
+
+ if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
+
+ REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
+ BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn);
+ }
+}
+
+static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+{
struct attn_route attn;
struct attn_route group_mask;
+ int port = bp->port;
+ int index;
u32 reg_addr;
u32 val;
@@ -3391,64 +4310,14 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
DP(NETIF_MSG_HW, "group[%d]: %llx\n", index,
(unsigned long long)group_mask.sig[0]);
- if (attn.sig[3] & group_mask.sig[3] &
- EVEREST_GEN_ATTN_IN_USE_MASK) {
-
- if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) {
-
- BNX2X_ERR("MC assert!\n");
- bnx2x_panic();
-
- } else if (attn.sig[3] & BNX2X_MCP_ASSERT) {
-
- BNX2X_ERR("MCP assert!\n");
- REG_WR(bp,
- MISC_REG_AEU_GENERAL_ATTN_11, 0);
- bnx2x_mc_assert(bp);
-
- } else {
- BNX2X_ERR("UNKOWEN HW ASSERT!\n");
- }
- }
-
- if (attn.sig[1] & group_mask.sig[1] &
- BNX2X_DOORQ_ASSERT) {
-
- val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
- BNX2X_ERR("DB hw attention 0x%x\n", val);
- /* DORQ discard attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from DORQ\n");
- }
-
- if (attn.sig[2] & group_mask.sig[2] &
- AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
-
- val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
- BNX2X_ERR("CFC hw attention 0x%x\n", val);
- /* CFC error attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from CFC\n");
- }
-
- if (attn.sig[2] & group_mask.sig[2] &
- AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
-
- val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
- BNX2X_ERR("PXP hw attention 0x%x\n", val);
- /* RQ_USDMDP_FIFO_OVERFLOW */
- if (val & 0x18000)
- BNX2X_ERR("FATAL error from PXP\n");
- }
-
- if (attn.sig[3] & group_mask.sig[3] &
- EVEREST_LATCHED_ATTN_IN_USE_MASK) {
-
- REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
- 0x7ff);
- DP(NETIF_MSG_HW, "got latched bits 0x%x\n",
- attn.sig[3]);
- }
+ bnx2x_attn_int_deasserted3(bp,
+ attn.sig[3] & group_mask.sig[3]);
+ bnx2x_attn_int_deasserted1(bp,
+ attn.sig[1] & group_mask.sig[1]);
+ bnx2x_attn_int_deasserted2(bp,
+ attn.sig[2] & group_mask.sig[2]);
+ bnx2x_attn_int_deasserted0(bp,
+ attn.sig[0] & group_mask.sig[0]);
if ((attn.sig[0] & group_mask.sig[0] &
HW_INTERRUT_ASSERT_SET_0) ||
@@ -3456,7 +4325,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
HW_INTERRUT_ASSERT_SET_1) ||
(attn.sig[2] & group_mask.sig[2] &
HW_INTERRUT_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block attention\n");
+ BNX2X_ERR("FATAL HW block attention"
+ " set0 0x%x set1 0x%x"
+ " set2 0x%x\n",
+ (attn.sig[0] & group_mask.sig[0] &
+ HW_INTERRUT_ASSERT_SET_0),
+ (attn.sig[1] & group_mask.sig[1] &
+ HW_INTERRUT_ASSERT_SET_1),
+ (attn.sig[2] & group_mask.sig[2] &
+ HW_INTERRUT_ASSERT_SET_2));
if ((attn.sig[0] & group_mask.sig[0] &
HW_PRTY_ASSERT_SET_0) ||
@@ -3464,7 +4341,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
HW_PRTY_ASSERT_SET_1) ||
(attn.sig[2] & group_mask.sig[2] &
HW_PRTY_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block parity atention\n");
+ BNX2X_ERR("FATAL HW block parity attention\n");
}
}
@@ -3529,7 +4406,7 @@ static void bnx2x_sp_task(struct work_struct *work)
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
return;
}
@@ -3539,12 +4416,11 @@ static void bnx2x_sp_task(struct work_struct *work)
DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
- if (status & 0x1) {
- /* HW attentions */
+ /* HW attentions */
+ if (status & 0x1)
bnx2x_attn_int(bp);
- }
- /* CStorm events: query_stats, cfc delete ramrods */
+ /* CStorm events: query_stats, port delete ramrod */
if (status & 0x2)
bp->stat_pending = 0;
@@ -3558,6 +4434,7 @@ static void bnx2x_sp_task(struct work_struct *work)
IGU_INT_NOP, 1);
bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
IGU_INT_ENABLE, 1);
+
}
static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
@@ -3567,11 +4444,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
return IRQ_HANDLED;
}
- bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+ bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -3906,7 +4783,7 @@ static void bnx2x_stop_stats(struct bnx2x *bp)
while (bp->stats_state != STATS_STATE_DISABLE) {
if (!timeout) {
- BNX2X_ERR("timeout wating for stats stop\n");
+ BNX2X_ERR("timeout waiting for stats stop\n");
break;
}
timeout--;
@@ -4173,39 +5050,37 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
- nstats->tx_bytes =
- bnx2x_hilo(&estats->total_bytes_transmitted_hi);
+ nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = estats->checksum_discard +
- estats->mac_discard;
+ nstats->rx_dropped = estats->checksum_discard + estats->mac_discard;
nstats->tx_dropped = 0;
nstats->multicast =
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
- nstats->collisions =
- estats->single_collision_transmit_frames +
- estats->multiple_collision_transmit_frames +
- estats->late_collision_frames +
- estats->excessive_collision_frames;
+ nstats->collisions = estats->single_collision_transmit_frames +
+ estats->multiple_collision_transmit_frames +
+ estats->late_collision_frames +
+ estats->excessive_collision_frames;
nstats->rx_length_errors = estats->runt_packets_received +
estats->jabber_packets_received;
- nstats->rx_over_errors = estats->no_buff_discard;
+ nstats->rx_over_errors = estats->brb_discard +
+ estats->brb_truncate_discard;
nstats->rx_crc_errors = estats->crc_receive_errors;
nstats->rx_frame_errors = estats->alignment_errors;
- nstats->rx_fifo_errors = estats->brb_discard +
- estats->brb_truncate_discard;
+ nstats->rx_fifo_errors = estats->no_buff_discard;
nstats->rx_missed_errors = estats->xxoverflow_discard;
nstats->rx_errors = nstats->rx_length_errors +
nstats->rx_over_errors +
nstats->rx_crc_errors +
nstats->rx_frame_errors +
- nstats->rx_fifo_errors;
+ nstats->rx_fifo_errors +
+ nstats->rx_missed_errors;
nstats->tx_aborted_errors = estats->late_collision_frames +
- estats->excessive_collision_frames;
+ estats->excessive_collision_frames;
nstats->tx_carrier_errors = estats->false_carrier_detections;
nstats->tx_fifo_errors = 0;
nstats->tx_heartbeat_errors = 0;
@@ -4334,7 +5209,7 @@ static void bnx2x_timer(unsigned long data)
return;
if (atomic_read(&bp->intr_sem) != 0)
- goto bnx2x_restart_timer;
+ goto timer_restart;
if (poll) {
struct bnx2x_fastpath *fp = &bp->fp[0];
@@ -4344,7 +5219,7 @@ static void bnx2x_timer(unsigned long data)
rc = bnx2x_rx_int(fp, 1000);
}
- if (!nomcp && (bp->bc_ver >= 0x040003)) {
+ if (!nomcp) {
int port = bp->port;
u32 drv_pulse;
u32 mcp_pulse;
@@ -4353,9 +5228,9 @@ static void bnx2x_timer(unsigned long data)
bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
/* TBD - add SYSTEM_TIME */
drv_pulse = bp->fw_drv_pulse_wr_seq;
- SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse);
+ SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse);
- mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) &
+ mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) &
MCP_PULSE_SEQ_MASK);
/* The delta between driver pulse and mcp response
* should be 1 (before mcp response) or 0 (after mcp response)
@@ -4369,11 +5244,11 @@ static void bnx2x_timer(unsigned long data)
}
if (bp->stats_state == STATS_STATE_DISABLE)
- goto bnx2x_restart_timer;
+ goto timer_restart;
bnx2x_update_stats(bp);
-bnx2x_restart_timer:
+timer_restart:
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
@@ -4438,6 +5313,9 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
atten_status_block);
def_sb->atten_status_block.status_block_id = id;
+ bp->def_att_idx = 0;
+ bp->attn_state = 0;
+
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -4472,6 +5350,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
u_def_status_block);
def_sb->u_def_status_block.status_block_id = id;
+ bp->def_u_idx = 0;
+
REG_WR(bp, BAR_USTRORM_INTMEM +
USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_USTRORM_INTMEM +
@@ -4489,6 +5369,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
c_def_status_block);
def_sb->c_def_status_block.status_block_id = id;
+ bp->def_c_idx = 0;
+
REG_WR(bp, BAR_CSTRORM_INTMEM +
CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_CSTRORM_INTMEM +
@@ -4506,6 +5388,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
t_def_status_block);
def_sb->t_def_status_block.status_block_id = id;
+ bp->def_t_idx = 0;
+
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_TSTRORM_INTMEM +
@@ -4523,6 +5407,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
x_def_status_block);
def_sb->x_def_status_block.status_block_id = id;
+ bp->def_x_idx = 0;
+
REG_WR(bp, BAR_XSTRORM_INTMEM +
XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -4535,6 +5421,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
REG_WR16(bp, BAR_XSTRORM_INTMEM +
XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+ bp->stat_pending = 0;
+
bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
}
@@ -4626,7 +5514,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
fp->rx_bd_prod = fp->rx_comp_prod = ring_prod;
fp->rx_pkt = fp->rx_calls = 0;
- /* Warning! this will genrate an interrupt (to the TSTORM) */
+ /* Warning! this will generate an interrupt (to the TSTORM) */
/* must only be done when chip is initialized */
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod);
@@ -4678,7 +5566,6 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp)
bp->spq_left = MAX_SPQ_PENDING;
bp->spq_prod_idx = 0;
- bp->dsb_sp_prod_idx = 0;
bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
bp->spq_prod_bd = bp->spq;
bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
@@ -4755,6 +5642,42 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
}
+static void bnx2x_set_client_config(struct bnx2x *bp)
+{
+#ifdef BCM_VLAN
+ int mode = bp->rx_mode;
+#endif
+ int i, port = bp->port;
+ struct tstorm_eth_client_config tstorm_client = {0};
+
+ tstorm_client.mtu = bp->dev->mtu;
+ tstorm_client.statistics_counter_id = 0;
+ tstorm_client.config_flags =
+ TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+#ifdef BCM_VLAN
+ if (mode && bp->vlgrp) {
+ tstorm_client.config_flags |=
+ TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+ DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+ }
+#endif
+ if (mode != BNX2X_RX_MODE_PROMISC)
+ tstorm_client.drop_flags =
+ TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR;
+
+ for_each_queue(bp, i) {
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, i),
+ ((u32 *)&tstorm_client)[0]);
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4,
+ ((u32 *)&tstorm_client)[1]);
+ }
+
+/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
+ ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+}
+
static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
{
int mode = bp->rx_mode;
@@ -4794,41 +5717,9 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
((u32 *)&tstorm_mac_filter)[i]); */
}
-}
-static void bnx2x_set_client_config(struct bnx2x *bp, int client_id)
-{
-#ifdef BCM_VLAN
- int mode = bp->rx_mode;
-#endif
- int port = bp->port;
- struct tstorm_eth_client_config tstorm_client = {0};
-
- tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.statistics_counter_id = 0;
- tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
-#ifdef BCM_VLAN
- if (mode && bp->vlgrp) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
- DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
- }
-#endif
- tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR |
- TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, client_id),
- ((u32 *)&tstorm_client)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4,
- ((u32 *)&tstorm_client)[1]);
-
-/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
- ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+ if (mode != BNX2X_RX_MODE_NONE)
+ bnx2x_set_client_config(bp);
}
static void bnx2x_init_internal(struct bnx2x *bp)
@@ -4836,7 +5727,6 @@ static void bnx2x_init_internal(struct bnx2x *bp)
int port = bp->port;
struct tstorm_eth_function_common_config tstorm_config = {0};
struct stats_indication_flags stats_flags = {0};
- int i;
if (is_multi(bp)) {
tstorm_config.config_flags = MULTI_FLAGS;
@@ -4850,13 +5740,9 @@ static void bnx2x_init_internal(struct bnx2x *bp)
/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
(*(u32 *)&tstorm_config)); */
- bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */
+ bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
bnx2x_set_storm_rx_mode(bp);
- for_each_queue(bp, i)
- bnx2x_set_client_config(bp, i);
-
-
stats_flags.collect_eth = cpu_to_le32(1);
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
@@ -4902,7 +5788,7 @@ static void bnx2x_nic_init(struct bnx2x *bp)
bnx2x_init_internal(bp);
bnx2x_init_stats(bp);
bnx2x_init_ind_table(bp);
- bnx2x_enable_int(bp);
+ bnx2x_int_enable(bp);
}
@@ -5265,8 +6151,10 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
if (mode & 0x1) { /* init common */
DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n",
func, mode);
- REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff);
- REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ 0xffffffff);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ 0xfffc);
bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
@@ -5359,7 +6247,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8);
#endif
bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
- /* softrest pulse */
+ /* soft reset pulse */
REG_WR(bp, QM_REG_SOFT_RESET, 1);
REG_WR(bp, QM_REG_SOFT_RESET, 0);
@@ -5413,7 +6301,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
REG_WR(bp, SRC_REG_SOFT_RST, 1);
for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
REG_WR(bp, i, 0xc0cac01a);
- /* TODO: repleace with something meaningfull */
+ /* TODO: replace with something meaningful */
}
/* SRCH COMMON comes here */
REG_WR(bp, SRC_REG_SOFT_RST, 0);
@@ -5486,6 +6374,28 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
enable_blocks_attention(bp);
/* enable_blocks_parity(bp); */
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure is indicated by SPIO 5 */
+ bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+ MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+ /* set to active low mode */
+ val = REG_RD(bp, MISC_REG_SPIO_INT);
+ val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+ MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+ REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+ /* enable interrupt to signal the IGU */
+ val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+ val |= (1 << MISC_REGISTERS_SPIO_5);
+ REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+ break;
+
+ default:
+ break;
+ }
+
} /* end of common init */
/* per port init */
@@ -5645,9 +6555,21 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
/* Port MCP comes here */
/* Port DMAE comes here */
+ switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* add SPIO 5 to group 0 */
+ val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+ val |= AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+ break;
+
+ default:
+ break;
+ }
+
bnx2x_link_reset(bp);
- /* Reset pciex errors for debug */
+ /* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
REG_WR(bp, 0x2814, 0xffffffff);
@@ -5669,9 +6591,9 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
port = bp->port;
bp->fw_drv_pulse_wr_seq =
- (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) &
+ (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) &
DRV_PULSE_SEQ_MASK);
- bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param);
+ bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param);
DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n",
bp->fw_drv_pulse_wr_seq, bp->fw_mb);
} else {
@@ -5681,16 +6603,15 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
return 0;
}
-
-/* send the MCP a request, block untill there is a reply */
+/* send the MCP a request, block until there is a reply */
static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
{
- u32 rc = 0;
- u32 seq = ++bp->fw_seq;
int port = bp->port;
+ u32 seq = ++bp->fw_seq;
+ u32 rc = 0;
- SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq);
- DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq);
+ SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq));
+ DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
/* let the FW do it's magic ... */
msleep(100); /* TBD */
@@ -5698,19 +6619,20 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
if (CHIP_REV_IS_SLOW(bp))
msleep(900);
- rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header);
-
+ rc = SHMEM_RD(bp, func_mb[port].fw_mb_header);
DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
/* is this a reply to our command? */
if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
rc &= FW_MSG_CODE_MASK;
+
} else {
/* FW BUG! */
BNX2X_ERR("FW failed to respond!\n");
bnx2x_fw_dump(bp);
rc = 0;
}
+
return rc;
}
@@ -5869,7 +6791,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
for (i = 0; i < 16*1024; i += 64)
* (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
- /* now sixup the last line in the block to point to the next block */
+ /* now fixup the last line in the block to point to the next block */
*(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
/* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
@@ -5950,22 +6872,19 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
int i;
free_irq(bp->msix_table[0].vector, bp->dev);
- DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n",
+ DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
bp->msix_table[0].vector);
for_each_queue(bp, i) {
- DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq "
+ DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
"state(%x)\n", i, bp->msix_table[i + 1].vector,
bnx2x_fp(bp, i, state));
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) {
-
- free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED;
-
- } else
- DP(NETIF_MSG_IFDOWN, "irq not freed\n");
+ if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
+ BNX2X_ERR("IRQ of fp #%d being freed while "
+ "state != closed\n", i);
+ free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
}
}
@@ -5995,7 +6914,7 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
if (pci_enable_msix(bp->pdev, &bp->msix_table[0],
bp->num_queues + 1)){
- BNX2X_ERR("failed to enable msix\n");
+ BNX2X_LOG("failed to enable MSI-X\n");
return -1;
}
@@ -6010,11 +6929,8 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
static int bnx2x_req_msix_irqs(struct bnx2x *bp)
{
-
int i, rc;
- DP(NETIF_MSG_IFUP, "about to request sp irq\n");
-
rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
bp->dev->name, bp->dev);
@@ -6029,7 +6945,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
bp->dev->name, &bp->fp[i]);
if (rc) {
- BNX2X_ERR("request fp #%d irq failed\n", i);
+ BNX2X_ERR("request fp #%d irq failed "
+ "rc %d\n", i, rc);
bnx2x_free_msix_irqs(bp);
return -EBUSY;
}
@@ -6109,8 +7026,8 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
/* can take a while if any port is running */
int timeout = 500;
- /* DP("waiting for state to become %d on IDX [%d]\n",
- state, sb_idx); */
+ DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
might_sleep();
@@ -6128,7 +7045,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
mb(); /* state is changed by bnx2x_sp_event()*/
- if (*state_p != state)
+ if (*state_p == state)
return 0;
timeout--;
@@ -6136,17 +7053,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
}
-
/* timeout! */
- BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx);
- return -EBUSY;
+ BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
+ return -EBUSY;
}
static int bnx2x_setup_leading(struct bnx2x *bp)
{
- /* reset IGU staae */
+ /* reset IGU state */
bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
/* SETUP ramrod */
@@ -6162,12 +7079,13 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index)
/* reset IGU state */
bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ /* SETUP ramrod */
bp->fp[index].state = BNX2X_FP_STATE_OPENING;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
/* Wait for completion */
return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 1);
+ &(bp->fp[index].state), 0);
}
@@ -6177,8 +7095,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
{
- int rc;
- int i = 0;
+ u32 load_code;
+ int i;
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
@@ -6188,26 +7106,28 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
initialized, otherwise - not.
*/
if (!nomcp) {
- rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, unloading\n");
+ return -EBUSY;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ BNX2X_ERR("MCP refused load request, unloading\n");
return -EBUSY; /* other port in diagnostic mode */
}
} else {
- rc = FW_MSG_CODE_DRV_LOAD_COMMON;
+ load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
}
- DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
-
/* if we can't use msix we only need one fp,
* so try to enable msix with the requested number of fp's
* and fallback to inta with one fp
*/
if (req_irq) {
-
if (use_inta) {
bp->num_queues = 1;
} else {
- if (use_multi > 1 && use_multi <= 16)
+ if ((use_multi > 1) && (use_multi <= 16))
/* user requested number */
bp->num_queues = use_multi;
else if (use_multi == 1)
@@ -6216,15 +7136,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
bp->num_queues = 1;
if (bnx2x_enable_msix(bp)) {
- /* faild to enable msix */
+ /* failed to enable msix */
bp->num_queues = 1;
if (use_multi)
- BNX2X_ERR("Muti requested but failed"
+ BNX2X_ERR("Multi requested but failed"
" 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;
@@ -6232,13 +7154,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
if (bp->flags & USING_MSIX_FLAG) {
if (bnx2x_req_msix_irqs(bp)) {
pci_disable_msix(bp->pdev);
- goto out_error;
+ goto load_error;
}
} else {
if (bnx2x_req_irq(bp)) {
BNX2X_ERR("IRQ request failed, aborting\n");
- goto out_error;
+ goto load_error;
}
}
}
@@ -6249,31 +7171,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
/* Initialize HW */
- if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) {
+ if (bnx2x_function_init(bp,
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) {
BNX2X_ERR("HW init failed, aborting\n");
- goto out_error;
+ goto load_error;
}
atomic_set(&bp->intr_sem, 0);
- /* Reenable SP tasklet */
- /*if (bp->sp_task_en) { */
- /* tasklet_enable(&bp->sp_task);*/
- /*} else { */
- /* bp->sp_task_en = 1; */
- /*} */
/* Setup NIC internals and enable interrupts */
bnx2x_nic_init(bp);
/* Send LOAD_DONE command to MCP */
if (!nomcp) {
- rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc);
- if (!rc) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+ if (!load_code) {
BNX2X_ERR("MCP response failure, unloading\n");
- goto int_disable;
+ goto load_int_disable;
}
}
@@ -6285,11 +7201,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
napi_enable(&bnx2x_fp(bp, i, napi));
if (bnx2x_setup_leading(bp))
- goto stop_netif;
+ goto load_stop_netif;
for_each_nondefault_queue(bp, i)
if (bnx2x_setup_multi(bp, i))
- goto stop_netif;
+ goto load_stop_netif;
bnx2x_set_mac_addr(bp);
@@ -6313,42 +7229,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
return 0;
-stop_netif:
+load_stop_netif:
for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
-int_disable:
- bnx2x_disable_int_sync(bp);
+load_int_disable:
+ bnx2x_int_disable_sync(bp);
bnx2x_free_skbs(bp);
bnx2x_free_irq(bp);
-out_error:
+load_error:
bnx2x_free_mem(bp);
/* TBD we really need to reset the chip
if we want to recover from this */
- return rc;
+ return -EBUSY;
}
-static void bnx2x_netif_stop(struct bnx2x *bp)
-{
- int i;
-
- bp->rx_mode = BNX2X_RX_MODE_NONE;
- bnx2x_set_storm_rx_mode(bp);
-
- bnx2x_disable_int_sync(bp);
- bnx2x_link_reset(bp);
-
- for_each_queue(bp, i)
- napi_disable(&bnx2x_fp(bp, i, napi));
-
- if (netif_running(bp->dev)) {
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
-}
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
@@ -6401,20 +7299,20 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
int rc;
- /* halt the connnection */
+ /* halt the connection */
bp->fp[index].state = BNX2X_FP_STATE_HALTING;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
&(bp->fp[index].state), 1);
- if (rc) /* timout */
+ if (rc) /* timeout */
return rc;
/* delete cfc entry */
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index,
+ return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
&(bp->fp[index].state), 1);
}
@@ -6422,8 +7320,8 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
static void bnx2x_stop_leading(struct bnx2x *bp)
{
-
- /* if the other port is hadling traffic,
+ u16 dsb_sp_prod_idx;
+ /* if the other port is handling traffic,
this can take a lot of time */
int timeout = 500;
@@ -6437,52 +7335,71 @@ static void bnx2x_stop_leading(struct bnx2x *bp)
&(bp->fp[0].state), 1))
return;
- bp->dsb_sp_prod_idx = *bp->dsb_sp_prod;
+ dsb_sp_prod_idx = *bp->dsb_sp_prod;
- /* Send CFC_DELETE ramrod */
+ /* Send PORT_DELETE ramrod */
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
- /*
- Wait for completion.
+ /* Wait for completion to arrive on default status block
we are going to reset the chip anyway
so there is not much to do if this times out
*/
- while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) {
- timeout--;
- msleep(1);
+ while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) {
+ timeout--;
+ msleep(1);
}
-
+ if (!timeout) {
+ DP(NETIF_MSG_IFDOWN, "timeout polling for completion "
+ "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
+ *bp->dsb_sp_prod, dsb_sp_prod_idx);
+ }
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+ bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
}
-static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
+
+static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq)
{
u32 reset_code = 0;
- int rc;
- int i;
+ int i, timeout;
bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
- /* Calling flush_scheduled_work() may deadlock because
- * linkwatch_event() may be on the workqueue and it will try to get
- * the rtnl_lock which we are holding.
- */
+ del_timer_sync(&bp->timer);
- while (bp->in_reset_task)
- msleep(1);
+ bp->rx_mode = BNX2X_RX_MODE_NONE;
+ bnx2x_set_storm_rx_mode(bp);
- /* Delete the timer: do it before disabling interrupts, as it
- may be stil STAT_QUERY ramrod pending after stopping the timer */
- del_timer_sync(&bp->timer);
+ if (netif_running(bp->dev)) {
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
+ }
+
+ /* Wait until all fast path tasks complete */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ timeout = 1000;
+ while (bnx2x_has_work(fp) && (timeout--))
+ msleep(1);
+ if (!timeout)
+ BNX2X_ERR("timeout waiting for queue[%d]\n", i);
+ }
/* Wait until stat ramrod returns and all SP tasks complete */
- while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING))
+ timeout = 1000;
+ while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) &&
+ (timeout--))
msleep(1);
- /* Stop fast path, disable MAC, disable interrupts, disable napi */
- bnx2x_netif_stop(bp);
+ for_each_queue(bp, i)
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ /* Disable interrupts after Tx and Rx are disabled on stack level */
+ bnx2x_int_disable_sync(bp);
if (bp->flags & NO_WOL_FLAG)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
+
else if (bp->wol) {
u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
u8 *mac_addr = bp->dev->dev_addr;
@@ -6499,28 +7416,37 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
+
} else
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
+ /* Close multi and leading connections */
for_each_nondefault_queue(bp, i)
if (bnx2x_stop_multi(bp, i))
- goto error;
-
+ goto unload_error;
bnx2x_stop_leading(bp);
+ if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
+ (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
+ DP(NETIF_MSG_IFDOWN, "failed to close leading properly!"
+ "state 0x%x fp[0].state 0x%x",
+ bp->state, bp->fp[0].state);
+ }
+
+unload_error:
+ bnx2x_link_reset(bp);
-error:
if (!nomcp)
- rc = bnx2x_fw_command(bp, reset_code);
+ reset_code = bnx2x_fw_command(bp, reset_code);
else
- rc = FW_MSG_CODE_DRV_UNLOAD_COMMON;
+ reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
/* Release IRQs */
- if (fre_irq)
+ if (free_irq)
bnx2x_free_irq(bp);
/* Reset the chip */
- bnx2x_reset_chip(bp, rc);
+ bnx2x_reset_chip(bp, reset_code);
/* Report UNLOAD_DONE to MCP */
if (!nomcp)
@@ -6531,8 +7457,7 @@ error:
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
- /* Set link down */
- bp->link_up = 0;
+
netif_carrier_off(bp->dev);
return 0;
@@ -6568,7 +7493,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
SUPPORTED_Pause |
@@ -6581,10 +7506,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
bp->phy_flags |= PHY_SGMII_FLAG;
- bp->supported |= (/* SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |*/
+ bp->supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
@@ -6620,7 +7545,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_10000baseT_Full |
SUPPORTED_TP | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
@@ -6629,12 +7554,46 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n",
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
ext_phy_type);
bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
+ ext_phy_type);
+
+ bp->supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
@@ -6691,7 +7650,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
SUPPORTED_1000baseT_Full);
if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->supported &= ~SUPPORTED_2500baseT_Full;
+ bp->supported &= ~SUPPORTED_2500baseX_Full;
if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
bp->supported &= ~SUPPORTED_10000baseT_Full;
@@ -6711,13 +7670,8 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
bp->req_line_speed = 0;
bp->advertising = bp->supported;
} else {
- u32 ext_phy_type;
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- if ((ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+ if (XGXS_EXT_PHY_TYPE(bp) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) {
/* force 10G, no AN */
bp->req_line_speed = SPEED_10000;
bp->advertising =
@@ -6734,8 +7688,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
+ if (bp->supported & SUPPORTED_10baseT_Full) {
bp->req_line_speed = SPEED_10;
bp->advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
@@ -6749,8 +7702,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
+ if (bp->supported & SUPPORTED_10baseT_Half) {
bp->req_line_speed = SPEED_10;
bp->req_duplex = DUPLEX_HALF;
bp->advertising = (ADVERTISED_10baseT_Half |
@@ -6765,8 +7717,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
+ if (bp->supported & SUPPORTED_100baseT_Full) {
bp->req_line_speed = SPEED_100;
bp->advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
@@ -6780,8 +7731,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
+ if (bp->supported & SUPPORTED_100baseT_Half) {
bp->req_line_speed = SPEED_100;
bp->req_duplex = DUPLEX_HALF;
bp->advertising = (ADVERTISED_100baseT_Half |
@@ -6796,8 +7746,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+ if (bp->supported & SUPPORTED_1000baseT_Full) {
bp->req_line_speed = SPEED_1000;
bp->advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_TP);
@@ -6811,10 +7760,9 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
break;
case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) {
+ if (bp->supported & SUPPORTED_2500baseX_Full) {
bp->req_line_speed = SPEED_2500;
- bp->advertising = (ADVERTISED_2500baseT_Full |
+ bp->advertising = (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
} else {
BNX2X_ERR("NVRAM config error. "
@@ -6828,15 +7776,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
case PORT_FEATURE_LINK_SPEED_10G_CX4:
case PORT_FEATURE_LINK_SPEED_10G_KX4:
case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " phy_flags 0x%x\n",
- bp->link_config, bp->phy_flags);
- return;
- }
- if (bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+ if (bp->supported & SUPPORTED_10000baseT_Full) {
bp->req_line_speed = SPEED_10000;
bp->advertising = (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
@@ -6863,43 +7803,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
bp->req_flow_ctrl = (bp->link_config &
PORT_FEATURE_FLOW_CONTROL_MASK);
- /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
+ if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (bp->supported & SUPPORTED_Autoneg))
bp->req_autoneg |= AUTONEG_FLOW_CTRL;
- if (bp->dev->mtu <= 4500) {
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- }
- break;
-
- case FLOW_CTRL_TX:
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
-
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- case FLOW_CTRL_NONE:
- default:
- bp->pause_mode = PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x\n"
- KERN_INFO " pause_mode %d advertising 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl,
- bp->pause_mode, bp->advertising);
+ BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x"
+ " advertising 0x%x\n",
+ bp->req_autoneg, bp->req_flow_ctrl, bp->advertising);
}
static void bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -6933,15 +7843,15 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
val = SHMEM_RD(bp, validity_map[port]);
if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- BNX2X_ERR("MCP validity signature bad\n");
+ BNX2X_ERR("BAD MCP validity signature\n");
- bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) &
+ bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
-
+ bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
bp->serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config);
+ SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
bp->lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
bp->ext_phy_config =
@@ -6954,13 +7864,13 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
bp->link_config =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- BNX2X_DEV_INFO("hw_config (%08x) serdes_config (%08x)\n"
+ BNX2X_DEV_INFO("hw_config (%08x) board (%08x) serdes_config (%08x)\n"
KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n"
KERN_INFO " speed_cap_mask (%08x) link_config (%08x)"
" fw_seq (%08x)\n",
- bp->hw_config, bp->serdes_config, bp->lane_config,
- bp->ext_phy_config, bp->speed_cap_mask,
- bp->link_config, bp->fw_seq);
+ bp->hw_config, bp->board, bp->serdes_config,
+ bp->lane_config, bp->ext_phy_config,
+ bp->speed_cap_mask, bp->link_config, bp->fw_seq);
switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
bnx2x_link_settings_supported(bp, switch_cfg);
@@ -7014,14 +7924,8 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
return;
set_mac: /* only supposed to happen on emulation/FPGA */
- BNX2X_ERR("warning constant MAC workaround active\n");
- bp->dev->dev_addr[0] = 0;
- bp->dev->dev_addr[1] = 0x50;
- bp->dev->dev_addr[2] = 0xc2;
- bp->dev->dev_addr[3] = 0x2c;
- bp->dev->dev_addr[4] = 0x71;
- bp->dev->dev_addr[5] = port ? 0x0d : 0x0e;
-
+ BNX2X_ERR("warning rendom MAC workaround active\n");
+ random_ether_addr(bp->dev->dev_addr);
memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
}
@@ -7048,19 +7952,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
if (bp->phy_flags & PHY_XGXS_FLAG) {
- cmd->port = PORT_FIBRE;
- } else {
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ cmd->port = PORT_FIBRE;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ cmd->port = PORT_TP;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ bp->ext_phy_config);
+ }
+ } else
cmd->port = PORT_TP;
- }
cmd->phy_address = bp->phy_addr;
cmd->transceiver = XCVR_INTERNAL;
- if (bp->req_autoneg & AUTONEG_SPEED) {
+ if (bp->req_autoneg & AUTONEG_SPEED)
cmd->autoneg = AUTONEG_ENABLE;
- } else {
+ else
cmd->autoneg = AUTONEG_DISABLE;
- }
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
@@ -7091,8 +8010,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (cmd->port) {
case PORT_TP:
- if (!(bp->supported & SUPPORTED_TP))
+ if (!(bp->supported & SUPPORTED_TP)) {
+ DP(NETIF_MSG_LINK, "TP not supported\n");
return -EINVAL;
+ }
if (bp->phy_flags & PHY_XGXS_FLAG) {
bnx2x_link_reset(bp);
@@ -7102,8 +8023,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
case PORT_FIBRE:
- if (!(bp->supported & SUPPORTED_FIBRE))
+ if (!(bp->supported & SUPPORTED_FIBRE)) {
+ DP(NETIF_MSG_LINK, "FIBRE not supported\n");
return -EINVAL;
+ }
if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
bnx2x_link_reset(bp);
@@ -7113,12 +8036,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
default:
+ DP(NETIF_MSG_LINK, "Unknown port type\n");
return -EINVAL;
}
if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->supported & SUPPORTED_Autoneg))
+ if (!(bp->supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
return -EINVAL;
+ }
/* advertise the requested speed and duplex if supported */
cmd->advertising &= bp->supported;
@@ -7133,14 +8059,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (cmd->speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->supported & SUPPORTED_10baseT_Full))
+ if (!(bp->supported &
+ SUPPORTED_10baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "10M full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10baseT_Full |
ADVERTISED_TP);
} else {
- if (!(bp->supported & SUPPORTED_10baseT_Half))
+ if (!(bp->supported &
+ SUPPORTED_10baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "10M half not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10baseT_Half |
ADVERTISED_TP);
@@ -7150,15 +8084,21 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case SPEED_100:
if (cmd->duplex == DUPLEX_FULL) {
if (!(bp->supported &
- SUPPORTED_100baseT_Full))
+ SUPPORTED_100baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "100M full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_100baseT_Full |
ADVERTISED_TP);
} else {
if (!(bp->supported &
- SUPPORTED_100baseT_Half))
+ SUPPORTED_100baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "100M half not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_100baseT_Half |
ADVERTISED_TP);
@@ -7166,39 +8106,54 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
case SPEED_1000:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "1G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_1000baseT_Full))
+ if (!(bp->supported & SUPPORTED_1000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "1G full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_1000baseT_Full |
ADVERTISED_TP);
break;
case SPEED_2500:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK,
+ "2.5G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_2500baseT_Full))
+ if (!(bp->supported & SUPPORTED_2500baseX_Full)) {
+ DP(NETIF_MSG_LINK,
+ "2.5G full not supported\n");
return -EINVAL;
+ }
- advertising = (ADVERTISED_2500baseT_Full |
+ advertising = (ADVERTISED_2500baseX_Full |
ADVERTISED_TP);
break;
case SPEED_10000:
- if (cmd->duplex != DUPLEX_FULL)
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "10G half not supported\n");
return -EINVAL;
+ }
- if (!(bp->supported & SUPPORTED_10000baseT_Full))
+ if (!(bp->supported & SUPPORTED_10000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "10G full not supported\n");
return -EINVAL;
+ }
advertising = (ADVERTISED_10000baseT_Full |
ADVERTISED_FIBRE);
break;
default:
+ DP(NETIF_MSG_LINK, "Unsupported speed\n");
return -EINVAL;
}
@@ -7398,8 +8353,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
u32 cmd_flags)
{
- int rc;
- int count, i;
+ int count, i, rc;
u32 val;
/* build the command word */
@@ -7452,13 +8406,13 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(NETIF_MSG_NVM,
- "Invalid paramter: offset 0x%x buf_size 0x%x\n",
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
offset, buf_size);
return -EINVAL;
}
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7519,8 +8473,7 @@ static int bnx2x_get_eeprom(struct net_device *dev,
static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
u32 cmd_flags)
{
- int rc;
- int count, i;
+ int count, i, rc;
/* build the command word */
cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
@@ -7557,7 +8510,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
return rc;
}
-#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
+#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
int buf_size)
@@ -7568,7 +8521,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
u32 val;
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7621,13 +8574,13 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(NETIF_MSG_NVM,
- "Invalid paramter: offset 0x%x buf_size 0x%x\n",
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
offset, buf_size);
return -EINVAL;
}
if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+ DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
" buf_size (0x%x) > flash_size (0x%x)\n",
offset, buf_size, bp->flash_size);
return -EINVAL;
@@ -7788,52 +8741,29 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
- bp->req_flow_ctrl = FLOW_CTRL_AUTO;
if (epause->autoneg) {
- bp->req_autoneg |= AUTONEG_FLOW_CTRL;
- if (bp->dev->mtu <= 4500) {
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
+ if (!(bp->supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
+ return -EINVAL;
}
- } else {
+ bp->req_autoneg |= AUTONEG_FLOW_CTRL;
+ } else
bp->req_autoneg &= ~AUTONEG_FLOW_CTRL;
- if (epause->rx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_RX;
- if (epause->tx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_TX;
-
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- bp->req_flow_ctrl = FLOW_CTRL_NONE;
- bp->pause_mode = PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
+ bp->req_flow_ctrl = FLOW_CTRL_AUTO;
- case FLOW_CTRL_TX:
- bp->pause_mode = PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
+ if (epause->rx_pause)
+ bp->req_flow_ctrl |= FLOW_CTRL_RX;
+ if (epause->tx_pause)
+ bp->req_flow_ctrl |= FLOW_CTRL_TX;
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->pause_mode = PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- }
+ if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
+ (bp->req_flow_ctrl == FLOW_CTRL_AUTO))
+ bp->req_flow_ctrl = FLOW_CTRL_NONE;
- DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n"
- DP_LEVEL " pause_mode %d advertising 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode,
- bp->advertising);
+ DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n",
+ bp->req_autoneg, bp->req_flow_ctrl);
bnx2x_stop_stats(bp);
bnx2x_link_initialize(bp);
@@ -7906,81 +8836,87 @@ static void bnx2x_self_test(struct net_device *dev,
static struct {
char string[ETH_GSTRING_LEN];
} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = {
- { "rx_bytes"}, /* 0 */
- { "rx_error_bytes"}, /* 1 */
- { "tx_bytes"}, /* 2 */
- { "tx_error_bytes"}, /* 3 */
- { "rx_ucast_packets"}, /* 4 */
- { "rx_mcast_packets"}, /* 5 */
- { "rx_bcast_packets"}, /* 6 */
- { "tx_ucast_packets"}, /* 7 */
- { "tx_mcast_packets"}, /* 8 */
- { "tx_bcast_packets"}, /* 9 */
- { "tx_mac_errors"}, /* 10 */
- { "tx_carrier_errors"}, /* 11 */
- { "rx_crc_errors"}, /* 12 */
- { "rx_align_errors"}, /* 13 */
- { "tx_single_collisions"}, /* 14 */
- { "tx_multi_collisions"}, /* 15 */
- { "tx_deferred"}, /* 16 */
- { "tx_excess_collisions"}, /* 17 */
- { "tx_late_collisions"}, /* 18 */
- { "tx_total_collisions"}, /* 19 */
- { "rx_fragments"}, /* 20 */
- { "rx_jabbers"}, /* 21 */
- { "rx_undersize_packets"}, /* 22 */
- { "rx_oversize_packets"}, /* 23 */
- { "rx_xon_frames"}, /* 24 */
- { "rx_xoff_frames"}, /* 25 */
- { "tx_xon_frames"}, /* 26 */
- { "tx_xoff_frames"}, /* 27 */
- { "rx_mac_ctrl_frames"}, /* 28 */
- { "rx_filtered_packets"}, /* 29 */
- { "rx_discards"}, /* 30 */
+ { "rx_bytes"},
+ { "rx_error_bytes"},
+ { "tx_bytes"},
+ { "tx_error_bytes"},
+ { "rx_ucast_packets"},
+ { "rx_mcast_packets"},
+ { "rx_bcast_packets"},
+ { "tx_ucast_packets"},
+ { "tx_mcast_packets"},
+ { "tx_bcast_packets"},
+ { "tx_mac_errors"}, /* 10 */
+ { "tx_carrier_errors"},
+ { "rx_crc_errors"},
+ { "rx_align_errors"},
+ { "tx_single_collisions"},
+ { "tx_multi_collisions"},
+ { "tx_deferred"},
+ { "tx_excess_collisions"},
+ { "tx_late_collisions"},
+ { "tx_total_collisions"},
+ { "rx_fragments"}, /* 20 */
+ { "rx_jabbers"},
+ { "rx_undersize_packets"},
+ { "rx_oversize_packets"},
+ { "rx_xon_frames"},
+ { "rx_xoff_frames"},
+ { "tx_xon_frames"},
+ { "tx_xoff_frames"},
+ { "rx_mac_ctrl_frames"},
+ { "rx_filtered_packets"},
+ { "rx_discards"}, /* 30 */
+ { "brb_discard"},
+ { "brb_truncate"},
+ { "xxoverflow"}
};
#define STATS_OFFSET32(offset_name) \
(offsetof(struct bnx2x_eth_stats, offset_name) / 4)
static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = {
- STATS_OFFSET32(total_bytes_received_hi), /* 0 */
- STATS_OFFSET32(stat_IfHCInBadOctets_hi), /* 1 */
- STATS_OFFSET32(total_bytes_transmitted_hi), /* 2 */
- STATS_OFFSET32(stat_IfHCOutBadOctets_hi), /* 3 */
- STATS_OFFSET32(total_unicast_packets_received_hi), /* 4 */
- STATS_OFFSET32(total_multicast_packets_received_hi), /* 5 */
- STATS_OFFSET32(total_broadcast_packets_received_hi), /* 6 */
- STATS_OFFSET32(total_unicast_packets_transmitted_hi), /* 7 */
- STATS_OFFSET32(total_multicast_packets_transmitted_hi), /* 8 */
- STATS_OFFSET32(total_broadcast_packets_transmitted_hi), /* 9 */
- STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */
- STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), /* 11 */
- STATS_OFFSET32(crc_receive_errors), /* 12 */
- STATS_OFFSET32(alignment_errors), /* 13 */
- STATS_OFFSET32(single_collision_transmit_frames), /* 14 */
- STATS_OFFSET32(multiple_collision_transmit_frames), /* 15 */
- STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), /* 16 */
- STATS_OFFSET32(excessive_collision_frames), /* 17 */
- STATS_OFFSET32(late_collision_frames), /* 18 */
- STATS_OFFSET32(number_of_bugs_found_in_stats_spec), /* 19 */
- STATS_OFFSET32(runt_packets_received), /* 20 */
- STATS_OFFSET32(jabber_packets_received), /* 21 */
- STATS_OFFSET32(error_runt_packets_received), /* 22 */
- STATS_OFFSET32(error_jabber_packets_received), /* 23 */
- STATS_OFFSET32(pause_xon_frames_received), /* 24 */
- STATS_OFFSET32(pause_xoff_frames_received), /* 25 */
- STATS_OFFSET32(pause_xon_frames_transmitted), /* 26 */
- STATS_OFFSET32(pause_xoff_frames_transmitted), /* 27 */
- STATS_OFFSET32(control_frames_received), /* 28 */
- STATS_OFFSET32(mac_filter_discard), /* 29 */
- STATS_OFFSET32(no_buff_discard), /* 30 */
+ STATS_OFFSET32(total_bytes_received_hi),
+ STATS_OFFSET32(stat_IfHCInBadOctets_hi),
+ STATS_OFFSET32(total_bytes_transmitted_hi),
+ STATS_OFFSET32(stat_IfHCOutBadOctets_hi),
+ STATS_OFFSET32(total_unicast_packets_received_hi),
+ STATS_OFFSET32(total_multicast_packets_received_hi),
+ STATS_OFFSET32(total_broadcast_packets_received_hi),
+ STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */
+ STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors),
+ STATS_OFFSET32(crc_receive_errors),
+ STATS_OFFSET32(alignment_errors),
+ STATS_OFFSET32(single_collision_transmit_frames),
+ STATS_OFFSET32(multiple_collision_transmit_frames),
+ STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions),
+ STATS_OFFSET32(excessive_collision_frames),
+ STATS_OFFSET32(late_collision_frames),
+ STATS_OFFSET32(number_of_bugs_found_in_stats_spec),
+ STATS_OFFSET32(runt_packets_received), /* 20 */
+ STATS_OFFSET32(jabber_packets_received),
+ STATS_OFFSET32(error_runt_packets_received),
+ STATS_OFFSET32(error_jabber_packets_received),
+ STATS_OFFSET32(pause_xon_frames_received),
+ STATS_OFFSET32(pause_xoff_frames_received),
+ STATS_OFFSET32(pause_xon_frames_transmitted),
+ STATS_OFFSET32(pause_xoff_frames_transmitted),
+ STATS_OFFSET32(control_frames_received),
+ STATS_OFFSET32(mac_filter_discard),
+ STATS_OFFSET32(no_buff_discard), /* 30 */
+ STATS_OFFSET32(brb_discard),
+ STATS_OFFSET32(brb_truncate_discard),
+ STATS_OFFSET32(xxoverflow_discard)
};
static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4,
+ 4, 4, 4, 4
};
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@@ -8138,9 +9074,7 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
* net_device service functions
*/
-/* Called with rtnl_lock from vlan functions and also netif_tx_lock
- * from set_multicast.
- */
+/* called with netif_tx_lock from set_multicast */
static void bnx2x_set_rx_mode(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -8314,7 +9248,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
tx_bd->general_data |= 1; /* header nbd */
- /* remeber the first bd of the packet */
+ /* remember the first bd of the packet */
tx_buf->first_bd = bd_prod;
DP(NETIF_MSG_TX_QUEUED,
@@ -8334,7 +9268,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* for now NS flag is not used in Linux */
pbd->global_data = (len |
- ((skb->protocol == ETH_P_8021Q) <<
+ ((skb->protocol == ntohs(ETH_P_8021Q)) <<
ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
pbd->ip_hlen = ip_hdrlen(skb) / 2;
pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen);
@@ -8343,7 +9277,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_bd->bd_flags.as_bitfield |=
ETH_TX_BD_FLAGS_TCP_CSUM;
- pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF;
+ pbd->tcp_flags = pbd_tcp_flags(skb);
pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2);
pbd->tcp_pseudo_csum = swab16(th->check);
@@ -8387,7 +9321,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_shinfo(skb)->gso_size &&
(skb->len > (bp->dev->mtu + ETH_HLEN))) {
- int hlen = 2 * le32_to_cpu(pbd->total_hlen);
+ int hlen = 2 * le16_to_cpu(pbd->total_hlen);
DP(NETIF_MSG_TX_QUEUED,
"TSO packet len %d hlen %d total len %d tso size %d\n",
@@ -8427,7 +9361,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_bd->vlan = cpu_to_le16(pkt_prod);
/* this marks the bd
* as one that has no individual mapping
- * the FW ignors this flag in a bd not maked start
+ * the FW ignores this flag in a bd not marked start
*/
tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
DP(NETIF_MSG_TX_QUEUED,
@@ -8504,9 +9438,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod);
- fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd);
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod += cpu_to_le32(1);
+ fp->hw_tx_prods->packets_prod =
+ cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
DOORBELL(bp, fp_index, 0);
mmiowb();
@@ -8525,11 +9461,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
-static struct net_device_stats *bnx2x_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
/* Called with rtnl_lock */
static int bnx2x_open(struct net_device *dev)
{
@@ -8543,16 +9474,13 @@ static int bnx2x_open(struct net_device *dev)
/* Called with rtnl_lock */
static int bnx2x_close(struct net_device *dev)
{
- int rc;
struct bnx2x *bp = netdev_priv(dev);
/* Unload the driver, release IRQs */
- rc = bnx2x_nic_unload(bp, 1);
- if (rc) {
- BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc);
- return rc;
- }
- bnx2x_set_power_state(bp, PCI_D3hot);
+ bnx2x_nic_unload(bp, 1);
+
+ if (!CHIP_REV_IS_SLOW(bp))
+ bnx2x_set_power_state(bp, PCI_D3hot);
return 0;
}
@@ -8584,7 +9512,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCGMIIPHY:
data->phy_id = bp->phy_addr;
- /* fallthru */
+ /* fallthrough */
case SIOCGMIIREG: {
u32 mii_regval;
@@ -8633,7 +9561,7 @@ static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
/* This does not race with packet allocation
- * because the actuall alloc size is
+ * because the actual alloc size is
* only updated as part of load
*/
dev->mtu = new_mtu;
@@ -8666,7 +9594,7 @@ static void bnx2x_vlan_rx_register(struct net_device *dev,
bp->vlgrp = vlgrp;
if (netif_running(dev))
- bnx2x_set_rx_mode(dev);
+ bnx2x_set_client_config(bp);
}
#endif
@@ -8695,14 +9623,18 @@ static void bnx2x_reset_task(struct work_struct *work)
if (!netif_running(bp->dev))
return;
- bp->in_reset_task = 1;
+ rtnl_lock();
- bnx2x_netif_stop(bp);
+ if (bp->state != BNX2X_STATE_OPEN) {
+ DP(NETIF_MSG_TX_ERR, "state is %x, returning\n", bp->state);
+ goto reset_task_exit;
+ }
bnx2x_nic_unload(bp, 0);
bnx2x_nic_load(bp, 0);
- bp->in_reset_task = 0;
+reset_task_exit:
+ rtnl_unlock();
}
static int __devinit bnx2x_init_board(struct pci_dev *pdev,
@@ -8783,8 +9715,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
spin_lock_init(&bp->phy_lock);
- bp->in_reset_task = 0;
-
INIT_WORK(&bp->reset_task, bnx2x_reset_task);
INIT_WORK(&bp->sp_task, bnx2x_sp_task);
@@ -8813,7 +9743,7 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
bnx2x_get_hwinfo(bp);
if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- printk(KERN_ERR PFX "FPGA detacted. MCP disabled,"
+ printk(KERN_ERR PFX "FPGA detected. MCP disabled,"
" will only init first device\n");
onefunc = 1;
nomcp = 1;
@@ -8882,14 +9812,32 @@ err_out:
return rc;
}
+static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
+ return val;
+}
+
+/* return value of 1=2.5GHz 2=5GHz */
+static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
+ return val;
+}
+
static int __devinit bnx2x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int version_printed;
struct net_device *dev = NULL;
struct bnx2x *bp;
- int rc, i;
+ int rc;
int port = PCI_FUNC(pdev->devfn);
+ DECLARE_MAC_BUF(mac);
if (version_printed++ == 0)
printk(KERN_INFO "%s", version);
@@ -8906,6 +9854,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
if (port && onefunc) {
printk(KERN_ERR PFX "second function disabled. exiting\n");
+ free_netdev(dev);
return 0;
}
@@ -8918,7 +9867,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
dev->hard_start_xmit = bnx2x_start_xmit;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->get_stats = bnx2x_get_stats;
dev->ethtool_ops = &bnx2x_ethtool_ops;
dev->open = bnx2x_open;
dev->stop = bnx2x_close;
@@ -8944,7 +9892,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
rc = register_netdev(dev);
if (rc) {
- printk(KERN_ERR PFX "Cannot register net device\n");
+ dev_err(&pdev->dev, "Cannot register net device\n");
if (bp->regview)
iounmap(bp->regview);
if (bp->doorbells)
@@ -8959,32 +9907,30 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
bp->name = board_info[ent->driver_data].name;
- printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz "
- "found at mem %lx, IRQ %d, ",
- dev->name, bp->name,
+ printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
+ " IRQ %d, ", dev->name, bp->name,
((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
((CHIP_ID(bp) & 0x0ff0) >> 4),
- ((bp->flags & PCIX_FLAG) ? "-X" : ""),
- ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
- bp->bus_speed_mhz,
- dev->base_addr,
- bp->pdev->irq);
-
- printk("node addr ");
- for (i = 0; i < 6; i++)
- printk("%2.2x", dev->dev_addr[i]);
- printk("\n");
-
+ bnx2x_get_pcie_width(bp),
+ (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
+ dev->base_addr, bp->pdev->irq);
+ printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
return 0;
}
static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp;
+
+ if (!dev) {
+ /* we get here if init_one() fails */
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return;
+ }
+
+ bp = netdev_priv(dev);
- flush_scheduled_work();
- /*tasklet_kill(&bp->sp_task);*/
unregister_netdev(dev);
if (bp->regview)
@@ -9002,34 +9948,43 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
+ struct bnx2x *bp;
+
+ if (!dev)
+ return 0;
if (!netif_running(dev))
return 0;
- rc = bnx2x_nic_unload(bp, 0);
- if (!rc)
- return rc;
+ bp = netdev_priv(dev);
+
+ bnx2x_nic_unload(bp, 0);
netif_device_detach(dev);
- pci_save_state(pdev);
+ pci_save_state(pdev);
bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
+
return 0;
}
static int bnx2x_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp;
int rc;
+ if (!dev) {
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+
if (!netif_running(dev))
return 0;
- pci_restore_state(pdev);
+ bp = netdev_priv(dev);
+ pci_restore_state(pdev);
bnx2x_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 4f7ae6f7745..4f0c0d31e7c 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
@@ -24,6 +24,8 @@
#define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */
#define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */
#define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */
+#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */
#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */
@@ -40,6 +42,12 @@
__LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
} while (0)
+/* for logging (never masked) */
+#define BNX2X_LOG(__fmt, __args...) do { \
+ printk(KERN_NOTICE "[%s:%d(%s)]" __fmt, __FUNCTION__, \
+ __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+ } while (0)
+
/* before we have a dev->name use dev_info() */
#define BNX2X_DEV_INFO(__fmt, __args...) do { \
if (bp->msglevel & NETIF_MSG_PROBE) \
@@ -423,8 +431,6 @@ struct bnx2x_fastpath {
#define BNX2X_FP_STATE_OPEN 0xa0000
#define BNX2X_FP_STATE_HALTING 0xb0000
#define BNX2X_FP_STATE_HALTED 0xc0000
-#define BNX2X_FP_STATE_DELETED 0xd0000
-#define BNX2X_FP_STATE_CLOSE_IRQ 0xe0000
int index;
@@ -505,7 +511,6 @@ struct bnx2x {
struct eth_spe *spq;
dma_addr_t spq_mapping;
u16 spq_prod_idx;
- u16 dsb_sp_prod_idx;
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
u16 *dsb_sp_prod;
@@ -517,7 +522,7 @@ struct bnx2x {
*/
u8 stat_pending;
- /* End of fileds used in the performance code paths */
+ /* End of fields used in the performance code paths */
int panic;
int msglevel;
@@ -540,8 +545,6 @@ struct bnx2x {
spinlock_t phy_lock;
struct work_struct reset_task;
- u16 in_reset_task;
-
struct work_struct sp_task;
struct timer_list timer;
@@ -555,7 +558,6 @@ struct bnx2x {
#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
-#define CHIP_NUM_5710 0x57100000
#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
@@ -574,7 +576,8 @@ struct bnx2x {
u32 fw_mb;
u32 hw_config;
- u32 serdes_config;
+ u32 board;
+ u32 serdes_config;
u32 lane_config;
u32 ext_phy_config;
#define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
@@ -595,11 +598,11 @@ struct bnx2x {
u8 tx_lane_swap;
u8 link_up;
+ u8 phy_link_up;
u32 supported;
/* link settings - missing defines */
#define SUPPORTED_2500baseT_Full (1 << 15)
-#define SUPPORTED_CX4 (1 << 16)
u32 phy_flags;
/*#define PHY_SERDES_FLAG 0x1*/
@@ -644,16 +647,9 @@ struct bnx2x {
#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
- u32 pause_mode;
-#define PAUSE_NONE 0
-#define PAUSE_SYMMETRIC 1
-#define PAUSE_ASYMMETRIC 2
-#define PAUSE_BOTH 3
-
u32 advertising;
/* link settings - missing defines */
#define ADVERTISED_2500baseT_Full (1 << 15)
-#define ADVERTISED_CX4 (1 << 16)
u32 link_status;
u32 line_speed;
@@ -667,6 +663,8 @@ struct bnx2x {
#define NVRAM_TIMEOUT_COUNT 30000
#define NVRAM_PAGE_SIZE 256
+ u8 wol;
+
int rx_ring_size;
u16 tx_quick_cons_trip_int;
@@ -718,9 +716,6 @@ struct bnx2x {
#endif
char *name;
- u16 bus_speed_mhz;
- u8 wol;
- u8 pad;
/* used to synchronize stats collecting */
int stats_state;
@@ -856,8 +851,8 @@ struct bnx2x {
#define MAX_SPQ_PENDING 8
-#define BNX2X_NUM_STATS 31
-#define BNX2X_NUM_TESTS 2
+#define BNX2X_NUM_STATS 34
+#define BNX2X_NUM_TESTS 1
#define DPM_TRIGER_TYPE 0x40
@@ -867,6 +862,15 @@ struct bnx2x {
DPM_TRIGER_TYPE); \
} while (0)
+/* PCIE link and speed */
+#define PCICFG_LINK_WIDTH 0x1f00000
+#define PCICFG_LINK_WIDTH_SHIFT 20
+#define PCICFG_LINK_SPEED 0xf0000
+#define PCICFG_LINK_SPEED_SHIFT 16
+
+#define BMAC_CONTROL_RX_ENABLE 2
+
+#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
/* stuff added to make the code fit 80Col */
@@ -939,13 +943,13 @@ struct bnx2x {
#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
-#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \
+#define NIG_STATUS_XGXS0_LINK10G \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
-#define NIG_XGXS0_LINK_STATUS \
+#define NIG_STATUS_XGXS0_LINK_STATUS \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
-#define NIG_XGXS0_LINK_STATUS_SIZE \
+#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
-#define NIG_SERDES0_LINK_STATUS \
+#define NIG_STATUS_SERDES0_LINK_STATUS \
NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
#define NIG_MASK_MI_INT \
NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index 62a6eb81025..3b968904ca6 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 6fd959c34d1..b21075ccb52 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
@@ -8,169 +8,9 @@
*/
-#define FUNC_0 0
-#define FUNC_1 1
-#define FUNC_MAX 2
-
-
-/* This value (in milliseconds) determines the frequency of the driver
- * issuing the PULSE message code. The firmware monitors this periodic
- * pulse to determine when to switch to an OS-absent mode. */
-#define DRV_PULSE_PERIOD_MS 250
-
-/* This value (in milliseconds) determines how long the driver should
- * wait for an acknowledgement from the firmware before timing out. Once
- * the firmware has timed out, the driver will assume there is no firmware
- * running and there won't be any firmware-driver synchronization during a
- * driver reset. */
-#define FW_ACK_TIME_OUT_MS 5000
-
-#define FW_ACK_POLL_TIME_MS 1
-
-#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
-
-/* LED Blink rate that will achieve ~15.9Hz */
-#define LED_BLINK_RATE_VAL 480
-
-/****************************************************************************
- * Driver <-> FW Mailbox *
- ****************************************************************************/
-struct drv_fw_mb {
- u32 drv_mb_header;
-#define DRV_MSG_CODE_MASK 0xffff0000
-#define DRV_MSG_CODE_LOAD_REQ 0x10000000
-#define DRV_MSG_CODE_LOAD_DONE 0x11000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000
-#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000
-#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000
-#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000
-#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000
-#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000
-#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
-#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
-#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
-
-#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 drv_mb_param;
-
- u32 fw_mb_header;
-#define FW_MSG_CODE_MASK 0xffff0000
-#define FW_MSG_CODE_DRV_LOAD_COMMON 0x11000000
-#define FW_MSG_CODE_DRV_LOAD_PORT 0x12000000
-#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x13000000
-#define FW_MSG_CODE_DRV_LOAD_DONE 0x14000000
-#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x21000000
-#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x22000000
-#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x23000000
-#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50000000
-#define FW_MSG_CODE_DIAG_REFUSE 0x51000000
-#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70000000
-#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x71000000
-#define FW_MSG_CODE_GET_KEY_DONE 0x80000000
-#define FW_MSG_CODE_NO_KEY 0x8f000000
-#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x8f800000
-#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90000000
-#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x91000000
-#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x92000000
-#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x93000000
-#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x94000000
-
-#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 fw_mb_param;
-
- u32 link_status;
- /* Driver should update this field on any link change event */
-
-#define LINK_STATUS_LINK_FLAG_MASK 0x00000001
-#define LINK_STATUS_LINK_UP 0x00000001
-#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E
-#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1)
-
-#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020
-#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
-
-#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
-#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080
-#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
-
-#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
-#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
-#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800
-#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000
-#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000
-#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000
-#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000
-
-#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000
-#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000
-
-#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000
-#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000
-
-#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
-#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18)
-#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18)
-#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18)
-#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18)
-
-#define LINK_STATUS_SERDES_LINK 0x00100000
-
-#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000
-#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000
-#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000
-#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000
-#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000
-#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000
-#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
-#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
-
- u32 drv_pulse_mb;
-#define DRV_PULSE_SEQ_MASK 0x00007fff
-#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
- /* The system time is in the format of
- * (year-2001)*12*32 + month*32 + day. */
-#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicate to the firmware not to go into the
- * OS-absent when it is not getting driver pulse.
- * This is used for debugging as well for PXE(MBA). */
-
- u32 mcp_pulse_mb;
-#define MCP_PULSE_SEQ_MASK 0x00007fff
-#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicates to the driver not to assert due to lack
- * of MCP response */
-#define MCP_EVENT_MASK 0xffff0000
-#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
-
-};
-
+#define PORT_0 0
+#define PORT_1 1
+#define PORT_MAX 2
/****************************************************************************
* Shared HW configuration *
@@ -249,7 +89,7 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000
#define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000
-#define SHARED_HW_CFG_HIDE_FUNC1 0x00002000
+#define SHARED_HW_CFG_HIDE_PORT1 0x00002000
u32 power_dissipated; /* 0x11c */
#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
@@ -290,6 +130,8 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
@@ -304,13 +146,12 @@ struct shared_hw_cfg { /* NVRAM Offset */
};
+
/****************************************************************************
* Port HW configuration *
****************************************************************************/
-struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
+struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
- /* Fields below are port specific (in anticipation of dual port
- devices */
u32 pci_id;
#define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000
#define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff
@@ -420,6 +261,8 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00
#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff
@@ -462,11 +305,13 @@ struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
};
+
/****************************************************************************
* Shared Feature configuration *
****************************************************************************/
struct shared_feat_cfg { /* NVRAM Offset */
- u32 bmc_common; /* 0x450 */
+
+ u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
};
@@ -475,7 +320,8 @@ struct shared_feat_cfg { /* NVRAM Offset */
/****************************************************************************
* Port Feature configuration *
****************************************************************************/
-struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
+struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
+
u32 config;
#define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f
#define PORT_FEATURE_BAR1_SIZE_SHIFT 0
@@ -609,8 +455,7 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
#define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe
#define PORT_FEATURE_SMBUS_ADDR_SHIFT 1
- u32 iscsib_boot_cfg;
-#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT 0x00000001
+ u32 reserved1;
u32 link_config; /* Used as HW defaults for the driver */
#define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000
@@ -657,20 +502,201 @@ struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
};
+/*****************************************************************************
+ * Device Information *
+ *****************************************************************************/
+struct dev_info { /* size */
+
+ u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
+
+ struct shared_hw_cfg shared_hw_config; /* 40 */
+
+ struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */
+
+ struct shared_feat_cfg shared_feature_config; /* 4 */
+
+ struct port_feat_cfg port_feature_config[PORT_MAX]; /* 116*2=232 */
+
+};
+
+
+#define FUNC_0 0
+#define FUNC_1 1
+#define E1_FUNC_MAX 2
+#define FUNC_MAX E1_FUNC_MAX
+
+
+/* This value (in milliseconds) determines the frequency of the driver
+ * issuing the PULSE message code. The firmware monitors this periodic
+ * pulse to determine when to switch to an OS-absent mode. */
+#define DRV_PULSE_PERIOD_MS 250
+
+/* This value (in milliseconds) determines how long the driver should
+ * wait for an acknowledgement from the firmware before timing out. Once
+ * the firmware has timed out, the driver will assume there is no firmware
+ * running and there won't be any firmware-driver synchronization during a
+ * driver reset. */
+#define FW_ACK_TIME_OUT_MS 5000
+
+#define FW_ACK_POLL_TIME_MS 1
+
+#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
+
+/* LED Blink rate that will achieve ~15.9Hz */
+#define LED_BLINK_RATE_VAL 480
+
/****************************************************************************
- * Device Information *
+ * Driver <-> FW Mailbox *
****************************************************************************/
-struct dev_info { /* size */
+struct drv_port_mb {
+
+ u32 link_status;
+ /* Driver should update this field on any link change event */
+
+#define LINK_STATUS_LINK_FLAG_MASK 0x00000001
+#define LINK_STATUS_LINK_UP 0x00000001
+#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E
+#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1)
+
+#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020
+#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
+
+#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
+#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080
+#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
+
+#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
+#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
+#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800
+#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000
+#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000
+#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000
+#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000
+
+#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000
+#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000
+
+#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000
+#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000
+
+#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
+#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18)
+#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18)
+#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18)
+#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18)
+
+#define LINK_STATUS_SERDES_LINK 0x00100000
+
+#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000
+#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000
+#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000
+#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000
+#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000
+#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000
+#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
+#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
- u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
+ u32 reserved[3];
- struct shared_hw_cfg shared_hw_config; /* 40 */
+};
+
+
+struct drv_func_mb {
+
+ u32 drv_mb_header;
+#define DRV_MSG_CODE_MASK 0xffff0000
+#define DRV_MSG_CODE_LOAD_REQ 0x10000000
+#define DRV_MSG_CODE_LOAD_DONE 0x11000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000
+#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000
+#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000
+#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000
+#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000
+#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000
+#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
+#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
+#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
+
+#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
+
+ u32 drv_mb_param;
+
+ u32 fw_mb_header;
+#define FW_MSG_CODE_MASK 0xffff0000
+#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000
+#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000
+#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000
+#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000
+#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000
+#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000
+#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000
+#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000
+#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000
+#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000
+#define FW_MSG_CODE_DIAG_REFUSE 0x50200000
+#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000
+#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000
+#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000
+#define FW_MSG_CODE_GET_KEY_DONE 0x80100000
+#define FW_MSG_CODE_NO_KEY 0x80f00000
+#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000
+#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000
+#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000
+#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000
+#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000
+#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000
+
+#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
+
+ u32 fw_mb_param;
+
+ u32 drv_pulse_mb;
+#define DRV_PULSE_SEQ_MASK 0x00007fff
+#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
+ /* The system time is in the format of
+ * (year-2001)*12*32 + month*32 + day. */
+#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
+ /* Indicate to the firmware not to go into the
+ * OS-absent when it is not getting driver pulse.
+ * This is used for debugging as well for PXE(MBA). */
- struct port_hw_cfg port_hw_config[FUNC_MAX]; /* 400*2=800 */
+ u32 mcp_pulse_mb;
+#define MCP_PULSE_SEQ_MASK 0x00007fff
+#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
+ /* Indicates to the driver not to assert due to lack
+ * of MCP response */
+#define MCP_EVENT_MASK 0xffff0000
+#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
- struct shared_feat_cfg shared_feature_config; /* 4 */
+ u32 iscsi_boot_signature;
+ u32 iscsi_boot_block_offset;
- struct port_feat_cfg port_feature_config[FUNC_MAX];/* 116*2=232 */
+ u32 reserved[3];
};
@@ -678,9 +704,8 @@ struct dev_info { /* size */
/****************************************************************************
* Management firmware state *
****************************************************************************/
-/* Allocate 320 bytes for management firmware: still not known exactly
- * how much IMD needs. */
-#define MGMTFW_STATE_WORD_SIZE 80
+/* Allocate 440 bytes for management firmware */
+#define MGMTFW_STATE_WORD_SIZE 110
struct mgmtfw_state {
u32 opaque[MGMTFW_STATE_WORD_SIZE];
@@ -691,31 +716,40 @@ struct mgmtfw_state {
* Shared Memory Region *
****************************************************************************/
struct shmem_region { /* SharedMem Offset (size) */
- u32 validity_map[FUNC_MAX]; /* 0x0 (4 * 2 = 0x8) */
-#define SHR_MEM_VALIDITY_PCI_CFG 0x00000001
-#define SHR_MEM_VALIDITY_MB 0x00000002
-#define SHR_MEM_VALIDITY_DEV_INFO 0x00000004
+
+ u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */
+#define SHR_MEM_FORMAT_REV_ID ('A'<<24)
+#define SHR_MEM_FORMAT_REV_MASK 0xff000000
+ /* validity bits */
+#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000
+#define SHR_MEM_VALIDITY_MB 0x00200000
+#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000
+#define SHR_MEM_VALIDITY_RESERVED 0x00000007
/* One licensing bit should be set */
#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038
#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008
#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010
#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020
+ /* Active MFW */
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0
+#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0
- struct drv_fw_mb drv_fw_mb[FUNC_MAX]; /* 0x8 (28 * 2 = 0x38) */
-
- struct dev_info dev_info; /* 0x40 (0x438) */
+ struct dev_info dev_info; /* 0x8 (0x438) */
-#ifdef _LICENSE_H
- license_key_t drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */
-#else /* Linux! */
- u8 reserved[52*FUNC_MAX];
-#endif
+ u8 reserved[52*PORT_MAX];
/* FW information (for internal FW use) */
- u32 fw_info_fio_offset; /* 0x4e0 (0x4) */
- struct mgmtfw_state mgmtfw_state; /* 0x4e4 (0x140) */
+ u32 fw_info_fio_offset; /* 0x4a8 (0x4) */
+ struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
+
+ struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
+ struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */
-}; /* 0x624 */
+}; /* 0x6dc */
#define BCM_5710_FW_MAJOR_VERSION 4
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 04f93bff2ef..dcaecc53bdb 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,6 +1,6 @@
/* bnx2x_init.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
@@ -409,7 +409,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
pci_read_config_word(bp->pdev,
bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val);
+ DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val);
w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
@@ -472,10 +472,14 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
- REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order);
+ REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order);
+ REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
+ if (r_order == MAX_RD_ORD)
+ REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
+
+ REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16);
}
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 86055297ab0..5a1aa0b5504 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 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
@@ -24,6 +24,8 @@
#define BRB1_REG_BRB1_INT_STS 0x6011c
/* [RW 4] Parity mask register #0 read/write */
#define BRB1_REG_BRB1_PRTY_MASK 0x60138
+/* [R 4] Parity register #0 read */
+#define BRB1_REG_BRB1_PRTY_STS 0x6012c
/* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At
address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
@@ -281,6 +283,8 @@
#define CDU_REG_CDU_INT_STS 0x101030
/* [RW 5] Parity mask register #0 read/write */
#define CDU_REG_CDU_PRTY_MASK 0x10104c
+/* [R 5] Parity register #0 read */
+#define CDU_REG_CDU_PRTY_STS 0x101040
/* [RC 32] logging of error data in case of a CDU load error:
{expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error;
ype_error; ctual_active; ctual_compressed_context}; */
@@ -308,6 +312,8 @@
#define CFC_REG_CFC_INT_STS_CLR 0x104100
/* [RW 4] Parity mask register #0 read/write */
#define CFC_REG_CFC_PRTY_MASK 0x104118
+/* [R 4] Parity register #0 read */
+#define CFC_REG_CFC_PRTY_STS 0x10410c
/* [RW 21] CID cam access (21:1 - Data; alid - 0) */
#define CFC_REG_CID_CAM 0x104800
#define CFC_REG_CONTROL0 0x104028
@@ -354,6 +360,8 @@
#define CSDM_REG_CSDM_INT_MASK_1 0xc22ac
/* [RW 11] Parity mask register #0 read/write */
#define CSDM_REG_CSDM_PRTY_MASK 0xc22bc
+/* [R 11] Parity register #0 read */
+#define CSDM_REG_CSDM_PRTY_STS 0xc22b0
#define CSDM_REG_ENABLE_IN1 0xc2238
#define CSDM_REG_ENABLE_IN2 0xc223c
#define CSDM_REG_ENABLE_OUT1 0xc2240
@@ -438,6 +446,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define CSEM_REG_CSEM_PRTY_MASK_0 0x200130
#define CSEM_REG_CSEM_PRTY_MASK_1 0x200140
+/* [R 32] Parity register #0 read */
+#define CSEM_REG_CSEM_PRTY_STS_0 0x200124
+#define CSEM_REG_CSEM_PRTY_STS_1 0x200134
#define CSEM_REG_ENABLE_IN 0x2000a4
#define CSEM_REG_ENABLE_OUT 0x2000a8
/* [RW 32] This address space contains all registers and memories that are
@@ -526,6 +537,8 @@
#define CSEM_REG_TS_9_AS 0x20005c
/* [RW 1] Parity mask register #0 read/write */
#define DBG_REG_DBG_PRTY_MASK 0xc0a8
+/* [R 1] Parity register #0 read */
+#define DBG_REG_DBG_PRTY_STS 0xc09c
/* [RW 2] debug only: These bits indicate the credit for PCI request type 4
interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are
configured */
@@ -543,6 +556,8 @@
#define DMAE_REG_DMAE_INT_MASK 0x102054
/* [RW 4] Parity mask register #0 read/write */
#define DMAE_REG_DMAE_PRTY_MASK 0x102064
+/* [R 4] Parity register #0 read */
+#define DMAE_REG_DMAE_PRTY_STS 0x102058
/* [RW 1] Command 0 go. */
#define DMAE_REG_GO_C0 0x102080
/* [RW 1] Command 1 go. */
@@ -623,6 +638,8 @@
#define DORQ_REG_DORQ_INT_STS_CLR 0x170178
/* [RW 2] Parity mask register #0 read/write */
#define DORQ_REG_DORQ_PRTY_MASK 0x170190
+/* [R 2] Parity register #0 read */
+#define DORQ_REG_DORQ_PRTY_STS 0x170184
/* [RW 8] The address to write the DPM CID to STORM. */
#define DORQ_REG_DPM_CID_ADDR 0x170044
/* [RW 5] The DPM mode CID extraction offset. */
@@ -692,6 +709,8 @@
#define HC_REG_CONFIG_1 0x108004
/* [RW 3] Parity mask register #0 read/write */
#define HC_REG_HC_PRTY_MASK 0x1080a0
+/* [R 3] Parity register #0 read */
+#define HC_REG_HC_PRTY_STS 0x108094
/* [RW 17] status block interrupt mask; one in each bit means unmask; zerow
in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1...
bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */
@@ -1127,6 +1146,7 @@
#define MISC_REG_AEU_GENERAL_ATTN_17 0xa044
#define MISC_REG_AEU_GENERAL_ATTN_18 0xa048
#define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c
+#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028
#define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c
#define MISC_REG_AEU_GENERAL_ATTN_2 0xa008
#define MISC_REG_AEU_GENERAL_ATTN_20 0xa050
@@ -1135,6 +1155,9 @@
#define MISC_REG_AEU_GENERAL_ATTN_4 0xa010
#define MISC_REG_AEU_GENERAL_ATTN_5 0xa014
#define MISC_REG_AEU_GENERAL_ATTN_6 0xa018
+#define MISC_REG_AEU_GENERAL_ATTN_7 0xa01c
+#define MISC_REG_AEU_GENERAL_ATTN_8 0xa020
+#define MISC_REG_AEU_GENERAL_ATTN_9 0xa024
/* [RW 32] first 32b for inverting the input for function 0; for each bit:
0= do not invert; 1= invert; mapped as follows: [0] NIG attention for
function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp;
@@ -1183,6 +1206,40 @@
starts at 0x0 for the A0 tape-out and increments by one for each
all-layer tape-out. */
#define MISC_REG_CHIP_REV 0xa40c
+/* [RW 32] The following driver registers(1..6) represent 6 drivers and 32
+ clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_1 0xa510
+/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
+ these bits is written as a '1'; the corresponding SPIO bit will turn off
+ it's drivers and become an input. This is the reset state of all GPIO
+ pins. The read value of these bits will be a '1' if that last command
+ (#SET; #CLR; or #FLOAT) for this bit was a #FLOAT. (reset value 0xff).
+ [23-20] CLR port 1; 19-16] CLR port 0; When any of these bits is written
+ as a '1'; the corresponding GPIO bit will drive low. The read value of
+ these bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for
+ this bit was a #CLR. (reset value 0). [15-12] SET port 1; 11-8] port 0;
+ SET When any of these bits is written as a '1'; the corresponding GPIO
+ bit will drive high (if it has that capability). The read value of these
+ bits will be a '1' if that last command (#SET; #CLR; or #FLOAT) for this
+ bit was a #SET. (reset value 0). [7-4] VALUE port 1; [3-0] VALUE port 0;
+ RO; These bits indicate the read value of each of the eight GPIO pins.
+ This is the result value of the pin; not the drive value. Writing these
+ bits will have not effect. */
+#define MISC_REG_GPIO 0xa490
/* [RW 1] Setting this bit enables a timer in the GRC block to timeout any
access that does not finish within
~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is
@@ -1223,6 +1280,8 @@
#define MISC_REG_MISC_INT_MASK 0xa388
/* [RW 1] Parity mask register #0 read/write */
#define MISC_REG_MISC_PRTY_MASK 0xa398
+/* [R 1] Parity register #0 read */
+#define MISC_REG_MISC_PRTY_STS 0xa38c
/* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911.
inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1
divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1
@@ -1264,6 +1323,55 @@
/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
shared with the driver resides */
#define MISC_REG_SHARED_MEM_ADDR 0xa2b4
+/* [RW 32] SPIO. [31-24] FLOAT When any of these bits is written as a '1';
+ the corresponding SPIO bit will turn off it's drivers and become an
+ input. This is the reset state of all SPIO pins. The read value of these
+ bits will be a '1' if that last command (#SET; #CL; or #FLOAT) for this
+ bit was a #FLOAT. (reset value 0xff). [23-16] CLR When any of these bits
+ is written as a '1'; the corresponding SPIO bit will drive low. The read
+ value of these bits will be a '1' if that last command (#SET; #CLR; or
+#FLOAT) for this bit was a #CLR. (reset value 0). [15-8] SET When any of
+ these bits is written as a '1'; the corresponding SPIO bit will drive
+ high (if it has that capability). The read value of these bits will be a
+ '1' if that last command (#SET; #CLR; or #FLOAT) for this bit was a #SET.
+ (reset value 0). [7-0] VALUE RO; These bits indicate the read value of
+ each of the eight SPIO pins. This is the result value of the pin; not the
+ drive value. Writing these bits will have not effect. Each 8 bits field
+ is divided as follows: [0] VAUX Enable; when pulsed low; enables supply
+ from VAUX. (This is an output pin only; the FLOAT field is not applicable
+ for this pin); [1] VAUX Disable; when pulsed low; disables supply form
+ VAUX. (This is an output pin only; FLOAT field is not applicable for this
+ pin); [2] SEL_VAUX_B - Control to power switching logic. Drive low to
+ select VAUX supply. (This is an output pin only; it is not controlled by
+ the SET and CLR fields; it is controlled by the Main Power SM; the FLOAT
+ field is not applicable for this pin; only the VALUE fields is relevant -
+ it reflects the output value); [3] reserved; [4] spio_4; [5] spio_5; [6]
+ Bit 0 of UMP device ID select; read by UMP firmware; [7] Bit 1 of UMP
+ device ID select; read by UMP firmware. */
+#define MISC_REG_SPIO 0xa4fc
+/* [RW 8] These bits enable the SPIO_INTs to signals event to the IGU/MC.
+ according to the following map: [3:0] reserved; [4] spio_4 [5] spio_5;
+ [7:0] reserved */
+#define MISC_REG_SPIO_EVENT_EN 0xa2b8
+/* [RW 32] SPIO INT. [31-24] OLD_CLR Writing a '1' to these bit clears the
+ corresponding bit in the #OLD_VALUE register. This will acknowledge an
+ interrupt on the falling edge of corresponding SPIO input (reset value
+ 0). [23-16] OLD_SET Writing a '1' to these bit sets the corresponding bit
+ in the #OLD_VALUE register. This will acknowledge an interrupt on the
+ rising edge of corresponding SPIO input (reset value 0). [15-8] OLD_VALUE
+ RO; These bits indicate the old value of the SPIO input value. When the
+ ~INT_STATE bit is set; this bit indicates the OLD value of the pin such
+ that if ~INT_STATE is set and this bit is '0'; then the interrupt is due
+ to a low to high edge. If ~INT_STATE is set and this bit is '1'; then the
+ interrupt is due to a high to low edge (reset value 0). [7-0] INT_STATE
+ RO; These bits indicate the current SPIO interrupt state for each SPIO
+ pin. This bit is cleared when the appropriate #OLD_SET or #OLD_CLR
+ command bit is written. This bit is set when the SPIO input does not
+ match the current value in #OLD_VALUE (reset value 0). */
+#define MISC_REG_SPIO_INT 0xa500
+/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
+ loaded; 0-prepare; -unprepare */
+#define MISC_REG_UNPREPARED 0xa424
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15)
@@ -1392,6 +1500,9 @@
#define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
+/* [RW 1] Value of this register will be transmitted to port swap when
+ ~nig_registers_strap_override.strap_override =1 */
+#define NIG_REG_PORT_SWAP 0x10394
/* [RW 1] output enable for RX parser descriptor IF */
#define NIG_REG_PRS_EOP_OUT_EN 0x10104
/* [RW 1] Input enable for RX parser request IF */
@@ -1410,6 +1521,10 @@
#define NIG_REG_STAT2_BRB_OCTET 0x107e0
#define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328
#define NIG_REG_STATUS_INTERRUPT_PORT1 0x1032c
+/* [RW 1] port swap mux selection. If this register equal to 0 then port
+ swap is equal to SPIO pin that inputs from ifmux_serdes_swap. If 1 then
+ ort swap is equal to ~nig_registers_port_swap.port_swap */
+#define NIG_REG_STRAP_OVERRIDE 0x10398
/* [RW 1] output enable for RX_XCM0 IF */
#define NIG_REG_XCM0_OUT_EN 0x100f0
/* [RW 1] output enable for RX_XCM1 IF */
@@ -1499,6 +1614,8 @@
#define PB_REG_PB_INT_STS 0x1c
/* [RW 4] Parity mask register #0 read/write */
#define PB_REG_PB_PRTY_MASK 0x38
+/* [R 4] Parity register #0 read */
+#define PB_REG_PB_PRTY_STS 0x2c
#define PRS_REG_A_PRSU_20 0x40134
/* [R 8] debug only: CFC load request current credit. Transaction based. */
#define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164
@@ -1590,6 +1707,8 @@
#define PRS_REG_PRS_INT_STS 0x40188
/* [RW 8] Parity mask register #0 read/write */
#define PRS_REG_PRS_PRTY_MASK 0x401a4
+/* [R 8] Parity register #0 read */
+#define PRS_REG_PRS_PRTY_STS 0x40198
/* [RW 8] Context region for pure acknowledge packets. Used in CFC load
request message */
#define PRS_REG_PURE_REGIONS 0x40024
@@ -1718,6 +1837,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define PXP2_REG_PXP2_PRTY_MASK_0 0x120588
#define PXP2_REG_PXP2_PRTY_MASK_1 0x120598
+/* [R 32] Parity register #0 read */
+#define PXP2_REG_PXP2_PRTY_STS_0 0x12057c
+#define PXP2_REG_PXP2_PRTY_STS_1 0x12058c
/* [R 1] Debug only: The 'almost full' indication from each fifo (gives
indication about backpressure) */
#define PXP2_REG_RD_ALMOST_FULL_0 0x120424
@@ -1911,6 +2033,8 @@
#define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8
/* [WB 53] Onchip address table */
#define PXP2_REG_RQ_ONCHIP_AT 0x122000
+/* [RW 13] Pending read limiter threshold; in Dwords */
+#define PXP2_REG_RQ_PDR_LIMIT 0x12033c
/* [RW 2] Endian mode for qm */
#define PXP2_REG_RQ_QM_ENDIAN_M 0x120194
/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k;
@@ -1921,6 +2045,9 @@
/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B;
001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
#define PXP2_REG_RQ_RD_MBS0 0x120160
+/* [RW 3] Max burst size filed for read requests port 1; 000 - 128B;
+ 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
+#define PXP2_REG_RQ_RD_MBS1 0x120168
/* [RW 2] Endian mode for src */
#define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c
/* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k;
@@ -2000,10 +2127,17 @@
/* [RW 3] Max burst size filed for write requests port 0; 000 - 128B;
001:256B; 010: 512B; */
#define PXP2_REG_RQ_WR_MBS0 0x12015c
+/* [RW 3] Max burst size filed for write requests port 1; 000 - 128B;
+ 001:256B; 010: 512B; */
+#define PXP2_REG_RQ_WR_MBS1 0x120164
/* [RW 10] if Number of entries in dmae fifo will be higer than this
threshold then has_payload indication will be asserted; the default value
should be equal to &gt; write MBS size! */
#define PXP2_REG_WR_DMAE_TH 0x120368
+/* [RW 10] if Number of entries in usdmdp fifo will be higer than this
+ threshold then has_payload indication will be asserted; the default value
+ should be equal to &gt; write MBS size! */
+#define PXP2_REG_WR_USDMDP_TH 0x120348
/* [R 1] debug only: Indication if PSWHST arbiter is idle */
#define PXP_REG_HST_ARB_IS_IDLE 0x103004
/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
@@ -2021,6 +2155,8 @@
#define PXP_REG_PXP_INT_STS_CLR_0 0x10306c
/* [RW 26] Parity mask register #0 read/write */
#define PXP_REG_PXP_PRTY_MASK 0x103094
+/* [R 26] Parity register #0 read */
+#define PXP_REG_PXP_PRTY_STS 0x103088
/* [RW 4] The activity counter initial increment value sent in the load
request */
#define QM_REG_ACTCTRINITVAL_0 0x168040
@@ -2127,6 +2263,8 @@
#define QM_REG_QM_INT_STS 0x168438
/* [RW 9] Parity mask register #0 read/write */
#define QM_REG_QM_PRTY_MASK 0x168454
+/* [R 9] Parity register #0 read */
+#define QM_REG_QM_PRTY_STS 0x168448
/* [R 32] Current queues in pipeline: Queues from 32 to 63 */
#define QM_REG_QSTATUS_HIGH 0x16802c
/* [R 32] Current queues in pipeline: Queues from 0 to 31 */
@@ -2410,6 +2548,8 @@
#define SRC_REG_SRC_INT_STS 0x404ac
/* [RW 3] Parity mask register #0 read/write */
#define SRC_REG_SRC_PRTY_MASK 0x404c8
+/* [R 3] Parity register #0 read */
+#define SRC_REG_SRC_PRTY_STS 0x404bc
/* [R 4] Used to read the value of the XX protection CAM occupancy counter. */
#define TCM_REG_CAM_OCCUP 0x5017c
/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
@@ -2730,6 +2870,8 @@
#define TSDM_REG_TSDM_INT_MASK_1 0x422ac
/* [RW 11] Parity mask register #0 read/write */
#define TSDM_REG_TSDM_PRTY_MASK 0x422bc
+/* [R 11] Parity register #0 read */
+#define TSDM_REG_TSDM_PRTY_STS 0x422b0
/* [RW 5] The number of time_slots in the arbitration cycle */
#define TSEM_REG_ARB_CYCLE_SIZE 0x180034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -2854,6 +2996,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define TSEM_REG_TSEM_PRTY_MASK_0 0x180120
#define TSEM_REG_TSEM_PRTY_MASK_1 0x180130
+/* [R 32] Parity register #0 read */
+#define TSEM_REG_TSEM_PRTY_STS_0 0x180114
+#define TSEM_REG_TSEM_PRTY_STS_1 0x180124
/* [R 5] Used to read the XX protection CAM occupancy counter. */
#define UCM_REG_CAM_OCCUP 0xe0170
/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
@@ -3155,6 +3300,8 @@
#define USDM_REG_USDM_INT_MASK_1 0xc42b0
/* [RW 11] Parity mask register #0 read/write */
#define USDM_REG_USDM_PRTY_MASK 0xc42c0
+/* [R 11] Parity register #0 read */
+#define USDM_REG_USDM_PRTY_STS 0xc42b4
/* [RW 5] The number of time_slots in the arbitration cycle */
#define USEM_REG_ARB_CYCLE_SIZE 0x300034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -3279,6 +3426,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define USEM_REG_USEM_PRTY_MASK_0 0x300130
#define USEM_REG_USEM_PRTY_MASK_1 0x300140
+/* [R 32] Parity register #0 read */
+#define USEM_REG_USEM_PRTY_STS_0 0x300124
+#define USEM_REG_USEM_PRTY_STS_1 0x300134
/* [RW 2] The queue index for registration on Aux1 counter flag. */
#define XCM_REG_AUX1_Q 0x20134
/* [RW 2] Per each decision rule the queue index to register to. */
@@ -3684,6 +3834,8 @@
#define XSDM_REG_XSDM_INT_MASK_1 0x1662ac
/* [RW 11] Parity mask register #0 read/write */
#define XSDM_REG_XSDM_PRTY_MASK 0x1662bc
+/* [R 11] Parity register #0 read */
+#define XSDM_REG_XSDM_PRTY_STS 0x1662b0
/* [RW 5] The number of time_slots in the arbitration cycle */
#define XSEM_REG_ARB_CYCLE_SIZE 0x280034
/* [RW 3] The source that is associated with arbitration element 0. Source
@@ -3808,6 +3960,9 @@
/* [RW 32] Parity mask register #0 read/write */
#define XSEM_REG_XSEM_PRTY_MASK_0 0x280130
#define XSEM_REG_XSEM_PRTY_MASK_1 0x280140
+/* [R 32] Parity register #0 read */
+#define XSEM_REG_XSEM_PRTY_STS_0 0x280124
+#define XSEM_REG_XSEM_PRTY_STS_1 0x280134
#define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0)
#define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1)
#define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0)
@@ -3847,6 +4002,8 @@
#define EMAC_MDIO_COMM_START_BUSY (1L<<29)
#define EMAC_MDIO_MODE_AUTO_POLL (1L<<4)
#define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31)
+#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16)
+#define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16
#define EMAC_MODE_25G_MODE (1L<<5)
#define EMAC_MODE_ACPI_RCVD (1L<<20)
#define EMAC_MODE_HALF_DUPLEX (1L<<1)
@@ -3874,6 +4031,17 @@
#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
#define EMAC_TX_MODE_RESET (1L<<0)
+#define MISC_REGISTERS_GPIO_1 1
+#define MISC_REGISTERS_GPIO_2 2
+#define MISC_REGISTERS_GPIO_3 3
+#define MISC_REGISTERS_GPIO_CLR_POS 16
+#define MISC_REGISTERS_GPIO_FLOAT (0xffL<<24)
+#define MISC_REGISTERS_GPIO_FLOAT_POS 24
+#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1
+#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0
+#define MISC_REGISTERS_GPIO_PORT_SHIFT 4
+#define MISC_REGISTERS_GPIO_SET_POS 8
#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588
#define MISC_REGISTERS_RESET_REG_1_SET 0x584
#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598
@@ -3891,6 +4059,25 @@
#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW (0x1<<4)
#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8)
#define MISC_REGISTERS_RESET_REG_3_SET 0x5a4
+#define MISC_REGISTERS_SPIO_4 4
+#define MISC_REGISTERS_SPIO_5 5
+#define MISC_REGISTERS_SPIO_7 7
+#define MISC_REGISTERS_SPIO_CLR_POS 16
+#define MISC_REGISTERS_SPIO_FLOAT (0xffL<<24)
+#define GRC_MISC_REGISTERS_SPIO_FLOAT7 0x80000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT6 0x40000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT5 0x20000000
+#define GRC_MISC_REGISTERS_SPIO_FLOAT4 0x10000000
+#define MISC_REGISTERS_SPIO_FLOAT_POS 24
+#define MISC_REGISTERS_SPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_SPIO_INT_OLD_SET_POS 16
+#define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1
+#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0
+#define MISC_REGISTERS_SPIO_SET_POS 8
+#define HW_LOCK_MAX_RESOURCE_VALUE 31
+#define HW_LOCK_RESOURCE_8072_MDIO 0
+#define HW_LOCK_RESOURCE_GPIO 1
+#define HW_LOCK_RESOURCE_SPIO 2
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -3918,6 +4105,7 @@
#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3)
#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2)
#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22)
+#define AEU_INPUTS_ATTN_BITS_SPIO5 (1<<15)
#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27)
#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5)
#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25)
@@ -4206,6 +4394,9 @@
#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000
#define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11
#define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS 0x0001
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS 0x0010
#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15
#define MDIO_REG_BANK_GP_STATUS 0x8120
@@ -4362,11 +4553,13 @@
#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001
+#define EXT_PHY_AUTO_NEG_DEVAD 0x7
#define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1
#define EXT_PHY_OPT_WIS_DEVAD 0x2
#define EXT_PHY_OPT_PCS_DEVAD 0x3
#define EXT_PHY_OPT_PHY_XS_DEVAD 0x4
#define EXT_PHY_OPT_CNTL 0x0
+#define EXT_PHY_OPT_CNTL2 0x7
#define EXT_PHY_OPT_PMD_RX_SD 0xa
#define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a
#define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800
@@ -4378,11 +4571,24 @@
#define EXT_PHY_OPT_LASI_STATUS 0x9005
#define EXT_PHY_OPT_PCS_STATUS 0x0020
#define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018
+#define EXT_PHY_OPT_AN_LINK_STATUS 0x8304
+#define EXT_PHY_OPT_AN_CL37_CL73 0x8370
+#define EXT_PHY_OPT_AN_CL37_FD 0xffe4
+#define EXT_PHY_OPT_AN_CL37_AN 0xffe0
+#define EXT_PHY_OPT_AN_ADV 0x11
#define EXT_PHY_KR_PMA_PMD_DEVAD 0x1
#define EXT_PHY_KR_PCS_DEVAD 0x3
#define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7
#define EXT_PHY_KR_CTRL 0x0000
+#define EXT_PHY_KR_STATUS 0x0001
+#define EXT_PHY_KR_AUTO_NEG_COMPLETE 0x0020
+#define EXT_PHY_KR_AUTO_NEG_ADVERT 0x0010
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE 0x0400
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC 0x0800
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH 0x0C00
+#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK 0x0C00
+#define EXT_PHY_KR_LP_AUTO_NEG 0x0013
#define EXT_PHY_KR_CTRL2 0x0007
#define EXT_PHY_KR_PCS_STATUS 0x0020
#define EXT_PHY_KR_PMD_CTRL 0x0096
@@ -4391,4 +4597,8 @@
#define EXT_PHY_KR_MISC_CTRL1 0xca85
#define EXT_PHY_KR_GEN_CTRL 0xca10
#define EXT_PHY_KR_ROM_CODE 0xca19
+#define EXT_PHY_KR_ROM_RESET_INTERNAL_MP 0x0188
+#define EXT_PHY_KR_ROM_MICRO_RESET 0x018a
+
+#define EXT_PHY_SFX7101_XGXS_TEST1 0xc00a
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 57175097513..348371fda59 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -172,30 +172,30 @@ static char version[] __initdata =
them to system IRQ numbers. This mapping is card specific and is set to
the configuration of the Cirrus Eval board for this chip. */
#ifdef CONFIG_ARCH_CLPS7500
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {12,0,0,0};
#elif defined(CONFIG_SH_HICOSH4)
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x0300, 0};
static unsigned int cs8900_irq_map[] = {1,0,0,0};
#elif defined(CONFIG_MACH_IXDP2351)
-static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
#include <asm/irq.h>
#elif defined(CONFIG_ARCH_IXDP2X01)
#include <asm/irq.h>
-static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
#elif defined(CONFIG_ARCH_PNX010X)
#include <asm/irq.h>
#include <asm/arch/gpio.h>
#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
-static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
#else
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {10,11,12,5};
#endif
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 3beace55b58..7fe20310eb5 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -438,7 +438,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
* For non-82573 silicon, write data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data)
@@ -547,7 +547,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
* poll for completion.
*
* If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data)
@@ -1053,7 +1053,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
/* If SerDes loopback mode is entered, there is no form
* of reset to take the adapter out of that mode. So we
* have to explicitly take the adapter out of loopback
- * mode. This prevents drivers from twidling their thumbs
+ * mode. This prevents drivers from twiddling their thumbs
* if another tool failed to take it out of loopback mode.
*/
ew32(SCTL,
@@ -1098,7 +1098,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
* e1000e_get_laa_state_82571 - Get locally administered address state
* @hw: pointer to the HW structure
*
- * Retrieve and return the current locally administed address state.
+ * Retrieve and return the current locally administered address state.
**/
bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
{
@@ -1113,7 +1113,7 @@ bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
* @hw: pointer to the HW structure
* @state: enable/disable locally administered address
*
- * Enable/Disable the current locally administed address state.
+ * Enable/Disable the current locally administers address state.
**/
void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
{
@@ -1281,16 +1281,6 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
static struct e1000_nvm_operations e82571_nvm_ops = {
.acquire_nvm = e1000_acquire_nvm_82571,
- .read_nvm = e1000e_read_nvm_spi,
- .release_nvm = e1000_release_nvm_82571,
- .update_nvm = e1000_update_nvm_checksum_82571,
- .valid_led_default = e1000_valid_led_default_82571,
- .validate_nvm = e1000_validate_nvm_checksum_82571,
- .write_nvm = e1000_write_nvm_82571,
-};
-
-static struct e1000_nvm_operations e82573_nvm_ops = {
- .acquire_nvm = e1000_acquire_nvm_82571,
.read_nvm = e1000e_read_nvm_eerd,
.release_nvm = e1000_release_nvm_82571,
.update_nvm = e1000_update_nvm_checksum_82571,
@@ -1355,6 +1345,6 @@ struct e1000_info e1000_82573_info = {
.get_invariants = e1000_get_invariants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_m88,
- .nvm_ops = &e82573_nvm_ops,
+ .nvm_ops = &e82571_nvm_ops,
};
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 6232c3e9668..a4f511f549f 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -66,7 +66,7 @@
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
/* Extended Device Control */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
@@ -75,12 +75,12 @@
#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
-/* Receive Decriptor bit definitions */
+/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
@@ -223,7 +223,7 @@
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
-/* Constants used to intrepret the masked PCI-X bus speed. */
+/* Constants used to interpret the masked PCI-X bus speed. */
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
@@ -517,7 +517,7 @@
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_STATUS 0x01 /* Status Register */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 8b88c226e85..327c0620da3 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -42,8 +42,7 @@
struct e1000_info;
#define ndev_printk(level, netdev, format, arg...) \
- printk(level "%s: %s: " format, (netdev)->dev.parent->bus_id, \
- (netdev)->name, ## arg)
+ printk(level "%s: " format, (netdev)->name, ## arg)
#ifdef DEBUG
#define ndev_dbg(netdev, format, arg...) \
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 3c5862f97db..916025b30fc 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -184,7 +184,7 @@ enum e1e_registers {
E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */
E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */
E1000_RXCSUM = 0x05000, /* RX Checksum Control - RW */
- E1000_RFCTL = 0x05008, /* Receive Filter Control*/
+ E1000_RFCTL = 0x05008, /* Receive Filter Control */
E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */
E1000_RA = 0x05400, /* Receive Address - RW Array */
E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
@@ -202,7 +202,7 @@ enum e1e_registers {
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
- E1000_HICR = 0x08F00, /* Host Inteface Control */
+ E1000_HICR = 0x08F00, /* Host Interface Control */
};
/* RSS registers */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 8f8139de1f4..0ae39550768 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -671,7 +671,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
* e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
* @hw: pointer to the HW structure
*
- * Polarity is determined on the polarity reveral feature being enabled.
+ * Polarity is determined on the polarity reversal feature being enabled.
* This function is only called by other family-specific
* routines.
**/
@@ -947,7 +947,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
/* Either we should have a hardware SPI cycle in progress
* bit to check against, in order to start a new cycle or
* FDONE bit should be changed in the hardware so that it
- * is 1 after harware reset, which can then be used as an
+ * is 1 after hardware reset, which can then be used as an
* indication whether a cycle is in progress or has been
* completed.
*/
@@ -1155,7 +1155,7 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
* which writes the checksum to the shadow ram. The changes in the shadow
* ram are then committed to the EEPROM by processing each bank at a time
* checking for the modified bit and writing only the pending changes.
- * After a succesful commit, the shadow ram is cleared and is ready for
+ * After a successful commit, the shadow ram is cleared and is ready for
* future writes.
**/
static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
@@ -1680,7 +1680,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
* - initialize LED identification
* - setup receive address registers
* - setup flow control
- * - setup transmit discriptors
+ * - setup transmit descriptors
* - clear statistics
**/
static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
@@ -1961,7 +1961,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
ew32(PHY_CTRL, phy_ctrl);
- /* Call gig speed drop workaround on Giga disable before accessing
+ /* Call gig speed drop workaround on Gig disable before accessing
* any PHY registers */
e1000e_gig_downshift_workaround_ich8lan(hw);
@@ -1972,7 +1972,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
/**
* e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state
* @hw: pointer to the HW structure
- * @state: boolean value used to set the current Kumaran workaround state
+ * @state: boolean value used to set the current Kumeran workaround state
*
* If ICH8, set the current Kumeran workaround state (enabled - TRUE
* /disabled - FALSE).
@@ -2017,7 +2017,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
ew32(PHY_CTRL, reg);
- /* Call gig speed drop workaround on Giga disable before
+ /* Call gig speed drop workaround on Gig disable before
* accessing any PHY registers */
if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
@@ -2045,7 +2045,7 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
* @hw: pointer to the HW structure
*
* Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
- * LPLU, Giga disable, MDIC PHY reset):
+ * LPLU, Gig disable, MDIC PHY reset):
* 1) Set Kumeran Near-end loopback
* 2) Clear Kumeran Near-end loopback
* Should only be called for ICH8[m] devices with IGP_3 Phy.
@@ -2089,10 +2089,10 @@ static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
}
/**
- * e1000_led_on_ich8lan - Turn LED's on
+ * e1000_led_on_ich8lan - Turn LEDs on
* @hw: pointer to the HW structure
*
- * Turn on the LED's.
+ * Turn on the LEDs.
**/
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
{
@@ -2105,10 +2105,10 @@ static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
}
/**
- * e1000_led_off_ich8lan - Turn LED's off
+ * e1000_led_off_ich8lan - Turn LEDs off
* @hw: pointer to the HW structure
*
- * Turn off the LED's.
+ * Turn off the LEDs.
**/
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
{
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 16f35fadb74..95f75a43c9f 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -589,9 +589,6 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
s32 ret_val;
u16 nvm_data;
- if (mac->fc != e1000_fc_default)
- return 0;
-
/* Read and store word 0x0F of the EEPROM. This word contains bits
* that determine the hardware's default PAUSE (flow control) mode,
* a bit that determines whether the HW defaults to enabling or
@@ -1107,34 +1104,13 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
mac->fc = e1000_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
- }
- /* Per the IEEE spec, at this point flow control should be
- * disabled. However, we want to consider that we could
- * be connected to a legacy switch that doesn't advertise
- * desired flow control, but can be forced on the link
- * partner. So if we advertised no flow control, that is
- * what we will resolve to. If we advertised some kind of
- * receive capability (Rx Pause Only or Full Flow Control)
- * and the link partner advertised none, we will configure
- * ourselves to enable Rx Flow Control only. We can do
- * this safely for two reasons: If the link partner really
- * didn't want flow control enabled, and we enable Rx, no
- * harm done since we won't be receiving any PAUSE frames
- * anyway. If the intent on the link partner was to have
- * flow control enabled, then by us enabling RX only, we
- * can at least receive pause frames and process them.
- * This is a good idea because in most cases, since we are
- * predominantly a server NIC, more times than not we will
- * be asked to delay transmission of packets than asking
- * our link partner to pause transmission of frames.
- */
- else if ((mac->original_fc == e1000_fc_none) ||
- (mac->original_fc == e1000_fc_tx_pause)) {
+ } else {
+ /*
+ * Per the IEEE spec, at this point flow control
+ * should be disabled.
+ */
mac->fc = e1000_fc_none;
hw_dbg(hw, "Flow Control = NONE.\r\n");
- } else {
- mac->fc = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
}
/* Now we need to do one last check... If we auto-
@@ -1164,7 +1140,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
}
/**
- * e1000e_get_speed_and_duplex_copper - Retreive current speed/duplex
+ * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1200,7 +1176,7 @@ s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *dup
}
/**
- * e1000e_get_speed_and_duplex_fiber_serdes - Retreive current speed/duplex
+ * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1410,7 +1386,7 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
* e1000e_blink_led - Blink LED
* @hw: pointer to the HW structure
*
- * Blink the led's which are set to be on.
+ * Blink the LEDs which are set to be on.
**/
s32 e1000e_blink_led(struct e1000_hw *hw)
{
@@ -1515,7 +1491,7 @@ void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
* @hw: pointer to the HW structure
*
* Returns 0 if successful, else returns -10
- * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued
+ * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
* the master requests to be disabled.
*
* Disables PCI-Express master access and verifies there are no pending
@@ -1876,7 +1852,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
}
/**
- * e1000e_read_nvm_spi - Read EEPROM's using SPI
+ * e1000e_read_nvm_spi - Reads EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
@@ -1980,7 +1956,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000e_update_nvm_checksum is not called after this function , the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
**/
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
@@ -2222,7 +2198,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
- * This function checks whether the HOST IF is enabled for command operaton
+ * This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
@@ -2254,7 +2230,7 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
}
/**
- * e1000e_check_mng_mode - check managament mode
+ * e1000e_check_mng_mode - check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3031d6d1624..fc5c63f4f57 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1006,7 +1006,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
* e1000_get_hw_control - get control of the h/w from f/w
* @adapter: address of board private structure
*
- * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that
* the driver is loaded. For AMT version (only with 82573)
* of the f/w this means that the network i/f is open.
@@ -1032,7 +1032,7 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter)
* e1000_release_hw_control - release control of the h/w to f/w
* @adapter: address of board private structure
*
- * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
+ * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
* For ASF and Pass Through versions of f/w this means that the
* driver is no longer loaded. For AMT version (only with 82573) i
* of the f/w this means that the network i/f is closed.
@@ -1241,6 +1241,11 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
/**
* e1000_update_itr - update the dynamic ITR value based on statistics
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ *
* Stores a new ITR value based on packets and byte
* counts during the last interrupt. The advantage of per interrupt
* computation is faster updates and more accurate ITR for the current
@@ -1250,10 +1255,6 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
* while increasing bulk throughput.
* this functionality is controlled by the InterruptThrottleRate module
* parameter (see e1000_param.c)
- * @adapter: pointer to adapter
- * @itr_setting: current adapter->itr
- * @packets: the number of packets during this measurement interval
- * @bytes: the number of bytes during this measurement interval
**/
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
u16 itr_setting, int packets,
@@ -1366,6 +1367,7 @@ set_itr_now:
/**
* e1000_clean - NAPI Rx polling callback
* @adapter: board private structure
+ * @budget: amount of packets driver is allowed to process this poll
**/
static int e1000_clean(struct napi_struct *napi, int budget)
{
@@ -2000,7 +2002,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
e1000_check_reset_block(hw))
return;
- /* managebility (AMT) is enabled */
+ /* manageability (AMT) is enabled */
if (er32(MANC) & E1000_MANC_SMBUS_EN)
return;
@@ -3488,7 +3490,6 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
static void e1000e_disable_l1aspm(struct pci_dev *pdev)
{
int pos;
- u32 cap;
u16 val;
/*
@@ -3503,7 +3504,6 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev)
* active.
*/
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
if (val & 0x2) {
dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index fc6fee112f1..dab3c468a76 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -121,7 +121,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
* @offset: register offset to be read
* @data: pointer to the read data
*
- * Reads the MDI control regsiter in the PHY at offset and stores the
+ * Reads the MDI control register in the PHY at offset and stores the
* information read to data.
**/
static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
@@ -1172,7 +1172,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
}
/**
- * e1000e_check_downshift - Checks whether a downshift in speed occured
+ * e1000e_check_downshift - Checks whether a downshift in speed occurred
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns 1
@@ -1388,8 +1388,8 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which reperesent the
- * cobination of course and fine gain value, the value can be put
+ * cable. By reading the AGC registers, which represent the
+ * combination of course and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
**/
@@ -1619,7 +1619,7 @@ s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
* Verify the reset block is not blocking us from resetting. Acquire
* semaphore (if necessary) and read/set/write the device control reset
* bit in the PHY. Wait the appropriate delay time for the device to
- * reset and relase the semaphore (if necessary).
+ * reset and release the semaphore (if necessary).
**/
s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
{
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 88fb53eba71..7c4ead35cfa 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0083"
+#define DRV_VERSION "EHEA_0087"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
@@ -386,6 +386,13 @@ struct ehea_port_res {
#define EHEA_MAX_PORTS 16
+
+#define EHEA_NUM_PORTRES_FW_HANDLES 6 /* QP handle, SendCQ handle,
+ RecvCQ handle, EQ handle,
+ SendMR handle, RecvMR handle */
+#define EHEA_NUM_PORT_FW_HANDLES 1 /* EQ handle */
+#define EHEA_NUM_ADAPTER_FW_HANDLES 2 /* MR handle, NEQ handle */
+
struct ehea_adapter {
u64 handle;
struct of_device *ofdev;
@@ -405,6 +412,31 @@ struct ehea_mc_list {
u64 macaddr;
};
+/* kdump support */
+struct ehea_fw_handle_entry {
+ u64 adh; /* Adapter Handle */
+ u64 fwh; /* Firmware Handle */
+};
+
+struct ehea_fw_handle_array {
+ struct ehea_fw_handle_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
+struct ehea_bcmc_reg_entry {
+ u64 adh; /* Adapter Handle */
+ u32 port_id; /* Logical Port Id */
+ u8 reg_type; /* Registration Type */
+ u64 macaddr;
+};
+
+struct ehea_bcmc_reg_array {
+ struct ehea_bcmc_reg_entry *arr;
+ int num_entries;
+ struct semaphore lock;
+};
+
#define EHEA_PORT_UP 1
#define EHEA_PORT_DOWN 0
#define EHEA_PHY_LINK_UP 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c051c7e09b9..21af674b764 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
#include <linux/if_ether.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <asm/kexec.h>
#include <net/ip.h>
@@ -98,8 +99,10 @@ static int port_name_cnt;
static LIST_HEAD(adapter_list);
u64 ehea_driver_flags;
struct work_struct ehea_rereg_mr_task;
-
struct semaphore dlpar_mem_lock;
+struct ehea_fw_handle_array ehea_fw_handles;
+struct ehea_bcmc_reg_array ehea_bcmc_regs;
+
static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id);
@@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg)
}
}
+static void ehea_update_firmware_handles(void)
+{
+ struct ehea_fw_handle_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ int num_adapters = 0;
+ int num_ports = 0;
+ int num_portres = 0;
+ int i = 0;
+ int num_fw_handles, k, l;
+
+ /* Determine number of handles */
+ list_for_each_entry(adapter, &adapter_list, list) {
+ num_adapters++;
+
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_ports++;
+ num_portres += port->num_def_qps + port->num_add_tx_qps;
+ }
+ }
+
+ num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES +
+ num_ports * EHEA_NUM_PORT_FW_HANDLES +
+ num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
+
+ if (num_fw_handles) {
+ arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ for (l = 0;
+ l < port->num_def_qps + port->num_add_tx_qps;
+ l++) {
+ struct ehea_port_res *pr = &port->port_res[l];
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->qp->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_cq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->eq->fw_handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->send_mr.handle;
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = pr->recv_mr.handle;
+ }
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = port->qp_eq->fw_handle;
+ }
+
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->neq->fw_handle;
+
+ if (adapter->mr.handle) {
+ arr[i].adh = adapter->handle;
+ arr[i++].fwh = adapter->mr.handle;
+ }
+ }
+
+out_update:
+ kfree(ehea_fw_handles.arr);
+ ehea_fw_handles.arr = arr;
+ ehea_fw_handles.num_entries = i;
+}
+
+static void ehea_update_bcmc_registrations(void)
+{
+ struct ehea_bcmc_reg_entry *arr = NULL;
+ struct ehea_adapter *adapter;
+ struct ehea_mc_list *mc_entry;
+ int num_registrations = 0;
+ int i = 0;
+ int k;
+
+ /* Determine number of registrations */
+ list_for_each_entry(adapter, &adapter_list, list)
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ num_registrations += 2; /* Broadcast registrations */
+
+ list_for_each_entry(mc_entry, &port->mc_list->list,list)
+ num_registrations += 2;
+ }
+
+ if (num_registrations) {
+ arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
+ if (!arr)
+ return; /* Keep the existing array */
+ } else
+ goto out_update;
+
+ list_for_each_entry(adapter, &adapter_list, list) {
+ for (k = 0; k < EHEA_MAX_PORTS; k++) {
+ struct ehea_port *port = adapter->port[k];
+
+ if (!port || (port->state != EHEA_PORT_UP))
+ continue;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = port->mac_addr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_BROADCAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = port->mac_addr;
+
+ list_for_each_entry(mc_entry,
+ &port->mc_list->list, list) {
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_UNTAGGED;
+ arr[i++].macaddr = mc_entry->macaddr;
+
+ arr[i].adh = adapter->handle;
+ arr[i].port_id = port->logical_port_id;
+ arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+ EHEA_BCMC_MULTICAST |
+ EHEA_BCMC_VLANID_ALL;
+ arr[i++].macaddr = mc_entry->macaddr;
+ }
+ }
+ }
+
+out_update:
+ kfree(ehea_bcmc_regs.arr);
+ ehea_bcmc_regs.arr = arr;
+ ehea_bcmc_regs.num_entries = i;
+}
+
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
{
struct ehea_port *port = netdev_priv(dev);
@@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
+ down(&ehea_bcmc_regs.lock);
+
/* Deregister old MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
port->mac_addr = cb0->port_mac_addr << 16;
/* Register new MAC in pHYP */
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret)
- goto out_free;
+ goto out_upregs;
ret = 0;
+
+out_upregs:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
out_free:
kfree(cb0);
out:
@@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
+ down(&ehea_bcmc_regs.lock);
+
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
- return;
+ goto out;
}
ehea_allmulti(dev, 0);
@@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
return;
}
@@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
+ down(&ehea_fw_handles.lock);
+
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev)
}
}
- ret = 0;
+ down(&ehea_bcmc_regs.lock);
+
+ ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+ if (ret) {
+ ret = -EIO;
+ goto out_free_irqs;
+ }
+
port->state = EHEA_PORT_UP;
+
+ ret = 0;
goto out;
out_free_irqs:
@@ -2334,6 +2512,12 @@ out:
if (ret)
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
+ down(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
+ ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
ehea_free_interrupts(dev);
+ down(&ehea_fw_handles.lock);
+
port->state = EHEA_PORT_DOWN;
+ ehea_update_bcmc_registrations();
+ up(&ehea_bcmc_regs.lock);
+
ret = ehea_clean_all_portres(port);
if (ret)
ehea_info("Failed freeing resources for %s. ret=%i",
dev->name, ret);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return ret;
}
@@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
INIT_WORK(&port->reset_task, ehea_reset_port);
-
- ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
- if (ret) {
- ret = -EIO;
- goto out_unreg_port;
- }
-
ehea_set_ethtool_ops(dev);
ret = register_netdev(dev);
if (ret) {
ehea_error("register_netdev failed. ret=%d", ret);
- goto out_dereg_bc;
+ goto out_unreg_port;
}
port->lro_max_aggr = lro_max_aggr;
@@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
return port;
-out_dereg_bc:
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
out_unreg_port:
ehea_unregister_port(port);
@@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
{
unregister_netdev(port->netdev);
ehea_unregister_port(port);
- ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
kfree(port->mc_list);
free_netdev(port->netdev);
port->adapter->active_ports--;
@@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
i++;
};
-
return 0;
}
@@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
+ down(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3239,7 +3423,10 @@ out_kill_eq:
out_free_ad:
kfree(adapter);
+
out:
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
return ret;
}
@@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
+ down(&ehea_fw_handles.lock);
+
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
ehea_destroy_eq(adapter->neq);
ehea_remove_adapter_mr(adapter);
list_del(&adapter->list);
-
kfree(adapter);
+ ehea_update_firmware_handles();
+ up(&ehea_fw_handles.lock);
+
return 0;
}
+void ehea_crash_handler(void)
+{
+ int i;
+
+ if (ehea_fw_handles.arr)
+ for (i = 0; i < ehea_fw_handles.num_entries; i++)
+ ehea_h_free_resource(ehea_fw_handles.arr[i].adh,
+ ehea_fw_handles.arr[i].fwh,
+ FORCE_FREE);
+
+ if (ehea_bcmc_regs.arr)
+ for (i = 0; i < ehea_bcmc_regs.num_entries; i++)
+ ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh,
+ ehea_bcmc_regs.arr[i].port_id,
+ ehea_bcmc_regs.arr[i].reg_type,
+ ehea_bcmc_regs.arr[i].macaddr,
+ 0, H_DEREG_BCMC);
+}
+
static int ehea_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *unused)
{
@@ -3330,7 +3540,12 @@ int __init ehea_module_init(void)
INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+ memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
+ memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
+
sema_init(&dlpar_mem_lock, 1);
+ sema_init(&ehea_fw_handles.lock, 1);
+ sema_init(&ehea_bcmc_regs.lock, 1);
ret = check_module_parm();
if (ret)
@@ -3340,12 +3555,18 @@ int __init ehea_module_init(void)
if (ret)
goto out;
- register_reboot_notifier(&ehea_reboot_nb);
+ ret = register_reboot_notifier(&ehea_reboot_nb);
+ if (ret)
+ ehea_info("failed registering reboot notifier");
+
+ ret = crash_shutdown_register(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed registering crash handler");
ret = ibmebus_register_driver(&ehea_driver);
if (ret) {
ehea_error("failed registering eHEA device driver on ebus");
- goto out;
+ goto out2;
}
ret = driver_create_file(&ehea_driver.driver,
@@ -3353,21 +3574,33 @@ int __init ehea_module_init(void)
if (ret) {
ehea_error("failed to register capabilities attribute, ret=%d",
ret);
- unregister_reboot_notifier(&ehea_reboot_nb);
- ibmebus_unregister_driver(&ehea_driver);
- goto out;
+ goto out3;
}
+ return ret;
+
+out3:
+ ibmebus_unregister_driver(&ehea_driver);
+out2:
+ unregister_reboot_notifier(&ehea_reboot_nb);
+ crash_shutdown_unregister(&ehea_crash_handler);
out:
return ret;
}
static void __exit ehea_module_exit(void)
{
+ int ret;
+
flush_scheduled_work();
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
unregister_reboot_notifier(&ehea_reboot_nb);
+ ret = crash_shutdown_unregister(&ehea_crash_handler);
+ if (ret)
+ ehea_info("failed unregistering crash handler");
+ kfree(ehea_fw_handles.arr);
+ kfree(ehea_bcmc_regs.arr);
ehea_destroy_busmap();
}
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 42d94edeee2..af869cf9ae7 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -946,16 +946,11 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct fs_enet_private *fep = netdev_priv(dev);
struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
- unsigned long flags;
- int rc;
if (!netif_running(dev))
return -EINVAL;
- spin_lock_irqsave(&fep->lock, flags);
- rc = phy_mii_ioctl(fep->phydev, mii, cmd);
- spin_unlock_irqrestore(&fep->lock, flags);
- return rc;
+ return phy_mii_ioctl(fep->phydev, mii, cmd);
}
extern int fs_mii_connect(struct net_device *dev);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 4244fc282f2..718cf77e345 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -605,7 +605,7 @@ void stop_gfar(struct net_device *dev)
free_skb_resources(priv);
- dma_free_coherent(NULL,
+ dma_free_coherent(&dev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -626,7 +626,7 @@ static void free_skb_resources(struct gfar_private *priv)
for (i = 0; i < priv->tx_ring_size; i++) {
if (priv->tx_skbuff[i]) {
- dma_unmap_single(NULL, txbdp->bufPtr,
+ dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
txbdp->length,
DMA_TO_DEVICE);
dev_kfree_skb_any(priv->tx_skbuff[i]);
@@ -643,7 +643,7 @@ static void free_skb_resources(struct gfar_private *priv)
if(priv->rx_skbuff != NULL) {
for (i = 0; i < priv->rx_ring_size; i++) {
if (priv->rx_skbuff[i]) {
- dma_unmap_single(NULL, rxbdp->bufPtr,
+ dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
priv->rx_buffer_size,
DMA_FROM_DEVICE);
@@ -708,7 +708,7 @@ int startup_gfar(struct net_device *dev)
gfar_write(&regs->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(NULL,
+ vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
sizeof (struct txbd8) * priv->tx_ring_size +
sizeof (struct rxbd8) * priv->rx_ring_size,
&addr, GFP_KERNEL);
@@ -919,7 +919,7 @@ err_irq_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(NULL,
+ dma_free_coherent(&dev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -1053,7 +1053,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set buffer length and pointer */
txbdp->length = skb->len;
- txbdp->bufPtr = dma_map_single(NULL, skb->data,
+ txbdp->bufPtr = dma_map_single(&dev->dev, skb->data,
skb->len, DMA_TO_DEVICE);
/* Save the skb pointer so we can free it later */
@@ -1332,7 +1332,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
*/
skb_reserve(skb, alignamount);
- bdp->bufPtr = dma_map_single(NULL, skb->data,
+ bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE);
bdp->length = 0;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index bff280eff5e..6a1f2309209 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -439,7 +439,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
err = igb_request_msix(adapter);
if (!err) {
/* enable IAM, auto-mask,
- * DO NOT USE EIAME or IAME in legacy mode */
+ * DO NOT USE EIAM or IAM in legacy mode */
wr32(E1000_IAM, IMS_ENABLE_MASK);
goto request_done;
}
@@ -465,14 +465,9 @@ static int igb_request_irq(struct igb_adapter *adapter)
err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
netdev->name, netdev);
- if (err) {
+ if (err)
dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
err);
- goto request_done;
- }
-
- /* enable IAM, auto-mask */
- wr32(E1000_IAM, IMS_ENABLE_MASK);
request_done:
return err;
@@ -821,7 +816,8 @@ void igb_reset(struct igb_adapter *adapter)
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
igb_reset_adaptive(&adapter->hw);
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+ if (adapter->hw.phy.ops.get_phy_info)
+ adapter->hw.phy.ops.get_phy_info(&adapter->hw);
}
/**
@@ -2057,7 +2053,8 @@ static void igb_set_multi(struct net_device *netdev)
static void igb_update_phy_info(unsigned long data)
{
struct igb_adapter *adapter = (struct igb_adapter *) data;
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+ if (adapter->hw.phy.ops.get_phy_info)
+ adapter->hw.phy.ops.get_phy_info(&adapter->hw);
}
/**
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 53a9fd086f9..75f3a68ee35 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -67,6 +67,7 @@ static struct ixgb_stats ixgb_gstrings_stats[] = {
{"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},
{"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},
{"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)},
+ {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
{"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)},
{"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)},
{"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)},
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 81bf005ff28..1d210ed4613 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -148,7 +148,7 @@ static void macb_handle_link_change(struct net_device *dev)
if (phydev->duplex)
reg |= MACB_BIT(FD);
- if (phydev->speed)
+ if (phydev->speed == SPEED_100)
reg |= MACB_BIT(SPD);
macb_writel(bp, NCFGR, reg);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 6323988dfa1..fd8158a86f6 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -590,6 +590,13 @@ static int pcnet_config(struct pcmcia_device *link)
dev->if_port = 0;
}
+ if ((link->conf.ConfigBase == 0x03c0)
+ && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+ printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
+ printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
+ goto failed;
+ }
+
local_hw_info = get_hwinfo(link);
if (local_hw_info == NULL)
local_hw_info = get_prom(link);
@@ -1567,12 +1574,11 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
-/* PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */
+ PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
-/* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6e9f619c491..963630c65ca 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus)
int i;
int err = 0;
- mutex_init(&bus->mdio_lock);
-
if (NULL == bus || NULL == bus->name ||
NULL == bus->read ||
NULL == bus->write)
return -EINVAL;
+ mutex_init(&bus->mdio_lock);
+
if (bus->reset)
bus->reset(bus);
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 750d2a99cb4..daf5abab953 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2690,6 +2690,7 @@ int gelic_wl_driver_probe(struct gelic_card *card)
return -ENOMEM;
/* setup net_device structure */
+ SET_NETDEV_DEV(netdev, &card->dev->core);
gelic_wl_setup_netdev_ops(netdev);
/* setup some of net_device and register it */
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 202fdf35662..20745fd4e97 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1633,13 +1633,18 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
struct net_device *dev)
{
- u8 from;
+ int rc;
+
+ rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
+ if (rc < 0) {
+ u8 reg;
- pci_read_config_byte(pdev, 0x73, &from);
+ pci_read_config_byte(pdev, 0x73, &reg);
- return (from & 0x00000001) ?
- sis190_get_mac_addr_from_apc(pdev, dev) :
- sis190_get_mac_addr_from_eeprom(pdev, dev);
+ if (reg & 0x00000001)
+ rc = sis190_get_mac_addr_from_apc(pdev, dev);
+ }
+ return rc;
}
static void sis190_set_speed_auto(struct net_device *dev)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 9a6295909e4..54c662690f6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -572,8 +572,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
default:
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+
/* turn off the Rx LED (LED_RX) */
- ledover &= ~PHY_M_LED_MO_RX;
+ ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
}
if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
@@ -602,7 +603,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
/* turn on 100 Mbps LED (LED_LINK100) */
- ledover |= PHY_M_LED_MO_100;
+ ledover |= PHY_M_LED_MO_100(MO_LED_ON);
}
if (ledover)
@@ -3322,82 +3323,80 @@ static void sky2_set_multicast(struct net_device *dev)
/* Can have one global because blinking is controlled by
* ethtool and that is always under RTNL mutex
*/
-static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
+static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
{
- u16 pg;
+ struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
- switch (hw->chip_id) {
- case CHIP_ID_YUKON_XL:
+ spin_lock_bh(&sky2->phy_lock);
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
+ hw->chip_id == CHIP_ID_YUKON_EX ||
+ hw->chip_id == CHIP_ID_YUKON_SUPR) {
+ u16 pg;
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
- on ? (PHY_M_LEDC_LOS_CTRL(1) |
- PHY_M_LEDC_INIT_CTRL(7) |
- PHY_M_LEDC_STA1_CTRL(7) |
- PHY_M_LEDC_STA0_CTRL(7))
- : 0);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- break;
+ switch (mode) {
+ case MO_LED_OFF:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(8) |
+ PHY_M_LEDC_INIT_CTRL(8) |
+ PHY_M_LEDC_STA1_CTRL(8) |
+ PHY_M_LEDC_STA0_CTRL(8));
+ break;
+ case MO_LED_ON:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(9) |
+ PHY_M_LEDC_INIT_CTRL(9) |
+ PHY_M_LEDC_STA1_CTRL(9) |
+ PHY_M_LEDC_STA0_CTRL(9));
+ break;
+ case MO_LED_BLINK:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(0xa) |
+ PHY_M_LEDC_INIT_CTRL(0xa) |
+ PHY_M_LEDC_STA1_CTRL(0xa) |
+ PHY_M_LEDC_STA0_CTRL(0xa));
+ break;
+ case MO_LED_NORM:
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+ PHY_M_LEDC_LOS_CTRL(1) |
+ PHY_M_LEDC_INIT_CTRL(8) |
+ PHY_M_LEDC_STA1_CTRL(7) |
+ PHY_M_LEDC_STA0_CTRL(7));
+ }
- default:
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+ } else
gm_phy_write(hw, port, PHY_MARV_LED_OVER,
- on ? PHY_M_LED_ALL : 0);
- }
+ PHY_M_LED_MO_DUP(mode) |
+ PHY_M_LED_MO_10(mode) |
+ PHY_M_LED_MO_100(mode) |
+ PHY_M_LED_MO_1000(mode) |
+ PHY_M_LED_MO_RX(mode) |
+ PHY_M_LED_MO_TX(mode));
+
+ spin_unlock_bh(&sky2->phy_lock);
}
/* blink LED's for finding board */
static int sky2_phys_id(struct net_device *dev, u32 data)
{
struct sky2_port *sky2 = netdev_priv(dev);
- struct sky2_hw *hw = sky2->hw;
- unsigned port = sky2->port;
- u16 ledctrl, ledover = 0;
- long ms;
- int interrupted;
- int onoff = 1;
+ unsigned int i;
- if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
- ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
- else
- ms = data * 1000;
-
- /* save initial values */
- spin_lock_bh(&sky2->phy_lock);
- if (hw->chip_id == CHIP_ID_YUKON_XL) {
- u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- } else {
- ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
- ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
- }
-
- interrupted = 0;
- while (!interrupted && ms > 0) {
- sky2_led(hw, port, onoff);
- onoff = !onoff;
-
- spin_unlock_bh(&sky2->phy_lock);
- interrupted = msleep_interruptible(250);
- spin_lock_bh(&sky2->phy_lock);
-
- ms -= 250;
- }
+ if (data == 0)
+ data = UINT_MAX;
- /* resume regularly scheduled programming */
- if (hw->chip_id == CHIP_ID_YUKON_XL) {
- u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- } else {
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
- gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+ for (i = 0; i < data; i++) {
+ sky2_led(sky2, MO_LED_ON);
+ if (msleep_interruptible(500))
+ break;
+ sky2_led(sky2, MO_LED_OFF);
+ if (msleep_interruptible(500))
+ break;
}
- spin_unlock_bh(&sky2->phy_lock);
+ sky2_led(sky2, MO_LED_NORM);
return 0;
}
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 5ab5c1c7c5a..7bb3ba9bcbd 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1318,18 +1318,21 @@ enum {
BLINK_670MS = 4,/* 670 ms */
};
-/**** PHY_MARV_LED_OVER 16 bit r/w LED control */
-enum {
- PHY_M_LED_MO_DUP = 3<<10,/* Bit 11..10: Duplex */
- PHY_M_LED_MO_10 = 3<<8, /* Bit 9.. 8: Link 10 */
- PHY_M_LED_MO_100 = 3<<6, /* Bit 7.. 6: Link 100 */
- PHY_M_LED_MO_1000 = 3<<4, /* Bit 5.. 4: Link 1000 */
- PHY_M_LED_MO_RX = 3<<2, /* Bit 3.. 2: Rx */
- PHY_M_LED_MO_TX = 3<<0, /* Bit 1.. 0: Tx */
-
- PHY_M_LED_ALL = PHY_M_LED_MO_DUP | PHY_M_LED_MO_10
- | PHY_M_LED_MO_100 | PHY_M_LED_MO_1000
- | PHY_M_LED_MO_RX,
+/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x) ((x)<<14) /* Bit 15..14: SGMII AN Timer */
+
+#define PHY_M_LED_MO_DUP(x) ((x)<<10) /* Bit 11..10: Duplex */
+#define PHY_M_LED_MO_10(x) ((x)<<8) /* Bit 9.. 8: Link 10 */
+#define PHY_M_LED_MO_100(x) ((x)<<6) /* Bit 7.. 6: Link 100 */
+#define PHY_M_LED_MO_1000(x) ((x)<<4) /* Bit 5.. 4: Link 1000 */
+#define PHY_M_LED_MO_RX(x) ((x)<<2) /* Bit 3.. 2: Rx */
+#define PHY_M_LED_MO_TX(x) ((x)<<0) /* Bit 1.. 0: Tx */
+
+enum led_mode {
+ MO_LED_NORM = 0,
+ MO_LED_BLINK = 1,
+ MO_LED_OFF = 2,
+ MO_LED_ON = 3,
};
/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 3af5b92b48c..0166407d706 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -1400,7 +1400,7 @@ static void TLan_SetMulticastList( struct net_device *dev )
*
**************************************************************/
-u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
{
/* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
return 0;
@@ -1432,7 +1432,7 @@ u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int eoc = 0;
@@ -1518,7 +1518,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
{
TLan_ReadAndClearStats( dev, TLAN_RECORD );
@@ -1554,7 +1554,7 @@ u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 ack = 0;
@@ -1689,7 +1689,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
{
printk( "TLAN: Test interrupt on %s.\n", dev->name );
return 1;
@@ -1719,7 +1719,7 @@ u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
TLanList *head_list;
@@ -1767,7 +1767,7 @@ u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 ack;
@@ -1842,7 +1842,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
*
**************************************************************/
-u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
{
TLanPrivateInfo *priv = netdev_priv(dev);
dma_addr_t head_list_phys;
@@ -1902,7 +1902,7 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
*
**************************************************************/
-void TLan_Timer( unsigned long data )
+static void TLan_Timer( unsigned long data )
{
struct net_device *dev = (struct net_device *) data;
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -1983,7 +1983,7 @@ void TLan_Timer( unsigned long data )
*
**************************************************************/
-void TLan_ResetLists( struct net_device *dev )
+static void TLan_ResetLists( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int i;
@@ -2043,7 +2043,7 @@ void TLan_ResetLists( struct net_device *dev )
} /* TLan_ResetLists */
-void TLan_FreeLists( struct net_device *dev )
+static void TLan_FreeLists( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
int i;
@@ -2092,7 +2092,7 @@ void TLan_FreeLists( struct net_device *dev )
*
**************************************************************/
-void TLan_PrintDio( u16 io_base )
+static void TLan_PrintDio( u16 io_base )
{
u32 data0, data1;
int i;
@@ -2127,7 +2127,7 @@ void TLan_PrintDio( u16 io_base )
*
**************************************************************/
-void TLan_PrintList( TLanList *list, char *type, int num)
+static void TLan_PrintList( TLanList *list, char *type, int num)
{
int i;
@@ -2163,7 +2163,7 @@ void TLan_PrintList( TLanList *list, char *type, int num)
*
**************************************************************/
-void TLan_ReadAndClearStats( struct net_device *dev, int record )
+static void TLan_ReadAndClearStats( struct net_device *dev, int record )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u32 tx_good, tx_under;
@@ -2238,7 +2238,7 @@ void TLan_ReadAndClearStats( struct net_device *dev, int record )
*
**************************************************************/
-void
+static void
TLan_ResetAdapter( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -2324,7 +2324,7 @@ TLan_ResetAdapter( struct net_device *dev )
-void
+static void
TLan_FinishReset( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
@@ -2448,7 +2448,7 @@ TLan_FinishReset( struct net_device *dev )
*
**************************************************************/
-void TLan_SetMac( struct net_device *dev, int areg, char *mac )
+static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
{
int i;
@@ -2490,7 +2490,7 @@ void TLan_SetMac( struct net_device *dev, int areg, char *mac )
*
********************************************************************/
-void TLan_PhyPrint( struct net_device *dev )
+static void TLan_PhyPrint( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 i, data0, data1, data2, data3, phy;
@@ -2539,7 +2539,7 @@ void TLan_PhyPrint( struct net_device *dev )
*
********************************************************************/
-void TLan_PhyDetect( struct net_device *dev )
+static void TLan_PhyDetect( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 control;
@@ -2586,7 +2586,7 @@ void TLan_PhyDetect( struct net_device *dev )
-void TLan_PhyPowerDown( struct net_device *dev )
+static void TLan_PhyPowerDown( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 value;
@@ -2611,7 +2611,7 @@ void TLan_PhyPowerDown( struct net_device *dev )
-void TLan_PhyPowerUp( struct net_device *dev )
+static void TLan_PhyPowerUp( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 value;
@@ -2632,7 +2632,7 @@ void TLan_PhyPowerUp( struct net_device *dev )
-void TLan_PhyReset( struct net_device *dev )
+static void TLan_PhyReset( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 phy;
@@ -2660,7 +2660,7 @@ void TLan_PhyReset( struct net_device *dev )
-void TLan_PhyStartLink( struct net_device *dev )
+static void TLan_PhyStartLink( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 ability;
@@ -2747,7 +2747,7 @@ void TLan_PhyStartLink( struct net_device *dev )
-void TLan_PhyFinishAutoNeg( struct net_device *dev )
+static void TLan_PhyFinishAutoNeg( struct net_device *dev )
{
TLanPrivateInfo *priv = netdev_priv(dev);
u16 an_adv;
@@ -2903,7 +2903,7 @@ void TLan_PhyMonitor( struct net_device *dev )
*
**************************************************************/
-int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
+static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
{
u8 nack;
u16 sio, tmp;
@@ -2993,7 +2993,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
*
**************************************************************/
-void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
+static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
{
u16 sio;
u32 i;
@@ -3035,7 +3035,7 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
*
**************************************************************/
-void TLan_MiiSync( u16 base_port )
+static void TLan_MiiSync( u16 base_port )
{
int i;
u16 sio;
@@ -3074,7 +3074,7 @@ void TLan_MiiSync( u16 base_port )
*
**************************************************************/
-void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
+static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
{
u16 sio;
int minten;
@@ -3144,7 +3144,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
*
**************************************************************/
-void TLan_EeSendStart( u16 io_base )
+static void TLan_EeSendStart( u16 io_base )
{
u16 sio;
@@ -3184,7 +3184,7 @@ void TLan_EeSendStart( u16 io_base )
*
**************************************************************/
-int TLan_EeSendByte( u16 io_base, u8 data, int stop )
+static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
{
int err;
u8 place;
@@ -3245,7 +3245,7 @@ int TLan_EeSendByte( u16 io_base, u8 data, int stop )
*
**************************************************************/
-void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
+static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
{
u8 place;
u16 sio;
@@ -3303,7 +3303,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
*
**************************************************************/
-int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
+static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
{
int err;
TLanPrivateInfo *priv = netdev_priv(dev);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index a7afeea156b..a59c1f224aa 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -482,9 +482,11 @@ static void uli526x_init(struct net_device *dev)
struct uli526x_board_info *db = netdev_priv(dev);
unsigned long ioaddr = db->ioaddr;
u8 phy_tmp;
+ u8 timeout;
u16 phy_value;
u16 phy_reg_reset;
+
ULI526X_DBUG(0, "uli526x_init()", 0);
/* Reset M526x MAC controller */
@@ -509,11 +511,19 @@ static void uli526x_init(struct net_device *dev)
/* Parser SROM and media mode */
db->media_mode = uli526x_media_mode;
- /* Phyxcer capability setting */
+ /* phyxcer capability setting */
phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id);
phy_reg_reset = (phy_reg_reset | 0x8000);
phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id);
+
+ /* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management
+ * functions") or phy data sheet for details on phy reset
+ */
udelay(500);
+ timeout = 10;
+ while (timeout-- &&
+ phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000)
+ udelay(100);
/* Process Phyxcer Media Mode */
uli526x_set_phyxcer(db);
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 7c851b1e6da..8c9d6ae2bb3 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1893,7 +1893,7 @@ static void rhine_shutdown (struct pci_dev *pdev)
/* Make sure we use pattern 0, 1 and not 4, 5 */
if (rp->quirks & rq6patterns)
- iowrite8(0x04, ioaddr + 0xA7);
+ iowrite8(0x04, ioaddr + WOLcgClr);
if (rp->wolopts & WAKE_MAGIC) {
iowrite8(WOLmagic, ioaddr + WOLcrSet);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fdc23678117..19fd4cb0ddf 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -361,6 +361,7 @@ static int virtnet_probe(struct virtio_device *vdev)
netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight);
vi->dev = dev;
vi->vdev = vdev;
+ vdev->priv = vi;
/* We expect two virtqueues, receive then send. */
vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
@@ -395,7 +396,6 @@ static int virtnet_probe(struct virtio_device *vdev)
}
pr_debug("virtnet: registered device %s\n", dev->name);
- vdev->priv = vi;
return 0;
unregister:
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1a2141dabdc..8bc4bc4c330 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -32,6 +32,7 @@ config B43_PCI_AUTOSELECT
bool
depends on B43 && SSB_PCIHOST_POSSIBLE
select SSB_PCIHOST
+ select SSB_B43_PCI_BRIDGE
default y
# Auto-select SSB PCICORE driver, if possible
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index 6745579ba96..13c65faf024 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -25,6 +25,7 @@ config B43LEGACY_PCI_AUTOSELECT
bool
depends on B43LEGACY && SSB_PCIHOST_POSSIBLE
select SSB_PCIHOST
+ select SSB_B43_PCI_BRIDGE
default y
# Auto-select SSB PCICORE driver, if possible
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
index 0159701e845..afb8f4305c2 100644
--- a/drivers/net/wireless/bcm43xx/Kconfig
+++ b/drivers/net/wireless/bcm43xx/Kconfig
@@ -1,6 +1,6 @@
config BCM43XX
tristate "Broadcom BCM43xx wireless support (DEPRECATED)"
- depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
+ depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && (!SSB_B43_PCI_BRIDGE || SSB != y) && EXPERIMENTAL
select WIRELESS_EXT
select FW_LOADER
select HW_RANDOM
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index eab020338fd..b3c1acbcc65 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1040,7 +1040,6 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
lbs_deb_leave(LBS_DEB_CMD);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_mesh_access);
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
{
@@ -1576,7 +1575,6 @@ done:
lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
/**
* @brief This function allocates the command buffer and link
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index aaacd9bd6bd..4e22341b4f3 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -69,7 +69,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
int lbs_remove_card(struct lbs_private *priv);
int lbs_start_card(struct lbs_private *priv);
int lbs_stop_card(struct lbs_private *priv);
-int lbs_reset_device(struct lbs_private *priv);
void lbs_host_to_card_done(struct lbs_private *priv);
int lbs_update_channel(struct lbs_private *priv);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 84fb49ca0fa..4d4e2f3b66a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1351,8 +1351,6 @@ done:
lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
return ret;
}
-EXPORT_SYMBOL_GPL(lbs_add_mesh);
-
static void lbs_remove_mesh(struct lbs_private *priv)
{
@@ -1372,7 +1370,6 @@ static void lbs_remove_mesh(struct lbs_private *priv)
free_netdev(mesh_dev);
lbs_deb_leave(LBS_DEB_MESH);
}
-EXPORT_SYMBOL_GPL(lbs_remove_mesh);
/**
* @brief This function finds the CFP in
@@ -1458,20 +1455,6 @@ void lbs_interrupt(struct lbs_private *priv)
}
EXPORT_SYMBOL_GPL(lbs_interrupt);
-int lbs_reset_device(struct lbs_private *priv)
-{
- int ret;
-
- lbs_deb_enter(LBS_DEB_MAIN);
- ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
- CMD_ACT_HALT, 0, 0, NULL);
- msleep_interruptible(10);
-
- lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
- return ret;
-}
-EXPORT_SYMBOL_GPL(lbs_reset_device);
-
static int __init lbs_init_module(void)
{
lbs_deb_enter(LBS_DEB_MAIN);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 8ce2ddf8024..d9460aed1f2 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -228,9 +228,9 @@ struct NDIS_WLAN_BSSID_EX {
struct NDIS_802_11_SSID Ssid;
__le32 Privacy;
__le32 Rssi;
- enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ __le32 NetworkTypeInUse;
struct NDIS_802_11_CONFIGURATION Configuration;
- enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ __le32 InfrastructureMode;
u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
__le32 IELength;
u8 IEs[0];
@@ -279,11 +279,11 @@ struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
} __attribute__((packed));
/* these have to match what is in wpa_supplicant */
-enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 }
- wpa_cipher;
-enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA,
- KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
+enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
+ CIPHER_WEP104 };
+enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
+ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
/*
* private data
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d6cba138c7a..c69f85ed766 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -960,8 +960,12 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2400pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2400pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e874fdcae20..91e87b53374 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1112,8 +1112,12 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2500pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 4ca9730e5e9..638c3d24310 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1001,8 +1001,12 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt2500usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt2500usb_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 72cfe00c1ed..07adc576db4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -97,12 +97,16 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
libconf.ant.rx = rx;
libconf.ant.tx = tx;
+ if (rx == rt2x00dev->link.ant.active.rx &&
+ tx == rt2x00dev->link.ant.active.tx)
+ return;
+
/*
* Antenna setup changes require the RX to be disabled,
* else the changes will be ignored by the device.
*/
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
/*
* Write new antenna setup to device and reset the link tuner.
@@ -116,7 +120,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00dev->link.ant.active.tx = libconf.ant.tx;
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c4be2ac4d7a..0d51f478bcd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -61,11 +61,33 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring);
/*
* Link tuning handlers
*/
-static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
+void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
{
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Reset link information.
+ * Both the currently active vgc level as well as
+ * the link tuner counter should be reset. Resetting
+ * the counter is important for devices where the
+ * device should only perform link tuning during the
+ * first minute after being enabled.
+ */
rt2x00dev->link.count = 0;
rt2x00dev->link.vgc_level = 0;
+ /*
+ * Reset the link tuner.
+ */
+ rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
+}
+
+static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ /*
+ * Clear all (possibly) pre-existing quality statistics.
+ */
memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
/*
@@ -79,10 +101,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.qual.rx_percentage = 50;
rt2x00dev->link.qual.tx_percentage = 50;
- /*
- * Reset the link tuner.
- */
- rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
+ rt2x00lib_reset_link_tuner(rt2x00dev);
queue_delayed_work(rt2x00dev->hw->workqueue,
&rt2x00dev->link.work, LINK_TUNE_INTERVAL);
@@ -93,15 +112,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
cancel_delayed_work_sync(&rt2x00dev->link.work);
}
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- rt2x00lib_stop_link_tuner(rt2x00dev);
- rt2x00lib_start_link_tuner(rt2x00dev);
-}
-
/*
* Ring initialization
*/
@@ -260,19 +270,11 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
if (sample_a == sample_b)
return;
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) {
- if (sample_a > sample_b && rx == ANTENNA_B)
- rx = ANTENNA_A;
- else if (rx == ANTENNA_A)
- rx = ANTENNA_B;
- }
+ if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
+ rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) {
- if (sample_a > sample_b && tx == ANTENNA_B)
- tx = ANTENNA_A;
- else if (tx == ANTENNA_A)
- tx = ANTENNA_B;
- }
+ if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
+ tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
rt2x00lib_config_antenna(rt2x00dev, rx, tx);
}
@@ -293,7 +295,7 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
* sample the rssi from the other antenna to make a valid
* comparison between the 2 antennas.
*/
- if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5)
+ if (abs(rssi_curr - rssi_old) < 5)
return;
rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
@@ -319,15 +321,15 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
- rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
- rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY)
+ rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
!(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
- rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+ rt2x00dev->link.ant.flags = 0;
return;
}
@@ -441,17 +443,18 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
rt2x00dev->ops->lib->link_tuner(rt2x00dev);
/*
- * Evaluate antenna setup.
- */
- rt2x00lib_evaluate_antenna(rt2x00dev);
-
- /*
* Precalculate a portion of the link signal which is
* in based on the tx/rx success/failure counters.
*/
rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
/*
+ * Evaluate antenna setup, make this the last step since this could
+ * possibly reset some statistics.
+ */
+ rt2x00lib_evaluate_antenna(rt2x00dev);
+
+ /*
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev->link.count++;
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 838421216da..b1915dc7dda 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -85,6 +85,8 @@ enum dev_state {
STATE_RADIO_OFF,
STATE_RADIO_RX_ON,
STATE_RADIO_RX_OFF,
+ STATE_RADIO_RX_ON_LINK,
+ STATE_RADIO_RX_OFF_LINK,
STATE_RADIO_IRQ_ON,
STATE_RADIO_IRQ_OFF,
};
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index b31f0c26c32..e808db98f2f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1482,8 +1482,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
rt61pci_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt61pci_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4d576ab3e7f..4fac2d414d8 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1208,8 +1208,12 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
rt73usb_disable_radio(rt2x00dev);
break;
case STATE_RADIO_RX_ON:
+ case STATE_RADIO_RX_ON_LINK:
+ rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+ break;
case STATE_RADIO_RX_OFF:
- rt73usb_toggle_rx(rt2x00dev, state);
+ case STATE_RADIO_RX_OFF_LINK:
+ rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index c3076217871..d8a5c229c5a 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1851,8 +1851,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
}
}
/* See how many write buffers are required to hold this data */
- numBuffers= ( skb->len + privptr->p_env->write_size - 1) /
- ( privptr->p_env->write_size);
+ numBuffers = DIV_ROUND_UP(skb->len, privptr->p_env->write_size);
/* If that number of buffers isn't available, give up for now */
if (privptr->write_free_count < numBuffers ||
@@ -2114,8 +2113,7 @@ init_ccw_bk(struct net_device *dev)
*/
ccw_blocks_perpage= PAGE_SIZE / CCWBK_SIZE;
ccw_pages_required=
- (ccw_blocks_required+ccw_blocks_perpage -1) /
- ccw_blocks_perpage;
+ DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage);
#ifdef DEBUGMSG
printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n",
@@ -2131,30 +2129,29 @@ init_ccw_bk(struct net_device *dev)
* provide good performance. With packing buffers support 32k
* buffers are used.
*/
- if (privptr->p_env->read_size < PAGE_SIZE) {
- claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size;
- claw_read_pages= (privptr->p_env->read_buffers +
- claw_reads_perpage -1) / claw_reads_perpage;
+ if (privptr->p_env->read_size < PAGE_SIZE) {
+ claw_reads_perpage = PAGE_SIZE / privptr->p_env->read_size;
+ claw_read_pages = DIV_ROUND_UP(privptr->p_env->read_buffers,
+ claw_reads_perpage);
}
else { /* > or equal */
- privptr->p_buff_pages_perread=
- (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
- claw_read_pages=
- privptr->p_env->read_buffers * privptr->p_buff_pages_perread;
+ privptr->p_buff_pages_perread =
+ DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+ claw_read_pages = privptr->p_env->read_buffers *
+ privptr->p_buff_pages_perread;
}
if (privptr->p_env->write_size < PAGE_SIZE) {
- claw_writes_perpage=
- PAGE_SIZE / privptr->p_env->write_size;
- claw_write_pages=
- (privptr->p_env->write_buffers + claw_writes_perpage -1) /
- claw_writes_perpage;
+ claw_writes_perpage =
+ PAGE_SIZE / privptr->p_env->write_size;
+ claw_write_pages = DIV_ROUND_UP(privptr->p_env->write_buffers,
+ claw_writes_perpage);
}
else { /* > or equal */
- privptr->p_buff_pages_perwrite=
- (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
- claw_write_pages=
- privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite;
+ privptr->p_buff_pages_perwrite =
+ DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+ claw_write_pages = privptr->p_env->write_buffers *
+ privptr->p_buff_pages_perwrite;
}
#ifdef DEBUGMSG
if (privptr->p_env->read_size < PAGE_SIZE) {
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 78fd33125e0..adea792fb67 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -35,6 +35,11 @@ config SSB_PCIHOST
If unsure, say Y
+config SSB_B43_PCI_BRIDGE
+ bool
+ depends on SSB_PCIHOST
+ default n
+
config SSB_PCMCIAHOST_POSSIBLE
bool
depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index e235144add7..de94c2eb7a3 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -14,6 +14,6 @@ ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
# b43 pci-ssb-bridge driver
# Not strictly a part of SSB, but kept here for convenience
-ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o
+ssb-$(CONFIG_SSB_B43_PCI_BRIDGE) += b43_pci_bridge.o
obj-$(CONFIG_SSB) += ssb.o
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 6d99a988005..07ab48d9cea 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -393,7 +393,7 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
chipid_top != 0x5300)
return 0;
- if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
+ if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
return 0;
/* The 200-pin BCM4712 package does not bond out PCI. Even when
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index a789364264a..21eca2b5118 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -120,10 +120,10 @@ extern int ssb_devices_thaw(struct ssb_bus *bus);
extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
/* b43_pci_bridge.c */
-#ifdef CONFIG_SSB_PCIHOST
+#ifdef CONFIG_SSB_B43_PCI_BRIDGE
extern int __init b43_pci_ssb_bridge_init(void);
extern void __exit b43_pci_ssb_bridge_exit(void);
-#else /* CONFIG_SSB_PCIHOST */
+#else /* CONFIG_SSB_B43_PCI_BRIDGR */
static inline int b43_pci_ssb_bridge_init(void)
{
return 0;