static int __nfp_abm_reset_root(struct net_device *netdev, struct nfp_abm_link *alink, u32 handle, unsigned int qs, u32 init_val) { struct nfp_port *port = nfp_port_from_netdev(netdev); int ret; ret = nfp_abm_ctrl_set_all_q_lvls(alink, init_val); memset(alink->qdiscs, 0, sizeof(*alink->qdiscs) * alink->num_qdiscs); alink->parent = handle; alink->num_qdiscs = qs; port->tc_offload_cnt = qs; return ret; }
/** * nfp_flower_del_offload() - Removes a flow from hardware. * @app: Pointer to the APP handle * @netdev: netdev structure. * @flow: TC flower classifier offload structure * @egress: Netdev is the egress dev. * * Removes a flow from the repeated hash structure and clears the * action payload. * * Return: negative value on error, 0 if removed successfully. */ static int nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, struct tc_cls_flower_offload *flow, bool egress) { struct nfp_port *port = nfp_port_from_netdev(netdev); struct nfp_fl_payload *nfp_flow; struct net_device *ingr_dev; int err; ingr_dev = egress ? NULL : netdev; nfp_flow = nfp_flower_search_fl_table(app, flow->cookie, ingr_dev, NFP_FL_STATS_CTX_DONT_CARE); if (!nfp_flow) return egress ? 0 : -ENOENT; err = nfp_modify_flow_metadata(app, nfp_flow); if (err) goto err_free_flow; if (nfp_flow->nfp_tun_ipv4_addr) nfp_tunnel_del_ipv4_off(app, nfp_flow->nfp_tun_ipv4_addr); err = nfp_flower_xmit_flow(netdev, nfp_flow, NFP_FLOWER_CMSG_TYPE_FLOW_DEL); if (err) goto err_free_flow; 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); kfree_rcu(nfp_flow, rcu); return err; }
/** * nfp_flower_add_offload() - Adds a new flow to hardware. * @app: Pointer to the APP handle * @netdev: netdev structure. * @flow: TC flower classifier offload structure. * @egress: NFP netdev is the egress. * * Adds a new flow to the repeated hash structure and action payload. * * Return: negative value on error, 0 if configured successfully. */ static int 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; struct net_device *ingr_dev; int err; ingr_dev = egress ? NULL : netdev; flow_pay = nfp_flower_search_fl_table(app, flow->cookie, ingr_dev, NFP_FL_STATS_CTX_DONT_CARE); if (flow_pay) { /* Ignore as duplicate if it has been added by different cb. */ if (flow_pay->ingress_offload && egress) return 0; else return -EOPNOTSUPP; } key_layer = kmalloc(sizeof(*key_layer), GFP_KERNEL); if (!key_layer) return -ENOMEM; err = nfp_flower_calculate_key_layers(app, key_layer, flow, egress, &tun_type); if (err) goto err_free_key_ls; flow_pay = nfp_flower_allocate_new(key_layer, egress); if (!flow_pay) { err = -ENOMEM; goto err_free_key_ls; } flow_pay->ingress_dev = egress ? NULL : netdev; err = nfp_flower_compile_flow_match(flow, key_layer, netdev, flow_pay, tun_type); if (err) goto err_destroy_flow; err = nfp_flower_compile_action(app, flow, netdev, flow_pay); if (err) goto err_destroy_flow; err = nfp_compile_flow_metadata(app, flow, flow_pay, flow_pay->ingress_dev); if (err) goto err_destroy_flow; err = nfp_flower_xmit_flow(netdev, flow_pay, NFP_FLOWER_CMSG_TYPE_FLOW_ADD); if (err) goto err_destroy_flow; 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); return 0; err_destroy_flow: kfree(flow_pay->action_data); kfree(flow_pay->mask_data); kfree(flow_pay->unmasked_data); kfree(flow_pay); err_free_key_ls: kfree(key_layer); return err; }
[NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000, [NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000, [NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000, }; struct nfp_eth_table_port *eth_port; struct nfp_port *port; struct nfp_net *nn; u32 sts, ls; /* Init to unknowns */ ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); cmd->base.port = PORT_OTHER; cmd->base.speed = SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; port = nfp_port_from_netdev(netdev); eth_port = nfp_port_get_eth_port(port); if (eth_port) { cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ? AUTONEG_ENABLE : AUTONEG_DISABLE; nfp_net_set_fec_link_mode(eth_port, cmd); } if (!netif_carrier_ok(netdev)) return 0; /* Use link speed from ETH table if available, otherwise try the BAR */ if (eth_port) { cmd->base.port = eth_port->port_type; cmd->base.speed = eth_port->speed; cmd->base.duplex = DUPLEX_FULL;