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 /drivers | |
| 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
Diffstat (limited to 'drivers')
| -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 | } |
