1*d14abf15SRobert Mustacchi #ifndef __COMMAND_H__
2*d14abf15SRobert Mustacchi #define __COMMAND_H__
3*d14abf15SRobert Mustacchi
4*d14abf15SRobert Mustacchi /* This file containes the slow-path send queue and the L2 Command code */
5*d14abf15SRobert Mustacchi #include "57712_reg.h"
6*d14abf15SRobert Mustacchi #include "577xx_int_offsets.h"
7*d14abf15SRobert Mustacchi #include "context.h"
8*d14abf15SRobert Mustacchi #include "lm5710.h"
9*d14abf15SRobert Mustacchi //#include "5710_hsi.h"
10*d14abf15SRobert Mustacchi //#define MAX_PROTO 2
11*d14abf15SRobert Mustacchi
12*d14abf15SRobert Mustacchi /* How many slow-path-queue elements can be sent in parallel divided into normal and high priority */
13*d14abf15SRobert Mustacchi #define MAX_NORMAL_PRIORITY_SPE 7
14*d14abf15SRobert Mustacchi #define MAX_HIGH_PRIORITY_SPE 1
15*d14abf15SRobert Mustacchi #define MAX_NUM_SPE 8
16*d14abf15SRobert Mustacchi
17*d14abf15SRobert Mustacchi #define CMD_PRIORITY_NORMAL 0x10
18*d14abf15SRobert Mustacchi #define CMD_PRIORITY_MEDIUM 0x20
19*d14abf15SRobert Mustacchi #define CMD_PRIORITY_HIGH 0x30
20*d14abf15SRobert Mustacchi
21*d14abf15SRobert Mustacchi
22*d14abf15SRobert Mustacchi
23*d14abf15SRobert Mustacchi
24*d14abf15SRobert Mustacchi /* structure representing a list of slow-path-completions */
25*d14abf15SRobert Mustacchi typedef struct _sp_cqes_info {
26*d14abf15SRobert Mustacchi union eth_rx_cqe sp_cqe[MAX_NUM_SPE];
27*d14abf15SRobert Mustacchi u8_t idx;
28*d14abf15SRobert Mustacchi } sp_cqes_info;
29*d14abf15SRobert Mustacchi
30*d14abf15SRobert Mustacchi
_lm_sq_post(struct _lm_device_t * pdev,struct sq_pending_command * pending)31*d14abf15SRobert Mustacchi static __inline void _lm_sq_post(struct _lm_device_t *pdev,struct sq_pending_command * pending)
32*d14abf15SRobert Mustacchi {
33*d14abf15SRobert Mustacchi u32_t func = FUNC_ID(pdev);
34*d14abf15SRobert Mustacchi
35*d14abf15SRobert Mustacchi /* TODO replace this with the proper struct */
36*d14abf15SRobert Mustacchi /* CID needs port number to be encoded int it */
37*d14abf15SRobert Mustacchi mm_memcpy(pdev->sq_info.sq_chain.prod_bd, &pending->command, sizeof(pending->command));
38*d14abf15SRobert Mustacchi
39*d14abf15SRobert Mustacchi pdev->sq_info.sq_chain.prod_idx ++;
40*d14abf15SRobert Mustacchi pdev->sq_info.sq_chain.bd_left --;
41*d14abf15SRobert Mustacchi
42*d14abf15SRobert Mustacchi if (pdev->sq_info.sq_chain.prod_bd == pdev->sq_info.sq_chain.last_bd) {
43*d14abf15SRobert Mustacchi pdev->sq_info.sq_chain.prod_bd = pdev->sq_info.sq_chain.sq_chain_virt;
44*d14abf15SRobert Mustacchi }else{
45*d14abf15SRobert Mustacchi pdev->sq_info.sq_chain.prod_bd ++ ;
46*d14abf15SRobert Mustacchi }
47*d14abf15SRobert Mustacchi
48*d14abf15SRobert Mustacchi
49*d14abf15SRobert Mustacchi DbgMessage(pdev,VERBOSEl2sp | VERBOSEl4sp, "Writing SP prod %d, conn_and_cmd_data=%x, type=%d \n",pdev->sq_info.sq_chain.prod_idx, pending->command.hdr.conn_and_cmd_data, pending->command.hdr.type);
50*d14abf15SRobert Mustacchi
51*d14abf15SRobert Mustacchi if (IS_PFDEV(pdev) && pdev->sq_info.sq_state == SQ_STATE_NORMAL) {
52*d14abf15SRobert Mustacchi LM_INTMEM_WRITE16(pdev, XSTORM_SPQ_PROD_OFFSET(func), pdev->sq_info.sq_chain.prod_idx, BAR_XSTRORM_INTMEM);
53*d14abf15SRobert Mustacchi }
54*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
55*d14abf15SRobert Mustacchi else {
56*d14abf15SRobert Mustacchi LM_INTMEM_WRITE16(PFDEV(pdev),XSTORM_VF_SPQ_PROD_OFFSET(ABS_VFID(pdev)), pdev->sq_info.sq_chain.prod_idx, BAR_XSTRORM_INTMEM);
57*d14abf15SRobert Mustacchi }
58*d14abf15SRobert Mustacchi #endif
59*d14abf15SRobert Mustacchi }
60*d14abf15SRobert Mustacchi
61*d14abf15SRobert Mustacchi /**
62*d14abf15SRobert Mustacchi * @Description: This function fills a command that is received
63*d14abf15SRobert Mustacchi * as a parameter given the input...
64*d14abf15SRobert Mustacchi *
65*d14abf15SRobert Mustacchi * @param pdev
66*d14abf15SRobert Mustacchi * @param pending - OUT: this entry is filled given the input
67*d14abf15SRobert Mustacchi * below
68*d14abf15SRobert Mustacchi * @param cid
69*d14abf15SRobert Mustacchi * @param command - FW Command ID
70*d14abf15SRobert Mustacchi * @param type - The type of connection, can optionally
71*d14abf15SRobert Mustacchi * include the function id as well if it differs
72*d14abf15SRobert Mustacchi * from the function of pdev (for example for VFs)
73*d14abf15SRobert Mustacchi *
74*d14abf15SRobert Mustacchi * @param data - Data for FW ramrod
75*d14abf15SRobert Mustacchi * @param release_mem_flag - Determines whether the sp pending
76*d14abf15SRobert Mustacchi * command will be returned to the pool
77*d14abf15SRobert Mustacchi * at the end of usage.
78*d14abf15SRobert Mustacchi */
lm_sq_post_fill_entry(struct _lm_device_t * pdev,struct sq_pending_command * pending,u32_t cid,u8_t command,u16_t type,u64_t data,u8_t release_mem_flag)79*d14abf15SRobert Mustacchi static __inline void lm_sq_post_fill_entry(struct _lm_device_t* pdev,
80*d14abf15SRobert Mustacchi struct sq_pending_command * pending,
81*d14abf15SRobert Mustacchi u32_t cid,
82*d14abf15SRobert Mustacchi u8_t command,
83*d14abf15SRobert Mustacchi u16_t type,
84*d14abf15SRobert Mustacchi u64_t data,
85*d14abf15SRobert Mustacchi u8_t release_mem_flag)
86*d14abf15SRobert Mustacchi {
87*d14abf15SRobert Mustacchi /* In some cases type may already contain the func-id (VF specifically) so we add it only if it's not there... */
88*d14abf15SRobert Mustacchi if (!(type & SPE_HDR_T_FUNCTION_ID))
89*d14abf15SRobert Mustacchi {
90*d14abf15SRobert Mustacchi type |= (FUNC_ID(pdev) << SPE_HDR_T_FUNCTION_ID_SHIFT);
91*d14abf15SRobert Mustacchi }
92*d14abf15SRobert Mustacchi
93*d14abf15SRobert Mustacchi // CID MSB is function number
94*d14abf15SRobert Mustacchi pending->command.hdr.conn_and_cmd_data = mm_cpu_to_le32((command << SPE_HDR_T_CMD_ID_SHIFT ) | HW_CID(pdev,cid));
95*d14abf15SRobert Mustacchi pending->command.hdr.type = mm_cpu_to_le16(type);
96*d14abf15SRobert Mustacchi pending->command.protocol_data.hi = mm_cpu_to_le32(U64_HI(data));
97*d14abf15SRobert Mustacchi pending->command.protocol_data.lo = mm_cpu_to_le32(U64_LO(data));
98*d14abf15SRobert Mustacchi pending->flags = 0;
99*d14abf15SRobert Mustacchi
100*d14abf15SRobert Mustacchi if (release_mem_flag)
101*d14abf15SRobert Mustacchi {
102*d14abf15SRobert Mustacchi SET_FLAGS(pending->flags, SQ_PEND_RELEASE_MEM);
103*d14abf15SRobert Mustacchi }
104*d14abf15SRobert Mustacchi
105*d14abf15SRobert Mustacchi pending->cid = cid;
106*d14abf15SRobert Mustacchi pending->type = type; /* don't kill function ID, RSC VF update really uses the value (& SPE_HDR_T_CONN_TYPE);*/
107*d14abf15SRobert Mustacchi pending->cmd = command;
108*d14abf15SRobert Mustacchi
109*d14abf15SRobert Mustacchi }
110*d14abf15SRobert Mustacchi
111*d14abf15SRobert Mustacchi /**
112*d14abf15SRobert Mustacchi * Description
113*d14abf15SRobert Mustacchi * Add the entry to the pending SP list.
114*d14abf15SRobert Mustacchi * Try to add entry's from the list to the sq_chain if possible.(there is are less then 8 ramrod commands pending)
115*d14abf15SRobert Mustacchi *
116*d14abf15SRobert Mustacchi * @param pdev
117*d14abf15SRobert Mustacchi * @param pending - The pending list entry.
118*d14abf15SRobert Mustacchi * @param priority - (high or low) to witch list to insert the pending list entry.
119*d14abf15SRobert Mustacchi *
120*d14abf15SRobert Mustacchi * @return lm_status_t: LM_STATUS_SUCCESS on success or
121*d14abf15SRobert Mustacchi * LM_STATUS_REQUEST_NOT_ACCEPTED if slowpath queue is
122*d14abf15SRobert Mustacchi * in blocked state.
123*d14abf15SRobert Mustacchi */
124*d14abf15SRobert Mustacchi lm_status_t lm_sq_post_entry(struct _lm_device_t * pdev,
125*d14abf15SRobert Mustacchi struct sq_pending_command * pending,
126*d14abf15SRobert Mustacchi u8_t priority);
127*d14abf15SRobert Mustacchi
128*d14abf15SRobert Mustacchi /*
129*d14abf15SRobert Mustacchi post a ramrod to the sq
130*d14abf15SRobert Mustacchi takes the sq pending list spinlock and adds the request
131*d14abf15SRobert Mustacchi will not block
132*d14abf15SRobert Mustacchi but the actuall posting to the sq might be deffered until there is room
133*d14abf15SRobert Mustacchi MUST only have one request pending per CID (this is up to the caller to enforce)
134*d14abf15SRobert Mustacchi */
135*d14abf15SRobert Mustacchi lm_status_t lm_sq_post(struct _lm_device_t *pdev,
136*d14abf15SRobert Mustacchi u32_t cid,
137*d14abf15SRobert Mustacchi u8_t command,
138*d14abf15SRobert Mustacchi u8_t priority,
139*d14abf15SRobert Mustacchi u16_t type,
140*d14abf15SRobert Mustacchi u64_t data);
141*d14abf15SRobert Mustacchi
142*d14abf15SRobert Mustacchi /**
143*d14abf15SRobert Mustacchi * @Description
144*d14abf15SRobert Mustacchi * inform the sq mechanism of completed ramrods because the
145*d14abf15SRobert Mustacchi * completions arrive on the fast-path rings the fast-path
146*d14abf15SRobert Mustacchi * needs to inform the sq that the ramrod has been serviced
147*d14abf15SRobert Mustacchi * will not block, it also needs to notify which ramrod has
148*d14abf15SRobert Mustacchi * been completed since completions can arrive in a different
149*d14abf15SRobert Mustacchi * sequence than sent.
150*d14abf15SRobert Mustacchi * @param pdev
151*d14abf15SRobert Mustacchi * @param priority: priority of ramrod being completed
152*d14abf15SRobert Mustacchi * (different credits)
153*d14abf15SRobert Mustacchi * @param command: which command is completed
154*d14abf15SRobert Mustacchi * @param type: connection type
155*d14abf15SRobert Mustacchi * @param cid: connection id that ramrod was sent with
156*d14abf15SRobert Mustacchi */
157*d14abf15SRobert Mustacchi void lm_sq_complete(struct _lm_device_t *pdev, u8_t priority,
158*d14abf15SRobert Mustacchi u8_t command, u16_t type, u32_t cid );
159*d14abf15SRobert Mustacchi
160*d14abf15SRobert Mustacchi /**
161*d14abf15SRobert Mustacchi * @description
162*d14abf15SRobert Mustacchi * do any deffered posting pending on the sq, will take the list spinlock
163*d14abf15SRobert Mustacchi * will not block. Check sq state, if its pending (it means no hw...) call flush
164*d14abf15SRobert Mustacchi * at the end, which will take care of completing these completions internally.
165*d14abf15SRobert Mustacchi * @param pdev
166*d14abf15SRobert Mustacchi *
167*d14abf15SRobert Mustacchi * @return lm_status_t SUCCESS: is no pending requests were sent. PENDING if a
168*d14abf15SRobert Mustacchi * if pending request was sent.
169*d14abf15SRobert Mustacchi */
170*d14abf15SRobert Mustacchi lm_status_t lm_sq_post_pending(struct _lm_device_t *pdev);
171*d14abf15SRobert Mustacchi
172*d14abf15SRobert Mustacchi /*
173*d14abf15SRobert Mustacchi post a slow-path command
174*d14abf15SRobert Mustacchi takes a spinlock, does not sleep
175*d14abf15SRobert Mustacchi actuall command posting may be delayed
176*d14abf15SRobert Mustacchi */
lm_command_post(struct _lm_device_t * pdev,u32_t cid,u8_t command,u8_t priority,u16_t type,u64_t data)177*d14abf15SRobert Mustacchi static __inline lm_status_t lm_command_post( struct _lm_device_t* pdev,
178*d14abf15SRobert Mustacchi u32_t cid,
179*d14abf15SRobert Mustacchi u8_t command,
180*d14abf15SRobert Mustacchi u8_t priority,
181*d14abf15SRobert Mustacchi u16_t type,
182*d14abf15SRobert Mustacchi u64_t data )
183*d14abf15SRobert Mustacchi {
184*d14abf15SRobert Mustacchi return lm_sq_post(pdev, cid, command, priority, type, data );
185*d14abf15SRobert Mustacchi }
186*d14abf15SRobert Mustacchi
187*d14abf15SRobert Mustacchi
188*d14abf15SRobert Mustacchi /* TODO: move functions above to lm_sp.c */
189*d14abf15SRobert Mustacchi /**
190*d14abf15SRobert Mustacchi * @Description
191*d14abf15SRobert Mustacchi * change state of slowpath queue.
192*d14abf15SRobert Mustacchi *
193*d14abf15SRobert Mustacchi * @param pdev
194*d14abf15SRobert Mustacchi * @param state NORMAL, PENDING, BLOCKED
195*d14abf15SRobert Mustacchi */
196*d14abf15SRobert Mustacchi void lm_sq_change_state(struct _lm_device_t *pdev, lm_sq_state_t state);
197*d14abf15SRobert Mustacchi
198*d14abf15SRobert Mustacchi /**
199*d14abf15SRobert Mustacchi * @Description
200*d14abf15SRobert Mustacchi * This function completes any pending slowpath requests.
201*d14abf15SRobert Mustacchi * It does this as if they were completed via cookie...
202*d14abf15SRobert Mustacchi * It needs to know all the possible cookies and which
203*d14abf15SRobert Mustacchi * completions to give. Any new ramrod should be added to
204*d14abf15SRobert Mustacchi * this function. Also if it should be ignored.
205*d14abf15SRobert Mustacchi *
206*d14abf15SRobert Mustacchi * @param pdev
207*d14abf15SRobert Mustacchi */
208*d14abf15SRobert Mustacchi void lm_sq_complete_pending_requests(struct _lm_device_t *pdev);
209*d14abf15SRobert Mustacchi
210*d14abf15SRobert Mustacchi /**
211*d14abf15SRobert Mustacchi * @Description
212*d14abf15SRobert Mustacchi * This function takes care of registering a DPC for
213*d14abf15SRobert Mustacchi * completing slowpaths internally in the driver (if such
214*d14abf15SRobert Mustacchi * exist)
215*d14abf15SRobert Mustacchi * @param pdev
216*d14abf15SRobert Mustacchi *
217*d14abf15SRobert Mustacchi * @return lm_status_t SUCCESS: if all flushed (i.e. dpc not
218*d14abf15SRobert Mustacchi * scheduled)
219*d14abf15SRobert Mustacchi * PENDING: if dpc is scheduled
220*d14abf15SRobert Mustacchi */
221*d14abf15SRobert Mustacchi lm_status_t lm_sq_flush(struct _lm_device_t *pdev);
222*d14abf15SRobert Mustacchi
223*d14abf15SRobert Mustacchi /**
224*d14abf15SRobert Mustacchi * @Description
225*d14abf15SRobert Mustacchi * Checks if the sq is empty
226*d14abf15SRobert Mustacchi *
227*d14abf15SRobert Mustacchi * @param pdev
228*d14abf15SRobert Mustacchi *
229*d14abf15SRobert Mustacchi * @return u8_t TRUE if empty FALSE o/w
230*d14abf15SRobert Mustacchi */
231*d14abf15SRobert Mustacchi u8_t lm_sq_is_empty(struct _lm_device_t *pdev);
232*d14abf15SRobert Mustacchi
233*d14abf15SRobert Mustacchi
234*d14abf15SRobert Mustacchi lm_status_t lm_sq_comp_cb_register(struct _lm_device_t *pdev, u8_t type, lm_sq_comp_cb_t cb);
235*d14abf15SRobert Mustacchi
236*d14abf15SRobert Mustacchi lm_status_t lm_sq_comp_cb_deregister(struct _lm_device_t *pdev, u8_t type);
237*d14abf15SRobert Mustacchi
238*d14abf15SRobert Mustacchi
239*d14abf15SRobert Mustacchi
240*d14abf15SRobert Mustacchi #endif //__COMMAND_H__
241