예제 #1
0
/* Caller must hold etsects->lock. */
static u64 tmr_cnt_read(struct etsects *etsects)
{
	u64 ns;
	u32 lo, hi;

	lo = gfar_read(&etsects->regs->tmr_cnt_l);
	hi = gfar_read(&etsects->regs->tmr_cnt_h);
	ns = ((u64) hi) << 32;
	ns |= lo;
	return ns;
}
예제 #2
0
static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (length > GFAR_MAX_FIFO_THRESHOLD)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_threshold = length;

	temp = gfar_read(&priv->regs->fifo_tx_thr);
	temp &= ~FIFO_TX_THR_MASK;
	temp |= length;
	gfar_write(&priv->regs->fifo_tx_thr, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}
예제 #3
0
static ssize_t gfar_set_bd_stash(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	int new_setting = 0;
	u32 temp;
	unsigned long flags;

	/* Find out the new setting */
	if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
		new_setting = 1;
	else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
		new_setting = 0;
	else
		return count;

	spin_lock_irqsave(&priv->rxlock, flags);

	/* Set the new stashing value */
	priv->bd_stash_en = new_setting;

	temp = gfar_read(&priv->regs->attr);

	if (new_setting)
		temp |= ATTR_BDSTASH;
	else
		temp &= ~(ATTR_BDSTASH);

	gfar_write(&priv->regs->attr, temp);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}
예제 #4
0
static ssize_t gfar_set_rx_stash_index(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	unsigned short index = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
		return count;

	local_irq_save(flags);
	lock_rx_qs(priv);

	if (index > priv->rx_stash_size)
		goto out;

	if (index == priv->rx_stash_index)
		goto out;

	priv->rx_stash_index = index;

	temp = gfar_read(&regs->attreli);
	temp &= ~ATTRELI_EI_MASK;
	temp |= ATTRELI_EI(index);
	gfar_write(&regs->attreli, temp);

out:
	unlock_rx_qs(priv);
	local_irq_restore(flags);

	return count;
}
예제 #5
0
static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int num = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (num > GFAR_MAX_FIFO_STARVE_OFF)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_starve_off = num;

	temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
	temp &= ~FIFO_TX_STARVE_OFF_MASK;
	temp |= num;
	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}
예제 #6
0
static ssize_t gfar_set_fifo_threshold(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (length > GFAR_MAX_FIFO_THRESHOLD)
		return count;

	local_irq_save(flags);
	lock_tx_qs(priv);

	priv->fifo_threshold = length;

	temp = gfar_read(&regs->fifo_tx_thr);
	temp &= ~FIFO_TX_THR_MASK;
	temp |= length;
	gfar_write(&regs->fifo_tx_thr, temp);

	unlock_tx_qs(priv);
	local_irq_restore(flags);

	return count;
}
예제 #7
0
static ssize_t gfar_set_fifo_starve_off(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	unsigned int num = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (num > GFAR_MAX_FIFO_STARVE_OFF)
		return count;

	local_irq_save(flags);
	lock_tx_qs(priv);

	priv->fifo_starve_off = num;

	temp = gfar_read(&regs->fifo_tx_starve_shutoff);
	temp &= ~FIFO_TX_STARVE_OFF_MASK;
	temp |= num;
	gfar_write(&regs->fifo_tx_starve_shutoff, temp);

	unlock_tx_qs(priv);
	local_irq_restore(flags);

	return count;
}
예제 #8
0
static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned short index = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	spin_lock_irqsave(&priv->rxlock, flags);
	if (index > priv->rx_stash_size)
		return count;

	if (index == priv->rx_stash_index)
		return count;

	priv->rx_stash_index = index;

	temp = gfar_read(&priv->regs->attreli);
	temp &= ~ATTRELI_EI_MASK;
	temp |= ATTRELI_EI(index);
	gfar_write(&priv->regs->attreli, flags);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}
예제 #9
0
static ssize_t gfar_set_fifo_starve(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	unsigned int num = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (num > GFAR_MAX_FIFO_STARVE)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_starve = num;

	temp = gfar_read(&priv->regs->fifo_tx_starve);
	temp &= ~FIFO_TX_STARVE_MASK;
	temp |= num;
	gfar_write(&priv->regs->fifo_tx_starve, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}
예제 #10
0
/* Reset the MIIM registers, and wait for the bus to free */
int gfar_mdio_reset(struct mii_bus *bus)
{
	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
	unsigned int timeout = PHY_INIT_TIMEOUT;

	spin_lock_bh(&bus->mdio_lock);

	/* Reset the management interface */
	gfar_write(&regs->miimcfg, MIIMCFG_RESET);

	/* Setup the MII Mgmt clock speed */
	gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);

	/* Wait until the bus is free */
	while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
			timeout--)
		cpu_relax();

	spin_unlock_bh(&bus->mdio_lock);

	if(timeout <= 0) {
		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
				bus->name);
		return -EBUSY;
	}

	return 0;
}
예제 #11
0
static ssize_t gfar_set_rx_stash_size(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
		return count;

	local_irq_save(flags);
	lock_rx_qs(priv);

	if (length > priv->rx_buffer_size)
		goto out;

	if (length == priv->rx_stash_size)
		goto out;

	priv->rx_stash_size = length;

	temp = gfar_read(&regs->attreli);
	temp &= ~ATTRELI_EL_MASK;
	temp |= ATTRELI_EL(length);
	gfar_write(&regs->attreli, temp);

	/* Turn stashing on/off as appropriate */
	temp = gfar_read(&regs->attr);

	if (length)
		temp |= ATTR_BUFSTASH;
	else
		temp &= ~(ATTR_BUFSTASH);

	gfar_write(&regs->attr, temp);

out:
	unlock_rx_qs(priv);
	local_irq_restore(flags);

	return count;
}
예제 #12
0
/* Return a dump of the GFAR register space */
static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
	int i;
	struct gfar_private *priv = netdev_priv(dev);
	u32 __iomem *theregs = (u32 __iomem *) priv->regs;
	u32 *buf = (u32 *) regbuf;

	for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
		buf[i] = gfar_read(&theregs[i]);
}
예제 #13
0
/* Read the bus for PHY at addr mii_id, register regnum, and
 * return the value.  Clears miimcom first.  All PHY
 * Operation done on the bus attached to the local interface,
 * which may be different from the generic mdio bus
 * This is helpful in programming interfaces like
 * the TBI which, inturn, control interfaces like onchip SERDES
 * and are always tied to the local mdio pins, which may not be the
 * same as system mdio bus, used for controlling the external PHYs, for example.
 */
int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
{
	u16 value;

	/* Set the PHY address and the register address we want to read */
	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);

	/* Clear miimcom, and then initiate a read */
	gfar_write(&regs->miimcom, 0);
	gfar_write(&regs->miimcom, MII_READ_COMMAND);

	/* Wait for the transaction to finish */
	while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
		cpu_relax();

	/* Grab the value of the register from miimstat */
	value = gfar_read(&regs->miimstat);

	return value;
}
예제 #14
0
static ssize_t gfar_set_rx_stash_size(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
		return count;

	spin_lock_irqsave(&priv->rxlock, flags);
	if (length > priv->rx_buffer_size)
		goto out;

	if (length == priv->rx_stash_size)
		goto out;

	priv->rx_stash_size = length;

	temp = gfar_read(&priv->regs->attreli);
	temp &= ~ATTRELI_EL_MASK;
	temp |= ATTRELI_EL(length);
	gfar_write(&priv->regs->attreli, temp);

	
	temp = gfar_read(&priv->regs->attr);

	if (length)
		temp |= ATTR_BUFSTASH;
	else
		temp &= ~(ATTR_BUFSTASH);

	gfar_write(&priv->regs->attr, temp);

out:
	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}
예제 #15
0
/* configuration has to be done through the TSEC1 MIIM regs */
int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar *regbase = priv->phyregs;
	u16 value;

	/* Set the PHY address and the register address we want to read */
	gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);

	/* Clear miimcom, and then initiate a read */
	gfar_write(&regbase->miimcom, 0);
	gfar_write(&regbase->miimcom, MII_READ_COMMAND);

	/* Wait for the transaction to finish */
	while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
		cpu_relax();

	/* Grab the value of the register from miimstat */
	value = gfar_read(&regbase->miimstat);

	return value;
}
예제 #16
0
/* Write value to the PHY at mii_id at register regnum,
 * on the bus attached to the local interface, which may be different from the 
 * generic mdio bus (tied to a single interface), waiting until the write is 
 * done before returning. This is helpful in programming interfaces like
 * the TBI which control interfaces like onchip SERDES and are always tied to 
 * the local mdio pins, which may not be the same as system mdio bus, used for 
 * controlling the external PHYs, for example.
 */
int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value)
{
	/* Set the PHY address and the register address we want to write */
	gfar_write(&regs->miimadd, (mii_id << 8) | regnum);

	/* Write out the value we want */
	gfar_write(&regs->miimcon, value);

	/* Wait for the transaction to finish */
	while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
		cpu_relax();

	return 0;
}
예제 #17
0
static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	spin_lock_irqsave(&priv->rxlock, flags);
	if (length > priv->rx_buffer_size)
		return count;

	if (length == priv->rx_stash_size)
		return count;

	priv->rx_stash_size = length;

	temp = gfar_read(&priv->regs->attreli);
	temp &= ~ATTRELI_EL_MASK;
	temp |= ATTRELI_EL(length);
	gfar_write(&priv->regs->attreli, temp);

	/* Turn stashing on/off as appropriate */
	temp = gfar_read(&priv->regs->attr);

	if (length)
		temp |= ATTR_BUFSTASH;
	else
		temp &= ~(ATTR_BUFSTASH);

	gfar_write(&priv->regs->attr, temp);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}
예제 #18
0
/* configuration has to be done through the TSEC1 MIIM regs */
void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar *regbase = priv->phyregs;

	/* Set the PHY address and the register address we want to write */
	gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);

	/* Write out the value we want */
	gfar_write(&regbase->miimcon, value);

	/* Wait for the transaction to finish */
	while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
		cpu_relax();
}
예제 #19
0
/* Fill in an array of 64-bit statistics from various sources.
 * This array will be appended to the end of the ethtool_stats
 * structure, and returned to user space
 */
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
			    u64 *buf)
{
	int i;
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	atomic64_t *extra = (atomic64_t *)&priv->extra_stats;

	for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
		buf[i] = atomic64_read(&extra[i]);

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
		u32 __iomem *rmon = (u32 __iomem *) &regs->rmon;

		for (; i < GFAR_STATS_LEN; i++, rmon++)
			buf[i] = (u64) gfar_read(rmon);
	}
}
예제 #20
0
static ssize_t gfar_set_bd_stash(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	int new_setting = 0;
	u32 temp;
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
		return count;


	/* Find out the new setting */
	if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
		new_setting = 1;
	else if (!strncmp("off", buf, count - 1) ||
		 !strncmp("0", buf, count - 1))
		new_setting = 0;
	else
		return count;


	local_irq_save(flags);
	lock_rx_qs(priv);

	/* Set the new stashing value */
	priv->bd_stash_en = new_setting;

	temp = gfar_read(&regs->attr);

	if (new_setting)
		temp |= ATTR_BDSTASH;
	else
		temp &= ~(ATTR_BDSTASH);

	gfar_write(&regs->attr, temp);

	unlock_rx_qs(priv);
	local_irq_restore(flags);

	return count;
}
예제 #21
0
/* Fill in an array of 64-bit statistics from various sources.
 * This array will be appended to the end of the ethtool_stats
 * structure, and returned to user space
 */
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
{
	int i;
	struct gfar_private *priv = netdev_priv(dev);
	u64 *extra = (u64 *) & priv->extra_stats;

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
		u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon;
		struct gfar_stats *stats = (struct gfar_stats *) buf;

		for (i = 0; i < GFAR_RMON_LEN; i++)
			stats->rmon[i] = (u64) gfar_read(&rmon[i]);

		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
			stats->extra[i] = extra[i];
	} else
		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
			buf[i] = extra[i];
}
예제 #22
0
static ssize_t gfar_set_bd_stash(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
	int new_setting = 0;
	u32 temp;
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
		return count;

	
	if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
		new_setting = 1;
	else if (!strncmp("off", buf, count - 1)
		 || !strncmp("0", buf, count - 1))
		new_setting = 0;
	else
		return count;

	spin_lock_irqsave(&priv->rxlock, flags);

	
	priv->bd_stash_en = new_setting;

	temp = gfar_read(&priv->regs->attr);

	if (new_setting)
		temp |= ATTR_BDSTASH;
	else
		temp &= ~(ATTR_BDSTASH);

	gfar_write(&priv->regs->attr, temp);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}
예제 #23
0
/**************************************************************************************************
Syntax:      	    static void p2020_tsec_set_hardware_reg_configuration
Parameters:     	
Remarks:	        set p2020 etsec registers configurations for hardware	
Return Value:	    
***************************************************************************************************/
void p2020_tsec_set_hardware_reg_configuration(struct net_device *dev)
{
	struct dev_mc_list *mc_ptr;
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar  *regs = priv->gfargrp[0].regs;
	u32 tempval;
//Zoya [04 апр. 2014 г.]
	///Ошибка! не работает???

	// Set RCTRL to PROMISC mode
	printk("++Enable Promis mode for %s\n\r", dev->name);
	tempval = gfar_read(&regs->rctrl);
	tempval |= RCTRL_PROM;
	gfar_write(&regs->rctrl, tempval);
		
/*
	printk("++Enable Multicast Frame for eth2\n\r++");
	//Set multicast frames incoming packet
	gfar_write(&regs->igaddr0, 0xffffffff);
	gfar_write(&regs->igaddr1, 0xffffffff);
	gfar_write(&regs->igaddr2, 0xffffffff);
	gfar_write(&regs->igaddr3, 0xffffffff);
	gfar_write(&regs->igaddr4, 0xffffffff);
	gfar_write(&regs->igaddr5, 0xffffffff);
	gfar_write(&regs->igaddr6, 0xffffffff);
	gfar_write(&regs->igaddr7, 0xffffffff);
	gfar_write(&regs->gaddr0, 0xffffffff);
	gfar_write(&regs->gaddr1, 0xffffffff);
	gfar_write(&regs->gaddr2, 0xffffffff);
	gfar_write(&regs->gaddr3, 0xffffffff);
	gfar_write(&regs->gaddr4, 0xffffffff);
	gfar_write(&regs->gaddr5, 0xffffffff);
	gfar_write(&regs->gaddr6, 0xffffffff);
	gfar_write(&regs->gaddr7, 0xffffffff);
 */
	
}
예제 #24
0
static int gfar_spauseparam(struct net_device *dev,
			    struct ethtool_pauseparam *epause)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct phy_device *phydev = priv->phydev;
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 oldadv, newadv;

	if (!phydev)
		return -ENODEV;

	if (!(phydev->supported & SUPPORTED_Pause) ||
	    (!(phydev->supported & SUPPORTED_Asym_Pause) &&
	     (epause->rx_pause != epause->tx_pause)))
		return -EINVAL;

	priv->rx_pause_en = priv->tx_pause_en = 0;
	if (epause->rx_pause) {
		priv->rx_pause_en = 1;

		if (epause->tx_pause) {
			priv->tx_pause_en = 1;
			/* FLOW_CTRL_RX & TX */
			newadv = ADVERTISED_Pause;
		} else  /* FLOW_CTLR_RX */
			newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
	} else if (epause->tx_pause) {
		priv->tx_pause_en = 1;
		/* FLOW_CTLR_TX */
		newadv = ADVERTISED_Asym_Pause;
	} else
		newadv = 0;

	if (epause->autoneg)
		priv->pause_aneg_en = 1;
	else
		priv->pause_aneg_en = 0;

	oldadv = phydev->advertising &
		(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
	if (oldadv != newadv) {
		phydev->advertising &=
			~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
		phydev->advertising |= newadv;
		if (phydev->autoneg)
			/* inform link partner of our
			 * new flow ctrl settings
			 */
			return phy_start_aneg(phydev);

		if (!epause->autoneg) {
			u32 tempval;
			tempval = gfar_read(&regs->maccfg1);
			tempval &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);

			priv->tx_actual_en = 0;
			if (priv->tx_pause_en) {
				priv->tx_actual_en = 1;
				tempval |= MACCFG1_TX_FLOW;
			}

			if (priv->rx_pause_en)
				tempval |= MACCFG1_RX_FLOW;
			gfar_write(&regs->maccfg1, tempval);
		}
	}

	return 0;
}