diff options
Diffstat (limited to 'drivers/net/ethernet/pensando')
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_devlink.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_if.h | 45 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.c | 113 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 31 |
7 files changed, 177 insertions, 33 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index 9d0514cfeb5c..626b9113e7c4 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -481,6 +481,20 @@ int ionic_dev_cmd_vf_getattr(struct ionic *ionic, int vf, u8 attr, return err; } +void ionic_vf_start(struct ionic *ionic) +{ + union ionic_dev_cmd cmd = { + .vf_ctrl.opcode = IONIC_CMD_VF_CTRL, + .vf_ctrl.ctrl_opcode = IONIC_VF_CTRL_START_ALL, + }; + + if (!(ionic->ident.dev.capabilities & cpu_to_le64(IONIC_DEV_CAP_VF_CTRL))) + return; + + ionic_dev_cmd_go(&ionic->idev, &cmd); + ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT); +} + /* LIF commands */ void ionic_dev_cmd_queue_identify(struct ionic_dev *idev, u16 lif_type, u8 qtype, u8 qver) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index 563c302eb033..2a1d7b9c07e7 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -124,6 +124,8 @@ static_assert(sizeof(struct ionic_vf_setattr_cmd) == 64); static_assert(sizeof(struct ionic_vf_setattr_comp) == 16); static_assert(sizeof(struct ionic_vf_getattr_cmd) == 64); static_assert(sizeof(struct ionic_vf_getattr_comp) == 16); +static_assert(sizeof(struct ionic_vf_ctrl_cmd) == 64); +static_assert(sizeof(struct ionic_vf_ctrl_comp) == 16); #endif /* __CHECKER__ */ struct ionic_devinfo { @@ -324,6 +326,7 @@ int ionic_dev_cmd_vf_getattr(struct ionic *ionic, int vf, u8 attr, struct ionic_vf_getattr_comp *comp); void ionic_dev_cmd_queue_identify(struct ionic_dev *idev, u16 lif_type, u8 qtype, u8 qver); +void ionic_vf_start(struct ionic *ionic); void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver); void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index, dma_addr_t addr); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c index 4297ed9024c0..567f778433e2 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c @@ -90,7 +90,7 @@ int ionic_devlink_register(struct ionic *ionic) return err; } - devlink_port_type_eth_set(&ionic->dl_port, ionic->lif->netdev); + SET_NETDEV_DEVLINK_PORT(ionic->lif->netdev, &ionic->dl_port); devlink_register(dl); return 0; } diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h index 4a90f611c611..eac09b2375b8 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -8,7 +8,7 @@ #define IONIC_DEV_INFO_VERSION 1 #define IONIC_IFNAMSIZ 16 -/** +/* * enum ionic_cmd_opcode - Device commands */ enum ionic_cmd_opcode { @@ -54,6 +54,7 @@ enum ionic_cmd_opcode { /* SR/IOV commands */ IONIC_CMD_VF_GETATTR = 60, IONIC_CMD_VF_SETATTR = 61, + IONIC_CMD_VF_CTRL = 62, /* QoS commands */ IONIC_CMD_QOS_CLASS_IDENTIFY = 240, @@ -200,6 +201,7 @@ struct ionic_dev_reset_comp { }; #define IONIC_IDENTITY_VERSION_1 1 +#define IONIC_DEV_IDENTITY_VERSION_2 2 /** * struct ionic_dev_identify_cmd - Driver/device identify command @@ -254,6 +256,14 @@ union ionic_drv_identity { }; /** + * enum ionic_dev_capability - Device capabilities + * @IONIC_DEV_CAP_VF_CTRL: Device supports VF ctrl operations + */ +enum ionic_dev_capability { + IONIC_DEV_CAP_VF_CTRL = BIT(0), +}; + +/** * union ionic_dev_identity - device identity information * @version: Version of device identify * @type: Identify type (0 for now) @@ -273,6 +283,7 @@ union ionic_drv_identity { * @hwstamp_mask: Bitmask for subtraction of hardware tick values. * @hwstamp_mult: Hardware tick to nanosecond multiplier. * @hwstamp_shift: Hardware tick to nanosecond divisor (power of two). + * @capabilities: Device capabilities */ union ionic_dev_identity { struct { @@ -290,6 +301,7 @@ union ionic_dev_identity { __le64 hwstamp_mask; __le32 hwstamp_mult; __le32 hwstamp_shift; + __le64 capabilities; }; __le32 words[478]; }; @@ -2044,6 +2056,35 @@ struct ionic_vf_getattr_comp { u8 color; }; +enum ionic_vf_ctrl_opcode { + IONIC_VF_CTRL_START_ALL = 0, + IONIC_VF_CTRL_START = 1, +}; + +/** + * struct ionic_vf_ctrl_cmd - VF control command + * @opcode: Opcode for the command + * @vf_index: VF Index. It is unused if op START_ALL is used. + * @ctrl_opcode: VF control operation type + */ +struct ionic_vf_ctrl_cmd { + u8 opcode; + u8 ctrl_opcode; + __le16 vf_index; + /* private: */ + u8 rsvd1[60]; +}; + +/** + * struct ionic_vf_ctrl_comp - VF_CTRL command completion. + * @status: Status of the command (enum ionic_status_code) + */ +struct ionic_vf_ctrl_comp { + u8 status; + /* private: */ + u8 rsvd[15]; +}; + /** * struct ionic_qos_identify_cmd - QoS identify command * @opcode: opcode @@ -2865,6 +2906,7 @@ union ionic_dev_cmd { struct ionic_vf_setattr_cmd vf_setattr; struct ionic_vf_getattr_cmd vf_getattr; + struct ionic_vf_ctrl_cmd vf_ctrl; struct ionic_lif_identify_cmd lif_identify; struct ionic_lif_init_cmd lif_init; @@ -2903,6 +2945,7 @@ union ionic_dev_cmd_comp { struct ionic_vf_setattr_comp vf_setattr; struct ionic_vf_getattr_comp vf_getattr; + struct ionic_vf_ctrl_comp vf_ctrl; struct ionic_lif_identify_comp lif_identify; struct ionic_lif_init_comp lif_init; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 19d4848df17d..4dd16c487f2b 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -1491,7 +1491,13 @@ static int ionic_init_nic_features(struct ionic_lif *lif) NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_TSO_ECN; + NETIF_F_TSO_ECN | + NETIF_F_GSO_GRE | + NETIF_F_GSO_GRE_CSUM | + NETIF_F_GSO_IPXIP4 | + NETIF_F_GSO_IPXIP6 | + NETIF_F_GSO_UDP_TUNNEL | + NETIF_F_GSO_UDP_TUNNEL_CSUM; if (lif->nxqs > 1) features |= NETIF_F_RXHASH; @@ -2220,7 +2226,7 @@ static int ionic_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd } } -static int ionic_update_cached_vf_config(struct ionic *ionic, int vf) +static int ionic_get_fw_vf_config(struct ionic *ionic, int vf, struct ionic_vf *vfdata) { struct ionic_vf_getattr_comp comp = { 0 }; int err; @@ -2231,14 +2237,14 @@ static int ionic_update_cached_vf_config(struct ionic *ionic, int vf) if (err && comp.status != IONIC_RC_ENOSUPP) goto err_out; if (!err) - ionic->vfs[vf].vlanid = comp.vlanid; + vfdata->vlanid = comp.vlanid; attr = IONIC_VF_ATTR_SPOOFCHK; err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp); if (err && comp.status != IONIC_RC_ENOSUPP) goto err_out; if (!err) - ionic->vfs[vf].spoofchk = comp.spoofchk; + vfdata->spoofchk = comp.spoofchk; attr = IONIC_VF_ATTR_LINKSTATE; err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp); @@ -2247,13 +2253,13 @@ static int ionic_update_cached_vf_config(struct ionic *ionic, int vf) if (!err) { switch (comp.linkstate) { case IONIC_VF_LINK_STATUS_UP: - ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_ENABLE; + vfdata->linkstate = IFLA_VF_LINK_STATE_ENABLE; break; case IONIC_VF_LINK_STATUS_DOWN: - ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_DISABLE; + vfdata->linkstate = IFLA_VF_LINK_STATE_DISABLE; break; case IONIC_VF_LINK_STATUS_AUTO: - ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_AUTO; + vfdata->linkstate = IFLA_VF_LINK_STATE_AUTO; break; default: dev_warn(ionic->dev, "Unexpected link state %u\n", comp.linkstate); @@ -2266,21 +2272,21 @@ static int ionic_update_cached_vf_config(struct ionic *ionic, int vf) if (err && comp.status != IONIC_RC_ENOSUPP) goto err_out; if (!err) - ionic->vfs[vf].maxrate = comp.maxrate; + vfdata->maxrate = comp.maxrate; attr = IONIC_VF_ATTR_TRUST; err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp); if (err && comp.status != IONIC_RC_ENOSUPP) goto err_out; if (!err) - ionic->vfs[vf].trusted = comp.trust; + vfdata->trusted = comp.trust; attr = IONIC_VF_ATTR_MAC; err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp); if (err && comp.status != IONIC_RC_ENOSUPP) goto err_out; if (!err) - ether_addr_copy(ionic->vfs[vf].macaddr, comp.macaddr); + ether_addr_copy(vfdata->macaddr, comp.macaddr); err_out: if (err) @@ -2295,6 +2301,7 @@ static int ionic_get_vf_config(struct net_device *netdev, { struct ionic_lif *lif = netdev_priv(netdev); struct ionic *ionic = lif->ionic; + struct ionic_vf vfdata = { 0 }; int ret = 0; if (!netif_device_present(netdev)) @@ -2308,14 +2315,14 @@ static int ionic_get_vf_config(struct net_device *netdev, ivf->vf = vf; ivf->qos = 0; - ret = ionic_update_cached_vf_config(ionic, vf); + ret = ionic_get_fw_vf_config(ionic, vf, &vfdata); if (!ret) { - ivf->vlan = le16_to_cpu(ionic->vfs[vf].vlanid); - ivf->spoofchk = ionic->vfs[vf].spoofchk; - ivf->linkstate = ionic->vfs[vf].linkstate; - ivf->max_tx_rate = le32_to_cpu(ionic->vfs[vf].maxrate); - ivf->trusted = ionic->vfs[vf].trusted; - ether_addr_copy(ivf->mac, ionic->vfs[vf].macaddr); + ivf->vlan = le16_to_cpu(vfdata.vlanid); + ivf->spoofchk = vfdata.spoofchk; + ivf->linkstate = vfdata.linkstate; + ivf->max_tx_rate = le32_to_cpu(vfdata.maxrate); + ivf->trusted = vfdata.trusted; + ether_addr_copy(ivf->mac, vfdata.macaddr); } } @@ -2562,6 +2569,76 @@ static int ionic_set_vf_link_state(struct net_device *netdev, int vf, int set) return ret; } +static void ionic_vf_attr_replay(struct ionic_lif *lif) +{ + struct ionic_vf_setattr_cmd vfc = { }; + struct ionic *ionic = lif->ionic; + struct ionic_vf *v; + int i; + + if (!ionic->vfs) + return; + + down_read(&ionic->vf_op_lock); + + for (i = 0; i < ionic->num_vfs; i++) { + v = &ionic->vfs[i]; + + if (v->stats_pa) { + vfc.attr = IONIC_VF_ATTR_STATSADDR; + vfc.stats_pa = cpu_to_le64(v->stats_pa); + ionic_set_vf_config(ionic, i, &vfc); + vfc.stats_pa = 0; + } + + if (!is_zero_ether_addr(v->macaddr)) { + vfc.attr = IONIC_VF_ATTR_MAC; + ether_addr_copy(vfc.macaddr, v->macaddr); + ionic_set_vf_config(ionic, i, &vfc); + eth_zero_addr(vfc.macaddr); + } + + if (v->vlanid) { + vfc.attr = IONIC_VF_ATTR_VLAN; + vfc.vlanid = v->vlanid; + ionic_set_vf_config(ionic, i, &vfc); + vfc.vlanid = 0; + } + + if (v->maxrate) { + vfc.attr = IONIC_VF_ATTR_RATE; + vfc.maxrate = v->maxrate; + ionic_set_vf_config(ionic, i, &vfc); + vfc.maxrate = 0; + } + + if (v->spoofchk) { + vfc.attr = IONIC_VF_ATTR_SPOOFCHK; + vfc.spoofchk = v->spoofchk; + ionic_set_vf_config(ionic, i, &vfc); + vfc.spoofchk = 0; + } + + if (v->trusted) { + vfc.attr = IONIC_VF_ATTR_TRUST; + vfc.trust = v->trusted; + ionic_set_vf_config(ionic, i, &vfc); + vfc.trust = 0; + } + + if (v->linkstate) { + vfc.attr = IONIC_VF_ATTR_LINKSTATE; + vfc.linkstate = v->linkstate; + ionic_set_vf_config(ionic, i, &vfc); + vfc.linkstate = 0; + } + } + + up_read(&ionic->vf_op_lock); + + ionic_vf_start(ionic); +} + static const struct net_device_ops ionic_netdev_ops = { .ndo_open = ionic_open, .ndo_stop = ionic_stop, @@ -3042,6 +3119,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) if (err) goto err_qcqs_free; + ionic_vf_attr_replay(lif); + if (lif->registered) ionic_lif_set_netdev_info(lif); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 5456c2b15d9b..a13530ec4dd8 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -533,7 +533,7 @@ int ionic_identify(struct ionic *ionic) sz = min(sizeof(ident->drv), sizeof(idev->dev_cmd_regs->data)); memcpy_toio(&idev->dev_cmd_regs->data, &ident->drv, sz); - ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1); + ionic_dev_cmd_identify(idev, IONIC_DEV_IDENTITY_VERSION_2); err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT); if (!err) { sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data)); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index c03986bf2628..0c3977416cd1 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -348,16 +348,25 @@ void ionic_rx_fill(struct ionic_queue *q) struct ionic_rxq_sg_desc *sg_desc; struct ionic_rxq_sg_elem *sg_elem; struct ionic_buf_info *buf_info; + unsigned int fill_threshold; struct ionic_rxq_desc *desc; unsigned int remain_len; unsigned int frag_len; unsigned int nfrags; + unsigned int n_fill; unsigned int i, j; unsigned int len; + n_fill = ionic_q_space_avail(q); + + fill_threshold = min_t(unsigned int, IONIC_RX_FILL_THRESHOLD, + q->num_descs / IONIC_RX_FILL_DIV); + if (n_fill < fill_threshold) + return; + len = netdev->mtu + ETH_HLEN + VLAN_HLEN; - for (i = ionic_q_space_avail(q); i; i--) { + for (i = n_fill; i; i--) { nfrags = 0; remain_len = len; desc_info = &q->info[q->head_idx]; @@ -511,7 +520,6 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) struct ionic_cq *cq = napi_to_cq(napi); struct ionic_dev *idev; struct ionic_lif *lif; - u16 rx_fill_threshold; u32 work_done = 0; u32 flags = 0; @@ -521,10 +529,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) work_done = ionic_cq_service(cq, budget, ionic_rx_service, NULL, NULL); - rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD, - cq->num_descs / IONIC_RX_FILL_DIV); - if (work_done && ionic_q_space_avail(cq->bound_q) >= rx_fill_threshold) - ionic_rx_fill(cq->bound_q); + ionic_rx_fill(cq->bound_q); if (work_done < budget && napi_complete_done(napi, work_done)) { ionic_dim_update(qcq, IONIC_LIF_F_RX_DIM_INTR); @@ -550,7 +555,6 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) struct ionic_dev *idev; struct ionic_lif *lif; struct ionic_cq *txcq; - u16 rx_fill_threshold; u32 rx_work_done = 0; u32 tx_work_done = 0; u32 flags = 0; @@ -565,10 +569,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) rx_work_done = ionic_cq_service(rxcq, budget, ionic_rx_service, NULL, NULL); - rx_fill_threshold = min_t(u16, IONIC_RX_FILL_THRESHOLD, - rxcq->num_descs / IONIC_RX_FILL_DIV); - if (rx_work_done && ionic_q_space_avail(rxcq->bound_q) >= rx_fill_threshold) - ionic_rx_fill(rxcq->bound_q); + ionic_rx_fill(rxcq->bound_q); if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) { ionic_dim_update(qcq, 0); @@ -925,8 +926,12 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb) len = skb->len; mss = skb_shinfo(skb)->gso_size; - outer_csum = (skb_shinfo(skb)->gso_type & SKB_GSO_GRE_CSUM) || - (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM); + outer_csum = (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE | + SKB_GSO_GRE_CSUM | + SKB_GSO_IPXIP4 | + SKB_GSO_IPXIP6 | + SKB_GSO_UDP_TUNNEL | + SKB_GSO_UDP_TUNNEL_CSUM)); has_vlan = !!skb_vlan_tag_present(skb); vlan_tci = skb_vlan_tag_get(skb); encap = skb->encapsulation; |