Exemplo n.º 1
0
static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
{
	struct phylink_link_state config;
	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
	u32 advertising;
	int ret;

	memset(&config, 0, sizeof(config));
	ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
	ethtool_convert_legacy_u32_to_link_mode(config.advertising,
						phy->advertising);
	config.interface = pl->link_config.interface;

	/*
	 * This is the new way of dealing with flow control for PHYs,
	 * as described by Timur Tabi in commit 529ed1275263 ("net: phy:
	 * phy drivers should not set SUPPORTED_[Asym_]Pause") except
	 * using our validate call to the MAC, we rely upon the MAC
	 * clearing the bits from both supported and advertising fields.
	 */
	if (phylink_test(supported, Pause))
		phylink_set(config.advertising, Pause);
	if (phylink_test(supported, Asym_Pause))
		phylink_set(config.advertising, Asym_Pause);

	ret = phylink_validate(pl, supported, &config);
	if (ret)
		return ret;

	phy->phylink = pl;
	phy->phy_link_change = phylink_phy_change;

	netdev_info(pl->netdev,
		    "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev),
		    phy->drv->name);

	mutex_lock(&phy->lock);
	mutex_lock(&pl->state_mutex);
	pl->netdev->phydev = phy;
	pl->phydev = phy;
	linkmode_copy(pl->supported, supported);
	linkmode_copy(pl->link_config.advertising, config.advertising);

	/* Restrict the phy advertisment according to the MAC support. */
	ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising);
	phy->advertising = advertising;
	mutex_unlock(&pl->state_mutex);
	mutex_unlock(&phy->lock);

	netdev_dbg(pl->netdev,
		   "phy: setting supported %*pb advertising 0x%08x\n",
		   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
		   phy->advertising);

	phy_start_machine(phy);
	if (phy->irq > 0)
		phy_start_interrupts(phy);

	return 0;
}
Exemplo n.º 2
0
/* phy_connect:
 *
 * description: Convenience function for connecting ethernet
 *   devices to PHY devices.  The default behavior is for
 *   the PHY infrastructure to handle everything, and only notify
 *   the connected driver when the link status changes.  If you
 *   don't want, or can't use the provided functionality, you may
 *   choose to call only the subset of functions which provide
 *   the desired functionality.
 */
struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
		void (*handler)(struct net_device *), u32 flags)
{
	struct phy_device *phydev;

	phydev = phy_attach(dev, phy_id, flags);

	if (IS_ERR(phydev))
		return phydev;

	phy_prepare_link(phydev, handler);

	phy_start_machine(phydev, NULL);

	if (phydev->irq > 0)
		phy_start_interrupts(phydev);

	return phydev;
}
Exemplo n.º 3
0
static int yatse_open(struct net_device *ndev){
	struct yatse_private *priv = netdev_priv(ndev);
	int ret;
	unsigned long flags;

	printk(KERN_INFO "yatse: opening\n");

	priv->link = 0;

#if 0
	ret = dma_set_mask(&ndev->dev, 0xffffffffULL); /* 32-bit DMA addresses */
	if(ret) goto out;
#endif

	spin_lock_irqsave(&priv->dma.rx_lock, flags);
	spin_lock(&priv->dma.tx_lock);
	ret = yatse_dma_init(ndev);
	spin_unlock(&priv->dma.tx_lock);
	spin_unlock_irqrestore(&priv->dma.rx_lock, flags);
	if(ret) goto out;

	tasklet_init(&priv->tx_tasklet, yatse_tx_complete, (unsigned long)ndev);

	ret = yatse_init_phy(ndev);
	if(ret) goto out;

	ret = yatse_init_mac(ndev);
	if(ret) goto out;


	napi_enable(&priv->napi);

	phy_start(priv->phydev);
	if(priv->phy_irq != PHY_POLL) phy_start_interrupts(priv->phydev);
	netif_start_queue(ndev);

	printk(KERN_INFO "yatse: open done, interface up\n");

out:
	return ret;
}