hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
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,29 @@
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
+ if ((le32_to_cpu(gdesc->dword[0]) &
1240
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
1241
+ skb->csum_level = 1;
1242
+ }
1243
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
1244
+ !(le32_to_cpu(gdesc->dword[0]) &
1245
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
1246
+ WARN_ON_ONCE(gdesc->rcd.frg &&
1247
+ !(le32_to_cpu(gdesc->dword[0]) &
1248
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
11771249 } else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
11781250 (1 << VMXNET3_RCD_TUC_SHIFT))) {
11791251 skb->ip_summed = CHECKSUM_UNNECESSARY;
1180
- BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
1181
- BUG_ON(gdesc->rcd.frg);
1252
+ if ((le32_to_cpu(gdesc->dword[0]) &
1253
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
1254
+ skb->csum_level = 1;
1255
+ }
1256
+ WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
1257
+ !(le32_to_cpu(gdesc->dword[0]) &
1258
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
1259
+ WARN_ON_ONCE(gdesc->rcd.frg &&
1260
+ !(le32_to_cpu(gdesc->dword[0]) &
1261
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
11821262 } else {
11831263 if (gdesc->rcd.csum) {
11841264 skb->csum = htons(gdesc->rcd.csum);
....@@ -1284,6 +1364,7 @@
12841364 };
12851365 u32 num_pkts = 0;
12861366 bool skip_page_frags = false;
1367
+ bool encap_lro = false;
12871368 struct Vmxnet3_RxCompDesc *rcd;
12881369 struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
12891370 u16 segCnt = 0, mss = 0;
....@@ -1424,13 +1505,18 @@
14241505 if (VMXNET3_VERSION_GE_2(adapter) &&
14251506 rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
14261507 struct Vmxnet3_RxCompDescExt *rcdlro;
1508
+ union Vmxnet3_GenericDesc *gdesc;
1509
+
14271510 rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
1511
+ gdesc = (union Vmxnet3_GenericDesc *)rcd;
14281512
14291513 segCnt = rcdlro->segCnt;
14301514 WARN_ON_ONCE(segCnt == 0);
14311515 mss = rcdlro->mss;
14321516 if (unlikely(segCnt <= 1))
14331517 segCnt = 0;
1518
+ encap_lro = (le32_to_cpu(gdesc->dword[0]) &
1519
+ (1UL << VMXNET3_RCD_HDR_INNER_SHIFT));
14341520 } else {
14351521 segCnt = 0;
14361522 }
....@@ -1498,7 +1584,7 @@
14981584 vmxnet3_rx_csum(adapter, skb,
14991585 (union Vmxnet3_GenericDesc *)rcd);
15001586 skb->protocol = eth_type_trans(skb, adapter->netdev);
1501
- if (!rcd->tcp ||
1587
+ if ((!rcd->tcp && !encap_lro) ||
15021588 !(adapter->netdev->features & NETIF_F_LRO))
15031589 goto not_lro;
15041590
....@@ -1507,7 +1593,7 @@
15071593 SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
15081594 skb_shinfo(skb)->gso_size = mss;
15091595 skb_shinfo(skb)->gso_segs = segCnt;
1510
- } else if (segCnt != 0 || skb->len > mtu) {
1596
+ } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
15111597 u32 hlen;
15121598
15131599 hlen = vmxnet3_get_hdr_len(adapter, skb,
....@@ -1536,6 +1622,7 @@
15361622 napi_gro_receive(&rq->napi, skb);
15371623
15381624 ctx->skb = NULL;
1625
+ encap_lro = false;
15391626 num_pkts++;
15401627 }
15411628
....@@ -1583,6 +1670,10 @@
15831670 {
15841671 u32 i, ring_idx;
15851672 struct Vmxnet3_RxDesc *rxd;
1673
+
1674
+ /* ring has already been cleaned up */
1675
+ if (!rq->rx_ring[0].base)
1676
+ return;
15861677
15871678 for (ring_idx = 0; ring_idx < 2; ring_idx++) {
15881679 for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
....@@ -1815,8 +1906,8 @@
18151906
18161907 sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
18171908 rq->rx_ring[1].size);
1818
- bi = dma_zalloc_coherent(&adapter->pdev->dev, sz, &rq->buf_info_pa,
1819
- GFP_KERNEL);
1909
+ bi = dma_alloc_coherent(&adapter->pdev->dev, sz, &rq->buf_info_pa,
1910
+ GFP_KERNEL);
18201911 if (!bi)
18211912 goto err;
18221913
....@@ -2433,6 +2524,10 @@
24332524 if (adapter->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
24342525 devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
24352526
2527
+ if (adapter->netdev->features & (NETIF_F_GSO_UDP_TUNNEL |
2528
+ NETIF_F_GSO_UDP_TUNNEL_CSUM))
2529
+ devRead->misc.uptFeatures |= UPT1_F_RXINNEROFLD;
2530
+
24362531 devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu);
24372532 devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa);
24382533 devRead->misc.queueDescLen = cpu_to_le32(
....@@ -2558,6 +2653,39 @@
25582653 spin_unlock_irqrestore(&adapter->cmd_lock, flags);
25592654 }
25602655
2656
+static void
2657
+vmxnet3_init_rssfields(struct vmxnet3_adapter *adapter)
2658
+{
2659
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
2660
+ union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
2661
+ unsigned long flags;
2662
+
2663
+ if (!VMXNET3_VERSION_GE_4(adapter))
2664
+ return;
2665
+
2666
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
2667
+
2668
+ if (adapter->default_rss_fields) {
2669
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2670
+ VMXNET3_CMD_GET_RSS_FIELDS);
2671
+ adapter->rss_fields =
2672
+ VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
2673
+ } else {
2674
+ cmdInfo->setRssFields = adapter->rss_fields;
2675
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2676
+ VMXNET3_CMD_SET_RSS_FIELDS);
2677
+ /* Not all requested RSS may get applied, so get and
2678
+ * cache what was actually applied.
2679
+ */
2680
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2681
+ VMXNET3_CMD_GET_RSS_FIELDS);
2682
+ adapter->rss_fields =
2683
+ VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
2684
+ }
2685
+
2686
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
2687
+}
2688
+
25612689 int
25622690 vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
25632691 {
....@@ -2607,6 +2735,7 @@
26072735 }
26082736
26092737 vmxnet3_init_coalesce(adapter);
2738
+ vmxnet3_init_rssfields(adapter);
26102739
26112740 for (i = 0; i < adapter->num_rx_queues; i++) {
26122741 VMXNET3_WRITE_BAR0_REG(adapter,
....@@ -3043,6 +3172,18 @@
30433172 NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
30443173 NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
30453174 NETIF_F_LRO;
3175
+
3176
+ if (VMXNET3_VERSION_GE_4(adapter)) {
3177
+ netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
3178
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
3179
+
3180
+ netdev->hw_enc_features = NETIF_F_SG | NETIF_F_RXCSUM |
3181
+ NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
3182
+ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_TSO | NETIF_F_TSO6 |
3183
+ NETIF_F_LRO | NETIF_F_GSO_UDP_TUNNEL |
3184
+ NETIF_F_GSO_UDP_TUNNEL_CSUM;
3185
+ }
3186
+
30463187 if (dma64)
30473188 netdev->hw_features |= NETIF_F_HIGHDMA;
30483189 netdev->vlan_features = netdev->hw_features &
....@@ -3199,7 +3340,7 @@
31993340
32003341
32013342 static void
3202
-vmxnet3_tx_timeout(struct net_device *netdev)
3343
+vmxnet3_tx_timeout(struct net_device *netdev, unsigned int txqueue)
32033344 {
32043345 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
32053346 adapter->tx_timeout_count++;
....@@ -3247,7 +3388,9 @@
32473388 .ndo_start_xmit = vmxnet3_xmit_frame,
32483389 .ndo_set_mac_address = vmxnet3_set_mac_addr,
32493390 .ndo_change_mtu = vmxnet3_change_mtu,
3391
+ .ndo_fix_features = vmxnet3_fix_features,
32503392 .ndo_set_features = vmxnet3_set_features,
3393
+ .ndo_features_check = vmxnet3_features_check,
32513394 .ndo_get_stats64 = vmxnet3_get_stats64,
32523395 .ndo_tx_timeout = vmxnet3_tx_timeout,
32533396 .ndo_set_rx_mode = vmxnet3_set_mc,
....@@ -3385,7 +3528,12 @@
33853528 goto err_alloc_pci;
33863529
33873530 ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
3388
- if (ver & (1 << VMXNET3_REV_3)) {
3531
+ if (ver & (1 << VMXNET3_REV_4)) {
3532
+ VMXNET3_WRITE_BAR1_REG(adapter,
3533
+ VMXNET3_REG_VRRS,
3534
+ 1 << VMXNET3_REV_4);
3535
+ adapter->version = VMXNET3_REV_4 + 1;
3536
+ } else if (ver & (1 << VMXNET3_REV_3)) {
33893537 VMXNET3_WRITE_BAR1_REG(adapter,
33903538 VMXNET3_REG_VRRS,
33913539 1 << VMXNET3_REV_3);
....@@ -3429,9 +3577,13 @@
34293577 err = -ENOMEM;
34303578 goto err_ver;
34313579 }
3432
- memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
34333580 adapter->coal_conf->coalMode = VMXNET3_COALESCE_DISABLED;
34343581 adapter->default_coal_mode = true;
3582
+ }
3583
+
3584
+ if (VMXNET3_VERSION_GE_4(adapter)) {
3585
+ adapter->default_rss_fields = true;
3586
+ adapter->rss_fields = VMXNET3_RSS_FIELDS_DEFAULT;
34353587 }
34363588
34373589 SET_NETDEV_DEV(netdev, &pdev->dev);
....@@ -3650,13 +3802,19 @@
36503802 }
36513803
36523804 if (adapter->wol & WAKE_ARP) {
3653
- in_dev = in_dev_get(netdev);
3654
- if (!in_dev)
3655
- goto skip_arp;
3805
+ rcu_read_lock();
36563806
3657
- ifa = (struct in_ifaddr *)in_dev->ifa_list;
3658
- if (!ifa)
3807
+ in_dev = __in_dev_get_rcu(netdev);
3808
+ if (!in_dev) {
3809
+ rcu_read_unlock();
36593810 goto skip_arp;
3811
+ }
3812
+
3813
+ ifa = rcu_dereference(in_dev->ifa_list);
3814
+ if (!ifa) {
3815
+ rcu_read_unlock();
3816
+ goto skip_arp;
3817
+ }
36603818
36613819 pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/
36623820 sizeof(struct arphdr) + /* ARP header */
....@@ -3676,7 +3834,9 @@
36763834
36773835 /* The Unicast IPv4 address in 'tip' field. */
36783836 arpreq += 2 * ETH_ALEN + sizeof(u32);
3679
- *(u32 *)arpreq = ifa->ifa_address;
3837
+ *(__be32 *)arpreq = ifa->ifa_address;
3838
+
3839
+ rcu_read_unlock();
36803840
36813841 /* The mask for the relevant bits. */
36823842 pmConf->filters[i].mask[0] = 0x00;
....@@ -3685,7 +3845,6 @@
36853845 pmConf->filters[i].mask[3] = 0x00;
36863846 pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */
36873847 pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
3688
- in_dev_put(in_dev);
36893848
36903849 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
36913850 i++;