Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934068AbXKPSsk (ORCPT ); Fri, 16 Nov 2007 13:48:40 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S933891AbXKPSsZ (ORCPT ); Fri, 16 Nov 2007 13:48:25 -0500 Received: from pentafluge.infradead.org ([213.146.154.40]:38243 "EHLO pentafluge.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933573AbXKPSsW (ORCPT ); Fri, 16 Nov 2007 13:48:22 -0500 Date: Fri, 16 Nov 2007 10:47:33 -0800 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, Andrew Morton , torvalds@linux-foundation.org, stable@kernel.org Subject: Re: Linux 2.6.23.5 Message-ID: <20071116184733.GJ9807@kroah.com> References: <20071116183752.GA9807@kroah.com> <20071116184721.GI9807@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20071116184721.GI9807@kroah.com> User-Agent: Mutt/1.5.16 (2007-06-09) Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 33013 Lines: 967 diff --git a/Makefile b/Makefile index 0c34409..e11814e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 23 -EXTRAVERSION = .4 +EXTRAVERSION = .5 NAME = Arr Matey! A Hairy Bilge Rat! # *DOCUMENTATION* diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index c82e245..329a252 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -563,8 +563,7 @@ int ehea_destroy_qp(struct ehea_qp *qp) int ehea_create_busmap( void ) { u64 vaddr = EHEA_BUSMAP_START; - unsigned long abs_max_pfn = 0; - unsigned long sec_max_pfn; + unsigned long high_section_index = 0; int i; /* @@ -574,14 +573,10 @@ int ehea_create_busmap( void ) ehea_bmap.valid_sections = 0; for (i = 0; i < NR_MEM_SECTIONS; i++) - if (valid_section_nr(i)) { - sec_max_pfn = section_nr_to_pfn(i); - if (sec_max_pfn > abs_max_pfn) - abs_max_pfn = sec_max_pfn; - ehea_bmap.valid_sections++; - } + if (valid_section_nr(i)) + high_section_index = i; - ehea_bmap.entries = abs_max_pfn / EHEA_PAGES_PER_SECTION + 1; + ehea_bmap.entries = high_section_index + 1; ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr)); if (!ehea_bmap.vaddr) @@ -593,6 +588,7 @@ int ehea_create_busmap( void ) if (pfn_valid(pfn)) { ehea_bmap.vaddr[i] = vaddr; vaddr += EHEA_SECTSIZE; + ehea_bmap.valid_sections++; } else ehea_bmap.vaddr[i] = 0; } @@ -637,7 +633,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE; - pt = kzalloc(EHEA_MAX_RPAGE * sizeof(u64), GFP_KERNEL); + pt = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!pt) { ehea_error("no mem"); ret = -ENOMEM; @@ -660,8 +656,8 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) void *sectbase = __va(i << SECTION_SIZE_BITS); unsigned long k = 0; - for (j = 0; j < (PAGES_PER_SECTION / EHEA_MAX_RPAGE); - j++) { + for (j = 0; j < (EHEA_PAGES_PER_SECTION / + EHEA_MAX_RPAGE); j++) { for (m = 0; m < EHEA_MAX_RPAGE; m++) { pg = sectbase + ((k++) * EHEA_PAGESIZE); diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index b71f845..352cb38 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h @@ -39,7 +39,7 @@ #define EHEA_PAGESHIFT 12 #define EHEA_PAGESIZE (1UL << EHEA_PAGESHIFT) #define EHEA_SECTSIZE (1UL << 24) -#define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> PAGE_SHIFT) +#define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> EHEA_PAGESHIFT) #if (1UL << SECTION_SIZE_BITS) < EHEA_SECTSIZE #error eHEA module can't work if kernel sectionsize < ehea sectionsize diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 1938d6d..d68796e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -988,7 +988,7 @@ static void nv_enable_irq(struct net_device *dev) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(dev->irq); + enable_irq(np->pci_dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); @@ -1004,7 +1004,7 @@ static void nv_disable_irq(struct net_device *dev) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(dev->irq); + disable_irq(np->pci_dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); @@ -1601,7 +1601,7 @@ static void nv_do_rx_refill(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(dev->irq); + disable_irq(np->pci_dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -1619,7 +1619,7 @@ static void nv_do_rx_refill(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(dev->irq); + enable_irq(np->pci_dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -3557,10 +3557,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test) if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; + dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; + dev->irq = np->pci_dev->irq; goto out_err; } @@ -3623,7 +3625,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq_lockdep(dev->irq); + disable_irq_lockdep(np->pci_dev->irq); mask = np->irqmask; } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { @@ -3641,6 +3643,8 @@ static void nv_do_nic_poll(unsigned long data) } np->nic_poll_irq = 0; + /* disable_irq() contains synchronize_irq, thus no irq handler can run now */ + if (np->recover_error) { np->recover_error = 0; printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); @@ -3677,7 +3681,6 @@ static void nv_do_nic_poll(unsigned long data) } } - /* FIXME: Do we need synchronize_irq(dev->irq) here? */ writel(mask, base + NvRegIrqMask); pci_push(base); @@ -3690,7 +3693,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq_lockdep(dev->irq); + enable_irq_lockdep(np->pci_dev->irq); } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { nv_nic_irq_rx(0, dev); @@ -4943,7 +4946,7 @@ static int nv_close(struct net_device *dev) np->in_shutdown = 1; spin_unlock_irq(&np->lock); netif_poll_disable(dev); - synchronize_irq(dev->irq); + synchronize_irq(np->pci_dev->irq); del_timer_sync(&np->oom_kick); del_timer_sync(&np->nic_poll); @@ -5563,6 +5566,22 @@ static struct pci_device_id pci_tbl[] = { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, + { /* MCP77 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP77 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP77 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, + { /* MCP77 Ethernet Controller */ + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + }, {0,}, }; diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index abe91cb..7da0d07 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -487,7 +487,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) { struct pppol2tp_session *session = NULL; struct pppol2tp_tunnel *tunnel; - unsigned char *ptr; + unsigned char *ptr, *optr; u16 hdrflags; u16 tunnel_id, session_id; int length; @@ -495,7 +495,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) tunnel = pppol2tp_sock_to_tunnel(sock); if (tunnel == NULL) - goto error; + goto no_tunnel; /* UDP always verifies the packet length. */ __skb_pull(skb, sizeof(struct udphdr)); @@ -508,7 +508,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) } /* Point to L2TP header */ - ptr = skb->data; + optr = ptr = skb->data; /* Get L2TP header flags */ hdrflags = ntohs(*(__be16*)ptr); @@ -636,12 +636,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) /* If offset bit set, skip it. */ if (hdrflags & L2TP_HDRFLAG_O) { offset = ntohs(*(__be16 *)ptr); - skb->transport_header += 2 + offset; - if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2)) - goto discard; + ptr += 2 + offset; } - __skb_pull(skb, skb_transport_offset(skb)); + offset = ptr - optr; + if (!pskb_may_pull(skb, offset)) + goto discard; + + __skb_pull(skb, offset); /* Skip PPP header, if present. In testing, Microsoft L2TP clients * don't send the PPP header (PPP header compression enabled), but @@ -651,6 +653,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) * Note that skb->data[] isn't dereferenced from a u16 ptr here since * the field may be unaligned. */ + if (!pskb_may_pull(skb, 2)) + goto discard; + if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03)) skb_pull(skb, 2); @@ -708,6 +713,10 @@ discard: return 0; error: + /* Put UDP header back */ + __skb_push(skb, sizeof(struct udphdr)); + +no_tunnel: return 1; } @@ -1049,6 +1058,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Get routing info from the tunnel socket */ dst_release(skb->dst); skb->dst = sk_dst_get(sk_tun); + skb_orphan(skb); + skb->sk = sk_tun; /* Queue the packet to IP for output */ len = skb->len; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index e3d8520..b3d4728 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -57,7 +57,7 @@ #define TX_WATCHDOG (5 * HZ) #define NAPI_WEIGHT 64 #define BLINK_MS 250 -#define LINK_HZ (HZ/2) +#define LINK_HZ HZ MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); MODULE_AUTHOR("Stephen Hemminger "); @@ -992,19 +992,15 @@ static void xm_link_down(struct skge_hw *hw, int port) { struct net_device *dev = hw->dev[port]; struct skge_port *skge = netdev_priv(dev); - u16 cmd, msk; + u16 cmd = xm_read16(hw, port, XM_MMU_CMD); - if (hw->phy_type == SK_PHY_XMAC) { - msk = xm_read16(hw, port, XM_IMSK); - msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND; - xm_write16(hw, port, XM_IMSK, msk); - } + xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE); - cmd = xm_read16(hw, port, XM_MMU_CMD); cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); xm_write16(hw, port, XM_MMU_CMD, cmd); + /* dummy read to ensure writing */ - (void) xm_read16(hw, port, XM_MMU_CMD); + xm_read16(hw, port, XM_MMU_CMD); if (netif_carrier_ok(dev)) skge_link_down(skge); @@ -1100,7 +1096,7 @@ static void genesis_reset(struct skge_hw *hw, int port) /* reset the statistics module */ xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); - xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ + xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE); xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ @@ -1138,7 +1134,7 @@ static void bcom_check_link(struct skge_hw *hw, int port) u16 status; /* read twice because of latch */ - (void) xm_phy_read(hw, port, PHY_BCOM_STAT); + xm_phy_read(hw, port, PHY_BCOM_STAT); status = xm_phy_read(hw, port, PHY_BCOM_STAT); if ((status & PHY_ST_LSYNC) == 0) { @@ -1339,7 +1335,7 @@ static void xm_phy_init(struct skge_port *skge) mod_timer(&skge->link_timer, jiffies + LINK_HZ); } -static void xm_check_link(struct net_device *dev) +static int xm_check_link(struct net_device *dev) { struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; @@ -1347,25 +1343,25 @@ static void xm_check_link(struct net_device *dev) u16 status; /* read twice because of latch */ - (void) xm_phy_read(hw, port, PHY_XMAC_STAT); + xm_phy_read(hw, port, PHY_XMAC_STAT); status = xm_phy_read(hw, port, PHY_XMAC_STAT); if ((status & PHY_ST_LSYNC) == 0) { xm_link_down(hw, port); - return; + return 0; } if (skge->autoneg == AUTONEG_ENABLE) { u16 lpa, res; if (!(status & PHY_ST_AN_OVER)) - return; + return 0; lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP); if (lpa & PHY_B_AN_RF) { printk(KERN_NOTICE PFX "%s: remote fault\n", dev->name); - return; + return 0; } res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI); @@ -1381,7 +1377,7 @@ static void xm_check_link(struct net_device *dev) default: printk(KERN_NOTICE PFX "%s: duplex mismatch\n", dev->name); - return; + return 0; } /* We are using IEEE 802.3z/D5.0 Table 37-4 */ @@ -1405,11 +1401,14 @@ static void xm_check_link(struct net_device *dev) if (!netif_carrier_ok(dev)) genesis_link_up(skge); + return 1; } /* Poll to check for link coming up. + * * Since internal PHY is wired to a level triggered pin, can't - * get an interrupt when carrier is detected. + * get an interrupt when carrier is detected, need to poll for + * link coming up. */ static void xm_link_timer(unsigned long arg) { @@ -1417,29 +1416,35 @@ static void xm_link_timer(unsigned long arg) struct net_device *dev = skge->netdev; struct skge_hw *hw = skge->hw; int port = skge->port; + int i; + unsigned long flags; if (!netif_running(dev)) return; - if (netif_carrier_ok(dev)) { + spin_lock_irqsave(&hw->phy_lock, flags); + + /* + * Verify that the link by checking GPIO register three times. + * This pin has the signal from the link_sync pin connected to it. + */ + for (i = 0; i < 3; i++) { + if (xm_read16(hw, port, XM_GP_PORT) & XM_GP_INP_ASS) + goto link_down; + } + + /* Re-enable interrupt to detect link down */ + if (xm_check_link(dev)) { + u16 msk = xm_read16(hw, port, XM_IMSK); + msk &= ~XM_IS_INP_ASS; + xm_write16(hw, port, XM_IMSK, msk); xm_read16(hw, port, XM_ISRC); - if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)) - goto nochange; } else { - if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS) - goto nochange; - xm_read16(hw, port, XM_ISRC); - if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) - goto nochange; +link_down: + mod_timer(&skge->link_timer, + round_jiffies(jiffies + LINK_HZ)); } - - spin_lock(&hw->phy_lock); - xm_check_link(dev); - spin_unlock(&hw->phy_lock); - -nochange: - if (netif_running(dev)) - mod_timer(&skge->link_timer, jiffies + LINK_HZ); + spin_unlock_irqrestore(&hw->phy_lock, flags); } static void genesis_mac_init(struct skge_hw *hw, int port) @@ -1683,14 +1688,16 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", skge->netdev->name, status); - if (hw->phy_type == SK_PHY_XMAC && - (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC))) - xm_link_down(hw, port); + if (hw->phy_type == SK_PHY_XMAC && (status & XM_IS_INP_ASS)) { + xm_link_down(hw, port); + mod_timer(&skge->link_timer, jiffies + 1); + } if (status & XM_IS_TXF_UR) { xm_write32(hw, port, XM_MODE, XM_MD_FTF); ++skge->net_stats.tx_fifo_errors; } + if (status & XM_IS_RXF_OV) { xm_write32(hw, port, XM_MODE, XM_MD_FRF); ++skge->net_stats.rx_fifo_errors; @@ -1750,11 +1757,12 @@ static void genesis_link_up(struct skge_port *skge) } xm_write32(hw, port, XM_MODE, mode); - msk = XM_DEF_MSK; - if (hw->phy_type != SK_PHY_XMAC) - msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ + /* Turn on detection of Tx underrun, Rx overrun */ + msk = xm_read16(hw, port, XM_IMSK); + msk &= ~(XM_IS_RXF_OV | XM_IS_TXF_UR); xm_write16(hw, port, XM_IMSK, msk); + xm_read16(hw, port, XM_ISRC); /* get MMU Command Reg. */ @@ -2185,7 +2193,7 @@ static void yukon_mac_intr(struct skge_hw *hw, int port) u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); if (netif_msg_intr(skge)) - printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", + printk(KERN_DEBUG PFX "%s: yukon mac interrupt status 0x%x\n", dev->name, status); if (status & GM_IS_RX_FF_OR) { diff --git a/drivers/net/skge.h b/drivers/net/skge.h index edd7146..323d6c6 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2193,11 +2193,9 @@ enum { XM_IS_TXF_UR = 1<<2, /* Bit 2: Transmit FIFO Underrun */ XM_IS_TX_COMP = 1<<1, /* Bit 1: Frame Tx Complete */ XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ -}; - -#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \ - XM_IS_RXF_OV | XM_IS_TXF_UR)) + XM_IMSK_DISABLE = 0xffff, +}; /* XM_HW_CFG 16 bit r/w Hardware Config Register */ enum { diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ea117fc..2575077 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -603,21 +603,22 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) { u32 reg1; - static const u32 phy_power[] - = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; - - /* looks like this XL is back asswards .. */ - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) - onoff = !onoff; + static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; + static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA }; sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); + if (onoff) /* Turn off phy power saving */ reg1 &= ~phy_power[port]; else reg1 |= phy_power[port]; + if (onoff && hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) + reg1 |= coma_mode[port]; + + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); sky2_pci_read32(hw, PCI_DEV_REG1); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); @@ -2246,20 +2247,26 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) while (hw->st_idx != hwidx) { struct sky2_port *sky2; struct sky2_status_le *le = hw->st_le + hw->st_idx; - unsigned port = le->css & CSS_LINK_BIT; + unsigned port; struct net_device *dev; struct sk_buff *skb; u32 status; u16 length; + u8 opcode = le->opcode; + + if (!(opcode & HW_OWNER)) + break; hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); + port = le->css & CSS_LINK_BIT; dev = hw->dev[port]; sky2 = netdev_priv(dev); length = le16_to_cpu(le->length); status = le32_to_cpu(le->status); - switch (le->opcode & ~HW_OWNER) { + le->opcode = 0; + switch (opcode & ~HW_OWNER) { case OP_RXSTAT: ++rx[port]; skb = sky2_receive(dev, length, status); @@ -2352,7 +2359,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) default: if (net_ratelimit()) printk(KERN_WARNING PFX - "unknown status opcode 0x%x\n", le->opcode); + "unknown status opcode 0x%x\n", opcode); } } @@ -3564,20 +3571,64 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, { const struct sky2_port *sky2 = netdev_priv(dev); const void __iomem *io = sky2->hw->regs; + unsigned int b; regs->version = 1; - memset(p, 0, regs->len); - memcpy_fromio(p, io, B3_RAM_ADDR); - - /* skip diagnostic ram region */ - memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1); + for (b = 0; b < 128; b++) { + /* This complicated switch statement is to make sure and + * only access regions that are unreserved. + * Some blocks are only valid on dual port cards. + * and block 3 has some special diagnostic registers that + * are poison. + */ + switch (b) { + case 3: + /* skip diagnostic ram region */ + memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10); + break; - /* copy GMAC registers */ - memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000); - if (sky2->hw->ports > 1) - memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000); + /* dual port cards only */ + case 5: /* Tx Arbiter 2 */ + case 9: /* RX2 */ + case 14 ... 15: /* TX2 */ + case 17: case 19: /* Ram Buffer 2 */ + case 22 ... 23: /* Tx Ram Buffer 2 */ + case 25: /* Rx MAC Fifo 1 */ + case 27: /* Tx MAC Fifo 2 */ + case 31: /* GPHY 2 */ + case 40 ... 47: /* Pattern Ram 2 */ + case 52: case 54: /* TCP Segmentation 2 */ + case 112 ... 116: /* GMAC 2 */ + if (sky2->hw->ports == 1) + goto reserved; + /* fall through */ + case 0: /* Control */ + case 2: /* Mac address */ + case 4: /* Tx Arbiter 1 */ + case 7: /* PCI express reg */ + case 8: /* RX1 */ + case 12 ... 13: /* TX1 */ + case 16: case 18:/* Rx Ram Buffer 1 */ + case 20 ... 21: /* Tx Ram Buffer 1 */ + case 24: /* Rx MAC Fifo 1 */ + case 26: /* Tx MAC Fifo 1 */ + case 28 ... 29: /* Descriptor and status unit */ + case 30: /* GPHY 1*/ + case 32 ... 39: /* Pattern Ram 1 */ + case 48: case 50: /* TCP Segmentation 1 */ + case 56 ... 60: /* PCI space */ + case 80 ... 84: /* GMAC 1 */ + memcpy_fromio(p, io, 128); + break; + default: +reserved: + memset(p, 0, 128); + } + p += 128; + io += 128; + } } /* In order to do Jumbo packets on these chips, need to turn off the diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9034a05..f80721e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.81" -#define DRV_MODULE_RELDATE "September 5, 2007" +#define DRV_MODULE_VERSION "3.81.1" +#define DRV_MODULE_RELDATE "October 18, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -4874,6 +4874,12 @@ static void tg3_restore_pci_state(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd); + if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { + pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, + tp->pci_cacheline_sz); + pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER, + tp->pci_lat_timer); + } /* Make sure PCI-X relaxed ordering bit is clear. */ pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); val &= ~PCIX_CAPS_RELAXED_ORDERING; diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 8990585..e690609 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -2102,12 +2102,46 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ)); } +static void send_scan_event(void *data) +{ + struct ipw2100_priv *priv = data; + union iwreq_data wrqu; + + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL); +} + +static void ipw2100_scan_event_later(struct work_struct *work) +{ + send_scan_event(container_of(work, struct ipw2100_priv, + scan_event_later.work)); +} + +static void ipw2100_scan_event_now(struct work_struct *work) +{ + send_scan_event(container_of(work, struct ipw2100_priv, + scan_event_now)); +} + static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) { IPW_DEBUG_SCAN("scan complete\n"); /* Age the scan results... */ priv->ieee->scans++; priv->status &= ~STATUS_SCANNING; + + /* Only userspace-requested scan completion events go out immediately */ + if (!priv->user_requested_scan) { + if (!delayed_work_pending(&priv->scan_event_later)) + queue_delayed_work(priv->workqueue, + &priv->scan_event_later, + round_jiffies(msecs_to_jiffies(4000))); + } else { + priv->user_requested_scan = 0; + cancel_delayed_work(&priv->scan_event_later); + queue_work(priv->workqueue, &priv->scan_event_now); + } } #ifdef CONFIG_IPW2100_DEBUG @@ -4376,6 +4410,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv) cancel_delayed_work(&priv->wx_event_work); cancel_delayed_work(&priv->hang_check); cancel_delayed_work(&priv->rf_kill); + cancel_delayed_work(&priv->scan_event_later); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; } @@ -6118,6 +6153,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check); INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); + INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now); + INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) ipw2100_irq_tasklet, (unsigned long)priv); @@ -7427,6 +7464,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev, } IPW_DEBUG_WX("Initiating scan...\n"); + + priv->user_requested_scan = 1; if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) { IPW_DEBUG_WX("Start scan failed.\n"); diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h index de7d384..1ee3348 100644 --- a/drivers/net/wireless/ipw2100.h +++ b/drivers/net/wireless/ipw2100.h @@ -588,6 +588,10 @@ struct ipw2100_priv { struct delayed_work wx_event_work; struct delayed_work hang_check; struct delayed_work rf_kill; + struct work_struct scan_event_now; + struct delayed_work scan_event_later; + + int user_requested_scan; u32 interrupts; int tx_interrupts; diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 4cf0ff7..0560270 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -562,7 +562,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, nr_subband * sizeof(struct ieeetypes_subbandset)); cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + - domain->header.len + + le16_to_cpu(domain->header.len) + sizeof(struct mrvlietypesheader) + S_DS_GEN); } else { diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 4a8f5dc..86fff8d 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -185,14 +185,12 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, switch (pkey->len) { case KEY_LEN_WEP_40: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_40_bit); + wep->keytype[i] = cmd_type_wep_40_bit; memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; case KEY_LEN_WEP_104: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_104_bit); + wep->keytype[i] = cmd_type_wep_104_bit; memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 2fcc3bf..873c405 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -973,7 +973,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) /* Quality by TX errors */ priv->wstats.discard.retries = priv->stats.tx_errors; - tx_retries = le16_to_cpu(adapter->logmsg.retry); + tx_retries = le32_to_cpu(adapter->logmsg.retry); if (tx_retries > 75) tx_qual = (90 - tx_retries) * POOR / 15; @@ -989,10 +989,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; quality = min(quality, tx_qual); - priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable); - priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag); + priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable); + priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure); + priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure); /* Calculate quality */ priv->wstats.qual.qual = max(quality, (u32)100); diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index e61c6d5..66704b8 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -78,7 +78,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, struct rtl8187_tx_hdr *hdr; struct rtl8187_tx_info *info; struct urb *urb; - u32 tmp; + __le16 rts_dur = 0; + u32 flags; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { @@ -86,24 +87,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, return 0; } - hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); - tmp = skb->len - sizeof(*hdr); - tmp |= RTL8187_TX_FLAG_NO_ENCRYPT; - tmp |= control->rts_cts_rate << 19; - tmp |= control->tx_rate << 24; - if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb)) - tmp |= RTL8187_TX_FLAG_MORE_FRAG; + flags = skb->len; + flags |= RTL8187_TX_FLAG_NO_ENCRYPT; + flags |= control->rts_cts_rate << 19; + flags |= control->tx_rate << 24; + if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) + flags |= RTL8187_TX_FLAG_MORE_FRAG; if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { - tmp |= RTL8187_TX_FLAG_RTS; - hdr->rts_duration = - ieee80211_rts_duration(dev, skb->len, control); + flags |= RTL8187_TX_FLAG_RTS; + rts_dur = ieee80211_rts_duration(dev, skb->len, control); } if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) - tmp |= RTL8187_TX_FLAG_CTS; - hdr->flags = cpu_to_le32(tmp); + flags |= RTL8187_TX_FLAG_CTS; + + hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); + hdr->flags = cpu_to_le32(flags); hdr->len = 0; - tmp = control->retry_limit << 8; - hdr->retry = cpu_to_le32(tmp); + hdr->rts_duration = rts_dur; + hdr->retry = cpu_to_le32(control->retry_limit << 8); info = (struct rtl8187_tx_info *)skb->cb; info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC); diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 935b144..d5c0c66 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -327,8 +327,8 @@ static void zd1201_usbrx(struct urb *urb) memcpy(skb_put(skb, 6), &data[datalen-8], 6); memcpy(skb_put(skb, 2), &data[datalen-24], 2); memcpy(skb_put(skb, len), data, len); - skb->dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, zd->dev); + skb->dev->last_rx = jiffies; zd->stats.rx_packets++; zd->stats.rx_bytes += skb->len; netif_rx(skb); @@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb) memcpy(skb_put(skb, 2), &data[6], 2); memcpy(skb_put(skb, len), data+8, len); } - skb->dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, zd->dev); + skb->dev->last_rx = jiffies; zd->stats.rx_packets++; zd->stats.rx_bytes += skb->len; netif_rx(skb); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index a9c339e..5326301 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1041,14 +1041,17 @@ error: static void disconnect(struct usb_interface *intf) { struct net_device *netdev = zd_intf_to_netdev(intf); - struct zd_mac *mac = zd_netdev_mac(netdev); - struct zd_usb *usb = &mac->chip.usb; + struct zd_mac *mac; + struct zd_usb *usb; /* Either something really bad happened, or we're just dealing with * a DEVICE_INSTALLER. */ if (netdev == NULL) return; + mac = zd_netdev_mac(netdev); + usb = &mac->chip.usb; + dev_dbg_f(zd_usb_dev(usb), "\n"); zd_netdev_disconnect(netdev); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 55f307f..85d434b 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1233,6 +1233,10 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 +#define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760 +#define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761 +#define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762 +#define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/