From f83284fe209b1d143244bf462abf1b414eb7b62a Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 25 Jul 2009 07:41:12 +0000 Subject: fealnx: Write outside array bounds phy_idx is checked to be < 4, but np->phys[] is 2 elements long Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 891be28..ee51557 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -584,7 +584,8 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, if (np->flags == HAS_MII_XCVR) { int phy, phy_idx = 0; - for (phy = 1; phy < 32 && phy_idx < 4; phy++) { + for (phy = 1; phy < 32 && phy_idx < ARRAY_SIZE(np->phys); + phy++) { int mii_status = mdio_read(dev, phy, 1); if (mii_status != 0xffff && mii_status != 0x0000) { -- cgit v0.10.2 From 3b73e79b0dcc86f8bec68a34b7fb812eec953f34 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 25 Jul 2009 12:01:50 +0000 Subject: at1700: Read buffer overflow loop bound looks to be wrong, for an array of length 8 Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 18b566a..cf30e27 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -318,7 +318,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) pos3 = mca_read_stored_pos( slot, 3 ); pos4 = mca_read_stored_pos( slot, 4 ); - for (l_i = 0; l_i < 0x09; l_i++) + for (l_i = 0; l_i < 8; l_i++) if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i]) break; ioaddr = at1700_mca_probe_list[l_i]; -- cgit v0.10.2 From c65d3198addb1a2862d4b88bc2a74ac9cbed66f9 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 25 Jul 2009 12:38:33 +0000 Subject: tokenring: Read buffer overflow io[i] is read before the bounds check on i, order should be reversed Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 9d89611..08a6c41 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -1912,7 +1912,7 @@ static int __init ibmtr_init(void) find_turbo_adapters(io); - for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) { + for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) { struct net_device *dev; irq[i] = 0; mem[i] = 0; -- cgit v0.10.2 From d513d018e2236930b6163241bbdce64d2c0de49e Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sun, 26 Jul 2009 18:53:17 -0700 Subject: eepro: Read buffer overflow io[i] is read before the bounds check on i, order should be reversed Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index cc2ab64..4f70034 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1784,7 +1784,7 @@ int __init init_module(void) printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n"); } - for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) { + for (i = 0; i < MAX_EEPRO && io[i] != -1; i++) { dev = alloc_etherdev(sizeof(struct eepro_local)); if (!dev) break; -- cgit v0.10.2 From dcf777f6ed9799c5ac90ac17a5c369e6b73ca92e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 26 Jul 2009 19:11:14 -0700 Subject: NET: ROSE: Don't use static buffer. The use of a static buffer in rose2asc() to return its result is not threadproof and can result in corruption if multiple threads are trying to use one of the procfs files based on rose2asc(). Signed-off-by: Ralf Baechle Signed-off-by: David S. Miller diff --git a/include/net/rose.h b/include/net/rose.h index cbd5364..5ba9f02 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -156,7 +156,7 @@ extern int sysctl_rose_maximum_vcs; extern int sysctl_rose_window_size; extern int rosecmp(rose_address *, rose_address *); extern int rosecmpm(rose_address *, rose_address *, unsigned short); -extern const char *rose2asc(const rose_address *); +extern char *rose2asc(char *buf, const rose_address *); extern struct sock *rose_find_socket(unsigned int, struct rose_neigh *); extern void rose_kill_by_neigh(struct rose_neigh *); extern unsigned int rose_new_lci(struct rose_neigh *); diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 6bd8e938..f0a76f6 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -92,23 +92,21 @@ static void rose_set_lockdep_key(struct net_device *dev) /* * Convert a ROSE address into text. */ -const char *rose2asc(const rose_address *addr) +char *rose2asc(char *buf, const rose_address *addr) { - static char buffer[11]; - if (addr->rose_addr[0] == 0x00 && addr->rose_addr[1] == 0x00 && addr->rose_addr[2] == 0x00 && addr->rose_addr[3] == 0x00 && addr->rose_addr[4] == 0x00) { - strcpy(buffer, "*"); + strcpy(buf, "*"); } else { - sprintf(buffer, "%02X%02X%02X%02X%02X", addr->rose_addr[0] & 0xFF, + sprintf(buf, "%02X%02X%02X%02X%02X", addr->rose_addr[0] & 0xFF, addr->rose_addr[1] & 0xFF, addr->rose_addr[2] & 0xFF, addr->rose_addr[3] & 0xFF, addr->rose_addr[4] & 0xFF); } - return buffer; + return buf; } /* @@ -1437,7 +1435,7 @@ static void rose_info_stop(struct seq_file *seq, void *v) static int rose_info_show(struct seq_file *seq, void *v) { - char buf[11]; + char buf[11], rsbuf[11]; if (v == SEQ_START_TOKEN) seq_puts(seq, @@ -1455,8 +1453,8 @@ static int rose_info_show(struct seq_file *seq, void *v) devname = dev->name; seq_printf(seq, "%-10s %-9s ", - rose2asc(&rose->dest_addr), - ax2asc(buf, &rose->dest_call)); + rose2asc(rsbuf, &rose->dest_addr), + ax2asc(buf, &rose->dest_call)); if (ax25cmp(&rose->source_call, &null_ax25_address) == 0) callsign = "??????-?"; @@ -1465,7 +1463,7 @@ static int rose_info_show(struct seq_file *seq, void *v) seq_printf(seq, "%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n", - rose2asc(&rose->source_addr), + rose2asc(rsbuf, &rose->source_addr), callsign, devname, rose->lci & 0x0FFF, diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index a81066a..9478d9b 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -1104,6 +1104,7 @@ static void rose_node_stop(struct seq_file *seq, void *v) static int rose_node_show(struct seq_file *seq, void *v) { + char rsbuf[11]; int i; if (v == SEQ_START_TOKEN) @@ -1112,13 +1113,13 @@ static int rose_node_show(struct seq_file *seq, void *v) const struct rose_node *rose_node = v; /* if (rose_node->loopback) { seq_printf(seq, "%-10s %04d 1 loopback\n", - rose2asc(&rose_node->address), - rose_node->mask); + rose2asc(rsbuf, &rose_node->address), + rose_node->mask); } else { */ seq_printf(seq, "%-10s %04d %d", - rose2asc(&rose_node->address), - rose_node->mask, - rose_node->count); + rose2asc(rsbuf, &rose_node->address), + rose_node->mask, + rose_node->count); for (i = 0; i < rose_node->count; i++) seq_printf(seq, " %05d", @@ -1267,7 +1268,7 @@ static void rose_route_stop(struct seq_file *seq, void *v) static int rose_route_show(struct seq_file *seq, void *v) { - char buf[11]; + char buf[11], rsbuf[11]; if (v == SEQ_START_TOKEN) seq_puts(seq, @@ -1279,7 +1280,7 @@ static int rose_route_show(struct seq_file *seq, void *v) seq_printf(seq, "%3.3X %-10s %-9s %05d ", rose_route->lci1, - rose2asc(&rose_route->src_addr), + rose2asc(rsbuf, &rose_route->src_addr), ax2asc(buf, &rose_route->src_call), rose_route->neigh1->number); else @@ -1289,10 +1290,10 @@ static int rose_route_show(struct seq_file *seq, void *v) if (rose_route->neigh2) seq_printf(seq, "%3.3X %-10s %-9s %05d\n", - rose_route->lci2, - rose2asc(&rose_route->dest_addr), - ax2asc(buf, &rose_route->dest_call), - rose_route->neigh2->number); + rose_route->lci2, + rose2asc(rsbuf, &rose_route->dest_addr), + ax2asc(buf, &rose_route->dest_call), + rose_route->neigh2->number); else seq_puts(seq, "000 * * 00000\n"); -- cgit v0.10.2 From 4a29f396429132dc59f1856ea6cfc860a1955fa1 Mon Sep 17 00:00:00 2001 From: Alessandro Rubini Date: Wed, 22 Jul 2009 12:49:08 +0000 Subject: smc91x.h: add config for Nomadik evaluation kit Signed-off-by: Alessandro Rubini Acked-by: Andrea Gallo Signed-off-by: David S. Miller diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index f1f773b..57a159f 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -186,7 +186,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) #define SMC_IRQ_FLAGS (-1) /* from resource */ -#elif defined(CONFIG_MACH_LOGICPD_PXA270) +#elif defined(CONFIG_MACH_LOGICPD_PXA270) \ + || defined(CONFIG_MACH_NOMADIK_8815NHK) #define SMC_CAN_USE_8BIT 0 #define SMC_CAN_USE_16BIT 1 -- cgit v0.10.2 From c587aea951a56d29741a3cef4ea3e142c93b3207 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Thu, 23 Jul 2009 23:06:32 +0000 Subject: net/bridge: use kobject_put to release kobject in br_add_if error path kobject_init_and_add will alloc memory for kobj->name, so in br_add_if error path, simply use kobject_del will not free memory for kobj->name. Fix by using kobject_put instead, kobject_put will internally calls kobject_del and frees memory for kobj->name. Signed-off-by: Xiaotian Feng Acked-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 8a96672..eb404dc 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -424,7 +424,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) err2: br_fdb_delete_by_port(br, p, 1); err1: - kobject_del(&p->kobj); + kobject_put(&p->kobj); err0: dev_set_promiscuity(dev, -1); put_back: -- cgit v0.10.2 From c8a5a658b826508c7c61b57e9a590f7b8760fb51 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Sun, 26 Jul 2009 20:17:21 -0700 Subject: netxen: reset ring consumer during cleanup Reset consumer of status rings to 0 when cleaning up sw resources. Status rings are not deleted during suspend since they have napi objects. This ensures correct rx processing across suspen-resume. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 5d3343e..7acf204 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -184,6 +184,13 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) kfree(recv_ctx->rds_rings); skip_rds: + if (recv_ctx->sds_rings == NULL) + goto skip_sds; + + for(ring = 0; ring < adapter->max_sds_rings; ring++) + recv_ctx->sds_rings[ring].consumer = 0; + +skip_sds: if (adapter->tx_ring == NULL) return; -- cgit v0.10.2 From ca52efd5490f97f396d3c5863ba714624f272033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Fri, 24 Jul 2009 12:34:19 +0000 Subject: r8169: WakeOnLan fix for the 8168 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More stuff for http://bugzilla.kernel.org/show_bug.cgi?id=9512 Some 8168 are unable to WoL when receiving is not enabled (plain old 8169 do not seem to care). It is not exactly pretty to leave the receiver enabled but we should now enable DMA late enough for it to be safe. Some late stage boot failure due to pxe and friends may benefit from the delayed enabling of bus-mastering as well. Signed-off-by: Francois Romieu Tested-by: Jaromír Cápík Cc: Edward Hsu diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 4b53b58..b82780d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2060,8 +2060,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } } - pci_set_master(pdev); - /* ioremap MMIO region */ ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE); if (!ioaddr) { @@ -2089,6 +2087,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) RTL_W16(IntrStatus, 0xffff); + pci_set_master(pdev); + /* Identify chip attached to board */ rtl8169_get_mac_version(tp, ioaddr); @@ -3874,6 +3874,15 @@ static void rtl_shutdown(struct pci_dev *pdev) spin_unlock_irq(&tp->lock); if (system_state == SYSTEM_POWER_OFF) { + /* WoL fails with some 8168 when the receiver is disabled. */ + if (tp->features & RTL_FEATURE_WOL) { + pci_clear_master(pdev); + + RTL_W8(ChipCmd, CmdRxEnb); + /* PCI commit */ + RTL_R8(ChipCmd); + } + pci_wake_from_d3(pdev, true); pci_set_power_state(pdev, PCI_D3hot); } -- cgit v0.10.2 From 8bae1b2b13beb4cf4c0f119f97640503c2b74b0f Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 23 Jul 2009 18:00:39 +0000 Subject: ixgbe: fix for 82599 errata marking UDP checksum errors There is an 82599 errata that UDP frames with a zero checksum are incorrectly marked as checksum invalid by the hardware. This was leading to misleading hw_csum_rx_error counts. This patch adds a test around this counter increase for this condition. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 6887759..200454f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -511,8 +511,11 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, * @skb: skb currently being received and modified **/ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, - u32 status_err, struct sk_buff *skb) + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) { + u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); + skb->ip_summed = CHECKSUM_NONE; /* Rx csum disabled */ @@ -530,6 +533,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, return; if (status_err & IXGBE_RXDADV_ERR_TCPE) { + u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + + /* + * 82599 errata, UDP frames with a 0 checksum can be marked as + * checksum errors. + */ + if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) && + (adapter->hw.mac.type == ixgbe_mac_82599EB)) + return; + adapter->hw_csum_rx_error++; return; } @@ -803,7 +816,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - ixgbe_rx_checksum(adapter, staterr, skb); + ixgbe_rx_checksum(adapter, rx_desc, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; -- cgit v0.10.2 From 0cbb0a781a42f131e9c6836554f402cb85f8f38b Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Mon, 27 Jul 2009 10:49:44 -0700 Subject: net: irda: init spinlock after memcpy irttp_dup() copies a tsap_cb struct, but does not initialize the spinlock in the new structure, which confuses lockdep. Signed-off-by: Deepak Saxena Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: David S. Miller diff --git a/net/irda/irttp.c b/net/irda/irttp.c index ecf4eb2..9cb79f9 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -1453,6 +1453,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) } /* Dup */ memcpy(new, orig, sizeof(struct tsap_cb)); + spin_lock_init(&new->lock); /* We don't need the old instance any more */ spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags); -- cgit v0.10.2 From 6d7760a88c25057c2c2243e5dfe2d731064bd31d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 27 Jul 2009 11:25:58 -0700 Subject: cnic: Fix ISCSI_KEVENT_IF_DOWN message handling. When a net device goes down or when the bnx2i driver is unloaded, the code was not generating the ISCSI_KEVENT_IF_DOWN message properly and this could cause the userspace driver to crash. This is fixed by sending the message properly in the shutdown path. cnic_uio_stop() is also added to send the message when bnx2i is unregistering. Signed-off-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 4d1515f..4869d77 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -227,7 +227,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, } rcu_read_lock(); - ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]); + ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); if (ulp_ops) ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len); rcu_read_unlock(); @@ -319,6 +319,20 @@ static int cnic_abort_prep(struct cnic_sock *csk) return 0; } +static void cnic_uio_stop(void) +{ + struct cnic_dev *dev; + + read_lock(&cnic_dev_lock); + list_for_each_entry(dev, &cnic_dev_list, list) { + struct cnic_local *cp = dev->cnic_priv; + + if (cp->cnic_uinfo) + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + } + read_unlock(&cnic_dev_lock); +} + int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) { struct cnic_dev *dev; @@ -390,6 +404,9 @@ int cnic_unregister_driver(int ulp_type) } read_unlock(&cnic_dev_lock); + if (ulp_type == CNIC_ULP_ISCSI) + cnic_uio_stop(); + rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL); mutex_unlock(&cnic_lock); @@ -632,7 +649,6 @@ static void cnic_free_resc(struct cnic_dev *dev) int i = 0; if (cp->cnic_uinfo) { - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); while (cp->uio_dev != -1 && i < 15) { msleep(100); i++; @@ -1057,6 +1073,9 @@ static void cnic_ulp_stop(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int if_type; + if (cp->cnic_uinfo) + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + rcu_read_lock(); for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { struct cnic_ulp_ops *ulp_ops; -- cgit v0.10.2 From 3995bd9332a51b626237d6671cfeb7235e6c1305 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 24 Jul 2009 11:13:14 -0700 Subject: iwlwifi: fix TX queue race I had a problem on 4965 hardware (well, probably other hardware too, but others don't survive my stress testing right now, unfortunately) where the driver was sending invalid commands to the device, but no such thing could be seen from the driver's point of view. I could reproduce this fairly easily by sending multiple TCP streams with iperf on different TIDs, though sometimes a single iperf stream was sufficient. It even happened with a single core, but I have forced preemption turned on. The culprit was a queue overrun, where we advanced the queue's write pointer over the read pointer. After careful analysis I've come to the conclusion that the cause is a race condition between iwlwifi and mac80211. mac80211, of course, checks whether the queue is stopped, before transmitting a frame. This effectively looks like this: lock(queues) if (stopped(queue)) { unlock(queues) return busy; } unlock(queues) ... <-- this place will be important there is some more code here drv_tx(frame) The driver, on the other hand, can stop and start queues, which does lock(queues) mark_running/stopped(queue) unlock(queues) [if marked running: wake up tasklet to send pending frames] Now, however, once the driver starts the queue, mac80211 can see that and end up at the marked place above, at which point for some reason the driver seems to stop the queue again (I don't understand that) and then we end up transmitting while the queue is actually full. Now, this shouldn't actually matter much, but for some reason I've seen it happen multiple times in a row and the queue actually overflows, at which point the queue bites itself in the tail and things go completely wrong. This patch fixes this by just dropping the packet should this have happened, and making the lock in iwlwifi cover everything so iwlwifi can't race against itself (dropping the lock there might make it more likely, but it did seem to happen without that too). Since we can't hold the lock across drv_tx() above, I see no way to fix this in mac80211, but I also don't understand why I haven't seen this before -- maybe I just never stress tested it this badly. With this patch, the device has survived many minutes of simultanously sending two iperf streams on different TIDs with combined throughput of about 60 Mbps. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 9bbeec9..5febb31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -720,8 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) goto drop_unlock; } - spin_unlock_irqrestore(&priv->lock, flags); - hdr_len = ieee80211_hdrlen(fc); /* Find (or create) index into station table for destination station */ @@ -729,7 +727,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); - goto drop; + goto drop_unlock; } IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); @@ -750,14 +748,17 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id); } - priv->stations[sta_id].tid[tid].tfds_in_queue++; } txq = &priv->txq[txq_id]; q = &txq->q; txq->swq_id = swq_id; - spin_lock_irqsave(&priv->lock, flags); + if (unlikely(iwl_queue_space(q) < q->high_mark)) + goto drop_unlock; + + if (ieee80211_is_data_qos(fc)) + priv->stations[sta_id].tid[tid].tfds_in_queue++; /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); @@ -902,7 +903,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock: spin_unlock_irqrestore(&priv->lock, flags); -drop: return -1; } EXPORT_SYMBOL(iwl_tx_skb); -- cgit v0.10.2 From 45f5fa32b130b2a59f9b726be45ce7fa73fb834c Mon Sep 17 00:00:00 2001 From: reinette chatre Date: Tue, 21 Jul 2009 09:29:07 -0700 Subject: iwlagn: fix minimum number of queues setting We need to provide a reasonable minimum that will result in a working setup if used. Set minimum to be 10 to provide for 4 standard TX queues + 1 command queue + 2 (unused) HCCA queues + 4 HT queues (one per AC). We allow the user to change the number of queues used via a module parameter and use this minimum value to check if it is valid. Without this patch a user can select a value for the number of queues that will result in a failing setup. Signed-off-by: Reinette Chatre Reviewed-by: Tomas Winkler Acked-by: Tomas Winkler Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index fbb3a57..2de6471 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -112,7 +112,7 @@ enum iwl3945_antenna { #define IWL_TX_FIFO_NONE 7 /* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES 4 +#define IWL39_MIN_NUM_QUEUES 4 #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e2d620f..650e20a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -258,8 +258,10 @@ struct iwl_channel_info { #define IWL_TX_FIFO_HCCA_2 6 #define IWL_TX_FIFO_NONE 7 -/* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES 4 +/* Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate the 4 standard TX queues, 1 command + * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ +#define IWL_MIN_NUM_QUEUES 10 /* Power management (not Tx power) structures */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 956798f..2f50ab6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4018,10 +4018,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e SET_IEEE80211_DEV(hw, &pdev->dev); if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) || - (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) { + (iwl3945_mod_params.num_of_queues < IWL39_MIN_NUM_QUEUES)) { IWL_ERR(priv, "invalid queues_num, should be between %d and %d\n", - IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); + IWL39_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); err = -EINVAL; goto out_ieee80211_free_hw; } -- cgit v0.10.2 From 2a21f86917f7a9fe13b180e895a816871a234dee Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 25 Jul 2009 15:22:59 +0300 Subject: wireless: ERR_PTR vs null iwm_wdev_alloc() returns an ERR_PTR on failure and not null. It also prints its own dev_err() message so I removed that as well. Compile tested only. Sorry. Found by smatch (http://repo.or.cz/w/smatch.git). Signed-off-by: Dan Carpenter Acked-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index aea5ccf..bf294e4 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -106,10 +106,8 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, int ret = 0; wdev = iwm_wdev_alloc(sizeof_bus, dev); - if (!wdev) { - dev_err(dev, "no memory for wireless device instance\n"); - return ERR_PTR(-ENOMEM); - } + if (IS_ERR(wdev)) + return wdev; iwm = wdev_to_iwm(wdev); iwm->bus_ops = if_ops; -- cgit v0.10.2 From 3d0ccd021b23c18ea2d399fe4a43c955485c765c Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 25 Jul 2009 23:02:32 +0200 Subject: airo: Buffer overflow SSID_rid has space for only 3 ssids. txPowerLevels[i] is read before the bounds check for i Signed-off-by: Roel Kluin Acked-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index c70604f..8ce5e4c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5918,20 +5918,19 @@ static int airo_set_essid(struct net_device *dev, readSsidRid(local, &SSID_rid); /* Check if we asked for `any' */ - if(dwrq->flags == 0) { + if (dwrq->flags == 0) { /* Just send an empty SSID list */ memset(&SSID_rid, 0, sizeof(SSID_rid)); } else { - int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1; /* Check the size of the string */ - if(dwrq->length > IW_ESSID_MAX_SIZE) { + if (dwrq->length > IW_ESSID_MAX_SIZE) return -E2BIG ; - } + /* Check if index is valid */ - if((index < 0) || (index >= 4)) { + if (index >= ARRAY_SIZE(SSID_rid.ssids)) return -EINVAL; - } /* Set the SSID */ memset(SSID_rid.ssids[index].ssid, 0, @@ -6819,7 +6818,7 @@ static int airo_set_txpow(struct net_device *dev, return -EINVAL; } clear_bit (FLAG_RADIO_OFF, &local->flags); - for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) + for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++) if (v == cap_rid.txPowerLevels[i]) { readConfigRid(local, 1); local->config.txPower = v; -- cgit v0.10.2 From 008749fc9917b799c469478141ddd1a4c81d06ca Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 25 Jul 2009 23:21:22 +0200 Subject: ath9k: Read outside array bounds Incorrect limits leads to reads outside array bounds. Signed-off-by: Roel Kluin Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index a2fda70..ce0e86c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -460,7 +460,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) integer = swab32(eep->modalHeader.antCtrlCommon); eep->modalHeader.antCtrlCommon = integer; - for (i = 0; i < AR5416_MAX_CHAINS; i++) { + for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { integer = swab32(eep->modalHeader.antCtrlChain[i]); eep->modalHeader.antCtrlChain[i] = integer; } @@ -914,7 +914,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, ctlMode, numCtlModes, isHt40CtlMode, (pCtlMode[ctlMode] & EXT_ADDITIVE)); - for (i = 0; (i < AR5416_NUM_CTLS) && + for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " -- cgit v0.10.2 From 082e708acc50a5b625b9bde0bb1af90dfdbd1942 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 25 Jul 2009 23:34:31 +0200 Subject: iwlwifi: Read outside array bounds tid is bounded (above) by the size of default_tid_to_tx_fifo (17 elements), but the size of priv->stations[].tid[] is MAX_TID_COUNT (9) elements. Signed-off-by: Roel Kluin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 5febb31..2e89040 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1171,6 +1171,8 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) IWL_ERR(priv, "Start AGG on invalid station\n"); return -ENXIO; } + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); -- cgit v0.10.2 From 78f1a8b758d57c2d2c9f3db7199cd30803854c82 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 27 Jul 2009 08:38:25 -0700 Subject: mac80211: do not queue work after suspend in the dynamic ps timer Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index aca22b0..07e7e41 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -721,7 +721,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) { struct ieee80211_local *local = (void *) data; - if (local->quiescing) + if (local->quiescing || local->suspended) return; queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); -- cgit v0.10.2 From 27fed4175acf81ddd91d9a4ee2fd298981f60295 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jul 2009 18:39:45 -0700 Subject: ip: fix logic of reverse path filter sysctl Even though reverse path filter was changed from simple boolean to trinary control, the loose mode only works if both all and device are configured because of this logic error. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index acef2a7..ad27c7d 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -82,7 +82,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING) #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING) -#define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER) +#define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER) #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ ACCEPT_SOURCE_ROUTE) #define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY) -- cgit v0.10.2 From 430453fc2a5f3f2c1d98ebc3c3d4c54f3060e3c3 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 28 Jul 2009 09:59:47 +0200 Subject: libertas: Read outside array bounds reads bss->rates[j] before checking bounds of index, and should use ARRAY_SIZE to determine the size of the array. Signed-off-by: Roel Kluin Acked-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 601b542..6c95af3 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -5,6 +5,7 @@ * for sending scan commands to the firmware. */ #include +#include #include #include #include @@ -876,7 +877,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, iwe.u.bitrate.disabled = 0; iwe.u.bitrate.value = 0; - for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { + for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) { /* Bit rate given in 500 kb/s units */ iwe.u.bitrate.value = bss->rates[j] * 500000; current_val = iwe_stream_add_value(info, start, current_val, -- cgit v0.10.2 From 57921c312e8cef72ba35a4cfe870b376da0b1b87 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 28 Jul 2009 12:05:00 +0200 Subject: libertas: Read buffer overflow Several arrays were read before checking whether the index was within bounds. ARRAY_SIZE() should be used to determine the size of arrays. rates->rates has an arraysize of 1, so calling get_common_rates() with a rates_size of MAX_RATES (14) was causing reads out of bounds. tmp_size can increment at most to (ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1), so that should be the number of elements of tmp[]. A goto can be eliminated: ret was already set upon its declaration. Signed-off-by: Roel Kluin Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index b9b3741..d699737 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -1,6 +1,7 @@ /* Copyright (C) 2006, Red Hat, Inc. */ #include +#include #include #include #include @@ -43,21 +44,21 @@ static int get_common_rates(struct lbs_private *priv, u16 *rates_size) { u8 *card_rates = lbs_bg_rates; - size_t num_card_rates = sizeof(lbs_bg_rates); int ret = 0, i, j; - u8 tmp[30]; + u8 tmp[(ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1)]; size_t tmp_size = 0; /* For each rate in card_rates that exists in rate1, copy to tmp */ - for (i = 0; card_rates[i] && (i < num_card_rates); i++) { - for (j = 0; rates[j] && (j < *rates_size); j++) { + for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && card_rates[i]; i++) { + for (j = 0; j < *rates_size && rates[j]; j++) { if (rates[j] == card_rates[i]) tmp[tmp_size++] = card_rates[i]; } } lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); - lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates); + lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, + ARRAY_SIZE(lbs_bg_rates)); lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); @@ -69,10 +70,7 @@ static int get_common_rates(struct lbs_private *priv, lbs_pr_alert("Previously set fixed data rate %#x isn't " "compatible with the network.\n", priv->cur_rate); ret = -1; - goto done; } - ret = 0; - done: memset(rates, 0, *rates_size); *rates_size = min_t(int, tmp_size, *rates_size); @@ -322,7 +320,7 @@ static int lbs_associate(struct lbs_private *priv, rates = (struct mrvl_ie_rates_param_set *) pos; rates->header.type = cpu_to_le16(TLV_TYPE_RATES); memcpy(&rates->rates, &bss->rates, MAX_RATES); - tmplen = MAX_RATES; + tmplen = min_t(u16, ARRAY_SIZE(rates->rates), MAX_RATES); if (get_common_rates(priv, rates->rates, &tmplen)) { ret = -1; goto done; @@ -598,7 +596,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, /* Copy Data rates from the rates recorded in scan response */ memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates)); - ratesize = min_t(u16, sizeof(cmd.bss.rates), MAX_RATES); + ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), MAX_RATES); memcpy(cmd.bss.rates, bss->rates, ratesize); if (get_common_rates(priv, cmd.bss.rates, &ratesize)) { lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n"); -- cgit v0.10.2 From 89c3a8aca28e6d57f2ae945d97858a372d624b81 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Jul 2009 18:10:17 +0200 Subject: mac80211: fix suspend Jan reported that his b43-based laptop hangs during suspend. The problem turned out to be mac80211 asking the driver to stop the hardware before removing interfaces, and interface removal caused b43 to touch the hardware (while down, which causes the hang). This patch fixes mac80211 to do reorder these operations to have them in the correct order -- first remove interfaces and then stop the hardware. Some more code is necessary to be able to do so in a race-free manner, in particular it is necessary to not process frames received during quiescing. Fixes http://bugzilla.kernel.org/show_bug.cgi?id=13337. Reported-by: Jan Scholz Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 7a549f9..5e3d476 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -55,15 +55,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) rcu_read_unlock(); - /* flush again, in case driver queued work */ - flush_workqueue(local->hw.workqueue); - - /* stop hardware - this must stop RX */ - if (local->open_count) { - ieee80211_led_radio(local, false); - drv_stop(local); - } - /* remove STAs */ spin_lock_irqsave(&local->sta_lock, flags); list_for_each_entry(sta, &local->sta_list, list) { @@ -111,7 +102,22 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) drv_remove_interface(local, &conf); } + /* stop hardware - this must stop RX */ + if (local->open_count) { + ieee80211_led_radio(local, false); + drv_stop(local); + } + + /* + * flush again, in case driver queued work -- it + * shouldn't be doing (or cancel everything in the + * stop callback) that but better safe than sorry. + */ + flush_workqueue(local->hw.workqueue); + local->suspended = true; + /* need suspended to be visible before quiescing is false */ + barrier(); local->quiescing = false; return 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index de5bba7..0936fc2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2453,6 +2453,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, return; } + /* + * If we're suspending, it is possible although not too likely + * that we'd be receiving frames after having already partially + * quiesced the stack. We can't process such frames then since + * that might, for example, cause stations to be added or other + * driver callbacks be invoked. + */ + if (unlikely(local->quiescing || local->suspended)) { + kfree_skb(skb); + return; + } + if (status->flag & RX_FLAG_HT) { /* rate_idx is MCS index */ if (WARN_ON(status->rate_idx < 0 || -- cgit v0.10.2 From ca7daea612b480ecf0fc5bd1630b88447fe73fc5 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 30 Jul 2009 04:38:19 +0000 Subject: net/netlabel: Add kmalloc NULL tests The test on map4 should be a test on map6. The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ expression *x; identifier f; constant char *C; @@ x = \(kmalloc\|kcalloc\|kzalloc\)(...); ... when != x == NULL when != x != NULL when != (x || ...) ( kfree(x) | f(...,C,...,x,...) | *f(...,x,...) | *x->f ) // Signed-off-by: Julia Lawall Acked-by: Paul Moore Signed-off-by: David S. Miller diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index b0e582f..16e6c43 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -151,7 +151,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, addr6 = addr; mask6 = mask; map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); - if (map4 == NULL) + if (map6 == NULL) goto cfg_unlbl_map_add_failure; map6->type = NETLBL_NLTYPE_UNLABELED; ipv6_addr_copy(&map6->list.addr, addr6); -- cgit v0.10.2 From a541f8401d8e9113a89ee902cb8d8e412d6d3569 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 29 Jul 2009 08:49:52 +0000 Subject: iscsi: Use GFP_ATOMIC in iscsi_offload_mesg(). Changing to GFP_ATOMIC because the only caller in cnic/bnx2i may be calling this function while holding spin_lock. This problem was discovered by Mike Christie. Signed-off-by: Michael Chan Acked-by: Mike Christie Signed-off-by: David S. Miller diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 783e33c..b47240c 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -990,7 +990,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost, struct iscsi_uevent *ev; int len = NLMSG_SPACE(sizeof(*ev) + data_size); - skb = alloc_skb(len, GFP_NOIO); + skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { printk(KERN_ERR "can not deliver iscsi offload message:OOM\n"); return -ENOMEM; @@ -1012,7 +1012,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost, memcpy((char *)ev + sizeof(*ev), data, data_size); - return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO); + return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC); } EXPORT_SYMBOL_GPL(iscsi_offload_mesg); -- cgit v0.10.2 From 2a8aaacda5097fa92a39948da1b4c6614b6e150e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 30 Jul 2009 13:10:50 -0700 Subject: docbook: fix printk of ip address Use the %pI4 format string instead of %d.%d.%d.%d and NIPQUAD. Signed-off-by: Tobias Klauser Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl index a50d6cd..992e67e 100644 --- a/Documentation/DocBook/kernel-hacking.tmpl +++ b/Documentation/DocBook/kernel-hacking.tmpl @@ -449,8 +449,8 @@ printk(KERN_INFO "i = %u\n", i); -__u32 ipaddress; -printk(KERN_INFO "my ip: %d.%d.%d.%d\n", NIPQUAD(ipaddress)); +__be32 ipaddress; +printk(KERN_INFO "my ip: %pI4\n", &ipaddress); -- cgit v0.10.2 From 3d54015b750e5d5e950a1dcee2735387fd4b6e1a Mon Sep 17 00:00:00 2001 From: roel kluin Date: Thu, 30 Jul 2009 00:26:32 +0000 Subject: 3c515: Write outside array bounds if dev_alloc_skb() fails on the first iteration, a write to cp->rx_ring[-1] occurs. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 3e00fa8..4a7c328 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -832,7 +832,9 @@ static int corkscrew_open(struct net_device *dev) skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ vp->rx_ring[i].addr = isa_virt_to_bus(skb->data); } - vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ + if (i != 0) + vp->rx_ring[i - 1].next = + isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); } if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */ -- cgit v0.10.2 From a3e8ee682003685b8b9c98c89340a42e48c3e813 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Wed, 29 Jul 2009 23:46:59 +0000 Subject: ipv4: ARP neigh procfs buffer overflow If arp_format_neigh_entry() can be called with n->dev->addr_len == 0, then a write to hbuffer[-1] occurs. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c29d75d..090e999 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1304,7 +1304,9 @@ static void arp_format_neigh_entry(struct seq_file *seq, hbuffer[k++] = hex_asc_lo(n->ha[j]); hbuffer[k++] = ':'; } - hbuffer[--k] = 0; + if (k != 0) + --k; + hbuffer[k] = 0; #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) } #endif -- cgit v0.10.2 From f0c5b35c6c93c89a9d8ccab19b0b4842f5dfddc5 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Wed, 29 Jul 2009 03:18:56 +0000 Subject: eexpress: Read buffer overflow start_code is 69 words, but the code always writes a multiple of 16 words, so the last 11 words written are outside the array. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 1686dca..1f016d6 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -1474,13 +1474,13 @@ static void eexp_hw_init586(struct net_device *dev) outw(0x0000, ioaddr + 0x800c); outw(0x0000, ioaddr + 0x800e); - for (i = 0; i < (sizeof(start_code)); i+=32) { + for (i = 0; i < ARRAY_SIZE(start_code) * 2; i+=32) { int j; outw(i, ioaddr + SM_PTR); - for (j = 0; j < 16; j+=2) + for (j = 0; j < 16 && (i+j)/2 < ARRAY_SIZE(start_code); j+=2) outw(start_code[(i+j)/2], ioaddr+0x4000+j); - for (j = 0; j < 16; j+=2) + for (j = 0; j < 16 && (i+j+16)/2 < ARRAY_SIZE(start_code); j+=2) outw(start_code[(i+j+16)/2], ioaddr+0x8000+j); } -- cgit v0.10.2 From 72fc939789dbe7ca091b50b686d45ac0df15417a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Jul 2009 23:43:08 +0000 Subject: pppoe: fix /proc/net/pppoe If a socket is hashed in last slot of pppoe hash table (PPPOE_HASH_SIZE-1) we report it many times (up to filling seq buffer) (Only the last socket of last slot) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index f0031f1..5f20902 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -1063,6 +1063,7 @@ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos) else { int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); + po = NULL; while (++hash < PPPOE_HASH_SIZE) { po = pn->hash_table[hash]; if (po) -- cgit v0.10.2 From accff95c2500c7bce671c1f722de6f8810fe550d Mon Sep 17 00:00:00 2001 From: Jiajun Wu Date: Thu, 30 Jul 2009 14:20:42 -0700 Subject: gianfar: fix coalescing setup in ethtool support Parameter order for using mk_ic_value(count, time) was reversed, the patch fixes this. Signed-off-by: Jiajun Wu Signed-off-by: Li Yang Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index dbf06e9..2234118 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -366,9 +366,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals return -EINVAL; } - priv->rxic = mk_ic_value( - gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs), - cvals->rx_max_coalesced_frames); + priv->rxic = mk_ic_value(cvals->rx_max_coalesced_frames, + gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs)); /* Set up tx coalescing */ if ((cvals->tx_coalesce_usecs == 0) || @@ -390,9 +389,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals return -EINVAL; } - priv->txic = mk_ic_value( - gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs), - cvals->tx_max_coalesced_frames); + priv->txic = mk_ic_value(cvals->tx_max_coalesced_frames, + gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs)); gfar_write(&priv->regs->rxic, 0); if (priv->rxcoalescing) -- cgit v0.10.2 From 8f9a71673d9f397a365f4d18c307e91141b8fe92 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:25:09 +0000 Subject: ixgbe: Fix netpoll to be properly multiqueue aware Our ndo_poll_controller callback is broken for anything but non-multiqueue setups. This fixes that issue. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 200454f..60c4a8b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5360,12 +5360,19 @@ static int ixgbe_del_sanmac_netdev(struct net_device *dev) static void ixgbe_netpoll(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; - disable_irq(adapter->pdev->irq); adapter->flags |= IXGBE_FLAG_IN_NETPOLL; - ixgbe_intr(adapter->pdev->irq, netdev); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + for (i = 0; i < num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + ixgbe_msix_clean_many(0, q_vector); + } + } else { + ixgbe_intr(adapter->pdev->irq, netdev); + } adapter->flags &= ~IXGBE_FLAG_IN_NETPOLL; - enable_irq(adapter->pdev->irq); } #endif -- cgit v0.10.2 From 0c19d6af9253f19b41821c29b9c49c2214f19425 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:25:28 +0000 Subject: ixgbe: Fix usage of second flags bitmap when using LRO/RSC A second set of feature flag bits was added, and the hardware RSC engine flags were moved there. However, the code itself didn't make the move completely to use the new bitmap. Signed-off-by: Peter P Waskiewicz Jr Acked-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 2a97800..7ddb50c 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1999,13 +1999,13 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) ethtool_op_set_flags(netdev, data); - if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)) + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) return 0; /* if state changes we need to update adapter->flags and reset */ if ((!!(data & ETH_FLAG_LRO)) != - (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) { - adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED; + (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { + adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; if (netif_running(netdev)) ixgbe_reinit_locked(adapter); else diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 60c4a8b..110c65a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -780,7 +780,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE) + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) rsc_count = ixgbe_get_rsc_count(rx_desc); if (rsc_count) { @@ -2036,7 +2036,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); } } else { - if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) && + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else @@ -2165,7 +2165,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); } - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { /* Enable 82599 HW-RSC */ for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i].reg_idx; @@ -3812,8 +3812,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; } else if (hw->mac.type == ixgbe_mac_82599EB) { adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; - adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE; - adapter->flags |= IXGBE_FLAG2_RSC_ENABLED; + adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->ring_feature[RING_F_FDIR].indices = IXGBE_MAX_FDIR_INDICES; @@ -5618,7 +5618,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; /* make sure the EEPROM is good */ -- cgit v0.10.2 From 0a924578bc4a2823a95c151f56975c71f5c156bb Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:26:00 +0000 Subject: ixgbe: Fix RSC completion delay causing Rx interrupts to stop When a user disables interrupt throttling with ethtool on 82599 devices, the interrupt timer may not be re-enabled if hardware RSC is running. The RSC completions in hardware don't complete before the next ITR event tries to fire, so the ITR timer never gets re-armed. This patch increases the amount of time between interrupts when throttling is disabled (rx-usecs = 0) when the hardware RSC deature is enabled. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 1b12c7b..e11d83d 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -96,6 +96,8 @@ #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 #define IXGBE_TX_FLAGS_VLAN_SHIFT 16 +#define IXGBE_MAX_RSC_INT_RATE 162760 + /* wrapper around a pointer to a socket buffer, * so a DMA handle can be stored along with the buffer */ struct ixgbe_tx_buffer { diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 7ddb50c..79144e9 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1975,7 +1975,10 @@ static int ixgbe_set_coalesce(struct net_device *netdev, * any other value means disable eitr, which is best * served by setting the interrupt rate very high */ - adapter->eitr_param = IXGBE_MAX_INT_RATE; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + adapter->eitr_param = IXGBE_MAX_RSC_INT_RATE; + else + adapter->eitr_param = IXGBE_MAX_INT_RATE; adapter->itr_setting = 0; } -- cgit v0.10.2