static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr, struct mdio_ops *mdio_ops) { struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); if (!cphy) return NULL; cphy_init(cphy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops); /* Configure particular PHY's to run in a different mode. */ if ((board_info(adapter)->caps & SUPPORTED_TP) && board_info(adapter)->chip_phy == CHBT_PHY_88E1111) { /* * Configure the PHY transmitter as class A to reduce EMI. */ (void) simple_mdio_write(cphy, MV88E1XXX_EXTENDED_ADDR_REGISTER, 0xB); (void) simple_mdio_write(cphy, MV88E1XXX_EXTENDED_REGISTER, 0x8004); } (void) mv88e1xxx_downshift_set(cphy, 1); /* Enable downshift */ /* LED */ if (is_T2(adapter)) { (void) simple_mdio_write(cphy, MV88E1XXX_LED_CONTROL_REGISTER, 0x1); } return cphy; }
static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { struct adapter *adapter = netdev_priv(dev); struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); if (!cphy) return NULL; cphy_init(cphy, dev, phy_addr, &mv88e1xxx_ops, mdio_ops); if ((board_info(adapter)->caps & SUPPORTED_TP) && board_info(adapter)->chip_phy == CHBT_PHY_88E1111) { (void) simple_mdio_write(cphy, MV88E1XXX_EXTENDED_ADDR_REGISTER, 0xB); (void) simple_mdio_write(cphy, MV88E1XXX_EXTENDED_REGISTER, 0x8004); } (void) mv88e1xxx_downshift_set(cphy, 1); if (is_T2(adapter)) { (void) simple_mdio_write(cphy, MV88E1XXX_LED_CONTROL_REGISTER, 0x1); } return cphy; }
int t3_tn1010_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &tn1010_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_AUI | SUPPORTED_TP, "1000/10GBASE-T"); msleep(500); /* PHY needs up to 500ms to start responding to MDIO */ return 0; }
static struct cphy *my3126_phy_create(adapter_t *adapter, int phy_addr, struct mdio_ops *mdio_ops) { struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL); if (!cphy) return NULL; cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); cphy->bmsr = 0; return cphy; }
static struct cphy *my3126_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL); if (!cphy) return NULL; cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops); INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); cphy->bmsr = 0; return cphy; }
int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { int err; unsigned int val; cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops, SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); msleep(20); /* PHY needs ~10ms to start responding to MDIO */ err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val); if (err) return err; if (val & VSC_CTRL_MEDIA_MODE_HI) { /* copper interface, just need to configure the LEDs */ return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100); } phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_FIBRE | SUPPORTED_IRQ; phy->desc = "1000BASE-X"; phy->ops = &vsc8211_fiber_ops; err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1); if (err) return err; err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1); if (err) return err; err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0); if (err) return err; err = mdio_write(phy, 0, VSC8211_EXT_CTRL, val | VSC_CTRL_CLAUSE37_VIEW); if (err) return err; err = vsc8211_reset(phy, 0); if (err) return err; udelay(5); /* delay after reset before next SMI */ return 0; }
void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int stat; cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops); /* * Some cards where the PHY is supposed to be at address 0 actually * have it at 1. */ if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && stat == 0xffff) phy->addr = 1; }
int t3_vsc8211_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { struct cphy *phy = &pinfo->phy; int err; unsigned int val; cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &vsc8211_ops, mdio_ops, SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); msleep(20); /* PHY needs ~10ms to start responding to MDIO */ /* Disable Link Speed Auto-Downshift */ if ((err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1)) != 0 || (err = mdio_read(phy, 0, VSC8211_EXT_CTRL_3, &val)) != 0 || (err = mdio_write(phy, 0, VSC8211_EXT_CTRL_3, (val & ~(F_LNKSPEEDDSENABLE)) )) != 0 || (err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0)) != 0 ) return err; err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val); if (err) return err; if (val & VSC_CTRL_MEDIA_MODE_HI) { /* copper interface, just need to configure the LEDs */ return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100); } phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_FIBRE | SUPPORTED_IRQ; phy->desc = "1000BASE-X"; phy->ops = &vsc8211_fiber_ops; if ((err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1)) != 0 || (err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1)) != 0 || (err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0)) != 0 || (err = mdio_write(phy, 0, VSC8211_EXT_CTRL, val | VSC_CTRL_CLAUSE37_VIEW)) != 0 || (err = vsc8211_reset(phy, 0)) != 0) return err; udelay(5); /* delay after reset before next SMI */ return 0; }
int t3_mv88e1xxx_phy_prep(pinfo_t *pinfo, int phy_addr, const struct mdio_ops *mdio_ops) { struct cphy *phy = &pinfo->phy; int err; cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &mv88e1xxx_ops, mdio_ops, SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); /* Configure copper PHY transmitter as class A to reduce EMI. */ err = mdio_write(phy, 0, MV88E1XXX_EXTENDED_ADDR, 0xb); if (!err) err = mdio_write(phy, 0, MV88E1XXX_EXTENDED_DATA, 0x8004); if (!err) err = mv88e1xxx_downshift_set(phy, 1); /* Enable downshift */ return err; }
static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, struct mdio_ops *mdio_ops) { u32 val; struct cphy *cphy = kmalloc(sizeof(*cphy), GFP_KERNEL); if (!cphy) return NULL; memset(cphy, 0, sizeof(*cphy)); cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops); /* Commands the PHY to enable XFP's clock. */ mdio_read(cphy, 0x3, 0x8300, &val); mdio_write(cphy, 0x3, 0x8300, val | 1); /* Clear link status. Required because of a bug in the PHY. */ mdio_read(cphy, 0x1, 0x8, &val); mdio_read(cphy, 0x3, 0x8, &val); /* Allows for Link,Ack LED turn on/off */ led_init(cphy); return cphy; }
static struct cphy *mv88x201x_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { u32 val; struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); if (!cphy) return NULL; cphy_init(cphy, dev, phy_addr, &mv88x201x_ops, mdio_ops); /* Commands the PHY to enable XFP's clock. */ cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val); cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1); /* Clear link status. Required because of a bug in the PHY. */ cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val); cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val); /* Allows for Link,Ack LED turn on/off */ led_init(cphy); return cphy; }
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int v, v2, gpio, wait; int err; cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); /* * The PHY has been out of reset ever since the system powered up. So * we do a hard reset over here. */ gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); msleep(1); t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); /* * Give it enough time to load the firmware and get ready for mdio. */ msleep(1000); wait = 500; /* in 10ms increments */ do { err = mdio_read(phy, MDIO_DEV_VEND1, MII_BMCR, &v); if (err || v == 0xffff) { /* Allow prep_adapter to succeed when ffff is read */ CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", phy_addr, err, v); goto done; } v &= AQ_RESET; if (v) msleep(10); } while (v && --wait); if (v) { CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", phy_addr, v); goto done; /* let prep_adapter succeed */ } /* Datasheet says 3s max but this has been observed */ wait = (500 - wait) * 10 + 1000; if (wait > 3000) CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); /* Firmware version check. */ (void) mdio_read(phy, MDIO_DEV_VEND1, AQ_FW_VERSION, &v); if (v != 101) CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", phy_addr, v); /* * The PHY should start in really-low-power mode. Prepare it for normal * operations. */ err = mdio_read(phy, MDIO_DEV_VEND1, MII_BMCR, &v); if (err) return err; if (v & AQ_LOWPOWER) { err = t3_mdio_change_bits(phy, MDIO_DEV_VEND1, MII_BMCR, AQ_LOWPOWER, 0); if (err) return err; msleep(10); } else CH_WARN(adapter, "PHY%d does not start in low power mode.\n", phy_addr); /* * Verify XAUI settings, but let prep succeed no matter what. */ v = v2 = 0; mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_RX_CFG, &v); mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_TX_CFG, &v2); if (v != 0x1b || v2 != 0x1b) CH_WARN(adapter, "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", phy_addr, v, v2); done: return err; }
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int v, v2, gpio, wait; int err; cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); msleep(1); t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); msleep(1000); wait = 500; do { err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); if (err || v == 0xffff) { CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", phy_addr, err, v); goto done; } v &= AQ_RESET; if (v) msleep(10); } while (v && --wait); if (v) { CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", phy_addr, v); goto done; } wait = (500 - wait) * 10 + 1000; if (wait > 3000) CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v); if (v != 101) CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", phy_addr, v); err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); if (err) return err; if (v & AQ_LOWPOWER) { err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1, AQ_LOWPOWER, 0); if (err) return err; msleep(10); } else CH_WARN(adapter, "PHY%d does not start in low power mode.\n", phy_addr); v = v2 = 0; t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v); t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2); if (v != 0x1b || v2 != 0x1b) CH_WARN(adapter, "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", phy_addr, v, v2); done: return err; }
void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(phy, adapter, 1, &xaui_direct_ops, mdio_ops); }
void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops); ael100x_txon(phy); }
void t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops); t3_os_sleep(20); /* PHY needs ~10ms to start responding to MDIO */ }