@@ -347,6 +347,19 @@ int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data)
}
/* LIF commands */
+void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
+ u16 lif_type, u8 qtype, u8 qver)
+{
+ union ionic_dev_cmd cmd = {
+ .q_identify.opcode = IONIC_CMD_Q_IDENTIFY,
+ .q_identify.lif_type = lif_type,
+ .q_identify.type = qtype,
+ .q_identify.ver = qver,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
+
void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver)
{
union ionic_dev_cmd cmd = {
@@ -669,6 +682,7 @@ void ionic_eqs_deinit(struct ionic *ionic)
static int ionic_eq_init(struct ionic_eq *eq)
{
struct ionic *ionic = eq->ionic;
+ union ionic_q_identity *q_ident;
union ionic_dev_cmd cmd = {
.q_init = {
.opcode = IONIC_CMD_Q_INIT,
@@ -684,6 +698,26 @@ static int ionic_eq_init(struct ionic_eq *eq)
};
int err;
+ q_ident = (union ionic_q_identity *)&ionic->idev.dev_cmd_regs->data;
+
+ mutex_lock(&ionic->dev_cmd_lock);
+ ionic_dev_cmd_queue_identify(&ionic->idev, IONIC_LIF_TYPE_CLASSIC,
+ IONIC_QTYPE_EQ, 0);
+ err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
+ cmd.q_init.ver = q_ident->version;
+ mutex_unlock(&ionic->dev_cmd_lock);
+
+ if (err == -EINVAL) {
+ dev_err(ionic->dev, "eq init failed, not supported\n");
+ return err;
+ } else if (err == -EIO) {
+ dev_err(ionic->dev, "q_ident eq failed, not supported on older FW\n");
+ return err;
+ } else if (err) {
+ dev_warn(ionic->dev, "eq version type request failed %d, defaulting to %d\n",
+ err, cmd.q_init.ver);
+ }
+
ionic_intr_mask(ionic->idev.intr_ctrl, eq->intr.index,
IONIC_INTR_MASK_SET);
ionic_intr_clean(ionic->idev.intr_ctrl, eq->intr.index);
@@ -304,6 +304,8 @@ void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type);
void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type);
int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data);
+void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
+ u16 lif_type, u8 qtype, u8 qver);
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);
@@ -42,6 +42,7 @@ enum ionic_cmd_opcode {
IONIC_CMD_RX_FILTER_DEL = 32,
/* Queue commands */
+ IONIC_CMD_Q_IDENTIFY = 39,
IONIC_CMD_Q_INIT = 40,
IONIC_CMD_Q_CONTROL = 41,
@@ -461,6 +462,65 @@ struct ionic_lif_init_cmd {
u8 rsvd2[48];
};
+/**
+ * struct ionic_q_identify_cmd - queue identify command
+ * @opcode: opcode
+ * @lif_type: lif type (enum lif_type)
+ * @type: logical queue type (enum logical_qtype)
+ * @ver: highest queue type version that the driver supports
+ */
+struct ionic_q_identify_cmd {
+ u8 opcode;
+ u8 rsvd;
+ __le16 lif_type;
+ u8 type;
+ u8 ver;
+ u8 rsvd2[58];
+};
+
+/**
+ * struct ionic_q_identify_comp - queue identify command completion
+ * @status: status of the command (enum status_code)
+ * @ver: queue type version that can be used with FW
+ */
+struct ionic_q_identify_comp {
+ u8 status;
+ u8 rsvd;
+ __le16 comp_index;
+ u8 ver;
+ u8 rsvd2[11];
+};
+
+/**
+ * union ionic_q_identity - queue identity information
+ * @version: queue type version that can be used with FW
+ * @supported: bitfield of queue versions, first bit = ver 0
+ * @features: queue features
+ * @desc_sz: descriptor size
+ * @comp_sz: completion descriptor size
+ * @sg_desc_sz: sg descriptor size
+ * @max_sg_elems: maximum number of sg elements
+ * @sg_desc_stride: number of sg elements per descriptor
+ */
+union ionic_q_identity {
+ struct {
+ u8 version;
+ u8 supported;
+ u8 rsvd[6];
+#define IONIC_QIDENT_F_CQ 0x01 /* queue has completion ring */
+#define IONIC_QIDENT_F_SG 0x02 /* queue has scatter/gather ring */
+#define IONIC_QIDENT_F_EQ 0x04 /* queue can use event queue */
+#define IONIC_QIDENT_F_CMB 0x08 /* queue is in cmb bar */
+ __le64 features;
+ __le16 desc_sz;
+ __le16 comp_sz;
+ __le16 sg_desc_sz;
+ __le16 max_sg_elems;
+ __le16 sg_desc_stride;
+ };
+ __le32 words[478];
+};
+
/**
* struct ionic_lif_init_comp - LIF init command completion
* @status: The status of the command (enum status_code)
@@ -2392,6 +2452,7 @@ union ionic_dev_cmd {
struct ionic_qos_init_cmd qos_init;
struct ionic_qos_reset_cmd qos_reset;
+ struct ionic_q_identify_cmd q_identify;
struct ionic_q_init_cmd q_init;
struct ionic_q_control_cmd q_control;
};
@@ -2425,6 +2486,7 @@ union ionic_dev_cmd_comp {
ionic_qos_init_comp qos_init;
ionic_qos_reset_comp qos_reset;
+ struct ionic_q_identify_comp q_identify;
struct ionic_q_init_comp q_init;
};
Add the queue identity query and use it to verify that EventQueues are supported in the FW. Signed-off-by: Shannon Nelson <snelson@pensando.io> --- .../net/ethernet/pensando/ionic/ionic_dev.c | 34 ++++++++++ .../net/ethernet/pensando/ionic/ionic_dev.h | 2 + .../net/ethernet/pensando/ionic/ionic_if.h | 62 +++++++++++++++++++ 3 files changed, 98 insertions(+)