Loading drivers/net/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -2483,6 +2483,7 @@ config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" depends on CHELSIO_T3_DEPENDS select FW_LOADER select MDIO help This driver supports Chelsio T3-based gigabit and 10Gb Ethernet adapters. Loading drivers/net/cxgb3/ael1002.c +76 −70 Original line number Diff line number Diff line Loading @@ -33,14 +33,6 @@ #include "regs.h" enum { PMD_RSD = 10, /* PMA/PMD receive signal detect register */ PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ XS_LN_STAT = 24 /* XS lane status register */ }; enum { AEL100X_TX_DISABLE = 9, AEL100X_TX_CONFIG1 = 0xc002, AEL1002_PWR_DOWN_HI = 0xc011, AEL1002_PWR_DOWN_LO = 0xc012, Loading Loading @@ -74,7 +66,7 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) for (err = 0; rv->mmd_addr && !err; rv++) { if (rv->clear_bits == 0xffff) err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr, rv->set_bits); else err = t3_mdio_change_bits(phy, rv->mmd_addr, Loading @@ -86,7 +78,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) static void ael100x_txon(struct cphy *phy) { int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; int tx_on_gpio = phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; msleep(100); t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); Loading @@ -97,10 +90,11 @@ static int ael1002_power_down(struct cphy *phy, int enable) { int err; err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); if (!err) err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, enable ? BMCR_PDOWN : 0); err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); return err; } Loading @@ -109,11 +103,11 @@ static int ael1002_reset(struct cphy *phy, int wait) int err; if ((err = ael1002_power_down(phy, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, 0, 1 << 5))) return err; return 0; Loading @@ -132,12 +126,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET, &stat0); if (!err) err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); err = t3_mdio_read(phy, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1, &stat1); if (!err) err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); err = t3_mdio_read(phy, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; Loading @@ -157,6 +154,7 @@ static struct cphy_ops ael1002_ops = { .intr_handler = ael1002_intr_noop, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -171,13 +169,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael1006_reset(struct cphy *phy, int wait) { return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); } static int ael1006_power_down(struct cphy *phy, int enable) { return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, enable ? BMCR_PDOWN : 0); return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); } static struct cphy_ops ael1006_ops = { Loading @@ -188,6 +186,7 @@ static struct cphy_ops ael1006_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1006_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -203,9 +202,9 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael2005_setup_sr_edc(struct cphy *phy) { static struct reg_val regs[] = { { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, { 0, 0, 0, 0 } }; static u16 sr_edc[] = { Loading Loading @@ -490,7 +489,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy) msleep(50); for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], sr_edc[i + 1]); if (!err) phy->priv = edc_sr; Loading @@ -500,12 +499,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy) static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) { static struct reg_val regs[] = { { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, { 0, 0, 0, 0 } }; static struct reg_val preemphasis[] = { { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, { 0, 0, 0, 0 } }; static u16 twinax_edc[] = { Loading Loading @@ -887,7 +886,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) msleep(50); for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], twinax_edc[i + 1]); if (!err) phy->priv = edc_twinax; Loading @@ -899,18 +898,18 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) int i, err; unsigned int stat, data; err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, (dev_addr << 8) | (1 << 8) | word_addr); if (err) return err; for (i = 0; i < 5; i++) { msleep(1); err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); if (err) return err; if ((stat & 3) == 1) { err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, &data); if (err) return err; Loading @@ -918,7 +917,7 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) } } CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", phy->addr, word_addr); phy->mdio.prtad, word_addr); return -ETIMEDOUT; } Loading @@ -927,7 +926,7 @@ static int get_module_type(struct cphy *phy, int delay_ms) int v; unsigned int stat; v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat); if (v) return v; Loading Loading @@ -971,48 +970,48 @@ static int get_module_type(struct cphy *phy, int delay_ms) static int ael2005_intr_enable(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); return err ? err : t3_phy_lasi_intr_enable(phy); } static int ael2005_intr_disable(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); return err ? err : t3_phy_lasi_intr_disable(phy); } static int ael2005_intr_clear(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); return err ? err : t3_phy_lasi_intr_clear(phy); } static int ael2005_reset(struct cphy *phy, int wait) { static struct reg_val regs0[] = { { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, { 0, 0, 0, 0 } }; static struct reg_val regs1[] = { { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, { 0, 0, 0, 0 } }; int err; unsigned int lasi_ctrl; err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_CTRL, &lasi_ctrl); if (err) return err; err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0); if (err) return err; Loading Loading @@ -1051,12 +1050,12 @@ static int ael2005_intr_handler(struct cphy *phy) unsigned int stat; int ret, edc_needed, cause = 0; ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); if (ret) return ret; if (stat & AEL2005_MODDET_IRQ) { ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); if (ret) return ret; Loading Loading @@ -1098,6 +1097,7 @@ static struct cphy_ops ael2005_ops = { .intr_handler = ael2005_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -1107,7 +1107,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | SUPPORTED_IRQ, "10GBASE-R"); msleep(125); return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, 1 << 5); } Loading @@ -1119,12 +1119,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET, &stat0); if (!err) err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); err = t3_mdio_read(phy, MDIO_MMD_PCS, MDIO_PCS_10GBX_STAT1, &stat1); if (!err) err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); err = t3_mdio_read(phy, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; Loading @@ -1144,6 +1147,7 @@ static struct cphy_ops qt2045_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_x, .power_down = ael1006_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -1159,9 +1163,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, * 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) && if (!phy_addr && !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && stat == 0xffff) phy->addr = 1; phy->mdio.prtad = 1; return 0; } Loading @@ -1175,15 +1180,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, { if (link_ok) { unsigned int status; int prtad = phy->mdio.prtad; status = t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT0, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT1, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT2, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); XGM_REG(A_XGM_SERDES_STAT3, prtad)); *link_ok = !(status & F_LOWSIG0); } if (speed) Loading Loading @@ -1211,7 +1217,7 @@ static struct cphy_ops xaui_direct_ops = { int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; Loading drivers/net/cxgb3/common.h +23 −30 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ #include <linux/init.h> #include <linux/netdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/mdio.h> #include "version.h" #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) Loading Loading @@ -184,10 +184,11 @@ struct cphy; struct adapter; struct mdio_ops { int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *val); int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val); int (*read)(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr); int (*write)(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val); unsigned mode_support; }; struct adapter_info { Loading Loading @@ -520,17 +521,6 @@ enum { MAC_RXFIFO_SIZE = 32768 }; /* IEEE 802.3 specified MDIO devices */ enum { MDIO_DEV_PMA_PMD = 1, MDIO_DEV_WIS = 2, MDIO_DEV_PCS = 3, MDIO_DEV_XGXS = 4, MDIO_DEV_ANEG = 7, MDIO_DEV_VEND1 = 30, MDIO_DEV_VEND2 = 31 }; /* LASI control and status registers */ enum { RX_ALARM_CTRL = 0x9000, Loading Loading @@ -583,11 +573,12 @@ struct cphy_ops { int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, int *duplex, int *fc); int (*power_down)(struct cphy *phy, int enable); u32 mmds; }; /* A PHY instance */ struct cphy { u8 addr; /* PHY address */ u8 modtype; /* PHY module type */ short priv; /* scratch pad */ unsigned int caps; /* PHY capabilities */ Loading @@ -595,23 +586,23 @@ struct cphy { const char *desc; /* PHY description */ unsigned long fifo_errors; /* FIFO over/under-flows */ const struct cphy_ops *ops; /* PHY operations */ int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *val); int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val); struct mdio_if_info mdio; }; /* Convenience MDIO read/write wrappers */ static inline int mdio_read(struct cphy *phy, int mmd, int reg, static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg, unsigned int *valp) { return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp); int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg); *valp = (rc >= 0) ? rc : -1; return (rc >= 0) ? 0 : rc; } static inline int mdio_write(struct cphy *phy, int mmd, int reg, static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg, unsigned int val) { return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val); return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd, reg, val); } /* Convenience initializer */ Loading @@ -620,14 +611,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter, const struct mdio_ops *mdio_ops, unsigned int caps, const char *desc) { phy->addr = phy_addr; phy->caps = caps; phy->adapter = adapter; phy->desc = desc; phy->ops = phy_ops; if (mdio_ops) { phy->mdio_read = mdio_ops->read; phy->mdio_write = mdio_ops->write; phy->mdio.prtad = phy_addr; phy->mdio.mmds = phy_ops->mmds; phy->mdio.mode_support = mdio_ops->mode_support; phy->mdio.mdio_read = mdio_ops->read; phy->mdio.mdio_write = mdio_ops->write; } } Loading drivers/net/cxgb3/cxgb3_main.c +13 −58 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mii.h> #include <linux/mdio.h> #include <linux/sockios.h> #include <linux/workqueue.h> #include <linux/proc_fs.h> Loading Loading @@ -1593,7 +1593,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; cmd->phy_address = p->phy.addr; cmd->phy_address = p->phy.mdio.prtad; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = p->link_config.autoneg; cmd->maxtxpkt = 0; Loading Loading @@ -2308,70 +2308,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) struct mii_ioctl_data *data = if_mii(req); struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret, mmd; switch (cmd) { case SIOCGMIIPHY: data->phy_id = pi->phy.addr; case SIOCGMIIREG: case SIOCSMIIREG: /* Convert phy_id from older PRTAD/DEVAD format */ if (is_10G(adapter) && !mdio_phy_id_is_c45(data->phy_id) && (data->phy_id & 0x1f00) && !(data->phy_id & 0xe0e0)) data->phy_id = mdio_phy_id_c45(data->phy_id >> 8, data->phy_id & 0x1f); /* FALLTHRU */ case SIOCGMIIREG:{ u32 val; struct cphy *phy = &pi->phy; if (!phy->mdio_read) return -EOPNOTSUPP; if (is_10G(adapter)) { mmd = data->phy_id >> 8; if (!mmd) mmd = MDIO_DEV_PCS; else if (mmd > MDIO_DEV_VEND2) return -EINVAL; ret = phy->mdio_read(adapter, data->phy_id & 0x1f, mmd, data->reg_num, &val); } else ret = phy->mdio_read(adapter, data->phy_id & 0x1f, 0, data->reg_num & 0x1f, &val); if (!ret) data->val_out = val; break; } case SIOCSMIIREG:{ struct cphy *phy = &pi->phy; if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!phy->mdio_write) return -EOPNOTSUPP; if (is_10G(adapter)) { mmd = data->phy_id >> 8; if (!mmd) mmd = MDIO_DEV_PCS; else if (mmd > MDIO_DEV_VEND2) return -EINVAL; ret = phy->mdio_write(adapter, data->phy_id & 0x1f, mmd, data->reg_num, data->val_in); } else ret = phy->mdio_write(adapter, data->phy_id & 0x1f, 0, data->reg_num & 0x1f, data->val_in); break; } case SIOCGMIIPHY: return mdio_mii_ioctl(&pi->phy.mdio, data, cmd); case SIOCCHIOCTL: return cxgb_extension_ioctl(dev, req->ifr_data); default: return -EOPNOTSUPP; } return ret; } static int cxgb_change_mtu(struct net_device *dev, int new_mtu) Loading drivers/net/cxgb3/t3_hw.c +42 −36 Original line number Diff line number Diff line Loading @@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai) /* * MI1 read/write operations for clause 22 PHYs. */ static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *valp) static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); if (mmd_addr) return -EINVAL; mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); ret = t3_read_reg(adapter, A_MI1_DATA); mutex_unlock(&adapter->mdio_lock); return ret; } static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val) static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); if (mmd_addr) return -EINVAL; mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); Loading @@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ops = { t3_mi1_read, t3_mi1_write .read = t3_mi1_read, .write = t3_mi1_write, .mode_support = MDIO_SUPPORTS_C22 }; /* Loading @@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr, /* * MI1 read/write operations for indirect-addressed PHYs. */ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *valp) static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); Loading @@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); ret = t3_read_reg(adapter, A_MI1_DATA); } mutex_unlock(&adapter->mdio_lock); return ret; } static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val) static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); Loading @@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ext_ops = { mi1_ext_read, mi1_ext_write .read = mi1_ext_read, .write = mi1_ext_write, .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22 }; /** Loading @@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, int ret; unsigned int val; ret = mdio_read(phy, mmd, reg, &val); ret = t3_mdio_read(phy, mmd, reg, &val); if (!ret) { val &= ~clear; ret = mdio_write(phy, mmd, reg, val | set); ret = t3_mdio_write(phy, mmd, reg, val | set); } return ret; } Loading @@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait) int err; unsigned int ctl; err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET); err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER, MDIO_CTRL1_RESET); if (err || !wait) return err; do { err = mdio_read(phy, mmd, MII_BMCR, &ctl); err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl); if (err) return err; ctl &= BMCR_RESET; ctl &= MDIO_CTRL1_RESET; if (ctl) msleep(1); } while (ctl && --wait); Loading @@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) int err; unsigned int val = 0; err = mdio_read(phy, 0, MII_CTRL1000, &val); err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val); if (err) return err; Loading @@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) if (advert & ADVERTISED_1000baseT_Full) val |= ADVERTISE_1000FULL; err = mdio_write(phy, 0, MII_CTRL1000, val); err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val); if (err) return err; Loading @@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) val |= ADVERTISE_PAUSE_CAP; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_PAUSE_ASYM; return mdio_write(phy, 0, MII_ADVERTISE, val); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** Loading @@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert) val |= ADVERTISE_1000XPAUSE; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_1000XPSE_ASYM; return mdio_write(phy, 0, MII_ADVERTISE, val); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** Loading @@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) int err; unsigned int ctl; err = mdio_read(phy, 0, MII_BMCR, &ctl); err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl); if (err) return err; Loading @@ -462,30 +467,30 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) } if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ ctl |= BMCR_ANENABLE; return mdio_write(phy, 0, MII_BMCR, ctl); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl); } int t3_phy_lasi_intr_enable(struct cphy *phy) { return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 1); } int t3_phy_lasi_intr_disable(struct cphy *phy) { return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 0); } int t3_phy_lasi_intr_clear(struct cphy *phy) { u32 val; return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); return t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &val); } int t3_phy_lasi_intr_handler(struct cphy *phy) { unsigned int status; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &status); if (err) return err; Loading Loading @@ -3863,6 +3868,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, ai->mdio_ops); if (ret) return ret; p->phy.mdio.dev = adapter->port[i]; mac_prep(&p->mac, adapter, j); /* Loading Loading @@ -3918,7 +3924,7 @@ int t3_replay_prep_adapter(struct adapter *adapter) ; pti = &port_types[adapter->params.vpd.port_type[j]]; ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL); ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL); if (ret) return ret; p->phy.ops->power_down(&p->phy, 1); Loading Loading
drivers/net/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -2483,6 +2483,7 @@ config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" depends on CHELSIO_T3_DEPENDS select FW_LOADER select MDIO help This driver supports Chelsio T3-based gigabit and 10Gb Ethernet adapters. Loading
drivers/net/cxgb3/ael1002.c +76 −70 Original line number Diff line number Diff line Loading @@ -33,14 +33,6 @@ #include "regs.h" enum { PMD_RSD = 10, /* PMA/PMD receive signal detect register */ PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ XS_LN_STAT = 24 /* XS lane status register */ }; enum { AEL100X_TX_DISABLE = 9, AEL100X_TX_CONFIG1 = 0xc002, AEL1002_PWR_DOWN_HI = 0xc011, AEL1002_PWR_DOWN_LO = 0xc012, Loading Loading @@ -74,7 +66,7 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) for (err = 0; rv->mmd_addr && !err; rv++) { if (rv->clear_bits == 0xffff) err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr, rv->set_bits); else err = t3_mdio_change_bits(phy, rv->mmd_addr, Loading @@ -86,7 +78,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) static void ael100x_txon(struct cphy *phy) { int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; int tx_on_gpio = phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; msleep(100); t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); Loading @@ -97,10 +90,11 @@ static int ael1002_power_down(struct cphy *phy, int enable) { int err; err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); if (!err) err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, enable ? BMCR_PDOWN : 0); err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); return err; } Loading @@ -109,11 +103,11 @@ static int ael1002_reset(struct cphy *phy, int wait) int err; if ((err = ael1002_power_down(phy, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, 0, 1 << 5))) return err; return 0; Loading @@ -132,12 +126,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET, &stat0); if (!err) err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); err = t3_mdio_read(phy, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1, &stat1); if (!err) err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); err = t3_mdio_read(phy, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; Loading @@ -157,6 +154,7 @@ static struct cphy_ops ael1002_ops = { .intr_handler = ael1002_intr_noop, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -171,13 +169,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael1006_reset(struct cphy *phy, int wait) { return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); } static int ael1006_power_down(struct cphy *phy, int enable) { return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, BMCR_PDOWN, enable ? BMCR_PDOWN : 0); return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); } static struct cphy_ops ael1006_ops = { Loading @@ -188,6 +186,7 @@ static struct cphy_ops ael1006_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1006_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -203,9 +202,9 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael2005_setup_sr_edc(struct cphy *phy) { static struct reg_val regs[] = { { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, { 0, 0, 0, 0 } }; static u16 sr_edc[] = { Loading Loading @@ -490,7 +489,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy) msleep(50); for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], sr_edc[i + 1]); if (!err) phy->priv = edc_sr; Loading @@ -500,12 +499,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy) static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) { static struct reg_val regs[] = { { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, { 0, 0, 0, 0 } }; static struct reg_val preemphasis[] = { { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, { 0, 0, 0, 0 } }; static u16 twinax_edc[] = { Loading Loading @@ -887,7 +886,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) msleep(50); for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], twinax_edc[i + 1]); if (!err) phy->priv = edc_twinax; Loading @@ -899,18 +898,18 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) int i, err; unsigned int stat, data; err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, (dev_addr << 8) | (1 << 8) | word_addr); if (err) return err; for (i = 0; i < 5; i++) { msleep(1); err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); if (err) return err; if ((stat & 3) == 1) { err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, &data); if (err) return err; Loading @@ -918,7 +917,7 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) } } CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", phy->addr, word_addr); phy->mdio.prtad, word_addr); return -ETIMEDOUT; } Loading @@ -927,7 +926,7 @@ static int get_module_type(struct cphy *phy, int delay_ms) int v; unsigned int stat; v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat); if (v) return v; Loading Loading @@ -971,48 +970,48 @@ static int get_module_type(struct cphy *phy, int delay_ms) static int ael2005_intr_enable(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); return err ? err : t3_phy_lasi_intr_enable(phy); } static int ael2005_intr_disable(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); return err ? err : t3_phy_lasi_intr_disable(phy); } static int ael2005_intr_clear(struct cphy *phy) { int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); return err ? err : t3_phy_lasi_intr_clear(phy); } static int ael2005_reset(struct cphy *phy, int wait) { static struct reg_val regs0[] = { { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, { 0, 0, 0, 0 } }; static struct reg_val regs1[] = { { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, { 0, 0, 0, 0 } }; int err; unsigned int lasi_ctrl; err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_CTRL, &lasi_ctrl); if (err) return err; err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0); if (err) return err; Loading Loading @@ -1051,12 +1050,12 @@ static int ael2005_intr_handler(struct cphy *phy) unsigned int stat; int ret, edc_needed, cause = 0; ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); if (ret) return ret; if (stat & AEL2005_MODDET_IRQ) { ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); if (ret) return ret; Loading Loading @@ -1098,6 +1097,7 @@ static struct cphy_ops ael2005_ops = { .intr_handler = ael2005_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -1107,7 +1107,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | SUPPORTED_IRQ, "10GBASE-R"); msleep(125); return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, 1 << 5); } Loading @@ -1119,12 +1119,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_RXDET, &stat0); if (!err) err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); err = t3_mdio_read(phy, MDIO_MMD_PCS, MDIO_PCS_10GBX_STAT1, &stat1); if (!err) err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); err = t3_mdio_read(phy, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; Loading @@ -1144,6 +1147,7 @@ static struct cphy_ops qt2045_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_x, .power_down = ael1006_power_down, .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, Loading @@ -1159,9 +1163,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, * 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) && if (!phy_addr && !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && stat == 0xffff) phy->addr = 1; phy->mdio.prtad = 1; return 0; } Loading @@ -1175,15 +1180,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, { if (link_ok) { unsigned int status; int prtad = phy->mdio.prtad; status = t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT0, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT1, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | XGM_REG(A_XGM_SERDES_STAT2, prtad)) | t3_read_reg(phy->adapter, XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); XGM_REG(A_XGM_SERDES_STAT3, prtad)); *link_ok = !(status & F_LOWSIG0); } if (speed) Loading Loading @@ -1211,7 +1217,7 @@ static struct cphy_ops xaui_direct_ops = { int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; Loading
drivers/net/cxgb3/common.h +23 −30 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ #include <linux/init.h> #include <linux/netdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/mdio.h> #include "version.h" #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) Loading Loading @@ -184,10 +184,11 @@ struct cphy; struct adapter; struct mdio_ops { int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *val); int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val); int (*read)(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr); int (*write)(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val); unsigned mode_support; }; struct adapter_info { Loading Loading @@ -520,17 +521,6 @@ enum { MAC_RXFIFO_SIZE = 32768 }; /* IEEE 802.3 specified MDIO devices */ enum { MDIO_DEV_PMA_PMD = 1, MDIO_DEV_WIS = 2, MDIO_DEV_PCS = 3, MDIO_DEV_XGXS = 4, MDIO_DEV_ANEG = 7, MDIO_DEV_VEND1 = 30, MDIO_DEV_VEND2 = 31 }; /* LASI control and status registers */ enum { RX_ALARM_CTRL = 0x9000, Loading Loading @@ -583,11 +573,12 @@ struct cphy_ops { int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, int *duplex, int *fc); int (*power_down)(struct cphy *phy, int enable); u32 mmds; }; /* A PHY instance */ struct cphy { u8 addr; /* PHY address */ u8 modtype; /* PHY module type */ short priv; /* scratch pad */ unsigned int caps; /* PHY capabilities */ Loading @@ -595,23 +586,23 @@ struct cphy { const char *desc; /* PHY description */ unsigned long fifo_errors; /* FIFO over/under-flows */ const struct cphy_ops *ops; /* PHY operations */ int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *val); int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val); struct mdio_if_info mdio; }; /* Convenience MDIO read/write wrappers */ static inline int mdio_read(struct cphy *phy, int mmd, int reg, static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg, unsigned int *valp) { return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp); int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg); *valp = (rc >= 0) ? rc : -1; return (rc >= 0) ? 0 : rc; } static inline int mdio_write(struct cphy *phy, int mmd, int reg, static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg, unsigned int val) { return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val); return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd, reg, val); } /* Convenience initializer */ Loading @@ -620,14 +611,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter, const struct mdio_ops *mdio_ops, unsigned int caps, const char *desc) { phy->addr = phy_addr; phy->caps = caps; phy->adapter = adapter; phy->desc = desc; phy->ops = phy_ops; if (mdio_ops) { phy->mdio_read = mdio_ops->read; phy->mdio_write = mdio_ops->write; phy->mdio.prtad = phy_addr; phy->mdio.mmds = phy_ops->mmds; phy->mdio.mode_support = mdio_ops->mode_support; phy->mdio.mdio_read = mdio_ops->read; phy->mdio.mdio_write = mdio_ops->write; } } Loading
drivers/net/cxgb3/cxgb3_main.c +13 −58 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> #include <linux/mii.h> #include <linux/mdio.h> #include <linux/sockios.h> #include <linux/workqueue.h> #include <linux/proc_fs.h> Loading Loading @@ -1593,7 +1593,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; cmd->phy_address = p->phy.addr; cmd->phy_address = p->phy.mdio.prtad; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = p->link_config.autoneg; cmd->maxtxpkt = 0; Loading Loading @@ -2308,70 +2308,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) struct mii_ioctl_data *data = if_mii(req); struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret, mmd; switch (cmd) { case SIOCGMIIPHY: data->phy_id = pi->phy.addr; case SIOCGMIIREG: case SIOCSMIIREG: /* Convert phy_id from older PRTAD/DEVAD format */ if (is_10G(adapter) && !mdio_phy_id_is_c45(data->phy_id) && (data->phy_id & 0x1f00) && !(data->phy_id & 0xe0e0)) data->phy_id = mdio_phy_id_c45(data->phy_id >> 8, data->phy_id & 0x1f); /* FALLTHRU */ case SIOCGMIIREG:{ u32 val; struct cphy *phy = &pi->phy; if (!phy->mdio_read) return -EOPNOTSUPP; if (is_10G(adapter)) { mmd = data->phy_id >> 8; if (!mmd) mmd = MDIO_DEV_PCS; else if (mmd > MDIO_DEV_VEND2) return -EINVAL; ret = phy->mdio_read(adapter, data->phy_id & 0x1f, mmd, data->reg_num, &val); } else ret = phy->mdio_read(adapter, data->phy_id & 0x1f, 0, data->reg_num & 0x1f, &val); if (!ret) data->val_out = val; break; } case SIOCSMIIREG:{ struct cphy *phy = &pi->phy; if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!phy->mdio_write) return -EOPNOTSUPP; if (is_10G(adapter)) { mmd = data->phy_id >> 8; if (!mmd) mmd = MDIO_DEV_PCS; else if (mmd > MDIO_DEV_VEND2) return -EINVAL; ret = phy->mdio_write(adapter, data->phy_id & 0x1f, mmd, data->reg_num, data->val_in); } else ret = phy->mdio_write(adapter, data->phy_id & 0x1f, 0, data->reg_num & 0x1f, data->val_in); break; } case SIOCGMIIPHY: return mdio_mii_ioctl(&pi->phy.mdio, data, cmd); case SIOCCHIOCTL: return cxgb_extension_ioctl(dev, req->ifr_data); default: return -EOPNOTSUPP; } return ret; } static int cxgb_change_mtu(struct net_device *dev, int new_mtu) Loading
drivers/net/cxgb3/t3_hw.c +42 −36 Original line number Diff line number Diff line Loading @@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai) /* * MI1 read/write operations for clause 22 PHYs. */ static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *valp) static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); if (mmd_addr) return -EINVAL; mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); ret = t3_read_reg(adapter, A_MI1_DATA); mutex_unlock(&adapter->mdio_lock); return ret; } static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val) static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); if (mmd_addr) return -EINVAL; mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); Loading @@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ops = { t3_mi1_read, t3_mi1_write .read = t3_mi1_read, .write = t3_mi1_write, .mode_support = MDIO_SUPPORTS_C22 }; /* Loading @@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr, /* * MI1 read/write operations for indirect-addressed PHYs. */ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int *valp) static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); Loading @@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) *valp = t3_read_reg(adapter, A_MI1_DATA); ret = t3_read_reg(adapter, A_MI1_DATA); } mutex_unlock(&adapter->mdio_lock); return ret; } static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, int reg_addr, unsigned int val) static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr, u16 reg_addr, u16 val) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); Loading @@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ext_ops = { mi1_ext_read, mi1_ext_write .read = mi1_ext_read, .write = mi1_ext_write, .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22 }; /** Loading @@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, int ret; unsigned int val; ret = mdio_read(phy, mmd, reg, &val); ret = t3_mdio_read(phy, mmd, reg, &val); if (!ret) { val &= ~clear; ret = mdio_write(phy, mmd, reg, val | set); ret = t3_mdio_write(phy, mmd, reg, val | set); } return ret; } Loading @@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait) int err; unsigned int ctl; err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET); err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER, MDIO_CTRL1_RESET); if (err || !wait) return err; do { err = mdio_read(phy, mmd, MII_BMCR, &ctl); err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl); if (err) return err; ctl &= BMCR_RESET; ctl &= MDIO_CTRL1_RESET; if (ctl) msleep(1); } while (ctl && --wait); Loading @@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) int err; unsigned int val = 0; err = mdio_read(phy, 0, MII_CTRL1000, &val); err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val); if (err) return err; Loading @@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) if (advert & ADVERTISED_1000baseT_Full) val |= ADVERTISE_1000FULL; err = mdio_write(phy, 0, MII_CTRL1000, val); err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val); if (err) return err; Loading @@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) val |= ADVERTISE_PAUSE_CAP; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_PAUSE_ASYM; return mdio_write(phy, 0, MII_ADVERTISE, val); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** Loading @@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert) val |= ADVERTISE_1000XPAUSE; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_1000XPSE_ASYM; return mdio_write(phy, 0, MII_ADVERTISE, val); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** Loading @@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) int err; unsigned int ctl; err = mdio_read(phy, 0, MII_BMCR, &ctl); err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl); if (err) return err; Loading @@ -462,30 +467,30 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) } if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ ctl |= BMCR_ANENABLE; return mdio_write(phy, 0, MII_BMCR, ctl); return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl); } int t3_phy_lasi_intr_enable(struct cphy *phy) { return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 1); } int t3_phy_lasi_intr_disable(struct cphy *phy) { return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 0); } int t3_phy_lasi_intr_clear(struct cphy *phy) { u32 val; return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); return t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &val); } int t3_phy_lasi_intr_handler(struct cphy *phy) { unsigned int status; int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &status); if (err) return err; Loading Loading @@ -3863,6 +3868,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, ai->mdio_ops); if (ret) return ret; p->phy.mdio.dev = adapter->port[i]; mac_prep(&p->mac, adapter, j); /* Loading Loading @@ -3918,7 +3924,7 @@ int t3_replay_prep_adapter(struct adapter *adapter) ; pti = &port_types[adapter->params.vpd.port_type[j]]; ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL); ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL); if (ret) return ret; p->phy.ops->power_down(&p->phy, 1); Loading