From: Greg Kroah-Hartman Date: Thu, 14 Jun 2012 17:41:40 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.35~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98d7b41dddac2d6f6a9482a0f5592963fd3a6978;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: can-c_can-fix-an-interrupt-thrash-issue-with-c_can-driver.patch can-c_can-fix-bug-echo_skb-is-occupied-during-transmit.patch can-c_can-fix-race-condition-in-c_can_open.patch cfg80211-fix-interface-combinations-check.patch hwmon-fam15h_power-increase-output-resolution.patch net-sierra_net-device-ids-for-aircard-320u.patch --- diff --git a/queue-3.0/can-c_can-fix-an-interrupt-thrash-issue-with-c_can-driver.patch b/queue-3.0/can-c_can-fix-an-interrupt-thrash-issue-with-c_can-driver.patch new file mode 100644 index 00000000000..fc4b4a6409b --- /dev/null +++ b/queue-3.0/can-c_can-fix-an-interrupt-thrash-issue-with-c_can-driver.patch @@ -0,0 +1,68 @@ +From 148c87c89e1a8863d3d965179f3ab1a06490569e Mon Sep 17 00:00:00 2001 +From: AnilKumar Ch +Date: Wed, 23 May 2012 17:45:10 +0530 +Subject: can: c_can: fix an interrupt thrash issue with c_can driver + +From: AnilKumar Ch + +commit 148c87c89e1a8863d3d965179f3ab1a06490569e upstream. + +This patch fixes an interrupt thrash issue with c_can driver. + +In c_can_isr() function interrupts are disabled and enabled only in +c_can_poll() function. c_can_isr() & c_can_poll() both read the +irqstatus flag. However, irqstatus is always read as 0 in c_can_poll() +because all C_CAN interrupts are disabled in c_can_isr(). This causes +all interrupts to be re-enabled in c_can_poll() which in turn causes +another interrupt since the event is not really handled. This keeps +happening causing a flood of interrupts. + +To fix this, read the irqstatus register in isr and use the same cached +value in the poll function. + +Signed-off-by: AnilKumar Ch +Acked-by: Wolfgang Grandegger +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/c_can/c_can.c | 7 +++---- + drivers/net/can/c_can/c_can.h | 1 + + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -954,7 +954,7 @@ static int c_can_poll(struct napi_struct + struct net_device *dev = napi->dev; + struct c_can_priv *priv = netdev_priv(dev); + +- irqstatus = priv->read_reg(priv, &priv->regs->interrupt); ++ irqstatus = priv->irqstatus; + if (!irqstatus) + goto end; + +@@ -1032,12 +1032,11 @@ end: + + static irqreturn_t c_can_isr(int irq, void *dev_id) + { +- u16 irqstatus; + struct net_device *dev = (struct net_device *)dev_id; + struct c_can_priv *priv = netdev_priv(dev); + +- irqstatus = priv->read_reg(priv, &priv->regs->interrupt); +- if (!irqstatus) ++ priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); ++ if (!priv->irqstatus) + return IRQ_NONE; + + /* disable all interrupts and schedule the NAPI */ +--- a/drivers/net/can/c_can/c_can.h ++++ b/drivers/net/can/c_can/c_can.h +@@ -76,6 +76,7 @@ struct c_can_priv { + unsigned int tx_next; + unsigned int tx_echo; + void *priv; /* for board-specific data */ ++ u16 irqstatus; + }; + + struct net_device *alloc_c_can_dev(void); diff --git a/queue-3.0/can-c_can-fix-bug-echo_skb-is-occupied-during-transmit.patch b/queue-3.0/can-c_can-fix-bug-echo_skb-is-occupied-during-transmit.patch new file mode 100644 index 00000000000..d8395234c74 --- /dev/null +++ b/queue-3.0/can-c_can-fix-bug-echo_skb-is-occupied-during-transmit.patch @@ -0,0 +1,67 @@ +From 617caccebe451716df21c069b079d5936ed7b0f3 Mon Sep 17 00:00:00 2001 +From: AnilKumar Ch +Date: Wed, 23 May 2012 17:45:09 +0530 +Subject: can: c_can: fix "BUG! echo_skb is occupied!" during transmit + +From: AnilKumar Ch + +commit 617caccebe451716df21c069b079d5936ed7b0f3 upstream. + +This patch fixes an issue with transmit routine, which causes +"can_put_echo_skb: BUG! echo_skb is occupied!" message when +using "cansequence -p" on D_CAN controller. + +In c_can driver, while transmitting packets tx_echo flag holds +the no of can frames put for transmission into the hardware. + +As the comment above c_can_do_tx() indicates, if we find any packet +which is not transmitted then we should stop looking for more. +In the current implementation this is not taken care of causing the +said message. + +Also, fix the condition used to find if the packet is transmitted +or not. Current code skips the first tx message object and ends up +checking one extra invalid object. + +While at it, fix the comment on top of c_can_do_tx() to use the +terminology "packet" instead of "package" since it is more +standard. + +Signed-off-by: AnilKumar Ch +Acked-by: Wolfgang Grandegger +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/c_can/c_can.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -688,7 +688,7 @@ static int c_can_get_berr_counter(const + * + * We iterate from priv->tx_echo to priv->tx_next and check if the + * packet has been transmitted, echo it back to the CAN framework. +- * If we discover a not yet transmitted package, stop looking for more. ++ * If we discover a not yet transmitted packet, stop looking for more. + */ + static void c_can_do_tx(struct net_device *dev) + { +@@ -700,7 +700,7 @@ static void c_can_do_tx(struct net_devic + for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { + msg_obj_no = get_tx_echo_msg_obj(priv); + val = c_can_read_reg32(priv, &priv->regs->txrqst1); +- if (!(val & (1 << msg_obj_no))) { ++ if (!(val & (1 << (msg_obj_no - 1)))) { + can_get_echo_skb(dev, + msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); + stats->tx_bytes += priv->read_reg(priv, +@@ -708,6 +708,8 @@ static void c_can_do_tx(struct net_devic + & IF_MCONT_DLC_MASK; + stats->tx_packets++; + c_can_inval_msg_object(dev, 0, msg_obj_no); ++ } else { ++ break; + } + } + diff --git a/queue-3.0/can-c_can-fix-race-condition-in-c_can_open.patch b/queue-3.0/can-c_can-fix-race-condition-in-c_can_open.patch new file mode 100644 index 00000000000..95aed648f24 --- /dev/null +++ b/queue-3.0/can-c_can-fix-race-condition-in-c_can_open.patch @@ -0,0 +1,45 @@ +From f461f27a4436dbe691908fe08b867ef888848cc3 Mon Sep 17 00:00:00 2001 +From: AnilKumar Ch +Date: Wed, 23 May 2012 17:45:11 +0530 +Subject: can: c_can: fix race condition in c_can_open() + +From: AnilKumar Ch + +commit f461f27a4436dbe691908fe08b867ef888848cc3 upstream. + +Fix the issue of C_CAN interrupts getting disabled forever when canconfig +utility is used multiple times. According to NAPI usage we disable all +the hardware interrupts in ISR and re-enable them in poll(). Current +implementation calls napi_enable() after hardware interrupts are enabled. +If we get any interrupts between these two steps then we do not process +those interrupts because napi is not enabled. Mostly these interrupts +come because of STATUS is not 0x7 or ERROR interrupts. If napi_enable() +happens before HW interrupts enabled then c_can_poll() function will be +called eventual re-enabling. + +This patch moves the napi_enable() call before interrupts enabled. + +Signed-off-by: AnilKumar Ch +Acked-by: Wolfgang Grandegger +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/c_can/c_can.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -1066,10 +1066,11 @@ static int c_can_open(struct net_device + goto exit_irq_fail; + } + ++ napi_enable(&priv->napi); ++ + /* start the c_can controller */ + c_can_start(dev); + +- napi_enable(&priv->napi); + netif_start_queue(dev); + + return 0; diff --git a/queue-3.0/cfg80211-fix-interface-combinations-check.patch b/queue-3.0/cfg80211-fix-interface-combinations-check.patch new file mode 100644 index 00000000000..57d811373d8 --- /dev/null +++ b/queue-3.0/cfg80211-fix-interface-combinations-check.patch @@ -0,0 +1,79 @@ +From 463454b5dbd8dbab6e2fc6c557329e5b811b9c32 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 5 Jun 2012 12:16:50 +0200 +Subject: cfg80211: fix interface combinations check + +From: Johannes Berg + +commit 463454b5dbd8dbab6e2fc6c557329e5b811b9c32 upstream. + +If a given interface combination doesn't contain +a required interface type then we missed checking +that and erroneously allowed it even though iface +type wasn't there at all. Add a check that makes +sure that all interface types are accounted for. + +Reported-by: Mohammed Shafi Shajakhan +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/util.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -937,6 +937,7 @@ int cfg80211_can_change_interface(struct + enum nl80211_iftype iftype) + { + struct wireless_dev *wdev_iter; ++ u32 used_iftypes = BIT(iftype); + int num[NUM_NL80211_IFTYPES]; + int total = 1; + int i, j; +@@ -970,12 +971,14 @@ int cfg80211_can_change_interface(struct + + num[wdev_iter->iftype]++; + total++; ++ used_iftypes |= BIT(wdev_iter->iftype); + } + mutex_unlock(&rdev->devlist_mtx); + + for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; + struct ieee80211_iface_limit *limits; ++ u32 all_iftypes = 0; + + c = &rdev->wiphy.iface_combinations[i]; + +@@ -990,6 +993,7 @@ int cfg80211_can_change_interface(struct + if (rdev->wiphy.software_iftypes & BIT(iftype)) + continue; + for (j = 0; j < c->n_limits; j++) { ++ all_iftypes |= limits[j].types; + if (!(limits[j].types & BIT(iftype))) + continue; + if (limits[j].max < num[iftype]) +@@ -997,7 +1001,20 @@ int cfg80211_can_change_interface(struct + limits[j].max -= num[iftype]; + } + } +- /* yay, it fits */ ++ ++ /* ++ * Finally check that all iftypes that we're currently ++ * using are actually part of this combination. If they ++ * aren't then we can't use this combination and have ++ * to continue to the next. ++ */ ++ if ((all_iftypes & used_iftypes) != used_iftypes) ++ goto cont; ++ ++ /* ++ * This combination covered all interface types and ++ * supported the requested numbers, so we're good. ++ */ + kfree(limits); + return 0; + cont: diff --git a/queue-3.0/hwmon-fam15h_power-increase-output-resolution.patch b/queue-3.0/hwmon-fam15h_power-increase-output-resolution.patch new file mode 100644 index 00000000000..4ccb438aec1 --- /dev/null +++ b/queue-3.0/hwmon-fam15h_power-increase-output-resolution.patch @@ -0,0 +1,54 @@ +From 941a956b0e387b21f385f486c34ef67576775cfc Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 23 Mar 2012 10:02:17 +0100 +Subject: hwmon: (fam15h_power) Increase output resolution + +From: Andre Przywara + +commit 941a956b0e387b21f385f486c34ef67576775cfc upstream. + +On high CPU load the accumulating values in the running_avg_cap +register are very low (below 10), so averaging them too early leads +to unnecessary poor output resolution. Since we pretend to output +micro-Watt we better keep all the bits we have as long as possible. + +Signed-off-by: Andre Przywara +Signed-off-by: Andreas Herrmann +Acked-by: Guenter Roeck +Signed-off-by: Jean Delvare +Signed-off-by: Tim Gardner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/fam15h_power.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/hwmon/fam15h_power.c ++++ b/drivers/hwmon/fam15h_power.c +@@ -61,14 +61,14 @@ static ssize_t show_power(struct device + REG_TDP_RUNNING_AVERAGE, &val); + running_avg_capture = (val >> 4) & 0x3fffff; + running_avg_capture = sign_extend32(running_avg_capture, 21); +- running_avg_range = val & 0xf; ++ running_avg_range = (val & 0xf) + 1; + + pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5), + REG_TDP_LIMIT3, &val); + + tdp_limit = val >> 16; +- curr_pwr_watts = tdp_limit + data->base_tdp - +- (s32)(running_avg_capture >> (running_avg_range + 1)); ++ curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range; ++ curr_pwr_watts -= running_avg_capture; + curr_pwr_watts *= data->tdp_to_watts; + + /* +@@ -78,7 +78,7 @@ static ssize_t show_power(struct device + * scaling factor 1/(2^16). For conversion we use + * (10^6)/(2^16) = 15625/(2^10) + */ +- curr_pwr_watts = (curr_pwr_watts * 15625) >> 10; ++ curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range); + return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts); + } + static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL); diff --git a/queue-3.0/net-sierra_net-device-ids-for-aircard-320u.patch b/queue-3.0/net-sierra_net-device-ids-for-aircard-320u.patch new file mode 100644 index 00000000000..3e326ca31d6 --- /dev/null +++ b/queue-3.0/net-sierra_net-device-ids-for-aircard-320u.patch @@ -0,0 +1,68 @@ +From dd03cff23d694cfb0fdae80cb618e7ced05ea696 Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +Date: Tue, 5 Jun 2012 21:18:10 +0000 +Subject: net: sierra_net: device IDs for Aircard 320U++ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjørn Mork + +commit dd03cff23d694cfb0fdae80cb618e7ced05ea696 upstream. + +Adding device IDs for Aircard 320U and two other devices +found in the out-of-tree version of this driver. + +Cc: linux@sierrawireless.com +Cc: Autif Khan +Cc: Tom Cassidy +Signed-off-by: Bjørn Mork +Acked-by: Greg Kroah-Hartman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/sierra_net.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/sierra_net.c ++++ b/drivers/net/usb/sierra_net.c +@@ -943,7 +943,7 @@ struct sk_buff *sierra_net_tx_fixup(stru + } + + static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; +-static const struct sierra_net_info_data sierra_net_info_data_68A3 = { ++static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { + .rx_urb_size = 8 * 1024, + .whitelist = { + .infolen = ARRAY_SIZE(sierra_net_ifnum_list), +@@ -951,7 +951,7 @@ static const struct sierra_net_info_data + } + }; + +-static const struct driver_info sierra_net_info_68A3 = { ++static const struct driver_info sierra_net_info_direct_ip = { + .description = "Sierra Wireless USB-to-WWAN Modem", + .flags = FLAG_WWAN | FLAG_SEND_ZLP, + .bind = sierra_net_bind, +@@ -959,12 +959,18 @@ static const struct driver_info sierra_n + .status = sierra_net_status, + .rx_fixup = sierra_net_rx_fixup, + .tx_fixup = sierra_net_tx_fixup, +- .data = (unsigned long)&sierra_net_info_data_68A3, ++ .data = (unsigned long)&sierra_net_info_data_direct_ip, + }; + + static const struct usb_device_id products[] = { + {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ +- .driver_info = (unsigned long) &sierra_net_info_68A3}, ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, ++ {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ ++ .driver_info = (unsigned long) &sierra_net_info_direct_ip}, + + {}, /* last item */ + }; diff --git a/queue-3.0/series b/queue-3.0/series index 3e530476f51..6c3ff4324a0 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -3,3 +3,9 @@ btree-fix-tree-corruption-in-btree_get_prev.patch powerpc-fix-kernel-panic-during-kernel-module-load.patch crypto-aesni-intel-fix-unaligned-cbc-decrypt-for-x86-32.patch mac80211-clean-up-remain-on-channel-on-interface-stop.patch +cfg80211-fix-interface-combinations-check.patch +net-sierra_net-device-ids-for-aircard-320u.patch +can-c_can-fix-bug-echo_skb-is-occupied-during-transmit.patch +can-c_can-fix-an-interrupt-thrash-issue-with-c_can-driver.patch +can-c_can-fix-race-condition-in-c_can_open.patch +hwmon-fam15h_power-increase-output-resolution.patch