diff options
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_if.h | 88 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.h | 14 |
5 files changed, 89 insertions, 44 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); 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_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; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index f49486b6d04d..db60c5405a58 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -5,6 +5,7 @@ #include <linux/dynamic_debug.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> +#include <linux/if_vlan.h> #include <linux/rtnetlink.h> #include <linux/interrupt.h> #include <linux/pci.h> @@ -718,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; @@ -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; @@ -2620,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; } diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h index ed126dd74e01..f1e7d3ef1c58 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; @@ -235,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); |