diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/Kconfig | 4 | ||||
-rw-r--r-- | drivers/char/mxser.c | 1 | ||||
-rw-r--r-- | drivers/char/rtc.c | 5 | ||||
-rw-r--r-- | drivers/net/tg3.c | 178 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2200.h | 1 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 10 |
6 files changed, 131 insertions, 68 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index df5f2b0e075..a1de06d76de 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -175,7 +175,7 @@ config MOXA_INTELLIO config MOXA_SMARTIO tristate "Moxa SmartIO support" - depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32) + depends on SERIAL_NONSTANDARD help Say Y here if you have a Moxa SmartIO multiport serial card. @@ -735,7 +735,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 + depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 && !SPARC64 ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index f022f094443..d0ef1ae4129 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -63,7 +63,6 @@ #include <asm/system.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/segment.h> #include <asm/bitops.h> #include <asm/uaccess.h> diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index cd4fe8b1709..63fff7c1244 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -938,10 +938,9 @@ found: /* * XXX Interrupt pin #7 in Espresso is shared between RTC and - * PCI Slot 2 INTA# (and some INTx# in Slot 1). SA_INTERRUPT here - * is asking for trouble with add-on boards. Change to SA_SHIRQ. + * PCI Slot 2 INTA# (and some INTx# in Slot 1). */ - if (request_irq(rtc_irq, rtc_interrupt, SA_INTERRUPT, "rtc", (void *)&rtc_port)) { + if (request_irq(rtc_irq, rtc_interrupt, SA_SHIRQ, "rtc", (void *)&rtc_port)) { /* * Standard way for sparc to print irq's is to use * __irq_itoa(). I think for EBus it's ok to use %d. diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3faf62310f8..dc57352e5a9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -36,6 +36,7 @@ #include <linux/ip.h> #include <linux/tcp.h> #include <linux/workqueue.h> +#include <linux/prefetch.h> #include <net/checksum.h> @@ -66,8 +67,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.38" -#define DRV_MODULE_RELDATE "September 1, 2005" +#define DRV_MODULE_VERSION "3.39" +#define DRV_MODULE_RELDATE "September 5, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -487,7 +488,8 @@ static void tg3_disable_ints(struct tg3 *tp) static inline void tg3_cond_int(struct tg3 *tp) { - if (tp->hw_status->status & SD_STATUS_UPDATED) + if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && + (tp->hw_status->status & SD_STATUS_UPDATED)) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); } @@ -3219,18 +3221,17 @@ static int tg3_poll(struct net_device *netdev, int *budget) netdev->quota -= work_done; } - if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { tp->last_tag = sblk->status_tag; - rmb(); - sblk->status &= ~SD_STATUS_UPDATED; + rmb(); + } else + sblk->status &= ~SD_STATUS_UPDATED; /* if no more work, tell net stack and NIC we're done */ done = !tg3_has_work(tp); if (done) { - spin_lock(&tp->lock); netif_rx_complete(netdev); tg3_restart_ints(tp); - spin_unlock(&tp->lock); } return (done ? 0 : 1); @@ -3278,8 +3279,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct tg3 *tp = netdev_priv(dev); - struct tg3_hw_status *sblk = tp->hw_status; + prefetch(tp->hw_status); + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); /* * Writing any value to intr-mbox-0 clears PCI INTA# and * chip-internal interrupt pending events. @@ -3288,19 +3290,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) * event coalescing. */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); - tp->last_tag = sblk->status_tag; - rmb(); - if (tg3_irq_sync(tp)) - goto out; - sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) + if (likely(!tg3_irq_sync(tp))) netif_rx_schedule(dev); /* schedule NAPI poll */ - else { - /* No work, re-enable interrupts. */ - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - tp->last_tag << 24); - } -out: + return IRQ_RETVAL(1); } @@ -3330,9 +3322,10 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (tg3_irq_sync(tp)) goto out; sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) + if (likely(tg3_has_work(tp))) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); netif_rx_schedule(dev); /* schedule NAPI poll */ - else { + } else { /* No work, shared interrupt perhaps? re-enable * interrupts, and flush that PCI write */ @@ -3358,7 +3351,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if ((sblk->status & SD_STATUS_UPDATED) || + if ((sblk->status_tag != tp->last_tag) || !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { /* * writing any value to intr-mbox-0 clears PCI INTA# and @@ -3369,19 +3362,17 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); - tp->last_tag = sblk->status_tag; - rmb(); if (tg3_irq_sync(tp)) goto out; - sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) - netif_rx_schedule(dev); /* schedule NAPI poll */ - else { - /* no work, shared interrupt perhaps? re-enable - * interrupts, and flush that PCI write + if (netif_rx_schedule_prep(dev)) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + /* Update last_tag to mark that this status has been + * seen. Because interrupt may be shared, we may be + * racing with tg3_poll(), so only update last_tag + * if tg3_poll() is not scheduled. */ - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - tp->last_tag << 24); + tp->last_tag = sblk->status_tag; + __netif_rx_schedule(dev); } } else { /* shared interrupt */ handled = 0; @@ -5962,7 +5953,7 @@ static int tg3_reset_hw(struct tg3 *tp) tw32(MAC_LED_CTRL, tp->led_ctrl); tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); - if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); } @@ -6244,6 +6235,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (err) return err; + tp->hw_status->status &= ~SD_STATUS_UPDATED; tg3_enable_ints(tp); tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | @@ -7559,6 +7551,38 @@ static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) } } +static int tg3_phys_id(struct net_device *dev, u32 data) +{ + struct tg3 *tp = netdev_priv(dev); + int i; + + if (!netif_running(tp->dev)) + return -EAGAIN; + + if (data == 0) + data = 2; + + for (i = 0; i < (data * 2); i++) { + if ((i % 2) == 0) + tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | + LED_CTRL_1000MBPS_ON | + LED_CTRL_100MBPS_ON | + LED_CTRL_10MBPS_ON | + LED_CTRL_TRAFFIC_OVERRIDE | + LED_CTRL_TRAFFIC_BLINK | + LED_CTRL_TRAFFIC_LED); + + else + tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | + LED_CTRL_TRAFFIC_OVERRIDE); + + if (msleep_interruptible(500)) + break; + } + tw32(MAC_LED_CTRL, tp->led_ctrl); + return 0; +} + static void tg3_get_ethtool_stats (struct net_device *dev, struct ethtool_stats *estats, u64 *tmp_stats) { @@ -7618,7 +7642,7 @@ static int tg3_test_link(struct tg3 *tp) if (!netif_running(tp->dev)) return -ENODEV; - if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) max = TG3_SERDES_TIMEOUT_SEC; else max = TG3_COPPER_TIMEOUT_SEC; @@ -7903,9 +7927,12 @@ static int tg3_test_memory(struct tg3 *tp) return err; } -static int tg3_test_loopback(struct tg3 *tp) +#define TG3_MAC_LOOPBACK 0 +#define TG3_PHY_LOOPBACK 1 + +static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) { - u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; + u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key; u32 desc_idx; struct sk_buff *skb, *rx_skb; u8 *tx_data; @@ -7913,18 +7940,26 @@ static int tg3_test_loopback(struct tg3 *tp) int num_pkts, tx_len, rx_len, i, err; struct tg3_rx_buffer_desc *desc; - if (!netif_running(tp->dev)) - return -ENODEV; + if (loopback_mode == TG3_MAC_LOOPBACK) { + mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | + MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | + MAC_MODE_PORT_MODE_GMII; + tw32(MAC_MODE, mac_mode); + } else if (loopback_mode == TG3_PHY_LOOPBACK) { + mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | + MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) + mac_mode &= ~MAC_MODE_LINK_POLARITY; + tw32(MAC_MODE, mac_mode); + + tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | + BMCR_SPEED1000); + } + else + return -EINVAL; err = -EIO; - tg3_reset_hw(tp); - - mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | - MAC_MODE_PORT_MODE_GMII; - tw32(MAC_MODE, mac_mode); - tx_len = 1514; skb = dev_alloc_skb(tx_len); tx_data = skb_put(skb, tx_len); @@ -7945,15 +7980,15 @@ static int tg3_test_loopback(struct tg3 *tp) rx_start_idx = tp->hw_status->idx[0].rx_producer; - send_idx = 0; num_pkts = 0; - tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); + tg3_set_txd(tp, tp->tx_prod, map, tx_len, 0, 1); - send_idx++; + tp->tx_prod++; num_pkts++; - tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); + tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, + tp->tx_prod); tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); udelay(10); @@ -7966,7 +8001,7 @@ static int tg3_test_loopback(struct tg3 *tp) tx_idx = tp->hw_status->idx[0].tx_consumer; rx_idx = tp->hw_status->idx[0].rx_producer; - if ((tx_idx == send_idx) && + if ((tx_idx == tp->tx_prod) && (rx_idx == (rx_start_idx + num_pkts))) break; } @@ -7974,7 +8009,7 @@ static int tg3_test_loopback(struct tg3 *tp) pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); dev_kfree_skb(skb); - if (tx_idx != send_idx) + if (tx_idx != tp->tx_prod) goto out; if (rx_idx != rx_start_idx + num_pkts) @@ -8010,6 +8045,30 @@ out: return err; } +#define TG3_MAC_LOOPBACK_FAILED 1 +#define TG3_PHY_LOOPBACK_FAILED 2 +#define TG3_LOOPBACK_FAILED (TG3_MAC_LOOPBACK_FAILED | \ + TG3_PHY_LOOPBACK_FAILED) + +static int tg3_test_loopback(struct tg3 *tp) +{ + int err = 0; + + if (!netif_running(tp->dev)) + return TG3_LOOPBACK_FAILED; + + tg3_reset_hw(tp); + + if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) + err |= TG3_MAC_LOOPBACK_FAILED; + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK)) + err |= TG3_PHY_LOOPBACK_FAILED; + } + + return err; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { @@ -8050,10 +8109,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, etest->flags |= ETH_TEST_FL_FAILED; data[3] = 1; } - if (tg3_test_loopback(tp) != 0) { + if ((data[4] = tg3_test_loopback(tp)) != 0) etest->flags |= ETH_TEST_FL_FAILED; - data[4] = 1; - } tg3_full_unlock(tp); @@ -8241,6 +8298,7 @@ static struct ethtool_ops tg3_ethtool_ops = { .self_test_count = tg3_get_test_count, .self_test = tg3_self_test, .get_strings = tg3_get_strings, + .phys_id = tg3_phys_id, .get_stats_count = tg3_get_stats_count, .get_ethtool_stats = tg3_get_ethtool_stats, .get_coalesce = tg3_get_coalesce, @@ -8305,7 +8363,8 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp) tw32(NVRAM_CFG1, nvcfg1); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) { switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: tp->nvram_jedecnum = JEDEC_ATMEL; @@ -8719,8 +8778,9 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, if (i == (len - 4)) nvram_cmd |= NVRAM_CMD_LAST; - if ((tp->nvram_jedecnum == JEDEC_ST) && - (nvram_cmd & NVRAM_CMD_FIRST)) { + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && + (tp->nvram_jedecnum == JEDEC_ST) && + (nvram_cmd & NVRAM_CMD_FIRST)) { if ((ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_WREN | NVRAM_CMD_GO | diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index 3bff09d9315..dc3e7bc805f 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h @@ -45,6 +45,7 @@ #include <linux/firmware.h> #include <linux/wireless.h> +#include <linux/dma-mapping.h> #include <asm/io.h> #include <net/ieee80211.h> diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 0cc879eb1c0..5959e6755a8 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -269,7 +269,10 @@ static void sunsu_stop_tx(struct uart_port *port) __stop_tx(up); - if (up->port.type == PORT_16C950 && tty_stop /*FIXME*/) { + /* + * We really want to stop the transmitter from sending. + */ + if (up->port.type == PORT_16C950) { up->acr |= UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -283,10 +286,11 @@ static void sunsu_start_tx(struct uart_port *port) up->ier |= UART_IER_THRI; serial_out(up, UART_IER, up->ier); } + /* - * We only do this from uart_start + * Re-enable the transmitter if we disabled it. */ - if (tty_start && up->port.type == PORT_16C950 /*FIXME*/) { + if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } |