aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_controlq.c
diff options
context:
space:
mode:
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>2018-03-20 10:58:10 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-03-26 13:34:49 -0400
commit940b61af02f497fcd911b9e2d75c6b8cf76b92fd (patch)
tree01b0d4c3d52df2b6dcef563f81e34b37237be11a /drivers/net/ethernet/intel/ice/ice_controlq.c
parentdc49c77236769c571e77d49450b2dfc001d60e33 (diff)
ice: Initialize PF and setup miscellaneous interrupt
This patch continues the initialization flow as follows: 1) Allocate and initialize necessary fields (like vsi, num_alloc_vsi, irq_tracker, etc) in the ice_pf instance. 2) Setup the miscellaneous interrupt handler. This also known as the "other interrupt causes" (OIC) handler and is used to handle non hotpath interrupts (like control queue events, link events, exceptions, etc. 3) Implement a background task to process admin queue receive (ARQ) events received by the driver. CC: Shannon Nelson <shannon.nelson@oracle.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Acked-by: Shannon Nelson <shannon.nelson@oracle.com> Tested-by: Tony Brelinski <tonyx.brelinski@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_controlq.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_controlq.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c
index b32c0fc04bc9..5909a4407e38 100644
--- a/drivers/net/ethernet/intel/ice/ice_controlq.c
+++ b/drivers/net/ethernet/intel/ice/ice_controlq.c
@@ -963,3 +963,104 @@ void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode)
963 desc->opcode = cpu_to_le16(opcode); 963 desc->opcode = cpu_to_le16(opcode);
964 desc->flags = cpu_to_le16(ICE_AQ_FLAG_SI); 964 desc->flags = cpu_to_le16(ICE_AQ_FLAG_SI);
965} 965}
966
967/**
968 * ice_clean_rq_elem
969 * @hw: pointer to the hw struct
970 * @cq: pointer to the specific Control queue
971 * @e: event info from the receive descriptor, includes any buffers
972 * @pending: number of events that could be left to process
973 *
974 * This function cleans one Admin Receive Queue element and returns
975 * the contents through e. It can also return how many events are
976 * left to process through 'pending'.
977 */
978enum ice_status
979ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
980 struct ice_rq_event_info *e, u16 *pending)
981{
982 u16 ntc = cq->rq.next_to_clean;
983 enum ice_status ret_code = 0;
984 struct ice_aq_desc *desc;
985 struct ice_dma_mem *bi;
986 u16 desc_idx;
987 u16 datalen;
988 u16 flags;
989 u16 ntu;
990
991 /* pre-clean the event info */
992 memset(&e->desc, 0, sizeof(e->desc));
993
994 /* take the lock before we start messing with the ring */
995 mutex_lock(&cq->rq_lock);
996
997 if (!cq->rq.count) {
998 ice_debug(hw, ICE_DBG_AQ_MSG,
999 "Control Receive queue not initialized.\n");
1000 ret_code = ICE_ERR_AQ_EMPTY;
1001 goto clean_rq_elem_err;
1002 }
1003
1004 /* set next_to_use to head */
1005 ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);
1006
1007 if (ntu == ntc) {
1008 /* nothing to do - shouldn't need to update ring's values */
1009 ret_code = ICE_ERR_AQ_NO_WORK;
1010 goto clean_rq_elem_out;
1011 }
1012
1013 /* now clean the next descriptor */
1014 desc = ICE_CTL_Q_DESC(cq->rq, ntc);
1015 desc_idx = ntc;
1016
1017 flags = le16_to_cpu(desc->flags);
1018 if (flags & ICE_AQ_FLAG_ERR) {
1019 ret_code = ICE_ERR_AQ_ERROR;
1020 cq->rq_last_status = (enum ice_aq_err)le16_to_cpu(desc->retval);
1021 ice_debug(hw, ICE_DBG_AQ_MSG,
1022 "Control Receive Queue Event received with error 0x%x\n",
1023 cq->rq_last_status);
1024 }
1025 memcpy(&e->desc, desc, sizeof(e->desc));
1026 datalen = le16_to_cpu(desc->datalen);
1027 e->msg_len = min(datalen, e->buf_len);
1028 if (e->msg_buf && e->msg_len)
1029 memcpy(e->msg_buf, cq->rq.r.rq_bi[desc_idx].va, e->msg_len);
1030
1031 ice_debug(hw, ICE_DBG_AQ_MSG, "ARQ: desc and buffer:\n");
1032
1033 ice_debug_cq(hw, ICE_DBG_AQ_CMD, (void *)desc, e->msg_buf,
1034 cq->rq_buf_size);
1035
1036 /* Restore the original datalen and buffer address in the desc,
1037 * FW updates datalen to indicate the event message size
1038 */
1039 bi = &cq->rq.r.rq_bi[ntc];
1040 memset(desc, 0, sizeof(*desc));
1041
1042 desc->flags = cpu_to_le16(ICE_AQ_FLAG_BUF);
1043 if (cq->rq_buf_size > ICE_AQ_LG_BUF)
1044 desc->flags |= cpu_to_le16(ICE_AQ_FLAG_LB);
1045 desc->datalen = cpu_to_le16(bi->size);
1046 desc->params.generic.addr_high = cpu_to_le32(upper_32_bits(bi->pa));
1047 desc->params.generic.addr_low = cpu_to_le32(lower_32_bits(bi->pa));
1048
1049 /* set tail = the last cleaned desc index. */
1050 wr32(hw, cq->rq.tail, ntc);
1051 /* ntc is updated to tail + 1 */
1052 ntc++;
1053 if (ntc == cq->num_rq_entries)
1054 ntc = 0;
1055 cq->rq.next_to_clean = ntc;
1056 cq->rq.next_to_use = ntu;
1057
1058clean_rq_elem_out:
1059 /* Set pending if needed, unlock and return */
1060 if (pending)
1061 *pending = (u16)((ntc > ntu ? cq->rq.count : 0) + (ntu - ntc));
1062clean_rq_elem_err:
1063 mutex_unlock(&cq->rq_lock);
1064
1065 return ret_code;
1066}