diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_ib.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f429bce24c20..66cafa20c246 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -31,8 +31,6 @@ | |||
31 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 31 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
32 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 32 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
33 | * SOFTWARE. | 33 | * SOFTWARE. |
34 | * | ||
35 | * $Id: ipoib_ib.c 1386 2004-12-27 16:23:17Z roland $ | ||
36 | */ | 34 | */ |
37 | 35 | ||
38 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
@@ -290,7 +288,10 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) | |||
290 | if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) | 288 | if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) |
291 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 289 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
292 | 290 | ||
293 | netif_receive_skb(skb); | 291 | if (dev->features & NETIF_F_LRO) |
292 | lro_receive_skb(&priv->lro.lro_mgr, skb, NULL); | ||
293 | else | ||
294 | netif_receive_skb(skb); | ||
294 | 295 | ||
295 | repost: | 296 | repost: |
296 | if (unlikely(ipoib_ib_post_receive(dev, wr_id))) | 297 | if (unlikely(ipoib_ib_post_receive(dev, wr_id))) |
@@ -442,6 +443,9 @@ poll_more: | |||
442 | } | 443 | } |
443 | 444 | ||
444 | if (done < budget) { | 445 | if (done < budget) { |
446 | if (dev->features & NETIF_F_LRO) | ||
447 | lro_flush_all(&priv->lro.lro_mgr); | ||
448 | |||
445 | netif_rx_complete(dev, napi); | 449 | netif_rx_complete(dev, napi); |
446 | if (unlikely(ib_req_notify_cq(priv->recv_cq, | 450 | if (unlikely(ib_req_notify_cq(priv->recv_cq, |
447 | IB_CQ_NEXT_COMP | | 451 | IB_CQ_NEXT_COMP | |
@@ -898,7 +902,8 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
898 | return 0; | 902 | return 0; |
899 | } | 903 | } |
900 | 904 | ||
901 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) | 905 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, |
906 | enum ipoib_flush_level level) | ||
902 | { | 907 | { |
903 | struct ipoib_dev_priv *cpriv; | 908 | struct ipoib_dev_priv *cpriv; |
904 | struct net_device *dev = priv->dev; | 909 | struct net_device *dev = priv->dev; |
@@ -911,7 +916,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) | |||
911 | * the parent is down. | 916 | * the parent is down. |
912 | */ | 917 | */ |
913 | list_for_each_entry(cpriv, &priv->child_intfs, list) | 918 | list_for_each_entry(cpriv, &priv->child_intfs, list) |
914 | __ipoib_ib_dev_flush(cpriv, pkey_event); | 919 | __ipoib_ib_dev_flush(cpriv, level); |
915 | 920 | ||
916 | mutex_unlock(&priv->vlan_mutex); | 921 | mutex_unlock(&priv->vlan_mutex); |
917 | 922 | ||
@@ -925,7 +930,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) | |||
925 | return; | 930 | return; |
926 | } | 931 | } |
927 | 932 | ||
928 | if (pkey_event) { | 933 | if (level == IPOIB_FLUSH_HEAVY) { |
929 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { | 934 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { |
930 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 935 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
931 | ipoib_ib_dev_down(dev, 0); | 936 | ipoib_ib_dev_down(dev, 0); |
@@ -943,11 +948,15 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) | |||
943 | priv->pkey_index = new_index; | 948 | priv->pkey_index = new_index; |
944 | } | 949 | } |
945 | 950 | ||
946 | ipoib_dbg(priv, "flushing\n"); | 951 | if (level == IPOIB_FLUSH_LIGHT) { |
952 | ipoib_mark_paths_invalid(dev); | ||
953 | ipoib_mcast_dev_flush(dev); | ||
954 | } | ||
947 | 955 | ||
948 | ipoib_ib_dev_down(dev, 0); | 956 | if (level >= IPOIB_FLUSH_NORMAL) |
957 | ipoib_ib_dev_down(dev, 0); | ||
949 | 958 | ||
950 | if (pkey_event) { | 959 | if (level == IPOIB_FLUSH_HEAVY) { |
951 | ipoib_ib_dev_stop(dev, 0); | 960 | ipoib_ib_dev_stop(dev, 0); |
952 | ipoib_ib_dev_open(dev); | 961 | ipoib_ib_dev_open(dev); |
953 | } | 962 | } |
@@ -957,27 +966,34 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) | |||
957 | * we get here, don't bring it back up if it's not configured up | 966 | * we get here, don't bring it back up if it's not configured up |
958 | */ | 967 | */ |
959 | if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { | 968 | if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { |
960 | ipoib_ib_dev_up(dev); | 969 | if (level >= IPOIB_FLUSH_NORMAL) |
970 | ipoib_ib_dev_up(dev); | ||
961 | ipoib_mcast_restart_task(&priv->restart_task); | 971 | ipoib_mcast_restart_task(&priv->restart_task); |
962 | } | 972 | } |
963 | } | 973 | } |
964 | 974 | ||
965 | void ipoib_ib_dev_flush(struct work_struct *work) | 975 | void ipoib_ib_dev_flush_light(struct work_struct *work) |
976 | { | ||
977 | struct ipoib_dev_priv *priv = | ||
978 | container_of(work, struct ipoib_dev_priv, flush_light); | ||
979 | |||
980 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_LIGHT); | ||
981 | } | ||
982 | |||
983 | void ipoib_ib_dev_flush_normal(struct work_struct *work) | ||
966 | { | 984 | { |
967 | struct ipoib_dev_priv *priv = | 985 | struct ipoib_dev_priv *priv = |
968 | container_of(work, struct ipoib_dev_priv, flush_task); | 986 | container_of(work, struct ipoib_dev_priv, flush_normal); |
969 | 987 | ||
970 | ipoib_dbg(priv, "Flushing %s\n", priv->dev->name); | 988 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_NORMAL); |
971 | __ipoib_ib_dev_flush(priv, 0); | ||
972 | } | 989 | } |
973 | 990 | ||
974 | void ipoib_pkey_event(struct work_struct *work) | 991 | void ipoib_ib_dev_flush_heavy(struct work_struct *work) |
975 | { | 992 | { |
976 | struct ipoib_dev_priv *priv = | 993 | struct ipoib_dev_priv *priv = |
977 | container_of(work, struct ipoib_dev_priv, pkey_event_task); | 994 | container_of(work, struct ipoib_dev_priv, flush_heavy); |
978 | 995 | ||
979 | ipoib_dbg(priv, "Flushing %s and restarting its QP\n", priv->dev->name); | 996 | __ipoib_ib_dev_flush(priv, IPOIB_FLUSH_HEAVY); |
980 | __ipoib_ib_dev_flush(priv, 1); | ||
981 | } | 997 | } |
982 | 998 | ||
983 | void ipoib_ib_dev_cleanup(struct net_device *dev) | 999 | void ipoib_ib_dev_cleanup(struct net_device *dev) |