Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7004405c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  Phonet: keep TX queue disabled when the device is off
  SCHED: netem: Correct documentation comment in code.
  netfilter: update rwlock initialization for nat_table
  netlabel: Compiler warning and NULL pointer dereference fix
  e1000e: fix double release of mutex
  IA64: HP_SIMETH needs to depend upon NET
  netpoll: fix race on poll_list resulting in garbage entry
  ipv6: silence log messages for locally generated multicast
  sungem: improve ethtool output with internal pcs and serdes
  tcp: tcp_vegas cong avoid fix 
  sungem: Make PCS PHY support partially work again.
parents d2ff9118 4798a2b8
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@ menu "HP Simulator drivers"


config HP_SIMETH
config HP_SIMETH
	bool "Simulated Ethernet "
	bool "Simulated Ethernet "
	depends on NET


config HP_SIMSERIAL
config HP_SIMSERIAL
	bool "Simulated serial driver support"
	bool "Simulated serial driver support"
+7 −2
Original line number Original line Diff line number Diff line
@@ -1893,12 +1893,17 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
		ctrl |= E1000_CTRL_PHY_RST;
		ctrl |= E1000_CTRL_PHY_RST;
	}
	}
	ret_val = e1000_acquire_swflag_ich8lan(hw);
	ret_val = e1000_acquire_swflag_ich8lan(hw);
	/* Whether or not the swflag was acquired, we need to reset the part */
	hw_dbg(hw, "Issuing a global reset to ich8lan");
	hw_dbg(hw, "Issuing a global reset to ich8lan");
	ew32(CTRL, (ctrl | E1000_CTRL_RST));
	ew32(CTRL, (ctrl | E1000_CTRL_RST));
	msleep(20);
	msleep(20);


	/* release the swflag because it is not reset by hardware reset */
	if (!ret_val) {
		/* release the swflag because it is not reset by
		 * hardware reset
		 */
		e1000_release_swflag_ich8lan(hw);
		e1000_release_swflag_ich8lan(hw);
	}


	ret_val = e1000e_get_auto_rd_done(hw);
	ret_val = e1000e_get_auto_rd_done(hw);
	if (ret_val) {
	if (ret_val) {
+88 −56
Original line number Original line Diff line number Diff line
@@ -1142,6 +1142,70 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
	return NETDEV_TX_OK;
	return NETDEV_TX_OK;
}
}


static void gem_pcs_reset(struct gem *gp)
{
	int limit;
	u32 val;

	/* Reset PCS unit. */
	val = readl(gp->regs + PCS_MIICTRL);
	val |= PCS_MIICTRL_RST;
	writel(val, gp->regs + PCS_MIICTRL);

	limit = 32;
	while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) {
		udelay(100);
		if (limit-- <= 0)
			break;
	}
	if (limit <= 0)
		printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
		       gp->dev->name);
}

static void gem_pcs_reinit_adv(struct gem *gp)
{
	u32 val;

	/* Make sure PCS is disabled while changing advertisement
	 * configuration.
	 */
	val = readl(gp->regs + PCS_CFG);
	val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO);
	writel(val, gp->regs + PCS_CFG);

	/* Advertise all capabilities except assymetric
	 * pause.
	 */
	val = readl(gp->regs + PCS_MIIADV);
	val |= (PCS_MIIADV_FD | PCS_MIIADV_HD |
		PCS_MIIADV_SP | PCS_MIIADV_AP);
	writel(val, gp->regs + PCS_MIIADV);

	/* Enable and restart auto-negotiation, disable wrapback/loopback,
	 * and re-enable PCS.
	 */
	val = readl(gp->regs + PCS_MIICTRL);
	val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE);
	val &= ~PCS_MIICTRL_WB;
	writel(val, gp->regs + PCS_MIICTRL);

	val = readl(gp->regs + PCS_CFG);
	val |= PCS_CFG_ENABLE;
	writel(val, gp->regs + PCS_CFG);

	/* Make sure serialink loopback is off.  The meaning
	 * of this bit is logically inverted based upon whether
	 * you are in Serialink or SERDES mode.
	 */
	val = readl(gp->regs + PCS_SCTRL);
	if (gp->phy_type == phy_serialink)
		val &= ~PCS_SCTRL_LOOP;
	else
		val |= PCS_SCTRL_LOOP;
	writel(val, gp->regs + PCS_SCTRL);
}

#define STOP_TRIES 32
#define STOP_TRIES 32


/* Must be invoked under gp->lock and gp->tx_lock. */
/* Must be invoked under gp->lock and gp->tx_lock. */
@@ -1168,6 +1232,9 @@ static void gem_reset(struct gem *gp)


	if (limit <= 0)
	if (limit <= 0)
		printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);
		printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name);

	if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes)
		gem_pcs_reinit_adv(gp);
}
}


/* Must be invoked under gp->lock and gp->tx_lock. */
/* Must be invoked under gp->lock and gp->tx_lock. */
@@ -1324,7 +1391,7 @@ static int gem_set_link_modes(struct gem *gp)
	    	   gp->phy_type == phy_serdes) {
	    	   gp->phy_type == phy_serdes) {
		u32 pcs_lpa = readl(gp->regs + PCS_MIILP);
		u32 pcs_lpa = readl(gp->regs + PCS_MIILP);


		if (pcs_lpa & PCS_MIIADV_FD)
		if ((pcs_lpa & PCS_MIIADV_FD) || gp->phy_type == phy_serdes)
			full_duplex = 1;
			full_duplex = 1;
		speed = SPEED_1000;
		speed = SPEED_1000;
	}
	}
@@ -1488,6 +1555,9 @@ static void gem_link_timer(unsigned long data)
			val = readl(gp->regs + PCS_MIISTAT);
			val = readl(gp->regs + PCS_MIISTAT);


		if ((val & PCS_MIISTAT_LS) != 0) {
		if ((val & PCS_MIISTAT_LS) != 0) {
			if (gp->lstate == link_up)
				goto restart;

			gp->lstate = link_up;
			gp->lstate = link_up;
			netif_carrier_on(gp->dev);
			netif_carrier_on(gp->dev);
			(void)gem_set_link_modes(gp);
			(void)gem_set_link_modes(gp);
@@ -1708,61 +1778,8 @@ static void gem_init_phy(struct gem *gp)
		if (gp->phy_mii.def && gp->phy_mii.def->ops->init)
		if (gp->phy_mii.def && gp->phy_mii.def->ops->init)
			gp->phy_mii.def->ops->init(&gp->phy_mii);
			gp->phy_mii.def->ops->init(&gp->phy_mii);
	} else {
	} else {
		u32 val;
		gem_pcs_reset(gp);
		int limit;
		gem_pcs_reinit_adv(gp);

		/* Reset PCS unit. */
		val = readl(gp->regs + PCS_MIICTRL);
		val |= PCS_MIICTRL_RST;
		writel(val, gp->regs + PCS_MIICTRL);

		limit = 32;
		while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) {
			udelay(100);
			if (limit-- <= 0)
				break;
		}
		if (limit <= 0)
			printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
			       gp->dev->name);

		/* Make sure PCS is disabled while changing advertisement
		 * configuration.
		 */
		val = readl(gp->regs + PCS_CFG);
		val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO);
		writel(val, gp->regs + PCS_CFG);

		/* Advertise all capabilities except assymetric
		 * pause.
		 */
		val = readl(gp->regs + PCS_MIIADV);
		val |= (PCS_MIIADV_FD | PCS_MIIADV_HD |
			PCS_MIIADV_SP | PCS_MIIADV_AP);
		writel(val, gp->regs + PCS_MIIADV);

		/* Enable and restart auto-negotiation, disable wrapback/loopback,
		 * and re-enable PCS.
		 */
		val = readl(gp->regs + PCS_MIICTRL);
		val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE);
		val &= ~PCS_MIICTRL_WB;
		writel(val, gp->regs + PCS_MIICTRL);

		val = readl(gp->regs + PCS_CFG);
		val |= PCS_CFG_ENABLE;
		writel(val, gp->regs + PCS_CFG);

		/* Make sure serialink loopback is off.  The meaning
		 * of this bit is logically inverted based upon whether
		 * you are in Serialink or SERDES mode.
		 */
		val = readl(gp->regs + PCS_SCTRL);
		if (gp->phy_type == phy_serialink)
			val &= ~PCS_SCTRL_LOOP;
		else
			val |= PCS_SCTRL_LOOP;
		writel(val, gp->regs + PCS_SCTRL);
	}
	}


	/* Default aneg parameters */
	/* Default aneg parameters */
@@ -2680,6 +2697,21 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
		cmd->speed = 0;
		cmd->speed = 0;
		cmd->duplex = cmd->port = cmd->phy_address =
		cmd->duplex = cmd->port = cmd->phy_address =
			cmd->transceiver = cmd->autoneg = 0;
			cmd->transceiver = cmd->autoneg = 0;

		/* serdes means usually a Fibre connector, with most fixed */
		if (gp->phy_type == phy_serdes) {
			cmd->port = PORT_FIBRE;
			cmd->supported = (SUPPORTED_1000baseT_Half |
				SUPPORTED_1000baseT_Full |
				SUPPORTED_FIBRE | SUPPORTED_Autoneg |
				SUPPORTED_Pause | SUPPORTED_Asym_Pause);
			cmd->advertising = cmd->supported;
			cmd->transceiver = XCVR_INTERNAL;
			if (gp->lstate == link_up)
				cmd->speed = SPEED_1000;
			cmd->duplex = DUPLEX_FULL;
			cmd->autoneg = 1;
		}
	}
	}
	cmd->maxtxpkt = cmd->maxrxpkt = 0;
	cmd->maxtxpkt = cmd->maxrxpkt = 0;


+7 −0
Original line number Original line Diff line number Diff line
@@ -319,6 +319,7 @@ enum
{
{
	NAPI_STATE_SCHED,	/* Poll is scheduled */
	NAPI_STATE_SCHED,	/* Poll is scheduled */
	NAPI_STATE_DISABLE,	/* Disable pending */
	NAPI_STATE_DISABLE,	/* Disable pending */
	NAPI_STATE_NPSVC,	/* Netpoll - don't dequeue from poll_list */
};
};


extern void __napi_schedule(struct napi_struct *n);
extern void __napi_schedule(struct napi_struct *n);
@@ -1497,6 +1498,12 @@ static inline void netif_rx_complete(struct net_device *dev,
{
{
	unsigned long flags;
	unsigned long flags;


	/*
	 * don't let napi dequeue from the cpu poll list
	 * just in case its running on a different cpu
	 */
	if (unlikely(test_bit(NAPI_STATE_NPSVC, &napi->state)))
		return;
	local_irq_save(flags);
	local_irq_save(flags);
	__netif_rx_complete(dev, napi);
	__netif_rx_complete(dev, napi);
	local_irq_restore(flags);
	local_irq_restore(flags);
+2 −0
Original line number Original line Diff line number Diff line
@@ -133,9 +133,11 @@ static int poll_one_napi(struct netpoll_info *npinfo,


	npinfo->rx_flags |= NETPOLL_RX_DROP;
	npinfo->rx_flags |= NETPOLL_RX_DROP;
	atomic_inc(&trapped);
	atomic_inc(&trapped);
	set_bit(NAPI_STATE_NPSVC, &napi->state);


	work = napi->poll(napi, budget);
	work = napi->poll(napi, budget);


	clear_bit(NAPI_STATE_NPSVC, &napi->state);
	atomic_dec(&trapped);
	atomic_dec(&trapped);
	npinfo->rx_flags &= ~NETPOLL_RX_DROP;
	npinfo->rx_flags &= ~NETPOLL_RX_DROP;


Loading