diff options
Diffstat (limited to 'drivers/net/ethernet/netronome')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/bpf/main.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/bpf/main.h | 24 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/offload.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_app.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_asm.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_main.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_port.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_port.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h | 43 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c | 21 |
16 files changed, 110 insertions, 74 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 322027792fe8..34e98aa6b956 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -35,6 +35,7 @@ #include "../nfpcore/nfp_cpp.h" #include "../nfpcore/nfp_nffw.h" +#include "../nfpcore/nfp_nsp.h" #include "../nfp_app.h" #include "../nfp_main.h" #include "../nfp_net.h" @@ -87,9 +88,20 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) static int nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) { + struct nfp_pf *pf = app->pf; struct nfp_bpf_vnic *bv; int err; + if (!pf->eth_tbl) { + nfp_err(pf->cpp, "No ETH table\n"); + return -EINVAL; + } + if (pf->max_data_vnics != pf->eth_tbl->count) { + nfp_err(pf->cpp, "ETH entries don't match vNICs (%d vs %d)\n", + pf->max_data_vnics, pf->eth_tbl->count); + return -EINVAL; + } + bv = kzalloc(sizeof(*bv), GFP_KERNEL); if (!bv) return -ENOMEM; @@ -170,6 +182,7 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, return err; bv->tc_prog = cls_bpf->prog; + nn->port->tc_offload_cnt = !!bv->tc_prog; return 0; } @@ -207,13 +220,6 @@ static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev, } } -static bool nfp_bpf_tc_busy(struct nfp_app *app, struct nfp_net *nn) -{ - struct nfp_bpf_vnic *bv = nn->app_priv; - - return !!bv->tc_prog; -} - static int nfp_bpf_change_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu) { @@ -417,7 +423,6 @@ const struct nfp_app_type app_bpf = { .ctrl_msg_rx = nfp_bpf_ctrl_msg_rx, .setup_tc = nfp_bpf_setup_tc, - .tc_busy = nfp_bpf_tc_busy, .bpf = nfp_ndo_bpf, .xdp_offload = nfp_bpf_xdp_offload, }; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index 424fe8338105..054df3dc0698 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -112,22 +112,22 @@ enum pkt_vec { * @map_elems_in_use: number of elements allocated to offloaded maps * * @adjust_head: adjust head capability - * @flags: extra flags for adjust head - * @off_min: minimal packet offset within buffer required - * @off_max: maximum packet offset within buffer required - * @guaranteed_sub: amount of negative adjustment guaranteed possible - * @guaranteed_add: amount of positive adjustment guaranteed possible + * @adjust_head.flags: extra flags for adjust head + * @adjust_head.off_min: minimal packet offset within buffer required + * @adjust_head.off_max: maximum packet offset within buffer required + * @adjust_head.guaranteed_sub: negative adjustment guaranteed possible + * @adjust_head.guaranteed_add: positive adjustment guaranteed possible * * @maps: map capability - * @types: supported map types - * @max_maps: max number of maps supported - * @max_elems: max number of entries in each map - * @max_key_sz: max size of map key - * @max_val_sz: max size of map value - * @max_elem_sz: max size of map entry (key + value) + * @maps.types: supported map types + * @maps.max_maps: max number of maps supported + * @maps.max_elems: max number of entries in each map + * @maps.max_key_sz: max size of map key + * @maps.max_val_sz: max size of map value + * @maps.max_elem_sz: max size of map entry (key + value) * * @helpers: helper addressess for various calls - * @map_lookup: map lookup helper address + * @helpers.map_lookup: map lookup helper address */ struct nfp_app_bpf { struct nfp_app *app; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 08c4c6dc5f7f..eb5c13dea8f5 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -349,6 +349,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, struct tc_cls_flower_offload *flow, bool egress) { enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE; + struct nfp_port *port = nfp_port_from_netdev(netdev); struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload *flow_pay; struct nfp_fl_key_ls *key_layer; @@ -390,6 +391,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, INIT_HLIST_NODE(&flow_pay->link); flow_pay->tc_flower_cookie = flow->cookie; hash_add_rcu(priv->flow_table, &flow_pay->link, flow->cookie); + port->tc_offload_cnt++; /* Deallocate flow payload when flower rule has been destroyed. */ kfree(key_layer); @@ -421,6 +423,7 @@ static int nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, struct tc_cls_flower_offload *flow) { + struct nfp_port *port = nfp_port_from_netdev(netdev); struct nfp_fl_payload *nfp_flow; int err; @@ -442,6 +445,7 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, err_free_flow: hash_del_rcu(&nfp_flow->link); + port->tc_offload_cnt--; kfree(nfp_flow->action_data); kfree(nfp_flow->mask_data); kfree(nfp_flow->unmasked_data); diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index b03f22f29612..ec524d97869d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -50,9 +50,9 @@ * @seq: sequence number of the message * @count: number of tunnels report in message * @flags: options part of the request - * @ipv4: dest IPv4 address of active route - * @egress_port: port the encapsulated packet egressed - * @extra: reserved for future use + * @tun_info.ipv4: dest IPv4 address of active route + * @tun_info.egress_port: port the encapsulated packet egressed + * @tun_info.extra: reserved for future use * @tun_info: tunnels that have sent traffic in reported period */ struct nfp_tun_active_tuns { @@ -132,8 +132,8 @@ struct nfp_ipv4_addr_entry { * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP * @reserved: reserved for future use * @count: number of MAC addresses in the message - * @index: index of MAC address in the lookup table - * @addr: interface MAC address + * @addresses.index: index of MAC address in the lookup table + * @addresses.addr: interface MAC address * @addresses: series of MACs to offload */ struct nfp_tun_mac_addr { diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h index 437964afa8ee..20546ae67909 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h @@ -92,7 +92,6 @@ extern const struct nfp_app_type app_flower; * @stop: stop application logic * @ctrl_msg_rx: control message handler * @setup_tc: setup TC ndo - * @tc_busy: TC HW offload busy (rules loaded) * @bpf: BPF ndo offload-related calls * @xdp_offload: offload an XDP program * @eswitch_mode_get: get SR-IOV eswitch mode @@ -135,7 +134,6 @@ struct nfp_app_type { int (*setup_tc)(struct nfp_app *app, struct net_device *netdev, enum tc_setup_type type, void *type_data); - bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn); int (*bpf)(struct nfp_app *app, struct nfp_net *nn, struct netdev_bpf *xdp); int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn, @@ -301,13 +299,6 @@ static inline bool nfp_app_has_tc(struct nfp_app *app) return app && app->type->setup_tc; } -static inline bool nfp_app_tc_busy(struct nfp_app *app, struct nfp_net *nn) -{ - if (!app || !app->type->tc_busy) - return false; - return app->type->tc_busy(app, nn); -} - static inline int nfp_app_setup_tc(struct nfp_app *app, struct net_device *netdev, enum tc_setup_type type, void *type_data) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.c b/drivers/net/ethernet/netronome/nfp/nfp_asm.c index 3f6952b66a49..1e597600c693 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_asm.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.c @@ -107,7 +107,7 @@ u16 immed_get_value(u64 instr) if (!unreg_is_imm(reg)) reg = FIELD_GET(OP_IMMED_B_SRC, instr); - return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr); + return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr) << 8; } void immed_set_value(u64 *instr, u16 immed) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index cc570bb6563c..ab301d56430b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -649,3 +649,4 @@ MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw"); MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("The Netronome Flow Processor (NFP) driver."); +MODULE_VERSION(UTS_RELEASE); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h index d88eda9707e6..787df47ec430 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h @@ -193,7 +193,8 @@ struct nfp_net_tx_desc { /** * struct nfp_net_tx_buf - software TX buffer descriptor - * @skb: sk_buff associated with this buffer + * @skb: normal ring, sk_buff associated with this buffer + * @frag: XDP ring, page frag associated with this buffer * @dma_addr: DMA mapping address of the buffer * @fidx: Fragment index (-1 for the head and [0..nr_frags-1] for frags) * @pkt_cnt: Number of packets to be produced out of the skb associated @@ -377,6 +378,9 @@ struct nfp_net_rx_ring { * struct nfp_net_r_vector - Per ring interrupt vector configuration * @nfp_net: Backpointer to nfp_net structure * @napi: NAPI structure for this ring vec + * @tasklet: ctrl vNIC, tasklet for servicing the r_vec + * @queue: ctrl vNIC, send queue + * @lock: ctrl vNIC, r_vec lock protects @queue * @tx_ring: Pointer to TX ring * @rx_ring: Pointer to RX ring * @xdp_ring: Pointer to an extra TX ring for XDP diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index c0fd351c86b1..a05be0ab2713 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -3210,10 +3210,9 @@ static int nfp_net_set_features(struct net_device *netdev, new_ctrl &= ~NFP_NET_CFG_CTRL_GATHER; } - if (changed & NETIF_F_HW_TC && nfp_app_tc_busy(nn->app, nn)) { - nn_err(nn, "Cannot disable HW TC offload while in use\n"); - return -EBUSY; - } + err = nfp_port_set_features(netdev, features); + if (err) + return err; nn_dbg(nn, "Feature change 0x%llx -> 0x%llx (changed=0x%llx)\n", netdev->features, features, changed); @@ -3734,7 +3733,7 @@ static void nfp_net_netdev_init(struct nfp_net *nn) netdev->features = netdev->hw_features; - if (nfp_app_has_tc(nn->app)) + if (nfp_app_has_tc(nn->app) && nn->port) netdev->hw_features |= NETIF_F_HW_TC; /* Advertise but disable TSO by default. */ @@ -3751,6 +3750,8 @@ static void nfp_net_netdev_init(struct nfp_net *nn) netdev->min_mtu = ETH_MIN_MTU; netdev->max_mtu = nn->max_mtu; + netdev->gso_max_segs = NFP_NET_LSO_MAX_SEGS; + netif_carrier_off(netdev); nfp_net_set_ethtool_ops(netdev); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c index ffb402746ad4..1f9149bb2ae6 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c @@ -65,7 +65,7 @@ int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem, u32 hdr = readl(data); length = FIELD_GET(NFP_NET_CFG_TLV_HEADER_LENGTH, hdr); - offset = data - ctrl_mem + NFP_NET_CFG_TLV_BASE; + offset = data - ctrl_mem; /* Advance past the header */ data += 4; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h index eeecef2caac6..4499a7333078 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h @@ -59,9 +59,12 @@ #define NFP_NET_RX_OFFSET 32 /** - * Maximum header size supported for LSO frames + * LSO parameters + * %NFP_NET_LSO_MAX_HDR_SZ: Maximum header size supported for LSO frames + * %NFP_NET_LSO_MAX_SEGS: Maximum number of segments LSO frame can produce */ #define NFP_NET_LSO_MAX_HDR_SZ 255 +#define NFP_NET_LSO_MAX_SEGS 64 /** * Prepend field types diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index f67da6bde9da..619570524d2a 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -265,6 +265,7 @@ const struct net_device_ops nfp_repr_netdev_ops = { .ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk, .ndo_get_vf_config = nfp_app_get_vf_config, .ndo_set_vf_link_state = nfp_app_set_vf_link_state, + .ndo_set_features = nfp_port_set_features, }; static void nfp_repr_clean(struct nfp_repr *repr) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c index 34a6e035fe9a..7bd8be5c833b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c @@ -32,6 +32,7 @@ */ #include <linux/lockdep.h> +#include <linux/netdevice.h> #include <net/switchdev.h> #include "nfpcore/nfp_cpp.h" @@ -100,6 +101,23 @@ int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type, return nfp_app_setup_tc(port->app, netdev, type, type_data); } +int nfp_port_set_features(struct net_device *netdev, netdev_features_t features) +{ + struct nfp_port *port; + + port = nfp_port_from_netdev(netdev); + if (!port) + return 0; + + if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && + port->tc_offload_cnt) { + netdev_err(netdev, "Cannot disable HW TC offload while offloads active\n"); + return -EBUSY; + } + + return 0; +} + struct nfp_port * nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id) { diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h index 21bd4aa32646..fa7e669a969c 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h @@ -72,6 +72,8 @@ enum nfp_port_flags { * @netdev: backpointer to associated netdev * @type: what port type does the entity represent * @flags: port flags + * @tc_offload_cnt: number of active TC offloads, how offloads are counted + * is not defined, use as a boolean * @app: backpointer to the app structure * @dl_port: devlink port structure * @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme @@ -87,6 +89,7 @@ struct nfp_port { enum nfp_port_type type; unsigned long flags; + unsigned long tc_offload_cnt; struct nfp_app *app; @@ -121,6 +124,9 @@ static inline bool nfp_port_is_vnic(const struct nfp_port *port) return port->type == NFP_PORT_PF_PORT || port->type == NFP_PORT_VF_PORT; } +int +nfp_port_set_features(struct net_device *netdev, netdev_features_t features); + struct nfp_port *nfp_port_from_netdev(struct net_device *netdev); struct nfp_port * nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id); diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h index e983c9d7f86c..f23d9e06f097 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h @@ -98,28 +98,29 @@ enum nfp_eth_fec { * @max_index: max of @index fields of all @ports * @ports: table of ports * - * @eth_index: port index according to legacy ethX numbering - * @index: chip-wide first channel index - * @nbi: NBI index - * @base: first channel index (within NBI) - * @lanes: number of channels - * @speed: interface speed (in Mbps) - * @interface: interface (module) plugged in - * @media: media type of the @interface - * @fec: forward error correction mode - * @aneg: auto negotiation mode - * @mac_addr: interface MAC address - * @label_port: port id - * @label_subport: id of interface within port (for split ports) - * @enabled: is enabled? - * @tx_enabled: is TX enabled? - * @rx_enabled: is RX enabled? - * @override_changed: is media reconfig pending? + * @ports.eth_index: port index according to legacy ethX numbering + * @ports.index: chip-wide first channel index + * @ports.nbi: NBI index + * @ports.base: first channel index (within NBI) + * @ports.lanes: number of channels + * @ports.speed: interface speed (in Mbps) + * @ports.interface: interface (module) plugged in + * @ports.media: media type of the @interface + * @ports.fec: forward error correction mode + * @ports.aneg: auto negotiation mode + * @ports.mac_addr: interface MAC address + * @ports.label_port: port id + * @ports.label_subport: id of interface within port (for split ports) + * @ports.enabled: is enabled? + * @ports.tx_enabled: is TX enabled? + * @ports.rx_enabled: is RX enabled? + * @ports.override_changed: is media reconfig pending? * - * @port_type: one of %PORT_* defines for ethtool - * @port_lanes: total number of lanes on the port (sum of lanes of all subports) - * @is_split: is interface part of a split port - * @fec_modes_supported: bitmap of FEC modes supported + * @ports.port_type: one of %PORT_* defines for ethtool + * @ports.port_lanes: total number of lanes on the port (sum of lanes of all + * subports) + * @ports.is_split: is interface part of a split port + * @ports.fec_modes_supported: bitmap of FEC modes supported */ struct nfp_eth_table { unsigned int count; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c index b1dd13ff282b..7e14725055c7 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c @@ -56,16 +56,17 @@ /** * struct nfp_resource_entry - Resource table entry - * @owner: NFP CPP Lock, interface owner - * @key: NFP CPP Lock, posix_crc32(name, 8) - * @region: Memory region descriptor - * @name: ASCII, zero padded name - * @reserved - * @cpp_action: CPP Action - * @cpp_token: CPP Token - * @cpp_target: CPP Target ID - * @page_offset: 256-byte page offset into target's CPP address - * @page_size: size, in 256-byte pages + * @mutex: NFP CPP Lock + * @mutex.owner: NFP CPP Lock, interface owner + * @mutex.key: NFP CPP Lock, posix_crc32(name, 8) + * @region: Memory region descriptor + * @region.name: ASCII, zero padded name + * @region.reserved: padding + * @region.cpp_action: CPP Action + * @region.cpp_token: CPP Token + * @region.cpp_target: CPP Target ID + * @region.page_offset: 256-byte page offset into target's CPP address + * @region.page_size: size, in 256-byte pages */ struct nfp_resource_entry { struct nfp_resource_entry_mutex { |