Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: natsemi: Avoid IntrStatus lossage if RX state machine resets. natsemi: Fix NAPI for interrupt sharing natsemi: Consistently use interrupt enable/disable functions NetXen: Fix softlockup seen during hardware access NetXen: Bug fix for Jumbo frames on XG card skge: set mac address bonding fix
This commit is contained in:
commit
b810cdfcf9
@ -1712,7 +1712,7 @@ static void init_registers(struct net_device *dev)
|
|||||||
|
|
||||||
/* Enable interrupts by setting the interrupt mask. */
|
/* Enable interrupts by setting the interrupt mask. */
|
||||||
writel(DEFAULT_INTR, ioaddr + IntrMask);
|
writel(DEFAULT_INTR, ioaddr + IntrMask);
|
||||||
writel(1, ioaddr + IntrEnable);
|
natsemi_irq_enable(dev);
|
||||||
|
|
||||||
writel(RxOn | TxOn, ioaddr + ChipCmd);
|
writel(RxOn | TxOn, ioaddr + ChipCmd);
|
||||||
writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */
|
writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */
|
||||||
@ -2119,28 +2119,35 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
|
|||||||
struct netdev_private *np = netdev_priv(dev);
|
struct netdev_private *np = netdev_priv(dev);
|
||||||
void __iomem * ioaddr = ns_ioaddr(dev);
|
void __iomem * ioaddr = ns_ioaddr(dev);
|
||||||
|
|
||||||
if (np->hands_off)
|
/* Reading IntrStatus automatically acknowledges so don't do
|
||||||
|
* that while interrupts are disabled, (for example, while a
|
||||||
|
* poll is scheduled). */
|
||||||
|
if (np->hands_off || !readl(ioaddr + IntrEnable))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
/* Reading automatically acknowledges. */
|
|
||||||
np->intr_status = readl(ioaddr + IntrStatus);
|
np->intr_status = readl(ioaddr + IntrStatus);
|
||||||
|
|
||||||
|
if (!np->intr_status)
|
||||||
|
return IRQ_NONE;
|
||||||
|
|
||||||
if (netif_msg_intr(np))
|
if (netif_msg_intr(np))
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
"%s: Interrupt, status %#08x, mask %#08x.\n",
|
"%s: Interrupt, status %#08x, mask %#08x.\n",
|
||||||
dev->name, np->intr_status,
|
dev->name, np->intr_status,
|
||||||
readl(ioaddr + IntrMask));
|
readl(ioaddr + IntrMask));
|
||||||
|
|
||||||
if (!np->intr_status)
|
|
||||||
return IRQ_NONE;
|
|
||||||
|
|
||||||
prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
|
prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
|
||||||
|
|
||||||
if (netif_rx_schedule_prep(dev)) {
|
if (netif_rx_schedule_prep(dev)) {
|
||||||
/* Disable interrupts and register for poll */
|
/* Disable interrupts and register for poll */
|
||||||
natsemi_irq_disable(dev);
|
natsemi_irq_disable(dev);
|
||||||
__netif_rx_schedule(dev);
|
__netif_rx_schedule(dev);
|
||||||
}
|
} else
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
|
||||||
|
dev->name, np->intr_status,
|
||||||
|
readl(ioaddr + IntrMask));
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2156,6 +2163,20 @@ static int natsemi_poll(struct net_device *dev, int *budget)
|
|||||||
int work_done = 0;
|
int work_done = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (netif_msg_intr(np))
|
||||||
|
printk(KERN_DEBUG
|
||||||
|
"%s: Poll, status %#08x, mask %#08x.\n",
|
||||||
|
dev->name, np->intr_status,
|
||||||
|
readl(ioaddr + IntrMask));
|
||||||
|
|
||||||
|
/* netdev_rx() may read IntrStatus again if the RX state
|
||||||
|
* machine falls over so do it first. */
|
||||||
|
if (np->intr_status &
|
||||||
|
(IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
|
||||||
|
IntrRxErr | IntrRxOverrun)) {
|
||||||
|
netdev_rx(dev, &work_done, work_to_do);
|
||||||
|
}
|
||||||
|
|
||||||
if (np->intr_status &
|
if (np->intr_status &
|
||||||
(IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) {
|
(IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) {
|
||||||
spin_lock(&np->lock);
|
spin_lock(&np->lock);
|
||||||
@ -2167,12 +2188,6 @@ static int natsemi_poll(struct net_device *dev, int *budget)
|
|||||||
if (np->intr_status & IntrAbnormalSummary)
|
if (np->intr_status & IntrAbnormalSummary)
|
||||||
netdev_error(dev, np->intr_status);
|
netdev_error(dev, np->intr_status);
|
||||||
|
|
||||||
if (np->intr_status &
|
|
||||||
(IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
|
|
||||||
IntrRxErr | IntrRxOverrun)) {
|
|
||||||
netdev_rx(dev, &work_done, work_to_do);
|
|
||||||
}
|
|
||||||
|
|
||||||
*budget -= work_done;
|
*budget -= work_done;
|
||||||
dev->quota -= work_done;
|
dev->quota -= work_done;
|
||||||
|
|
||||||
@ -2399,19 +2414,8 @@ static struct net_device_stats *get_stats(struct net_device *dev)
|
|||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
static void natsemi_poll_controller(struct net_device *dev)
|
static void natsemi_poll_controller(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct netdev_private *np = netdev_priv(dev);
|
|
||||||
|
|
||||||
disable_irq(dev->irq);
|
disable_irq(dev->irq);
|
||||||
|
intr_handler(dev->irq, dev);
|
||||||
/*
|
|
||||||
* A real interrupt might have already reached us at this point
|
|
||||||
* but NAPI might still haven't called us back. As the interrupt
|
|
||||||
* status register is cleared by reading, we should prevent an
|
|
||||||
* interrupt loss in this case...
|
|
||||||
*/
|
|
||||||
if (!np->intr_status)
|
|
||||||
intr_handler(dev->irq, dev);
|
|
||||||
|
|
||||||
enable_irq(dev->irq);
|
enable_irq(dev->irq);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3071,7 +3075,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr)
|
|||||||
* Could be used to send a netlink message.
|
* Could be used to send a netlink message.
|
||||||
*/
|
*/
|
||||||
writel(WOLPkt | LinkChange, ioaddr + IntrMask);
|
writel(WOLPkt | LinkChange, ioaddr + IntrMask);
|
||||||
writel(1, ioaddr + IntrEnable);
|
natsemi_irq_enable(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3202,7 +3206,7 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
|
|||||||
disable_irq(dev->irq);
|
disable_irq(dev->irq);
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irq(&np->lock);
|
||||||
|
|
||||||
writel(0, ioaddr + IntrEnable);
|
natsemi_irq_disable(dev);
|
||||||
np->hands_off = 1;
|
np->hands_off = 1;
|
||||||
natsemi_stop_rxtx(dev);
|
natsemi_stop_rxtx(dev);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
@ -232,6 +232,7 @@ enum {
|
|||||||
#define MPORT_SINGLE_FUNCTION_MODE 0x1111
|
#define MPORT_SINGLE_FUNCTION_MODE 0x1111
|
||||||
|
|
||||||
extern unsigned long long netxen_dma_mask;
|
extern unsigned long long netxen_dma_mask;
|
||||||
|
extern unsigned long last_schedule_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NetXen host-peg signal message structure
|
* NetXen host-peg signal message structure
|
||||||
|
@ -462,6 +462,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
|
|||||||
}
|
}
|
||||||
printk(KERN_INFO "%s: flash unlocked. \n",
|
printk(KERN_INFO "%s: flash unlocked. \n",
|
||||||
netxen_nic_driver_name);
|
netxen_nic_driver_name);
|
||||||
|
last_schedule_time = jiffies;
|
||||||
ret = netxen_flash_erase_secondary(adapter);
|
ret = netxen_flash_erase_secondary(adapter);
|
||||||
if (ret != FLASH_SUCCESS) {
|
if (ret != FLASH_SUCCESS) {
|
||||||
printk(KERN_ERR "%s: Flash erase failed.\n",
|
printk(KERN_ERR "%s: Flash erase failed.\n",
|
||||||
|
@ -822,7 +822,10 @@ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu)
|
|||||||
{
|
{
|
||||||
struct netxen_adapter *adapter = port->adapter;
|
struct netxen_adapter *adapter = port->adapter;
|
||||||
new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
|
new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
|
||||||
netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
|
if (port->portnum == 0)
|
||||||
|
netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
|
||||||
|
else if (port->portnum == 1)
|
||||||
|
netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ struct crb_addr_pair {
|
|||||||
u32 data;
|
u32 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned long last_schedule_time;
|
||||||
|
|
||||||
#define NETXEN_MAX_CRB_XFORM 60
|
#define NETXEN_MAX_CRB_XFORM 60
|
||||||
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
|
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
|
||||||
#define NETXEN_ADDR_ERROR (0xffffffff)
|
#define NETXEN_ADDR_ERROR (0xffffffff)
|
||||||
@ -404,9 +406,14 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
|
|||||||
static inline int
|
static inline int
|
||||||
do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
|
do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
|
||||||
{
|
{
|
||||||
|
if (jiffies > (last_schedule_time + (8 * HZ))) {
|
||||||
|
last_schedule_time = jiffies;
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
|
||||||
udelay(70); /* prevent bursting on CRB */
|
udelay(100); /* prevent bursting on CRB */
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
|
||||||
if (netxen_wait_rom_done(adapter)) {
|
if (netxen_wait_rom_done(adapter)) {
|
||||||
@ -415,7 +422,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
|
|||||||
}
|
}
|
||||||
/* reset abyte_cnt and dummy_byte_cnt */
|
/* reset abyte_cnt and dummy_byte_cnt */
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
|
||||||
udelay(70); /* prevent bursting on CRB */
|
udelay(100); /* prevent bursting on CRB */
|
||||||
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
|
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
|
||||||
|
|
||||||
*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
|
*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
|
||||||
|
@ -3275,24 +3275,30 @@ static int skge_set_mac_address(struct net_device *dev, void *p)
|
|||||||
struct skge_hw *hw = skge->hw;
|
struct skge_hw *hw = skge->hw;
|
||||||
unsigned port = skge->port;
|
unsigned port = skge->port;
|
||||||
const struct sockaddr *addr = p;
|
const struct sockaddr *addr = p;
|
||||||
|
u16 ctrl;
|
||||||
|
|
||||||
if (!is_valid_ether_addr(addr->sa_data))
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
mutex_lock(&hw->phy_mutex);
|
|
||||||
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
||||||
memcpy_toio(hw->regs + B2_MAC_1 + port*8,
|
|
||||||
dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy_toio(hw->regs + B2_MAC_2 + port*8,
|
|
||||||
dev->dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
if (hw->chip_id == CHIP_ID_GENESIS)
|
/* disable Rx */
|
||||||
xm_outaddr(hw, port, XM_SA, dev->dev_addr);
|
ctrl = gma_read16(hw, port, GM_GP_CTRL);
|
||||||
else {
|
gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA);
|
||||||
gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
|
|
||||||
gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
|
memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
|
||||||
|
memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
|
||||||
|
|
||||||
|
if (netif_running(dev)) {
|
||||||
|
if (hw->chip_id == CHIP_ID_GENESIS)
|
||||||
|
xm_outaddr(hw, port, XM_SA, dev->dev_addr);
|
||||||
|
else {
|
||||||
|
gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
|
||||||
|
gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&hw->phy_mutex);
|
|
||||||
|
gma_write16(hw, port, GM_GP_CTRL, ctrl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user