예제 #1
0
파일: mv88e1xxx.c 프로젝트: maliyu/SOM2416
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;
}
예제 #2
0
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;
}
예제 #4
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
0
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;
}
예제 #9
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;
}
예제 #10
0
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;
}
예제 #11
0
파일: mv88x201x.c 프로젝트: 19Dan01/linux
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #14
0
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);
}
예제 #15
0
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 */
}