From 4b03b27349c03b72a084b2484623a744565bc399 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:04 -0700 Subject: [PATCH 1/6] ionic: get MTU from lif identity Change from using hardcoded MTU limits and instead use the firmware defined limits. The value from the LIF attributes is the frame size, so we take off the header size to convert to MTU size. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_dev.h | 2 -- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 17 ++++++++++++++--- drivers/net/ethernet/pensando/ionic/ionic_lif.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index 525434f10025..d5cba502abca 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -10,8 +10,6 @@ #include "ionic_if.h" #include "ionic_regs.h" -#define IONIC_MIN_MTU ETH_MIN_MTU -#define IONIC_MAX_MTU 9194 #define IONIC_MAX_TX_DESC 8192 #define IONIC_MAX_RX_DESC 16384 #define IONIC_MIN_TXRX_DESC 16 diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index f49486b6d04d..cfcef41b7b23 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -2022,11 +2023,16 @@ reset_out: static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index) { struct device *dev = ionic->dev; + union ionic_lif_identity *lid; struct net_device *netdev; struct ionic_lif *lif; int tbl_sz; int err; + lid = kzalloc(sizeof(*lid), GFP_KERNEL); + if (!lid) + return ERR_PTR(-ENOMEM); + netdev = alloc_etherdev_mqs(sizeof(*lif), ionic->ntxqs_per_lif, ionic->ntxqs_per_lif); if (!netdev) { @@ -2045,8 +2051,12 @@ static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index netdev->watchdog_timeo = 2 * HZ; netif_carrier_off(netdev); - netdev->min_mtu = IONIC_MIN_MTU; - netdev->max_mtu = IONIC_MAX_MTU; + lif->identity = lid; + lif->lif_type = IONIC_LIF_TYPE_CLASSIC; + ionic_lif_identify(ionic, lif->lif_type, lif->identity); + lif->netdev->min_mtu = le32_to_cpu(lif->identity->eth.min_frame_size); + lif->netdev->max_mtu = + le32_to_cpu(lif->identity->eth.max_frame_size) - ETH_HLEN - VLAN_HLEN; lif->neqs = ionic->neqs_per_lif; lif->nxqs = ionic->ntxqs_per_lif; @@ -2113,6 +2123,7 @@ err_out_free_lif_info: err_out_free_netdev: free_netdev(lif->netdev); lif = NULL; + kfree(lid); return ERR_PTR(err); } @@ -2132,7 +2143,6 @@ int ionic_lifs_alloc(struct ionic *ionic) return -ENOMEM; } - lif->lif_type = IONIC_LIF_TYPE_CLASSIC; ionic_lif_queue_identify(lif); return 0; @@ -2243,6 +2253,7 @@ static void ionic_lif_free(struct ionic_lif *lif) ionic_lif_reset(lif); /* free lif info */ + kfree(lif->identity); dma_free_coherent(dev, lif->info_sz, lif->info, lif->info_pa); lif->info = NULL; lif->info_pa = 0; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h index ed126dd74e01..949f96dc9cd8 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h @@ -184,6 +184,7 @@ struct ionic_lif { u16 lif_type; unsigned int nucast; + union ionic_lif_identity *identity; struct ionic_lif_info *info; dma_addr_t info_pa; u32 info_sz; From c8768e7321d2f2c69c3467928a2e63630e682e22 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:05 -0700 Subject: [PATCH 2/6] ionic: set netdev default name If the host system's udev fails to set a new name for the network port, there is no NETDEV_CHANGENAME event to trigger the driver to send the name down to the firmware. It is safe to set the lif name multiple times, so we add a call early on to set the default netdev name to be sure the FW has something to use in its internal debug logging. Then when udev gets around to changing it we can update it to the actual name the system will be using. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index cfcef41b7b23..bbfa25cd3294 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -2631,6 +2631,7 @@ int ionic_lifs_register(struct ionic *ionic) return err; } ionic->master_lif->registered = true; + ionic_lif_set_netdev_info(ionic->master_lif); return 0; } From 4471b1c13ae7e3c8be64a9e015c6bc31468e1b16 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:06 -0700 Subject: [PATCH 3/6] ionic: remove unused ionic_coal_hw_to_usec Clean up some unused code. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_lif.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h index 949f96dc9cd8..f1e7d3ef1c58 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h @@ -236,19 +236,6 @@ static inline u32 ionic_coal_usec_to_hw(struct ionic *ionic, u32 usecs) return (usecs * mult) / div; } -static inline u32 ionic_coal_hw_to_usec(struct ionic *ionic, u32 units) -{ - u32 mult = le32_to_cpu(ionic->ident.dev.intr_coal_mult); - u32 div = le32_to_cpu(ionic->ident.dev.intr_coal_div); - - /* Div-by-zero should never be an issue, but check anyway */ - if (!div || !mult) - return 0; - - /* Convert from device units to usec */ - return (units * div) / mult; -} - typedef void (*ionic_reset_cb)(struct ionic_lif *lif, void *arg); void ionic_link_status_check_request(struct ionic_lif *lif); From 3fbc9bb6ca32d12d4d32a7ae32abef67ac95f889 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:07 -0700 Subject: [PATCH 4/6] ionic: update eid test for overflow Fix up our comparison to better handle a potential (but largely unlikely) wrap around. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index bbfa25cd3294..db60c5405a58 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -719,7 +719,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq, eid = le64_to_cpu(comp->event.eid); /* Have we run out of new completions to process? */ - if (eid <= lif->last_eid) + if ((s64)(eid - lif->last_eid) <= 0) return false; lif->last_eid = eid; From 6a6014e2fb276753d4dc9b803370e7af7f57e30b Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:08 -0700 Subject: [PATCH 5/6] ionic: rearrange reset and bus-master control We can prevent potential incorrect DMA access attempts from the NIC by enabling bus-master after the reset, and by disabling bus-master earlier in cleanup. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c index 2924cde440aa..85c686c16741 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -247,12 +247,11 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_pci_disable_device; } - pci_set_master(pdev); pcie_print_link_status(pdev); err = ionic_map_bars(ionic); if (err) - goto err_out_pci_clear_master; + goto err_out_pci_disable_device; /* Configure the device */ err = ionic_setup(ionic); @@ -260,6 +259,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(dev, "Cannot setup device: %d, aborting\n", err); goto err_out_unmap_bars; } + pci_set_master(pdev); err = ionic_identify(ionic); if (err) { @@ -350,6 +350,7 @@ err_out_reset: ionic_reset(ionic); err_out_teardown: ionic_dev_teardown(ionic); + pci_clear_master(pdev); /* Don't fail the probe for these errors, keep * the hw interface around for inspection */ @@ -358,8 +359,6 @@ err_out_teardown: err_out_unmap_bars: ionic_unmap_bars(ionic); pci_release_regions(pdev); -err_out_pci_clear_master: - pci_clear_master(pdev); err_out_pci_disable_device: pci_disable_device(pdev); err_out_debugfs_del_dev: @@ -389,9 +388,9 @@ static void ionic_remove(struct pci_dev *pdev) ionic_port_reset(ionic); ionic_reset(ionic); ionic_dev_teardown(ionic); + pci_clear_master(pdev); ionic_unmap_bars(ionic); pci_release_regions(pdev); - pci_clear_master(pdev); pci_disable_device(pdev); ionic_debugfs_del_dev(ionic); mutex_destroy(&ionic->dev_cmd_lock); From 1b897e7d8d4496e81c1e896ab516536a6f509a95 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 21 Jul 2020 13:34:09 -0700 Subject: [PATCH 6/6] ionic: interface file updates Add some new interface values and update a few more descriptions. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_if.h | 88 ++++++++++++++----- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h index 7e22ba4ed915..acc94b244cf3 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -59,6 +59,8 @@ enum ionic_cmd_opcode { IONIC_CMD_QOS_CLASS_INIT = 241, IONIC_CMD_QOS_CLASS_RESET = 242, IONIC_CMD_QOS_CLASS_UPDATE = 243, + IONIC_CMD_QOS_CLEAR_STATS = 244, + IONIC_CMD_QOS_RESET = 245, /* Firmware commands */ IONIC_CMD_FW_DOWNLOAD = 254, @@ -90,8 +92,8 @@ enum ionic_status_code { IONIC_RC_DEV_CMD = 18, /* Device cmd attempted on AdminQ */ IONIC_RC_ENOSUPP = 19, /* Operation not supported */ IONIC_RC_ERROR = 29, /* Generic error */ - IONIC_RC_ERDMA = 30, /* Generic RDMA error */ + IONIC_RC_EVFID = 31, /* VF ID does not exist */ }; enum ionic_notifyq_opcode { @@ -103,7 +105,7 @@ enum ionic_notifyq_opcode { }; /** - * struct cmd - General admin command format + * struct ionic_admin_cmd - General admin command format * @opcode: Opcode for the command * @lif_index: LIF index * @cmd_data: Opcode-specific command bytes @@ -167,7 +169,7 @@ struct ionic_dev_init_cmd { }; /** - * struct init_comp - Device init command completion + * struct ionic_dev_init_comp - Device init command completion * @status: Status of the command (enum ionic_status_code) */ struct ionic_dev_init_comp { @@ -185,7 +187,7 @@ struct ionic_dev_reset_cmd { }; /** - * struct reset_comp - Reset command completion + * struct ionic_dev_reset_comp - Reset command completion * @status: Status of the command (enum ionic_status_code) */ struct ionic_dev_reset_comp { @@ -357,12 +359,12 @@ struct ionic_lif_logical_qtype { * enum ionic_lif_state - LIF state * @IONIC_LIF_DISABLE: LIF disabled * @IONIC_LIF_ENABLE: LIF enabled - * @IONIC_LIF_HANG_RESET: LIF hung, being reset + * @IONIC_LIF_QUIESCE: LIF Quiesced */ enum ionic_lif_state { - IONIC_LIF_DISABLE = 0, + IONIC_LIF_QUIESCE = 0, IONIC_LIF_ENABLE = 1, - IONIC_LIF_HANG_RESET = 2, + IONIC_LIF_DISABLE = 2, }; /** @@ -371,6 +373,7 @@ enum ionic_lif_state { * @name: LIF name * @mtu: MTU * @mac: Station MAC address + * @vlan: Default Vlan ID * @features: Features (enum ionic_eth_hw_features) * @queue_count: Queue counts per queue-type */ @@ -381,7 +384,7 @@ union ionic_lif_config { char name[IONIC_IFNAMSIZ]; __le32 mtu; u8 mac[6]; - u8 rsvd2[2]; + __le16 vlan; __le64 features; __le32 queue_count[IONIC_QTYPE_MAX]; } __packed; @@ -489,13 +492,13 @@ struct ionic_lif_init_comp { u8 rsvd2[12]; }; - /** - * struct ionic_q_identify_cmd - queue identify command - * @opcode: opcode - * @lif_type: LIF type (enum ionic_lif_type) - * @type: Logical queue type (enum ionic_logical_qtype) - * @ver: Highest queue type version that the driver supports - */ +/** + * struct ionic_q_identify_cmd - queue identify command + * @opcode: opcode + * @lif_type: LIF type (enum ionic_lif_type) + * @type: Logical queue type (enum ionic_logical_qtype) + * @ver: Highest queue type version that the driver supports + */ struct ionic_q_identify_cmd { u8 opcode; u8 rsvd; @@ -983,6 +986,14 @@ enum ionic_pkt_type { IONIC_PKT_TYPE_IPV6 = 0x008, IONIC_PKT_TYPE_IPV6_TCP = 0x018, IONIC_PKT_TYPE_IPV6_UDP = 0x028, + /* below types are only used if encap offloads are enabled on lif */ + IONIC_PKT_TYPE_ENCAP_NON_IP = 0x40, + IONIC_PKT_TYPE_ENCAP_IPV4 = 0x41, + IONIC_PKT_TYPE_ENCAP_IPV4_TCP = 0x43, + IONIC_PKT_TYPE_ENCAP_IPV4_UDP = 0x45, + IONIC_PKT_TYPE_ENCAP_IPV6 = 0x48, + IONIC_PKT_TYPE_ENCAP_IPV6_TCP = 0x58, + IONIC_PKT_TYPE_ENCAP_IPV6_UDP = 0x68, }; enum ionic_eth_hw_features { @@ -1003,6 +1014,9 @@ enum ionic_eth_hw_features { IONIC_ETH_HW_TSO_IPXIP6 = BIT(14), IONIC_ETH_HW_TSO_UDP = BIT(15), IONIC_ETH_HW_TSO_UDP_CSUM = BIT(16), + IONIC_ETH_HW_RX_CSUM_GENEVE = BIT(17), + IONIC_ETH_HW_TX_CSUM_GENEVE = BIT(18), + IONIC_ETH_HW_TSO_GENEVE = BIT(19) }; /** @@ -1011,7 +1025,7 @@ enum ionic_eth_hw_features { * @type: Queue type * @lif_index: LIF index * @index: Queue index - * @oper: Operation (enum q_control_oper) + * @oper: Operation (enum ionic_q_control_oper) */ struct ionic_q_control_cmd { u8 opcode; @@ -1172,7 +1186,7 @@ enum ionic_port_loopback_mode { * struct ionic_xcvr_status - Transceiver Status information * @state: Transceiver status (enum ionic_xcvr_state) * @phy: Physical connection type (enum ionic_phy_type) - * @pid: Transceiver link mode (enum pid) + * @pid: Transceiver link mode (enum ionic_xcvr_pid) * @sprom: Transceiver sprom contents */ struct ionic_xcvr_status { @@ -1186,7 +1200,7 @@ struct ionic_xcvr_status { * union ionic_port_config - Port configuration * @speed: port speed (in Mbps) * @mtu: mtu - * @state: port admin state (enum port_admin_state) + * @state: port admin state (enum ionic_port_admin_state) * @an_enable: autoneg enable * @fec_type: fec type (enum ionic_port_fec_type) * @pause_type: pause type (enum ionic_port_pause_type) @@ -1874,12 +1888,14 @@ struct ionic_qos_identify_comp { }; #define IONIC_QOS_TC_MAX 8 +#define IONIC_QOS_ALL_TC 0xFF /* Capri max supported, should be renamed. */ #define IONIC_QOS_CLASS_MAX 7 #define IONIC_QOS_PCP_MAX 8 #define IONIC_QOS_CLASS_NAME_SZ 32 #define IONIC_QOS_DSCP_MAX 64 #define IONIC_QOS_ALL_PCP 0xFF +#define IONIC_DSCP_BLOCK_SIZE 8 /** * enum ionic_qos_class @@ -1923,6 +1939,7 @@ enum ionic_qos_sched_type { * IONIC_QOS_CONFIG_F_NO_DROP drop/nodrop * IONIC_QOS_CONFIG_F_RW_DOT1Q_PCP enable dot1q pcp rewrite * IONIC_QOS_CONFIG_F_RW_IP_DSCP enable ip dscp rewrite + * IONIC_QOS_CONFIG_F_NON_DISRUPTIVE Non-disruptive TC update * @sched_type: QoS class scheduling type (enum ionic_qos_sched_type) * @class_type: QoS class type (enum ionic_qos_class_type) * @pause_type: QoS pause type (enum ionic_qos_pause_type) @@ -1944,6 +1961,8 @@ union ionic_qos_config { /* Used to rewrite PCP or DSCP value. */ #define IONIC_QOS_CONFIG_F_RW_DOT1Q_PCP BIT(2) #define IONIC_QOS_CONFIG_F_RW_IP_DSCP BIT(3) +/* Non-disruptive TC update */ +#define IONIC_QOS_CONFIG_F_NON_DISRUPTIVE BIT(4) u8 flags; u8 sched_type; u8 class_type; @@ -2019,6 +2038,16 @@ struct ionic_qos_reset_cmd { u8 rsvd[62]; }; +/** + * struct ionic_qos_clear_port_stats_cmd - Qos config reset command + * @opcode: Opcode + */ +struct ionic_qos_clear_stats_cmd { + u8 opcode; + u8 group_bitmap; + u8 rsvd[62]; +}; + typedef struct ionic_admin_comp ionic_qos_reset_comp; /** @@ -2164,7 +2193,7 @@ struct ionic_notifyq_event { * struct ionic_link_change_event - Link change event notification * @eid: event number * @ecode: event code = IONIC_EVENT_LINK_CHANGE - * @link_status: link up or down, with error bits (enum port_status) + * @link_status: link up/down, with error bits (enum ionic_port_status) * @link_speed: speed of the network link * * Sent when the network link state changes between UP and DOWN @@ -2377,6 +2406,16 @@ enum ionic_pb_buffer_drop_stats { IONIC_BUFFER_DROP_MAX, }; +enum ionic_oflow_drop_stats { + IONIC_OFLOW_OCCUPANCY_DROP, + IONIC_OFLOW_EMERGENCY_STOP_DROP, + IONIC_OFLOW_WRITE_BUFFER_ACK_FILL_UP_DROP, + IONIC_OFLOW_WRITE_BUFFER_ACK_FULL_DROP, + IONIC_OFLOW_WRITE_BUFFER_FULL_DROP, + IONIC_OFLOW_CONTROL_FIFO_FULL_DROP, + IONIC_OFLOW_DROP_MAX, +}; + /** * struct port_pb_stats - packet buffers system stats * uses ionic_pb_buffer_drop_stats for drop_counts[] @@ -2390,12 +2429,20 @@ struct ionic_port_pb_stats { __le64 input_queue_buffer_occupancy[IONIC_QOS_TC_MAX]; __le64 input_queue_port_monitor[IONIC_QOS_TC_MAX]; __le64 output_queue_port_monitor[IONIC_QOS_TC_MAX]; + __le64 oflow_drop_counts[IONIC_OFLOW_DROP_MAX]; + __le64 input_queue_good_pkts_in[IONIC_QOS_TC_MAX]; + __le64 input_queue_good_pkts_out[IONIC_QOS_TC_MAX]; + __le64 input_queue_err_pkts_in[IONIC_QOS_TC_MAX]; + __le64 input_queue_fifo_depth[IONIC_QOS_TC_MAX]; + __le64 input_queue_max_fifo_depth[IONIC_QOS_TC_MAX]; + __le64 input_queue_peak_occupancy[IONIC_QOS_TC_MAX]; + __le64 output_queue_buffer_occupancy[IONIC_QOS_TC_MAX]; }; /** * struct ionic_port_identity - port identity structure * @version: identity structure version - * @type: type of port (enum port_type) + * @type: type of port (enum ionic_port_type) * @num_lanes: number of lanes for the port * @autoneg: autoneg supported * @min_frame_size: minimum frame size supported @@ -2637,6 +2684,7 @@ union ionic_dev_cmd { struct ionic_qos_identify_cmd qos_identify; struct ionic_qos_init_cmd qos_init; struct ionic_qos_reset_cmd qos_reset; + struct ionic_qos_clear_stats_cmd qos_clear_stats; struct ionic_q_identify_cmd q_identify; struct ionic_q_init_cmd q_init;