Skip to content

Commit 940b61a

Browse files
refactormanJeff Kirsher
authored andcommitted
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 <[email protected]> Signed-off-by: Anirudh Venkataramanan <[email protected]> Acked-by: Shannon Nelson <[email protected]> Tested-by: Tony Brelinski <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent dc49c77 commit 940b61a

File tree

10 files changed

+1025
-1
lines changed

10 files changed

+1025
-1
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,113 @@
1212
#include <linux/compiler.h>
1313
#include <linux/etherdevice.h>
1414
#include <linux/pci.h>
15+
#include <linux/workqueue.h>
1516
#include <linux/aer.h>
17+
#include <linux/interrupt.h>
18+
#include <linux/timer.h>
1619
#include <linux/delay.h>
1720
#include <linux/bitmap.h>
21+
#include <linux/if_bridge.h>
1822
#include "ice_devids.h"
1923
#include "ice_type.h"
24+
#include "ice_txrx.h"
2025
#include "ice_switch.h"
2126
#include "ice_common.h"
2227
#include "ice_sched.h"
2328

2429
#define ICE_BAR0 0
30+
#define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16)
2531
#define ICE_AQ_LEN 64
32+
#define ICE_MIN_MSIX 2
33+
#define ICE_MAX_VSI_ALLOC 130
34+
#define ICE_MAX_TXQS 2048
35+
#define ICE_MAX_RXQS 2048
36+
#define ICE_RES_VALID_BIT 0x8000
37+
#define ICE_RES_MISC_VEC_ID (ICE_RES_VALID_BIT - 1)
2638

2739
#define ICE_DFLT_NETIF_M (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
2840

41+
struct ice_res_tracker {
42+
u16 num_entries;
43+
u16 search_hint;
44+
u16 list[1];
45+
};
46+
47+
struct ice_sw {
48+
struct ice_pf *pf;
49+
u16 sw_id; /* switch ID for this switch */
50+
u16 bridge_mode; /* VEB/VEPA/Port Virtualizer */
51+
};
52+
2953
enum ice_state {
3054
__ICE_DOWN,
55+
__ICE_PFR_REQ, /* set by driver and peers */
56+
__ICE_ADMINQ_EVENT_PENDING,
57+
__ICE_SERVICE_SCHED,
3158
__ICE_STATE_NBITS /* must be last */
3259
};
3360

61+
/* struct that defines a VSI, associated with a dev */
62+
struct ice_vsi {
63+
struct net_device *netdev;
64+
struct ice_port_info *port_info; /* back pointer to port_info */
65+
u16 vsi_num; /* HW (absolute) index of this VSI */
66+
} ____cacheline_internodealigned_in_smp;
67+
68+
enum ice_pf_flags {
69+
ICE_FLAG_MSIX_ENA,
70+
ICE_FLAG_FLTR_SYNC,
71+
ICE_FLAG_RSS_ENA,
72+
ICE_PF_FLAGS_NBITS /* must be last */
73+
};
74+
3475
struct ice_pf {
3576
struct pci_dev *pdev;
77+
struct msix_entry *msix_entries;
78+
struct ice_res_tracker *irq_tracker;
79+
struct ice_vsi **vsi; /* VSIs created by the driver */
80+
struct ice_sw *first_sw; /* first switch created by firmware */
3681
DECLARE_BITMAP(state, __ICE_STATE_NBITS);
82+
DECLARE_BITMAP(avail_txqs, ICE_MAX_TXQS);
83+
DECLARE_BITMAP(avail_rxqs, ICE_MAX_RXQS);
84+
DECLARE_BITMAP(flags, ICE_PF_FLAGS_NBITS);
85+
unsigned long serv_tmr_period;
86+
unsigned long serv_tmr_prev;
87+
struct timer_list serv_tmr;
88+
struct work_struct serv_task;
89+
struct mutex avail_q_mutex; /* protects access to avail_[rx|tx]qs */
90+
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
3791
u32 msg_enable;
92+
u32 oicr_idx; /* Other interrupt cause vector index */
93+
u32 num_lan_msix; /* Total MSIX vectors for base driver */
94+
u32 num_avail_msix; /* remaining MSIX vectors left unclaimed */
95+
u16 num_lan_tx; /* num lan tx queues setup */
96+
u16 num_lan_rx; /* num lan rx queues setup */
97+
u16 q_left_tx; /* remaining num tx queues left unclaimed */
98+
u16 q_left_rx; /* remaining num rx queues left unclaimed */
99+
u16 next_vsi; /* Next free slot in pf->vsi[] - 0-based! */
100+
u16 num_alloc_vsi;
101+
38102
struct ice_hw hw;
103+
char int_name[ICE_INT_NAME_STR_LEN];
39104
};
105+
106+
/**
107+
* ice_irq_dynamic_ena - Enable default interrupt generation settings
108+
* @hw: pointer to hw struct
109+
*/
110+
static inline void ice_irq_dynamic_ena(struct ice_hw *hw)
111+
{
112+
u32 vector = ((struct ice_pf *)hw->back)->oicr_idx;
113+
int itr = ICE_ITR_NONE;
114+
u32 val;
115+
116+
/* clear the PBA here, as this function is meant to clean out all
117+
* previous interrupts and enable the interrupt
118+
*/
119+
val = GLINT_DYN_CTL_INTENA_M | GLINT_DYN_CTL_CLEARPBA_M |
120+
(itr << GLINT_DYN_CTL_ITR_INDX_S);
121+
122+
wr32(hw, GLINT_DYN_CTL(vector), val);
123+
}
40124
#endif /* _ICE_H_ */

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,13 @@ struct ice_aq_desc {
583583
/* FW defined boundary for a large buffer, 4k >= Large buffer > 512 bytes */
584584
#define ICE_AQ_LG_BUF 512
585585

586+
#define ICE_AQ_FLAG_ERR_S 2
586587
#define ICE_AQ_FLAG_LB_S 9
587588
#define ICE_AQ_FLAG_RD_S 10
588589
#define ICE_AQ_FLAG_BUF_S 12
589590
#define ICE_AQ_FLAG_SI_S 13
590591

592+
#define ICE_AQ_FLAG_ERR BIT(ICE_AQ_FLAG_ERR_S) /* 0x4 */
591593
#define ICE_AQ_FLAG_LB BIT(ICE_AQ_FLAG_LB_S) /* 0x200 */
592594
#define ICE_AQ_FLAG_RD BIT(ICE_AQ_FLAG_RD_S) /* 0x400 */
593595
#define ICE_AQ_FLAG_BUF BIT(ICE_AQ_FLAG_BUF_S) /* 0x1000 */

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,12 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
282282
if (status)
283283
return status;
284284

285+
/* set these values to minimum allowed */
286+
hw->itr_gran_200 = ICE_ITR_GRAN_MIN_200;
287+
hw->itr_gran_100 = ICE_ITR_GRAN_MIN_100;
288+
hw->itr_gran_50 = ICE_ITR_GRAN_MIN_50;
289+
hw->itr_gran_25 = ICE_ITR_GRAN_MIN_25;
290+
285291
status = ice_init_all_ctrlq(hw);
286292
if (status)
287293
goto err_unroll_cqinit;

drivers/net/ethernet/intel/ice/ice_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req);
1717
enum ice_status ice_init_all_ctrlq(struct ice_hw *hw);
1818
void ice_shutdown_all_ctrlq(struct ice_hw *hw);
1919
enum ice_status
20+
ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
21+
struct ice_rq_event_info *e, u16 *pending);
22+
enum ice_status
2023
ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
2124
enum ice_aq_res_access_type access);
2225
void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res);

drivers/net/ethernet/intel/ice/ice_controlq.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,3 +963,104 @@ void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode)
963963
desc->opcode = cpu_to_le16(opcode);
964964
desc->flags = cpu_to_le16(ICE_AQ_FLAG_SI);
965965
}
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+
*/
978+
enum ice_status
979+
ice_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+
1058+
clean_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));
1062+
clean_rq_elem_err:
1063+
mutex_unlock(&cq->rq_lock);
1064+
1065+
return ret_code;
1066+
}

drivers/net/ethernet/intel/ice/ice_controlq.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ struct ice_sq_cd {
6767

6868
#define ICE_CTL_Q_DETAILS(R, i) (&(((struct ice_sq_cd *)((R).cmd_buf))[i]))
6969

70+
/* rq event information */
71+
struct ice_rq_event_info {
72+
struct ice_aq_desc desc;
73+
u16 msg_len;
74+
u16 buf_len;
75+
u8 *msg_buf;
76+
};
77+
7078
/* Control Queue information */
7179
struct ice_ctl_q_info {
7280
enum ice_ctl_q qtype;

drivers/net/ethernet/intel/ice/ice_hw_autogen.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
#define PF_FW_ARQLEN 0x00080280
1515
#define PF_FW_ARQLEN_ARQLEN_S 0
1616
#define PF_FW_ARQLEN_ARQLEN_M ICE_M(0x3FF, PF_FW_ARQLEN_ARQLEN_S)
17+
#define PF_FW_ARQLEN_ARQVFE_S 28
18+
#define PF_FW_ARQLEN_ARQVFE_M BIT(PF_FW_ARQLEN_ARQVFE_S)
19+
#define PF_FW_ARQLEN_ARQOVFL_S 29
20+
#define PF_FW_ARQLEN_ARQOVFL_M BIT(PF_FW_ARQLEN_ARQOVFL_S)
21+
#define PF_FW_ARQLEN_ARQCRIT_S 30
22+
#define PF_FW_ARQLEN_ARQCRIT_M BIT(PF_FW_ARQLEN_ARQCRIT_S)
1723
#define PF_FW_ARQLEN_ARQENABLE_S 31
1824
#define PF_FW_ARQLEN_ARQENABLE_M BIT(PF_FW_ARQLEN_ARQENABLE_S)
1925
#define PF_FW_ARQT 0x00080480
@@ -25,6 +31,12 @@
2531
#define PF_FW_ATQLEN 0x00080200
2632
#define PF_FW_ATQLEN_ATQLEN_S 0
2733
#define PF_FW_ATQLEN_ATQLEN_M ICE_M(0x3FF, PF_FW_ATQLEN_ATQLEN_S)
34+
#define PF_FW_ATQLEN_ATQVFE_S 28
35+
#define PF_FW_ATQLEN_ATQVFE_M BIT(PF_FW_ATQLEN_ATQVFE_S)
36+
#define PF_FW_ATQLEN_ATQOVFL_S 29
37+
#define PF_FW_ATQLEN_ATQOVFL_M BIT(PF_FW_ATQLEN_ATQOVFL_S)
38+
#define PF_FW_ATQLEN_ATQCRIT_S 30
39+
#define PF_FW_ATQLEN_ATQCRIT_M BIT(PF_FW_ATQLEN_ATQCRIT_S)
2840
#define PF_FW_ATQLEN_ATQENABLE_S 31
2941
#define PF_FW_ATQLEN_ATQENABLE_M BIT(PF_FW_ATQLEN_ATQENABLE_S)
3042
#define PF_FW_ATQT 0x00080400
@@ -43,6 +55,57 @@
4355
#define PFGEN_CTRL 0x00091000
4456
#define PFGEN_CTRL_PFSWR_S 0
4557
#define PFGEN_CTRL_PFSWR_M BIT(PFGEN_CTRL_PFSWR_S)
58+
#define PFHMC_ERRORDATA 0x00520500
59+
#define PFHMC_ERRORINFO 0x00520400
60+
#define GLINT_DYN_CTL(_INT) (0x00160000 + ((_INT) * 4))
61+
#define GLINT_DYN_CTL_INTENA_S 0
62+
#define GLINT_DYN_CTL_INTENA_M BIT(GLINT_DYN_CTL_INTENA_S)
63+
#define GLINT_DYN_CTL_CLEARPBA_S 1
64+
#define GLINT_DYN_CTL_CLEARPBA_M BIT(GLINT_DYN_CTL_CLEARPBA_S)
65+
#define GLINT_DYN_CTL_ITR_INDX_S 3
66+
#define GLINT_DYN_CTL_SW_ITR_INDX_S 25
67+
#define GLINT_DYN_CTL_SW_ITR_INDX_M ICE_M(0x3, GLINT_DYN_CTL_SW_ITR_INDX_S)
68+
#define GLINT_DYN_CTL_INTENA_MSK_S 31
69+
#define GLINT_DYN_CTL_INTENA_MSK_M BIT(GLINT_DYN_CTL_INTENA_MSK_S)
70+
#define GLINT_ITR(_i, _INT) (0x00154000 + ((_i) * 8192 + (_INT) * 4))
71+
#define PFINT_FW_CTL 0x0016C800
72+
#define PFINT_FW_CTL_MSIX_INDX_S 0
73+
#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, PFINT_FW_CTL_MSIX_INDX_S)
74+
#define PFINT_FW_CTL_ITR_INDX_S 11
75+
#define PFINT_FW_CTL_ITR_INDX_M ICE_M(0x3, PFINT_FW_CTL_ITR_INDX_S)
76+
#define PFINT_FW_CTL_CAUSE_ENA_S 30
77+
#define PFINT_FW_CTL_CAUSE_ENA_M BIT(PFINT_FW_CTL_CAUSE_ENA_S)
78+
#define PFINT_OICR 0x0016CA00
79+
#define PFINT_OICR_INTEVENT_S 0
80+
#define PFINT_OICR_INTEVENT_M BIT(PFINT_OICR_INTEVENT_S)
81+
#define PFINT_OICR_HLP_RDY_S 14
82+
#define PFINT_OICR_HLP_RDY_M BIT(PFINT_OICR_HLP_RDY_S)
83+
#define PFINT_OICR_CPM_RDY_S 15
84+
#define PFINT_OICR_CPM_RDY_M BIT(PFINT_OICR_CPM_RDY_S)
85+
#define PFINT_OICR_ECC_ERR_S 16
86+
#define PFINT_OICR_ECC_ERR_M BIT(PFINT_OICR_ECC_ERR_S)
87+
#define PFINT_OICR_MAL_DETECT_S 19
88+
#define PFINT_OICR_MAL_DETECT_M BIT(PFINT_OICR_MAL_DETECT_S)
89+
#define PFINT_OICR_GRST_S 20
90+
#define PFINT_OICR_GRST_M BIT(PFINT_OICR_GRST_S)
91+
#define PFINT_OICR_PCI_EXCEPTION_S 21
92+
#define PFINT_OICR_PCI_EXCEPTION_M BIT(PFINT_OICR_PCI_EXCEPTION_S)
93+
#define PFINT_OICR_GPIO_S 22
94+
#define PFINT_OICR_GPIO_M BIT(PFINT_OICR_GPIO_S)
95+
#define PFINT_OICR_STORM_DETECT_S 24
96+
#define PFINT_OICR_STORM_DETECT_M BIT(PFINT_OICR_STORM_DETECT_S)
97+
#define PFINT_OICR_HMC_ERR_S 26
98+
#define PFINT_OICR_HMC_ERR_M BIT(PFINT_OICR_HMC_ERR_S)
99+
#define PFINT_OICR_PE_CRITERR_S 28
100+
#define PFINT_OICR_PE_CRITERR_M BIT(PFINT_OICR_PE_CRITERR_S)
101+
#define PFINT_OICR_CTL 0x0016CA80
102+
#define PFINT_OICR_CTL_MSIX_INDX_S 0
103+
#define PFINT_OICR_CTL_MSIX_INDX_M ICE_M(0x7FF, PFINT_OICR_CTL_MSIX_INDX_S)
104+
#define PFINT_OICR_CTL_ITR_INDX_S 11
105+
#define PFINT_OICR_CTL_ITR_INDX_M ICE_M(0x3, PFINT_OICR_CTL_ITR_INDX_S)
106+
#define PFINT_OICR_CTL_CAUSE_ENA_S 30
107+
#define PFINT_OICR_CTL_CAUSE_ENA_M BIT(PFINT_OICR_CTL_CAUSE_ENA_S)
108+
#define PFINT_OICR_ENA 0x0016C900
46109
#define GLLAN_RCTL_0 0x002941F8
47110
#define GLNVM_FLA 0x000B6108
48111
#define GLNVM_FLA_LOCKED_S 6

0 commit comments

Comments
 (0)