summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c118
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c298
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c11
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c44
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h11
-rw-r--r--drivers/net/ethernet/broadcom/sb1250-mac.c3
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c36
10 files changed, 299 insertions, 227 deletions
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index d44331eb07fe..986019b2c849 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1727,7 +1727,7 @@ static int __devinit bcm_enet_probe(struct platform_device *pdev)
bus->priv = priv;
bus->read = bcm_enet_mdio_read_phylib;
bus->write = bcm_enet_mdio_write_phylib;
- sprintf(bus->id, "%d", priv->mac_id);
+ sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id);
/* only probe bus where we think the PHY is, because
* the mdio read operation return 0 instead of 0xffff
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 2b731b253598..03f3935fd8c2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3117,7 +3117,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
int rx_ring_size = 0;
#ifdef BCM_CNIC
- if (IS_MF_ISCSI_SD(bp)) {
+ if (!bp->rx_ring_size && IS_MF_ISCSI_SD(bp)) {
rx_ring_size = MIN_RX_SIZE_NONTPA;
bp->rx_ring_size = rx_ring_size;
} else
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index a688b9d975a2..31a8b38ab15e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -365,13 +365,18 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx);
if (cmd->autoneg == AUTONEG_ENABLE) {
+ u32 an_supported_speed = bp->port.supported[cfg_idx];
+ if (bp->link_params.phy[EXT_PHY1].type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+ an_supported_speed |= (SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full);
if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
DP(NETIF_MSG_LINK, "Autoneg not supported\n");
return -EINVAL;
}
/* advertise the requested speed and duplex if supported */
- if (cmd->advertising & ~(bp->port.supported[cfg_idx])) {
+ if (cmd->advertising & ~an_supported_speed) {
DP(NETIF_MSG_LINK, "Advertisement parameters "
"are not supported\n");
return -EINVAL;
@@ -1733,7 +1738,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
struct bnx2x_fp_txdata *txdata = &fp_tx->txdata[0];
u16 tx_start_idx, tx_idx;
u16 rx_start_idx, rx_idx;
- u16 pkt_prod, bd_prod, rx_comp_cons;
+ u16 pkt_prod, bd_prod;
struct sw_tx_bd *tx_buf;
struct eth_tx_start_bd *tx_start_bd;
struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
@@ -1868,8 +1873,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
if (rx_idx != rx_start_idx + num_pkts)
goto test_loopback_exit;
- rx_comp_cons = le16_to_cpu(fp_rx->rx_comp_cons);
- cqe = &fp_rx->rx_comp_ring[RCQ_BD(rx_comp_cons)];
+ cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
@@ -2116,18 +2120,16 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
case ETH_SS_STATS:
if (is_multi(bp)) {
num_stats = bnx2x_num_stat_queues(bp) *
- BNX2X_NUM_Q_STATS;
- if (!IS_MF_MODE_STAT(bp))
- num_stats += BNX2X_NUM_STATS;
- } else {
- if (IS_MF_MODE_STAT(bp)) {
- num_stats = 0;
- for (i = 0; i < BNX2X_NUM_STATS; i++)
- if (IS_FUNC_STAT(i))
- num_stats++;
- } else
- num_stats = BNX2X_NUM_STATS;
- }
+ BNX2X_NUM_Q_STATS;
+ } else
+ num_stats = 0;
+ if (IS_MF_MODE_STAT(bp)) {
+ for (i = 0; i < BNX2X_NUM_STATS; i++)
+ if (IS_FUNC_STAT(i))
+ num_stats++;
+ } else
+ num_stats += BNX2X_NUM_STATS;
+
return num_stats;
case ETH_SS_TEST:
@@ -2146,8 +2148,8 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
switch (stringset) {
case ETH_SS_STATS:
+ k = 0;
if (is_multi(bp)) {
- k = 0;
for_each_eth_queue(bp, i) {
memset(queue_name, 0, sizeof(queue_name));
sprintf(queue_name, "%d", i);
@@ -2158,20 +2160,17 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
queue_name);
k += BNX2X_NUM_Q_STATS;
}
- if (IS_MF_MODE_STAT(bp))
- break;
- for (j = 0; j < BNX2X_NUM_STATS; j++)
- strcpy(buf + (k + j)*ETH_GSTRING_LEN,
- bnx2x_stats_arr[j].string);
- } else {
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
- continue;
- strcpy(buf + j*ETH_GSTRING_LEN,
- bnx2x_stats_arr[i].string);
- j++;
- }
}
+
+
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
+
break;
case ETH_SS_TEST:
@@ -2185,10 +2184,9 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
{
struct bnx2x *bp = netdev_priv(dev);
u32 *hw_stats, *offset;
- int i, j, k;
+ int i, j, k = 0;
if (is_multi(bp)) {
- k = 0;
for_each_eth_queue(bp, i) {
hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
@@ -2209,46 +2207,28 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
}
k += BNX2X_NUM_Q_STATS;
}
- if (IS_MF_MODE_STAT(bp))
- return;
- hw_stats = (u32 *)&bp->eth_stats;
- for (j = 0; j < BNX2X_NUM_STATS; j++) {
- if (bnx2x_stats_arr[j].size == 0) {
- /* skip this counter */
- buf[k + j] = 0;
- continue;
- }
- offset = (hw_stats + bnx2x_stats_arr[j].offset);
- if (bnx2x_stats_arr[j].size == 4) {
- /* 4-byte counter */
- buf[k + j] = (u64) *offset;
- continue;
- }
- /* 8-byte counter */
- buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ j++;
+ continue;
}
- } else {
- hw_stats = (u32 *)&bp->eth_stats;
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
- continue;
- if (bnx2x_stats_arr[i].size == 0) {
- /* skip this counter */
- buf[j] = 0;
- j++;
- continue;
- }
- offset = (hw_stats + bnx2x_stats_arr[i].offset);
- if (bnx2x_stats_arr[i].size == 4) {
- /* 4-byte counter */
- buf[j] = (u64) *offset;
- j++;
- continue;
- }
- /* 8-byte counter */
- buf[j] = HILO_U64(*offset, *(offset + 1));
+ offset = (hw_stats + bnx2x_stats_arr[i].offset);
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
j++;
+ continue;
}
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ j++;
}
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 4df9505b67b6..2091e5dbbcdd 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -2502,7 +2502,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params,
struct bnx2x_nig_brb_pfc_port_params *nig_params)
{
u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
- u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
+ u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
u32 pkt_priority_to_cos = 0;
struct bnx2x *bp = params->bp;
u8 port = params->port;
@@ -2516,9 +2516,8 @@ static void bnx2x_update_pfc_nig(struct link_params *params,
* MAC control frames (that are not pause packets)
* will be forwarded to the XCM.
*/
- xcm_mask = REG_RD(bp,
- port ? NIG_REG_LLH1_XCM_MASK :
- NIG_REG_LLH0_XCM_MASK);
+ xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
+ NIG_REG_LLH0_XCM_MASK);
/*
* nig params will override non PFC params, since it's possible to
* do transition from PFC to SAFC
@@ -2533,8 +2532,8 @@ static void bnx2x_update_pfc_nig(struct link_params *params,
ppp_enable = 1;
xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
- xcm0_out_en = 0;
- p0_hwpfc_enable = 1;
+ xcm_out_en = 0;
+ hwpfc_enable = 1;
} else {
if (nig_params) {
llfc_out_en = nig_params->llfc_out_en;
@@ -2545,7 +2544,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params,
xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
- xcm0_out_en = 1;
+ xcm_out_en = 1;
}
if (CHIP_IS_E3(bp))
@@ -2564,13 +2563,16 @@ static void bnx2x_update_pfc_nig(struct link_params *params,
REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
NIG_REG_LLH0_XCM_MASK, xcm_mask);
- REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
+ REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
+ NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
/* output enable for RX_XCM # IF */
- REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
+ REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
+ NIG_REG_XCM0_OUT_EN, xcm_out_en);
/* HW PFC TX enable */
- REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
+ REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
+ NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
if (nig_params) {
u8 i = 0;
@@ -3761,7 +3763,15 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
/* Advertise pause */
bnx2x_ext_phy_set_pause(params, phy, vars);
- vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
+ /*
+ * Set KR Autoneg Work-Around flag for Warpcore version older than D108
+ */
+ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
+ if (val16 < 0xd108) {
+ DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
+ vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
+ }
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_DIGITAL5_MISC7, &val16);
@@ -9266,62 +9276,68 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
/* BCM8481/BCM84823/BCM84833 PHY SECTION */
/******************************************************************/
static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
- struct link_params *params)
+ struct bnx2x *bp,
+ u8 port)
{
u16 val, fw_ver1, fw_ver2, cnt;
- u8 port;
- struct bnx2x *bp = params->bp;
- port = params->port;
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
+ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
+ bnx2x_save_spirom_version(bp, port,
+ ((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f),
+ phy->ver_addr);
+ } else {
+ /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
+ /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
+ break;
+ udelay(5);
+ }
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx "
+ "phy fw version(1)\n");
+ bnx2x_save_spirom_version(bp, port, 0,
+ phy->ver_addr);
+ return;
+ }
- /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
- /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
- if (val & 1)
- break;
- udelay(5);
- }
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
- bnx2x_save_spirom_version(bp, port, 0,
- phy->ver_addr);
- return;
- }
+ /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
+ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+ if (val & 1)
+ break;
+ udelay(5);
+ }
+ if (cnt == 100) {
+ DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw "
+ "version(2)\n");
+ bnx2x_save_spirom_version(bp, port, 0,
+ phy->ver_addr);
+ return;
+ }
+ /* lower 16 bits of the register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
+ /* upper 16 bits of register SPI_FW_STATUS */
+ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
- /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
- bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
- for (cnt = 0; cnt < 100; cnt++) {
- bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
- if (val & 1)
- break;
- udelay(5);
- }
- if (cnt == 100) {
- DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
- bnx2x_save_spirom_version(bp, port, 0,
+ bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
phy->ver_addr);
- return;
}
- /* lower 16 bits of the register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
- /* upper 16 bits of register SPI_FW_STATUS */
- bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
-
- bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
- phy->ver_addr);
}
-
static void bnx2x_848xx_set_led(struct bnx2x *bp,
struct bnx2x_phy *phy)
{
@@ -9392,10 +9408,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
u16 tmp_req_line_speed;
tmp_req_line_speed = phy->req_line_speed;
- if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
if (phy->req_line_speed == SPEED_10000)
phy->req_line_speed = SPEED_AUTO_NEG;
-
+ } else {
+ /* Save spirom version */
+ bnx2x_save_848xx_spirom_version(phy, bp, params->port);
+ }
/*
* This phy uses the NIG latch mechanism since link indication
* arrives through its LED4 and not via its LASI signal, so we
@@ -9443,13 +9462,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
an_1000_val);
/* set 100 speed advertisement */
- if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
+ if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
(phy->speed_cap_mask &
(PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) &&
- (phy->supported &
- (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full)))) {
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))) {
an_10_100_val |= (1<<7);
/* Enable autoneg and restart autoneg for legacy speeds */
autoneg_val |= (1<<9 | 1<<12);
@@ -9539,9 +9555,6 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
1);
- /* Save spirom version */
- bnx2x_save_848xx_spirom_version(phy, params);
-
phy->req_line_speed = tmp_req_line_speed;
return 0;
@@ -9749,17 +9762,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
/* Wait for GPHY to come out of reset */
msleep(50);
- if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
- /* Bring PHY out of super isolate mode */
- bnx2x_cl45_read(bp, phy,
- MDIO_CTL_DEVAD,
- MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
- val &= ~MDIO_84833_SUPER_ISOLATE;
- bnx2x_cl45_write(bp, phy,
- MDIO_CTL_DEVAD,
- MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
- bnx2x_84833_pair_swap_cfg(phy, params, vars);
- } else {
+ if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
/*
* BCM84823 requires that XGXS links up first @ 10G for normal
* behavior.
@@ -9816,24 +9819,23 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
params->multi_phy_config, val);
- /* AutogrEEEn */
- if (params->feature_config_flags &
- FEATURE_CONFIG_AUTOGREEEN_ENABLED)
- cmd_args[0] = 0x2;
- else
- cmd_args[0] = 0x0;
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
+ bnx2x_84833_pair_swap_cfg(phy, params, vars);
- cmd_args[1] = 0x0;
- cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
- cmd_args[3] = PHY84833_CONSTANT_LATENCY;
- rc = bnx2x_84833_cmd_hdlr(phy, params,
- PHY84833_CMD_SET_EEE_MODE, cmd_args);
- if (rc != 0)
- DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
+ /* Keep AutogrEEEn disabled. */
+ cmd_args[0] = 0x0;
+ cmd_args[1] = 0x0;
+ cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
+ cmd_args[3] = PHY84833_CONSTANT_LATENCY;
+ rc = bnx2x_84833_cmd_hdlr(phy, params,
+ PHY84833_CMD_SET_EEE_MODE, cmd_args);
+ if (rc != 0)
+ DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
+ }
if (initialize)
rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
else
- bnx2x_save_848xx_spirom_version(phy, params);
+ bnx2x_save_848xx_spirom_version(phy, bp, params->port);
/* 84833 PHY has a better feature and doesn't need to support this. */
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
cms_enable = REG_RD(bp, params->shmem_base +
@@ -9851,6 +9853,16 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
MDIO_CTL_REG_84823_USER_CTRL_REG, val);
}
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
+ /* Bring PHY out of super isolate mode as the final step. */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_CTL_DEVAD,
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
+ val &= ~MDIO_84833_SUPER_ISOLATE;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_CTL_DEVAD,
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
+ }
return rc;
}
@@ -9988,10 +10000,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
} else {
bnx2x_cl45_read(bp, phy,
MDIO_CTL_DEVAD,
- 0x400f, &val16);
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
+ val16 |= MDIO_84833_SUPER_ISOLATE;
bnx2x_cl45_write(bp, phy,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0x800);
+ MDIO_CTL_DEVAD,
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
}
}
@@ -11516,6 +11529,19 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
}
phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
+ if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
+ (phy->ver_addr)) {
+ /*
+ * Remove 100Mb link supported for BCM84833 when phy fw
+ * version lower than or equal to 1.39
+ */
+ u32 raw_ver = REG_RD(bp, phy->ver_addr);
+ if (((raw_ver & 0x7F) <= 39) &&
+ (((raw_ver & 0xF80) >> 7) <= 1))
+ phy->supported &= ~(SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full);
+ }
+
/*
* In case mdc/mdio_access of the external phy is different than the
* mdc/mdio access of the XGXS, a HW lock must be taken in each access
@@ -12333,55 +12359,69 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
u32 chip_id)
{
u8 reset_gpios;
- struct bnx2x_phy phy;
- u32 shmem_base, shmem2_base, cnt;
- s8 port = 0;
- u16 val;
-
reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
udelay(10);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
reset_gpios);
- for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* This PHY is for E2 and E3. */
- shmem_base = shmem_base_path[port];
- shmem2_base = shmem2_base_path[port];
- /* Extract the ext phy address for the port */
- if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
- 0, &phy) !=
- 0) {
- DP(NETIF_MSG_LINK, "populate_phy failed\n");
- return -EINVAL;
- }
+ return 0;
+}
- /* Wait for FW completing its initialization. */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, &phy,
+static int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
+ struct bnx2x_phy *phy)
+{
+ u16 val, cnt;
+ /* Wait for FW completing its initialization. */
+ for (cnt = 0; cnt < 1500; cnt++) {
+ bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, &val);
- if (!(val & (1<<15)))
- break;
- msleep(1);
- }
- if (cnt >= 1000)
- DP(NETIF_MSG_LINK,
- "84833 Cmn reset timeout (%d)\n", port);
-
- /* Put the port in super isolate mode. */
- bnx2x_cl45_read(bp, &phy,
- MDIO_CTL_DEVAD,
- MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
- val |= MDIO_84833_SUPER_ISOLATE;
- bnx2x_cl45_write(bp, &phy,
- MDIO_CTL_DEVAD,
- MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
+ if (!(val & (1<<15)))
+ break;
+ msleep(1);
+ }
+ if (cnt >= 1500) {
+ DP(NETIF_MSG_LINK, "84833 reset timeout\n");
+ return -EINVAL;
}
+ /* Put the port in super isolate mode. */
+ bnx2x_cl45_read(bp, phy,
+ MDIO_CTL_DEVAD,
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
+ val |= MDIO_84833_SUPER_ISOLATE;
+ bnx2x_cl45_write(bp, phy,
+ MDIO_CTL_DEVAD,
+ MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
+
+ /* Save spirom version */
+ bnx2x_save_848xx_spirom_version(phy, bp, PORT_0);
return 0;
}
+int bnx2x_pre_init_phy(struct bnx2x *bp,
+ u32 shmem_base,
+ u32 shmem2_base,
+ u32 chip_id)
+{
+ int rc = 0;
+ struct bnx2x_phy phy;
+ bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
+ if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
+ PORT_0, &phy)) {
+ DP(NETIF_MSG_LINK, "populate_phy failed\n");
+ return -EINVAL;
+ }
+ switch (phy.type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
+ rc = bnx2x_84833_pre_init_phy(bp, &phy);
+ break;
+ default:
+ break;
+ }
+ return rc;
+}
static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
u32 shmem2_base_path[], u8 phy_index,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index ffeaaa95ed96..1e3f978ee6da 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -941,7 +941,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- i, j, rx_bd[1], rx_bd[0], sw_bd->skb);
+ i, j, rx_bd[1], rx_bd[0], sw_bd->data);
}
start = RX_SGE(fp->rx_sge_prod);
@@ -10536,6 +10536,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
{
struct bnx2x *bp;
int rc;
+ bool chip_is_e1x = (board_type == BCM57710 ||
+ board_type == BCM57711 ||
+ board_type == BCM57711E);
SET_NETDEV_DEV(dev, &pdev->dev);
bp = netdev_priv(dev);
@@ -10624,7 +10627,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0);
- if (CHIP_IS_E1x(bp)) {
+ if (chip_is_e1x) {
REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0);
REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0);
@@ -10635,9 +10638,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
* Enable internal target-read (in case we are probed after PF FLR).
* Must be done prior to any BAR read access. Only for 57712 and up
*/
- if (board_type != BCM57710 &&
- board_type != BCM57711 &&
- board_type != BCM57711E)
+ if (!chip_is_e1x)
REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
/* Reset the load counter */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 44609de4e5dc..dddbcf6e154e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -2176,6 +2176,7 @@
* set to 0x345678021. This is a new register (with 2_) added in E3 B0 to
* accommodate the 9 input clients to ETS arbiter. */
#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB 0x18684
+#define NIG_REG_P1_HWPFC_ENABLE 0x181d0
#define NIG_REG_P1_MAC_IN_EN 0x185c0
/* [RW 1] Output enable for TX MAC interface */
#define NIG_REG_P1_MAC_OUT_EN 0x185c4
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 5ac616093f9f..cb6339c35571 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -50,6 +50,7 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp,
int exe_len,
union bnx2x_qable_obj *owner,
exe_q_validate validate,
+ exe_q_remove remove,
exe_q_optimize optimize,
exe_q_execute exec,
exe_q_get get)
@@ -66,6 +67,7 @@ static inline void bnx2x_exe_queue_init(struct bnx2x *bp,
/* Owner specific callbacks */
o->validate = validate;
+ o->remove = remove;
o->optimize = optimize;
o->execute = exec;
o->get = get;
@@ -1340,6 +1342,35 @@ static int bnx2x_validate_vlan_mac(struct bnx2x *bp,
}
}
+static int bnx2x_remove_vlan_mac(struct bnx2x *bp,
+ union bnx2x_qable_obj *qo,
+ struct bnx2x_exeq_elem *elem)
+{
+ int rc = 0;
+
+ /* If consumption wasn't required, nothing to do */
+ if (test_bit(BNX2X_DONT_CONSUME_CAM_CREDIT,
+ &elem->cmd_data.vlan_mac.vlan_mac_flags))
+ return 0;
+
+ switch (elem->cmd_data.vlan_mac.cmd) {
+ case BNX2X_VLAN_MAC_ADD:
+ case BNX2X_VLAN_MAC_MOVE:
+ rc = qo->vlan_mac.put_credit(&qo->vlan_mac);
+ break;
+ case BNX2X_VLAN_MAC_DEL:
+ rc = qo->vlan_mac.get_credit(&qo->vlan_mac);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (rc != true)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes.
*
@@ -1801,8 +1832,14 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) {
if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags ==
- *vlan_mac_flags)
+ *vlan_mac_flags) {
+ rc = exeq->remove(bp, exeq->owner, exeq_pos);
+ if (rc) {
+ BNX2X_ERR("Failed to remove command\n");
+ return rc;
+ }
list_del(&exeq_pos->link);
+ }
}
spin_unlock_bh(&exeq->lock);
@@ -1908,6 +1945,7 @@ void bnx2x_init_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&mac_obj->exe_queue, 1, qable_obj,
bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_mac);
@@ -1924,6 +1962,7 @@ void bnx2x_init_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&mac_obj->exe_queue, CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_mac);
@@ -1963,6 +2002,7 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&vlan_obj->exe_queue, CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan);
@@ -2009,6 +2049,7 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp,
bnx2x_exe_queue_init(bp,
&vlan_mac_obj->exe_queue, 1, qable_obj,
bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan_mac);
@@ -2025,6 +2066,7 @@ void bnx2x_init_vlan_mac_obj(struct bnx2x *bp,
&vlan_mac_obj->exe_queue,
CLASSIFY_RULES_COUNT,
qable_obj, bnx2x_validate_vlan_mac,
+ bnx2x_remove_vlan_mac,
bnx2x_optimize_vlan_mac,
bnx2x_execute_vlan_mac,
bnx2x_exeq_get_vlan_mac);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 992308ff82e8..66da39f0c84a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -161,6 +161,10 @@ typedef int (*exe_q_validate)(struct bnx2x *bp,
union bnx2x_qable_obj *o,
struct bnx2x_exeq_elem *elem);
+typedef int (*exe_q_remove)(struct bnx2x *bp,
+ union bnx2x_qable_obj *o,
+ struct bnx2x_exeq_elem *elem);
+
/**
* @return positive is entry was optimized, 0 - if not, negative
* in case of an error.
@@ -203,11 +207,18 @@ struct bnx2x_exe_queue_obj {
*/
exe_q_validate validate;
+ /**
+ * Called before removing pending commands, cleaning allocated
+ * resources (e.g., credits from validate)
+ */
+ exe_q_remove remove;
/**
* This will try to cancel the current pending commands list
* considering the new command.
*
+ * Returns the number of optimized commands or a negative error code
+ *
* Must run under exe_queue->lock
*/
exe_q_optimize optimize;
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index 8fa7abc53ec6..084904ceaa30 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2259,7 +2259,8 @@ static int sbmac_init(struct platform_device *pldev, long long base)
}
sc->mii_bus->name = sbmac_mdio_string;
- snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+ snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ pldev->name, idx);
sc->mii_bus->priv = sc;
sc->mii_bus->read = sbmac_mii_read;
sc->mii_bus->write = sbmac_mii_write;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 076e02a415a0..a1f2e0fed78b 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6667,14 +6667,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
- if (skb_is_gso_v6(skb)) {
- hdr_len = skb_headlen(skb) - ETH_HLEN;
- } else {
- u32 ip_tcp_len;
-
- ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
- hdr_len = ip_tcp_len + tcp_opt_len;
+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
+ if (!skb_is_gso_v6(skb)) {
iph->check = 0;
iph->tot_len = htons(mss + hdr_len);
}
@@ -8846,9 +8841,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
udelay(100);
- if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1) {
+ if (tg3_flag(tp, USING_MSIX)) {
val = tr32(MSGINT_MODE);
- val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
+ val |= MSGINT_MODE_ENABLE;
+ if (tp->irq_cnt > 1)
+ val |= MSGINT_MODE_MULTIVEC_EN;
if (!tg3_flag(tp, 1SHOT_MSI))
val |= MSGINT_MODE_ONE_SHOT_DISABLE;
tw32(MSGINT_MODE, val);
@@ -9548,19 +9545,18 @@ static int tg3_request_firmware(struct tg3 *tp)
static bool tg3_enable_msix(struct tg3 *tp)
{
- int i, rc, cpus = num_online_cpus();
+ int i, rc;
struct msix_entry msix_ent[tp->irq_max];
- if (cpus == 1)
- /* Just fallback to the simpler MSI mode. */
- return false;
-
- /*
- * We want as many rx rings enabled as there are cpus.
- * The first MSIX vector only deals with link interrupts, etc,
- * so we add one to the number of vectors we are requesting.
- */
- tp->irq_cnt = min_t(unsigned, cpus + 1, tp->irq_max);
+ tp->irq_cnt = num_online_cpus();
+ if (tp->irq_cnt > 1) {
+ /* We want as many rx rings enabled as there are cpus.
+ * In multiqueue MSI-X mode, the first MSI-X vector
+ * only deals with link interrupts, etc, so we add
+ * one to the number of vectors we are requesting.
+ */
+ tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max);
+ }
for (i = 0; i < tp->irq_max; i++) {
msix_ent[i].entry = i;