@@ -46,6 +46,9 @@ static int ionic_start_queues(struct ionic_lif *lif);
4646static void ionic_stop_queues (struct ionic_lif * lif );
4747static void ionic_lif_queue_identify (struct ionic_lif * lif );
4848
49+ static int ionic_xdp_queues_config (struct ionic_lif * lif );
50+ static void ionic_xdp_unregister_rxq_info (struct ionic_queue * q );
51+
4952static void ionic_dim_work (struct work_struct * work )
5053{
5154 struct dim * dim = container_of (work , struct dim , work );
@@ -422,6 +425,7 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
422425 qcq -> sg_base_pa = 0 ;
423426 }
424427
428+ ionic_xdp_unregister_rxq_info (& qcq -> q );
425429 ionic_qcq_intr_free (lif , qcq );
426430
427431 vfree (qcq -> cq .info );
@@ -862,8 +866,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
862866 .type = q -> type ,
863867 .ver = lif -> qtype_info [q -> type ].version ,
864868 .index = cpu_to_le32 (q -> index ),
865- .flags = cpu_to_le16 (IONIC_QINIT_F_IRQ |
866- IONIC_QINIT_F_SG ),
869+ .flags = cpu_to_le16 (IONIC_QINIT_F_IRQ ),
867870 .intr_index = cpu_to_le16 (cq -> bound_intr -> index ),
868871 .pid = cpu_to_le16 (q -> pid ),
869872 .ring_size = ilog2 (q -> num_descs ),
@@ -875,6 +878,9 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
875878 };
876879 int err ;
877880
881+ if (!lif -> xdp_prog )
882+ ctx .cmd .q_init .flags |= cpu_to_le16 (IONIC_QINIT_F_SG );
883+
878884 if (qcq -> flags & IONIC_QCQ_F_CMB_RINGS ) {
879885 ctx .cmd .q_init .flags |= cpu_to_le16 (IONIC_QINIT_F_CMB );
880886 ctx .cmd .q_init .ring_base = cpu_to_le64 (qcq -> cmb_q_base_pa );
@@ -1640,6 +1646,8 @@ static int ionic_init_nic_features(struct ionic_lif *lif)
16401646 netdev -> priv_flags |= IFF_UNICAST_FLT |
16411647 IFF_LIVE_ADDR_CHANGE ;
16421648
1649+ netdev -> xdp_features = NETDEV_XDP_ACT_BASIC ;
1650+
16431651 return 0 ;
16441652}
16451653
@@ -1777,6 +1785,18 @@ static int ionic_start_queues_reconfig(struct ionic_lif *lif)
17771785 return err ;
17781786}
17791787
1788+ static bool ionic_xdp_is_valid_mtu (struct ionic_lif * lif , u32 mtu ,
1789+ struct bpf_prog * xdp_prog )
1790+ {
1791+ if (!xdp_prog )
1792+ return true;
1793+
1794+ if (mtu <= IONIC_XDP_MAX_LINEAR_MTU )
1795+ return true;
1796+
1797+ return false;
1798+ }
1799+
17801800static int ionic_change_mtu (struct net_device * netdev , int new_mtu )
17811801{
17821802 struct ionic_lif * lif = netdev_priv (netdev );
@@ -1789,8 +1809,13 @@ static int ionic_change_mtu(struct net_device *netdev, int new_mtu)
17891809 .mtu = cpu_to_le32 (new_mtu ),
17901810 },
17911811 };
1812+ struct bpf_prog * xdp_prog ;
17921813 int err ;
17931814
1815+ xdp_prog = READ_ONCE (lif -> xdp_prog );
1816+ if (!ionic_xdp_is_valid_mtu (lif , new_mtu , xdp_prog ))
1817+ return - EINVAL ;
1818+
17941819 err = ionic_adminq_post_wait (lif , & ctx );
17951820 if (err )
17961821 return err ;
@@ -2166,6 +2191,10 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
21662191 int derr = 0 ;
21672192 int i , err ;
21682193
2194+ err = ionic_xdp_queues_config (lif );
2195+ if (err )
2196+ return err ;
2197+
21692198 for (i = 0 ; i < lif -> nxqs ; i ++ ) {
21702199 if (!(lif -> rxqcqs [i ] && lif -> txqcqs [i ])) {
21712200 dev_err (lif -> ionic -> dev , "%s: bad qcq %d\n" , __func__ , i );
@@ -2211,6 +2240,8 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
22112240 derr = ionic_qcq_disable (lif , lif -> rxqcqs [i ], derr );
22122241 }
22132242
2243+ ionic_xdp_queues_config (lif );
2244+
22142245 return err ;
22152246}
22162247
@@ -2668,11 +2699,150 @@ static void ionic_vf_attr_replay(struct ionic_lif *lif)
26682699 ionic_vf_start (ionic );
26692700}
26702701
2702+ static void ionic_xdp_unregister_rxq_info (struct ionic_queue * q )
2703+ {
2704+ struct xdp_rxq_info * xi ;
2705+
2706+ if (!q -> xdp_rxq_info )
2707+ return ;
2708+
2709+ xi = q -> xdp_rxq_info ;
2710+ q -> xdp_rxq_info = NULL ;
2711+
2712+ xdp_rxq_info_unreg (xi );
2713+ kfree (xi );
2714+ }
2715+
2716+ static int ionic_xdp_register_rxq_info (struct ionic_queue * q , unsigned int napi_id )
2717+ {
2718+ struct xdp_rxq_info * rxq_info ;
2719+ int err ;
2720+
2721+ rxq_info = kzalloc (sizeof (* rxq_info ), GFP_KERNEL );
2722+ if (!rxq_info )
2723+ return - ENOMEM ;
2724+
2725+ err = xdp_rxq_info_reg (rxq_info , q -> lif -> netdev , q -> index , napi_id );
2726+ if (err ) {
2727+ dev_err (q -> dev , "Queue %d xdp_rxq_info_reg failed, err %d\n" ,
2728+ q -> index , err );
2729+ goto err_out ;
2730+ }
2731+
2732+ err = xdp_rxq_info_reg_mem_model (rxq_info , MEM_TYPE_PAGE_ORDER0 , NULL );
2733+ if (err ) {
2734+ dev_err (q -> dev , "Queue %d xdp_rxq_info_reg_mem_model failed, err %d\n" ,
2735+ q -> index , err );
2736+ xdp_rxq_info_unreg (rxq_info );
2737+ goto err_out ;
2738+ }
2739+
2740+ q -> xdp_rxq_info = rxq_info ;
2741+
2742+ return 0 ;
2743+
2744+ err_out :
2745+ kfree (rxq_info );
2746+ return err ;
2747+ }
2748+
2749+ static int ionic_xdp_queues_config (struct ionic_lif * lif )
2750+ {
2751+ unsigned int i ;
2752+ int err ;
2753+
2754+ if (!lif -> rxqcqs )
2755+ return 0 ;
2756+
2757+ /* There's no need to rework memory if not going to/from NULL program.
2758+ * If there is no lif->xdp_prog, there should also be no q.xdp_rxq_info
2759+ * This way we don't need to keep an *xdp_prog in every queue struct.
2760+ */
2761+ if (!lif -> xdp_prog == !lif -> rxqcqs [0 ]-> q .xdp_rxq_info )
2762+ return 0 ;
2763+
2764+ for (i = 0 ; i < lif -> ionic -> nrxqs_per_lif && lif -> rxqcqs [i ]; i ++ ) {
2765+ struct ionic_queue * q = & lif -> rxqcqs [i ]-> q ;
2766+
2767+ if (q -> xdp_rxq_info ) {
2768+ ionic_xdp_unregister_rxq_info (q );
2769+ continue ;
2770+ }
2771+
2772+ err = ionic_xdp_register_rxq_info (q , lif -> rxqcqs [i ]-> napi .napi_id );
2773+ if (err ) {
2774+ dev_err (lif -> ionic -> dev , "failed to register RX queue %d info for XDP, err %d\n" ,
2775+ i , err );
2776+ goto err_out ;
2777+ }
2778+ }
2779+
2780+ return 0 ;
2781+
2782+ err_out :
2783+ for (i = 0 ; i < lif -> ionic -> nrxqs_per_lif && lif -> rxqcqs [i ]; i ++ )
2784+ ionic_xdp_unregister_rxq_info (& lif -> rxqcqs [i ]-> q );
2785+
2786+ return err ;
2787+ }
2788+
2789+ static int ionic_xdp_config (struct net_device * netdev , struct netdev_bpf * bpf )
2790+ {
2791+ struct ionic_lif * lif = netdev_priv (netdev );
2792+ struct bpf_prog * old_prog ;
2793+ u32 maxfs ;
2794+
2795+ if (test_bit (IONIC_LIF_F_SPLIT_INTR , lif -> state )) {
2796+ #define XDP_ERR_SPLIT "XDP not available with split Tx/Rx interrupts"
2797+ NL_SET_ERR_MSG_MOD (bpf -> extack , XDP_ERR_SPLIT );
2798+ netdev_info (lif -> netdev , XDP_ERR_SPLIT );
2799+ return - EOPNOTSUPP ;
2800+ }
2801+
2802+ if (!ionic_xdp_is_valid_mtu (lif , netdev -> mtu , bpf -> prog )) {
2803+ #define XDP_ERR_MTU "MTU is too large for XDP without frags support"
2804+ NL_SET_ERR_MSG_MOD (bpf -> extack , XDP_ERR_MTU );
2805+ netdev_info (lif -> netdev , XDP_ERR_MTU );
2806+ return - EINVAL ;
2807+ }
2808+
2809+ maxfs = __le32_to_cpu (lif -> identity -> eth .max_frame_size ) - VLAN_ETH_HLEN ;
2810+ if (bpf -> prog )
2811+ maxfs = min_t (u32 , maxfs , IONIC_XDP_MAX_LINEAR_MTU );
2812+ netdev -> max_mtu = maxfs ;
2813+
2814+ if (!netif_running (netdev )) {
2815+ old_prog = xchg (& lif -> xdp_prog , bpf -> prog );
2816+ } else {
2817+ mutex_lock (& lif -> queue_lock );
2818+ ionic_stop_queues_reconfig (lif );
2819+ old_prog = xchg (& lif -> xdp_prog , bpf -> prog );
2820+ ionic_start_queues_reconfig (lif );
2821+ mutex_unlock (& lif -> queue_lock );
2822+ }
2823+
2824+ if (old_prog )
2825+ bpf_prog_put (old_prog );
2826+
2827+ return 0 ;
2828+ }
2829+
2830+ static int ionic_xdp (struct net_device * netdev , struct netdev_bpf * bpf )
2831+ {
2832+ switch (bpf -> command ) {
2833+ case XDP_SETUP_PROG :
2834+ return ionic_xdp_config (netdev , bpf );
2835+ default :
2836+ return - EINVAL ;
2837+ }
2838+ }
2839+
26712840static const struct net_device_ops ionic_netdev_ops = {
26722841 .ndo_open = ionic_open ,
26732842 .ndo_stop = ionic_stop ,
26742843 .ndo_eth_ioctl = ionic_eth_ioctl ,
26752844 .ndo_start_xmit = ionic_start_xmit ,
2845+ .ndo_bpf = ionic_xdp ,
26762846 .ndo_get_stats64 = ionic_get_stats64 ,
26772847 .ndo_set_rx_mode = ionic_ndo_set_rx_mode ,
26782848 .ndo_set_features = ionic_set_features ,
@@ -2755,6 +2925,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
27552925 swap (a -> q .base , b -> q .base );
27562926 swap (a -> q .base_pa , b -> q .base_pa );
27572927 swap (a -> q .info , b -> q .info );
2928+ swap (a -> q .xdp_rxq_info , b -> q .xdp_rxq_info );
27582929 swap (a -> q_base , b -> q_base );
27592930 swap (a -> q_base_pa , b -> q_base_pa );
27602931 swap (a -> q_size , b -> q_size );
0 commit comments