@@ -226,6 +226,8 @@ static void efx_fini_napi_channel(struct efx_channel *channel);
226
226
static void efx_fini_struct (struct efx_nic * efx );
227
227
static void efx_start_all (struct efx_nic * efx );
228
228
static void efx_stop_all (struct efx_nic * efx );
229
+ static int efx_xdp_setup_prog (struct efx_nic * efx , struct bpf_prog * prog );
230
+ static int efx_xdp (struct net_device * dev , struct netdev_bpf * xdp );
229
231
230
232
#define EFX_ASSERT_RESET_SERIALISED (efx ) \
231
233
do { \
@@ -2025,6 +2027,10 @@ static void efx_stop_all(struct efx_nic *efx)
2025
2027
2026
2028
static void efx_remove_all (struct efx_nic * efx )
2027
2029
{
2030
+ rtnl_lock ();
2031
+ efx_xdp_setup_prog (efx , NULL );
2032
+ rtnl_unlock ();
2033
+
2028
2034
efx_remove_channels (efx );
2029
2035
efx_remove_filters (efx );
2030
2036
#ifdef CONFIG_SFC_SRIOV
@@ -2280,6 +2286,17 @@ static void efx_watchdog(struct net_device *net_dev)
2280
2286
efx_schedule_reset (efx , RESET_TYPE_TX_WATCHDOG );
2281
2287
}
2282
2288
2289
+ static unsigned int efx_xdp_max_mtu (struct efx_nic * efx )
2290
+ {
2291
+ /* The maximum MTU that we can fit in a single page, allowing for
2292
+ * framing, overhead and XDP headroom.
2293
+ */
2294
+ int overhead = EFX_MAX_FRAME_LEN (0 ) + sizeof (struct efx_rx_page_state ) +
2295
+ efx -> rx_prefix_size + efx -> type -> rx_buffer_padding +
2296
+ efx -> rx_ip_align + XDP_PACKET_HEADROOM ;
2297
+
2298
+ return PAGE_SIZE - overhead ;
2299
+ }
2283
2300
2284
2301
/* Context: process, rtnl_lock() held. */
2285
2302
static int efx_change_mtu (struct net_device * net_dev , int new_mtu )
@@ -2291,6 +2308,14 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
2291
2308
if (rc )
2292
2309
return rc ;
2293
2310
2311
+ if (rtnl_dereference (efx -> xdp_prog ) &&
2312
+ new_mtu > efx_xdp_max_mtu (efx )) {
2313
+ netif_err (efx , drv , efx -> net_dev ,
2314
+ "Requested MTU of %d too big for XDP (max: %d)\n" ,
2315
+ new_mtu , efx_xdp_max_mtu (efx ));
2316
+ return - EINVAL ;
2317
+ }
2318
+
2294
2319
netif_dbg (efx , drv , efx -> net_dev , "changing MTU to %d\n" , new_mtu );
2295
2320
2296
2321
efx_device_detach_sync (efx );
@@ -2492,8 +2517,53 @@ static const struct net_device_ops efx_netdev_ops = {
2492
2517
#endif
2493
2518
.ndo_udp_tunnel_add = efx_udp_tunnel_add ,
2494
2519
.ndo_udp_tunnel_del = efx_udp_tunnel_del ,
2520
+ .ndo_bpf = efx_xdp
2495
2521
};
2496
2522
2523
+ static int efx_xdp_setup_prog (struct efx_nic * efx , struct bpf_prog * prog )
2524
+ {
2525
+ struct bpf_prog * old_prog ;
2526
+
2527
+ if (efx -> xdp_rxq_info_failed ) {
2528
+ netif_err (efx , drv , efx -> net_dev ,
2529
+ "Unable to bind XDP program due to previous failure of rxq_info\n" );
2530
+ return - EINVAL ;
2531
+ }
2532
+
2533
+ if (prog && efx -> net_dev -> mtu > efx_xdp_max_mtu (efx )) {
2534
+ netif_err (efx , drv , efx -> net_dev ,
2535
+ "Unable to configure XDP with MTU of %d (max: %d)\n" ,
2536
+ efx -> net_dev -> mtu , efx_xdp_max_mtu (efx ));
2537
+ return - EINVAL ;
2538
+ }
2539
+
2540
+ old_prog = rtnl_dereference (efx -> xdp_prog );
2541
+ rcu_assign_pointer (efx -> xdp_prog , prog );
2542
+ /* Release the reference that was originally passed by the caller. */
2543
+ if (old_prog )
2544
+ bpf_prog_put (old_prog );
2545
+
2546
+ return 0 ;
2547
+ }
2548
+
2549
+ /* Context: process, rtnl_lock() held. */
2550
+ static int efx_xdp (struct net_device * dev , struct netdev_bpf * xdp )
2551
+ {
2552
+ struct efx_nic * efx = netdev_priv (dev );
2553
+ struct bpf_prog * xdp_prog ;
2554
+
2555
+ switch (xdp -> command ) {
2556
+ case XDP_SETUP_PROG :
2557
+ return efx_xdp_setup_prog (efx , xdp -> prog );
2558
+ case XDP_QUERY_PROG :
2559
+ xdp_prog = rtnl_dereference (efx -> xdp_prog );
2560
+ xdp -> prog_id = xdp_prog ? xdp_prog -> aux -> id : 0 ;
2561
+ return 0 ;
2562
+ default :
2563
+ return - EINVAL ;
2564
+ }
2565
+ }
2566
+
2497
2567
static void efx_update_name (struct efx_nic * efx )
2498
2568
{
2499
2569
strcpy (efx -> name , efx -> net_dev -> name );
0 commit comments