aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2011-07-07 01:50:59 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-08 11:53:33 -0400
commit4fb99cd6ac4fe6d03a334a6f4ebb2bbfc4b479ed (patch)
tree498e9caf1f989f161e1d4f30f5df7f6d97a68731 /drivers
parent8e11680f5e1abc85298c12a99e2b741249eadc0c (diff)
sky2: support for new Optima chipsets (EXPERIMENTAL)
This is a backport from the vendor driver of support for the newer Optima (Prime and 2) chipsets. It also includes some setup changes for the current Optima chip as well. The code and comments intentionally mirror the vendor sk98lin driver to allow for easier maintenance. Although this adds support for new chip id's, these chip id's are not used by any of the current PCI device id's listed in the driver. The patch is just to get initial infrastructure in place to handle them when they come. I don't have access to any of this hardware to actually test it yet. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c89
-rw-r--r--drivers/net/sky2.h8
2 files changed, 89 insertions, 8 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index b1a675a94a17..6d6a56bf0aca 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -365,6 +365,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
365 gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec); 365 gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
366 } 366 }
367 } else { 367 } else {
368 if (hw->chip_id >= CHIP_ID_YUKON_OPT) {
369 u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2);
370
371 /* enable PHY Reverse Auto-Negotiation */
372 ctrl2 |= 1u << 13;
373
374 /* Write PHY changes (SW-reset must follow) */
375 gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2);
376 }
377
378
368 /* disable energy detect */ 379 /* disable energy detect */
369 ctrl &= ~PHY_M_PC_EN_DET_MSK; 380 ctrl &= ~PHY_M_PC_EN_DET_MSK;
370 381
@@ -626,6 +637,63 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
626 if (ledover) 637 if (ledover)
627 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); 638 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
628 639
640 } else if (hw->chip_id == CHIP_ID_YUKON_PRM &&
641 (sky2_read8(hw, B2_MAC_CFG) & 0xf) == 0x7) {
642 int i;
643 /* This a phy register setup workaround copied from vendor driver. */
644 static const struct {
645 u16 reg, val;
646 } eee_afe[] = {
647 { 0x156, 0x58ce },
648 { 0x153, 0x99eb },
649 { 0x141, 0x8064 },
650 /* { 0x155, 0x130b },*/
651 { 0x000, 0x0000 },
652 { 0x151, 0x8433 },
653 { 0x14b, 0x8c44 },
654 { 0x14c, 0x0f90 },
655 { 0x14f, 0x39aa },
656 /* { 0x154, 0x2f39 },*/
657 { 0x14d, 0xba33 },
658 { 0x144, 0x0048 },
659 { 0x152, 0x2010 },
660 /* { 0x158, 0x1223 },*/
661 { 0x140, 0x4444 },
662 { 0x154, 0x2f3b },
663 { 0x158, 0xb203 },
664 { 0x157, 0x2029 },
665 };
666
667 /* Start Workaround for OptimaEEE Rev.Z0 */
668 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fb);
669
670 gm_phy_write(hw, port, 1, 0x4099);
671 gm_phy_write(hw, port, 3, 0x1120);
672 gm_phy_write(hw, port, 11, 0x113c);
673 gm_phy_write(hw, port, 14, 0x8100);
674 gm_phy_write(hw, port, 15, 0x112a);
675 gm_phy_write(hw, port, 17, 0x1008);
676
677 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fc);
678 gm_phy_write(hw, port, 1, 0x20b0);
679
680 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
681
682 for (i = 0; i < ARRAY_SIZE(eee_afe); i++) {
683 /* apply AFE settings */
684 gm_phy_write(hw, port, 17, eee_afe[i].val);
685 gm_phy_write(hw, port, 16, eee_afe[i].reg | 1u<<13);
686 }
687
688 /* End Workaround for OptimaEEE */
689 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
690
691 /* Enable 10Base-Te (EEE) */
692 if (hw->chip_id >= CHIP_ID_YUKON_PRM) {
693 reg = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
694 gm_phy_write(hw, port, PHY_MARV_EXT_CTRL,
695 reg | PHY_M_10B_TE_ENABLE);
696 }
629 } 697 }
630 698
631 /* Enable phy interrupt on auto-negotiation complete (or link up) */ 699 /* Enable phy interrupt on auto-negotiation complete (or link up) */
@@ -2959,6 +3027,8 @@ static u32 sky2_mhz(const struct sky2_hw *hw)
2959 case CHIP_ID_YUKON_SUPR: 3027 case CHIP_ID_YUKON_SUPR:
2960 case CHIP_ID_YUKON_UL_2: 3028 case CHIP_ID_YUKON_UL_2:
2961 case CHIP_ID_YUKON_OPT: 3029 case CHIP_ID_YUKON_OPT:
3030 case CHIP_ID_YUKON_PRM:
3031 case CHIP_ID_YUKON_OP_2:
2962 return 125; 3032 return 125;
2963 3033
2964 case CHIP_ID_YUKON_FE: 3034 case CHIP_ID_YUKON_FE:
@@ -3064,6 +3134,8 @@ static int __devinit sky2_init(struct sky2_hw *hw)
3064 break; 3134 break;
3065 3135
3066 case CHIP_ID_YUKON_OPT: 3136 case CHIP_ID_YUKON_OPT:
3137 case CHIP_ID_YUKON_PRM:
3138 case CHIP_ID_YUKON_OP_2:
3067 hw->flags = SKY2_HW_GIGABIT 3139 hw->flags = SKY2_HW_GIGABIT
3068 | SKY2_HW_NEW_LE 3140 | SKY2_HW_NEW_LE
3069 | SKY2_HW_ADV_POWER_CTL; 3141 | SKY2_HW_ADV_POWER_CTL;
@@ -3163,30 +3235,33 @@ static void sky2_reset(struct sky2_hw *hw)
3163 sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS); 3235 sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS);
3164 } 3236 }
3165 3237
3166 if (hw->chip_id == CHIP_ID_YUKON_OPT) { 3238 if (hw->chip_id == CHIP_ID_YUKON_OPT ||
3239 hw->chip_id == CHIP_ID_YUKON_PRM ||
3240 hw->chip_id == CHIP_ID_YUKON_OP_2) {
3167 u16 reg; 3241 u16 reg;
3168 u32 msk; 3242 u32 msk;
3169 3243
3170 if (hw->chip_rev == 0) { 3244 if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
3171 /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ 3245 /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
3172 sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7)); 3246 sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7));
3173 3247
3174 /* set PHY Link Detect Timer to 1.1 second (11x 100ms) */ 3248 /* set PHY Link Detect Timer to 1.1 second (11x 100ms) */
3175 reg = 10; 3249 reg = 10;
3250
3251 /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
3252 sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
3176 } else { 3253 } else {
3177 /* set PHY Link Detect Timer to 0.4 second (4x 100ms) */ 3254 /* set PHY Link Detect Timer to 0.4 second (4x 100ms) */
3178 reg = 3; 3255 reg = 3;
3179 } 3256 }
3180 3257
3181 reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; 3258 reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
3259 reg |= PSM_CONFIG_REG4_RST_PHY_LINK_DETECT;
3182 3260
3183 /* reset PHY Link Detect */ 3261 /* reset PHY Link Detect */
3184 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); 3262 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3185 sky2_pci_write16(hw, PSM_CONFIG_REG4,
3186 reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT);
3187 sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); 3263 sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
3188 3264
3189
3190 /* enable PHY Quick Link */ 3265 /* enable PHY Quick Link */
3191 msk = sky2_read32(hw, B0_IMSK); 3266 msk = sky2_read32(hw, B0_IMSK);
3192 msk |= Y2_IS_PHY_QLNK; 3267 msk |= Y2_IS_PHY_QLNK;
@@ -4710,9 +4785,11 @@ static const char *sky2_name(u8 chipid, char *buf, int sz)
4710 "UL 2", /* 0xba */ 4785 "UL 2", /* 0xba */
4711 "Unknown", /* 0xbb */ 4786 "Unknown", /* 0xbb */
4712 "Optima", /* 0xbc */ 4787 "Optima", /* 0xbc */
4788 "Optima Prime", /* 0xbd */
4789 "Optima 2", /* 0xbe */
4713 }; 4790 };
4714 4791
4715 if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT) 4792 if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OP_2)
4716 strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); 4793 strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
4717 else 4794 else
4718 snprintf(buf, sz, "(chip %#x)", chipid); 4795 snprintf(buf, sz, "(chip %#x)", chipid);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 530378a66021..0af31b8b5f10 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -412,7 +412,7 @@ enum {
412 Y2_IS_HW_ERR = 1<<31, /* Interrupt HW Error */ 412 Y2_IS_HW_ERR = 1<<31, /* Interrupt HW Error */
413 Y2_IS_STAT_BMU = 1<<30, /* Status BMU Interrupt */ 413 Y2_IS_STAT_BMU = 1<<30, /* Status BMU Interrupt */
414 Y2_IS_ASF = 1<<29, /* ASF subsystem Interrupt */ 414 Y2_IS_ASF = 1<<29, /* ASF subsystem Interrupt */
415 415 Y2_IS_CPU_TO = 1<<28, /* CPU Timeout */
416 Y2_IS_POLL_CHK = 1<<27, /* Check IRQ from polling unit */ 416 Y2_IS_POLL_CHK = 1<<27, /* Check IRQ from polling unit */
417 Y2_IS_TWSI_RDY = 1<<26, /* IRQ on end of TWSI Tx */ 417 Y2_IS_TWSI_RDY = 1<<26, /* IRQ on end of TWSI Tx */
418 Y2_IS_IRQ_SW = 1<<25, /* SW forced IRQ */ 418 Y2_IS_IRQ_SW = 1<<25, /* SW forced IRQ */
@@ -547,6 +547,8 @@ enum {
547 CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */ 547 CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
548 CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */ 548 CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */
549 CHIP_ID_YUKON_OPT = 0xbc, /* YUKON-2 Optima */ 549 CHIP_ID_YUKON_OPT = 0xbc, /* YUKON-2 Optima */
550 CHIP_ID_YUKON_PRM = 0xbd, /* YUKON-2 Optima Prime */
551 CHIP_ID_YUKON_OP_2 = 0xbe, /* YUKON-2 Optima 2 */
550}; 552};
551 553
552enum yukon_xl_rev { 554enum yukon_xl_rev {
@@ -1420,8 +1422,10 @@ enum {
1420 PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */ 1422 PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
1421 PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */ 1423 PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */
1422 PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ 1424 PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */
1423 PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; 1425 PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */
1424 1426
1427 PHY_M_10B_TE_ENABLE = 1<<7, /* 10Base-Te Enable (88E8079 and above) */
1428};
1425#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK) 1429#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK)
1426 /* 00=1x; 01=2x; 10=3x; 11=4x */ 1430 /* 00=1x; 01=2x; 10=3x; 11=4x */
1427#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK) 1431#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK)