hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/vmxnet3/vmxnet3_drv.c
....@@ -1,7 +1,7 @@
11 /*
22 * Linux driver for VMware's vmxnet3 ethernet NIC.
33 *
4
- * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
4
+ * Copyright (C) 2008-2020, VMware, Inc. All Rights Reserved.
55 *
66 * This program is free software; you can redistribute it and/or modify it
77 * under the terms of the GNU General Public License as published by the
....@@ -535,8 +535,8 @@
535535 }
536536
537537 sz = tq->tx_ring.size * sizeof(tq->buf_info[0]);
538
- tq->buf_info = dma_zalloc_coherent(&adapter->pdev->dev, sz,
539
- &tq->buf_info_pa, GFP_KERNEL);
538
+ tq->buf_info = dma_alloc_coherent(&adapter->pdev->dev, sz,
539
+ &tq->buf_info_pa, GFP_KERNEL);
540540 if (!tq->buf_info)
541541 goto err;
542542
....@@ -595,6 +595,7 @@
595595 if (dma_mapping_error(&adapter->pdev->dev,
596596 rbi->dma_addr)) {
597597 dev_kfree_skb_any(rbi->skb);
598
+ rbi->skb = NULL;
598599 rq->stats.rx_buf_alloc_failure++;
599600 break;
600601 }
....@@ -619,6 +620,7 @@
619620 if (dma_mapping_error(&adapter->pdev->dev,
620621 rbi->dma_addr)) {
621622 put_page(rbi->page);
623
+ rbi->page = NULL;
622624 rq->stats.rx_buf_alloc_failure++;
623625 break;
624626 }
....@@ -657,13 +659,12 @@
657659 vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd,
658660 struct vmxnet3_rx_buf_info *rbi)
659661 {
660
- struct skb_frag_struct *frag = skb_shinfo(skb)->frags +
661
- skb_shinfo(skb)->nr_frags;
662
+ skb_frag_t *frag = skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
662663
663664 BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
664665
665666 __skb_frag_set_page(frag, rbi->page);
666
- frag->page_offset = 0;
667
+ skb_frag_off_set(frag, 0);
667668 skb_frag_size_set(frag, rcd->len);
668669 skb->data_len += rcd->len;
669670 skb->truesize += PAGE_SIZE;
....@@ -755,7 +756,7 @@
755756 }
756757
757758 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
758
- const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
759
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
759760 u32 buf_size;
760761
761762 buf_offset = 0;
....@@ -843,26 +844,52 @@
843844 u8 protocol = 0;
844845
845846 if (ctx->mss) { /* TSO */
846
- ctx->eth_ip_hdr_size = skb_transport_offset(skb);
847
- ctx->l4_hdr_size = tcp_hdrlen(skb);
848
- ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
847
+ if (VMXNET3_VERSION_GE_4(adapter) && skb->encapsulation) {
848
+ ctx->l4_offset = skb_inner_transport_offset(skb);
849
+ ctx->l4_hdr_size = inner_tcp_hdrlen(skb);
850
+ ctx->copy_size = ctx->l4_offset + ctx->l4_hdr_size;
851
+ } else {
852
+ ctx->l4_offset = skb_transport_offset(skb);
853
+ ctx->l4_hdr_size = tcp_hdrlen(skb);
854
+ ctx->copy_size = ctx->l4_offset + ctx->l4_hdr_size;
855
+ }
849856 } else {
850857 if (skb->ip_summed == CHECKSUM_PARTIAL) {
851
- ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb);
858
+ /* For encap packets, skb_checksum_start_offset refers
859
+ * to inner L4 offset. Thus, below works for encap as
860
+ * well as non-encap case
861
+ */
862
+ ctx->l4_offset = skb_checksum_start_offset(skb);
852863
853
- if (ctx->ipv4) {
854
- const struct iphdr *iph = ip_hdr(skb);
864
+ if (VMXNET3_VERSION_GE_4(adapter) &&
865
+ skb->encapsulation) {
866
+ struct iphdr *iph = inner_ip_hdr(skb);
855867
856
- protocol = iph->protocol;
857
- } else if (ctx->ipv6) {
858
- const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
868
+ if (iph->version == 4) {
869
+ protocol = iph->protocol;
870
+ } else {
871
+ const struct ipv6hdr *ipv6h;
859872
860
- protocol = ipv6h->nexthdr;
873
+ ipv6h = inner_ipv6_hdr(skb);
874
+ protocol = ipv6h->nexthdr;
875
+ }
876
+ } else {
877
+ if (ctx->ipv4) {
878
+ const struct iphdr *iph = ip_hdr(skb);
879
+
880
+ protocol = iph->protocol;
881
+ } else if (ctx->ipv6) {
882
+ const struct ipv6hdr *ipv6h;
883
+
884
+ ipv6h = ipv6_hdr(skb);
885
+ protocol = ipv6h->nexthdr;
886
+ }
861887 }
862888
863889 switch (protocol) {
864890 case IPPROTO_TCP:
865
- ctx->l4_hdr_size = tcp_hdrlen(skb);
891
+ ctx->l4_hdr_size = skb->encapsulation ? inner_tcp_hdrlen(skb) :
892
+ tcp_hdrlen(skb);
866893 break;
867894 case IPPROTO_UDP:
868895 ctx->l4_hdr_size = sizeof(struct udphdr);
....@@ -872,10 +899,10 @@
872899 break;
873900 }
874901
875
- ctx->copy_size = min(ctx->eth_ip_hdr_size +
902
+ ctx->copy_size = min(ctx->l4_offset +
876903 ctx->l4_hdr_size, skb->len);
877904 } else {
878
- ctx->eth_ip_hdr_size = 0;
905
+ ctx->l4_offset = 0;
879906 ctx->l4_hdr_size = 0;
880907 /* copy as much as allowed */
881908 ctx->copy_size = min_t(unsigned int,
....@@ -931,6 +958,25 @@
931958
932959
933960 static void
961
+vmxnet3_prepare_inner_tso(struct sk_buff *skb,
962
+ struct vmxnet3_tx_ctx *ctx)
963
+{
964
+ struct tcphdr *tcph = inner_tcp_hdr(skb);
965
+ struct iphdr *iph = inner_ip_hdr(skb);
966
+
967
+ if (iph->version == 4) {
968
+ iph->check = 0;
969
+ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
970
+ IPPROTO_TCP, 0);
971
+ } else {
972
+ struct ipv6hdr *iph = inner_ipv6_hdr(skb);
973
+
974
+ tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
975
+ IPPROTO_TCP, 0);
976
+ }
977
+}
978
+
979
+static void
934980 vmxnet3_prepare_tso(struct sk_buff *skb,
935981 struct vmxnet3_tx_ctx *ctx)
936982 {
....@@ -943,10 +989,7 @@
943989 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
944990 IPPROTO_TCP, 0);
945991 } else if (ctx->ipv6) {
946
- struct ipv6hdr *iph = ipv6_hdr(skb);
947
-
948
- tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
949
- IPPROTO_TCP, 0);
992
+ tcp_v6_gso_csum_prep(skb);
950993 }
951994 }
952995
....@@ -956,7 +999,7 @@
956999 int i;
9571000
9581001 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
959
- const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
1002
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
9601003
9611004 count += VMXNET3_TXD_NEEDED(skb_frag_size(frag));
9621005 }
....@@ -1007,7 +1050,11 @@
10071050 }
10081051 tq->stats.copy_skb_header++;
10091052 }
1010
- vmxnet3_prepare_tso(skb, &ctx);
1053
+ if (skb->encapsulation) {
1054
+ vmxnet3_prepare_inner_tso(skb, &ctx);
1055
+ } else {
1056
+ vmxnet3_prepare_tso(skb, &ctx);
1057
+ }
10111058 } else {
10121059 if (unlikely(count > VMXNET3_MAX_TXD_PER_PKT)) {
10131060
....@@ -1030,14 +1077,14 @@
10301077 BUG_ON(ret <= 0 && ctx.copy_size != 0);
10311078 /* hdrs parsed, check against other limits */
10321079 if (ctx.mss) {
1033
- if (unlikely(ctx.eth_ip_hdr_size + ctx.l4_hdr_size >
1080
+ if (unlikely(ctx.l4_offset + ctx.l4_hdr_size >
10341081 VMXNET3_MAX_TX_BUF_SIZE)) {
10351082 tq->stats.drop_oversized_hdr++;
10361083 goto drop_pkt;
10371084 }
10381085 } else {
10391086 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1040
- if (unlikely(ctx.eth_ip_hdr_size +
1087
+ if (unlikely(ctx.l4_offset +
10411088 skb->csum_offset >
10421089 VMXNET3_MAX_CSUM_OFFSET)) {
10431090 tq->stats.drop_oversized_hdr++;
....@@ -1084,16 +1131,33 @@
10841131 #endif
10851132 tx_num_deferred = le32_to_cpu(tq->shared->txNumDeferred);
10861133 if (ctx.mss) {
1087
- gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
1088
- gdesc->txd.om = VMXNET3_OM_TSO;
1089
- gdesc->txd.msscof = ctx.mss;
1134
+ if (VMXNET3_VERSION_GE_4(adapter) && skb->encapsulation) {
1135
+ gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
1136
+ gdesc->txd.om = VMXNET3_OM_ENCAP;
1137
+ gdesc->txd.msscof = ctx.mss;
1138
+
1139
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
1140
+ gdesc->txd.oco = 1;
1141
+ } else {
1142
+ gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
1143
+ gdesc->txd.om = VMXNET3_OM_TSO;
1144
+ gdesc->txd.msscof = ctx.mss;
1145
+ }
10901146 num_pkts = (skb->len - gdesc->txd.hlen + ctx.mss - 1) / ctx.mss;
10911147 } else {
10921148 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1093
- gdesc->txd.hlen = ctx.eth_ip_hdr_size;
1094
- gdesc->txd.om = VMXNET3_OM_CSUM;
1095
- gdesc->txd.msscof = ctx.eth_ip_hdr_size +
1096
- skb->csum_offset;
1149
+ if (VMXNET3_VERSION_GE_4(adapter) &&
1150
+ skb->encapsulation) {
1151
+ gdesc->txd.hlen = ctx.l4_offset +
1152
+ ctx.l4_hdr_size;
1153
+ gdesc->txd.om = VMXNET3_OM_ENCAP;
1154
+ gdesc->txd.msscof = 0; /* Reserved */
1155
+ } else {
1156
+ gdesc->txd.hlen = ctx.l4_offset;
1157
+ gdesc->txd.om = VMXNET3_OM_CSUM;
1158
+ gdesc->txd.msscof = ctx.l4_offset +
1159
+ skb->csum_offset;
1160
+ }
10971161 } else {
10981162 gdesc->txd.om = 0;
10991163 gdesc->txd.msscof = 0;
....@@ -1172,13 +1236,21 @@
11721236 (le32_to_cpu(gdesc->dword[3]) &
11731237 VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
11741238 skb->ip_summed = CHECKSUM_UNNECESSARY;
1175
- BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
1176
- BUG_ON(gdesc->rcd.frg);
1239
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
1240
+ !(le32_to_cpu(gdesc->dword[0]) &
1241
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
1242
+ WARN_ON_ONCE(gdesc->rcd.frg &&
1243
+ !(le32_to_cpu(gdesc->dword[0]) &
1244
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
11771245 } else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
11781246 (1 << VMXNET3_RCD_TUC_SHIFT))) {
11791247 skb->ip_summed = CHECKSUM_UNNECESSARY;
1180
- BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
1181
- BUG_ON(gdesc->rcd.frg);
1248
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
1249
+ !(le32_to_cpu(gdesc->dword[0]) &
1250
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
1251
+ WARN_ON_ONCE(gdesc->rcd.frg &&
1252
+ !(le32_to_cpu(gdesc->dword[0]) &
1253
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
11821254 } else {
11831255 if (gdesc->rcd.csum) {
11841256 skb->csum = htons(gdesc->rcd.csum);
....@@ -1284,6 +1356,7 @@
12841356 };
12851357 u32 num_pkts = 0;
12861358 bool skip_page_frags = false;
1359
+ bool encap_lro = false;
12871360 struct Vmxnet3_RxCompDesc *rcd;
12881361 struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
12891362 u16 segCnt = 0, mss = 0;
....@@ -1424,13 +1497,18 @@
14241497 if (VMXNET3_VERSION_GE_2(adapter) &&
14251498 rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
14261499 struct Vmxnet3_RxCompDescExt *rcdlro;
1500
+ union Vmxnet3_GenericDesc *gdesc;
1501
+
14271502 rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
1503
+ gdesc = (union Vmxnet3_GenericDesc *)rcd;
14281504
14291505 segCnt = rcdlro->segCnt;
14301506 WARN_ON_ONCE(segCnt == 0);
14311507 mss = rcdlro->mss;
14321508 if (unlikely(segCnt <= 1))
14331509 segCnt = 0;
1510
+ encap_lro = (le32_to_cpu(gdesc->dword[0]) &
1511
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT));
14341512 } else {
14351513 segCnt = 0;
14361514 }
....@@ -1498,7 +1576,7 @@
14981576 vmxnet3_rx_csum(adapter, skb,
14991577 (union Vmxnet3_GenericDesc *)rcd);
15001578 skb->protocol = eth_type_trans(skb, adapter->netdev);
1501
- if (!rcd->tcp ||
1579
+ if ((!rcd->tcp && !encap_lro) ||
15021580 !(adapter->netdev->features & NETIF_F_LRO))
15031581 goto not_lro;
15041582
....@@ -1507,7 +1585,7 @@
15071585 SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
15081586 skb_shinfo(skb)->gso_size = mss;
15091587 skb_shinfo(skb)->gso_segs = segCnt;
1510
- } else if (segCnt != 0 || skb->len > mtu) {
1588
+ } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
15111589 u32 hlen;
15121590
15131591 hlen = vmxnet3_get_hdr_len(adapter, skb,
....@@ -1536,6 +1614,7 @@
15361614 napi_gro_receive(&rq->napi, skb);
15371615
15381616 ctx->skb = NULL;
1617
+ encap_lro = false;
15391618 num_pkts++;
15401619 }
15411620
....@@ -1583,6 +1662,10 @@
15831662 {
15841663 u32 i, ring_idx;
15851664 struct Vmxnet3_RxDesc *rxd;
1665
+
1666
+ /* ring has already been cleaned up */
1667
+ if (!rq->rx_ring[0].base)
1668
+ return;
15861669
15871670 for (ring_idx = 0; ring_idx < 2; ring_idx++) {
15881671 for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
....@@ -1815,8 +1898,8 @@
18151898
18161899 sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
18171900 rq->rx_ring[1].size);
1818
- bi = dma_zalloc_coherent(&adapter->pdev->dev, sz, &rq->buf_info_pa,
1819
- GFP_KERNEL);
1901
+ bi = dma_alloc_coherent(&adapter->pdev->dev, sz, &rq->buf_info_pa,
1902
+ GFP_KERNEL);
18201903 if (!bi)
18211904 goto err;
18221905
....@@ -2433,6 +2516,10 @@
24332516 if (adapter->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
24342517 devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
24352518
2519
+ if (adapter->netdev->features & (NETIF_F_GSO_UDP_TUNNEL |
2520
+ NETIF_F_GSO_UDP_TUNNEL_CSUM))
2521
+ devRead->misc.uptFeatures |= UPT1_F_RXINNEROFLD;
2522
+
24362523 devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
24372524 devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa);
24382525 devRead->misc.queueDescLen = cpu_to_le32(
....@@ -2558,6 +2645,39 @@
25582645 spin_unlock_irqrestore(&adapter->cmd_lock, flags);
25592646 }
25602647
2648
+static void
2649
+vmxnet3_init_rssfields(struct vmxnet3_adapter *adapter)
2650
+{
2651
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
2652
+ union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
2653
+ unsigned long flags;
2654
+
2655
+ if (!VMXNET3_VERSION_GE_4(adapter))
2656
+ return;
2657
+
2658
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
2659
+
2660
+ if (adapter->default_rss_fields) {
2661
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2662
+ VMXNET3_CMD_GET_RSS_FIELDS);
2663
+ adapter->rss_fields =
2664
+ VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
2665
+ } else {
2666
+ cmdInfo->setRssFields = adapter->rss_fields;
2667
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2668
+ VMXNET3_CMD_SET_RSS_FIELDS);
2669
+ /* Not all requested RSS may get applied, so get and
2670
+ * cache what was actually applied.
2671
+ */
2672
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2673
+ VMXNET3_CMD_GET_RSS_FIELDS);
2674
+ adapter->rss_fields =
2675
+ VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
2676
+ }
2677
+
2678
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
2679
+}
2680
+
25612681 int
25622682 vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
25632683 {
....@@ -2607,6 +2727,7 @@
26072727 }
26082728
26092729 vmxnet3_init_coalesce(adapter);
2730
+ vmxnet3_init_rssfields(adapter);
26102731
26112732 for (i = 0; i < adapter->num_rx_queues; i++) {
26122733 VMXNET3_WRITE_BAR0_REG(adapter,
....@@ -3043,6 +3164,18 @@
30433164 NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
30443165 NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
30453166 NETIF_F_LRO;
3167
+
3168
+ if (VMXNET3_VERSION_GE_4(adapter)) {
3169
+ netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
3170
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
3171
+
3172
+ netdev->hw_enc_features = NETIF_F_SG | NETIF_F_RXCSUM |
3173
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
3174
+ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
3175
+ NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
3176
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
3177
+ }
3178
+
30463179 if (dma64)
30473180 netdev->hw_features |= NETIF_F_HIGHDMA;
30483181 netdev->vlan_features = netdev->hw_features &
....@@ -3199,7 +3332,7 @@
31993332
32003333
32013334 static void
3202
-vmxnet3_tx_timeout(struct net_device *netdev)
3335
+vmxnet3_tx_timeout(struct net_device *netdev, unsigned int txqueue)
32033336 {
32043337 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
32053338 adapter->tx_timeout_count++;
....@@ -3247,7 +3380,9 @@
32473380 .ndo_start_xmit = vmxnet3_xmit_frame,
32483381 .ndo_set_mac_address = vmxnet3_set_mac_addr,
32493382 .ndo_change_mtu = vmxnet3_change_mtu,
3383
+ .ndo_fix_features = vmxnet3_fix_features,
32503384 .ndo_set_features = vmxnet3_set_features,
3385
+ .ndo_features_check = vmxnet3_features_check,
32513386 .ndo_get_stats64 = vmxnet3_get_stats64,
32523387 .ndo_tx_timeout = vmxnet3_tx_timeout,
32533388 .ndo_set_rx_mode = vmxnet3_set_mc,
....@@ -3385,7 +3520,12 @@
33853520 goto err_alloc_pci;
33863521
33873522 ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
3388
- if (ver & (1 << VMXNET3_REV_3)) {
3523
+ if (ver & (1 << VMXNET3_REV_4)) {
3524
+ VMXNET3_WRITE_BAR1_REG(adapter,
3525
+ VMXNET3_REG_VRRS,
3526
+ 1 << VMXNET3_REV_4);
3527
+ adapter->version = VMXNET3_REV_4 + 1;
3528
+ } else if (ver & (1 << VMXNET3_REV_3)) {
33893529 VMXNET3_WRITE_BAR1_REG(adapter,
33903530 VMXNET3_REG_VRRS,
33913531 1 << VMXNET3_REV_3);
....@@ -3429,9 +3569,13 @@
34293569 err = -ENOMEM;
34303570 goto err_ver;
34313571 }
3432
- memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
34333572 adapter->coal_conf->coalMode = VMXNET3_COALESCE_DISABLED;
34343573 adapter->default_coal_mode = true;
3574
+ }
3575
+
3576
+ if (VMXNET3_VERSION_GE_4(adapter)) {
3577
+ adapter->default_rss_fields = true;
3578
+ adapter->rss_fields = VMXNET3_RSS_FIELDS_DEFAULT;
34353579 }
34363580
34373581 SET_NETDEV_DEV(netdev, &pdev->dev);
....@@ -3650,13 +3794,19 @@
36503794 }
36513795
36523796 if (adapter->wol & WAKE_ARP) {
3653
- in_dev = in_dev_get(netdev);
3654
- if (!in_dev)
3655
- goto skip_arp;
3797
+ rcu_read_lock();
36563798
3657
- ifa = (struct in_ifaddr *)in_dev->ifa_list;
3658
- if (!ifa)
3799
+ in_dev = __in_dev_get_rcu(netdev);
3800
+ if (!in_dev) {
3801
+ rcu_read_unlock();
36593802 goto skip_arp;
3803
+ }
3804
+
3805
+ ifa = rcu_dereference(in_dev->ifa_list);
3806
+ if (!ifa) {
3807
+ rcu_read_unlock();
3808
+ goto skip_arp;
3809
+ }
36603810
36613811 pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/
36623812 sizeof(struct arphdr) + /* ARP header */
....@@ -3676,7 +3826,9 @@
36763826
36773827 /* The Unicast IPv4 address in 'tip' field. */
36783828 arpreq += 2 * ETH_ALEN + sizeof(u32);
3679
- *(u32 *)arpreq = ifa->ifa_address;
3829
+ *(__be32 *)arpreq = ifa->ifa_address;
3830
+
3831
+ rcu_read_unlock();
36803832
36813833 /* The mask for the relevant bits. */
36823834 pmConf->filters[i].mask[0] = 0x00;
....@@ -3685,7 +3837,6 @@
36853837 pmConf->filters[i].mask[3] = 0x00;
36863838 pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */
36873839 pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
3688
- in_dev_put(in_dev);
36893840
36903841 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
36913842 i++;