Ejemplo n.º 1
0
static void ag71xx_phy_link_adjust(struct net_device *dev)
{
	struct ag71xx *ag = netdev_priv(dev);
	struct phy_device *phydev = ag->phy_dev;
	unsigned long flags;
	int status_change = 0;

	spin_lock_irqsave(&ag->lock, flags);

	if (phydev->link) {
		if (ag->duplex != phydev->duplex
		    || ag->speed != phydev->speed) {
			status_change = 1;
		}
	}

	if (phydev->link != ag->link)
		status_change = 1;

	ag->link = phydev->link;
	ag->duplex = phydev->duplex;
	ag->speed = phydev->speed;

	if (status_change)
		ag71xx_link_adjust(ag);

	spin_unlock_irqrestore(&ag->lock, flags);
}
Ejemplo n.º 2
0
void ag71xx_phy_start(struct ag71xx *ag)
{
	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);

	if (ag->phy_dev) {
		phy_start(ag->phy_dev);
	} else if (pdata->mii_bus_dev && pdata->switch_data) {
		ag71xx_ar7240_start(ag);
	} else {
		ag->link = 1;
		ag71xx_link_adjust(ag);
	}
}
Ejemplo n.º 3
0
void ag71xx_phy_stop(struct ag71xx *ag)
{
	struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
	unsigned long flags;

	if (ag->phy_dev)
		phy_stop(ag->phy_dev);
	else if (pdata->mii_bus_dev && pdata->switch_data)
		ag71xx_ar7240_stop(ag);

	spin_lock_irqsave(&ag->lock, flags);
	if (ag->link) {
		ag->link = 0;
		ag71xx_link_adjust(ag);
	}
	spin_unlock_irqrestore(&ag->lock, flags);
}
Ejemplo n.º 4
0
static void link_function(struct work_struct *work) {
	struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work);
	struct ar7240sw *as = ag->phy_priv;
	unsigned long flags;
	u8 mask;
	int i;
	int status = 0, link_up_count = 0;

	mask = ~as->swdata->phy_poll_mask;
	for (i = 0; i < AR7240_NUM_PHYS; i++) {
		int link;

		if (!(mask & BIT(i)))
			continue;

		link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR);
		if (link & BMSR_LSTATUS) {
			status = 1;
			link_up_count++;
		}
	}

	if (link_up_count != 0 && as->num_ports_linkup != link_up_count) {

		/* Set flowcontrol threshold based on linkup count */

		if (link_up_count == 1)
			ar7240sw_reg_write(as->mii_bus, 0x34, 0x16602090);
		else if (link_up_count == 2)
			ar7240sw_reg_write(as->mii_bus, 0x34, 0x90bcc0ff);
		else if (link_up_count > 2)
			ar7240sw_reg_write(as->mii_bus, 0x34, 0xb0c0c0ff);

		as->num_ports_linkup = link_up_count;
	}

	spin_lock_irqsave(&ag->lock, flags);
	if (status != ag->link) {
		ag->link = status;
		ag71xx_link_adjust(ag);
	}
	spin_unlock_irqrestore(&ag->lock, flags);

	schedule_delayed_work(&ag->link_work, HZ / 2);
}