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