45
45
#endif
46
46
#include <linux/crash_dump.h>
47
47
#include <net/busy_poll.h>
48
+ #include <net/vxlan.h>
48
49
49
50
#include "cq_enet_desc.h"
50
51
#include "vnic_dev.h"
@@ -176,6 +177,134 @@ static void enic_unset_affinity_hint(struct enic *enic)
176
177
irq_set_affinity_hint (enic -> msix_entry [i ].vector , NULL );
177
178
}
178
179
180
+ static void enic_udp_tunnel_add (struct net_device * netdev ,
181
+ struct udp_tunnel_info * ti )
182
+ {
183
+ struct enic * enic = netdev_priv (netdev );
184
+ __be16 port = ti -> port ;
185
+ int err ;
186
+
187
+ spin_lock_bh (& enic -> devcmd_lock );
188
+
189
+ if (ti -> type != UDP_TUNNEL_TYPE_VXLAN ) {
190
+ netdev_info (netdev , "udp_tnl: only vxlan tunnel offload supported" );
191
+ goto error ;
192
+ }
193
+
194
+ if (ti -> sa_family != AF_INET ) {
195
+ netdev_info (netdev , "vxlan: only IPv4 offload supported" );
196
+ goto error ;
197
+ }
198
+
199
+ if (enic -> vxlan .vxlan_udp_port_number ) {
200
+ if (ntohs (port ) == enic -> vxlan .vxlan_udp_port_number )
201
+ netdev_warn (netdev , "vxlan: udp port already offloaded" );
202
+ else
203
+ netdev_info (netdev , "vxlan: offload supported for only one UDP port" );
204
+
205
+ goto error ;
206
+ }
207
+
208
+ err = vnic_dev_overlay_offload_cfg (enic -> vdev ,
209
+ OVERLAY_CFG_VXLAN_PORT_UPDATE ,
210
+ ntohs (port ));
211
+ if (err )
212
+ goto error ;
213
+
214
+ err = vnic_dev_overlay_offload_ctrl (enic -> vdev , OVERLAY_FEATURE_VXLAN ,
215
+ enic -> vxlan .patch_level );
216
+ if (err )
217
+ goto error ;
218
+
219
+ enic -> vxlan .vxlan_udp_port_number = ntohs (port );
220
+
221
+ netdev_info (netdev , "vxlan fw-vers-%d: offload enabled for udp port: %d, sa_family: %d " ,
222
+ (int )enic -> vxlan .patch_level , ntohs (port ), ti -> sa_family );
223
+
224
+ goto unlock ;
225
+
226
+ error :
227
+ netdev_info (netdev , "failed to offload udp port: %d, sa_family: %d, type: %d" ,
228
+ ntohs (port ), ti -> sa_family , ti -> type );
229
+ unlock :
230
+ spin_unlock_bh (& enic -> devcmd_lock );
231
+ }
232
+
233
+ static void enic_udp_tunnel_del (struct net_device * netdev ,
234
+ struct udp_tunnel_info * ti )
235
+ {
236
+ struct enic * enic = netdev_priv (netdev );
237
+ int err ;
238
+
239
+ spin_lock_bh (& enic -> devcmd_lock );
240
+
241
+ if ((ti -> sa_family != AF_INET ) ||
242
+ ((ntohs (ti -> port ) != enic -> vxlan .vxlan_udp_port_number )) ||
243
+ (ti -> type != UDP_TUNNEL_TYPE_VXLAN )) {
244
+ netdev_info (netdev , "udp_tnl: port:%d, sa_family: %d, type: %d not offloaded" ,
245
+ ntohs (ti -> port ), ti -> sa_family , ti -> type );
246
+ goto unlock ;
247
+ }
248
+
249
+ err = vnic_dev_overlay_offload_ctrl (enic -> vdev , OVERLAY_FEATURE_VXLAN ,
250
+ OVERLAY_OFFLOAD_DISABLE );
251
+ if (err ) {
252
+ netdev_err (netdev , "vxlan: del offload udp port: %d failed" ,
253
+ ntohs (ti -> port ));
254
+ goto unlock ;
255
+ }
256
+
257
+ enic -> vxlan .vxlan_udp_port_number = 0 ;
258
+
259
+ netdev_info (netdev , "vxlan: del offload udp port %d, family %d\n" ,
260
+ ntohs (ti -> port ), ti -> sa_family );
261
+
262
+ unlock :
263
+ spin_unlock_bh (& enic -> devcmd_lock );
264
+ }
265
+
266
+ static netdev_features_t enic_features_check (struct sk_buff * skb ,
267
+ struct net_device * dev ,
268
+ netdev_features_t features )
269
+ {
270
+ const struct ethhdr * eth = (struct ethhdr * )skb_inner_mac_header (skb );
271
+ struct enic * enic = netdev_priv (dev );
272
+ struct udphdr * udph ;
273
+ u16 port = 0 ;
274
+ u16 proto ;
275
+
276
+ if (!skb -> encapsulation )
277
+ return features ;
278
+
279
+ features = vxlan_features_check (skb , features );
280
+
281
+ /* hardware only supports IPv4 vxlan tunnel */
282
+ if (vlan_get_protocol (skb ) != htons (ETH_P_IP ))
283
+ goto out ;
284
+
285
+ /* hardware does not support offload of ipv6 inner pkt */
286
+ if (eth -> h_proto != ntohs (ETH_P_IP ))
287
+ goto out ;
288
+
289
+ proto = ip_hdr (skb )-> protocol ;
290
+
291
+ if (proto == IPPROTO_UDP ) {
292
+ udph = udp_hdr (skb );
293
+ port = be16_to_cpu (udph -> dest );
294
+ }
295
+
296
+ /* HW supports offload of only one UDP port. Remove CSUM and GSO MASK
297
+ * for other UDP port tunnels
298
+ */
299
+ if (port != enic -> vxlan .vxlan_udp_port_number )
300
+ goto out ;
301
+
302
+ return features ;
303
+
304
+ out :
305
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK );
306
+ }
307
+
179
308
int enic_is_dynamic (struct enic * enic )
180
309
{
181
310
return enic -> pdev -> device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN ;
@@ -504,20 +633,19 @@ static int enic_queue_wq_skb_csum_l4(struct enic *enic, struct vnic_wq *wq,
504
633
return err ;
505
634
}
506
635
507
- static int enic_queue_wq_skb_tso (struct enic * enic , struct vnic_wq * wq ,
508
- struct sk_buff * skb , unsigned int mss ,
509
- int vlan_tag_insert , unsigned int vlan_tag ,
510
- int loopback )
636
+ static void enic_preload_tcp_csum_encap (struct sk_buff * skb )
511
637
{
512
- unsigned int frag_len_left = skb_headlen ( skb );
513
- unsigned int len_left = skb -> len - frag_len_left ;
514
- unsigned int hdr_len = skb_transport_offset (skb ) + tcp_hdrlen ( skb );
515
- int eop = ( len_left == 0 );
516
- unsigned int len ;
517
- dma_addr_t dma_addr ;
518
- unsigned int offset = 0 ;
519
- skb_frag_t * frag ;
638
+ if ( skb -> protocol == cpu_to_be16 ( ETH_P_IP )) {
639
+ inner_ip_hdr ( skb ) -> check = 0 ;
640
+ inner_tcp_hdr (skb )-> check =
641
+ ~ csum_tcpudp_magic ( inner_ip_hdr ( skb ) -> saddr ,
642
+ inner_ip_hdr ( skb ) -> daddr , 0 ,
643
+ IPPROTO_TCP , 0 ) ;
644
+ }
645
+ }
520
646
647
+ static void enic_preload_tcp_csum (struct sk_buff * skb )
648
+ {
521
649
/* Preload TCP csum field with IP pseudo hdr calculated
522
650
* with IP length set to zero. HW will later add in length
523
651
* to each TCP segment resulting from the TSO.
@@ -531,6 +659,30 @@ static int enic_queue_wq_skb_tso(struct enic *enic, struct vnic_wq *wq,
531
659
tcp_hdr (skb )-> check = ~csum_ipv6_magic (& ipv6_hdr (skb )-> saddr ,
532
660
& ipv6_hdr (skb )-> daddr , 0 , IPPROTO_TCP , 0 );
533
661
}
662
+ }
663
+
664
+ static int enic_queue_wq_skb_tso (struct enic * enic , struct vnic_wq * wq ,
665
+ struct sk_buff * skb , unsigned int mss ,
666
+ int vlan_tag_insert , unsigned int vlan_tag ,
667
+ int loopback )
668
+ {
669
+ unsigned int frag_len_left = skb_headlen (skb );
670
+ unsigned int len_left = skb -> len - frag_len_left ;
671
+ int eop = (len_left == 0 );
672
+ unsigned int offset = 0 ;
673
+ unsigned int hdr_len ;
674
+ dma_addr_t dma_addr ;
675
+ unsigned int len ;
676
+ skb_frag_t * frag ;
677
+
678
+ if (skb -> encapsulation ) {
679
+ hdr_len = skb_inner_transport_header (skb ) - skb -> data ;
680
+ hdr_len += inner_tcp_hdrlen (skb );
681
+ enic_preload_tcp_csum_encap (skb );
682
+ } else {
683
+ hdr_len = skb_transport_offset (skb ) + tcp_hdrlen (skb );
684
+ enic_preload_tcp_csum (skb );
685
+ }
534
686
535
687
/* Queue WQ_ENET_MAX_DESC_LEN length descriptors
536
688
* for the main skb fragment
@@ -579,6 +731,38 @@ static int enic_queue_wq_skb_tso(struct enic *enic, struct vnic_wq *wq,
579
731
return 0 ;
580
732
}
581
733
734
+ static inline int enic_queue_wq_skb_encap (struct enic * enic , struct vnic_wq * wq ,
735
+ struct sk_buff * skb ,
736
+ int vlan_tag_insert ,
737
+ unsigned int vlan_tag , int loopback )
738
+ {
739
+ unsigned int head_len = skb_headlen (skb );
740
+ unsigned int len_left = skb -> len - head_len ;
741
+ /* Hardware will overwrite the checksum fields, calculating from
742
+ * scratch and ignoring the value placed by software.
743
+ * Offload mode = 00
744
+ * mss[2], mss[1], mss[0] bits are set
745
+ */
746
+ unsigned int mss_or_csum = 7 ;
747
+ int eop = (len_left == 0 );
748
+ dma_addr_t dma_addr ;
749
+ int err = 0 ;
750
+
751
+ dma_addr = pci_map_single (enic -> pdev , skb -> data , head_len ,
752
+ PCI_DMA_TODEVICE );
753
+ if (unlikely (enic_dma_map_check (enic , dma_addr )))
754
+ return - ENOMEM ;
755
+
756
+ enic_queue_wq_desc_ex (wq , skb , dma_addr , head_len , mss_or_csum , 0 ,
757
+ vlan_tag_insert , vlan_tag ,
758
+ WQ_ENET_OFFLOAD_MODE_CSUM , eop , 1 /* SOP */ , eop ,
759
+ loopback );
760
+ if (!eop )
761
+ err = enic_queue_wq_skb_cont (enic , wq , skb , len_left , loopback );
762
+
763
+ return err ;
764
+ }
765
+
582
766
static inline void enic_queue_wq_skb (struct enic * enic ,
583
767
struct vnic_wq * wq , struct sk_buff * skb )
584
768
{
@@ -601,6 +785,9 @@ static inline void enic_queue_wq_skb(struct enic *enic,
601
785
err = enic_queue_wq_skb_tso (enic , wq , skb , mss ,
602
786
vlan_tag_insert , vlan_tag ,
603
787
loopback );
788
+ else if (skb -> encapsulation )
789
+ err = enic_queue_wq_skb_encap (enic , wq , skb , vlan_tag_insert ,
790
+ vlan_tag , loopback );
604
791
else if (skb -> ip_summed == CHECKSUM_PARTIAL )
605
792
err = enic_queue_wq_skb_csum_l4 (enic , wq , skb , vlan_tag_insert ,
606
793
vlan_tag , loopback );
@@ -1113,6 +1300,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1113
1300
u8 packet_error ;
1114
1301
u16 q_number , completed_index , bytes_written , vlan_tci , checksum ;
1115
1302
u32 rss_hash ;
1303
+ bool outer_csum_ok = true, encap = false;
1116
1304
1117
1305
if (skipped )
1118
1306
return ;
@@ -1161,7 +1349,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1161
1349
skb_put (skb , bytes_written );
1162
1350
skb -> protocol = eth_type_trans (skb , netdev );
1163
1351
skb_record_rx_queue (skb , q_number );
1164
- if (netdev -> features & NETIF_F_RXHASH ) {
1352
+ if ((netdev -> features & NETIF_F_RXHASH ) && rss_hash &&
1353
+ (type == 3 )) {
1165
1354
switch (rss_type ) {
1166
1355
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4 :
1167
1356
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6 :
@@ -1175,15 +1364,39 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
1175
1364
break ;
1176
1365
}
1177
1366
}
1367
+ if (enic -> vxlan .vxlan_udp_port_number ) {
1368
+ switch (enic -> vxlan .patch_level ) {
1369
+ case 0 :
1370
+ if (fcoe ) {
1371
+ encap = true;
1372
+ outer_csum_ok = fcoe_fc_crc_ok ;
1373
+ }
1374
+ break ;
1375
+ case 2 :
1376
+ if ((type == 7 ) &&
1377
+ (rss_hash & BIT (0 ))) {
1378
+ encap = true;
1379
+ outer_csum_ok = (rss_hash & BIT (1 )) &&
1380
+ (rss_hash & BIT (2 ));
1381
+ }
1382
+ break ;
1383
+ }
1384
+ }
1178
1385
1179
1386
/* Hardware does not provide whole packet checksum. It only
1180
1387
* provides pseudo checksum. Since hw validates the packet
1181
1388
* checksum but not provide us the checksum value. use
1182
1389
* CHECSUM_UNNECESSARY.
1390
+ *
1391
+ * In case of encap pkt tcp_udp_csum_ok/tcp_udp_csum_ok is
1392
+ * inner csum_ok. outer_csum_ok is set by hw when outer udp
1393
+ * csum is correct or is zero.
1183
1394
*/
1184
- if ((netdev -> features & NETIF_F_RXCSUM ) && tcp_udp_csum_ok &&
1185
- ipv4_csum_ok )
1395
+ if ((netdev -> features & NETIF_F_RXCSUM ) && ! csum_not_calc &&
1396
+ tcp_udp_csum_ok && ipv4_csum_ok && outer_csum_ok ) {
1186
1397
skb -> ip_summed = CHECKSUM_UNNECESSARY ;
1398
+ skb -> csum_level = encap ;
1399
+ }
1187
1400
1188
1401
if (vlan_stripped )
1189
1402
__vlan_hwaccel_put_tag (skb , htons (ETH_P_8021Q ), vlan_tci );
@@ -2285,6 +2498,9 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
2285
2498
#ifdef CONFIG_RFS_ACCEL
2286
2499
.ndo_rx_flow_steer = enic_rx_flow_steer ,
2287
2500
#endif
2501
+ .ndo_udp_tunnel_add = enic_udp_tunnel_add ,
2502
+ .ndo_udp_tunnel_del = enic_udp_tunnel_del ,
2503
+ .ndo_features_check = enic_features_check ,
2288
2504
};
2289
2505
2290
2506
static const struct net_device_ops enic_netdev_ops = {
@@ -2308,6 +2524,9 @@ static const struct net_device_ops enic_netdev_ops = {
2308
2524
#ifdef CONFIG_RFS_ACCEL
2309
2525
.ndo_rx_flow_steer = enic_rx_flow_steer ,
2310
2526
#endif
2527
+ .ndo_udp_tunnel_add = enic_udp_tunnel_add ,
2528
+ .ndo_udp_tunnel_del = enic_udp_tunnel_del ,
2529
+ .ndo_features_check = enic_features_check ,
2311
2530
};
2312
2531
2313
2532
static void enic_dev_deinit (struct enic * enic )
@@ -2683,6 +2902,39 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2683
2902
netdev -> hw_features |= NETIF_F_RXHASH ;
2684
2903
if (ENIC_SETTING (enic , RXCSUM ))
2685
2904
netdev -> hw_features |= NETIF_F_RXCSUM ;
2905
+ if (ENIC_SETTING (enic , VXLAN )) {
2906
+ u64 patch_level ;
2907
+
2908
+ netdev -> hw_enc_features |= NETIF_F_RXCSUM |
2909
+ NETIF_F_TSO |
2910
+ NETIF_F_TSO_ECN |
2911
+ NETIF_F_GSO_UDP_TUNNEL |
2912
+ NETIF_F_HW_CSUM |
2913
+ NETIF_F_GSO_UDP_TUNNEL_CSUM ;
2914
+ netdev -> hw_features |= netdev -> hw_enc_features ;
2915
+ /* get bit mask from hw about supported offload bit level
2916
+ * BIT(0) = fw supports patch_level 0
2917
+ * fcoe bit = encap
2918
+ * fcoe_fc_crc_ok = outer csum ok
2919
+ * BIT(1) = always set by fw
2920
+ * BIT(2) = fw supports patch_level 2
2921
+ * BIT(0) in rss_hash = encap
2922
+ * BIT(1,2) in rss_hash = outer_ip_csum_ok/
2923
+ * outer_tcp_csum_ok
2924
+ * used in enic_rq_indicate_buf
2925
+ */
2926
+ err = vnic_dev_get_supported_feature_ver (enic -> vdev ,
2927
+ VIC_FEATURE_VXLAN ,
2928
+ & patch_level );
2929
+ if (err )
2930
+ patch_level = 0 ;
2931
+ /* mask bits that are supported by driver
2932
+ */
2933
+ patch_level &= BIT_ULL (0 ) | BIT_ULL (2 );
2934
+ patch_level = fls (patch_level );
2935
+ patch_level = patch_level ? patch_level - 1 : 0 ;
2936
+ enic -> vxlan .patch_level = patch_level ;
2937
+ }
2686
2938
2687
2939
netdev -> features |= netdev -> hw_features ;
2688
2940
netdev -> vlan_features |= netdev -> features ;
0 commit comments