diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qede')
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_filter.c | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_fp.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_main.c | 33 |
5 files changed, 63 insertions, 31 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index a3a70ad..9935978c 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -40,6 +40,7 @@ #include <linux/kernel.h> #include <linux/mutex.h> #include <linux/bpf.h> +#include <net/xdp.h> #include <linux/qed/qede_rdma.h> #include <linux/io.h> #ifdef CONFIG_RFS_ACCEL @@ -52,9 +53,9 @@ #include <linux/qed/qed_eth_if.h> #define QEDE_MAJOR_VERSION 8 -#define QEDE_MINOR_VERSION 10 -#define QEDE_REVISION_VERSION 10 -#define QEDE_ENGINEERING_VERSION 21 +#define QEDE_MINOR_VERSION 33 +#define QEDE_REVISION_VERSION 0 +#define QEDE_ENGINEERING_VERSION 20 #define DRV_MODULE_VERSION __stringify(QEDE_MAJOR_VERSION) "." \ __stringify(QEDE_MINOR_VERSION) "." \ __stringify(QEDE_REVISION_VERSION) "." \ @@ -345,6 +346,7 @@ struct qede_rx_queue { u64 xdp_no_pass; void *handle; + struct xdp_rxq_info xdp_rxq; }; union db_prod { @@ -494,6 +496,8 @@ int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid); void qede_vlan_mark_nonconfigured(struct qede_dev *edev); int qede_configure_vlan_filters(struct qede_dev *edev); +netdev_features_t qede_fix_features(struct net_device *dev, + netdev_features_t features); int qede_set_features(struct net_device *dev, netdev_features_t features); void qede_set_rx_mode(struct net_device *ndev); void qede_config_rx_mode(struct net_device *ndev); diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c index dae7412..4ca3847 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c @@ -940,6 +940,9 @@ int qede_change_mtu(struct net_device *ndev, int new_mtu) DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), "Configuring MTU size of %d\n", new_mtu); + if (new_mtu > PAGE_SIZE) + ndev->features &= ~NETIF_F_GRO_HW; + /* Set the mtu field and re-start the interface if needed */ args.u.mtu = new_mtu; args.func = &qede_update_mtu; diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index c1a0708..6687e04 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -98,10 +98,18 @@ static void qede_configure_arfs_fltr(struct qede_dev *edev, u16 rxq_id, bool add_fltr) { const struct qed_eth_ops *op = edev->ops; + struct qed_ntuple_filter_params params; if (n->used) return; + memset(¶ms, 0, sizeof(params)); + + params.addr = n->mapping; + params.length = n->buf_len; + params.qid = rxq_id; + params.b_is_add = add_fltr; + DP_VERBOSE(edev, NETIF_MSG_RX_STATUS, "%s arfs filter flow_id=%d, sw_id=%d, src_port=%d, dst_port=%d, rxq=%d\n", add_fltr ? "Adding" : "Deleting", @@ -110,8 +118,7 @@ static void qede_configure_arfs_fltr(struct qede_dev *edev, n->used = true; n->filter_op = add_fltr; - op->ntuple_filter_config(edev->cdev, n, n->mapping, n->buf_len, 0, - rxq_id, add_fltr); + op->ntuple_filter_config(edev->cdev, n, ¶ms); } static void @@ -141,7 +148,10 @@ qede_enqueue_fltr_and_config_searcher(struct qede_dev *edev, edev->arfs->filter_count++; if (edev->arfs->filter_count == 1 && !edev->arfs->enable) { - edev->ops->configure_arfs_searcher(edev->cdev, true); + enum qed_filter_config_mode mode; + + mode = QED_FILTER_CONFIG_MODE_5_TUPLE; + edev->ops->configure_arfs_searcher(edev->cdev, mode); edev->arfs->enable = true; } @@ -160,8 +170,11 @@ qede_dequeue_fltr_and_config_searcher(struct qede_dev *edev, edev->arfs->filter_count--; if (!edev->arfs->filter_count && edev->arfs->enable) { + enum qed_filter_config_mode mode; + + mode = QED_FILTER_CONFIG_MODE_DISABLE; edev->arfs->enable = false; - edev->ops->configure_arfs_searcher(edev->cdev, false); + edev->ops->configure_arfs_searcher(edev->cdev, mode); } } @@ -255,8 +268,11 @@ void qede_process_arfs_filters(struct qede_dev *edev, bool free_fltr) if (!edev->arfs->filter_count) { if (edev->arfs->enable) { + enum qed_filter_config_mode mode; + + mode = QED_FILTER_CONFIG_MODE_DISABLE; edev->arfs->enable = false; - edev->ops->configure_arfs_searcher(edev->cdev, false); + edev->ops->configure_arfs_searcher(edev->cdev, mode); } #ifdef CONFIG_RFS_ACCEL } else { @@ -895,19 +911,26 @@ static void qede_set_features_reload(struct qede_dev *edev, edev->ndev->features = args->u.features; } +netdev_features_t qede_fix_features(struct net_device *dev, + netdev_features_t features) +{ + struct qede_dev *edev = netdev_priv(dev); + + if (edev->xdp_prog || edev->ndev->mtu > PAGE_SIZE || + !(features & NETIF_F_GRO)) + features &= ~NETIF_F_GRO_HW; + + return features; +} + int qede_set_features(struct net_device *dev, netdev_features_t features) { struct qede_dev *edev = netdev_priv(dev); netdev_features_t changes = features ^ dev->features; bool need_reload = false; - /* No action needed if hardware GRO is disabled during driver load */ - if (changes & NETIF_F_GRO) { - if (dev->features & NETIF_F_GRO) - need_reload = !edev->gro_disable; - else - need_reload = edev->gro_disable; - } + if (changes & NETIF_F_GRO_HW) + need_reload = true; if (need_reload) { struct qede_reload_args args; diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c index 48ec4c5..dafc079 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -1006,6 +1006,7 @@ static bool qede_rx_xdp(struct qede_dev *edev, xdp.data = xdp.data_hard_start + *data_offset; xdp_set_data_meta_invalid(&xdp); xdp.data_end = xdp.data + *len; + xdp.rxq = &rxq->xdp_rxq; /* Queues always have a full reset currently, so for the time * being until there's atomic program replace just mark read diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 8f9b3eb..2db70ea 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -545,6 +545,7 @@ static const struct net_device_ops qede_netdev_ops = { #endif .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, #ifdef CONFIG_QED_SRIOV @@ -572,6 +573,7 @@ static const struct net_device_ops qede_netdev_vf_ops = { .ndo_change_mtu = qede_change_mtu, .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, .ndo_udp_tunnel_add = qede_udp_tunnel_add, @@ -589,6 +591,7 @@ static const struct net_device_ops qede_netdev_vf_xdp_ops = { .ndo_change_mtu = qede_change_mtu, .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid, + .ndo_fix_features = qede_fix_features, .ndo_set_features = qede_set_features, .ndo_get_stats64 = qede_get_stats64, .ndo_udp_tunnel_add = qede_udp_tunnel_add, @@ -676,7 +679,7 @@ static void qede_init_ndev(struct qede_dev *edev) ndev->priv_flags |= IFF_UNICAST_FLT; /* user-changeble features */ - hw_features = NETIF_F_GRO | NETIF_F_SG | + hw_features = NETIF_F_GRO | NETIF_F_GRO_HW | NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; @@ -762,6 +765,12 @@ static void qede_free_fp_array(struct qede_dev *edev) fp = &edev->fp_array[i]; kfree(fp->sb_info); + /* Handle mem alloc failure case where qede_init_fp + * didn't register xdp_rxq_info yet. + * Implicit only (fp->type & QEDE_FASTPATH_RX) + */ + if (fp->rxq && xdp_rxq_info_is_reg(&fp->rxq->xdp_rxq)) + xdp_rxq_info_unreg(&fp->rxq->xdp_rxq); kfree(fp->rxq); kfree(fp->xdp_tx); kfree(fp->txq); @@ -1068,10 +1077,6 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) pci_set_drvdata(pdev, NULL); - /* Release edev's reference to XDP's bpf if such exist */ - if (edev->xdp_prog) - bpf_prog_put(edev->xdp_prog); - /* Use global ops since we've freed edev */ qed_ops->common->slowpath_stop(cdev); if (system_state == SYSTEM_POWER_OFF) @@ -1148,7 +1153,7 @@ static void qede_free_mem_sb(struct qede_dev *edev, struct qed_sb_info *sb_info, static int qede_alloc_mem_sb(struct qede_dev *edev, struct qed_sb_info *sb_info, u16 sb_id) { - struct status_block *sb_virt; + struct status_block_e4 *sb_virt; dma_addr_t sb_phys; int rc; @@ -1232,18 +1237,9 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq) dma_addr_t mapping; int i; - /* Don't perform FW aggregations in case of XDP */ - if (edev->xdp_prog) - edev->gro_disable = 1; - if (edev->gro_disable) return 0; - if (edev->ndev->mtu > PAGE_SIZE) { - edev->gro_disable = 1; - return 0; - } - for (i = 0; i < ETH_TPA_MAX_AGGS_NUM; i++) { struct qede_agg_info *tpa_info = &rxq->tpa_info[i]; struct sw_rx_data *replace_buf = &tpa_info->buffer; @@ -1273,6 +1269,7 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq) err: qede_free_sge_mem(edev, rxq); edev->gro_disable = 1; + edev->ndev->features &= ~NETIF_F_GRO_HW; return -ENOMEM; } @@ -1502,6 +1499,10 @@ static void qede_init_fp(struct qede_dev *edev) else fp->rxq->data_direction = DMA_FROM_DEVICE; fp->rxq->dev = &edev->pdev->dev; + + /* Driver have no error path from here */ + WARN_ON(xdp_rxq_info_reg(&fp->rxq->xdp_rxq, edev->ndev, + fp->rxq->rxq_id) < 0); } if (fp->type & QEDE_FASTPATH_TX) { @@ -1515,7 +1516,7 @@ static void qede_init_fp(struct qede_dev *edev) edev->ndev->name, queue_id); } - edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO); + edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW); } static int qede_set_real_num_queues(struct qede_dev *edev) |