diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-15 18:31:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-15 18:31:37 -0400 |
commit | b810cdfcf91d76f603fd48023aede48ced8e6bed (patch) | |
tree | 6b2dd0608c0241f29ac1e84fa7b629a1a0f5ceb9 | |
parent | e7b0d26a86943370c04d6833c6edba2a72a6e240 (diff) | |
parent | d2a900365b8963d7ca46f05d8e7176d1be3cc71d (diff) |
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
-rw-r--r-- | drivers/net/natsemi.c | 58 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 1 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 1 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 5 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 11 | ||||
-rw-r--r-- | drivers/net/skge.c | 28 |
6 files changed, 63 insertions, 41 deletions
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index c6172a77a6d7..349b96a3ec4c 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -1712,7 +1712,7 @@ static void init_registers(struct net_device *dev) | |||
1712 | 1712 | ||
1713 | /* Enable interrupts by setting the interrupt mask. */ | 1713 | /* Enable interrupts by setting the interrupt mask. */ |
1714 | writel(DEFAULT_INTR, ioaddr + IntrMask); | 1714 | writel(DEFAULT_INTR, ioaddr + IntrMask); |
1715 | writel(1, ioaddr + IntrEnable); | 1715 | natsemi_irq_enable(dev); |
1716 | 1716 | ||
1717 | writel(RxOn | TxOn, ioaddr + ChipCmd); | 1717 | writel(RxOn | TxOn, ioaddr + ChipCmd); |
1718 | writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */ | 1718 | writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */ |
@@ -2119,28 +2119,35 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) | |||
2119 | struct netdev_private *np = netdev_priv(dev); | 2119 | struct netdev_private *np = netdev_priv(dev); |
2120 | void __iomem * ioaddr = ns_ioaddr(dev); | 2120 | void __iomem * ioaddr = ns_ioaddr(dev); |
2121 | 2121 | ||
2122 | if (np->hands_off) | 2122 | /* Reading IntrStatus automatically acknowledges so don't do |
2123 | * that while interrupts are disabled, (for example, while a | ||
2124 | * poll is scheduled). */ | ||
2125 | if (np->hands_off || !readl(ioaddr + IntrEnable)) | ||
2123 | return IRQ_NONE; | 2126 | return IRQ_NONE; |
2124 | 2127 | ||
2125 | /* Reading automatically acknowledges. */ | ||
2126 | np->intr_status = readl(ioaddr + IntrStatus); | 2128 | np->intr_status = readl(ioaddr + IntrStatus); |
2127 | 2129 | ||
2130 | if (!np->intr_status) | ||
2131 | return IRQ_NONE; | ||
2132 | |||
2128 | if (netif_msg_intr(np)) | 2133 | if (netif_msg_intr(np)) |
2129 | printk(KERN_DEBUG | 2134 | printk(KERN_DEBUG |
2130 | "%s: Interrupt, status %#08x, mask %#08x.\n", | 2135 | "%s: Interrupt, status %#08x, mask %#08x.\n", |
2131 | dev->name, np->intr_status, | 2136 | dev->name, np->intr_status, |
2132 | readl(ioaddr + IntrMask)); | 2137 | readl(ioaddr + IntrMask)); |
2133 | 2138 | ||
2134 | if (!np->intr_status) | ||
2135 | return IRQ_NONE; | ||
2136 | |||
2137 | prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); | 2139 | prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); |
2138 | 2140 | ||
2139 | if (netif_rx_schedule_prep(dev)) { | 2141 | if (netif_rx_schedule_prep(dev)) { |
2140 | /* Disable interrupts and register for poll */ | 2142 | /* Disable interrupts and register for poll */ |
2141 | natsemi_irq_disable(dev); | 2143 | natsemi_irq_disable(dev); |
2142 | __netif_rx_schedule(dev); | 2144 | __netif_rx_schedule(dev); |
2143 | } | 2145 | } else |
2146 | printk(KERN_WARNING | ||
2147 | "%s: Ignoring interrupt, status %#08x, mask %#08x.\n", | ||
2148 | dev->name, np->intr_status, | ||
2149 | readl(ioaddr + IntrMask)); | ||
2150 | |||
2144 | return IRQ_HANDLED; | 2151 | return IRQ_HANDLED; |
2145 | } | 2152 | } |
2146 | 2153 | ||
@@ -2156,6 +2163,20 @@ static int natsemi_poll(struct net_device *dev, int *budget) | |||
2156 | int work_done = 0; | 2163 | int work_done = 0; |
2157 | 2164 | ||
2158 | do { | 2165 | do { |
2166 | if (netif_msg_intr(np)) | ||
2167 | printk(KERN_DEBUG | ||
2168 | "%s: Poll, status %#08x, mask %#08x.\n", | ||
2169 | dev->name, np->intr_status, | ||
2170 | readl(ioaddr + IntrMask)); | ||
2171 | |||
2172 | /* netdev_rx() may read IntrStatus again if the RX state | ||
2173 | * machine falls over so do it first. */ | ||
2174 | if (np->intr_status & | ||
2175 | (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | | ||
2176 | IntrRxErr | IntrRxOverrun)) { | ||
2177 | netdev_rx(dev, &work_done, work_to_do); | ||
2178 | } | ||
2179 | |||
2159 | if (np->intr_status & | 2180 | if (np->intr_status & |
2160 | (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { | 2181 | (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { |
2161 | spin_lock(&np->lock); | 2182 | spin_lock(&np->lock); |
@@ -2167,12 +2188,6 @@ static int natsemi_poll(struct net_device *dev, int *budget) | |||
2167 | if (np->intr_status & IntrAbnormalSummary) | 2188 | if (np->intr_status & IntrAbnormalSummary) |
2168 | netdev_error(dev, np->intr_status); | 2189 | netdev_error(dev, np->intr_status); |
2169 | 2190 | ||
2170 | if (np->intr_status & | ||
2171 | (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | | ||
2172 | IntrRxErr | IntrRxOverrun)) { | ||
2173 | netdev_rx(dev, &work_done, work_to_do); | ||
2174 | } | ||
2175 | |||
2176 | *budget -= work_done; | 2191 | *budget -= work_done; |
2177 | dev->quota -= work_done; | 2192 | dev->quota -= work_done; |
2178 | 2193 | ||
@@ -2399,19 +2414,8 @@ static struct net_device_stats *get_stats(struct net_device *dev) | |||
2399 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2414 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2400 | static void natsemi_poll_controller(struct net_device *dev) | 2415 | static void natsemi_poll_controller(struct net_device *dev) |
2401 | { | 2416 | { |
2402 | struct netdev_private *np = netdev_priv(dev); | ||
2403 | |||
2404 | disable_irq(dev->irq); | 2417 | disable_irq(dev->irq); |
2405 | 2418 | intr_handler(dev->irq, dev); | |
2406 | /* | ||
2407 | * A real interrupt might have already reached us at this point | ||
2408 | * but NAPI might still haven't called us back. As the interrupt | ||
2409 | * status register is cleared by reading, we should prevent an | ||
2410 | * interrupt loss in this case... | ||
2411 | */ | ||
2412 | if (!np->intr_status) | ||
2413 | intr_handler(dev->irq, dev); | ||
2414 | |||
2415 | enable_irq(dev->irq); | 2419 | enable_irq(dev->irq); |
2416 | } | 2420 | } |
2417 | #endif | 2421 | #endif |
@@ -3071,7 +3075,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr) | |||
3071 | * Could be used to send a netlink message. | 3075 | * Could be used to send a netlink message. |
3072 | */ | 3076 | */ |
3073 | writel(WOLPkt | LinkChange, ioaddr + IntrMask); | 3077 | writel(WOLPkt | LinkChange, ioaddr + IntrMask); |
3074 | writel(1, ioaddr + IntrEnable); | 3078 | natsemi_irq_enable(dev); |
3075 | } | 3079 | } |
3076 | } | 3080 | } |
3077 | 3081 | ||
@@ -3202,7 +3206,7 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state) | |||
3202 | disable_irq(dev->irq); | 3206 | disable_irq(dev->irq); |
3203 | spin_lock_irq(&np->lock); | 3207 | spin_lock_irq(&np->lock); |
3204 | 3208 | ||
3205 | writel(0, ioaddr + IntrEnable); | 3209 | natsemi_irq_disable(dev); |
3206 | np->hands_off = 1; | 3210 | np->hands_off = 1; |
3207 | natsemi_stop_rxtx(dev); | 3211 | natsemi_stop_rxtx(dev); |
3208 | netif_stop_queue(dev); | 3212 | netif_stop_queue(dev); |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 81742e4e5610..dd8ce35332fe 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -232,6 +232,7 @@ enum { | |||
232 | #define MPORT_SINGLE_FUNCTION_MODE 0x1111 | 232 | #define MPORT_SINGLE_FUNCTION_MODE 0x1111 |
233 | 233 | ||
234 | extern unsigned long long netxen_dma_mask; | 234 | extern unsigned long long netxen_dma_mask; |
235 | extern unsigned long last_schedule_time; | ||
235 | 236 | ||
236 | /* | 237 | /* |
237 | * NetXen host-peg signal message structure | 238 | * NetXen host-peg signal message structure |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 986ef98db229..ee1b5a24cbe7 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -462,6 +462,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
462 | } | 462 | } |
463 | printk(KERN_INFO "%s: flash unlocked. \n", | 463 | printk(KERN_INFO "%s: flash unlocked. \n", |
464 | netxen_nic_driver_name); | 464 | netxen_nic_driver_name); |
465 | last_schedule_time = jiffies; | ||
465 | ret = netxen_flash_erase_secondary(adapter); | 466 | ret = netxen_flash_erase_secondary(adapter); |
466 | if (ret != FLASH_SUCCESS) { | 467 | if (ret != FLASH_SUCCESS) { |
467 | printk(KERN_ERR "%s: Flash erase failed.\n", | 468 | printk(KERN_ERR "%s: Flash erase failed.\n", |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 1be55702557d..6537574a9cda 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -822,7 +822,10 @@ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu) | |||
822 | { | 822 | { |
823 | struct netxen_adapter *adapter = port->adapter; | 823 | struct netxen_adapter *adapter = port->adapter; |
824 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; | 824 | new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; |
825 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); | 825 | if (port->portnum == 0) |
826 | netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); | ||
827 | else if (port->portnum == 1) | ||
828 | netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); | ||
826 | return 0; | 829 | return 0; |
827 | } | 830 | } |
828 | 831 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 586d32b676af..229aa1c4fb79 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -42,6 +42,8 @@ struct crb_addr_pair { | |||
42 | u32 data; | 42 | u32 data; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | unsigned long last_schedule_time; | ||
46 | |||
45 | #define NETXEN_MAX_CRB_XFORM 60 | 47 | #define NETXEN_MAX_CRB_XFORM 60 |
46 | static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; | 48 | static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; |
47 | #define NETXEN_ADDR_ERROR (0xffffffff) | 49 | #define NETXEN_ADDR_ERROR (0xffffffff) |
@@ -404,9 +406,14 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, | |||
404 | static inline int | 406 | static inline int |
405 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | 407 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) |
406 | { | 408 | { |
409 | if (jiffies > (last_schedule_time + (8 * HZ))) { | ||
410 | last_schedule_time = jiffies; | ||
411 | schedule(); | ||
412 | } | ||
413 | |||
407 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); | 414 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); |
408 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); | 415 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); |
409 | udelay(70); /* prevent bursting on CRB */ | 416 | udelay(100); /* prevent bursting on CRB */ |
410 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); | 417 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); |
411 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); | 418 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); |
412 | if (netxen_wait_rom_done(adapter)) { | 419 | if (netxen_wait_rom_done(adapter)) { |
@@ -415,7 +422,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
415 | } | 422 | } |
416 | /* reset abyte_cnt and dummy_byte_cnt */ | 423 | /* reset abyte_cnt and dummy_byte_cnt */ |
417 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); | 424 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); |
418 | udelay(70); /* prevent bursting on CRB */ | 425 | udelay(100); /* prevent bursting on CRB */ |
419 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); | 426 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); |
420 | 427 | ||
421 | *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); | 428 | *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index eea75a401b0c..8fecf1b817f7 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -3275,24 +3275,30 @@ static int skge_set_mac_address(struct net_device *dev, void *p) | |||
3275 | struct skge_hw *hw = skge->hw; | 3275 | struct skge_hw *hw = skge->hw; |
3276 | unsigned port = skge->port; | 3276 | unsigned port = skge->port; |
3277 | const struct sockaddr *addr = p; | 3277 | const struct sockaddr *addr = p; |
3278 | u16 ctrl; | ||
3278 | 3279 | ||
3279 | if (!is_valid_ether_addr(addr->sa_data)) | 3280 | if (!is_valid_ether_addr(addr->sa_data)) |
3280 | return -EADDRNOTAVAIL; | 3281 | return -EADDRNOTAVAIL; |
3281 | 3282 | ||
3282 | mutex_lock(&hw->phy_mutex); | ||
3283 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 3283 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
3284 | memcpy_toio(hw->regs + B2_MAC_1 + port*8, | ||
3285 | dev->dev_addr, ETH_ALEN); | ||
3286 | memcpy_toio(hw->regs + B2_MAC_2 + port*8, | ||
3287 | dev->dev_addr, ETH_ALEN); | ||
3288 | 3284 | ||
3289 | if (hw->chip_id == CHIP_ID_GENESIS) | 3285 | /* disable Rx */ |
3290 | xm_outaddr(hw, port, XM_SA, dev->dev_addr); | 3286 | ctrl = gma_read16(hw, port, GM_GP_CTRL); |
3291 | else { | 3287 | gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA); |
3292 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); | 3288 | |
3293 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); | 3289 | memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN); |
3290 | memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN); | ||
3291 | |||
3292 | if (netif_running(dev)) { | ||
3293 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
3294 | xm_outaddr(hw, port, XM_SA, dev->dev_addr); | ||
3295 | else { | ||
3296 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); | ||
3297 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); | ||
3298 | } | ||
3294 | } | 3299 | } |
3295 | mutex_unlock(&hw->phy_mutex); | 3300 | |
3301 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | ||
3296 | 3302 | ||
3297 | return 0; | 3303 | return 0; |
3298 | } | 3304 | } |