aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2010-10-05 23:28:26 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-06 17:10:37 -0400
commitf2e0899f0f275cc3f5e9c9726178d7d0ac19b2db (patch)
tree436144046a751427bdd2e3fd284688582d2efe61 /drivers/net/bnx2x/bnx2x_link.c
parent8fe23fbd94af5a4c117fd0eb2f1c3f492f79efe8 (diff)
bnx2x: Add 57712 support
57712 HW supported with same set of features as for 57710/57711 Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c379
1 files changed, 305 insertions, 74 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 51d468d430e..3e99bf9c42b 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -377,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params,
377 return 0; 377 return 0;
378} 378}
379 379
380static void bnx2x_update_bmac2(struct link_params *params,
381 struct link_vars *vars,
382 u8 is_lb)
383{
384 /*
385 * Set rx control: Strip CRC and enable BigMAC to relay
386 * control packets to the system as well
387 */
388 u32 wb_data[2];
389 struct bnx2x *bp = params->bp;
390 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
391 NIG_REG_INGRESS_BMAC0_MEM;
392 u32 val = 0x14;
380 393
394 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
395 /* Enable BigMAC to react on received Pause packets */
396 val |= (1<<5);
397 wb_data[0] = val;
398 wb_data[1] = 0;
399 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
400 wb_data, 2);
401 udelay(30);
381 402
382static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, 403 /* Tx control */
404 val = 0xc0;
405 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
406 val |= 0x800000;
407 wb_data[0] = val;
408 wb_data[1] = 0;
409 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL,
410 wb_data, 2);
411
412 val = 0x8000;
413 wb_data[0] = val;
414 wb_data[1] = 0;
415 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
416 wb_data, 2);
417
418 /* mac control */
419 val = 0x3; /* Enable RX and TX */
420 if (is_lb) {
421 val |= 0x4; /* Local loopback */
422 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
423 }
424
425 wb_data[0] = val;
426 wb_data[1] = 0;
427 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
428 wb_data, 2);
429}
430
431
432static u8 bnx2x_bmac1_enable(struct link_params *params,
433 struct link_vars *vars,
383 u8 is_lb) 434 u8 is_lb)
384{ 435{
385 struct bnx2x *bp = params->bp; 436 struct bnx2x *bp = params->bp;
@@ -389,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
389 u32 wb_data[2]; 440 u32 wb_data[2];
390 u32 val; 441 u32 val;
391 442
392 DP(NETIF_MSG_LINK, "Enabling BigMAC\n"); 443 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
393 /* reset and unreset the BigMac */
394 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
395 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
396 msleep(1);
397
398 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
399 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
400
401 /* enable access for bmac registers */
402 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
403 444
404 /* XGXS control */ 445 /* XGXS control */
405 wb_data[0] = 0x3c; 446 wb_data[0] = 0x3c;
@@ -479,6 +520,103 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
479 wb_data, 2); 520 wb_data, 2);
480 } 521 }
481 522
523
524 return 0;
525}
526
527static u8 bnx2x_bmac2_enable(struct link_params *params,
528 struct link_vars *vars,
529 u8 is_lb)
530{
531 struct bnx2x *bp = params->bp;
532 u8 port = params->port;
533 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
534 NIG_REG_INGRESS_BMAC0_MEM;
535 u32 wb_data[2];
536
537 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
538
539 wb_data[0] = 0;
540 wb_data[1] = 0;
541 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
542 wb_data, 2);
543 udelay(30);
544
545 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
546 wb_data[0] = 0x3c;
547 wb_data[1] = 0;
548 REG_WR_DMAE(bp, bmac_addr +
549 BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
550 wb_data, 2);
551
552 udelay(30);
553
554 /* tx MAC SA */
555 wb_data[0] = ((params->mac_addr[2] << 24) |
556 (params->mac_addr[3] << 16) |
557 (params->mac_addr[4] << 8) |
558 params->mac_addr[5]);
559 wb_data[1] = ((params->mac_addr[0] << 8) |
560 params->mac_addr[1]);
561 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
562 wb_data, 2);
563
564 udelay(30);
565
566 /* Configure SAFC */
567 wb_data[0] = 0x1000200;
568 wb_data[1] = 0;
569 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
570 wb_data, 2);
571 udelay(30);
572
573 /* set rx mtu */
574 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
575 wb_data[1] = 0;
576 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
577 wb_data, 2);
578 udelay(30);
579
580 /* set tx mtu */
581 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
582 wb_data[1] = 0;
583 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
584 wb_data, 2);
585 udelay(30);
586 /* set cnt max size */
587 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
588 wb_data[1] = 0;
589 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
590 wb_data, 2);
591 udelay(30);
592 bnx2x_update_bmac2(params, vars, is_lb);
593
594 return 0;
595}
596
597u8 bnx2x_bmac_enable(struct link_params *params,
598 struct link_vars *vars,
599 u8 is_lb)
600{
601 u8 rc, port = params->port;
602 struct bnx2x *bp = params->bp;
603 u32 val;
604 /* reset and unreset the BigMac */
605 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
606 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
607 udelay(10);
608
609 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
610 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
611
612 /* enable access for bmac registers */
613 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
614
615 /* Enable BMAC according to BMAC type*/
616 if (CHIP_IS_E2(bp))
617 rc = bnx2x_bmac2_enable(params, vars, is_lb);
618 else
619 rc = bnx2x_bmac1_enable(params, vars, is_lb);
482 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); 620 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
483 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); 621 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
484 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); 622 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
@@ -493,7 +631,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
493 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); 631 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
494 632
495 vars->mac_type = MAC_TYPE_BMAC; 633 vars->mac_type = MAC_TYPE_BMAC;
496 return 0; 634 return rc;
497} 635}
498 636
499 637
@@ -519,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
519 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && 657 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
520 nig_bmac_enable) { 658 nig_bmac_enable) {
521 659
522 /* Clear Rx Enable bit in BMAC_CONTROL register */ 660 if (CHIP_IS_E2(bp)) {
523 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, 661 /* Clear Rx Enable bit in BMAC_CONTROL register */
524 wb_data, 2); 662 REG_RD_DMAE(bp, bmac_addr +
525 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; 663 BIGMAC2_REGISTER_BMAC_CONTROL,
526 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, 664 wb_data, 2);
527 wb_data, 2); 665 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
528 666 REG_WR_DMAE(bp, bmac_addr +
667 BIGMAC2_REGISTER_BMAC_CONTROL,
668 wb_data, 2);
669 } else {
670 /* Clear Rx Enable bit in BMAC_CONTROL register */
671 REG_RD_DMAE(bp, bmac_addr +
672 BIGMAC_REGISTER_BMAC_CONTROL,
673 wb_data, 2);
674 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
675 REG_WR_DMAE(bp, bmac_addr +
676 BIGMAC_REGISTER_BMAC_CONTROL,
677 wb_data, 2);
678 }
529 msleep(1); 679 msleep(1);
530 } 680 }
531} 681}
@@ -821,23 +971,31 @@ u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
821 return -EINVAL; 971 return -EINVAL;
822} 972}
823 973
824static void bnx2x_set_aer_mmd(struct link_params *params, 974static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
825 struct bnx2x_phy *phy) 975 struct bnx2x_phy *phy)
826{ 976{
827 struct bnx2x *bp = params->bp;
828 u32 ser_lane; 977 u32 ser_lane;
829 u16 offset; 978 u16 offset, aer_val;
830 979 struct bnx2x *bp = params->bp;
831 ser_lane = ((params->lane_config & 980 ser_lane = ((params->lane_config &
832 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 981 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
833 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 982 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
834 983
835 offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? 984 offset = phy->addr + ser_lane;
836 (phy->addr + ser_lane) : 0; 985 if (CHIP_IS_E2(bp))
837 986 aer_val = 0x2800 + offset - 1;
987 else
988 aer_val = 0x3800 + offset;
838 CL45_WR_OVER_CL22(bp, phy, 989 CL45_WR_OVER_CL22(bp, phy,
839 MDIO_REG_BANK_AER_BLOCK, 990 MDIO_REG_BANK_AER_BLOCK,
840 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); 991 MDIO_AER_BLOCK_AER_REG, aer_val);
992}
993static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
994 struct bnx2x_phy *phy)
995{
996 CL45_WR_OVER_CL22(bp, phy,
997 MDIO_REG_BANK_AER_BLOCK,
998 MDIO_AER_BLOCK_AER_REG, 0x3800);
841} 999}
842 1000
843/******************************************************************/ 1001/******************************************************************/
@@ -2046,12 +2204,12 @@ static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2046 u8 rc; 2204 u8 rc;
2047 vars->phy_flags |= PHY_SGMII_FLAG; 2205 vars->phy_flags |= PHY_SGMII_FLAG;
2048 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 2206 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2049 bnx2x_set_aer_mmd(params, phy); 2207 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2050 rc = bnx2x_reset_unicore(params, phy, 1); 2208 rc = bnx2x_reset_unicore(params, phy, 1);
2051 /* reset the SerDes and wait for reset bit return low */ 2209 /* reset the SerDes and wait for reset bit return low */
2052 if (rc != 0) 2210 if (rc != 0)
2053 return rc; 2211 return rc;
2054 bnx2x_set_aer_mmd(params, phy); 2212 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2055 2213
2056 return rc; 2214 return rc;
2057} 2215}
@@ -2076,7 +2234,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2076 vars->phy_flags &= ~PHY_SGMII_FLAG; 2234 vars->phy_flags &= ~PHY_SGMII_FLAG;
2077 2235
2078 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); 2236 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2079 bnx2x_set_aer_mmd(params, phy); 2237 bnx2x_set_aer_mmd_xgxs(params, phy);
2080 bnx2x_set_master_ln(params, phy); 2238 bnx2x_set_master_ln(params, phy);
2081 2239
2082 rc = bnx2x_reset_unicore(params, phy, 0); 2240 rc = bnx2x_reset_unicore(params, phy, 0);
@@ -2084,7 +2242,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2084 if (rc != 0) 2242 if (rc != 0)
2085 return rc; 2243 return rc;
2086 2244
2087 bnx2x_set_aer_mmd(params, phy); 2245 bnx2x_set_aer_mmd_xgxs(params, phy);
2088 2246
2089 /* setting the masterLn_def again after the reset */ 2247 /* setting the masterLn_def again after the reset */
2090 bnx2x_set_master_ln(params, phy); 2248 bnx2x_set_master_ln(params, phy);
@@ -2358,7 +2516,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
2358 0x6041); 2516 0x6041);
2359 msleep(200); 2517 msleep(200);
2360 /* set aer mmd back */ 2518 /* set aer mmd back */
2361 bnx2x_set_aer_mmd(params, phy); 2519 bnx2x_set_aer_mmd_xgxs(params, phy);
2362 2520
2363 /* and md_devad */ 2521 /* and md_devad */
2364 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 2522 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
@@ -2721,7 +2879,10 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
2721 struct bnx2x *bp = params->bp; 2879 struct bnx2x *bp = params->bp;
2722 u8 gpio_port; 2880 u8 gpio_port;
2723 /* HW reset */ 2881 /* HW reset */
2724 gpio_port = params->port; 2882 if (CHIP_IS_E2(bp))
2883 gpio_port = BP_PATH(bp);
2884 else
2885 gpio_port = params->port;
2725 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2886 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2726 MISC_REGISTERS_GPIO_OUTPUT_LOW, 2887 MISC_REGISTERS_GPIO_OUTPUT_LOW,
2727 gpio_port); 2888 gpio_port);
@@ -2799,8 +2960,9 @@ static u8 bnx2x_update_link_up(struct link_params *params,
2799 } 2960 }
2800 2961
2801 /* PBF - link up */ 2962 /* PBF - link up */
2802 rc |= bnx2x_pbf_update(params, vars->flow_ctrl, 2963 if (!(CHIP_IS_E2(bp)))
2803 vars->line_speed); 2964 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
2965 vars->line_speed);
2804 2966
2805 /* disable drain */ 2967 /* disable drain */
2806 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); 2968 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
@@ -3443,7 +3605,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
3443 u8 gpio_port; 3605 u8 gpio_port;
3444 DP(NETIF_MSG_LINK, "Init 8073\n"); 3606 DP(NETIF_MSG_LINK, "Init 8073\n");
3445 3607
3446 gpio_port = params->port; 3608 if (CHIP_IS_E2(bp))
3609 gpio_port = BP_PATH(bp);
3610 else
3611 gpio_port = params->port;
3447 /* Restore normal power mode*/ 3612 /* Restore normal power mode*/
3448 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 3613 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3449 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); 3614 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
@@ -3680,7 +3845,10 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
3680{ 3845{
3681 struct bnx2x *bp = params->bp; 3846 struct bnx2x *bp = params->bp;
3682 u8 gpio_port; 3847 u8 gpio_port;
3683 gpio_port = params->port; 3848 if (CHIP_IS_E2(bp))
3849 gpio_port = BP_PATH(bp);
3850 else
3851 gpio_port = params->port;
3684 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", 3852 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
3685 gpio_port); 3853 gpio_port);
3686 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 3854 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
@@ -6371,7 +6539,10 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
6371 phy->mdio_ctrl = bnx2x_get_emac_base(bp, 6539 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
6372 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, 6540 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
6373 port); 6541 port);
6374 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; 6542 if (CHIP_IS_E2(bp))
6543 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
6544 else
6545 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
6375 6546
6376 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", 6547 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
6377 port, phy->addr, phy->mdio_ctrl); 6548 port, phy->addr, phy->mdio_ctrl);
@@ -6742,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6742 } 6913 }
6743 6914
6744 bnx2x_emac_enable(params, vars, 0); 6915 bnx2x_emac_enable(params, vars, 0);
6745 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); 6916 if (!(CHIP_IS_E2(bp)))
6917 bnx2x_pbf_update(params, vars->flow_ctrl,
6918 vars->line_speed);
6746 /* disable drain */ 6919 /* disable drain */
6747 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 6920 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6748 6921
@@ -6932,18 +7105,34 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6932/****************************************************************************/ 7105/****************************************************************************/
6933/* Common function */ 7106/* Common function */
6934/****************************************************************************/ 7107/****************************************************************************/
6935static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) 7108static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7109 u32 shmem_base_path[],
7110 u32 shmem2_base_path[], u8 phy_index,
7111 u32 chip_id)
6936{ 7112{
6937 struct bnx2x_phy phy[PORT_MAX]; 7113 struct bnx2x_phy phy[PORT_MAX];
6938 struct bnx2x_phy *phy_blk[PORT_MAX]; 7114 struct bnx2x_phy *phy_blk[PORT_MAX];
6939 u16 val; 7115 u16 val;
6940 s8 port; 7116 s8 port;
7117 s8 port_of_path = 0;
6941 7118
6942 /* PART1 - Reset both phys */ 7119 /* PART1 - Reset both phys */
6943 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7120 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7121 u32 shmem_base, shmem2_base;
7122 /* In E2, same phy is using for port0 of the two paths */
7123 if (CHIP_IS_E2(bp)) {
7124 shmem_base = shmem_base_path[port];
7125 shmem2_base = shmem2_base_path[port];
7126 port_of_path = 0;
7127 } else {
7128 shmem_base = shmem_base_path[0];
7129 shmem2_base = shmem2_base_path[0];
7130 port_of_path = port;
7131 }
7132
6944 /* Extract the ext phy address for the port */ 7133 /* Extract the ext phy address for the port */
6945 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 7134 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
6946 port, &phy[port]) != 7135 port_of_path, &phy[port]) !=
6947 0) { 7136 0) {
6948 DP(NETIF_MSG_LINK, "populate_phy failed\n"); 7137 DP(NETIF_MSG_LINK, "populate_phy failed\n");
6949 return -EINVAL; 7138 return -EINVAL;
@@ -6981,9 +7170,15 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem
6981 /* PART2 - Download firmware to both phys */ 7170 /* PART2 - Download firmware to both phys */
6982 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7171 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6983 u16 fw_ver1; 7172 u16 fw_ver1;
7173 if (CHIP_IS_E2(bp))
7174 port_of_path = 0;
7175 else
7176 port_of_path = port;
6984 7177
7178 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7179 phy_blk[port]->addr);
6985 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], 7180 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
6986 port); 7181 port_of_path);
6987 7182
6988 bnx2x_cl45_read(bp, phy_blk[port], 7183 bnx2x_cl45_read(bp, phy_blk[port],
6989 MDIO_PMA_DEVAD, 7184 MDIO_PMA_DEVAD,
@@ -7039,9 +7234,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem
7039 } 7234 }
7040 return 0; 7235 return 0;
7041} 7236}
7042 7237static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7043static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base, 7238 u32 shmem_base_path[],
7044 u32 shmem2_base, u8 phy_index) 7239 u32 shmem2_base_path[], u8 phy_index,
7240 u32 chip_id)
7045{ 7241{
7046 u32 val; 7242 u32 val;
7047 s8 port; 7243 s8 port;
@@ -7056,6 +7252,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7056 bnx2x_ext_phy_hw_reset(bp, 1); 7252 bnx2x_ext_phy_hw_reset(bp, 1);
7057 msleep(5); 7253 msleep(5);
7058 for (port = 0; port < PORT_MAX; port++) { 7254 for (port = 0; port < PORT_MAX; port++) {
7255 u32 shmem_base, shmem2_base;
7256
7257 /* In E2, same phy is using for port0 of the two paths */
7258 if (CHIP_IS_E2(bp)) {
7259 shmem_base = shmem_base_path[port];
7260 shmem2_base = shmem2_base_path[port];
7261 } else {
7262 shmem_base = shmem_base_path[0];
7263 shmem2_base = shmem2_base_path[0];
7264 }
7059 /* Extract the ext phy address for the port */ 7265 /* Extract the ext phy address for the port */
7060 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 7266 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7061 port, &phy) != 7267 port, &phy) !=
@@ -7077,14 +7283,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7077 7283
7078 return 0; 7284 return 0;
7079} 7285}
7080static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, 7286static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7081 u32 shmem2_base, u8 phy_index) 7287 u32 shmem_base_path[],
7288 u32 shmem2_base_path[], u8 phy_index,
7289 u32 chip_id)
7082{ 7290{
7083 s8 port; 7291 s8 port;
7084 u32 swap_val, swap_override; 7292 u32 swap_val, swap_override;
7085 struct bnx2x_phy phy[PORT_MAX]; 7293 struct bnx2x_phy phy[PORT_MAX];
7086 struct bnx2x_phy *phy_blk[PORT_MAX]; 7294 struct bnx2x_phy *phy_blk[PORT_MAX];
7087 DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); 7295 s8 port_of_path;
7088 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 7296 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7089 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 7297 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7090 7298
@@ -7099,19 +7307,33 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7099 7307
7100 /* PART1 - Reset both phys */ 7308 /* PART1 - Reset both phys */
7101 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7309 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7310 u32 shmem_base, shmem2_base;
7311
7312 /* In E2, same phy is using for port0 of the two paths */
7313 if (CHIP_IS_E2(bp)) {
7314 shmem_base = shmem_base_path[port];
7315 shmem2_base = shmem2_base_path[port];
7316 port_of_path = 0;
7317 } else {
7318 shmem_base = shmem_base_path[0];
7319 shmem2_base = shmem2_base_path[0];
7320 port_of_path = port;
7321 }
7322
7102 /* Extract the ext phy address for the port */ 7323 /* Extract the ext phy address for the port */
7103 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, 7324 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7104 port, &phy[port]) != 7325 port_of_path, &phy[port]) !=
7105 0) { 7326 0) {
7106 DP(NETIF_MSG_LINK, "populate phy failed\n"); 7327 DP(NETIF_MSG_LINK, "populate phy failed\n");
7107 return -EINVAL; 7328 return -EINVAL;
7108 } 7329 }
7109 /* disable attentions */ 7330 /* disable attentions */
7110 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 7331 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7111 (NIG_MASK_XGXS0_LINK_STATUS | 7332 port_of_path*4,
7112 NIG_MASK_XGXS0_LINK10G | 7333 (NIG_MASK_XGXS0_LINK_STATUS |
7113 NIG_MASK_SERDES0_LINK_STATUS | 7334 NIG_MASK_XGXS0_LINK10G |
7114 NIG_MASK_MI_INT)); 7335 NIG_MASK_SERDES0_LINK_STATUS |
7336 NIG_MASK_MI_INT));
7115 7337
7116 7338
7117 /* Reset the phy */ 7339 /* Reset the phy */
@@ -7133,9 +7355,14 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7133 /* PART2 - Download firmware to both phys */ 7355 /* PART2 - Download firmware to both phys */
7134 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7356 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7135 u16 fw_ver1; 7357 u16 fw_ver1;
7136 7358 if (CHIP_IS_E2(bp))
7359 port_of_path = 0;
7360 else
7361 port_of_path = port;
7362 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7363 phy_blk[port]->addr);
7137 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], 7364 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7138 port); 7365 port_of_path);
7139 bnx2x_cl45_read(bp, phy_blk[port], 7366 bnx2x_cl45_read(bp, phy_blk[port],
7140 MDIO_PMA_DEVAD, 7367 MDIO_PMA_DEVAD,
7141 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 7368 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
@@ -7151,29 +7378,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7151 return 0; 7378 return 0;
7152} 7379}
7153 7380
7154static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, 7381static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7155 u32 shmem2_base, u8 phy_index, 7382 u32 shmem2_base_path[], u8 phy_index,
7156 u32 ext_phy_type) 7383 u32 ext_phy_type, u32 chip_id)
7157{ 7384{
7158 u8 rc = 0; 7385 u8 rc = 0;
7159 7386
7160 switch (ext_phy_type) { 7387 switch (ext_phy_type) {
7161 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 7388 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7162 rc = bnx2x_8073_common_init_phy(bp, shmem_base, 7389 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
7163 shmem2_base, phy_index); 7390 shmem2_base_path,
7391 phy_index, chip_id);
7164 break; 7392 break;
7165 7393
7166 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 7394 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7167 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: 7395 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7168 rc = bnx2x_8727_common_init_phy(bp, shmem_base, 7396 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7169 shmem2_base, phy_index); 7397 shmem2_base_path,
7398 phy_index, chip_id);
7170 break; 7399 break;
7171 7400
7172 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 7401 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7173 /* GPIO1 affects both ports, so there's need to pull 7402 /* GPIO1 affects both ports, so there's need to pull
7174 it for single port alone */ 7403 it for single port alone */
7175 rc = bnx2x_8726_common_init_phy(bp, shmem_base, 7404 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7176 shmem2_base, phy_index); 7405 shmem2_base_path,
7406 phy_index, chip_id);
7177 break; 7407 break;
7178 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 7408 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7179 rc = -EINVAL; 7409 rc = -EINVAL;
@@ -7188,8 +7418,8 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base,
7188 return rc; 7418 return rc;
7189} 7419}
7190 7420
7191u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, 7421u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7192 u32 shmem2_base) 7422 u32 shmem2_base_path[], u32 chip_id)
7193{ 7423{
7194 u8 rc = 0; 7424 u8 rc = 0;
7195 u8 phy_index; 7425 u8 phy_index;
@@ -7203,12 +7433,13 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base,
7203 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; 7433 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7204 phy_index++) { 7434 phy_index++) {
7205 ext_phy_config = bnx2x_get_ext_phy_config(bp, 7435 ext_phy_config = bnx2x_get_ext_phy_config(bp,
7206 shmem_base, 7436 shmem_base_path[0],
7207 phy_index, 0); 7437 phy_index, 0);
7208 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); 7438 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7209 rc |= bnx2x_ext_phy_common_init(bp, shmem_base, 7439 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
7210 shmem2_base, 7440 shmem2_base_path,
7211 phy_index, ext_phy_type); 7441 phy_index, ext_phy_type,
7442 chip_id);
7212 } 7443 }
7213 return rc; 7444 return rc;
7214} 7445}