diff options
author | Dmitry Kravkov <dmitry@broadcom.com> | 2010-10-05 23:28:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-06 17:10:37 -0400 |
commit | f2e0899f0f275cc3f5e9c9726178d7d0ac19b2db (patch) | |
tree | 436144046a751427bdd2e3fd284688582d2efe61 /drivers/net/bnx2x/bnx2x_link.c | |
parent | 8fe23fbd94af5a4c117fd0eb2f1c3f492f79efe8 (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.c | 379 |
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 | ||
380 | static 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 | ||
382 | static 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 | |||
432 | static 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 | |||
527 | static 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 | |||
597 | u8 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 | ||
824 | static void bnx2x_set_aer_mmd(struct link_params *params, | 974 | static 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 | } | ||
993 | static 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 | /****************************************************************************/ |
6935 | static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index) | 7108 | static 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 | 7237 | static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, | |
7043 | static 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 | } |
7080 | static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base, | 7286 | static 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 | ||
7154 | static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base, | 7381 | static 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 | ||
7191 | u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base, | 7421 | u8 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 | } |