From 509e7861d8a5e26bb07b5a3a13e2b9e442283631 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 26 Jan 2011 17:10:59 +0800 Subject: Bluetooth: add Atheros BT AR9285 fw supported Add the btusb.c blacklist [03f0:311d] for Atheros AR9285 Malbec BT and add to ath3k.c ath3-1.fw (md5:1211fa34c09e10ba48381586b7c3883d) supported this device. Signed-off-by: Cho, Yu-Chen Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a126e614601..333c21289d9 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -39,6 +39,8 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03F0, 0x311D) }, { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1da773f899a..4cefa91e6c3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -102,6 +102,9 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, + /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, -- cgit v1.2.3-18-g5258 From e733fb62082b3b187870dfba28d5f6730b8436c4 Mon Sep 17 00:00:00 2001 From: Bao Liang Date: Sat, 29 Jan 2011 21:39:37 +0800 Subject: Bluetooth: Set conn state to BT_DISCONN to avoid multiple responses This patch fixes a minor issue that two connection responses will be sent for one L2CAP connection request. If the L2CAP connection request is first blocked due to security reason and responded with reason "security block", the state of the connection remains BT_CONNECT2. If a pairing procedure completes successfully before the ACL connection is down, local host will send another connection complete response. See the following packets captured by hcidump. 2010-12-07 22:21:24.928096 < ACL data: handle 12 flags 0x00 dlen 16 0000: 0c 00 01 00 03 19 08 00 41 00 53 00 03 00 00 00 ........A.S..... ... ... 2010-12-07 22:21:35.791747 > HCI Event: Auth Complete (0x06) plen 3 status 0x00 handle 12 ... ... 2010-12-07 22:21:35.872372 > ACL data: handle 12 flags 0x02 dlen 16 L2CAP(s): Connect rsp: dcid 0x0054 scid 0x0040 result 0 status 0 Connection successful Signed-off-by: Liang Bao Acked-by: Ville Tervo Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 7550abb0c96..675614e38e1 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -859,6 +859,7 @@ static void __l2cap_sock_close(struct sock *sk, int reason) result = L2CAP_CR_SEC_BLOCK; else result = L2CAP_CR_BAD_PSM; + sk->sk_state = BT_DISCONN; rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); -- cgit v1.2.3-18-g5258 From c91d01556f52255a31575be0cb1981c92a2a5028 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 9 Feb 2011 08:46:06 +0100 Subject: iwl3945: remove plcp check Patch fixes: https://bugzilla.redhat.com/show_bug.cgi?id=654599 Many users report very low speed problem on 3945 devices, this patch fixes problem, but only for some of them. For unknown reason, sometimes after hw scanning, device is not able to receive frames at high rate. Since plcp health check may request hw scan to "reset radio", performance problem start to be observable after update kernel to .35, where plcp check was introduced. Bug reporter confirmed that removing plcp check fixed problem for him. Reported-and-tested-by: SilvioTO Cc: stable@kernel.org # 2.6.35+ Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a9b852be450..3eb14fd2204 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2734,7 +2734,6 @@ static struct iwl_lib_ops iwl3945_lib = { .isr_ops = { .isr = iwl_isr_legacy, }, - .check_plcp_health = iwl3945_good_plcp_health, .debugfs_ops = { .rx_stats_read = iwl3945_ucode_rx_stats_read, -- cgit v1.2.3-18-g5258 From a7b545f7fe753ca3dc1b51ca57f90cd59d974e44 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 8 Feb 2011 18:43:19 +0200 Subject: mac80211: add missing locking in ieee80211_reconfig When suspending an associated system, and then resuming, the station vif is being reconfigured without taking the sdata->u.mgd.mtx lock, which results in the following warning: WARNING: at net/mac80211/mlme.c:101 ieee80211_ap_probereq_get+0x58/0xb8 [mac80211]() Modules linked in: wl12xx_sdio wl12xx firmware_class crc7 mac80211 cfg80211 [last unloaded: crc7] Backtrace: [] (dump_backtrace+0x0/0x118) from [] (dump_stack+0x20/0x24) r7:00000000 r6:bf12d6ec r5:bf154aac r4:00000065 [] (dump_stack+0x0/0x24) from [] (warn_slowpath_common+0x5c/0x74) [] (warn_slowpath_common+0x0/0x74) from [] (warn_slowpath_null+0x2c/0x34) r9:000024ff r8:cd006460 r7:00000001 r6:00000000 r5:00000000 r4:cf1394a0 [] (warn_slowpath_null+0x0/0x34) from [] (ieee80211_ap_probereq_get+0x58/0xb8 [mac80211]) [] (ieee80211_ap_probereq_get+0x0/0xb8 [mac80211]) from [] (wl1271_cmd_build_ap_probe_req+0x30/0xf8 [wl12xx]) r4:cd007440 [] (wl1271_cmd_build_ap_probe_req+0x0/0xf8 [wl12xx]) from [] (wl1271_op_bss_info_changed+0x4c4/0x808 [wl12xx]) r5:cd007440 r4:000003b4 [] (wl1271_op_bss_info_changed+0x0/0x808 [wl12xx]) from [] (ieee80211_bss_info_change_notify+0x1a4/0x1f8 [mac80211]) [] (ieee80211_bss_info_change_notify+0x0/0x1f8 [mac80211]) from [] (ieee80211_reconfig+0x4d0/0x668 [mac80211]) r8:cf0eeea4 r7:cd00671c r6:00000000 r5:cd006460 r4:cf1394a0 [] (ieee80211_reconfig+0x0/0x668 [mac80211]) from [] (ieee80211_resume+0x60/0x70 [mac80211]) [] (ieee80211_resume+0x0/0x70 [mac80211]) from [] (wiphy_resume+0x6c/0x7c [cfg80211]) r5:cd006248 r4:cd006110 [] (wiphy_resume+0x0/0x7c [cfg80211]) from [] (legacy_resume+0x38/0x70) r7:00000000 r6:00000000 r5:cd006248 r4:cd0062fc [] (legacy_resume+0x0/0x70) from [] (device_resume+0x168/0x1a0) r8:c04ca8d8 r7:cd00627c r6:00000010 r5:cd006248 r4:cd0062fc [] (device_resume+0x0/0x1a0) from [] (dpm_resume_end+0xf8/0x3bc) r7:00000000 r6:00000005 r5:cd006248 r4:cd0062fc [] (dpm_resume_end+0x0/0x3bc) from [] (suspend_devices_and_enter+0x1b0/0x204) [] (suspend_devices_and_enter+0x0/0x204) from [] (enter_state+0xf0/0x148) r7:c037e978 r6:00000003 r5:c043d807 r4:00000000 [] (enter_state+0x0/0x148) from [] (state_store+0xa4/0xcc) r7:c037e978 r6:00000003 r5:00000003 r4:c043d807 [] (state_store+0x0/0xcc) from [] (kobj_attr_store+0x20/0x24) [] (kobj_attr_store+0x0/0x24) from [] (sysfs_write_file+0x11c/0x150) [] (sysfs_write_file+0x0/0x150) from [] (vfs_write+0xc0/0x14c) [] (vfs_write+0x0/0x14c) from [] (sys_write+0x4c/0x78) r8:40126000 r7:00000004 r6:cf1a7c80 r5:00000000 r4:00000000 [] (sys_write+0x0/0x78) from [] (ret_fast_syscall+0x0/0x30) r8:c00502c8 r7:00000004 r6:403525e8 r5:40126000 r4:00000004 Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cf68700abff..d036597aabb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1210,7 +1210,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: changed |= BSS_CHANGED_ASSOC; + mutex_lock(&sdata->u.mgd.mtx); ieee80211_bss_info_change_notify(sdata, changed); + mutex_unlock(&sdata->u.mgd.mtx); break; case NL80211_IFTYPE_ADHOC: changed |= BSS_CHANGED_IBSS; -- cgit v1.2.3-18-g5258 From 520732af9158308e96245b54f1d573861eafb631 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Feb 2011 20:05:25 -0800 Subject: net: fix ifenslave build flags -I (include path) should be specified for host builds. This one was overlooked somehow. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=25902 Signed-off-by: Randy Dunlap Reported-by: Alexey Salmin Signed-off-by: David S. Miller --- Documentation/networking/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile index 5aba7a33aee..24c308dd3fd 100644 --- a/Documentation/networking/Makefile +++ b/Documentation/networking/Makefile @@ -4,6 +4,8 @@ obj- := dummy.o # List of programs to build hostprogs-y := ifenslave +HOSTCFLAGS_ifenslave.o += -I$(objtree)/usr/include + # Tell kbuild to always build the programs always := $(hostprogs-y) -- cgit v1.2.3-18-g5258 From 0b150932197b185ad5816932912e648116c7a96a Mon Sep 17 00:00:00 2001 From: Hiroaki SHIMODA Date: Thu, 10 Feb 2011 23:08:33 -0800 Subject: xfrm: avoid possible oopse in xfrm_alloc_dst Commit 80c802f3073e84 (xfrm: cache bundles instead of policies for outgoing flows) introduced possible oopse when dst_alloc returns NULL. Signed-off-by: Hiroaki SHIMODA Signed-off-by: David S. Miller --- net/xfrm/xfrm_policy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8b3ef404c79..6459588befc 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1340,10 +1340,13 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) default: BUG(); } - xdst = dst_alloc(dst_ops) ?: ERR_PTR(-ENOBUFS); + xdst = dst_alloc(dst_ops); xfrm_policy_put_afinfo(afinfo); - xdst->flo.ops = &xfrm_bundle_fc_ops; + if (likely(xdst)) + xdst->flo.ops = &xfrm_bundle_fc_ops; + else + xdst = ERR_PTR(-ENOBUFS); return xdst; } -- cgit v1.2.3-18-g5258 From 946bf5ee3c46f73b5cbd52aab594697b1a132d1f Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Fri, 11 Feb 2011 11:21:57 -0800 Subject: ip_gre: Add IPPROTO_GRE to flowi in ipgre_tunnel_xmit Commit 5811662b15db018c740c57d037523683fd3e6123 ("net: use the macros defined for the members of flowi") accidentally removed the setting of IPPROTO_GRE from the struct flowi in ipgre_tunnel_xmit. This patch restores it. Signed-off-by: Steffen Klassert Acked-by: Changli Gao Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index eb68a0e34e4..6613edfac28 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -775,6 +775,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev .fl4_dst = dst, .fl4_src = tiph->saddr, .fl4_tos = RT_TOS(tos), + .proto = IPPROTO_GRE, .fl_gre_key = tunnel->parms.o_key }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { -- cgit v1.2.3-18-g5258 From 6b0d6a9b4296fa16a28d10d416db7a770fc03287 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 11 Feb 2011 12:36:55 +0000 Subject: bridge: Fix mglist corruption that leads to memory corruption The list mp->mglist is used to indicate whether a multicast group is active on the bridge interface itself as opposed to one of the constituent interfaces in the bridge. Unfortunately the operation that adds the mp->mglist node to the list neglected to check whether it has already been added. This leads to list corruption in the form of nodes pointing to itself. Normally this would be quite obvious as it would cause an infinite loop when walking the list. However, as this list is never actually walked (which means that we don't really need it, I'll get rid of it in a subsequent patch), this instead is hidden until we perform a delete operation on the affected nodes. As the same node may now be pointed to by more than one node, the delete operations can then cause modification of freed memory. This was observed in practice to cause corruption in 512-byte slabs, most commonly leading to crashes in jbd2. Thanks to Josef Bacik for pointing me in the right direction. Reported-by: Ian Page Hands Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/bridge/br_multicast.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index f701a21acb3..fdbd41c76ec 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -719,7 +719,8 @@ static int br_multicast_add_group(struct net_bridge *br, goto err; if (!port) { - hlist_add_head(&mp->mglist, &br->mglist); + if (hlist_unhashed(&mp->mglist)) + hlist_add_head(&mp->mglist, &br->mglist); mod_timer(&mp->timer, now + br->multicast_membership_interval); goto out; } -- cgit v1.2.3-18-g5258 From 24f9cdcbd743fd6adb8fb83688d8d86dcccde662 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 11 Feb 2011 12:42:07 +0000 Subject: bridge: Fix timer typo that may render snooping less effective In a couple of spots where we are supposed to modify the port group timer (p->timer) we instead modify the bridge interface group timer (mp->timer). The effect of this is mostly harmless. However, it can cause port subscriptions to be longer than they should be, thus making snooping less effective. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/bridge/br_multicast.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index fdbd41c76ec..c558274051e 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1178,7 +1178,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) - mod_timer(&mp->timer, now + max_delay); + mod_timer(&p->timer, now + max_delay); } out: @@ -1249,7 +1249,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) - mod_timer(&mp->timer, now + max_delay); + mod_timer(&p->timer, now + max_delay); } out: -- cgit v1.2.3-18-g5258 From 8a870178c0ad1bae9994c99bd01eb10c9903e616 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 12 Feb 2011 01:05:42 -0800 Subject: bridge: Replace mp->mglist hlist with a bool As it turns out we never need to walk through the list of multicast groups subscribed by the bridge interface itself (the only time we'd want to do that is when we shut down the bridge, in which case we simply walk through all multicast groups), we don't really need to keep an hlist for mp->mglist. This means that we can replace it with just a single bit to indicate whether the bridge interface is subscribed to a group. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/bridge/br_input.c | 2 +- net/bridge/br_multicast.c | 16 +++++++--------- net/bridge/br_private.h | 3 +-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 6f6d8e1b776..88e4aa9cb1f 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -80,7 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb) if (is_multicast_ether_addr(dest)) { mdst = br_mdb_get(br, skb); if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { - if ((mdst && !hlist_unhashed(&mdst->mglist)) || + if ((mdst && mdst->mglist) || br_multicast_is_router(br)) skb2 = skb; br_multicast_forward(mdst, skb, skb2); diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index c558274051e..09d5c098792 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -232,8 +232,7 @@ static void br_multicast_group_expired(unsigned long data) if (!netif_running(br->dev) || timer_pending(&mp->timer)) goto out; - if (!hlist_unhashed(&mp->mglist)) - hlist_del_init(&mp->mglist); + mp->mglist = false; if (mp->ports) goto out; @@ -276,7 +275,7 @@ static void br_multicast_del_pg(struct net_bridge *br, del_timer(&p->query_timer); call_rcu_bh(&p->rcu, br_multicast_free_pg); - if (!mp->ports && hlist_unhashed(&mp->mglist) && + if (!mp->ports && !mp->mglist && netif_running(br->dev)) mod_timer(&mp->timer, jiffies); @@ -528,7 +527,7 @@ static void br_multicast_group_query_expired(unsigned long data) struct net_bridge *br = mp->br; spin_lock(&br->multicast_lock); - if (!netif_running(br->dev) || hlist_unhashed(&mp->mglist) || + if (!netif_running(br->dev) || !mp->mglist || mp->queries_sent >= br->multicast_last_member_count) goto out; @@ -719,8 +718,7 @@ static int br_multicast_add_group(struct net_bridge *br, goto err; if (!port) { - if (hlist_unhashed(&mp->mglist)) - hlist_add_head(&mp->mglist, &br->mglist); + mp->mglist = true; mod_timer(&mp->timer, now + br->multicast_membership_interval); goto out; } @@ -1166,7 +1164,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, max_delay *= br->multicast_last_member_count; - if (!hlist_unhashed(&mp->mglist) && + if (mp->mglist && (timer_pending(&mp->timer) ? time_after(mp->timer.expires, now + max_delay) : try_to_del_timer_sync(&mp->timer) >= 0)) @@ -1237,7 +1235,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, goto out; max_delay *= br->multicast_last_member_count; - if (!hlist_unhashed(&mp->mglist) && + if (mp->mglist && (timer_pending(&mp->timer) ? time_after(mp->timer.expires, now + max_delay) : try_to_del_timer_sync(&mp->timer) >= 0)) @@ -1284,7 +1282,7 @@ static void br_multicast_leave_group(struct net_bridge *br, br->multicast_last_member_interval; if (!port) { - if (!hlist_unhashed(&mp->mglist) && + if (mp->mglist && (timer_pending(&mp->timer) ? time_after(mp->timer.expires, time) : try_to_del_timer_sync(&mp->timer) >= 0)) { diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 84aac7734bf..4e1b620b6be 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -84,13 +84,13 @@ struct net_bridge_port_group { struct net_bridge_mdb_entry { struct hlist_node hlist[2]; - struct hlist_node mglist; struct net_bridge *br; struct net_bridge_port_group __rcu *ports; struct rcu_head rcu; struct timer_list timer; struct timer_list query_timer; struct br_ip addr; + bool mglist; u32 queries_sent; }; @@ -238,7 +238,6 @@ struct net_bridge spinlock_t multicast_lock; struct net_bridge_mdb_htable __rcu *mdb; struct hlist_head router_list; - struct hlist_head mglist; struct timer_list multicast_router_timer; struct timer_list multicast_querier_timer; -- cgit v1.2.3-18-g5258 From 7ec79270d7de0c8ca602c47cb25a9652ec28f37f Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 31 Jan 2011 12:00:59 +0000 Subject: net: dcb: application priority is per net_device The app_data priority may not be the same for all net devices. In order for stacks with application notifiers to identify the specific net device dcb_app_type should be passed in the ptr. This allows handlers to use dev_get_by_name() to pin priority to net devices. Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 6b03f561cae..712ca026040 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1613,6 +1613,10 @@ EXPORT_SYMBOL(dcb_getapp); u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) { struct dcb_app_type *itr; + struct dcb_app_type event; + + memcpy(&event.name, dev->name, sizeof(event.name)); + memcpy(&event.app, new, sizeof(event.app)); spin_lock(&dcb_lock); /* Search for existing match and replace */ @@ -1644,7 +1648,7 @@ u8 dcb_setapp(struct net_device *dev, struct dcb_app *new) } out: spin_unlock(&dcb_lock); - call_dcbevent_notifiers(DCB_APP_EVENT, new); + call_dcbevent_notifiers(DCB_APP_EVENT, &event); return 0; } EXPORT_SYMBOL(dcb_setapp); -- cgit v1.2.3-18-g5258 From d3337de52af7fb0ebe605b02b740be4ee7dee9eb Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 10 Feb 2011 11:57:16 +0000 Subject: Don't potentially dereference NULL in net/dcb/dcbnl.c:dcbnl_getapp() nla_nest_start() may return NULL. If it does then we'll blow up in nla_nest_end() when we dereference the pointer. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- net/dcb/dcbnl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 712ca026040..d5074a56728 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -626,6 +626,9 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, dcb->cmd = DCB_CMD_GAPP; app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); + if (!app_nest) + goto out_cancel; + ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); if (ret) goto out_cancel; -- cgit v1.2.3-18-g5258 From ab60707ffe9920b66b4fff5181b44b14cd091472 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 10 Feb 2011 10:58:45 +0000 Subject: USB Network driver infrastructure: Fix leak when usb_autopm_get_interface() returns less than zero in kevent(). We'll leak the memory allocated to 'urb' in drivers/net/usb/usbnet.c:kevent() when we 'goto fail_lowmem' and the 'urb' variable goes out of scope while still completely unused. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ed9a41643ff..95c41d56631 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -931,8 +931,10 @@ fail_halt: if (urb != NULL) { clear_bit (EVENT_RX_MEMORY, &dev->flags); status = usb_autopm_get_interface(dev->intf); - if (status < 0) + if (status < 0) { + usb_free_urb(urb); goto fail_lowmem; + } if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) resched = 0; usb_autopm_put_interface(dev->intf); -- cgit v1.2.3-18-g5258 From c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 13 Feb 2011 16:50:45 -0800 Subject: hisax: Fix unchecked alloc_skb() return. Jesper Juhl noticed that l2_pull_iqueue() does not check to see if alloc_skb() fails. Fix this by first trying to reallocate the headroom if necessary, rather than later after we've made hard to undo state changes. Reported-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/isdn/hisax/isdnl2.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 0858791978d..98ac835281f 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -1243,14 +1243,21 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) st->l2.rc = 0; } +static int l2_hdr_space_needed(struct Layer2 *l2) +{ + int len = test_bit(FLG_LAPD, &l2->flag) ? 2 : 1; + + return len + (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); +} + static void l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; - struct sk_buff *skb, *oskb; + struct sk_buff *skb; struct Layer2 *l2 = &st->l2; u_char header[MAX_HEADER_LEN]; - int i; + int i, hdr_space_needed; int unsigned p1; u_long flags; @@ -1261,6 +1268,16 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) if (!skb) return; + hdr_space_needed = l2_hdr_space_needed(l2); + if (hdr_space_needed > skb_headroom(skb)) { + struct sk_buff *orig_skb = skb; + + skb = skb_realloc_headroom(skb, hdr_space_needed); + if (!skb) { + dev_kfree_skb(orig_skb); + return; + } + } spin_lock_irqsave(&l2->lock, flags); if(test_bit(FLG_MOD128, &l2->flag)) p1 = (l2->vs - l2->va) % 128; @@ -1285,19 +1302,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) l2->vs = (l2->vs + 1) % 8; } spin_unlock_irqrestore(&l2->lock, flags); - p1 = skb->data - skb->head; - if (p1 >= i) - memcpy(skb_push(skb, i), header, i); - else { - printk(KERN_WARNING - "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); - oskb = skb; - skb = alloc_skb(oskb->len + i, GFP_ATOMIC); - memcpy(skb_put(skb, i), header, i); - skb_copy_from_linear_data(oskb, - skb_put(skb, oskb->len), oskb->len); - dev_kfree_skb(oskb); - } + memcpy(skb_push(skb, i), header, i); st->l2.l2l1(st, PH_PULL | INDICATION, skb); test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { -- cgit v1.2.3-18-g5258 From 5b89db0e84bef81f6aa324f8f22a9258ff873de3 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 13 Feb 2011 11:15:35 +0000 Subject: Net, USB, Option, hso: Do not dereference NULL pointer In drivers/net/usb/hso.c::hso_create_bulk_serial_device() we have this code: ... serial = kzalloc(sizeof(*serial), GFP_KERNEL); if (!serial) goto exit; ... exit: hso_free_tiomget(serial); ... hso_free_tiomget() directly dereferences its argument, which in the example above is a NULL pointer, ouch. I could just add a 'if (serial)' test at the 'exit' label, but since most freeing functions in the kernel accept NULL pointers (and it seems like this was also assumed here) I opted to instead change 'hso_free_tiomget()' so that it is safe to call it with a NULL argument. I also modified the function to get rid of a pointles conditional before the call to 'usb_free_urb()' since that function already tests for NULL itself - besides fixing the NULL deref this change also buys us a few bytes in size. Before: $ size drivers/net/usb/hso.o text data bss dec hex filename 32200 592 9960 42752 a700 drivers/net/usb/hso.o After: $ size drivers/net/usb/hso.o text data bss dec hex filename 32196 592 9960 42748 a6fc drivers/net/usb/hso.o Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bed8fcedff4..6d83812603b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2628,15 +2628,15 @@ exit: static void hso_free_tiomget(struct hso_serial *serial) { - struct hso_tiocmget *tiocmget = serial->tiocmget; + struct hso_tiocmget *tiocmget; + if (!serial) + return; + tiocmget = serial->tiocmget; if (tiocmget) { - if (tiocmget->urb) { - usb_free_urb(tiocmget->urb); - tiocmget->urb = NULL; - } + usb_free_urb(tiocmget->urb); + tiocmget->urb = NULL; serial->tiocmget = NULL; kfree(tiocmget); - } } -- cgit v1.2.3-18-g5258 From da1ab3e233eb1ff4116b178006a89ddca7dcd928 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 13 Feb 2011 10:49:32 +0000 Subject: ATM, Solos PCI ADSL2+: Don't deref NULL pointer if net_ratelimit() and alloc_skb() interact badly. If alloc_skb() fails to allocate memory and returns NULL then we want to return -ENOMEM from drivers/atm/solos-pci.c::popen() regardless of the value of net_ratelimit(). The way the code is today, we may not return if net_ratelimit() returns 0, then we'll proceed to pass a NULL pointer to skb_put() which will blow up in our face. This patch ensures that we always return -ENOMEM on alloc_skb() failure and only let the dev_warn() be controlled by the value of net_ratelimit(). Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/atm/solos-pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 73fb1c4f4cd..25ef1a4556e 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -866,8 +866,9 @@ static int popen(struct atm_vcc *vcc) } skb = alloc_skb(sizeof(*header), GFP_ATOMIC); - if (!skb && net_ratelimit()) { - dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); + if (!skb) { + if (net_ratelimit()) + dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); return -ENOMEM; } header = (void *)skb_put(skb, sizeof(*header)); -- cgit v1.2.3-18-g5258 From 539c9aa5ba7c5f71794ef0948c6dd29552f033e4 Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Sun, 13 Feb 2011 17:00:05 -0800 Subject: stmmac: enable wol via magic frame by default. This patch enables it by default when the driver starts. This has been required by many people and seems to actually be useful on STB. At any rate, the WoL modes can be selected and turned-on/off by using the ethtool at run-time by users. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 34a0af3837f..0e5f03135b5 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1560,8 +1560,10 @@ static int stmmac_mac_device_setup(struct net_device *dev) priv->hw = device; - if (device_can_wakeup(priv->device)) + if (device_can_wakeup(priv->device)) { priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ + enable_irq_wake(dev->irq); + } return 0; } -- cgit v1.2.3-18-g5258 From ac09664248e300342e92b937c9894a8149ddf189 Mon Sep 17 00:00:00 2001 From: Toshiharu Okada Date: Tue, 8 Feb 2011 22:15:59 +0000 Subject: pch_gbe: Fix the issue that the receiving data is not normal. This PCH_GBE driver had an issue that the receiving data is not normal. This driver had not removed correctly the padding data which the DMA include in receiving data. This patch fixed this issue. Signed-off-by: Toshiharu Okada Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe_main.c | 97 +++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 4c9a7d4f3fc..f52d852569f 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -29,6 +29,7 @@ const char pch_driver_version[] = DRV_VERSION; #define PCH_GBE_SHORT_PKT 64 #define DSC_INIT16 0xC000 #define PCH_GBE_DMA_ALIGN 0 +#define PCH_GBE_DMA_PADDING 2 #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ #define PCH_GBE_COPYBREAK_DEFAULT 256 #define PCH_GBE_PCI_BAR 1 @@ -1365,16 +1366,13 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info; struct pch_gbe_rx_desc *rx_desc; u32 length; - unsigned char tmp_packet[ETH_HLEN]; unsigned int i; unsigned int cleaned_count = 0; bool cleaned = false; - struct sk_buff *skb; + struct sk_buff *skb, *new_skb; u8 dma_status; u16 gbec_status; u32 tcp_ip_status; - u8 skb_copy_flag = 0; - u8 skb_padding_flag = 0; i = rx_ring->next_to_clean; @@ -1418,55 +1416,70 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, pr_err("Receive CRC Error\n"); } else { /* get receive length */ - /* length convert[-3], padding[-2] */ - length = (rx_desc->rx_words_eob) - 3 - 2; + /* length convert[-3] */ + length = (rx_desc->rx_words_eob) - 3; /* Decide the data conversion method */ if (!adapter->rx_csum) { /* [Header:14][payload] */ - skb_padding_flag = 0; - skb_copy_flag = 1; + if (NET_IP_ALIGN) { + /* Because alignment differs, + * the new_skb is newly allocated, + * and data is copied to new_skb.*/ + new_skb = netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (!new_skb) { + /* dorrop error */ + pr_err("New skb allocation " + "Error\n"); + goto dorrop; + } + skb_reserve(new_skb, NET_IP_ALIGN); + memcpy(new_skb->data, skb->data, + length); + skb = new_skb; + } else { + /* DMA buffer is used as SKB as it is.*/ + buffer_info->skb = NULL; + } } else { /* [Header:14][padding:2][payload] */ - skb_padding_flag = 1; - if (length < copybreak) - skb_copy_flag = 1; - else - skb_copy_flag = 0; - } - - /* Data conversion */ - if (skb_copy_flag) { /* recycle skb */ - struct sk_buff *new_skb; - new_skb = - netdev_alloc_skb(netdev, - length + NET_IP_ALIGN); - if (new_skb) { - if (!skb_padding_flag) { - skb_reserve(new_skb, - NET_IP_ALIGN); + /* The length includes padding length */ + length = length - PCH_GBE_DMA_PADDING; + if ((length < copybreak) || + (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) { + /* Because alignment differs, + * the new_skb is newly allocated, + * and data is copied to new_skb. + * Padding data is deleted + * at the time of a copy.*/ + new_skb = netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (!new_skb) { + /* dorrop error */ + pr_err("New skb allocation " + "Error\n"); + goto dorrop; } + skb_reserve(new_skb, NET_IP_ALIGN); memcpy(new_skb->data, skb->data, - length); - /* save the skb - * in buffer_info as good */ + ETH_HLEN); + memcpy(&new_skb->data[ETH_HLEN], + &skb->data[ETH_HLEN + + PCH_GBE_DMA_PADDING], + length - ETH_HLEN); skb = new_skb; - } else if (!skb_padding_flag) { - /* dorrop error */ - pr_err("New skb allocation Error\n"); - goto dorrop; + } else { + /* Padding data is deleted + * by moving header data.*/ + memmove(&skb->data[PCH_GBE_DMA_PADDING], + &skb->data[0], ETH_HLEN); + skb_reserve(skb, NET_IP_ALIGN); + buffer_info->skb = NULL; } - } else { - buffer_info->skb = NULL; } - if (skb_padding_flag) { - memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); - memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], - ETH_HLEN); - skb_reserve(skb, NET_IP_ALIGN); - - } - + /* The length includes FCS length */ + length = length - ETH_FCS_LEN; /* update status of driver */ adapter->stats.rx_bytes += length; adapter->stats.rx_packets++; -- cgit v1.2.3-18-g5258 From de9963f0f2dfad128b26ae7bf6005f5948416a6d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 14 Feb 2011 17:35:07 +0100 Subject: netfilter: nf_iterate: fix incorrect RCU usage As noticed by Eric, nf_iterate doesn't use RCU correctly by accessing the prev pointer of a RCU protected list element when a verdict of NF_REPEAT is issued. Fix by jumping backwards to the hook invocation directly instead of loading the previous list element before continuing the list iteration. Reported-by: Eric Dumazet Acked-by: Eric Dumazet Signed-off-by: Patrick McHardy --- net/netfilter/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 32fcbe290c0..4aa614b8a96 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -133,6 +133,7 @@ unsigned int nf_iterate(struct list_head *head, /* Optimization: we don't need to hold module reference here, since function can't sleep. --RR */ +repeat: verdict = elem->hook(hook, skb, indev, outdev, okfn); if (verdict != NF_ACCEPT) { #ifdef CONFIG_NETFILTER_DEBUG @@ -145,7 +146,7 @@ unsigned int nf_iterate(struct list_head *head, #endif if (verdict != NF_REPEAT) return verdict; - *i = (*i)->prev; + goto repeat; } } return NF_ACCEPT; -- cgit v1.2.3-18-g5258 From ddfdb508866b3c07b295f6c85c271981d88afe4c Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Mon, 14 Feb 2011 11:44:01 -0800 Subject: net/can/softing: make CAN_SOFTING_CS depend on CAN_SOFTING The statement 'select CAN_SOFTING' may ignore the dependancies for CAN_SOFTING while selecting CAN_SOFTING_CS, as is therefore a bad choice. Signed-off-by: Kurt Van Dijck Acked-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/can/softing/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig index 8ba81b3ddd9..5de46a9a77b 100644 --- a/drivers/net/can/softing/Kconfig +++ b/drivers/net/can/softing/Kconfig @@ -18,7 +18,7 @@ config CAN_SOFTING config CAN_SOFTING_CS tristate "Softing Gmbh CAN pcmcia cards" depends on PCMCIA - select CAN_SOFTING + depends on CAN_SOFTING ---help--- Support for PCMCIA cards from Softing Gmbh & some cards from Vector Gmbh. -- cgit v1.2.3-18-g5258 From 5d17920bd4df6802fb48ccf8283721657c5a8257 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 14 Feb 2011 13:28:00 -0800 Subject: iwlwifi: Delete iwl3945_good_plcp_health. Fixes this build warning: drivers/net/wireless/iwlwifi/iwl-3945.c:411:13: warning: 'iwl3945_good_plcp_health' defined but not used As per Johannes Berg. Signed-off-by: David S. Miller --- drivers/net/wireless/iwlwifi/iwl-3945.c | 66 --------------------------------- 1 file changed, 66 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 3eb14fd2204..39b6f16c87f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -402,72 +402,6 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv, } #endif -/** - * iwl3945_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -static bool iwl3945_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - struct iwl3945_notif_statistics current_stat; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - memcpy(¤t_stat, pkt->u.raw, sizeof(struct - iwl3945_notif_statistics)); - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - combined_plcp_delta = - (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - - le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, the following - * data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(current_stat.rx.ofdm.plcp_err), - combined_plcp_delta, plcp_msec); - /* - * Reset the RF radio due to the high plcp - * error rate - */ - rc = false; - } - } - return rc; -} - void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -- cgit v1.2.3-18-g5258 From 98200ec28a66c8db5839ac26e9a895984206b50f Mon Sep 17 00:00:00 2001 From: Toshiharu Okada Date: Sun, 13 Feb 2011 22:51:54 +0000 Subject: pch_gbe: Fix the MAC Address load issue. With the specification of hardware, the processing at the time of driver starting was modified. This device write automatically the MAC address read from serial ROM into a MAC Adress1A/1B register at the time of power on reset. However, when stable clock is not supplied, the writing of MAC Adress1A/1B register may not be completed. In this case, it is necessary to load MAC address to MAC Address1A/1B register by the MAC Address1 load register. This patch always does the above processing, in order not to be dependent on system environment. Signed-off-by: Toshiharu Okada Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe.h | 2 +- drivers/net/pch_gbe/pch_gbe_main.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index a0c26a99520..e1e33c80fb2 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -73,7 +73,7 @@ struct pch_gbe_regs { struct pch_gbe_regs_mac_adr mac_adr[16]; u32 ADDR_MASK; u32 MIIM; - u32 reserve2; + u32 MAC_ADDR_LOAD; u32 RGMII_ST; u32 RGMII_CTRL; u32 reserve3[3]; diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index f52d852569f..b99e90aca37 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -89,6 +89,12 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data); + +inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) +{ + iowrite32(0x01, &hw->reg->MAC_ADDR_LOAD); +} + /** * pch_gbe_mac_read_mac_addr - Read MAC address * @hw: Pointer to the HW structure @@ -2331,6 +2337,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; pch_gbe_set_ethtool_ops(netdev); + pch_gbe_mac_load_mac_addr(&adapter->hw); pch_gbe_mac_reset_hw(&adapter->hw); /* setup the private structure */ -- cgit v1.2.3-18-g5258 From bb14a1af86d01f66dc9620725ac00a240331afec Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:22 +0000 Subject: cxgb4vf: Check driver parameters in the right place ... Check module parameter validity in the module initialization routine instead of the PCI Device Probe routine. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 56166ae2059..072b64e4937 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2488,17 +2488,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, struct port_info *pi; struct net_device *netdev; - /* - * Vet our module parameters. - */ - if (msi != MSI_MSIX && msi != MSI_MSI) { - dev_err(&pdev->dev, "bad module parameter msi=%d; must be %d" - " (MSI-X or MSI) or %d (MSI)\n", msi, MSI_MSIX, - MSI_MSI); - err = -EINVAL; - goto err_out; - } - /* * Print our driver banner the first time we're called to initialize a * device. @@ -2802,7 +2791,6 @@ err_release_regions: err_disable_device: pci_disable_device(pdev); -err_out: return err; } @@ -2915,6 +2903,17 @@ static int __init cxgb4vf_module_init(void) { int ret; + /* + * Vet our module parameters. + */ + if (msi != MSI_MSIX && msi != MSI_MSI) { + printk(KERN_WARNING KBUILD_MODNAME + ": bad module parameter msi=%d; must be %d" + " (MSI-X or MSI) or %d (MSI)\n", + msi, MSI_MSIX, MSI_MSI); + return -EINVAL; + } + /* Debugfs support is optional, just warn if this fails */ cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); if (!cxgb4vf_debugfs_root) -- cgit v1.2.3-18-g5258 From 843635e0349be9e318be224d6241069a40e23320 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:23 +0000 Subject: cxgb4vf: Behave properly when CONFIG_DEBUG_FS isn't defined ... When CONFIG_DEBUG_FS we get "ERR_PTR()"s back from the debugfs routines instead of NULL. Use the right predicates to check for this. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 072b64e4937..2be1088ff60 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2040,7 +2040,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) { int i; - BUG_ON(adapter->debugfs_root == NULL); + BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); /* * Debugfs support is best effort. @@ -2061,7 +2061,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) */ static void cleanup_debugfs(struct adapter *adapter) { - BUG_ON(adapter->debugfs_root == NULL); + BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); /* * Unlike our sister routine cleanup_proc(), we don't need to remove @@ -2700,11 +2700,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, /* * Set up our debugfs entries. */ - if (cxgb4vf_debugfs_root) { + if (!IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) { adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), cxgb4vf_debugfs_root); - if (adapter->debugfs_root == NULL) + if (IS_ERR_OR_NULL(adapter->debugfs_root)) dev_warn(&pdev->dev, "could not create debugfs" " directory"); else @@ -2759,7 +2759,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, */ err_free_debugfs: - if (adapter->debugfs_root) { + if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { cleanup_debugfs(adapter); debugfs_remove_recursive(adapter->debugfs_root); } @@ -2828,7 +2828,7 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) /* * Tear down our debugfs entries. */ - if (adapter->debugfs_root) { + if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { cleanup_debugfs(adapter); debugfs_remove_recursive(adapter->debugfs_root); } @@ -2916,12 +2916,12 @@ static int __init cxgb4vf_module_init(void) /* Debugfs support is optional, just warn if this fails */ cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!cxgb4vf_debugfs_root) + if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) printk(KERN_WARNING KBUILD_MODNAME ": could not create" " debugfs entry, continuing\n"); ret = pci_register_driver(&cxgb4vf_driver); - if (ret < 0) + if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) debugfs_remove(cxgb4vf_debugfs_root); return ret; } -- cgit v1.2.3-18-g5258 From 7e9c26295b2ae1be1285c7c9e593c19ce7ea7eba Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:24 +0000 Subject: cxgb4vf: Quiesce Virtual Interfaces on shutdown ... When a Virtual Machine is rebooted, KVM currently fails to issue a Function Level Reset against any "Attached PCI Devices" (AKA "PCI Passthrough"). In addition to leaving the attached device in a random state in the next booted kernel (which sort of violates the entire idea of a reboot reseting hardware state), this leaves our peer thinking that the link is still up. (Note that a bug has been filed with the KVM folks, #25332, but there's been no response on that as of yet.) So, we add a "->shutdown()" method for the Virtual Function PCI Device to handle administrative shutdowns like a reboot. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 2be1088ff60..6aad64df4dc 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2861,6 +2861,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) pci_release_regions(pdev); } +/* + * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt + * delivery. + */ +static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev) +{ + struct adapter *adapter; + int pidx; + + adapter = pci_get_drvdata(pdev); + if (!adapter) + return; + + /* + * Disable all Virtual Interfaces. This will shut down the + * delivery of all ingress packets into the chip for these + * Virtual Interfaces. + */ + for_each_port(adapter, pidx) { + struct net_device *netdev; + struct port_info *pi; + + if (!test_bit(pidx, &adapter->registered_device_map)) + continue; + + netdev = adapter->port[pidx]; + if (!netdev) + continue; + + pi = netdev_priv(netdev); + t4vf_enable_vi(adapter, pi->viid, false, false); + } + + /* + * Free up all Queues which will prevent further DMA and + * Interrupts allowing various internal pathways to drain. + */ + t4vf_free_sge_resources(adapter); +} + /* * PCI Device registration data structures. */ @@ -2894,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = { .id_table = cxgb4vf_pci_tbl, .probe = cxgb4vf_pci_probe, .remove = __devexit_p(cxgb4vf_pci_remove), + .shutdown = __devexit_p(cxgb4vf_pci_shutdown), }; /* -- cgit v1.2.3-18-g5258 From 0550769bb7f364fb9aeeb9412229fb7790ee79c4 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:25 +0000 Subject: cxgb4vf: Use defined Mailbox Timeout VF Driver should use mailbox command timeout specified in t4fw_interface.h rather than hard-coded value of 500ms. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/t4vf_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 0f51c80475c..192db226ec7 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -171,7 +171,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, delay_idx = 0; ms = delay[0]; - for (i = 0; i < 500; i += ms) { + for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) { if (sleep_ok) { ms = delay[delay_idx]; if (delay_idx < ARRAY_SIZE(delay) - 1) -- cgit v1.2.3-18-g5258 From d11327ad6695db8117c78d70611e71102ceec2ac Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 11 Feb 2011 07:44:16 +0000 Subject: arp_notify: unconditionally send gratuitous ARP for NETDEV_NOTIFY_PEERS. NETDEV_NOTIFY_PEER is an explicit request by the driver to send a link notification while NETDEV_UP/NETDEV_CHANGEADDR generate link notifications as a sort of side effect. In the later cases the sysctl option is present because link notification events can have undesired effects e.g. if the link is flapping. I don't think this applies in the case of an explicit request from a driver. This patch makes NETDEV_NOTIFY_PEER unconditional, if preferred we could add a new sysctl for this case which defaults to on. This change causes Xen post-migration ARP notifications (which cause switches to relearn their MAC tables etc) to be sent by default. Signed-off-by: Ian Campbell Signed-off-by: David S. Miller --- net/ipv4/devinet.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 748cb5b337b..df4616fce92 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1030,6 +1030,21 @@ static inline bool inetdev_valid_mtu(unsigned mtu) return mtu >= 68; } +static void inetdev_send_gratuitous_arp(struct net_device *dev, + struct in_device *in_dev) + +{ + struct in_ifaddr *ifa = in_dev->ifa_list; + + if (!ifa) + return; + + arp_send(ARPOP_REQUEST, ETH_P_ARP, + ifa->ifa_address, dev, + ifa->ifa_address, NULL, + dev->dev_addr, NULL); +} + /* Called only under RTNL semaphore */ static int inetdev_event(struct notifier_block *this, unsigned long event, @@ -1082,18 +1097,13 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, } ip_mc_up(in_dev); /* fall through */ - case NETDEV_NOTIFY_PEERS: case NETDEV_CHANGEADDR: + if (!IN_DEV_ARP_NOTIFY(in_dev)) + break; + /* fall through */ + case NETDEV_NOTIFY_PEERS: /* Send gratuitous ARP to notify of link change */ - if (IN_DEV_ARP_NOTIFY(in_dev)) { - struct in_ifaddr *ifa = in_dev->ifa_list; - - if (ifa) - arp_send(ARPOP_REQUEST, ETH_P_ARP, - ifa->ifa_address, dev, - ifa->ifa_address, NULL, - dev->dev_addr, NULL); - } + inetdev_send_gratuitous_arp(dev, in_dev); break; case NETDEV_DOWN: ip_mc_down(in_dev); -- cgit v1.2.3-18-g5258 From 6d90e8f45697c633f522269368297d7416fd8783 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Feb 2011 12:18:09 -0800 Subject: isdn: hisax: Use l2headersize() instead of dup (and buggy) func. There was a bug in my commit c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2 ("hisax: Fix unchecked alloc_skb() return.") One of the l2->flag checks is wrong. Even worse it turns out I'm duplicating an existing function, so use that instead. Reported-by: Milton Miller Signed-off-by: David S. Miller --- drivers/isdn/hisax/isdnl2.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 98ac835281f..cfff0c41d29 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -1243,13 +1243,6 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) st->l2.rc = 0; } -static int l2_hdr_space_needed(struct Layer2 *l2) -{ - int len = test_bit(FLG_LAPD, &l2->flag) ? 2 : 1; - - return len + (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); -} - static void l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) { @@ -1268,7 +1261,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) if (!skb) return; - hdr_space_needed = l2_hdr_space_needed(l2); + hdr_space_needed = l2headersize(l2, 0); if (hdr_space_needed > skb_headroom(skb)) { struct sk_buff *orig_skb = skb; -- cgit v1.2.3-18-g5258 From 615b32af9730def64330e4c0c95c973e90bd9c6d Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 2 Feb 2011 10:19:45 +0000 Subject: e1000e: check down flag in tasks This change is part of a fix to avoid any tasks running while the driver is exiting and deinitializing resources. Signed-off-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3065870cf2a..174633c9332 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -937,6 +937,9 @@ static void e1000_print_hw_hang(struct work_struct *work) u16 phy_status, phy_1000t_status, phy_ext_status; u16 pci_status; + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1e_rphy(hw, PHY_STATUS, &phy_status); e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); @@ -1506,6 +1509,9 @@ static void e1000e_downshift_workaround(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, downshift_task); + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); } @@ -3765,6 +3771,10 @@ static void e1000e_update_phy_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, update_phy_task); + + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1000_get_phy_info(&adapter->hw); } @@ -3775,6 +3785,10 @@ static void e1000e_update_phy_task(struct work_struct *work) static void e1000_update_phy_info(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *) data; + + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + schedule_work(&adapter->update_phy_task); } @@ -4149,6 +4163,9 @@ static void e1000_watchdog_task(struct work_struct *work) u32 link, tctl; int tx_pending = 0; + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + link = e1000e_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) { /* Cancel scheduled suspend requests. */ @@ -4887,6 +4904,10 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter; adapter = container_of(work, struct e1000_adapter, reset_task); + /* don't run the task if already down */ + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && (adapter->flags & FLAG_RX_RESTART_NOW))) { e1000e_dump(adapter); -- cgit v1.2.3-18-g5258 From 713b3c9e4c1a6da6b45da6474ed554ed0a48de69 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 2 Feb 2011 10:19:50 +0000 Subject: e1000e: flush all writebacks before unload The driver was not flushing all writebacks before unloading, possibly causing memory to be written by the hardware after the driver had reinitialized the rings. This adds missing functionality to flush any pending writebacks and is called in all spots where descriptors should be completed before the driver begins processing. Signed-off-by: Jesse Brandeburg Reviewed-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 174633c9332..3fa110ddb04 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3344,6 +3344,21 @@ int e1000e_up(struct e1000_adapter *adapter) return 0; } +static void e1000e_flush_descriptors(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + + if (!(adapter->flags2 & FLAG2_DMA_BURST)) + return; + + /* flush pending descriptor writebacks to memory */ + ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); + ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); + + /* execute the writes immediately */ + e1e_flush(); +} + void e1000e_down(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -3383,6 +3398,9 @@ void e1000e_down(struct e1000_adapter *adapter) if (!pci_channel_offline(adapter->pdev)) e1000e_reset(adapter); + + e1000e_flush_descriptors(adapter); + e1000_clean_tx_ring(adapter); e1000_clean_rx_ring(adapter); @@ -4354,19 +4372,12 @@ link_up: else ew32(ICS, E1000_ICS_RXDMT0); + /* flush pending descriptors to memory before detecting Tx hang */ + e1000e_flush_descriptors(adapter); + /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = 1; - /* flush partial descriptors to memory before detecting Tx hang */ - if (adapter->flags2 & FLAG2_DMA_BURST) { - ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); - ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); - /* - * no need to flush the writes because the timeout code does - * an er32 first thing - */ - } - /* * With 82571 controllers, LAA may be overwritten due to controller * reset from the other port. Set the appropriate LAA in RAR[0] -- cgit v1.2.3-18-g5258 From 4c7e604babd15db9dca3b07de167a0f93fe23bf4 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Thu, 17 Feb 2011 01:13:13 -0800 Subject: ixgbe: fix panic due to uninitialised pointer Systems containing an 82599EB and running a backported driver from upstream were panicing on boot. It turns out hw->mac.ops.setup_sfp is only set for 82599, so one should check to be sure that pointer is set before continuing in ixgbe_sfp_config_module_task. I verified by inspection that the upstream driver has the same issue and also added a check before the call in ixgbe_sfp_link_config. Signed-off-by: Andy Gospodarek Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbae703b46d..30f9ccfb4f8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3728,7 +3728,8 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) * We need to try and force an autonegotiation * session, then bring up link. */ - hw->mac.ops.setup_sfp(hw); + if (hw->mac.ops.setup_sfp) + hw->mac.ops.setup_sfp(hw); if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) schedule_work(&adapter->multispeed_fiber_task); } else { @@ -5968,7 +5969,8 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) unregister_netdev(adapter->netdev); return; } - hw->mac.ops.setup_sfp(hw); + if (hw->mac.ops.setup_sfp) + hw->mac.ops.setup_sfp(hw); if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) /* This will also work for DA Twinax connections */ -- cgit v1.2.3-18-g5258 From c600636bd560b04973174caa5e349a72bce51637 Mon Sep 17 00:00:00 2001 From: Amir Hanania Date: Tue, 15 Feb 2011 09:11:31 +0000 Subject: ixgbe: work around for DDP last buffer size A HW limitation was recently discovered where the last buffer in a DDP offload cannot be a full buffer size in length. Fix the issue with a work around by adding another buffer with size = 1. Signed-off-by: Amir Hanania Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 51 +++++++++++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_fcoe.h | 2 ++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 8753980668c..c54a88274d5 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -159,7 +159,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sg; unsigned int i, j, dmacount; unsigned int len; - static const unsigned int bufflen = 4096; + static const unsigned int bufflen = IXGBE_FCBUFF_MIN; unsigned int firstoff = 0; unsigned int lastsize; unsigned int thisoff = 0; @@ -254,6 +254,24 @@ int ixgbe_fcoe_ddp_get(struct net_de