Commit 8f5ee3c4 authored by Jacob Keller's avatar Jacob Keller Committed by Tony Nguyen
Browse files

ice: add support for sideband messages



In order to support certain device features, including enabling the PTP
hardware clock, the ice driver needs to control some registers on the
device PHY.

These registers are accessed by sending sideband messages. For some
hardware, these messages must be sent over the device admin queue, while
other hardware has a dedicated control queue for the sideband messages.

Add the neighbor device message structure for sending a message to the
neighboring device. Where supported, initialize the sideband control
queue and handle cleanup.

Add a wrapper function for sending sideband control queue messages that
read or write a neighboring device register.

Because some devices send sideband messages over the AdminQ, also
increase the length of the admin queue to allow more messages to be
queued up. This is important because the sideband messages add
additional pressure on the AQ usage.

This support will be used in following patches to enable support for
CONFIG_1588_PTP_CLOCK.

Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Tested-by: default avatarTony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 76cf404c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -74,8 +74,9 @@

#define ICE_DFLT_TRAFFIC_CLASS	BIT(0)
#define ICE_INT_NAME_STR_LEN	(IFNAMSIZ + 16)
#define ICE_AQ_LEN		64
#define ICE_AQ_LEN		192
#define ICE_MBXSQ_LEN		64
#define ICE_SBQ_LEN		64
#define ICE_MIN_LAN_TXRX_MSIX	1
#define ICE_MIN_LAN_OICR_MSIX	1
#define ICE_MIN_MSIX		(ICE_MIN_LAN_TXRX_MSIX + ICE_MIN_LAN_OICR_MSIX)
@@ -227,6 +228,7 @@ enum ice_pf_state {
	ICE_STATE_NOMINAL_CHECK_BITS,
	ICE_ADMINQ_EVENT_PENDING,
	ICE_MAILBOXQ_EVENT_PENDING,
	ICE_SIDEBANDQ_EVENT_PENDING,
	ICE_MDD_EVENT_PENDING,
	ICE_VFLR_EVENT_PENDING,
	ICE_FLTR_OVERFLOW_PROMISC,
+13 −0
Original line number Diff line number Diff line
@@ -1611,6 +1611,15 @@ struct ice_aqc_get_set_rss_lut {
	__le32 addr_low;
};

/* Sideband Control Interface Commands */
/* Neighbor Device Request (indirect 0x0C00); also used for the response. */
struct ice_aqc_neigh_dev_req {
	__le16 sb_data_len;
	u8 reserved[6];
	__le32 addr_high;
	__le32 addr_low;
};

/* Add Tx LAN Queues (indirect 0x0C30) */
struct ice_aqc_add_txqs {
	u8 num_qgrps;
@@ -1911,6 +1920,7 @@ struct ice_aq_desc {
		struct ice_aqc_lldp_filter_ctrl lldp_filter_ctrl;
		struct ice_aqc_get_set_rss_lut get_set_rss_lut;
		struct ice_aqc_get_set_rss_key get_set_rss_key;
		struct ice_aqc_neigh_dev_req neigh_dev;
		struct ice_aqc_add_txqs add_txqs;
		struct ice_aqc_dis_txqs dis_txqs;
		struct ice_aqc_add_rdma_qset add_rdma_qset;
@@ -2059,6 +2069,9 @@ enum ice_adminq_opc {
	ice_aqc_opc_get_rss_key				= 0x0B04,
	ice_aqc_opc_get_rss_lut				= 0x0B05,

	/* Sideband Control Interface commands */
	ice_aqc_opc_neighbour_device_request		= 0x0C00,

	/* Tx queue handling commands/events */
	ice_aqc_opc_add_txqs				= 0x0C30,
	ice_aqc_opc_dis_txqs				= 0x0C31,
+58 −0
Original line number Diff line number Diff line
@@ -1293,6 +1293,64 @@ const struct ice_ctx_ele ice_tlan_ctx_info[] = {
	{ 0 }
};

/* Sideband Queue command wrappers */

/**
 * ice_sbq_send_cmd - send Sideband Queue command to Sideband Queue
 * @hw: pointer to the HW struct
 * @desc: descriptor describing the command
 * @buf: buffer to use for indirect commands (NULL for direct commands)
 * @buf_size: size of buffer for indirect commands (0 for direct commands)
 * @cd: pointer to command details structure
 */
static int
ice_sbq_send_cmd(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
		 void *buf, u16 buf_size, struct ice_sq_cd *cd)
{
	return ice_status_to_errno(ice_sq_send_cmd(hw, ice_get_sbq(hw),
						   (struct ice_aq_desc *)desc,
						   buf, buf_size, cd));
}

/**
 * ice_sbq_rw_reg - Fill Sideband Queue command
 * @hw: pointer to the HW struct
 * @in: message info to be filled in descriptor
 */
int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in)
{
	struct ice_sbq_cmd_desc desc = {0};
	struct ice_sbq_msg_req msg = {0};
	u16 msg_len;
	int status;

	msg_len = sizeof(msg);

	msg.dest_dev = in->dest_dev;
	msg.opcode = in->opcode;
	msg.flags = ICE_SBQ_MSG_FLAGS;
	msg.sbe_fbe = ICE_SBQ_MSG_SBE_FBE;
	msg.msg_addr_low = cpu_to_le16(in->msg_addr_low);
	msg.msg_addr_high = cpu_to_le32(in->msg_addr_high);

	if (in->opcode)
		msg.data = cpu_to_le32(in->data);
	else
		/* data read comes back in completion, so shorten the struct by
		 * sizeof(msg.data)
		 */
		msg_len -= sizeof(msg.data);

	desc.flags = cpu_to_le16(ICE_AQ_FLAG_RD);
	desc.opcode = cpu_to_le16(ice_sbq_opc_neigh_dev_req);
	desc.param0.cmd_len = cpu_to_le16(msg_len);
	status = ice_sbq_send_cmd(hw, &desc, &msg, msg_len, NULL);
	if (!status && !in->opcode)
		in->data = le32_to_cpu
			(((struct ice_sbq_msg_cmpl *)&msg)->data);
	return status;
}

/* FW Admin Queue command wrappers */

/* Software lock/mutex that is meant to be held while the Global Config Lock
+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ enum ice_status
ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
		      struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size,
		      enum ice_adminq_opc opc, struct ice_sq_cd *cd);
bool ice_is_sbq_supported(struct ice_hw *hw);
struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw);
enum ice_status
ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,
		struct ice_aq_desc *desc, void *buf, u16 buf_size,
@@ -173,6 +175,7 @@ void ice_replay_post(struct ice_hw *hw);
void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
struct ice_q_ctx *
ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle);
int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in);
void
ice_stat_update40(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
		  u64 *prev_stat, u64 *cur_stat);
+62 −0
Original line number Diff line number Diff line
@@ -51,6 +51,19 @@ static void ice_mailbox_init_regs(struct ice_hw *hw)
	ICE_CQ_INIT_REGS(cq, PF_MBX);
}

/**
 * ice_sb_init_regs - Initialize Sideband registers
 * @hw: pointer to the hardware structure
 *
 * This assumes the alloc_sq and alloc_rq functions have already been called
 */
static void ice_sb_init_regs(struct ice_hw *hw)
{
	struct ice_ctl_q_info *cq = &hw->sbq;

	ICE_CQ_INIT_REGS(cq, PF_SB);
}

/**
 * ice_check_sq_alive
 * @hw: pointer to the HW struct
@@ -609,6 +622,10 @@ static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
		ice_adminq_init_regs(hw);
		cq = &hw->adminq;
		break;
	case ICE_CTL_Q_SB:
		ice_sb_init_regs(hw);
		cq = &hw->sbq;
		break;
	case ICE_CTL_Q_MAILBOX:
		ice_mailbox_init_regs(hw);
		cq = &hw->mailboxq;
@@ -645,6 +662,32 @@ static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
	return ret_code;
}

/**
 * ice_is_sbq_supported - is the sideband queue supported
 * @hw: pointer to the hardware structure
 *
 * Returns true if the sideband control queue interface is
 * supported for the device, false otherwise
 */
bool ice_is_sbq_supported(struct ice_hw *hw)
{
	/* The device sideband queue is only supported on devices with the
	 * generic MAC type.
	 */
	return hw->mac_type == ICE_MAC_GENERIC;
}

/**
 * ice_get_sbq - returns the right control queue to use for sideband
 * @hw: pointer to the hardware structure
 */
struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw)
{
	if (ice_is_sbq_supported(hw))
		return &hw->sbq;
	return &hw->adminq;
}

/**
 * ice_shutdown_ctrlq - shutdown routine for any control queue
 * @hw: pointer to the hardware structure
@@ -662,6 +705,9 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
		if (ice_check_sq_alive(hw, cq))
			ice_aq_q_shutdown(hw, true);
		break;
	case ICE_CTL_Q_SB:
		cq = &hw->sbq;
		break;
	case ICE_CTL_Q_MAILBOX:
		cq = &hw->mailboxq;
		break;
@@ -685,6 +731,9 @@ void ice_shutdown_all_ctrlq(struct ice_hw *hw)
{
	/* Shutdown FW admin queue */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);
	/* Shutdown PHY Sideband */
	if (ice_is_sbq_supported(hw))
		ice_shutdown_ctrlq(hw, ICE_CTL_Q_SB);
	/* Shutdown PF-VF Mailbox */
	ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}
@@ -724,6 +773,15 @@ enum ice_status ice_init_all_ctrlq(struct ice_hw *hw)

	if (status)
		return status;
	/* sideband control queue (SBQ) interface is not supported on some
	 * devices. Initialize if supported, else fallback to the admin queue
	 * interface
	 */
	if (ice_is_sbq_supported(hw)) {
		status = ice_init_ctrlq(hw, ICE_CTL_Q_SB);
		if (status)
			return status;
	}
	/* Init Mailbox queue */
	return ice_init_ctrlq(hw, ICE_CTL_Q_MAILBOX);
}
@@ -759,6 +817,8 @@ static void ice_init_ctrlq_locks(struct ice_ctl_q_info *cq)
enum ice_status ice_create_all_ctrlq(struct ice_hw *hw)
{
	ice_init_ctrlq_locks(&hw->adminq);
	if (ice_is_sbq_supported(hw))
		ice_init_ctrlq_locks(&hw->sbq);
	ice_init_ctrlq_locks(&hw->mailboxq);

	return ice_init_all_ctrlq(hw);
@@ -791,6 +851,8 @@ void ice_destroy_all_ctrlq(struct ice_hw *hw)
	ice_shutdown_all_ctrlq(hw);

	ice_destroy_ctrlq_locks(&hw->adminq);
	if (ice_is_sbq_supported(hw))
		ice_destroy_ctrlq_locks(&hw->sbq);
	ice_destroy_ctrlq_locks(&hw->mailboxq);
}

Loading