1*d14abf15SRobert Mustacchi /*******************************************************************************
2*d14abf15SRobert Mustacchi  * CDDL HEADER START
3*d14abf15SRobert Mustacchi  *
4*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
5*d14abf15SRobert Mustacchi  * Common Development and Distribution License (the "License").
6*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
7*d14abf15SRobert Mustacchi  *
8*d14abf15SRobert Mustacchi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d14abf15SRobert Mustacchi  * or http://www.opensolaris.org/os/licensing.
10*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
11*d14abf15SRobert Mustacchi  * and limitations under the License.
12*d14abf15SRobert Mustacchi  *
13*d14abf15SRobert Mustacchi  * When distributing Covered Code, include this CDDL HEADER in each
14*d14abf15SRobert Mustacchi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d14abf15SRobert Mustacchi  * If applicable, add the following below this CDDL HEADER, with the
16*d14abf15SRobert Mustacchi  * fields enclosed by brackets "[]" replaced with your own identifying
17*d14abf15SRobert Mustacchi  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d14abf15SRobert Mustacchi  *
19*d14abf15SRobert Mustacchi  * CDDL HEADER END
20*d14abf15SRobert Mustacchi  *
21*d14abf15SRobert Mustacchi  * Copyright 2014 QLogic Corporation
22*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
23*d14abf15SRobert Mustacchi  * QLogic End User License (the "License").
24*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
25*d14abf15SRobert Mustacchi  *
26*d14abf15SRobert Mustacchi  * You can obtain a copy of the License at
27*d14abf15SRobert Mustacchi  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
28*d14abf15SRobert Mustacchi  * QLogic_End_User_Software_License.txt
29*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
30*d14abf15SRobert Mustacchi  * and limitations under the License.
31*d14abf15SRobert Mustacchi  *
32*d14abf15SRobert Mustacchi  *
33*d14abf15SRobert Mustacchi  * Module Description:
34*d14abf15SRobert Mustacchi  *      This file contains the implementation of slow-path operations
35*d14abf15SRobert Mustacchi  *      for L2 + Common. It uses ecore_sp_verbs in most cases.
36*d14abf15SRobert Mustacchi  *
37*d14abf15SRobert Mustacchi  ******************************************************************************/
38*d14abf15SRobert Mustacchi 
39*d14abf15SRobert Mustacchi #include "lm5710.h"
40*d14abf15SRobert Mustacchi 
41*d14abf15SRobert Mustacchi #if !defined(__LINUX) && !defined(__SunOS)
42*d14abf15SRobert Mustacchi // disable warning C4127 (conditional expression is constant)
43*d14abf15SRobert Mustacchi // for this file (relevant when compiling with W4 warning level)
44*d14abf15SRobert Mustacchi #pragma warning( disable : 4127 )
45*d14abf15SRobert Mustacchi #endif /* __LINUX */
46*d14abf15SRobert Mustacchi 
47*d14abf15SRobert Mustacchi #if !defined(__LINUX) && !defined(__SunOS)
48*d14abf15SRobert Mustacchi #pragma warning( default : 4127 )
49*d14abf15SRobert Mustacchi #endif
50*d14abf15SRobert Mustacchi 
51*d14abf15SRobert Mustacchi #include "mm.h"
52*d14abf15SRobert Mustacchi #include "context.h"
53*d14abf15SRobert Mustacchi #include "command.h"
54*d14abf15SRobert Mustacchi #include "bd_chain.h"
55*d14abf15SRobert Mustacchi #include "ecore_common.h"
56*d14abf15SRobert Mustacchi #include "ecore_sp_verbs.h"
57*d14abf15SRobert Mustacchi #include "debug.h"
58*d14abf15SRobert Mustacchi 
59*d14abf15SRobert Mustacchi typedef enum _ecore_status_t ecore_status_t;
60*d14abf15SRobert Mustacchi 
61*d14abf15SRobert Mustacchi 
62*d14abf15SRobert Mustacchi 
63*d14abf15SRobert Mustacchi lm_status_t
lm_empty_ramrod_eth(IN struct _lm_device_t * pdev,IN const u32_t cid,IN u32_t data_cid,IN volatile u32_t * curr_state,IN u32_t new_state)64*d14abf15SRobert Mustacchi lm_empty_ramrod_eth(IN struct _lm_device_t *pdev,
65*d14abf15SRobert Mustacchi                     IN const u32_t          cid,
66*d14abf15SRobert Mustacchi                     IN u32_t                data_cid,
67*d14abf15SRobert Mustacchi                     IN volatile u32_t       *curr_state,
68*d14abf15SRobert Mustacchi                     IN u32_t                new_state)
69*d14abf15SRobert Mustacchi {
70*d14abf15SRobert Mustacchi     union eth_specific_data ramrod_data = {{0}};
71*d14abf15SRobert Mustacchi     lm_status_t             lm_status   = LM_STATUS_SUCCESS;
72*d14abf15SRobert Mustacchi 
73*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMi|INFORMl2sp, "#lm_empty_ramrod_eth_conn, curr_state=%d\n",curr_state);
74*d14abf15SRobert Mustacchi 
75*d14abf15SRobert Mustacchi     ASSERT_STATIC(sizeof(ramrod_data) == sizeof(u64_t));
76*d14abf15SRobert Mustacchi 
77*d14abf15SRobert Mustacchi     //Prepare ramrod data
78*d14abf15SRobert Mustacchi     ramrod_data.update_data_addr.lo = data_cid;
79*d14abf15SRobert Mustacchi     ramrod_data.update_data_addr.hi = 0 ;
80*d14abf15SRobert Mustacchi 
81*d14abf15SRobert Mustacchi     // Send Empty ramrod.
82*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
83*d14abf15SRobert Mustacchi                            cid,
84*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_ETH_EMPTY,
85*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
86*d14abf15SRobert Mustacchi                            ETH_CONNECTION_TYPE,
87*d14abf15SRobert Mustacchi                            *(u64_t *)&ramrod_data );
88*d14abf15SRobert Mustacchi 
89*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
90*d14abf15SRobert Mustacchi     {
91*d14abf15SRobert Mustacchi         return lm_status;
92*d14abf15SRobert Mustacchi     }
93*d14abf15SRobert Mustacchi 
94*d14abf15SRobert Mustacchi     /* curr_state may be NULL incase wait isn't required */
95*d14abf15SRobert Mustacchi     if (curr_state != NULL)
96*d14abf15SRobert Mustacchi     {
97*d14abf15SRobert Mustacchi         lm_status = lm_wait_state_change(pdev,
98*d14abf15SRobert Mustacchi                                          curr_state,
99*d14abf15SRobert Mustacchi                                          new_state);
100*d14abf15SRobert Mustacchi 
101*d14abf15SRobert Mustacchi         if ((lm_status != LM_STATUS_SUCCESS) && (lm_status != LM_STATUS_ABORTED))
102*d14abf15SRobert Mustacchi         {
103*d14abf15SRobert Mustacchi             DbgBreakMsg("lm_empty_ramrod_eth: lm_wait_state_change failed");
104*d14abf15SRobert Mustacchi         }
105*d14abf15SRobert Mustacchi     }
106*d14abf15SRobert Mustacchi 
107*d14abf15SRobert Mustacchi 
108*d14abf15SRobert Mustacchi 
109*d14abf15SRobert Mustacchi     return lm_status;
110*d14abf15SRobert Mustacchi } /* lm_empty_ramrod_eth */
111*d14abf15SRobert Mustacchi 
112*d14abf15SRobert Mustacchi 
113*d14abf15SRobert Mustacchi 
lm_ecore_status_to_lm_status(const ecore_status_t ecore_status)114*d14abf15SRobert Mustacchi static lm_status_t lm_ecore_status_to_lm_status( const ecore_status_t ecore_status )
115*d14abf15SRobert Mustacchi {
116*d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_FAILURE;
117*d14abf15SRobert Mustacchi 
118*d14abf15SRobert Mustacchi     switch (ecore_status)
119*d14abf15SRobert Mustacchi     {
120*d14abf15SRobert Mustacchi     case ECORE_SUCCESS:
121*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_SUCCESS;
122*d14abf15SRobert Mustacchi         break;
123*d14abf15SRobert Mustacchi 
124*d14abf15SRobert Mustacchi     case ECORE_TIMEOUT:
125*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_TIMEOUT;
126*d14abf15SRobert Mustacchi         break;
127*d14abf15SRobert Mustacchi 
128*d14abf15SRobert Mustacchi     case ECORE_INVAL:
129*d14abf15SRobert Mustacchi        lm_status = LM_STATUS_INVALID_PARAMETER;
130*d14abf15SRobert Mustacchi        break;
131*d14abf15SRobert Mustacchi 
132*d14abf15SRobert Mustacchi     case ECORE_BUSY:
133*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_BUSY;
134*d14abf15SRobert Mustacchi         break;
135*d14abf15SRobert Mustacchi 
136*d14abf15SRobert Mustacchi     case ECORE_NOMEM:
137*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_RESOURCE;
138*d14abf15SRobert Mustacchi         break;
139*d14abf15SRobert Mustacchi 
140*d14abf15SRobert Mustacchi     case ECORE_PENDING:
141*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_PENDING;
142*d14abf15SRobert Mustacchi         break;
143*d14abf15SRobert Mustacchi 
144*d14abf15SRobert Mustacchi     case ECORE_EXISTS:
145*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_EXISTING_OBJECT;
146*d14abf15SRobert Mustacchi         break;
147*d14abf15SRobert Mustacchi 
148*d14abf15SRobert Mustacchi     case ECORE_IO:
149*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_FAILURE;
150*d14abf15SRobert Mustacchi         break;
151*d14abf15SRobert Mustacchi 
152*d14abf15SRobert Mustacchi     default:
153*d14abf15SRobert Mustacchi         DbgBreakMsg("Unknwon ecore_status_t");
154*d14abf15SRobert Mustacchi         break;
155*d14abf15SRobert Mustacchi     }
156*d14abf15SRobert Mustacchi 
157*d14abf15SRobert Mustacchi     return lm_status;
158*d14abf15SRobert Mustacchi }
159*d14abf15SRobert Mustacchi 
lm_is_eq_completion(lm_device_t * pdev)160*d14abf15SRobert Mustacchi u8_t lm_is_eq_completion(lm_device_t *pdev)
161*d14abf15SRobert Mustacchi {
162*d14abf15SRobert Mustacchi     lm_eq_chain_t * eq_chain = NULL;
163*d14abf15SRobert Mustacchi     u8_t            result   = FALSE;
164*d14abf15SRobert Mustacchi 
165*d14abf15SRobert Mustacchi     DbgBreakIf(!pdev);
166*d14abf15SRobert Mustacchi     if (!pdev || IS_VFDEV(pdev))
167*d14abf15SRobert Mustacchi     {
168*d14abf15SRobert Mustacchi         return FALSE;
169*d14abf15SRobert Mustacchi     }
170*d14abf15SRobert Mustacchi 
171*d14abf15SRobert Mustacchi     eq_chain = &pdev->eq_info.eq_chain;
172*d14abf15SRobert Mustacchi     if ( eq_chain->hw_con_idx_ptr && (mm_le16_to_cpu(*eq_chain->hw_con_idx_ptr) != lm_bd_chain_cons_idx(&eq_chain->bd_chain)))
173*d14abf15SRobert Mustacchi     {
174*d14abf15SRobert Mustacchi         result = TRUE;
175*d14abf15SRobert Mustacchi     }
176*d14abf15SRobert Mustacchi 
177*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMeq, "lm_is_eq_completion: result is:%s\n", result? "TRUE" : "FALSE");
178*d14abf15SRobert Mustacchi 
179*d14abf15SRobert Mustacchi     return result;
180*d14abf15SRobert Mustacchi }
181*d14abf15SRobert Mustacchi 
182*d14abf15SRobert Mustacchi STATIC lm_status_t
lm_eth_init_client_init_general_data(IN lm_device_t * pdev,OUT struct client_init_general_data * general,IN const u8_t cid)183*d14abf15SRobert Mustacchi lm_eth_init_client_init_general_data(IN         lm_device_t                     *pdev,
184*d14abf15SRobert Mustacchi                                      OUT        struct client_init_general_data *general,
185*d14abf15SRobert Mustacchi                                      IN const   u8_t                            cid)
186*d14abf15SRobert Mustacchi {
187*d14abf15SRobert Mustacchi     const u8_t  stats_cnt_id  = LM_STATS_CNT_ID(pdev);
188*d14abf15SRobert Mustacchi     const u8_t  is_pfdev      = IS_PFDEV(pdev);
189*d14abf15SRobert Mustacchi     const u8_t  reg_cid        = (u8_t)lm_mp_get_reg_chain_from_chain(pdev,cid);
190*d14abf15SRobert Mustacchi     const u8_t  cos            = lm_mp_cos_from_chain(pdev, cid);
191*d14abf15SRobert Mustacchi     const u8_t  traffic_type  = LM_CHAIN_IDX_TRAFFIC_TYPE(pdev, cid);
192*d14abf15SRobert Mustacchi     lm_status_t lm_status     = LM_STATUS_SUCCESS;
193*d14abf15SRobert Mustacchi 
194*d14abf15SRobert Mustacchi     if( LLFC_DRIVER_TRAFFIC_TYPE_MAX == traffic_type)
195*d14abf15SRobert Mustacchi     {
196*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_eth_init_client_init_general_data failed ");
197*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
198*d14abf15SRobert Mustacchi     }
199*d14abf15SRobert Mustacchi 
200*d14abf15SRobert Mustacchi     /* General Structure */
201*d14abf15SRobert Mustacchi     general->activate_flg          = 1;
202*d14abf15SRobert Mustacchi     general->client_id             = LM_FW_CLI_ID(pdev, reg_cid);
203*d14abf15SRobert Mustacchi     general->is_fcoe_flg           = (cid == FCOE_CID(pdev))? TRUE : FALSE;
204*d14abf15SRobert Mustacchi     general->statistics_en_flg     = (is_pfdev || (stats_cnt_id != 0xFF))? TRUE : FALSE;
205*d14abf15SRobert Mustacchi     general->statistics_counter_id = (general->statistics_en_flg)? stats_cnt_id : DISABLE_STATISTIC_COUNTER_ID_VALUE;
206*d14abf15SRobert Mustacchi     general->sp_client_id          = LM_FW_CLI_ID(pdev, reg_cid);
207*d14abf15SRobert Mustacchi     general->mtu                   = mm_cpu_to_le16((u16_t)pdev->params.l2_cli_con_params[cid].mtu);
208*d14abf15SRobert Mustacchi     general->func_id               = FUNC_ID(pdev); /* FIXME: VFID needs to be given here for VFs... */
209*d14abf15SRobert Mustacchi     // Don't care data for Non cos clients
210*d14abf15SRobert Mustacchi     if(lm_chain_type_not_cos == lm_mp_get_chain_type(pdev,cid))
211*d14abf15SRobert Mustacchi     {
212*d14abf15SRobert Mustacchi         // FW requires a valid COS number
213*d14abf15SRobert Mustacchi         general->cos                   = 0;
214*d14abf15SRobert Mustacchi     }
215*d14abf15SRobert Mustacchi     else
216*d14abf15SRobert Mustacchi     {
217*d14abf15SRobert Mustacchi         general->cos                   = cos;//The connection cos, if applicable only if STATIC_COS is set
218*d14abf15SRobert Mustacchi     }
219*d14abf15SRobert Mustacchi     general->traffic_type          = traffic_type;
220*d14abf15SRobert Mustacchi 
221*d14abf15SRobert Mustacchi     /* TODO: using path_has_ovlan for finding if it is UFP/BD mode or not is correct?
222*d14abf15SRobert Mustacchi      * does this needs to be done even in lm_vf.c lm_vf_pf_acquire_msg
223*d14abf15SRobert Mustacchi      * function? Also how do we handle the check in lm_pf_vf_check_compatibility
224*d14abf15SRobert Mustacchi      */
225*d14abf15SRobert Mustacchi     if(IS_MF_SD_MODE(pdev) && (IS_SD_UFP_MODE(pdev) || IS_SD_BD_MODE(pdev)) && general->is_fcoe_flg)
226*d14abf15SRobert Mustacchi         general->fp_hsi_ver            = ETH_FP_HSI_VER_2;
227*d14abf15SRobert Mustacchi     else
228*d14abf15SRobert Mustacchi         general->fp_hsi_ver            = ETH_FP_HSI_VER_1; // default is v1 since only when conditions above are true HSI is v2
229*d14abf15SRobert Mustacchi 
230*d14abf15SRobert Mustacchi     return lm_status;
231*d14abf15SRobert Mustacchi }
232*d14abf15SRobert Mustacchi 
233*d14abf15SRobert Mustacchi STATIC void
lm_eth_init_client_init_rx_data(IN lm_device_t * pdev,OUT struct client_init_rx_data * rx,IN const u8_t cid,IN const u8_t sb_id)234*d14abf15SRobert Mustacchi lm_eth_init_client_init_rx_data(IN          lm_device_t                 *pdev,
235*d14abf15SRobert Mustacchi                                 OUT         struct client_init_rx_data  *rx,
236*d14abf15SRobert Mustacchi                                 IN const    u8_t                        cid,
237*d14abf15SRobert Mustacchi                                 IN const    u8_t                        sb_id)
238*d14abf15SRobert Mustacchi {
239*d14abf15SRobert Mustacchi     lm_bd_chain_t * rx_chain_sge  = NULL;
240*d14abf15SRobert Mustacchi     lm_bd_chain_t * rx_chain_bd   = NULL;
241*d14abf15SRobert Mustacchi     u8_t            rel_cid       = 0;
242*d14abf15SRobert Mustacchi 
243*d14abf15SRobert Mustacchi     DbgBreakIf(cid == FWD_CID(pdev));
244*d14abf15SRobert Mustacchi 
245*d14abf15SRobert Mustacchi     rx_chain_sge = LM_RXQ_SGE_PTR_IF_VALID(pdev, cid);
246*d14abf15SRobert Mustacchi     rx_chain_bd  = &LM_RXQ_CHAIN_BD(pdev, cid);
247*d14abf15SRobert Mustacchi 
248*d14abf15SRobert Mustacchi     rx->status_block_id               = LM_FW_SB_ID(pdev, sb_id);
249*d14abf15SRobert Mustacchi     // TPA is enabled in run time.(TPA is disabled in init time)
250*d14abf15SRobert Mustacchi     rx->tpa_en                        = 0;
251*d14abf15SRobert Mustacchi     rx->max_agg_size                  = mm_cpu_to_le16(0); /* TPA related only  */;
252*d14abf15SRobert Mustacchi     rx->max_tpa_queues                = 0;
253*d14abf15SRobert Mustacchi 
254*d14abf15SRobert Mustacchi     rx->extra_data_over_sgl_en_flg    = (cid == OOO_CID(pdev))? TRUE : FALSE;
255*d14abf15SRobert Mustacchi     rx->cache_line_alignment_log_size = (u8_t)LOG2(CACHE_LINE_SIZE/* TODO mm_get_cache_line_alignment()*/);
256*d14abf15SRobert Mustacchi     rx->enable_dynamic_hc             = (u8_t)pdev->params.enable_dynamic_hc[HC_INDEX_ETH_RX_CQ_CONS];
257*d14abf15SRobert Mustacchi 
258*d14abf15SRobert Mustacchi     rx->outer_vlan_removal_enable_flg = IS_MULTI_VNIC(pdev)? TRUE: FALSE;
259*d14abf15SRobert Mustacchi     if(OOO_CID(pdev) == cid)
260*d14abf15SRobert Mustacchi     {
261*d14abf15SRobert Mustacchi         rx->inner_vlan_removal_enable_flg = 0;
262*d14abf15SRobert Mustacchi     }
263*d14abf15SRobert Mustacchi     else
264*d14abf15SRobert Mustacchi     {
265*d14abf15SRobert Mustacchi         rx->inner_vlan_removal_enable_flg = !pdev->params.keep_vlan_tag;
266*d14abf15SRobert Mustacchi 
267*d14abf15SRobert Mustacchi         if(IS_MF_AFEX_MODE(pdev))
268*d14abf15SRobert Mustacchi         {
269*d14abf15SRobert Mustacchi             // In NIV we must remove default VLAN.
270*d14abf15SRobert Mustacchi             rx->silent_vlan_removal_flg         = 1;
271*d14abf15SRobert Mustacchi             rx->silent_vlan_value               = mm_cpu_to_le16(NIV_DEFAULT_VLAN(pdev));
272*d14abf15SRobert Mustacchi             rx->silent_vlan_mask                = mm_cpu_to_le16(ETHERNET_VLAN_ID_MASK);
273*d14abf15SRobert Mustacchi         }
274*d14abf15SRobert Mustacchi 
275*d14abf15SRobert Mustacchi     }
276*d14abf15SRobert Mustacchi 
277*d14abf15SRobert Mustacchi     rx->bd_page_base.lo= mm_cpu_to_le32(lm_bd_chain_phys_addr(rx_chain_bd, 0).as_u32.low);
278*d14abf15SRobert Mustacchi     rx->bd_page_base.hi= mm_cpu_to_le32(lm_bd_chain_phys_addr(rx_chain_bd, 0).as_u32.high);
279*d14abf15SRobert Mustacchi 
280*d14abf15SRobert Mustacchi     rx->cqe_page_base.lo = mm_cpu_to_le32(lm_bd_chain_phys_addr(&pdev->rx_info.rcq_chain[cid].bd_chain, 0).as_u32.low);
281*d14abf15SRobert Mustacchi     rx->cqe_page_base.hi = mm_cpu_to_le32(lm_bd_chain_phys_addr(&pdev->rx_info.rcq_chain[cid].bd_chain, 0).as_u32.high);
282*d14abf15SRobert Mustacchi 
283*d14abf15SRobert Mustacchi 
284*d14abf15SRobert Mustacchi     if (cid == LM_SW_LEADING_RSS_CID(pdev))
285*d14abf15SRobert Mustacchi     {
286*d14abf15SRobert Mustacchi         /* TODO: for now... doesn't have to be leading cid, anyone can get the approx mcast... */
287*d14abf15SRobert Mustacchi         rx->is_leading_rss = TRUE;
288*d14abf15SRobert Mustacchi         rx->is_approx_mcast = TRUE;
289*d14abf15SRobert Mustacchi     }
290*d14abf15SRobert Mustacchi 
291*d14abf15SRobert Mustacchi     rx->approx_mcast_engine_id = FUNC_ID(pdev); /* FIMXE (MichalS) */
292*d14abf15SRobert Mustacchi     rx->rss_engine_id          = FUNC_ID(pdev); /* FIMXE (MichalS) */
293*d14abf15SRobert Mustacchi 
294*d14abf15SRobert Mustacchi     if(rx_chain_sge)
295*d14abf15SRobert Mustacchi     {
296*d14abf15SRobert Mustacchi         /* override bd_buff_size if we are in LAH enabled mode */
297*d14abf15SRobert Mustacchi         rx->max_bytes_on_bd     = mm_cpu_to_le16((u16_t)pdev->params.l2_cli_con_params[cid].lah_size);
298*d14abf15SRobert Mustacchi         rx->vmqueue_mode_en_flg = TRUE;
299*d14abf15SRobert Mustacchi         rx->max_sges_for_packet = LM_MAX_SGES_FOR_PACKET;
300*d14abf15SRobert Mustacchi         rx->sge_buff_size       = mm_cpu_to_le16(MAX_L2_CLI_BUFFER_SIZE(pdev, cid) - (u16_t)pdev->params.l2_cli_con_params[cid].lah_size - (u16_t)pdev->params.rcv_buffer_offset - CACHE_LINE_SIZE);
301*d14abf15SRobert Mustacchi 
302*d14abf15SRobert Mustacchi         rx->sge_page_base.hi    = mm_cpu_to_le32(lm_bd_chain_phys_addr(rx_chain_sge, 0).as_u32.high);
303*d14abf15SRobert Mustacchi         rx->sge_page_base.lo    = mm_cpu_to_le32(lm_bd_chain_phys_addr(rx_chain_sge, 0).as_u32.low);
304*d14abf15SRobert Mustacchi     }
305*d14abf15SRobert Mustacchi     else
306*d14abf15SRobert Mustacchi     {
307*d14abf15SRobert Mustacchi         rx->max_bytes_on_bd     = mm_cpu_to_le16(MAX_L2_CLI_BUFFER_SIZE(pdev, cid) - (u16_t)pdev->params.rcv_buffer_offset - CACHE_LINE_SIZE);
308*d14abf15SRobert Mustacchi         rx->vmqueue_mode_en_flg = FALSE;
309*d14abf15SRobert Mustacchi         rx->max_sges_for_packet = 0;
310*d14abf15SRobert Mustacchi         rx->sge_buff_size       = 0;
311*d14abf15SRobert Mustacchi 
312*d14abf15SRobert Mustacchi         rx->sge_page_base.hi    = 0;
313*d14abf15SRobert Mustacchi         rx->sge_page_base.lo    = 0;
314*d14abf15SRobert Mustacchi     }
315*d14abf15SRobert Mustacchi 
316*d14abf15SRobert Mustacchi     if (cid == OOO_CID(pdev))
317*d14abf15SRobert Mustacchi     {
318*d14abf15SRobert Mustacchi         rel_cid = cid - LM_MAX_RSS_CHAINS(pdev);
319*d14abf15SRobert Mustacchi         rx->client_qzone_id = LM_FW_AUX_QZONE_ID(pdev, rel_cid);
320*d14abf15SRobert Mustacchi         rx->rx_sb_index_number = HC_SP_INDEX_ISCSI_OOO_RX_CONS;
321*d14abf15SRobert Mustacchi     }
322*d14abf15SRobert Mustacchi     else if (cid == ISCSI_CID(pdev))
323*d14abf15SRobert Mustacchi     {
324*d14abf15SRobert Mustacchi         rel_cid = cid - LM_MAX_RSS_CHAINS(pdev);
325*d14abf15SRobert Mustacchi         rx->client_qzone_id = LM_FW_AUX_QZONE_ID(pdev, rel_cid);
326*d14abf15SRobert Mustacchi         rx->rx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS;
327*d14abf15SRobert Mustacchi     }
328*d14abf15SRobert Mustacchi     else if (cid == FCOE_CID(pdev))
329*d14abf15SRobert Mustacchi     {
330*d14abf15SRobert Mustacchi         rel_cid = cid - LM_MAX_RSS_CHAINS(pdev);
331*d14abf15SRobert Mustacchi         rx->client_qzone_id = LM_FW_AUX_QZONE_ID(pdev, rel_cid);
332*d14abf15SRobert Mustacchi         rx->rx_sb_index_number = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS;
333*d14abf15SRobert Mustacchi     }
334*d14abf15SRobert Mustacchi     else if (cid < MAX_RX_CHAIN(pdev))
335*d14abf15SRobert Mustacchi     {
336*d14abf15SRobert Mustacchi         rx->client_qzone_id = LM_FW_DHC_QZONE_ID(pdev, sb_id);
337*d14abf15SRobert Mustacchi         rx->rx_sb_index_number = HC_INDEX_ETH_RX_CQ_CONS;
338*d14abf15SRobert Mustacchi     }
339*d14abf15SRobert Mustacchi     else
340*d14abf15SRobert Mustacchi     {
341*d14abf15SRobert Mustacchi         DbgMessage(NULL, FATAL, "Invalid cid 0x%x.\n", cid);
342*d14abf15SRobert Mustacchi         DbgBreakIf(1);
343*d14abf15SRobert Mustacchi     }
344*d14abf15SRobert Mustacchi 
345*d14abf15SRobert Mustacchi     // Avoiding rings thresholds verification is aimed for eVBD
346*d14abf15SRobert Mustacchi     // which receives its buffers and SGEs only after client init
347*d14abf15SRobert Mustacchi     // is completed.(eVBD receives the buffers and SGEs only after
348*d14abf15SRobert Mustacchi     // client setup is completed.)
349*d14abf15SRobert Mustacchi     rx->dont_verify_rings_pause_thr_flg = 1;
350*d14abf15SRobert Mustacchi 
351*d14abf15SRobert Mustacchi     /* FC */
352*d14abf15SRobert Mustacchi     if (pdev->params.l2_fw_flow_ctrl)
353*d14abf15SRobert Mustacchi     {
354*d14abf15SRobert Mustacchi         u16_t desired_cqe_bd_low_thresh;
355*d14abf15SRobert Mustacchi         u16_t desired_cqe_bd_high_thresh;
356*d14abf15SRobert Mustacchi         u16_t low_thresh;
357*d14abf15SRobert Mustacchi         u16_t high_thresh;
358*d14abf15SRobert Mustacchi         u16_t next_page_bds;
359*d14abf15SRobert Mustacchi 
360*d14abf15SRobert Mustacchi         next_page_bds = LM_RXQ_CHAIN_BD(pdev, cid).bds_skip_eop * LM_RXQ_CHAIN_BD(pdev, cid).page_cnt;
361*d14abf15SRobert Mustacchi         desired_cqe_bd_low_thresh = BRB_SIZE(pdev) + next_page_bds + FW_DROP_LEVEL(pdev);
362*d14abf15SRobert Mustacchi         desired_cqe_bd_high_thresh = desired_cqe_bd_low_thresh + DROPLESS_FC_HEADROOM;
363*d14abf15SRobert Mustacchi 
364*d14abf15SRobert Mustacchi         low_thresh  = mm_cpu_to_le16(min(desired_cqe_bd_low_thresh,  (u16_t)((LM_RXQ(pdev, cid).common.desc_cnt)/4)));
365*d14abf15SRobert Mustacchi         high_thresh = mm_cpu_to_le16(min(desired_cqe_bd_high_thresh, (u16_t)((LM_RXQ(pdev, cid).common.desc_cnt)/2)));
366*d14abf15SRobert Mustacchi 
367*d14abf15SRobert Mustacchi         rx->cqe_pause_thr_low  = low_thresh;
368*d14abf15SRobert Mustacchi         rx->bd_pause_thr_low   = low_thresh;
369*d14abf15SRobert Mustacchi         rx->sge_pause_thr_low  = 0;
370*d14abf15SRobert Mustacchi         rx->rx_cos_mask        = 1;
371*d14abf15SRobert Mustacchi         rx->cqe_pause_thr_high = high_thresh;
372*d14abf15SRobert Mustacchi         rx->bd_pause_thr_high  = high_thresh;
373*d14abf15SRobert Mustacchi         rx->sge_pause_thr_high = 0;
374*d14abf15SRobert Mustacchi     }
375*d14abf15SRobert Mustacchi }
376*d14abf15SRobert Mustacchi 
377*d14abf15SRobert Mustacchi STATIC void
lm_eth_init_client_init_tx_data(IN lm_device_t * pdev,OUT struct client_init_tx_data * tx,IN const u8_t cid,IN const u8_t sb_id)378*d14abf15SRobert Mustacchi lm_eth_init_client_init_tx_data(IN          lm_device_t                 *pdev,
379*d14abf15SRobert Mustacchi                                 OUT         struct client_init_tx_data  *tx,
380*d14abf15SRobert Mustacchi                                 IN const    u8_t                        cid,
381*d14abf15SRobert Mustacchi                                 IN const    u8_t                        sb_id)
382*d14abf15SRobert Mustacchi {
383*d14abf15SRobert Mustacchi 
384*d14abf15SRobert Mustacchi     /* Status block index init we do for Rx + Tx together so that we ask which cid we are only once */
385*d14abf15SRobert Mustacchi     if (cid == FWD_CID(pdev))
386*d14abf15SRobert Mustacchi     {
387*d14abf15SRobert Mustacchi         tx->tx_sb_index_number = HC_SP_INDEX_ETH_FW_TX_CQ_CONS;
388*d14abf15SRobert Mustacchi     }
389*d14abf15SRobert Mustacchi     else if (cid == OOO_CID(pdev))
390*d14abf15SRobert Mustacchi     {
391*d14abf15SRobert Mustacchi         // OOO CID doesn't really has a TX client this is don't
392*d14abf15SRobert Mustacchi         // care data for FW.
393*d14abf15SRobert Mustacchi         tx->tx_sb_index_number = HC_SP_INDEX_NOT_USED; /* D/C */
394*d14abf15SRobert Mustacchi     }
395*d14abf15SRobert Mustacchi     else if (cid == ISCSI_CID(pdev))
396*d14abf15SRobert Mustacchi     {
397*d14abf15SRobert Mustacchi         tx->tx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_CQ_CONS;
398*d14abf15SRobert Mustacchi     }
399*d14abf15SRobert Mustacchi     else if (cid == FCOE_CID(pdev))
400*d14abf15SRobert Mustacchi     {
401*d14abf15SRobert Mustacchi         tx->tx_sb_index_number = HC_SP_INDEX_ETH_FCOE_CQ_CONS;
402*d14abf15SRobert Mustacchi 
403*d14abf15SRobert Mustacchi         if (IS_MF_AFEX_MODE(pdev))
404*d14abf15SRobert Mustacchi         {
405*d14abf15SRobert Mustacchi             tx->force_default_pri_flg = TRUE;
406*d14abf15SRobert Mustacchi         }
407*d14abf15SRobert Mustacchi     }
408*d14abf15SRobert Mustacchi     else if (lm_chain_type_not_cos != lm_mp_get_chain_type(pdev, cid))
409*d14abf15SRobert Mustacchi     {
410*d14abf15SRobert Mustacchi         // This isn't realy cid it is the chain index
411*d14abf15SRobert Mustacchi         tx->tx_sb_index_number = lm_eth_tx_hc_cq_cons_cosx_from_chain(pdev, cid);
412*d14abf15SRobert Mustacchi     }
413*d14abf15SRobert Mustacchi     else
414*d14abf15SRobert Mustacchi     {
415*d14abf15SRobert Mustacchi         DbgMessage(NULL, FATAL, "Invalid cid 0x%x.\n", cid);
416*d14abf15SRobert Mustacchi         DbgBreakIf(1);
417*d14abf15SRobert Mustacchi     }
418*d14abf15SRobert Mustacchi 
419*d14abf15SRobert Mustacchi     /* TX Data (remaining , sb index above...)  */
420*d14abf15SRobert Mustacchi     /* ooo cid doesn't have a tx chain... */
421*d14abf15SRobert Mustacchi     if (cid != OOO_CID(pdev))
422*d14abf15SRobert Mustacchi     {
423*d14abf15SRobert Mustacchi         tx->tx_bd_page_base.hi = mm_cpu_to_le32(lm_bd_chain_phys_addr(&pdev->tx_info.chain[cid].bd_chain, 0).as_u32.high);
424*d14abf15SRobert Mustacchi         tx->tx_bd_page_base.lo = mm_cpu_to_le32(lm_bd_chain_phys_addr(&pdev->tx_info.chain[cid].bd_chain, 0).as_u32.low);
425*d14abf15SRobert Mustacchi     }
426*d14abf15SRobert Mustacchi     tx->tx_status_block_id = LM_FW_SB_ID(pdev, sb_id);
427*d14abf15SRobert Mustacchi     tx->enforce_security_flg = FALSE; /* TBD: turn on for KVM VF? */
428*d14abf15SRobert Mustacchi 
429*d14abf15SRobert Mustacchi     /* Tx Switching... */
430*d14abf15SRobert Mustacchi     if (IS_MF_SI_MODE(pdev) && pdev->params.npar_vm_switching_enable &&
431*d14abf15SRobert Mustacchi         (cid != FWD_CID(pdev)) && (cid != FCOE_CID(pdev)) && (cid != ISCSI_CID(pdev)))
432*d14abf15SRobert Mustacchi     {
433*d14abf15SRobert Mustacchi         tx->tx_switching_flg = TRUE;
434*d14abf15SRobert Mustacchi     }
435*d14abf15SRobert Mustacchi     else
436*d14abf15SRobert Mustacchi     {
437*d14abf15SRobert Mustacchi         tx->tx_switching_flg = FALSE;
438*d14abf15SRobert Mustacchi     }
439*d14abf15SRobert Mustacchi 
440*d14abf15SRobert Mustacchi     tx->tss_leading_client_id = LM_FW_CLI_ID(pdev, LM_SW_LEADING_RSS_CID(pdev));
441*d14abf15SRobert Mustacchi 
442*d14abf15SRobert Mustacchi     tx->refuse_outband_vlan_flg = 0;
443*d14abf15SRobert Mustacchi 
444*d14abf15SRobert Mustacchi 
445*d14abf15SRobert Mustacchi     // for encapsulated packets
446*d14abf15SRobert Mustacchi     // the hw ip header will be the inner ip header, the hw will incremnet the inner ip id.
447*d14abf15SRobert Mustacchi     // the fw ip header will be the outer ip header, this means that if the outer ip header is ipv4, its ip id will not be incremented.
448*d14abf15SRobert Mustacchi     tx->tunnel_lso_inc_ip_id = INT_HEADER;
449*d14abf15SRobert Mustacchi     // In case of non-Lso encapsulated packets with L4 checksum offload, the pseudo checksum location - on BD
450*d14abf15SRobert Mustacchi     tx->tunnel_non_lso_pcsum_location = CSUM_ON_BD;
451*d14abf15SRobert Mustacchi     // In case of non-Lso encapsulated packets with outer L3 ip checksum offload, the pseudo checksum location - on BD
452*d14abf15SRobert Mustacchi     tx->tunnel_non_lso_outer_ip_csum_location = CSUM_ON_BD;
453*d14abf15SRobert Mustacchi }
454*d14abf15SRobert Mustacchi 
lm_get_sw_client_idx_from_cid(lm_device_t * pdev,u32_t cid)455*d14abf15SRobert Mustacchi u32_t lm_get_sw_client_idx_from_cid(lm_device_t * pdev,
456*d14abf15SRobert Mustacchi                                     u32_t         cid)
457*d14abf15SRobert Mustacchi {
458*d14abf15SRobert Mustacchi 
459*d14abf15SRobert Mustacchi     u32_t client_info_idx;
460*d14abf15SRobert Mustacchi 
461*d14abf15SRobert Mustacchi     /* If MP is enabled, we need to take care of tx-only connections, which use the
462*d14abf15SRobert Mustacchi      * regular connection client-idx... the rest are split into regular eth
463*d14abf15SRobert Mustacchi      * and vfs... */
464*d14abf15SRobert Mustacchi     if (MM_DCB_MP_L2_IS_ENABLE(pdev))
465*d14abf15SRobert Mustacchi     {
466*d14abf15SRobert Mustacchi         if (lm_chain_type_cos_tx_only == lm_mp_get_chain_type(pdev, cid))
467*d14abf15SRobert Mustacchi         {
468*d14abf15SRobert Mustacchi             client_info_idx = lm_mp_get_reg_chain_from_chain(pdev,cid);
469*d14abf15SRobert Mustacchi             return client_info_idx;
470*d14abf15SRobert Mustacchi         }
471*d14abf15SRobert Mustacchi     }
472*d14abf15SRobert Mustacchi 
473*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
474*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev))
475*d14abf15SRobert Mustacchi     {
476*d14abf15SRobert Mustacchi         client_info_idx = lm_pf_get_sw_client_idx_from_cid(pdev, cid);
477*d14abf15SRobert Mustacchi     }
478*d14abf15SRobert Mustacchi     else
479*d14abf15SRobert Mustacchi #endif
480*d14abf15SRobert Mustacchi     {
481*d14abf15SRobert Mustacchi         client_info_idx = cid;
482*d14abf15SRobert Mustacchi     }
483*d14abf15SRobert Mustacchi 
484*d14abf15SRobert Mustacchi     return client_info_idx;
485*d14abf15SRobert Mustacchi }
486*d14abf15SRobert Mustacchi 
lm_get_fw_client_idx_from_cid(lm_device_t * pdev,u32_t cid)487*d14abf15SRobert Mustacchi u32_t lm_get_fw_client_idx_from_cid(lm_device_t * pdev,
488*d14abf15SRobert Mustacchi                                     u32_t         cid)
489*d14abf15SRobert Mustacchi {
490*d14abf15SRobert Mustacchi     u32_t client_info_idx;
491*d14abf15SRobert Mustacchi     u32_t fw_client_id;
492*d14abf15SRobert Mustacchi 
493*d14abf15SRobert Mustacchi     /* If MP is enabled, we need to take care of tx-only connections, which use the
494*d14abf15SRobert Mustacchi      * regular connection client-idx... the rest are split into regular eth
495*d14abf15SRobert Mustacchi      * and vfs... */
496*d14abf15SRobert Mustacchi     if (MM_DCB_MP_L2_IS_ENABLE(pdev))
497*d14abf15SRobert Mustacchi     {
498*d14abf15SRobert Mustacchi         if (lm_chain_type_cos_tx_only == lm_mp_get_chain_type(pdev, cid))
499*d14abf15SRobert Mustacchi         {
500*d14abf15SRobert Mustacchi             client_info_idx = lm_mp_get_reg_chain_from_chain(pdev,cid);
501*d14abf15SRobert Mustacchi             return LM_FW_CLI_ID(pdev, client_info_idx);
502*d14abf15SRobert Mustacchi         }
503*d14abf15SRobert Mustacchi     }
504*d14abf15SRobert Mustacchi 
505*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
506*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev))
507*d14abf15SRobert Mustacchi     {
508*d14abf15SRobert Mustacchi         fw_client_id = lm_pf_get_fw_client_idx_from_cid(pdev, cid);
509*d14abf15SRobert Mustacchi     }
510*d14abf15SRobert Mustacchi     else
511*d14abf15SRobert Mustacchi #endif
512*d14abf15SRobert Mustacchi     {
513*d14abf15SRobert Mustacchi         fw_client_id = LM_FW_CLI_ID(pdev, cid);
514*d14abf15SRobert Mustacchi     }
515*d14abf15SRobert Mustacchi 
516*d14abf15SRobert Mustacchi     return fw_client_id;
517*d14abf15SRobert Mustacchi }
518*d14abf15SRobert Mustacchi 
519*d14abf15SRobert Mustacchi STATIC lm_status_t
lm_eth_init_tx_queue_data(IN lm_device_t * pdev,IN const u8_t chain_id,IN const u8_t sb_id)520*d14abf15SRobert Mustacchi lm_eth_init_tx_queue_data(IN       lm_device_t * pdev,
521*d14abf15SRobert Mustacchi                           IN const u8_t          chain_id,
522*d14abf15SRobert Mustacchi                           IN const u8_t          sb_id)
523*d14abf15SRobert Mustacchi {
524*d14abf15SRobert Mustacchi     struct tx_queue_init_ramrod_data * tx_queue_init_data_virt = NULL;
525*d14abf15SRobert Mustacchi     u32_t                              client_info_idx         = 0;
526*d14abf15SRobert Mustacchi     lm_status_t                        lm_status               = LM_STATUS_SUCCESS;
527*d14abf15SRobert Mustacchi     u8_t                               cid                     = 0;
528*d14abf15SRobert Mustacchi 
529*d14abf15SRobert Mustacchi     if((lm_chain_type_cos_tx_only != lm_mp_get_chain_type(pdev,chain_id)) &&
530*d14abf15SRobert Mustacchi        (chain_id != FWD_CID(pdev)))
531*d14abf15SRobert Mustacchi     {
532*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_eth_init_tx_queue_data: the chain isn't TX only " );
533*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
534*d14abf15SRobert Mustacchi     }
535*d14abf15SRobert Mustacchi 
536*d14abf15SRobert Mustacchi     /* a bit redundant, but just so we're clear on terminology... */
537*d14abf15SRobert Mustacchi     cid = chain_id;
538*d14abf15SRobert Mustacchi 
539*d14abf15SRobert Mustacchi     /* Since ramrods are sent sequentially for tx only clients, and then regular client, and
540*d14abf15SRobert Mustacchi      * we won't have a case of these being sent in parallel, we can safely use the client_init_data_virt
541*d14abf15SRobert Mustacchi      * of the regular eth connection for the tx only connection.
542*d14abf15SRobert Mustacchi      * This way, we don't need to allocate client_info for tx only connections.
543*d14abf15SRobert Mustacchi      */
544*d14abf15SRobert Mustacchi     client_info_idx = lm_get_sw_client_idx_from_cid(pdev, cid);
545*d14abf15SRobert Mustacchi 
546*d14abf15SRobert Mustacchi     tx_queue_init_data_virt = &(pdev->client_info[client_info_idx].client_init_data_virt->tx_queue);
547*d14abf15SRobert Mustacchi 
548*d14abf15SRobert Mustacchi     if CHK_NULL(tx_queue_init_data_virt)
549*d14abf15SRobert Mustacchi     {
550*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
551*d14abf15SRobert Mustacchi     }
552*d14abf15SRobert Mustacchi 
553*d14abf15SRobert Mustacchi     mm_mem_zero(tx_queue_init_data_virt , sizeof(struct tx_queue_init_ramrod_data));
554*d14abf15SRobert Mustacchi 
555*d14abf15SRobert Mustacchi     /* General Structure */
556*d14abf15SRobert Mustacchi     lm_status = lm_eth_init_client_init_general_data(pdev,
557*d14abf15SRobert Mustacchi                                                      &(tx_queue_init_data_virt->general),
558*d14abf15SRobert Mustacchi                                                      chain_id);
559*d14abf15SRobert Mustacchi 
560*d14abf15SRobert Mustacchi     if(LM_STATUS_SUCCESS != lm_status)
561*d14abf15SRobert Mustacchi     {
562*d14abf15SRobert Mustacchi         return lm_status;
563*d14abf15SRobert Mustacchi     }
564*d14abf15SRobert Mustacchi 
565*d14abf15SRobert Mustacchi     /* Tx Data */
566*d14abf15SRobert Mustacchi     lm_eth_init_client_init_tx_data(pdev,
567*d14abf15SRobert Mustacchi                                     &(tx_queue_init_data_virt->tx),
568*d14abf15SRobert Mustacchi                                     chain_id,
569*d14abf15SRobert Mustacchi                                     sb_id);
570*d14abf15SRobert Mustacchi 
571*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
572*d14abf15SRobert Mustacchi }
573*d14abf15SRobert Mustacchi 
lm_eth_init_client_init_data(lm_device_t * pdev,u8_t cid,u8_t sb_id)574*d14abf15SRobert Mustacchi lm_status_t lm_eth_init_client_init_data(lm_device_t *pdev, u8_t cid, u8_t sb_id)
575*d14abf15SRobert Mustacchi {
576*d14abf15SRobert Mustacchi     struct client_init_ramrod_data * client_init_data_virt = NULL;
577*d14abf15SRobert Mustacchi     lm_status_t                      lm_status             = LM_STATUS_SUCCESS;
578*d14abf15SRobert Mustacchi     const u32_t                      client_info_idx       = lm_get_sw_client_idx_from_cid(pdev, cid);
579*d14abf15SRobert Mustacchi 
580*d14abf15SRobert Mustacchi 
581*d14abf15SRobert Mustacchi     if (client_info_idx >= ARRSIZE(pdev->client_info))
582*d14abf15SRobert Mustacchi     {
583*d14abf15SRobert Mustacchi         DbgBreakIf(client_info_idx >= ARRSIZE(pdev->client_info));
584*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
585*d14abf15SRobert Mustacchi     }
586*d14abf15SRobert Mustacchi 
587*d14abf15SRobert Mustacchi     client_init_data_virt = &(pdev->client_info[client_info_idx].client_init_data_virt->init_data);
588*d14abf15SRobert Mustacchi 
589*d14abf15SRobert Mustacchi     if CHK_NULL(client_init_data_virt)
590*d14abf15SRobert Mustacchi     {
591*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
592*d14abf15SRobert Mustacchi     }
593*d14abf15SRobert Mustacchi 
594*d14abf15SRobert Mustacchi     mm_mem_zero(client_init_data_virt , sizeof(struct client_init_ramrod_data));
595*d14abf15SRobert Mustacchi 
596*d14abf15SRobert Mustacchi     /* General Structure */
597*d14abf15SRobert Mustacchi     lm_status = lm_eth_init_client_init_general_data(pdev,
598*d14abf15SRobert Mustacchi                                          &(client_init_data_virt->general),
599*d14abf15SRobert Mustacchi                                          cid);
600*d14abf15SRobert Mustacchi     if(LM_STATUS_SUCCESS != lm_status)
601*d14abf15SRobert Mustacchi     {
602*d14abf15SRobert Mustacchi         return lm_status;
603*d14abf15SRobert Mustacchi     }
604*d14abf15SRobert Mustacchi 
605*d14abf15SRobert Mustacchi     /* Rx Data */
606*d14abf15SRobert Mustacchi     lm_eth_init_client_init_rx_data(pdev,
607*d14abf15SRobert Mustacchi                                     &(client_init_data_virt->rx),
608*d14abf15SRobert Mustacchi                                     cid,
609*d14abf15SRobert Mustacchi                                     sb_id);
610*d14abf15SRobert Mustacchi 
611*d14abf15SRobert Mustacchi     /* Tx Data */
612*d14abf15SRobert Mustacchi     lm_eth_init_client_init_tx_data(pdev,
613*d14abf15SRobert Mustacchi                                     &(client_init_data_virt->tx),
614*d14abf15SRobert Mustacchi                                     cid,
615*d14abf15SRobert Mustacchi                                     sb_id);
616*d14abf15SRobert Mustacchi 
617*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
618*d14abf15SRobert Mustacchi }
619*d14abf15SRobert Mustacchi 
620*d14abf15SRobert Mustacchi /**
621*d14abf15SRobert Mustacchi 
622*d14abf15SRobert Mustacchi  * @assumptions: STRONG ASSUMPTION: This function is not
623*d14abf15SRobert Mustacchi  *             called for SRIOV / MP connections...
624*d14abf15SRobert Mustacchi  */
lm_update_eth_client(IN struct _lm_device_t * pdev,IN const u8_t client_idx,IN const u16_t silent_vlan_value,IN const u16_t silent_vlan_mask,IN const u8_t silent_vlan_removal_flg,IN const u8_t silent_vlan_change_flg)625*d14abf15SRobert Mustacchi lm_status_t lm_update_eth_client(IN struct _lm_device_t    *pdev,
626*d14abf15SRobert Mustacchi                                  IN const u8_t             client_idx,
627*d14abf15SRobert Mustacchi                                  IN const u16_t            silent_vlan_value,
628*d14abf15SRobert Mustacchi                                  IN const u16_t            silent_vlan_mask,
629*d14abf15SRobert Mustacchi                                  IN const u8_t             silent_vlan_removal_flg,
630*d14abf15SRobert Mustacchi                                  IN const u8_t             silent_vlan_change_flg
631*d14abf15SRobert Mustacchi                                  )
632*d14abf15SRobert Mustacchi {
633*d14abf15SRobert Mustacchi     struct client_update_ramrod_data * client_update_data_virt = pdev->client_info[client_idx].update.data_virt;
634*d14abf15SRobert Mustacchi     lm_status_t                        lm_status               = LM_STATUS_FAILURE;
635*d14abf15SRobert Mustacchi     u32_t                              con_state               = 0;
636*d14abf15SRobert Mustacchi     const u32_t                        cid                     = client_idx; //lm_get_cid_from_sw_client_idx(pdev);
637*d14abf15SRobert Mustacchi 
638*d14abf15SRobert Mustacchi     if CHK_NULL(client_update_data_virt)
639*d14abf15SRobert Mustacchi     {
640*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
641*d14abf15SRobert Mustacchi     }
642*d14abf15SRobert Mustacchi 
643*d14abf15SRobert Mustacchi     mm_mem_zero(client_update_data_virt , sizeof(struct client_update_ramrod_data));
644*d14abf15SRobert Mustacchi 
645*d14abf15SRobert Mustacchi     MM_ACQUIRE_ETH_CON_LOCK(pdev);
646*d14abf15SRobert Mustacchi 
647*d14abf15SRobert Mustacchi     // We will send a client update ramrod in any case we can we don't optimize this flow.
648*d14abf15SRobert Mustacchi     // Client setup may already took the correct NIV value but the ramrod will be sent anyway
649*d14abf15SRobert Mustacchi     con_state = lm_get_con_state(pdev, cid);
650*d14abf15SRobert Mustacchi     if((LM_CON_STATE_OPEN != con_state) &&
651*d14abf15SRobert Mustacchi         (LM_CON_STATE_OPEN_SENT != con_state))
652*d14abf15SRobert Mustacchi     {
653*d14abf15SRobert Mustacchi         // Clinet is not in a state that it can recieve the ramrod
654*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
655*d14abf15SRobert Mustacchi         return LM_STATUS_ABORTED;
656*d14abf15SRobert Mustacchi     }
657*d14abf15SRobert Mustacchi 
658*d14abf15SRobert Mustacchi     /* We don't expect this function to be called for non eth regular connections.
659*d14abf15SRobert Mustacchi      * If we hit this assert it means we need support for SRIOV +  AFEX
660*d14abf15SRobert Mustacchi      */
661*d14abf15SRobert Mustacchi     if (cid >= MAX_RX_CHAIN(pdev))
662*d14abf15SRobert Mustacchi     {
663*d14abf15SRobert Mustacchi         DbgBreakIf(cid >= MAX_RX_CHAIN(pdev));
664*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
665*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
666*d14abf15SRobert Mustacchi     }
667*d14abf15SRobert Mustacchi 
668*d14abf15SRobert Mustacchi     DbgBreakIf( LM_CLI_UPDATE_NOT_USED != pdev->client_info[client_idx].update.state);
669*d14abf15SRobert Mustacchi 
670*d14abf15SRobert Mustacchi     pdev->client_info[client_idx].update.state = LM_CLI_UPDATE_USED;
671*d14abf15SRobert Mustacchi 
672*d14abf15SRobert Mustacchi     client_update_data_virt->client_id  = LM_FW_CLI_ID(pdev, client_idx);
673*d14abf15SRobert Mustacchi     client_update_data_virt->func_id    = FUNC_ID(pdev); /* FIXME: VFID needs to be given here for VFs... */
674*d14abf15SRobert Mustacchi 
675*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_value          = mm_cpu_to_le16(silent_vlan_value);
676*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_mask           = mm_cpu_to_le16(silent_vlan_mask);
677*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_removal_flg    = silent_vlan_removal_flg;
678*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_change_flg     = silent_vlan_change_flg;
679*d14abf15SRobert Mustacchi 
680*d14abf15SRobert Mustacchi     client_update_data_virt->refuse_outband_vlan_flg        = 0;
681*d14abf15SRobert Mustacchi     client_update_data_virt->refuse_outband_vlan_change_flg = 0;
682*d14abf15SRobert Mustacchi 
683*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
684*d14abf15SRobert Mustacchi                            cid,
685*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_ETH_CLIENT_UPDATE,
686*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
687*d14abf15SRobert Mustacchi                            ETH_CONNECTION_TYPE,
688*d14abf15SRobert Mustacchi                            pdev->client_info[client_idx].update.data_phys.as_u64);
689*d14abf15SRobert Mustacchi 
690*d14abf15SRobert Mustacchi     MM_RELEASE_ETH_CON_LOCK(pdev);
691*d14abf15SRobert Mustacchi 
692*d14abf15SRobert Mustacchi 
693*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
694*d14abf15SRobert Mustacchi     {
695*d14abf15SRobert Mustacchi         return lm_status;
696*d14abf15SRobert Mustacchi     }
697*d14abf15SRobert Mustacchi 
698*d14abf15SRobert Mustacchi     lm_status = lm_wait_state_change(pdev, &pdev->client_info[client_idx].update.state, LM_CLI_UPDATE_RECV);
699*d14abf15SRobert Mustacchi 
700*d14abf15SRobert Mustacchi     pdev->client_info[client_idx].update.state = LM_CLI_UPDATE_NOT_USED;
701*d14abf15SRobert Mustacchi 
702*d14abf15SRobert Mustacchi     return lm_status;
703*d14abf15SRobert Mustacchi }
704*d14abf15SRobert Mustacchi 
lm_establish_eth_con(struct _lm_device_t * pdev,u8_t const chain_idx,u8_t sb_id,u8_t attributes_bitmap)705*d14abf15SRobert Mustacchi lm_status_t lm_establish_eth_con(struct _lm_device_t *pdev, u8_t const chain_idx, u8_t sb_id, u8_t attributes_bitmap)
706*d14abf15SRobert Mustacchi {
707*d14abf15SRobert Mustacchi     lm_status_t     lm_status       = LM_STATUS_SUCCESS;
708*d14abf15SRobert Mustacchi     u8_t            cmd_id          = 0;
709*d14abf15SRobert Mustacchi     u8_t            type            = 0;
710*d14abf15SRobert Mustacchi     lm_rcq_chain_t* rcq_chain       = NULL;
711*d14abf15SRobert Mustacchi     const u8_t      cid             = chain_idx; /* redundant, but here for terminology sake... */
712*d14abf15SRobert Mustacchi     u32_t           client_info_idx = 0;
713*d14abf15SRobert Mustacchi 
714*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMi|INFORMl2sp, "#lm_establish_eth_con, cid=%d\n",cid);
715*d14abf15SRobert Mustacchi 
716*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
717*d14abf15SRobert Mustacchi     {
718*d14abf15SRobert Mustacchi         MM_ACQUIRE_ETH_CON_LOCK(pdev);
719*d14abf15SRobert Mustacchi     }
720*d14abf15SRobert Mustacchi 
721*d14abf15SRobert Mustacchi     lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
722*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
723*d14abf15SRobert Mustacchi     {
724*d14abf15SRobert Mustacchi         /* TODO: VF??? */
725*d14abf15SRobert Mustacchi         if( LM_CLIENT_ATTRIBUTES_REG_CLI == GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_REG_CLI ))
726*d14abf15SRobert Mustacchi         {
727*d14abf15SRobert Mustacchi             // Regular client or OOO CID
728*d14abf15SRobert Mustacchi             DbgBreakIf( LM_CLIENT_ATTRIBUTES_RX != GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_RX ));
729*d14abf15SRobert Mustacchi             lm_status = lm_eth_init_client_init_data(pdev, cid, sb_id);
730*d14abf15SRobert Mustacchi         }
731*d14abf15SRobert Mustacchi         else
732*d14abf15SRobert Mustacchi         {
733*d14abf15SRobert Mustacchi             // TX only client or FWD
734*d14abf15SRobert Mustacchi             DbgBreakIf( LM_CLIENT_ATTRIBUTES_RX == GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_RX ));
735*d14abf15SRobert Mustacchi             lm_status = lm_eth_init_tx_queue_data(pdev, cid, sb_id);
736*d14abf15SRobert Mustacchi         }
737*d14abf15SRobert Mustacchi 
738*d14abf15SRobert Mustacchi         if(LM_STATUS_SUCCESS != lm_status)
739*d14abf15SRobert Mustacchi         {
740*d14abf15SRobert Mustacchi             DbgBreakMsg("lm_establish_eth_con: lm_eth_init_client_init_data or lm_eth_init_tx_queue_data failed \n ");
741*d14abf15SRobert Mustacchi             if (IS_PFDEV(pdev))
742*d14abf15SRobert Mustacchi             {
743*d14abf15SRobert Mustacchi                 MM_RELEASE_ETH_CON_LOCK(pdev);
744*d14abf15SRobert Mustacchi             }
745*d14abf15SRobert Mustacchi             return lm_status;
746*d14abf15SRobert Mustacchi         }
747*d14abf15SRobert Mustacchi 
748*d14abf15SRobert Mustacchi         lm_init_connection_context(pdev, cid, sb_id);
749*d14abf15SRobert Mustacchi     }
750*d14abf15SRobert Mustacchi 
751*d14abf15SRobert Mustacchi     /* When we setup the RCQ ring we should advance the CQ cons by MAX_NUM_RAMRODS - the FWD CID is the only connection without an RCQ
752*d14abf15SRobert Mustacchi      * therefore we skip this operation for forward */
753*d14abf15SRobert Mustacchi     if( LM_CLIENT_ATTRIBUTES_REG_CLI == GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_REG_CLI ))
754*d14abf15SRobert Mustacchi     {
755*d14abf15SRobert Mustacchi         DbgBreakIf( LM_CLIENT_ATTRIBUTES_RX != GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_RX ));
756*d14abf15SRobert Mustacchi         cmd_id = RAMROD_CMD_ID_ETH_CLIENT_SETUP;
757*d14abf15SRobert Mustacchi         rcq_chain = &LM_RCQ(pdev, cid);
758*d14abf15SRobert Mustacchi         if (IS_PFDEV(pdev))
759*d14abf15SRobert Mustacchi         {
760*d14abf15SRobert Mustacchi             lm_bd_chain_bds_produced(&rcq_chain->bd_chain, ETH_MIN_RX_CQES_WITH_TPA_E1H_E2);
761*d14abf15SRobert Mustacchi         }
762*d14abf15SRobert Mustacchi     }
763*d14abf15SRobert Mustacchi     else
764*d14abf15SRobert Mustacchi     {
765*d14abf15SRobert Mustacchi         DbgBreakIf( LM_CLIENT_ATTRIBUTES_RX == GET_FLAGS(attributes_bitmap,LM_CLIENT_ATTRIBUTES_RX ));
766*d14abf15SRobert Mustacchi         if (cid == FWD_CID(pdev))
767*d14abf15SRobert Mustacchi         {
768*d14abf15SRobert Mustacchi             cmd_id = RAMROD_CMD_ID_ETH_FORWARD_SETUP;
769*d14abf15SRobert Mustacchi         }
770*d14abf15SRobert Mustacchi         else if(lm_chain_type_cos_tx_only == lm_mp_get_chain_type(pdev,cid))
771*d14abf15SRobert Mustacchi         {
772*d14abf15SRobert Mustacchi             cmd_id = RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP;
773*d14abf15SRobert Mustacchi         }
774*d14abf15SRobert Mustacchi         else
775*d14abf15SRobert Mustacchi         {
776*d14abf15SRobert Mustacchi             DbgBreakMsg(" lm_establish_eth_con: cmd_id not set ");
777*d14abf15SRobert Mustacchi             if (IS_PFDEV(pdev))
778*d14abf15SRobert Mustacchi             {
779*d14abf15SRobert Mustacchi                 MM_RELEASE_ETH_CON_LOCK(pdev);
780*d14abf15SRobert Mustacchi             }
781*d14abf15SRobert Mustacchi             return LM_STATUS_FAILURE;
782*d14abf15SRobert Mustacchi         }
783*d14abf15SRobert Mustacchi     }
784*d14abf15SRobert Mustacchi 
785*d14abf15SRobert Mustacchi     // Move to state ramrod sent must be done before ramrod is realy sent
786*d14abf15SRobert Mustacchi     lm_set_con_state(pdev, cid, LM_CON_STATE_OPEN_SENT);
787*d14abf15SRobert Mustacchi 
788*d14abf15SRobert Mustacchi     client_info_idx = lm_get_sw_client_idx_from_cid(pdev, cid);
789*d14abf15SRobert Mustacchi 
790*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
791*d14abf15SRobert Mustacchi     {
792*d14abf15SRobert Mustacchi         lm_status = lm_sq_post(pdev,
793*d14abf15SRobert Mustacchi                                cid,
794*d14abf15SRobert Mustacchi                                cmd_id,
795*d14abf15SRobert Mustacchi                                CMD_PRIORITY_MEDIUM,
796*d14abf15SRobert Mustacchi                                type,
797*d14abf15SRobert Mustacchi                                pdev->client_info[client_info_idx].client_init_data_phys.as_u64);
798*d14abf15SRobert Mustacchi     }
799*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
800*d14abf15SRobert Mustacchi     else
801*d14abf15SRobert Mustacchi     {
802*d14abf15SRobert Mustacchi         lm_status = lm_vf_queue_init(pdev, cid);
803*d14abf15SRobert Mustacchi     }
804*d14abf15SRobert Mustacchi #endif
805*d14abf15SRobert Mustacchi 
806*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
807*d14abf15SRobert Mustacchi     {
808*d14abf15SRobert Mustacchi         lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
809*d14abf15SRobert Mustacchi         if (IS_PFDEV(pdev))
810*d14abf15SRobert Mustacchi         {
811*d14abf15SRobert Mustacchi             MM_RELEASE_ETH_CON_LOCK(pdev);
812*d14abf15SRobert Mustacchi         }
813*d14abf15SRobert Mustacchi         return lm_status;
814*d14abf15SRobert Mustacchi     }
815*d14abf15SRobert Mustacchi 
816*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
817*d14abf15SRobert Mustacchi     {
818*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
819*d14abf15SRobert Mustacchi     }
820*d14abf15SRobert Mustacchi 
821*d14abf15SRobert Mustacchi     lm_status = lm_eth_wait_state_change(pdev, LM_CON_STATE_OPEN, cid);
822*d14abf15SRobert Mustacchi 
823*d14abf15SRobert Mustacchi 
824*d14abf15SRobert Mustacchi     return lm_status;
825*d14abf15SRobert Mustacchi } /* lm_establish_eth_con */
826*d14abf15SRobert Mustacchi 
827*d14abf15SRobert Mustacchi 
828*d14abf15SRobert Mustacchi /**
829*d14abf15SRobert Mustacchi  * @description
830*d14abf15SRobert Mustacchi  * Send all the ramrods and wait for there return.
831*d14abf15SRobert Mustacchi  * @param pdev
832*d14abf15SRobert Mustacchi  * @param chain_idx_base
833*d14abf15SRobert Mustacchi  *
834*d14abf15SRobert Mustacchi  * @return lm_status_t
835*d14abf15SRobert Mustacchi  * status success is returned if all the ramrods where received.
836*d14abf15SRobert Mustacchi  * Status failure is returned if not all the ramrods were
837*d14abf15SRobert Mustacchi  * received.
838*d14abf15SRobert Mustacchi  */
839*d14abf15SRobert Mustacchi lm_status_t
lm_tpa_send_ramrods_wait(IN lm_device_t * pdev,IN const u8_t chain_idx_base)840*d14abf15SRobert Mustacchi lm_tpa_send_ramrods_wait(IN lm_device_t  *pdev,
841*d14abf15SRobert Mustacchi                          IN const u8_t   chain_idx_base)
842*d14abf15SRobert Mustacchi {
843*d14abf15SRobert Mustacchi     lm_tpa_info_t   *tpa_info   = &LM_TPA_INFO(pdev);
844*d14abf15SRobert Mustacchi     lm_status_t     lm_status   = LM_STATUS_SUCCESS;
845*d14abf15SRobert Mustacchi 
846*d14abf15SRobert Mustacchi     DbgBreakIf(NULL != tpa_info->update_cookie);
847*d14abf15SRobert Mustacchi     DbgBreakIf(0 != tpa_info->ramrod_recv_cnt);
848*d14abf15SRobert Mustacchi 
849*d14abf15SRobert Mustacchi     lm_status = lm_tpa_send_ramrods(pdev,
850*d14abf15SRobert Mustacchi                                     chain_idx_base);
851*d14abf15SRobert Mustacchi 
852*d14abf15SRobert Mustacchi     if(LM_STATUS_SUCCESS != lm_status)
853*d14abf15SRobert Mustacchi     {
854*d14abf15SRobert Mustacchi         DbgBreakMsg(" Ramrod send failed ");
855*d14abf15SRobert Mustacchi         return lm_status;
856*d14abf15SRobert Mustacchi     }
857*d14abf15SRobert Mustacchi 
858*d14abf15SRobert Mustacchi     lm_status = lm_wait_state_change(pdev, &tpa_info->state, TPA_STATE_NONE);
859*d14abf15SRobert Mustacchi 
860*d14abf15SRobert Mustacchi     return lm_status;
861*d14abf15SRobert Mustacchi }
862*d14abf15SRobert Mustacchi 
863*d14abf15SRobert Mustacchi /**
864*d14abf15SRobert Mustacchi  * @description
865*d14abf15SRobert Mustacchi  * Update the ramrod IPVX according to the current and required
866*d14abf15SRobert Mustacchi  * state.
867*d14abf15SRobert Mustacchi  * @param pdev
868*d14abf15SRobert Mustacchi  * @param chain_idx
869*d14abf15SRobert Mustacchi  * @param vbd_rsc_ipvx_bit - The VBD TPA ipvX bit.
870*d14abf15SRobert Mustacchi  *
871*d14abf15SRobert Mustacchi  * @return STATIC u8_t - The HSI IPVX eth_tpa_update_command
872*d14abf15SRobert Mustacchi  */
873*d14abf15SRobert Mustacchi u8_t
lm_tpa_ramrod_update_ipvx(IN lm_device_t * pdev,IN const u8_t chain_idx,IN const u8_t vbd_tpa_ipvx_bit)874*d14abf15SRobert Mustacchi lm_tpa_ramrod_update_ipvx(IN lm_device_t   *pdev,
875*d14abf15SRobert Mustacchi                           IN const u8_t          chain_idx,
876*d14abf15SRobert Mustacchi                           IN const u8_t          vbd_tpa_ipvx_bit)
877*d14abf15SRobert Mustacchi {
878*d14abf15SRobert Mustacchi     // Add ramrod send code
879*d14abf15SRobert Mustacchi     const lm_tpa_info_t*    tpa_info    = &LM_TPA_INFO(pdev);
880*d14abf15SRobert Mustacchi     u8_t                    ramrod_ipvx = 0;
881*d14abf15SRobert Mustacchi 
882*d14abf15SRobert Mustacchi     if(GET_FLAGS(tpa_info->ipvx_enabled_required, vbd_tpa_ipvx_bit) ==
883*d14abf15SRobert Mustacchi        GET_FLAGS(tpa_info->ipvx_enabled_current, vbd_tpa_ipvx_bit))
884*d14abf15SRobert Mustacchi     {
885*d14abf15SRobert Mustacchi         ramrod_ipvx = TPA_UPDATE_NONE_COMMAND;
886*d14abf15SRobert Mustacchi     }
887*d14abf15SRobert Mustacchi     else if(GET_FLAGS(tpa_info->ipvx_enabled_required, vbd_tpa_ipvx_bit))
888*d14abf15SRobert Mustacchi     {
889*d14abf15SRobert Mustacchi         ramrod_ipvx = TPA_UPDATE_ENABLE_COMMAND;
890*d14abf15SRobert Mustacchi     }
891*d14abf15SRobert Mustacchi     else
892*d14abf15SRobert Mustacchi     {
893*d14abf15SRobert Mustacchi         ramrod_ipvx = TPA_UPDATE_DISABLE_COMMAND;
894*d14abf15SRobert Mustacchi     }
895*d14abf15SRobert Mustacchi     return ramrod_ipvx;
896*d14abf15SRobert Mustacchi }
897*d14abf15SRobert Mustacchi 
898*d14abf15SRobert Mustacchi /**
899*d14abf15SRobert Mustacchi  * @description
900*d14abf15SRobert Mustacchi  * Fill and send TPA ramrod.
901*d14abf15SRobert Mustacchi  * @param pdev
902*d14abf15SRobert Mustacchi  * @param chain_idx
903*d14abf15SRobert Mustacchi  */
904*d14abf15SRobert Mustacchi STATIC lm_status_t
lm_tpa_send_ramrod(IN lm_device_t * pdev,IN const u8_t chain_idx)905*d14abf15SRobert Mustacchi lm_tpa_send_ramrod(IN lm_device_t   *pdev,
906*d14abf15SRobert Mustacchi                    IN const u8_t    chain_idx)
907*d14abf15SRobert Mustacchi {
908*d14abf15SRobert Mustacchi     // Add ramrod send code
909*d14abf15SRobert Mustacchi     const lm_tpa_chain_t*   tpa_chain       = &LM_TPA( pdev, chain_idx );
910*d14abf15SRobert Mustacchi     const lm_bd_chain_t*    tpa_chain_bd    = &LM_TPA_CHAIN_BD(pdev, chain_idx);
911*d14abf15SRobert Mustacchi     lm_status_t             lm_status       = LM_STATUS_SUCCESS;
912*d14abf15SRobert Mustacchi 
913*d14abf15SRobert Mustacchi     if((CHK_NULL(tpa_chain->ramrod_data_virt)) ||
914*d14abf15SRobert Mustacchi        (lm_tpa_state_enable != tpa_chain->state)||
915*d14abf15SRobert Mustacchi        pdev->params.rss_chain_cnt <= chain_idx)
916*d14abf15SRobert Mustacchi     {
917*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_tpa_send_ramrod : invalid paramters");
918*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
919*d14abf15SRobert Mustacchi     }
920*d14abf15SRobert Mustacchi 
921*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->update_ipv4   =  lm_tpa_ramrod_update_ipvx(pdev,
922*d14abf15SRobert Mustacchi                                                       chain_idx,
923*d14abf15SRobert Mustacchi                                                       TPA_IPV4_ENABLED);
924*d14abf15SRobert Mustacchi 
925*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->update_ipv6   =  lm_tpa_ramrod_update_ipvx(pdev,
926*d14abf15SRobert Mustacchi                                                       chain_idx,
927*d14abf15SRobert Mustacchi                                                       TPA_IPV6_ENABLED);
928*d14abf15SRobert Mustacchi 
929*d14abf15SRobert Mustacchi     /* TPA mode to use (LRO or GRO) */
930*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->tpa_mode       = TPA_LRO;
931*d14abf15SRobert Mustacchi 
932*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->client_id     = LM_FW_CLI_ID(pdev, chain_idx);
933*d14abf15SRobert Mustacchi     /* maximal TPA queues allowed for this client */
934*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->max_tpa_queues        = LM_TPA_MAX_AGGS;
935*d14abf15SRobert Mustacchi     /* The maximal number of SGEs that can be used for one packet. depends on MTU and SGE size. must be 0 if SGEs are disabled */
936*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->max_sges_for_packet   = DIV_ROUND_UP_BITS(pdev->params.l2_cli_con_params[chain_idx].mtu, LM_TPA_PAGE_BITS);
937*d14abf15SRobert Mustacchi     // Avoiding rings thresholds verification is aimed for eVBD
938*d14abf15SRobert Mustacchi     // which receives its buffers and SGEs only after client init
939*d14abf15SRobert Mustacchi     // is completed.(eVBD receives the buffers and SGEs only after
940*d14abf15SRobert Mustacchi     // client setup is completed.)
941*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->dont_verify_rings_pause_thr_flg = 1;
942*d14abf15SRobert Mustacchi     /* Size of the buffers pointed by SGEs */
943*d14abf15SRobert Mustacchi     ASSERT_STATIC(LM_TPA_PAGE_SIZE < MAX_VARIABLE_VALUE(tpa_chain->ramrod_data_virt->sge_buff_size));
944*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->sge_buff_size         = mm_cpu_to_le16(LM_TPA_PAGE_SIZE);
945*d14abf15SRobert Mustacchi     /* maximal size for the aggregated TPA packets, reprted by the host */
946*d14abf15SRobert Mustacchi     ASSERT_STATIC((LM_TPA_MAX_AGG_SIZE * LM_TPA_PAGE_SIZE) < MAX_VARIABLE_VALUE(tpa_chain->ramrod_data_virt->max_agg_size));
947*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->max_agg_size          = mm_cpu_to_le16(LM_TPA_MAX_AGG_SIZE * LM_TPA_PAGE_SIZE);
948*d14abf15SRobert Mustacchi     //u32_t sge_page_base_lo /* The address to fetch the next sges from (low) */;
949*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->sge_page_base_lo      = mm_cpu_to_le32(tpa_chain_bd->bd_chain_phy.as_u32.low);
950*d14abf15SRobert Mustacchi     //u32_t sge_page_base_hi /* The address to fetch the next sges from (high) */;
951*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->sge_page_base_hi      = mm_cpu_to_le32(tpa_chain_bd->bd_chain_phy.as_u32.high);
952*d14abf15SRobert Mustacchi     //u16_t sge_pause_thr_low /* number of remaining sges under which, we send pause message */;
953*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->sge_pause_thr_low     = mm_cpu_to_le16(LM_TPA_SGE_PAUSE_THR_LOW);
954*d14abf15SRobert Mustacchi     //u16_t sge_pause_thr_high /* number of remaining sges above which, we send un-pause message */;
955*d14abf15SRobert Mustacchi     tpa_chain->ramrod_data_virt->sge_pause_thr_high    = mm_cpu_to_le16(LM_TPA_SGE_PAUSE_THR_HIGH);
956*d14abf15SRobert Mustacchi 
957*d14abf15SRobert Mustacchi     lm_sq_post(pdev,
958*d14abf15SRobert Mustacchi                chain_idx,
959*d14abf15SRobert Mustacchi                RAMROD_CMD_ID_ETH_TPA_UPDATE,
960*d14abf15SRobert Mustacchi                CMD_PRIORITY_MEDIUM,
961*d14abf15SRobert Mustacchi                ETH_CONNECTION_TYPE,
962*d14abf15SRobert Mustacchi                *(u64_t *)&(tpa_chain->ramrod_data_phys));
963*d14abf15SRobert Mustacchi 
964*d14abf15SRobert Mustacchi     DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
965*d14abf15SRobert Mustacchi 
966*d14abf15SRobert Mustacchi     return lm_status;
967*d14abf15SRobert Mustacchi }
968*d14abf15SRobert Mustacchi 
969*d14abf15SRobert Mustacchi 
970*d14abf15SRobert Mustacchi /**
971*d14abf15SRobert Mustacchi  * @description
972*d14abf15SRobert Mustacchi  * Run on all RSS chains and send the ramrod on each one.
973*d14abf15SRobert Mustacchi  * @param pdev
974*d14abf15SRobert Mustacchi  * @param chain_idx_base
975*d14abf15SRobert Mustacchi  */
976*d14abf15SRobert Mustacchi lm_status_t
lm_tpa_send_ramrods(IN lm_device_t * pdev,IN const u8_t chain_idx_base)977*d14abf15SRobert Mustacchi lm_tpa_send_ramrods(IN lm_device_t  *pdev,
978*d14abf15SRobert Mustacchi                     IN const u8_t   chain_idx_base)
979*d14abf15SRobert Mustacchi {
980*d14abf15SRobert Mustacchi     lm_tpa_info_t*  tpa_info    = &LM_TPA_INFO(pdev);
981*d14abf15SRobert Mustacchi     lm_status_t     lm_status   = LM_STATUS_SUCCESS;
982*d14abf15SRobert Mustacchi     u8_t            chain_idx   = 0;
983*d14abf15SRobert Mustacchi     u8_t            rss_idx     = 0;
984*d14abf15SRobert Mustacchi 
985*d14abf15SRobert Mustacchi     // Number of ramrods expected in receive
986*d14abf15SRobert Mustacchi     tpa_info->ramrod_recv_cnt = pdev->params.rss_chain_cnt;
987*d14abf15SRobert Mustacchi     tpa_info->state = TPA_STATE_RAMROD_SENT;
988*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
989*d14abf15SRobert Mustacchi     if (IS_VFDEV(pdev))
990*d14abf15SRobert Mustacchi     {
991*d14abf15SRobert Mustacchi         tpa_info->ramrod_recv_cnt++;
992*d14abf15SRobert Mustacchi         lm_status = lm_vf_pf_update_rsc(pdev);
993*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_SUCCESS) {
994*d14abf15SRobert Mustacchi             lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
995*d14abf15SRobert Mustacchi             if ((lm_status == LM_STATUS_SUCCESS) && (0 == mm_atomic_dec((u32_t*)(&tpa_info->ramrod_recv_cnt))))
996*d14abf15SRobert Mustacchi             {
997*d14abf15SRobert Mustacchi                 tpa_info->ipvx_enabled_current = tpa_info->ipvx_enabled_required;
998*d14abf15SRobert Mustacchi                 if (tpa_info->update_cookie)
999*d14abf15SRobert Mustacchi                 {
1000*d14abf15SRobert Mustacchi                     void* cookie = (void *)tpa_info->update_cookie;
1001*d14abf15SRobert Mustacchi                     tpa_info->update_cookie = NULL;
1002*d14abf15SRobert Mustacchi                     mm_set_done(pdev, 0, cookie);
1003*d14abf15SRobert Mustacchi                 }
1004*d14abf15SRobert Mustacchi             }
1005*d14abf15SRobert Mustacchi         }
1006*d14abf15SRobert Mustacchi 
1007*d14abf15SRobert Mustacchi     }
1008*d14abf15SRobert Mustacchi     else
1009*d14abf15SRobert Mustacchi #endif
1010*d14abf15SRobert Mustacchi     {
1011*d14abf15SRobert Mustacchi         LM_FOREACH_RSS_IDX(pdev, rss_idx)
1012*d14abf15SRobert Mustacchi         {
1013*d14abf15SRobert Mustacchi             chain_idx = chain_idx_base + RSS_ID_TO_CID(rss_idx);
1014*d14abf15SRobert Mustacchi             lm_status = lm_tpa_send_ramrod(pdev,
1015*d14abf15SRobert Mustacchi                                            chain_idx);
1016*d14abf15SRobert Mustacchi 
1017*d14abf15SRobert Mustacchi             if(LM_STATUS_SUCCESS != lm_status)
1018*d14abf15SRobert Mustacchi             {
1019*d14abf15SRobert Mustacchi                 DbgBreakMsg(" Ramrod send failed ");
1020*d14abf15SRobert Mustacchi                 break;
1021*d14abf15SRobert Mustacchi             }
1022*d14abf15SRobert Mustacchi         }
1023*d14abf15SRobert Mustacchi     }
1024*d14abf15SRobert Mustacchi 
1025*d14abf15SRobert Mustacchi     return lm_status;
1026*d14abf15SRobert Mustacchi }
1027*d14abf15SRobert Mustacchi 
1028*d14abf15SRobert Mustacchi /**
1029*d14abf15SRobert Mustacchi  * @description
1030*d14abf15SRobert Mustacchi  * Fill and send function_update_data ramrod.
1031*d14abf15SRobert Mustacchi  * @param pdev
1032*d14abf15SRobert Mustacchi  */
1033*d14abf15SRobert Mustacchi lm_status_t
lm_encap_send_ramrod(IN lm_device_t * pdev,u8_t new_encap_offload_state,void * cookie)1034*d14abf15SRobert Mustacchi lm_encap_send_ramrod(IN lm_device_t *pdev, u8_t new_encap_offload_state, void* cookie)
1035*d14abf15SRobert Mustacchi {
1036*d14abf15SRobert Mustacchi     lm_encap_info_t* encaps_info = &(pdev->encap_info);
1037*d14abf15SRobert Mustacchi     struct function_update_data*    data        = LM_SLOWPATH(pdev, encap_function_update_data);
1038*d14abf15SRobert Mustacchi     const lm_address_t              data_phys   = LM_SLOWPATH_PHYS(pdev, encap_function_update_data);
1039*d14abf15SRobert Mustacchi     lm_status_t                     lm_status   = LM_STATUS_SUCCESS;
1040*d14abf15SRobert Mustacchi 
1041*d14abf15SRobert Mustacchi     // check that we are not in the middle of handling another encapsulated packets offload set request (1 pending)
1042*d14abf15SRobert Mustacchi     DbgBreakIf(encaps_info->new_encap_offload_state != encaps_info->current_encap_offload_state);
1043*d14abf15SRobert Mustacchi     DbgBreakIf(encaps_info->update_cookie);
1044*d14abf15SRobert Mustacchi 
1045*d14abf15SRobert Mustacchi     encaps_info->new_encap_offload_state = new_encap_offload_state;
1046*d14abf15SRobert Mustacchi 
1047*d14abf15SRobert Mustacchi     if (encaps_info->new_encap_offload_state == encaps_info->current_encap_offload_state)
1048*d14abf15SRobert Mustacchi     {
1049*d14abf15SRobert Mustacchi         DbgMessage(pdev, VERBOSEencap, "no change in encapsulated packets offload state\n");
1050*d14abf15SRobert Mustacchi         return lm_status;
1051*d14abf15SRobert Mustacchi     }
1052*d14abf15SRobert Mustacchi 
1053*d14abf15SRobert Mustacchi     // remember this for mm_set_done call (called on completion of the ramrod)
1054*d14abf15SRobert Mustacchi     // mm_set_done will free memory of query_set_info
1055*d14abf15SRobert Mustacchi     encaps_info->update_cookie = cookie;
1056*d14abf15SRobert Mustacchi 
1057*d14abf15SRobert Mustacchi     // GRE config for the function will be updated according to the gre_tunnel_rss and nvgre_clss_en fields
1058*d14abf15SRobert Mustacchi     data->update_tunn_cfg_flg = TRUE;
1059*d14abf15SRobert Mustacchi 
1060*d14abf15SRobert Mustacchi     if (ENCAP_OFFLOAD_DISABLED == pdev->encap_info.new_encap_offload_state)
1061*d14abf15SRobert Mustacchi     {
1062*d14abf15SRobert Mustacchi         data->tunn_clss_en  = 0;
1063*d14abf15SRobert Mustacchi         data->tunnel_mode = TUNN_MODE_NONE;
1064*d14abf15SRobert Mustacchi     }
1065*d14abf15SRobert Mustacchi     else
1066*d14abf15SRobert Mustacchi     {
1067*d14abf15SRobert Mustacchi         data->tunn_clss_en  = 1;
1068*d14abf15SRobert Mustacchi         data->tunnel_mode = TUNN_MODE_GRE;
1069*d14abf15SRobert Mustacchi         data->gre_tunnel_type = NVGRE_TUNNEL;
1070*d14abf15SRobert Mustacchi     }
1071*d14abf15SRobert Mustacchi 
1072*d14abf15SRobert Mustacchi     data->echo = FUNC_UPDATE_RAMROD_SOURCE_ENCAP;
1073*d14abf15SRobert Mustacchi 
1074*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
1075*d14abf15SRobert Mustacchi                            0, //Don't care
1076*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE,
1077*d14abf15SRobert Mustacchi                            CMD_PRIORITY_NORMAL,
1078*d14abf15SRobert Mustacchi                            NONE_CONNECTION_TYPE,
1079*d14abf15SRobert Mustacchi                            data_phys.as_u64);
1080*d14abf15SRobert Mustacchi 
1081*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1082*d14abf15SRobert Mustacchi     {
1083*d14abf15SRobert Mustacchi         return lm_status;
1084*d14abf15SRobert Mustacchi     }
1085*d14abf15SRobert Mustacchi     return LM_STATUS_PENDING;
1086*d14abf15SRobert Mustacchi }
1087*d14abf15SRobert Mustacchi /**
1088*d14abf15SRobert Mustacchi  * This function is a general eq ramrod fuanction that waits
1089*d14abf15SRobert Mustacchi  * synchroniously for it's completion.
1090*d14abf15SRobert Mustacchi  *
1091*d14abf15SRobert Mustacchi  * @param pdev
1092*d14abf15SRobert Mustacchi  * cmd_id -The ramrod command ID
1093*d14abf15SRobert Mustacchi  * data -ramrod data
1094*d14abf15SRobert Mustacchi  * curr_state - what to poll on
1095*d14abf15SRobert Mustacchi  * curr_state Current state.
1096*d14abf15SRobert Mustacchi  * new_state - what we're waiting for.
1097*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS / TIMEOUT on waiting for
1098*d14abf15SRobert Mustacchi  *         completion
1099*d14abf15SRobert Mustacchi  */
1100*d14abf15SRobert Mustacchi lm_status_t
lm_eq_ramrod_post_sync(IN struct _lm_device_t * pdev,IN u8_t cmd_id,IN u64_t data,IN u8_t ramrod_priority,IN volatile u32_t * p_curr_state,IN u32_t curr_state,IN u32_t new_state)1101*d14abf15SRobert Mustacchi lm_eq_ramrod_post_sync( IN struct _lm_device_t  *pdev,
1102*d14abf15SRobert Mustacchi                         IN u8_t                 cmd_id,
1103*d14abf15SRobert Mustacchi                         IN u64_t                data,
1104*d14abf15SRobert Mustacchi                         IN u8_t                 ramrod_priority,
1105*d14abf15SRobert Mustacchi                         IN volatile u32_t       *p_curr_state,
1106*d14abf15SRobert Mustacchi                         IN u32_t                curr_state,
1107*d14abf15SRobert Mustacchi                         IN u32_t                new_state)
1108*d14abf15SRobert Mustacchi {
1109*d14abf15SRobert Mustacchi 
1110*d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_SUCCESS;
1111*d14abf15SRobert Mustacchi 
1112*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMeq|INFORMl2sp, "#lm_eq_ramrod\n");
1113*d14abf15SRobert Mustacchi 
1114*d14abf15SRobert Mustacchi     *p_curr_state = curr_state;
1115*d14abf15SRobert Mustacchi 
1116*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
1117*d14abf15SRobert Mustacchi                            0, //Don't care
1118*d14abf15SRobert Mustacchi                            cmd_id,
1119*d14abf15SRobert Mustacchi                            ramrod_priority,
1120*d14abf15SRobert Mustacchi                            NONE_CONNECTION_TYPE,
1121*d14abf15SRobert Mustacchi                            data );
1122*d14abf15SRobert Mustacchi 
1123*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1124*d14abf15SRobert Mustacchi     {
1125*d14abf15SRobert Mustacchi         return lm_status;
1126*d14abf15SRobert Mustacchi     }
1127*d14abf15SRobert Mustacchi 
1128*d14abf15SRobert Mustacchi     lm_status = lm_wait_state_change(pdev,
1129*d14abf15SRobert Mustacchi                                      p_curr_state,
1130*d14abf15SRobert Mustacchi                                      new_state);
1131*d14abf15SRobert Mustacchi 
1132*d14abf15SRobert Mustacchi     return lm_status;
1133*d14abf15SRobert Mustacchi } /* lm_eq_ramrod_post_sync */
1134*d14abf15SRobert Mustacchi 
1135*d14abf15SRobert Mustacchi static lm_status_t
lm_halt_eth_con(struct _lm_device_t * pdev,u32_t cid,const u8_t send_ramrod)1136*d14abf15SRobert Mustacchi lm_halt_eth_con(struct _lm_device_t *pdev, u32_t cid,
1137*d14abf15SRobert Mustacchi                 const u8_t send_ramrod)
1138*d14abf15SRobert Mustacchi {
1139*d14abf15SRobert Mustacchi     union eth_specific_data ramrod_data     = {{0}};
1140*d14abf15SRobert Mustacchi     lm_address_t            data_mapping    = {{0}};
1141*d14abf15SRobert Mustacchi     lm_status_t             lm_status       = LM_STATUS_SUCCESS  ;
1142*d14abf15SRobert Mustacchi     u32_t                   fw_client_idx   = 0xFFFFFFFF;
1143*d14abf15SRobert Mustacchi     u32_t                   con_state       = 0;
1144*d14abf15SRobert Mustacchi 
1145*d14abf15SRobert Mustacchi     fw_client_idx = lm_get_fw_client_idx_from_cid(pdev, cid);
1146*d14abf15SRobert Mustacchi 
1147*d14abf15SRobert Mustacchi     ASSERT_STATIC(sizeof(ramrod_data) == sizeof(u64_t));
1148*d14abf15SRobert Mustacchi 
1149*d14abf15SRobert Mustacchi 
1150*d14abf15SRobert Mustacchi     con_state = lm_get_con_state(pdev, cid);
1151*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARN/*INFORMi|INFORMl2sp*/, "#lm_halt_eth_con cid=%d fw_client_idx=%d client_info=%d(%d)\n",cid, fw_client_idx,
1152*d14abf15SRobert Mustacchi                 cid,con_state);
1153*d14abf15SRobert Mustacchi 
1154*d14abf15SRobert Mustacchi 
1155*d14abf15SRobert Mustacchi     if (ERR_IF(con_state != LM_CON_STATE_OPEN))
1156*d14abf15SRobert Mustacchi     {
1157*d14abf15SRobert Mustacchi         DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
1158*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1159*d14abf15SRobert Mustacchi     }
1160*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
1161*d14abf15SRobert Mustacchi     {
1162*d14abf15SRobert Mustacchi         MM_ACQUIRE_ETH_CON_LOCK(pdev);
1163*d14abf15SRobert Mustacchi     }
1164*d14abf15SRobert Mustacchi 
1165*d14abf15SRobert Mustacchi     if(FALSE == send_ramrod)
1166*d14abf15SRobert Mustacchi     {
1167*d14abf15SRobert Mustacchi         lm_set_con_state(pdev, cid, LM_CON_STATE_HALT);
1168*d14abf15SRobert Mustacchi         DbgMessage(pdev, WARNl2sp, "lm_close_eth_con:The HALT ramrod isn't sent \n");
1169*d14abf15SRobert Mustacchi         if (IS_PFDEV(pdev))
1170*d14abf15SRobert Mustacchi         {
1171*d14abf15SRobert Mustacchi             MM_RELEASE_ETH_CON_LOCK(pdev);
1172*d14abf15SRobert Mustacchi         }
1173*d14abf15SRobert Mustacchi         return LM_STATUS_SUCCESS;
1174*d14abf15SRobert Mustacchi     }
1175*d14abf15SRobert Mustacchi     // Send ramrod
1176*d14abf15SRobert Mustacchi     lm_set_con_state(pdev, cid, LM_CON_STATE_HALT_SENT);
1177*d14abf15SRobert Mustacchi     ramrod_data.halt_ramrod_data.client_id = fw_client_idx; //LM_FW_CLI_ID(pdev, client_info_idx);
1178*d14abf15SRobert Mustacchi 
1179*d14abf15SRobert Mustacchi     /* convert halt_ramrod_data to a big-endian friendly format */
1180*d14abf15SRobert Mustacchi     data_mapping.as_u32.low = ramrod_data.halt_ramrod_data.client_id;
1181*d14abf15SRobert Mustacchi 
1182*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
1183*d14abf15SRobert Mustacchi                            cid,
1184*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_ETH_HALT,
1185*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
1186*d14abf15SRobert Mustacchi                            ETH_CONNECTION_TYPE,
1187*d14abf15SRobert Mustacchi                            data_mapping.as_u64);
1188*d14abf15SRobert Mustacchi 
1189*d14abf15SRobert Mustacchi     if (IS_PFDEV(pdev))
1190*d14abf15SRobert Mustacchi     {
1191*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
1192*d14abf15SRobert Mustacchi     }
1193*d14abf15SRobert Mustacchi 
1194*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1195*d14abf15SRobert Mustacchi     {
1196*d14abf15SRobert Mustacchi         return lm_status;
1197*d14abf15SRobert Mustacchi     }
1198*d14abf15SRobert Mustacchi 
1199*d14abf15SRobert Mustacchi     lm_status = lm_eth_wait_state_change(pdev, LM_CON_STATE_HALT, cid);
1200*d14abf15SRobert Mustacchi 
1201*d14abf15SRobert Mustacchi     return lm_status;
1202*d14abf15SRobert Mustacchi } /* lm_halt_eth_con */
1203*d14abf15SRobert Mustacchi 
lm_terminate_eth_con(struct _lm_device_t * pdev,u32_t const cid)1204*d14abf15SRobert Mustacchi lm_status_t lm_terminate_eth_con(struct _lm_device_t *pdev,
1205*d14abf15SRobert Mustacchi                                  u32_t const          cid)
1206*d14abf15SRobert Mustacchi {
1207*d14abf15SRobert Mustacchi     lm_status_t lm_status  = LM_STATUS_SUCCESS;
1208*d14abf15SRobert Mustacchi 
1209*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMi|INFORMl2sp, "#lm_terminate_eth_con, cid=%d \n",cid);
1210*d14abf15SRobert Mustacchi 
1211*d14abf15SRobert Mustacchi     if (ERR_IF(lm_get_con_state(pdev, cid) != LM_CON_STATE_HALT))
1212*d14abf15SRobert Mustacchi     {
1213*d14abf15SRobert Mustacchi         DbgBreak();
1214*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1215*d14abf15SRobert Mustacchi     }
1216*d14abf15SRobert Mustacchi 
1217*d14abf15SRobert Mustacchi     if (IS_VFDEV(pdev))
1218*d14abf15SRobert Mustacchi     {
1219*d14abf15SRobert Mustacchi         lm_set_con_state(pdev, cid, LM_CON_STATE_TERMINATE);
1220*d14abf15SRobert Mustacchi         return LM_STATUS_SUCCESS; /* Not supported for VFs */
1221*d14abf15SRobert Mustacchi     }
1222*d14abf15SRobert Mustacchi 
1223*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
1224*d14abf15SRobert Mustacchi                            cid,
1225*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_ETH_TERMINATE,
1226*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
1227*d14abf15SRobert Mustacchi                            ETH_CONNECTION_TYPE,
1228*d14abf15SRobert Mustacchi                            0);
1229*d14abf15SRobert Mustacchi 
1230*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1231*d14abf15SRobert Mustacchi     {
1232*d14abf15SRobert Mustacchi         return lm_status;
1233*d14abf15SRobert Mustacchi     }
1234*d14abf15SRobert Mustacchi 
1235*d14abf15SRobert Mustacchi     lm_status = lm_eth_wait_state_change(pdev, LM_CON_STATE_TERMINATE, cid);
1236*d14abf15SRobert Mustacchi 
1237*d14abf15SRobert Mustacchi     return lm_status;
1238*d14abf15SRobert Mustacchi }
1239*d14abf15SRobert Mustacchi 
lm_cfc_del_eth_con(struct _lm_device_t * pdev,u32_t const cid)1240*d14abf15SRobert Mustacchi static lm_status_t lm_cfc_del_eth_con(struct _lm_device_t *pdev,
1241*d14abf15SRobert Mustacchi                                       u32_t const          cid)
1242*d14abf15SRobert Mustacchi {
1243*d14abf15SRobert Mustacchi /* VIA PF!!!!!!*/
1244*d14abf15SRobert Mustacchi     lm_status_t lm_status       = LM_STATUS_SUCCESS;
1245*d14abf15SRobert Mustacchi 
1246*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMi|INFORMl2sp, "#lm_cfc_del_eth_con, cid=%d\n",cid);
1247*d14abf15SRobert Mustacchi 
1248*d14abf15SRobert Mustacchi     if (ERR_IF(lm_get_con_state(pdev, cid) != LM_CON_STATE_TERMINATE))
1249*d14abf15SRobert Mustacchi     {
1250*d14abf15SRobert Mustacchi         DbgBreak();
1251*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1252*d14abf15SRobert Mustacchi     }
1253*d14abf15SRobert Mustacchi 
1254*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
1255*d14abf15SRobert Mustacchi                            cid,
1256*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_COMMON_CFC_DEL,
1257*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
1258*d14abf15SRobert Mustacchi                            NONE_CONNECTION_TYPE,
1259*d14abf15SRobert Mustacchi                            0);
1260*d14abf15SRobert Mustacchi 
1261*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1262*d14abf15SRobert Mustacchi     {
1263*d14abf15SRobert Mustacchi         return lm_status;
1264*d14abf15SRobert Mustacchi     }
1265*d14abf15SRobert Mustacchi 
1266*d14abf15SRobert Mustacchi     lm_status = lm_eth_wait_state_change(pdev, LM_CON_STATE_CLOSE, cid);
1267*d14abf15SRobert Mustacchi 
1268*d14abf15SRobert Mustacchi     return lm_status;
1269*d14abf15SRobert Mustacchi } /* lm_cfc_del_eth_con */
1270*d14abf15SRobert Mustacchi 
1271*d14abf15SRobert Mustacchi 
1272*d14abf15SRobert Mustacchi 
lm_establish_forward_con(struct _lm_device_t * pdev)1273*d14abf15SRobert Mustacchi lm_status_t lm_establish_forward_con(struct _lm_device_t *pdev)
1274*d14abf15SRobert Mustacchi {
1275*d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_SUCCESS;
1276*d14abf15SRobert Mustacchi     u8_t const  fwd_cid   = FWD_CID(pdev);
1277*d14abf15SRobert Mustacchi 
1278*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMi | INFORMl2sp, "lm_establish_forward_con\n");
1279*d14abf15SRobert Mustacchi     lm_status = lm_establish_eth_con(pdev, fwd_cid, DEF_STATUS_BLOCK_INDEX , LM_CLIENT_ATTRIBUTES_TX);
1280*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS) {
1281*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_establish_forward_con failed\n");
1282*d14abf15SRobert Mustacchi         return lm_status;
1283*d14abf15SRobert Mustacchi     }
1284*d14abf15SRobert Mustacchi 
1285*d14abf15SRobert Mustacchi     DbgMessage(pdev,INFORMi | INFORMl2sp, "Establish forward connection ramrod completed\n");
1286*d14abf15SRobert Mustacchi 
1287*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1288*d14abf15SRobert Mustacchi }
1289*d14abf15SRobert Mustacchi 
lm_close_forward_con(struct _lm_device_t * pdev)1290*d14abf15SRobert Mustacchi lm_status_t lm_close_forward_con(struct _lm_device_t *pdev)
1291*d14abf15SRobert Mustacchi {
1292*d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_SUCCESS;
1293*d14abf15SRobert Mustacchi     u8_t const  fwd_cid   = FWD_CID(pdev);
1294*d14abf15SRobert Mustacchi 
1295*d14abf15SRobert Mustacchi     /* halt and terminate ramrods (lm_{halt,terminate}_eth_con) are not sent for the forward channel connection.
1296*d14abf15SRobert Mustacchi        therefore we just change the state from OPEN to TERMINATE, and send the cfc del ramrod */
1297*d14abf15SRobert Mustacchi     DbgBreakIf(lm_get_con_state(pdev, fwd_cid) != LM_CON_STATE_OPEN);
1298*d14abf15SRobert Mustacchi     lm_set_con_state(pdev, fwd_cid, LM_CON_STATE_TERMINATE);
1299*d14abf15SRobert Mustacchi 
1300*d14abf15SRobert Mustacchi     lm_status = lm_cfc_del_eth_con(pdev,fwd_cid);
1301*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS) {
1302*d14abf15SRobert Mustacchi         return lm_status;
1303*d14abf15SRobert Mustacchi     }
1304*d14abf15SRobert Mustacchi 
1305*d14abf15SRobert Mustacchi     DbgMessage(pdev,INFORMi | INFORMl2sp, "lm_close_forward_con completed\n");
1306*d14abf15SRobert Mustacchi 
1307*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1308*d14abf15SRobert Mustacchi }
1309*d14abf15SRobert Mustacchi 
lm_close_eth_con(struct _lm_device_t * pdev,u32_t const cid,const u8_t send_halt_ramrod)1310*d14abf15SRobert Mustacchi lm_status_t lm_close_eth_con(struct _lm_device_t *pdev,
1311*d14abf15SRobert Mustacchi                              u32_t    const cid,
1312*d14abf15SRobert Mustacchi                              const  u8_t   send_halt_ramrod)
1313*d14abf15SRobert Mustacchi {
1314*d14abf15SRobert Mustacchi     lm_status_t lm_status;
1315*d14abf15SRobert Mustacchi     u8_t max_eth_cid;
1316*d14abf15SRobert Mustacchi 
1317*d14abf15SRobert Mustacchi     if (lm_fl_reset_is_inprogress(pdev)) {
1318*d14abf15SRobert Mustacchi         lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
1319*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_chip_stop: Under FLR: \"close\" cid=%d.\n", cid);
1320*d14abf15SRobert Mustacchi         return LM_STATUS_SUCCESS;
1321*d14abf15SRobert Mustacchi     }
1322*d14abf15SRobert Mustacchi 
1323*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
1324*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev)) {
1325*d14abf15SRobert Mustacchi         lm_status = lm_vf_queue_close(pdev, (u8_t)cid);
1326*d14abf15SRobert Mustacchi         return lm_status;
1327*d14abf15SRobert Mustacchi     }
1328*d14abf15SRobert Mustacchi #endif
1329*d14abf15SRobert Mustacchi 
1330*d14abf15SRobert Mustacchi 
1331*d14abf15SRobert Mustacchi     lm_status = lm_halt_eth_con(pdev,cid, send_halt_ramrod);
1332*d14abf15SRobert Mustacchi 
1333*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1334*d14abf15SRobert Mustacchi     {
1335*d14abf15SRobert Mustacchi         return lm_status;
1336*d14abf15SRobert Mustacchi     }
1337*d14abf15SRobert Mustacchi 
1338*d14abf15SRobert Mustacchi     lm_status = lm_terminate_eth_con(pdev,cid);
1339*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1340*d14abf15SRobert Mustacchi     {
1341*d14abf15SRobert Mustacchi         return lm_status;
1342*d14abf15SRobert Mustacchi     }
1343*d14abf15SRobert Mustacchi 
1344*d14abf15SRobert Mustacchi     lm_status = lm_cfc_del_eth_con(pdev,cid);
1345*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1346*d14abf15SRobert Mustacchi     {
1347*d14abf15SRobert Mustacchi         return lm_status;
1348*d14abf15SRobert Mustacchi     }
1349*d14abf15SRobert Mustacchi 
1350*d14abf15SRobert Mustacchi     if (MM_DCB_MP_L2_IS_ENABLE(pdev))
1351*d14abf15SRobert Mustacchi     {
1352*d14abf15SRobert Mustacchi         max_eth_cid = lm_mp_max_cos_chain_used(pdev);
1353*d14abf15SRobert Mustacchi     }
1354*d14abf15SRobert Mustacchi     else
1355*d14abf15SRobert Mustacchi     {
1356*d14abf15SRobert Mustacchi         max_eth_cid = MAX_RX_CHAIN(pdev);
1357*d14abf15SRobert Mustacchi     }
1358*d14abf15SRobert Mustacchi     if (cid < max_eth_cid) {
1359*d14abf15SRobert Mustacchi         lm_status = lm_clear_eth_con_resc(pdev,(u8_t)cid);
1360*d14abf15SRobert Mustacchi     }
1361*d14abf15SRobert Mustacchi 
1362*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1363*d14abf15SRobert Mustacchi     {
1364*d14abf15SRobert Mustacchi         return lm_status;
1365*d14abf15SRobert Mustacchi     }
1366*d14abf15SRobert Mustacchi 
1367*d14abf15SRobert Mustacchi     DbgMessage(pdev,INFORMi | INFORMl2sp, "lm_close_eth_con completed for cid=%d\n", cid);
1368*d14abf15SRobert Mustacchi 
1369*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
1370*d14abf15SRobert Mustacchi }
lm_eth_wait_state_change(struct _lm_device_t * pdev,u32_t new_state,u32_t cid)1371*d14abf15SRobert Mustacchi lm_status_t lm_eth_wait_state_change(struct _lm_device_t *pdev, u32_t new_state, u32_t cid)
1372*d14abf15SRobert Mustacchi {
1373*d14abf15SRobert Mustacchi     lm_cid_resc_t * cid_resc = lm_cid_resc(pdev, cid);
1374*d14abf15SRobert Mustacchi 
1375*d14abf15SRobert Mustacchi     if (CHK_NULL(cid_resc))
1376*d14abf15SRobert Mustacchi     {
1377*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1378*d14abf15SRobert Mustacchi     }
1379*d14abf15SRobert Mustacchi 
1380*d14abf15SRobert Mustacchi     return lm_wait_state_change(pdev, &cid_resc->con_state, new_state);
1381*d14abf15SRobert Mustacchi 
1382*d14abf15SRobert Mustacchi } /* lm_eth_wait_state_change */
1383*d14abf15SRobert Mustacchi 
1384*d14abf15SRobert Mustacchi /**lm_func_update_post_command Post a func_update ramrod and
1385*d14abf15SRobert Mustacchi  * wait for its completion.
1386*d14abf15SRobert Mustacchi  * Must be called from a work item.
1387*d14abf15SRobert Mustacchi  *
1388*d14abf15SRobert Mustacchi  * @param pdev the device
1389*d14abf15SRobert Mustacchi  * @param command the ramrod cmd_id (NONE_CONNECTION_TYPE is
1390*d14abf15SRobert Mustacchi  *                assumed)
1391*d14abf15SRobert Mustacchi  * @param data the ramrod data
1392*d14abf15SRobert Mustacchi  *
1393*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
1394*d14abf15SRobert Mustacchi  *         failure code on failure.
1395*d14abf15SRobert Mustacchi  */
1396*d14abf15SRobert Mustacchi lm_status_t
lm_l2mp_func_update_command(IN lm_device_t * pdev,IN const struct function_update_data * func_data)1397*d14abf15SRobert Mustacchi lm_l2mp_func_update_command( IN lm_device_t                         *pdev,
1398*d14abf15SRobert Mustacchi                              IN const struct function_update_data   *func_data)
1399*d14abf15SRobert Mustacchi {
1400*d14abf15SRobert Mustacchi     lm_status_t                     lm_status   = LM_STATUS_FAILURE;
1401*d14abf15SRobert Mustacchi     struct function_update_data*    data        = LM_SLOWPATH(pdev, l2mp_func_update_data);
1402*d14abf15SRobert Mustacchi     lm_address_t                    data_phys   = LM_SLOWPATH_PHYS(pdev, l2mp_func_update_data);
1403*d14abf15SRobert Mustacchi 
1404*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->slowpath_info.l2mp_func_update_ramrod_state != L2MP_FUNC_UPDATE_RAMROD_NOT_POSTED);
1405*d14abf15SRobert Mustacchi 
1406*d14abf15SRobert Mustacchi     mm_memcpy(data, func_data, sizeof(struct function_update_data));
1407*d14abf15SRobert Mustacchi 
1408*d14abf15SRobert Mustacchi     data->echo = FUNC_UPDATE_RAMROD_SOURCE_L2MP;
1409*d14abf15SRobert Mustacchi 
1410*d14abf15SRobert Mustacchi     lm_status = lm_eq_ramrod_post_sync(pdev,RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, data_phys.as_u64,CMD_PRIORITY_NORMAL,&pdev->slowpath_info.l2mp_func_update_ramrod_state, L2MP_FUNC_UPDATE_RAMROD_POSTED, L2MP_FUNC_UPDATE_RAMROD_COMPLETED);
1411*d14abf15SRobert Mustacchi     if (LM_STATUS_SUCCESS != lm_status)
1412*d14abf15SRobert Mustacchi     {
1413*d14abf15SRobert Mustacchi         DbgBreakIf(LM_STATUS_SUCCESS != lm_status);
1414*d14abf15SRobert Mustacchi         goto _exit;
1415*d14abf15SRobert Mustacchi     }
1416*d14abf15SRobert Mustacchi 
1417*d14abf15SRobert Mustacchi _exit:
1418*d14abf15SRobert Mustacchi     pdev->slowpath_info.l2mp_func_update_ramrod_state = L2MP_FUNC_UPDATE_RAMROD_NOT_POSTED;
1419*d14abf15SRobert Mustacchi     return lm_status;
1420*d14abf15SRobert Mustacchi }
1421*d14abf15SRobert Mustacchi 
1422*d14abf15SRobert Mustacchi /*********************** NIV **************************************/
1423*d14abf15SRobert Mustacchi 
lm_niv_post_command(struct _lm_device_t * pdev,IN const u8_t command,IN const u64_t data,IN const u32_t curr_state)1424*d14abf15SRobert Mustacchi lm_status_t lm_niv_post_command(struct _lm_device_t         *pdev,
1425*d14abf15SRobert Mustacchi                                 IN const u8_t               command,
1426*d14abf15SRobert Mustacchi                                 IN const u64_t              data,
1427*d14abf15SRobert Mustacchi                                 IN const u32_t              curr_state)
1428*d14abf15SRobert Mustacchi {
1429*d14abf15SRobert Mustacchi     lm_status_t              lm_status        = LM_STATUS_SUCCESS;
1430*d14abf15SRobert Mustacchi     const niv_ramrod_state_t niv_ramrod_state = curr_state;
1431*d14abf15SRobert Mustacchi 
1432*d14abf15SRobert Mustacchi     DbgBreakIf((NIV_RAMROD_COMPLETED  == curr_state)||
1433*d14abf15SRobert Mustacchi                (NIV_RAMROD_NOT_POSTED == curr_state));
1434*d14abf15SRobert Mustacchi 
1435*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->slowpath_info.niv_ramrod_state != NIV_RAMROD_NOT_POSTED);
1436*d14abf15SRobert Mustacchi 
1437*d14abf15SRobert Mustacchi     lm_status = lm_eq_ramrod_post_sync(pdev,command,data,CMD_PRIORITY_NORMAL,&pdev->slowpath_info.niv_ramrod_state, niv_ramrod_state, NIV_RAMROD_COMPLETED);
1438*d14abf15SRobert Mustacchi     if (LM_STATUS_SUCCESS != lm_status)
1439*d14abf15SRobert Mustacchi     {
1440*d14abf15SRobert Mustacchi         DbgBreakIf(LM_STATUS_SUCCESS != lm_status);
1441*d14abf15SRobert Mustacchi         goto _exit;
1442*d14abf15SRobert Mustacchi     }
1443*d14abf15SRobert Mustacchi 
1444*d14abf15SRobert Mustacchi _exit:
1445*d14abf15SRobert Mustacchi     pdev->slowpath_info.niv_ramrod_state = NIV_RAMROD_NOT_POSTED;
1446*d14abf15SRobert Mustacchi     return lm_status;
1447*d14abf15SRobert Mustacchi }
1448*d14abf15SRobert Mustacchi 
lm_niv_vif_update(struct _lm_device_t * pdev,IN const u16_t vif_id,IN const u16_t default_vlan,IN const u8_t allowed_priorities)1449*d14abf15SRobert Mustacchi lm_status_t lm_niv_vif_update(struct _lm_device_t *pdev,
1450*d14abf15SRobert Mustacchi                               IN const u16_t       vif_id,
1451*d14abf15SRobert Mustacchi                               IN const u16_t       default_vlan,
1452*d14abf15SRobert Mustacchi                               IN const u8_t        allowed_priorities)
1453*d14abf15SRobert Mustacchi {
1454*d14abf15SRobert Mustacchi     lm_status_t                         lm_status   = LM_STATUS_FAILURE;
1455*d14abf15SRobert Mustacchi     struct function_update_data*        data        = LM_SLOWPATH(pdev, niv_function_update_data);
1456*d14abf15SRobert Mustacchi     lm_address_t                        data_phys   = LM_SLOWPATH_PHYS(pdev, niv_function_update_data);
1457*d14abf15SRobert Mustacchi 
1458*d14abf15SRobert Mustacchi     data->vif_id_change_flg              = TRUE;
1459*d14abf15SRobert Mustacchi     data->vif_id                         = mm_cpu_to_le16(vif_id);
1460*d14abf15SRobert Mustacchi     data->afex_default_vlan_change_flg   = TRUE;
1461*d14abf15SRobert Mustacchi     data->afex_default_vlan              = mm_cpu_to_le16(default_vlan);
1462*d14abf15SRobert Mustacchi     data->allowed_priorities_change_flg  = TRUE;
1463*d14abf15SRobert Mustacchi     data->allowed_priorities             = allowed_priorities;
1464*d14abf15SRobert Mustacchi 
1465*d14abf15SRobert Mustacchi     data->network_cos_mode_change_flg    = FALSE;
1466*d14abf15SRobert Mustacchi     data->lb_mode_en                     = FALSE; //if a VIF update was received it means we're connected to a switch, so we're not in LB mode.
1467*d14abf15SRobert Mustacchi     data->lb_mode_en_change_flg          = 1;
1468*d14abf15SRobert Mustacchi     data->echo                           = FUNC_UPDATE_RAMROD_SOURCE_NIV;
1469*d14abf15SRobert Mustacchi 
1470*d14abf15SRobert Mustacchi     lm_status = lm_niv_post_command(pdev,RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, data_phys.as_u64, NIV_RAMROD_VIF_UPDATE_POSTED);
1471*d14abf15SRobert Mustacchi 
1472*d14abf15SRobert Mustacchi     return lm_status;
1473*d14abf15SRobert Mustacchi }
1474*d14abf15SRobert Mustacchi 
lm_niv_vif_list_update(struct _lm_device_t * pdev,IN const enum vif_list_rule_kind command,IN const u16_t list_index,IN const u8_t func_bit_map,IN const u8_t func_to_clear)1475*d14abf15SRobert Mustacchi lm_status_t lm_niv_vif_list_update(struct _lm_device_t *pdev,
1476*d14abf15SRobert Mustacchi                                    IN const enum vif_list_rule_kind command,
1477*d14abf15SRobert Mustacchi                                    IN const u16_t                   list_index,
1478*d14abf15SRobert Mustacchi                                    IN const u8_t                    func_bit_map,
1479*d14abf15SRobert Mustacchi                                    IN const u8_t                    func_to_clear)
1480*d14abf15SRobert Mustacchi {
1481*d14abf15SRobert Mustacchi     struct afex_vif_list_ramrod_data data      = {0};
1482*d14abf15SRobert Mustacchi     lm_status_t                      lm_status = LM_STATUS_FAILURE;
1483*d14abf15SRobert Mustacchi 
1484*d14abf15SRobert Mustacchi     data.func_bit_map          = func_bit_map;
1485*d14abf15SRobert Mustacchi     data.func_to_clear         = func_to_clear;
1486*d14abf15SRobert Mustacchi     data.afex_vif_list_command = command;
1487*d14abf15SRobert Mustacchi     data.vif_list_index        = list_index;
1488*d14abf15SRobert Mustacchi     data.echo                  = command;
1489*d14abf15SRobert Mustacchi 
1490*d14abf15SRobert Mustacchi     lm_status = lm_niv_post_command(pdev,RAMROD_CMD_ID_COMMON_AFEX_VIF_LISTS, *((u64_t*)(&data)), NIV_RAMROD_VIF_LISTS_POSTED);
1491*d14abf15SRobert Mustacchi 
1492*d14abf15SRobert Mustacchi     return lm_status;
1493*d14abf15SRobert Mustacchi }
1494*d14abf15SRobert Mustacchi 
1495*d14abf15SRobert Mustacchi 
1496*d14abf15SRobert Mustacchi 
1497*d14abf15SRobert Mustacchi /****************** CLASSIFICATION ********************************/
1498*d14abf15SRobert Mustacchi /**
1499*d14abf15SRobert Mustacchi  * Set/Unset a mac-address or mac-vlan pair on a given chain.
1500*d14abf15SRobert Mustacchi  *
1501*d14abf15SRobert Mustacchi  * @param pdev
1502*d14abf15SRobert Mustacchi  * @param mac_addr  - array of size ETHERNET_ADDRESS_SIZE
1503*d14abf15SRobert Mustacchi  *                    containing a valid mac addresses
1504*d14abf15SRobert Mustacchi  * @param vlan_tag  - vlan tag to be set with mac address
1505*d14abf15SRobert Mustacchi  * @param chain_idx - which chain to set the mac on. Chain_idx
1506*d14abf15SRobert Mustacchi  *                    will be transformed to a l2 client-id
1507*d14abf15SRobert Mustacchi  * @param cookie    - will be returned to MM layer on completion
1508*d14abf15SRobert Mustacchi  * @param set       - set or remove mac address
1509*d14abf15SRobert Mustacchi  * @param is_encap_inner_mac_filter - set if we filter according
1510*d14abf15SRobert Mustacchi  *                                  to inner mac (VMQ offload of
1511*d14abf15SRobert Mustacchi  *                                  encapsulated packets)
1512*d14abf15SRobert Mustacchi  *
1513*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS on syncrounous success, PENDING
1514*d14abf15SRobert Mustacchi  *         if completion will be called later, FAILURE o/w
1515*d14abf15SRobert Mustacchi  */
lm_set_mac_addr(struct _lm_device_t * pdev,u8_t * mac_addr,u16_t vlan_tag,u8_t chain_idx,void * cookie,const u8_t b_set,u8_t is_encap_inner_mac_filter)1516*d14abf15SRobert Mustacchi lm_status_t lm_set_mac_addr(struct _lm_device_t *pdev,
1517*d14abf15SRobert Mustacchi                             u8_t                *mac_addr,
1518*d14abf15SRobert Mustacchi                             u16_t               vlan_tag,
1519*d14abf15SRobert Mustacchi                             u8_t                chain_idx,
1520*d14abf15SRobert Mustacchi                             void*               cookie,
1521*d14abf15SRobert Mustacchi                             const u8_t          b_set,
1522*d14abf15SRobert Mustacchi                             u8_t                is_encap_inner_mac_filter)
1523*d14abf15SRobert Mustacchi {
1524*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params ramrod_param  = { 0 };
1525*d14abf15SRobert Mustacchi     lm_status_t                         lm_status     = LM_STATUS_FAILURE;
1526*d14abf15SRobert Mustacchi     ecore_status_t                      ecore_status  = ECORE_SUCCESS;
1527*d14abf15SRobert Mustacchi     lm_cli_idx_t                        lm_cli_idx    = LM_CLI_IDX_MAX;
1528*d14abf15SRobert Mustacchi     u8_t                                cid           = chain_idx; // FIXME!!!
1529*d14abf15SRobert Mustacchi 
1530*d14abf15SRobert Mustacchi     if ERR_IF(!mac_addr)
1531*d14abf15SRobert Mustacchi     {
1532*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_set_mac_addr: invalid params\n");
1533*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1534*d14abf15SRobert Mustacchi     }
1535*d14abf15SRobert Mustacchi 
1536*d14abf15SRobert Mustacchi     if (lm_reset_is_inprogress(pdev))
1537*d14abf15SRobert Mustacchi     {
1538*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_set_mac_addr: Under FLR!!!\n");
1539*d14abf15SRobert Mustacchi         return  LM_STATUS_SUCCESS;
1540*d14abf15SRobert Mustacchi     }
1541*d14abf15SRobert Mustacchi 
1542*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
1543*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
1544*d14abf15SRobert Mustacchi     {
1545*d14abf15SRobert Mustacchi         lm_status = lm_vf_pf_set_q_filters(pdev, LM_CLI_IDX_NDIS, cookie, Q_FILTER_MAC, mac_addr, ETHERNET_ADDRESS_SIZE,vlan_tag, b_set);
1546*d14abf15SRobert Mustacchi         return lm_status;
1547*d14abf15SRobert Mustacchi     }
1548*d14abf15SRobert Mustacchi #endif
1549*d14abf15SRobert Mustacchi 
1550*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARN/*INFORMl2sp*/, "lm_set_mac_addr: b_set=%d chain_idx=%d!!!\n", b_set, chain_idx);
1551*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_set_mac_addr: [%02x]:[%02x]:[%02x]:[%02x]:[%02x]:[%02x]!!!\n",
1552*d14abf15SRobert Mustacchi                                    mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
1553*d14abf15SRobert Mustacchi 
1554*d14abf15SRobert Mustacchi     /* Prepare ramrod params to be sent to ecore layer... */
1555*d14abf15SRobert Mustacchi     if (vlan_tag != LM_SET_CAM_NO_VLAN_FILTER)
1556*d14abf15SRobert Mustacchi     {
1557*d14abf15SRobert Mustacchi         DbgBreakIf(CHIP_IS_E1(pdev));
1558*d14abf15SRobert Mustacchi 
1559*d14abf15SRobert Mustacchi         ASSERT_STATIC( ETHERNET_ADDRESS_SIZE == sizeof(ramrod_param.user_req.u.vlan_mac.mac) );
1560*d14abf15SRobert Mustacchi 
1561*d14abf15SRobert Mustacchi         mm_memcpy( ramrod_param.user_req.u.vlan_mac.mac, mac_addr, sizeof(ramrod_param.user_req.u.vlan_mac.mac));
1562*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.vlan_mac.vlan = vlan_tag;
1563*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.vlan_mac.is_inner_mac = is_encap_inner_mac_filter;
1564*d14abf15SRobert Mustacchi 
1565*d14abf15SRobert Mustacchi         ramrod_param.vlan_mac_obj = &pdev->client_info[chain_idx].mac_vlan_obj;
1566*d14abf15SRobert Mustacchi     }
1567*d14abf15SRobert Mustacchi     else
1568*d14abf15SRobert Mustacchi     {
1569*d14abf15SRobert Mustacchi         ASSERT_STATIC( ETHERNET_ADDRESS_SIZE == sizeof(ramrod_param.user_req.u.mac.mac) );
1570*d14abf15SRobert Mustacchi 
1571*d14abf15SRobert Mustacchi         mm_memcpy( ramrod_param.user_req.u.mac.mac, mac_addr, sizeof(ramrod_param.user_req.u.mac.mac) );
1572*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.mac.is_inner_mac = is_encap_inner_mac_filter;
1573*d14abf15SRobert Mustacchi 
1574*d14abf15SRobert Mustacchi         ramrod_param.vlan_mac_obj = &pdev->client_info[chain_idx].mac_obj;
1575*d14abf15SRobert Mustacchi     }
1576*d14abf15SRobert Mustacchi     /* Set the cookie BEFORE sending the ramrod!!!! ramrod may complete in the mean time... */
1577*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->client_info[cid].set_mac_cookie != NULL);
1578*d14abf15SRobert Mustacchi     pdev->client_info[cid].set_mac_cookie = cookie;
1579*d14abf15SRobert Mustacchi 
1580*d14abf15SRobert Mustacchi     ramrod_param.user_req.cmd = b_set ? ECORE_VLAN_MAC_ADD : ECORE_VLAN_MAC_DEL;
1581*d14abf15SRobert Mustacchi 
1582*d14abf15SRobert Mustacchi     lm_cli_idx = LM_CHAIN_IDX_CLI(pdev, chain_idx);
1583*d14abf15SRobert Mustacchi 
1584*d14abf15SRobert Mustacchi     SET_BIT( ramrod_param.ramrod_flags, RAMROD_EXEC );
1585*d14abf15SRobert Mustacchi 
1586*d14abf15SRobert Mustacchi     switch (lm_cli_idx)
1587*d14abf15SRobert Mustacchi     {
1588*d14abf15SRobert Mustacchi     case LM_CLI_IDX_NDIS:
1589*d14abf15SRobert Mustacchi         SET_BIT (ramrod_param.user_req.vlan_mac_flags, ECORE_ETH_MAC);
1590*d14abf15SRobert Mustacchi         break;
1591*d14abf15SRobert Mustacchi 
1592*d14abf15SRobert Mustacchi     case LM_CLI_IDX_ISCSI:
1593*d14abf15SRobert Mustacchi         SET_BIT (ramrod_param.user_req.vlan_mac_flags, ECORE_ISCSI_ETH_MAC);
1594*d14abf15SRobert Mustacchi         break;
1595*d14abf15SRobert Mustacchi 
1596*d14abf15SRobert Mustacchi     default:
1597*d14abf15SRobert Mustacchi         /* Nothing... */
1598*d14abf15SRobert Mustacchi         break;
1599*d14abf15SRobert Mustacchi     }
1600*d14abf15SRobert Mustacchi 
1601*d14abf15SRobert Mustacchi     ecore_status = ecore_config_vlan_mac(pdev, &ramrod_param );
1602*d14abf15SRobert Mustacchi     lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1603*d14abf15SRobert Mustacchi 
1604*d14abf15SRobert Mustacchi     if( LM_STATUS_PENDING != lm_status )
1605*d14abf15SRobert Mustacchi     {
1606*d14abf15SRobert Mustacchi         pdev->client_info[cid].set_mac_cookie = NULL; // rollback
1607*d14abf15SRobert Mustacchi     }
1608*d14abf15SRobert Mustacchi     return lm_status;
1609*d14abf15SRobert Mustacchi }
1610*d14abf15SRobert Mustacchi 
1611*d14abf15SRobert Mustacchi /**
1612*d14abf15SRobert Mustacchi  * Set/Unset a vlan on a given chain.
1613*d14abf15SRobert Mustacchi  *      Setting/unsetting a vlan is a bit more complex than
1614*d14abf15SRobert Mustacchi  *      setting a mac address and is therefore implemented in a
1615*d14abf15SRobert Mustacchi  *      separate function. It require deleting a previous vlan
1616*d14abf15SRobert Mustacchi  *      tag if one was set, and changing rx-filtering rules. The
1617*d14abf15SRobert Mustacchi  *      change in rx-filtering rules has to do with "any-vlan".
1618*d14abf15SRobert Mustacchi  *      If no vlan is set we want "any-vlan" otherwise we want
1619*d14abf15SRobert Mustacchi  *      to remove the any-vlan, this requires another ramrod.
1620*d14abf15SRobert Mustacchi  *      The way this is implemented is as follows:
1621*d14abf15SRobert Mustacchi  *          1. prepare vlan add/remove commands without
1622*d14abf15SRobert Mustacchi  *          executing them (sp-verbs feature don't send EXEC)
1623*d14abf15SRobert Mustacchi  *          2. If need to set rx-mask, turn on a flag that will
1624*d14abf15SRobert Mustacchi  *          be checked on completion of rx-mask, in
1625*d14abf15SRobert Mustacchi  *          lm_eq_handle_rx_filter.., we look at this flag and
1626*d14abf15SRobert Mustacchi  *          if it's on execute the vlan pending command
1627*d14abf15SRobert Mustacchi  *          (sp-verbs CONT feature).
1628*d14abf15SRobert Mustacchi  *
1629*d14abf15SRobert Mustacchi  * @param pdev
1630*d14abf15SRobert Mustacchi  * @param vlan_tag  - vlan tag to be set
1631*d14abf15SRobert Mustacchi  * @param chain_idx - which chain to set the vlan on. Chain_idx
1632*d14abf15SRobert Mustacchi  *                    will be transformed to a l2 client-id
1633*d14abf15SRobert Mustacchi  * @param cookie    - will be returned to MM layer on completion
1634*d14abf15SRobert Mustacchi  * @param set       - set or remove vlan
1635*d14abf15SRobert Mustacchi  *
1636*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS on syncrounous success, PENDING
1637*d14abf15SRobert Mustacchi  *         if completion will be called later, FAILURE o/w
1638*d14abf15SRobert Mustacchi  */
lm_set_vlan_only(struct _lm_device_t * pdev,u16_t vlan_tag,u8_t chain_idx,void * cookie,const u8_t b_set)1639*d14abf15SRobert Mustacchi lm_status_t lm_set_vlan_only(struct _lm_device_t *pdev,
1640*d14abf15SRobert Mustacchi                              u16_t               vlan_tag,
1641*d14abf15SRobert Mustacchi                              u8_t                chain_idx,
1642*d14abf15SRobert Mustacchi                              void*               cookie,
1643*d14abf15SRobert Mustacchi                              const u8_t          b_set )
1644*d14abf15SRobert Mustacchi {
1645*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params ramrod_param       = { 0 };
1646*d14abf15SRobert Mustacchi     lm_status_t                         lm_status          = LM_STATUS_FAILURE;
1647*d14abf15SRobert Mustacchi     ecore_status_t                      ecore_status       = ECORE_SUCCESS;
1648*d14abf15SRobert Mustacchi     lm_cli_idx_t                        lm_cli_idx         = LM_CLI_IDX_MAX;
1649*d14abf15SRobert Mustacchi     u8_t                                cid                = chain_idx; // FIXME!!!
1650*d14abf15SRobert Mustacchi     u8_t                                b_set_rx_mask      = FALSE;
1651*d14abf15SRobert Mustacchi 
1652*d14abf15SRobert Mustacchi     if (lm_reset_is_inprogress(pdev))
1653*d14abf15SRobert Mustacchi     {
1654*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_set_mac_addr: Under FLR!!!\n");
1655*d14abf15SRobert Mustacchi         return  LM_STATUS_SUCCESS;
1656*d14abf15SRobert Mustacchi     }
1657*d14abf15SRobert Mustacchi 
1658*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
1659*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
1660*d14abf15SRobert Mustacchi     {
1661*d14abf15SRobert Mustacchi         /* 9/22/11 Michals: should we support this for VFs??? */
1662*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1663*d14abf15SRobert Mustacchi     }
1664*d14abf15SRobert Mustacchi #endif
1665*d14abf15SRobert Mustacchi 
1666*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_set_vlan_only: b_set=%d chain_idx=%d!!!\n", b_set, chain_idx);
1667*d14abf15SRobert Mustacchi 
1668*d14abf15SRobert Mustacchi     /* Prepare ramrod params to be sent to ecore layer... */
1669*d14abf15SRobert Mustacchi     if (CHIP_IS_E1x(pdev))
1670*d14abf15SRobert Mustacchi     {
1671*d14abf15SRobert Mustacchi         DbgMessage(pdev, WARN/*INFORMl2sp*/, "lm_set_vlan_only: not supported for E1x!!!\n");
1672*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
1673*d14abf15SRobert Mustacchi     }
1674*d14abf15SRobert Mustacchi 
1675*d14abf15SRobert Mustacchi     ramrod_param.vlan_mac_obj = &pdev->client_info[chain_idx].vlan_obj;
1676*d14abf15SRobert Mustacchi     if (pdev->client_info[chain_idx].current_set_vlan == vlan_tag)
1677*d14abf15SRobert Mustacchi     {
1678*d14abf15SRobert Mustacchi         return LM_STATUS_EXISTING_OBJECT;
1679*d14abf15SRobert Mustacchi     }
1680*d14abf15SRobert Mustacchi 
1681*d14abf15SRobert Mustacchi     /* Set the cookie BEFORE sending the ramrod!!!! ramrod may complete in the mean time... */
1682*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->client_info[cid].set_mac_cookie != NULL);
1683*d14abf15SRobert Mustacchi     pdev->client_info[cid].set_mac_cookie = cookie;
1684*d14abf15SRobert Mustacchi 
1685*d14abf15SRobert Mustacchi 
1686*d14abf15SRobert Mustacchi     if (b_set)
1687*d14abf15SRobert Mustacchi     {
1688*d14abf15SRobert Mustacchi         /* If we're just setting vlan, check if we need to delete the old one first... */
1689*d14abf15SRobert Mustacchi         if (pdev->client_info[chain_idx].current_set_vlan != 0)
1690*d14abf15SRobert Mustacchi         {
1691*d14abf15SRobert Mustacchi             ramrod_param.user_req.u.vlan.vlan = pdev->client_info[chain_idx].current_set_vlan;
1692*d14abf15SRobert Mustacchi             ramrod_param.user_req.cmd = ECORE_VLAN_MAC_DEL;
1693*d14abf15SRobert Mustacchi 
1694*d14abf15SRobert Mustacchi             ecore_status = ecore_config_vlan_mac(pdev, &ramrod_param );
1695*d14abf15SRobert Mustacchi             /* don't really care about the status... */
1696*d14abf15SRobert Mustacchi         }
1697*d14abf15SRobert Mustacchi 
1698*d14abf15SRobert Mustacchi         /* Prepare for the setting... */
1699*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.vlan.vlan = vlan_tag;
1700*d14abf15SRobert Mustacchi     }
1701*d14abf15SRobert Mustacchi     else
1702*d14abf15SRobert Mustacchi     {
1703*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.vlan.vlan = pdev->client_info[chain_idx].current_set_vlan;
1704*d14abf15SRobert Mustacchi     }
1705*d14abf15SRobert Mustacchi 
1706*d14abf15SRobert Mustacchi     pdev->client_info[chain_idx].current_set_vlan = vlan_tag;
1707*d14abf15SRobert Mustacchi 
1708*d14abf15SRobert Mustacchi     ramrod_param.user_req.cmd = b_set ? ECORE_VLAN_MAC_ADD : ECORE_VLAN_MAC_DEL;
1709*d14abf15SRobert Mustacchi 
1710*d14abf15SRobert Mustacchi     lm_cli_idx = LM_CHAIN_IDX_CLI(pdev, chain_idx);
1711*d14abf15SRobert Mustacchi 
1712*d14abf15SRobert Mustacchi     /* Determine if rx-mask needs to be changed as a result of this update. */
1713*d14abf15SRobert Mustacchi     b_set_rx_mask = (( b_set &&  pdev->client_info[cid].b_any_vlan_on) ||
1714*d14abf15SRobert Mustacchi                      (!b_set && !pdev->client_info[cid].b_any_vlan_on) );
1715*d14abf15SRobert Mustacchi 
1716*d14abf15SRobert Mustacchi     /* If we don't need to change the mask we need to execute commands now, otherwise they'll
1717*d14abf15SRobert Mustacchi        be executed from rx filter completion */
1718*d14abf15SRobert Mustacchi     if (!b_set_rx_mask )
1719*d14abf15SRobert Mustacchi     {
1720*d14abf15SRobert Mustacchi         SET_BIT( ramrod_param.ramrod_flags, RAMROD_EXEC );
1721*d14abf15SRobert Mustacchi     }
1722*d14abf15SRobert Mustacchi 
1723*d14abf15SRobert Mustacchi     ecore_status = ecore_config_vlan_mac(pdev, &ramrod_param );
1724*d14abf15SRobert Mustacchi     lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1725*d14abf15SRobert Mustacchi 
1726*d14abf15SRobert Mustacchi     if( (LM_STATUS_PENDING != lm_status) )
1727*d14abf15SRobert Mustacchi     {
1728*d14abf15SRobert Mustacchi         pdev->client_info[cid].set_mac_cookie = NULL; /* rollback */
1729*d14abf15SRobert Mustacchi         return lm_status;
1730*d14abf15SRobert Mustacchi     }
1731*d14abf15SRobert Mustacchi 
1732*d14abf15SRobert Mustacchi     /* see function description to understand this better... */
1733*d14abf15SRobert Mustacchi     if (b_set_rx_mask)
1734*d14abf15SRobert Mustacchi     {
1735*d14abf15SRobert Mustacchi         pdev->client_info[chain_idx].b_vlan_only_in_process = TRUE;
1736*d14abf15SRobert Mustacchi         lm_status = lm_set_rx_mask(pdev, cid, pdev->client_info[cid].last_set_rx_mask, NULL);
1737*d14abf15SRobert Mustacchi     }
1738*d14abf15SRobert Mustacchi 
1739*d14abf15SRobert Mustacchi     return lm_status;
1740*d14abf15SRobert Mustacchi }
1741*d14abf15SRobert Mustacchi /**
1742*d14abf15SRobert Mustacchi  *  Move a filter from one chain idx to another atomically
1743*d14abf15SRobert Mustacchi  *
1744*d14abf15SRobert Mustacchi  * @param pdev
1745*d14abf15SRobert Mustacchi  *
1746*d14abf15SRobert Mustacchi  * @param mac_addr       - array of size ETHERNET_ADDRESS_SIZE
1747*d14abf15SRobert Mustacchi  *                         containing a valid mac addresses
1748*d14abf15SRobert Mustacchi  * @param vlan_tag       - vlan tag to be set with mac address
1749*d14abf15SRobert Mustacchi  * @param src_chain_idx  - which chain to remove the mac from
1750*d14abf15SRobert Mustacchi  * @param dest_chain_idx - which chain to set the mac on
1751*d14abf15SRobert Mustacchi  * @param cookie         - will be returned to MM layer on completion
1752*d14abf15SRobert Mustacchi  *
1753*d14abf15SRobert Mustacchi  * @return lm_status_t
1754*d14abf15SRobert Mustacchi  */
lm_move_mac_addr(struct _lm_device_t * pdev,u8_t * mac_addr,u16_t vlan_tag,u8_t src_chain_idx,u8_t dest_chain_idx,void * cookie,u8_t is_encap_inner_mac_filter)1755*d14abf15SRobert Mustacchi lm_status_t lm_move_mac_addr(struct _lm_device_t *pdev, u8_t *mac_addr, u16_t vlan_tag,
1756*d14abf15SRobert Mustacchi                              u8_t src_chain_idx,  u8_t dest_chain_idx, void * cookie, u8_t is_encap_inner_mac_filter)
1757*d14abf15SRobert Mustacchi {
1758*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params ramrod_param = { 0 };
1759*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj          *dest_obj     = NULL;
1760*d14abf15SRobert Mustacchi     lm_status_t                         lm_status    = LM_STATUS_FAILURE;
1761*d14abf15SRobert Mustacchi     ecore_status_t                      ecore_status = ECORE_SUCCESS;
1762*d14abf15SRobert Mustacchi     u8_t                                sw_client_id       = src_chain_idx;
1763*d14abf15SRobert Mustacchi 
1764*d14abf15SRobert Mustacchi     if ERR_IF(!pdev || !mac_addr)
1765*d14abf15SRobert Mustacchi     {
1766*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_move_mac_addr: invalid params\n");
1767*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
1768*d14abf15SRobert Mustacchi     }
1769*d14abf15SRobert Mustacchi 
1770*d14abf15SRobert Mustacchi     if (lm_reset_is_inprogress(pdev))
1771*d14abf15SRobert Mustacchi     {
1772*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_move_mac_addr: Under FLR!!!\n");
1773*d14abf15SRobert Mustacchi         return  LM_STATUS_SUCCESS;
1774*d14abf15SRobert Mustacchi     }
1775*d14abf15SRobert Mustacchi 
1776*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
1777*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
1778*d14abf15SRobert Mustacchi     {
1779*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_move_mac_addr: Move not expected on VF\n");
1780*d14abf15SRobert Mustacchi         return lm_status;
1781*d14abf15SRobert Mustacchi     }
1782*d14abf15SRobert Mustacchi #endif
1783*d14abf15SRobert Mustacchi 
1784*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_move_mac_addr: src_chain_idx=%d dest_chain_idx=%d!!!\n",
1785*d14abf15SRobert Mustacchi                src_chain_idx, dest_chain_idx);
1786*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_move_mac_addr: [%d]:[%d]:[%d]:[%d]:[%d]:[%d] set=%d chain_idx=%d!!!\n",
1787*d14abf15SRobert Mustacchi                mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], mac_addr[6]);
1788*d14abf15SRobert Mustacchi 
1789*d14abf15SRobert Mustacchi     /* Prepare ramrod params to be sent to ecore layer... */
1790*d14abf15SRobert Mustacchi     if (vlan_tag != LM_SET_CAM_NO_VLAN_FILTER)
1791*d14abf15SRobert Mustacchi     {
1792*d14abf15SRobert Mustacchi         mm_memcpy( ramrod_param.user_req.u.vlan_mac.mac, mac_addr, sizeof(ramrod_param.user_req.u.vlan_mac.mac));
1793*d14abf15SRobert Mustacchi         ramrod_param.user_req.u.vlan_mac.vlan = vlan_tag;
1794*d14abf15SRobert Mustacchi 	ramrod_param.user_req.u.vlan_mac.is_inner_mac = is_encap_inner_mac_filter;
1795*d14abf15SRobert Mustacchi         ramrod_param.vlan_mac_obj = &pdev->client_info[src_chain_idx].mac_vlan_obj;
1796*d14abf15SRobert Mustacchi         dest_obj = &pdev->client_info[dest_chain_idx].mac_vlan_obj;
1797*d14abf15SRobert Mustacchi     }
1798*d14abf15SRobert Mustacchi     else
1799*d14abf15SRobert Mustacchi     {
1800*d14abf15SRobert Mustacchi         mm_memcpy( ramrod_param.user_req.u.mac.mac, mac_addr, sizeof(ramrod_param.user_req.u.mac.mac) );
1801*d14abf15SRobert Mustacchi 	ramrod_param.user_req.u.mac.is_inner_mac = is_encap_inner_mac_filter;
1802*d14abf15SRobert Mustacchi 
1803*d14abf15SRobert Mustacchi         ramrod_param.vlan_mac_obj = &pdev->client_info[src_chain_idx].mac_obj;
1804*d14abf15SRobert Mustacchi         dest_obj = &pdev->client_info[dest_chain_idx].mac_obj;
1805*d14abf15SRobert Mustacchi     }
1806*d14abf15SRobert Mustacchi 
1807*d14abf15SRobert Mustacchi 
1808*d14abf15SRobert Mustacchi     /* Set the cookie BEFORE sending the ramrod!!!! ramrod may complete in the mean time... */
1809*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->client_info[sw_client_id].set_mac_cookie != NULL);
1810*d14abf15SRobert Mustacchi     pdev->client_info[sw_client_id].set_mac_cookie = cookie;
1811*d14abf15SRobert Mustacchi 
1812*d14abf15SRobert Mustacchi     ramrod_param.user_req.cmd = ECORE_VLAN_MAC_MOVE;
1813*d14abf15SRobert Mustacchi 
1814*d14abf15SRobert Mustacchi     ramrod_param.user_req.target_obj = dest_obj;
1815*d14abf15SRobert Mustacchi 
1816*d14abf15SRobert Mustacchi     SET_BIT( ramrod_param.ramrod_flags, RAMROD_EXEC );
1817*d14abf15SRobert Mustacchi 
1818*d14abf15SRobert Mustacchi     ecore_status = ecore_config_vlan_mac(pdev, &ramrod_param );
1819*d14abf15SRobert Mustacchi 
1820*d14abf15SRobert Mustacchi     lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1821*d14abf15SRobert Mustacchi 
1822*d14abf15SRobert Mustacchi     if ( LM_STATUS_PENDING == lm_status )
1823*d14abf15SRobert Mustacchi     {
1824*d14abf15SRobert Mustacchi         /* FIXME: VF MACS in NIG stay??*/
1825*d14abf15SRobert Mustacchi     }
1826*d14abf15SRobert Mustacchi     else
1827*d14abf15SRobert Mustacchi     {
1828*d14abf15SRobert Mustacchi         pdev->client_info[sw_client_id].set_mac_cookie = NULL; // rollback
1829*d14abf15SRobert Mustacchi     }
1830*d14abf15SRobert Mustacchi     return lm_status;
1831*d14abf15SRobert Mustacchi }
1832*d14abf15SRobert Mustacchi 
1833*d14abf15SRobert Mustacchi /**
1834*d14abf15SRobert Mustacchi  * @Description
1835*d14abf15SRobert Mustacchi  *      Waits for the last set-mac called to complete, could be
1836*d14abf15SRobert Mustacchi  *      set-mac or set-mac-vlan...
1837*d14abf15SRobert Mustacchi  * @param pdev
1838*d14abf15SRobert Mustacchi  * @param chain_idx - the same chain-idx that the set-mac was
1839*d14abf15SRobert Mustacchi  *                  called on
1840*d14abf15SRobert Mustacchi  *
1841*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS or TIMEOUT
1842*d14abf15SRobert Mustacchi  */
lm_wait_set_mac_done(struct _lm_device_t * pdev,u8_t chain_idx)1843*d14abf15SRobert Mustacchi lm_status_t lm_wait_set_mac_done(struct _lm_device_t *pdev, u8_t chain_idx)
1844*d14abf15SRobert Mustacchi {
1845*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj *mac_obj      = &pdev->client_info[chain_idx].mac_obj;
1846*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj *mac_vlan_obj = &pdev->client_info[chain_idx].mac_vlan_obj;
1847*d14abf15SRobert Mustacchi     ecore_status_t            ecore_status  = mac_obj->wait(pdev, mac_obj);
1848*d14abf15SRobert Mustacchi     lm_status_t               lm_status     = lm_ecore_status_to_lm_status(ecore_status);
1849*d14abf15SRobert Mustacchi 
1850*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
1851*d14abf15SRobert Mustacchi     {
1852*d14abf15SRobert Mustacchi         DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1853*d14abf15SRobert Mustacchi         return lm_status;
1854*d14abf15SRobert Mustacchi     }
1855*d14abf15SRobert Mustacchi 
1856*d14abf15SRobert Mustacchi     if (!CHIP_IS_E1(pdev))
1857*d14abf15SRobert Mustacchi     {
1858*d14abf15SRobert Mustacchi         ecore_status = mac_vlan_obj->wait(pdev, mac_vlan_obj);
1859*d14abf15SRobert Mustacchi         lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1860*d14abf15SRobert Mustacchi 
1861*d14abf15SRobert Mustacchi         DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1862*d14abf15SRobert Mustacchi     }
1863*d14abf15SRobert Mustacchi 
1864*d14abf15SRobert Mustacchi     return lm_status;
1865*d14abf15SRobert Mustacchi }
1866*d14abf15SRobert Mustacchi 
1867*d14abf15SRobert Mustacchi /**
1868*d14abf15SRobert Mustacchi  * @Description
1869*d14abf15SRobert Mustacchi  *      Waits for the last set-vlan called to complete
1870*d14abf15SRobert Mustacchi  * @param pdev
1871*d14abf15SRobert Mustacchi  * @param chain_idx - the same chain-idx that the set-vlan was
1872*d14abf15SRobert Mustacchi  *                  called on
1873*d14abf15SRobert Mustacchi  *
1874*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS or TIMEOUT
1875*d14abf15SRobert Mustacchi  */
lm_wait_set_vlan_done(struct _lm_device_t * pdev,u8_t chain_idx)1876*d14abf15SRobert Mustacchi lm_status_t lm_wait_set_vlan_done(struct _lm_device_t *pdev, u8_t chain_idx)
1877*d14abf15SRobert Mustacchi {
1878*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj *vlan_obj     = &pdev->client_info[chain_idx].vlan_obj;
1879*d14abf15SRobert Mustacchi     lm_status_t               lm_status     = LM_STATUS_SUCCESS;
1880*d14abf15SRobert Mustacchi     ecore_status_t            ecore_status;
1881*d14abf15SRobert Mustacchi 
1882*d14abf15SRobert Mustacchi     if (!CHIP_IS_E1x(pdev))
1883*d14abf15SRobert Mustacchi     {
1884*d14abf15SRobert Mustacchi         ecore_status = vlan_obj->wait(pdev, vlan_obj);
1885*d14abf15SRobert Mustacchi         lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1886*d14abf15SRobert Mustacchi 
1887*d14abf15SRobert Mustacchi         DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1888*d14abf15SRobert Mustacchi     }
1889*d14abf15SRobert Mustacchi 
1890*d14abf15SRobert Mustacchi     return lm_status;
1891*d14abf15SRobert Mustacchi }
1892*d14abf15SRobert Mustacchi 
1893*d14abf15SRobert Mustacchi 
1894*d14abf15SRobert Mustacchi /**
1895*d14abf15SRobert Mustacchi  * Description
1896*d14abf15SRobert Mustacchi  *      Clears all the mac address that are set on a certain cid...
1897*d14abf15SRobert Mustacchi  * @param pdev
1898*d14abf15SRobert Mustacchi  * @param chain_idx - which chain_idx to clear macs on...
1899*d14abf15SRobert Mustacchi  *
1900*d14abf15SRobert Mustacchi  * @assumptions: Called in PASSIVE_LEVEL!! function sleeps...
1901*d14abf15SRobert Mustacchi  * @return lm_status_t
1902*d14abf15SRobert Mustacchi  */
lm_clear_all_mac_addr(struct _lm_device_t * pdev,const u8_t chain_idx)1903*d14abf15SRobert Mustacchi lm_status_t lm_clear_all_mac_addr(struct _lm_device_t *pdev, const u8_t chain_idx)
1904*d14abf15SRobert Mustacchi {
1905*d14abf15SRobert Mustacchi #define THE_REST_OF_ETH_MAC 0xffff
1906*d14abf15SRobert Mustacchi 
1907*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params   ramrod_params    = {0};
1908*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj           * vlan_mac_obj     = NULL;
1909*d14abf15SRobert Mustacchi     lm_status_t                           lm_status        = LM_STATUS_FAILURE;
1910*d14abf15SRobert Mustacchi     ecore_status_t                        ecore_status     = ECORE_SUCCESS;
1911*d14abf15SRobert Mustacchi     u32_t                                 mac_types[]      = {ECORE_ETH_MAC, ECORE_ISCSI_ETH_MAC, THE_REST_OF_ETH_MAC};
1912*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj           * vlan_mac_objs[2] = {NULL, NULL};
1913*d14abf15SRobert Mustacchi     u8_t                                  idx              = 0;
1914*d14abf15SRobert Mustacchi     u8_t                                  obj_idx          = 0;
1915*d14abf15SRobert Mustacchi 
1916*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_clear_all_mac_addr chain_idx=%d\n", chain_idx);
1917*d14abf15SRobert Mustacchi 
1918*d14abf15SRobert Mustacchi     vlan_mac_objs[0] = &pdev->client_info[chain_idx].mac_obj;
1919*d14abf15SRobert Mustacchi     vlan_mac_objs[1] = &pdev->client_info[chain_idx].mac_vlan_obj;
1920*d14abf15SRobert Mustacchi 
1921*d14abf15SRobert Mustacchi     for (obj_idx = 0; obj_idx < ARRSIZE(vlan_mac_objs); obj_idx++)
1922*d14abf15SRobert Mustacchi     {
1923*d14abf15SRobert Mustacchi         vlan_mac_obj = vlan_mac_objs[obj_idx];
1924*d14abf15SRobert Mustacchi         ramrod_params.vlan_mac_obj = vlan_mac_obj;
1925*d14abf15SRobert Mustacchi 
1926*d14abf15SRobert Mustacchi         /* mac_vlan_obj only relevant for chips that are not E1... */
1927*d14abf15SRobert Mustacchi         if ((vlan_mac_obj == &pdev->client_info[chain_idx].mac_vlan_obj) &&
1928*d14abf15SRobert Mustacchi             CHIP_IS_E1(pdev))
1929*d14abf15SRobert Mustacchi         {
1930*d14abf15SRobert Mustacchi             break;
1931*d14abf15SRobert Mustacchi         }
1932*d14abf15SRobert Mustacchi 
1933*d14abf15SRobert Mustacchi         for (idx = 0; idx < ARRSIZE(mac_types); idx++)
1934*d14abf15SRobert Mustacchi         {
1935*d14abf15SRobert Mustacchi             SET_BIT( ramrod_params.ramrod_flags, RAMROD_COMP_WAIT);
1936*d14abf15SRobert Mustacchi             ramrod_params.user_req.vlan_mac_flags = 0;
1937*d14abf15SRobert Mustacchi             if (mac_types[idx] != THE_REST_OF_ETH_MAC)
1938*d14abf15SRobert Mustacchi             {
1939*d14abf15SRobert Mustacchi                 SET_BIT( ramrod_params.user_req.vlan_mac_flags, mac_types[idx]);
1940*d14abf15SRobert Mustacchi             }
1941*d14abf15SRobert Mustacchi 
1942*d14abf15SRobert Mustacchi             ecore_status = vlan_mac_obj->delete_all( pdev, ramrod_params.vlan_mac_obj, &ramrod_params.user_req.vlan_mac_flags, &ramrod_params.ramrod_flags );
1943*d14abf15SRobert Mustacchi             lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1944*d14abf15SRobert Mustacchi 
1945*d14abf15SRobert Mustacchi             if (lm_status != LM_STATUS_SUCCESS)
1946*d14abf15SRobert Mustacchi             {
1947*d14abf15SRobert Mustacchi                 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1948*d14abf15SRobert Mustacchi                 return lm_status;
1949*d14abf15SRobert Mustacchi             }
1950*d14abf15SRobert Mustacchi 
1951*d14abf15SRobert Mustacchi         }
1952*d14abf15SRobert Mustacchi     }
1953*d14abf15SRobert Mustacchi 
1954*d14abf15SRobert Mustacchi     DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1955*d14abf15SRobert Mustacchi     return lm_status;
1956*d14abf15SRobert Mustacchi }
1957*d14abf15SRobert Mustacchi 
1958*d14abf15SRobert Mustacchi 
1959*d14abf15SRobert Mustacchi 
1960*d14abf15SRobert Mustacchi /**
1961*d14abf15SRobert Mustacchi  * Description
1962*d14abf15SRobert Mustacchi  *      Restores all the mac address that are set on a certain
1963*d14abf15SRobert Mustacchi  *      cid (after sleep / hibernate...)
1964*d14abf15SRobert Mustacchi  * @param pdev
1965*d14abf15SRobert Mustacchi  * @param chain_idx - which chain_idx to clear macs on...
1966*d14abf15SRobert Mustacchi  *
1967*d14abf15SRobert Mustacchi  * @assumptions: Called in PASSIVE_LEVEL!! function sleeps...
1968*d14abf15SRobert Mustacchi  * @return lm_status_t
1969*d14abf15SRobert Mustacchi  */
lm_restore_all_mac_addr(struct _lm_device_t * pdev,u8_t chain_idx)1970*d14abf15SRobert Mustacchi lm_status_t lm_restore_all_mac_addr(struct _lm_device_t *pdev, u8_t chain_idx)
1971*d14abf15SRobert Mustacchi {
1972*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params       ramrod_params = {0};
1973*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj *               vlan_mac_obj  = &pdev->client_info[chain_idx].mac_obj;
1974*d14abf15SRobert Mustacchi     lm_status_t                               lm_status     = LM_STATUS_FAILURE;
1975*d14abf15SRobert Mustacchi     ecore_status_t                            ecore_status  = ECORE_SUCCESS;
1976*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_registry_elem*      pos           = NULL;
1977*d14abf15SRobert Mustacchi 
1978*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_clear_all_mac_addr chain_idx=%d\n", chain_idx);
1979*d14abf15SRobert Mustacchi 
1980*d14abf15SRobert Mustacchi     ramrod_params.vlan_mac_obj = vlan_mac_obj;
1981*d14abf15SRobert Mustacchi 
1982*d14abf15SRobert Mustacchi     ECORE_SET_BIT(RAMROD_COMP_WAIT, &ramrod_params.ramrod_flags);
1983*d14abf15SRobert Mustacchi 
1984*d14abf15SRobert Mustacchi     do
1985*d14abf15SRobert Mustacchi     {
1986*d14abf15SRobert Mustacchi         ecore_status = vlan_mac_obj->restore(pdev, &ramrod_params, &pos);
1987*d14abf15SRobert Mustacchi         lm_status    = lm_ecore_status_to_lm_status(ecore_status);
1988*d14abf15SRobert Mustacchi         if (lm_status != LM_STATUS_SUCCESS)
1989*d14abf15SRobert Mustacchi         {
1990*d14abf15SRobert Mustacchi             DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
1991*d14abf15SRobert Mustacchi             return lm_status;
1992*d14abf15SRobert Mustacchi         }
1993*d14abf15SRobert Mustacchi     }
1994*d14abf15SRobert Mustacchi     while (pos != NULL);
1995*d14abf15SRobert Mustacchi 
1996*d14abf15SRobert Mustacchi     /* Take care of the pairs and vlans as well... */
1997*d14abf15SRobert Mustacchi     if (!CHIP_IS_E1(pdev))
1998*d14abf15SRobert Mustacchi     {
1999*d14abf15SRobert Mustacchi         vlan_mac_obj = &pdev->client_info[chain_idx].mac_vlan_obj;
2000*d14abf15SRobert Mustacchi         ramrod_params.vlan_mac_obj = vlan_mac_obj;
2001*d14abf15SRobert Mustacchi         ECORE_SET_BIT(RAMROD_COMP_WAIT, &ramrod_params.ramrod_flags);
2002*d14abf15SRobert Mustacchi 
2003*d14abf15SRobert Mustacchi         pos = NULL;
2004*d14abf15SRobert Mustacchi         do
2005*d14abf15SRobert Mustacchi         {
2006*d14abf15SRobert Mustacchi             ecore_status = vlan_mac_obj->restore(pdev, &ramrod_params, &pos);
2007*d14abf15SRobert Mustacchi             lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2008*d14abf15SRobert Mustacchi             if (lm_status != LM_STATUS_SUCCESS)
2009*d14abf15SRobert Mustacchi             {
2010*d14abf15SRobert Mustacchi                 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
2011*d14abf15SRobert Mustacchi                 return lm_status;
2012*d14abf15SRobert Mustacchi             }
2013*d14abf15SRobert Mustacchi         } while (pos != NULL);
2014*d14abf15SRobert Mustacchi     }
2015*d14abf15SRobert Mustacchi 
2016*d14abf15SRobert Mustacchi     if (!CHIP_IS_E1x(pdev))
2017*d14abf15SRobert Mustacchi     {
2018*d14abf15SRobert Mustacchi         vlan_mac_obj = &pdev->client_info[chain_idx].vlan_obj;
2019*d14abf15SRobert Mustacchi         ramrod_params.vlan_mac_obj = vlan_mac_obj;
2020*d14abf15SRobert Mustacchi         ECORE_SET_BIT(RAMROD_COMP_WAIT, &ramrod_params.ramrod_flags);
2021*d14abf15SRobert Mustacchi 
2022*d14abf15SRobert Mustacchi         pos = NULL;
2023*d14abf15SRobert Mustacchi         do
2024*d14abf15SRobert Mustacchi         {
2025*d14abf15SRobert Mustacchi             ecore_status = vlan_mac_obj->restore(pdev, &ramrod_params, &pos);
2026*d14abf15SRobert Mustacchi             lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2027*d14abf15SRobert Mustacchi             if (lm_status != LM_STATUS_SUCCESS)
2028*d14abf15SRobert Mustacchi             {
2029*d14abf15SRobert Mustacchi                 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
2030*d14abf15SRobert Mustacchi                 return lm_status;
2031*d14abf15SRobert Mustacchi     }
2032*d14abf15SRobert Mustacchi         } while (pos != NULL);
2033*d14abf15SRobert Mustacchi     }
2034*d14abf15SRobert Mustacchi 
2035*d14abf15SRobert Mustacchi     DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
2036*d14abf15SRobert Mustacchi     return lm_status;
2037*d14abf15SRobert Mustacchi }
2038*d14abf15SRobert Mustacchi 
2039*d14abf15SRobert Mustacchi /************************ RX FILTERING ***************************************/
2040*d14abf15SRobert Mustacchi 
2041*d14abf15SRobert Mustacchi /**
2042*d14abf15SRobert Mustacchi  * @Description
2043*d14abf15SRobert Mustacchi  *  - set/unset rx filtering for a client. The setting is done
2044*d14abf15SRobert Mustacchi  *    for RX + TX, since tx switching is enabled FW needs to
2045*d14abf15SRobert Mustacchi  *    know the configuration for tx filtering as well. The
2046*d14abf15SRobert Mustacchi  *    configuration is almost semmetric for rx / tx except for
2047*d14abf15SRobert Mustacchi  *    the case of promiscuous in which case rx is in
2048*d14abf15SRobert Mustacchi  *    accept_unmatched and Tx is in accept_all (meaning all
2049*d14abf15SRobert Mustacchi  *    traffic is sent to loopback channel)
2050*d14abf15SRobert Mustacchi  *
2051*d14abf15SRobert Mustacchi  * @Assumptions
2052*d14abf15SRobert Mustacchi  *  - An inter client lock is taken by the caller
2053*d14abf15SRobert Mustacchi  * @Return
2054*d14abf15SRobert Mustacchi  *  - Success / Pending or Failure
2055*d14abf15SRobert Mustacchi  */
2056*d14abf15SRobert Mustacchi lm_status_t
lm_set_rx_mask(lm_device_t * pdev,u8_t chain_idx,lm_rx_mask_t rx_mask,void * cookie)2057*d14abf15SRobert Mustacchi lm_set_rx_mask(lm_device_t *pdev, u8_t chain_idx, lm_rx_mask_t rx_mask,  void * cookie)
2058*d14abf15SRobert Mustacchi {
2059*d14abf15SRobert Mustacchi     struct ecore_rx_mode_ramrod_params ramrod_param    = {0};
2060*d14abf15SRobert Mustacchi     lm_cli_idx_t                       lm_cli_idx      = LM_CLI_IDX_MAX;
2061*d14abf15SRobert Mustacchi     unsigned long                      rx_accept_flags = 0;
2062*d14abf15SRobert Mustacchi     unsigned long                      tx_accept_flags = 0;
2063*d14abf15SRobert Mustacchi     lm_status_t                        lm_status       = LM_STATUS_SUCCESS;
2064*d14abf15SRobert Mustacchi     ecore_status_t                     ecore_status    = ECORE_SUCCESS;
2065*d14abf15SRobert Mustacchi 
2066*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_set_rx_mask chain_idx=%d rx_mask=%d\n", chain_idx, rx_mask);
2067*d14abf15SRobert Mustacchi 
2068*d14abf15SRobert Mustacchi     if (lm_reset_is_inprogress(pdev))
2069*d14abf15SRobert Mustacchi     {
2070*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_set_rx_mask: Under FLR!!!\n");
2071*d14abf15SRobert Mustacchi         return  LM_STATUS_SUCCESS;
2072*d14abf15SRobert Mustacchi     }
2073*d14abf15SRobert Mustacchi     #ifdef VF_INVOLVED
2074*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
2075*d14abf15SRobert Mustacchi     {
2076*d14abf15SRobert Mustacchi         return lm_vf_pf_set_q_filters(pdev, chain_idx, FALSE, Q_FILTER_RX_MASK, (u8_t*)&rx_mask, sizeof(lm_rx_mask_t), LM_SET_CAM_NO_VLAN_FILTER, FALSE);
2077*d14abf15SRobert Mustacchi     }
2078*d14abf15SRobert Mustacchi     #endif
2079*d14abf15SRobert Mustacchi 
2080*d14abf15SRobert Mustacchi     if (!pdev->client_info[chain_idx].b_vlan_only_in_process &&
2081*d14abf15SRobert Mustacchi          pdev->client_info[chain_idx].last_set_rx_mask == rx_mask)
2082*d14abf15SRobert Mustacchi     {
2083*d14abf15SRobert Mustacchi         /* No need to send a filter that has already been set...
2084*d14abf15SRobert Mustacchi            return immediately */
2085*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORMl2sp, "lm_set_rx_mask returning immediately: mask didn't change!\n");
2086*d14abf15SRobert Mustacchi         return LM_STATUS_SUCCESS;
2087*d14abf15SRobert Mustacchi     }
2088*d14abf15SRobert Mustacchi 
2089*d14abf15SRobert Mustacchi     /* initialize accept flags in ECORE language */
2090*d14abf15SRobert Mustacchi     if (pdev->client_info[chain_idx].current_set_vlan == 0)
2091*d14abf15SRobert Mustacchi     {
2092*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ANY_VLAN, &rx_accept_flags);
2093*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ANY_VLAN, &tx_accept_flags);
2094*d14abf15SRobert Mustacchi         pdev->client_info[chain_idx].b_any_vlan_on = TRUE;
2095*d14abf15SRobert Mustacchi     }
2096*d14abf15SRobert Mustacchi     else
2097*d14abf15SRobert Mustacchi     {
2098*d14abf15SRobert Mustacchi         pdev->client_info[chain_idx].b_any_vlan_on = FALSE;
2099*d14abf15SRobert Mustacchi     }
2100*d14abf15SRobert Mustacchi 
2101*d14abf15SRobert Mustacchi     /* find the desired filtering configuration */
2102*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_PROMISCUOUS_MODE)
2103*d14abf15SRobert Mustacchi     {
2104*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_UNICAST, &rx_accept_flags);
2105*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_UNMATCHED, &rx_accept_flags);
2106*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ALL_MULTICAST, &rx_accept_flags);
2107*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_BROADCAST, &rx_accept_flags);
2108*d14abf15SRobert Mustacchi 
2109*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_UNICAST, &tx_accept_flags);
2110*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ALL_MULTICAST, &tx_accept_flags);
2111*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_BROADCAST, &tx_accept_flags);
2112*d14abf15SRobert Mustacchi 
2113*d14abf15SRobert Mustacchi         /* In NPAR + vm_switch_enable mode, we need to turn on the ACCEPT_ALL_UNICAST for TX to make
2114*d14abf15SRobert Mustacchi          * sure all traffic passes on the loopback channel to enable non-enlighted vms to communicate (vms that we don't
2115*d14abf15SRobert Mustacchi          * have their MAC set) .
2116*d14abf15SRobert Mustacchi          * We turn it on once we're in promiscuous, which signals that there is probablly vms up that need
2117*d14abf15SRobert Mustacchi          * this feature. */
2118*d14abf15SRobert Mustacchi         if (IS_MF_SI_MODE(pdev) && pdev->params.npar_vm_switching_enable)
2119*d14abf15SRobert Mustacchi         {
2120*d14abf15SRobert Mustacchi             ECORE_SET_BIT_NA(ECORE_ACCEPT_ALL_UNICAST, &tx_accept_flags);
2121*d14abf15SRobert Mustacchi         }
2122*d14abf15SRobert Mustacchi 
2123*d14abf15SRobert Mustacchi     }
2124*d14abf15SRobert Mustacchi 
2125*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_ACCEPT_UNICAST)
2126*d14abf15SRobert Mustacchi     {
2127*d14abf15SRobert Mustacchi         /* accept matched ucast */
2128*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_UNICAST, &rx_accept_flags);
2129*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_UNICAST, &tx_accept_flags);
2130*d14abf15SRobert Mustacchi     }
2131*d14abf15SRobert Mustacchi 
2132*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_ACCEPT_MULTICAST)
2133*d14abf15SRobert Mustacchi     {
2134*d14abf15SRobert Mustacchi         /* accept matched mcast */
2135*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_MULTICAST, &rx_accept_flags);
2136*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_MULTICAST, &tx_accept_flags);
2137*d14abf15SRobert Mustacchi     }
2138*d14abf15SRobert Mustacchi 
2139*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_ACCEPT_ALL_MULTICAST)
2140*d14abf15SRobert Mustacchi     {
2141*d14abf15SRobert Mustacchi         /* accept all mcast */
2142*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ALL_MULTICAST, &rx_accept_flags);
2143*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_ALL_MULTICAST, &tx_accept_flags);
2144*d14abf15SRobert Mustacchi     }
2145*d14abf15SRobert Mustacchi 
2146*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_ACCEPT_BROADCAST)
2147*d14abf15SRobert Mustacchi     {
2148*d14abf15SRobert Mustacchi         /* accept matched bcast */
2149*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_BROADCAST, &rx_accept_flags);
2150*d14abf15SRobert Mustacchi         ECORE_SET_BIT_NA(ECORE_ACCEPT_BROADCAST, &tx_accept_flags);
2151*d14abf15SRobert Mustacchi     }
2152*d14abf15SRobert Mustacchi 
2153*d14abf15SRobert Mustacchi     if GET_FLAGS(rx_mask ,LM_RX_MASK_ACCEPT_ERROR_PACKET)
2154*d14abf15SRobert Mustacchi     {
2155*d14abf15SRobert Mustacchi         /* TBD: there is no usage in Miniport for this flag */
2156*d14abf15SRobert Mustacchi     }
2157*d14abf15SRobert Mustacchi 
2158*d14abf15SRobert Mustacchi     /* Prepare ramrod parameters */
2159*d14abf15SRobert Mustacchi     ramrod_param.cid         = chain_idx; // echo..
2160*d14abf15SRobert Mustacchi     ramrod_param.cl_id       = LM_FW_CLI_ID(pdev, chain_idx);
2161*d14abf15SRobert Mustacchi     ramrod_param.rx_mode_obj = &pdev->slowpath_info.rx_mode_obj;
2162*d14abf15SRobert Mustacchi     ramrod_param.func_id     = FUNC_ID(pdev);
2163*d14abf15SRobert Mustacchi 
2164*d14abf15SRobert Mustacchi     ramrod_param.pstate      = (unsigned long *)&pdev->client_info[chain_idx].sp_rxmode_state;
2165*d14abf15SRobert Mustacchi     ramrod_param.state       = ECORE_FILTER_RX_MODE_PENDING;
2166*d14abf15SRobert Mustacchi 
2167*d14abf15SRobert Mustacchi     // We set in lm_cli_idx always 0 (LM_CLI_IDX_NDIS) for E1x and lm_cli_idx for e2.
2168*d14abf15SRobert Mustacchi     // LM_CLI_IDX_NDIS is an occasional choice and could be any of the LM_CLI_IDX
2169*d14abf15SRobert Mustacchi     //
2170*d14abf15SRobert Mustacchi     // * rx_mode_rdata PER INDEX is problematic because:
2171*d14abf15SRobert Mustacchi     //      the rx filtering is same place in internal ram of e1.5/e1.0 and when we work with an array
2172*d14abf15SRobert Mustacchi     //      each client run over the bits of the previous client
2173*d14abf15SRobert Mustacchi     //
2174*d14abf15SRobert Mustacchi     // * rx_mode_rdata NOT PER INDEX is problematic because:
2175*d14abf15SRobert Mustacchi     //      in e2.0 when we send a ramrod, the rdata is same memory for all
2176*d14abf15SRobert Mustacchi     //      clients and therefore in case of parallel run of rx_mask of clients
2177*d14abf15SRobert Mustacchi     //      one of the ramrods actually won't be sent with the correct data
2178*d14abf15SRobert Mustacchi     //
2179*d14abf15SRobert Mustacchi     // * Conclusion: we have here a problem which make a conflict that both E1.0/E1.5 and E2 work without issues.
2180*d14abf15SRobert Mustacchi     //               This issue should be resolved in a proper way which should be discussed.
2181*d14abf15SRobert Mustacchi     //
2182*d14abf15SRobert Mustacchi     // This note is related to the following two CQ's:
2183*d14abf15SRobert Mustacchi     // CQ53609 - eVBD:57712: evbda!lm_sq_complete+7ca; Assert is seen while running ACPI S1 S3 sleep stress test
2184*d14abf15SRobert Mustacchi     // CQ53444 - OIS Certs: iSCSI Ping Test Fails
2185*d14abf15SRobert Mustacchi 
2186*d14abf15SRobert Mustacchi     lm_cli_idx = CHIP_IS_E1x(pdev) ? LM_CLI_IDX_NDIS : LM_CHAIN_IDX_CLI(pdev, chain_idx);
2187*d14abf15SRobert Mustacchi 
2188*d14abf15SRobert Mustacchi     if(LM_CLI_IDX_MAX <= lm_cli_idx)
2189*d14abf15SRobert Mustacchi     {
2190*d14abf15SRobert Mustacchi         DbgBreakMsg(" lm_cli_idx has an invalid value");
2191*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
2192*d14abf15SRobert Mustacchi     }
2193*d14abf15SRobert Mustacchi 
2194*d14abf15SRobert Mustacchi     ramrod_param.rdata = LM_SLOWPATH(pdev, rx_mode_rdata)[lm_cli_idx];
2195*d14abf15SRobert Mustacchi     ramrod_param.rdata_mapping = LM_SLOWPATH_PHYS(pdev, rx_mode_rdata)[lm_cli_idx];
2196*d14abf15SRobert Mustacchi 
2197*d14abf15SRobert Mustacchi     ECORE_SET_BIT(ECORE_FILTER_RX_MODE_PENDING, &pdev->client_info[chain_idx].sp_rxmode_state);
2198*d14abf15SRobert Mustacchi     ECORE_SET_BIT(RAMROD_RX, &ramrod_param.ramrod_flags);
2199*d14abf15SRobert Mustacchi     ECORE_SET_BIT(RAMROD_TX, &ramrod_param.ramrod_flags);
2200*d14abf15SRobert Mustacchi 
2201*d14abf15SRobert Mustacchi     ramrod_param.rx_mode_flags = 0; // FIXME ...
2202*d14abf15SRobert Mustacchi     ramrod_param.rx_accept_flags = rx_accept_flags;
2203*d14abf15SRobert Mustacchi     ramrod_param.tx_accept_flags = tx_accept_flags;
2204*d14abf15SRobert Mustacchi 
2205*d14abf15SRobert Mustacchi     /* Must be set before the ramrod... */
2206*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->client_info[chain_idx].set_rx_mode_cookie != NULL);
2207*d14abf15SRobert Mustacchi     pdev->client_info[chain_idx].last_set_rx_mask = rx_mask;
2208*d14abf15SRobert Mustacchi     pdev->client_info[chain_idx].set_rx_mode_cookie = cookie;
2209*d14abf15SRobert Mustacchi 
2210*d14abf15SRobert Mustacchi     ecore_status = ecore_config_rx_mode(pdev, &ramrod_param);
2211*d14abf15SRobert Mustacchi     lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2212*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "Status returned from ecore_config_rx_mode: %d\n", lm_status);
2213*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_SUCCESS)
2214*d14abf15SRobert Mustacchi     {
2215*d14abf15SRobert Mustacchi         pdev->client_info[chain_idx].set_rx_mode_cookie = NULL;
2216*d14abf15SRobert Mustacchi     }
2217*d14abf15SRobert Mustacchi     else if (lm_status == LM_STATUS_REQUEST_NOT_ACCEPTED)
2218*d14abf15SRobert Mustacchi     {
2219*d14abf15SRobert Mustacchi         /* Sq is blocked... meaning we're in error recovery, this is our one outstanding oid.
2220*d14abf15SRobert Mustacchi          * mark ecore as done, return PENDING to UM, don't clear cookie. This means miniport
2221*d14abf15SRobert Mustacchi          * will eventually get a completion as part of the re-initialization of the chip... */
2222*d14abf15SRobert Mustacchi         ECORE_CLEAR_BIT(ECORE_FILTER_RX_MODE_PENDING, &pdev->client_info[chain_idx].sp_rxmode_state);
2223*d14abf15SRobert Mustacchi     }
2224*d14abf15SRobert Mustacchi 
2225*d14abf15SRobert Mustacchi     return lm_status;
2226*d14abf15SRobert Mustacchi } /* lm_set_rx_mask */
2227*d14abf15SRobert Mustacchi 
2228*d14abf15SRobert Mustacchi /* Waits for the set=-rx-mode to complete*/
lm_wait_set_rx_mask_done(struct _lm_device_t * pdev,u8_t chain_idx)2229*d14abf15SRobert Mustacchi lm_status_t lm_wait_set_rx_mask_done(struct _lm_device_t *pdev, u8_t chain_idx)
2230*d14abf15SRobert Mustacchi {
2231*d14abf15SRobert Mustacchi     struct ecore_rx_mode_ramrod_params params = {0};
2232*d14abf15SRobert Mustacchi     lm_status_t lm_status;
2233*d14abf15SRobert Mustacchi 
2234*d14abf15SRobert Mustacchi     params.pstate = (unsigned long *)&pdev->client_info[chain_idx].sp_rxmode_state;
2235*d14abf15SRobert Mustacchi     params.state = ECORE_FILTER_RX_MODE_PENDING;
2236*d14abf15SRobert Mustacchi 
2237*d14abf15SRobert Mustacchi     lm_status = pdev->slowpath_info.rx_mode_obj.wait_comp(pdev, &params);
2238*d14abf15SRobert Mustacchi     DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
2239*d14abf15SRobert Mustacchi 
2240*d14abf15SRobert Mustacchi     return lm_status;
2241*d14abf15SRobert Mustacchi }
2242*d14abf15SRobert Mustacchi 
2243*d14abf15SRobert Mustacchi 
2244*d14abf15SRobert Mustacchi /*************************  MULTICAST  *****************************************/
_init_mcast_macs_list(lm_device_t * pdev,u8_t * mc_addrs,u32_t buf_len,struct ecore_mcast_ramrod_params * p)2245*d14abf15SRobert Mustacchi static INLINE lm_status_t _init_mcast_macs_list(lm_device_t *pdev,
2246*d14abf15SRobert Mustacchi                                                  u8_t*        mc_addrs,
2247*d14abf15SRobert Mustacchi                                                  u32_t        buf_len,
2248*d14abf15SRobert Mustacchi                                                  struct ecore_mcast_ramrod_params *p)
2249*d14abf15SRobert Mustacchi {
2250*d14abf15SRobert Mustacchi     u8                            mc_count = buf_len / ETHERNET_ADDRESS_SIZE;
2251*d14abf15SRobert Mustacchi     struct ecore_mcast_list_elem *mc_mac   = NULL;
2252*d14abf15SRobert Mustacchi 
2253*d14abf15SRobert Mustacchi     mc_mac = mm_rt_alloc_mem(pdev, sizeof(*mc_mac) * mc_count, 0);
2254*d14abf15SRobert Mustacchi 
2255*d14abf15SRobert Mustacchi     if (!mc_addrs) {
2256*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
2257*d14abf15SRobert Mustacchi     }
2258*d14abf15SRobert Mustacchi 
2259*d14abf15SRobert Mustacchi     d_list_clear(&p->mcast_list);
2260*d14abf15SRobert Mustacchi 
2261*d14abf15SRobert Mustacchi     while(buf_len && mc_addrs)
2262*d14abf15SRobert Mustacchi     {
2263*d14abf15SRobert Mustacchi         mc_mac->mac = mc_addrs;
2264*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORMl2sp, "mc_addrs[%d]:mc_addrs[%d]:mc_addrs[%d]:mc_addrs[%d]:mc_addrs[%d]:mc_addrs[%d]\n",
2265*d14abf15SRobert Mustacchi                    mc_addrs[0],mc_addrs[1],mc_addrs[2],mc_addrs[3],mc_addrs[4],mc_addrs[5]);
2266*d14abf15SRobert Mustacchi         d_list_push_tail(&p->mcast_list, &mc_mac->link);
2267*d14abf15SRobert Mustacchi         /* move on to next mc addr */
2268*d14abf15SRobert Mustacchi         buf_len -= ETHERNET_ADDRESS_SIZE;
2269*d14abf15SRobert Mustacchi         mc_addrs += ETHERNET_ADDRESS_SIZE;
2270*d14abf15SRobert Mustacchi         mc_mac++;
2271*d14abf15SRobert Mustacchi     }
2272*d14abf15SRobert Mustacchi 
2273*d14abf15SRobert Mustacchi     p->mcast_list_len = mc_count;
2274*d14abf15SRobert Mustacchi 
2275*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
2276*d14abf15SRobert Mustacchi }
2277*d14abf15SRobert Mustacchi 
__free_mcast_macs_list(lm_device_t * pdev,struct ecore_mcast_ramrod_params * p)2278*d14abf15SRobert Mustacchi static INLINE void __free_mcast_macs_list(lm_device_t *pdev,
2279*d14abf15SRobert Mustacchi                                           struct ecore_mcast_ramrod_params *p)
2280*d14abf15SRobert Mustacchi {
2281*d14abf15SRobert Mustacchi     struct ecore_mcast_list_elem *mc_mac = NULL;
2282*d14abf15SRobert Mustacchi     mc_mac = (struct ecore_mcast_list_elem *)d_list_peek_head(&p->mcast_list);
2283*d14abf15SRobert Mustacchi 
2284*d14abf15SRobert Mustacchi     if (mc_mac)
2285*d14abf15SRobert Mustacchi     {
2286*d14abf15SRobert Mustacchi         /* note that p->mcast_list_len is now set to 0 after processing */
2287*d14abf15SRobert Mustacchi         mm_rt_free_mem(pdev, mc_mac, sizeof(*mc_mac) * d_list_entry_cnt(&p->mcast_list), 0);
2288*d14abf15SRobert Mustacchi     }
2289*d14abf15SRobert Mustacchi }
2290*d14abf15SRobert Mustacchi 
2291*d14abf15SRobert Mustacchi /**
2292*d14abf15SRobert Mustacchi  * @Description
2293*d14abf15SRobert Mustacchi  *      Function configures a list of multicast addresses. Or
2294*d14abf15SRobert Mustacchi  *      resets the list previously configured
2295*d14abf15SRobert Mustacchi  *
2296*d14abf15SRobert Mustacchi  * @param pdev
2297*d14abf15SRobert Mustacchi  * @param mc_addrs    - array of multicast addresses. NULL if unset is required
2298*d14abf15SRobert Mustacchi  * @param buf_len     - length of the buffer - 0 if unset is required
2299*d14abf15SRobert Mustacchi  * @param cookie      - will be returned on completion
2300*d14abf15SRobert Mustacchi  * @param lm_cli_idx  - which lm client to send request on
2301*d14abf15SRobert Mustacchi  *
2302*d14abf15SRobert Mustacchi  * @return lm_status_t - SUCCESS on syncrounous completion
2303*d14abf15SRobert Mustacchi  *                       PENDING on asyncounous completion
2304*d14abf15SRobert Mustacchi  *                       FAILURE o/w
2305*d14abf15SRobert Mustacchi  */
lm_set_mc(struct _lm_device_t * pdev,u8_t * mc_addrs,u32_t buf_len,void * cookie,lm_cli_idx_t lm_cli_idx)2306*d14abf15SRobert Mustacchi lm_status_t lm_set_mc(struct _lm_device_t *pdev,
2307*d14abf15SRobert Mustacchi                       u8_t*  mc_addrs, /* may be NULL (for unset) */
2308*d14abf15SRobert Mustacchi                       u32_t  buf_len,  /* may be 0 (for unset) */
2309*d14abf15SRobert Mustacchi                       void * cookie,  lm_cli_idx_t lm_cli_idx)
2310*d14abf15SRobert Mustacchi {
2311*d14abf15SRobert Mustacchi     struct ecore_mcast_ramrod_params rparam       = {0};
2312*d14abf15SRobert Mustacchi     lm_status_t                      lm_status    = LM_STATUS_SUCCESS;
2313*d14abf15SRobert Mustacchi     ecore_status_t                   ecore_status = ECORE_SUCCESS;
2314*d14abf15SRobert Mustacchi 
2315*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
2316*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev)) {
2317*d14abf15SRobert Mustacchi         return lm_vf_pf_set_q_filters(pdev, lm_cli_idx, cookie, Q_FILTER_MC, mc_addrs, buf_len, LM_SET_CAM_NO_VLAN_FILTER, FALSE);
2318*d14abf15SRobert Mustacchi     }
2319*d14abf15SRobert Mustacchi #endif
2320*d14abf15SRobert Mustacchi 
2321*d14abf15SRobert Mustacchi     if(0 == LM_MC_TABLE_SIZE(pdev,lm_cli_idx))
2322*d14abf15SRobert Mustacchi     {
2323*d14abf15SRobert Mustacchi         DbgBreakMsg("size must be greater than zero for a valid client\n");
2324*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
2325*d14abf15SRobert Mustacchi     }
2326*d14abf15SRobert Mustacchi 
2327*d14abf15SRobert Mustacchi 
2328*d14abf15SRobert Mustacchi     /* Initialize params sent to ecore layer */
2329*d14abf15SRobert Mustacchi     /* Need to split to groups of 16 for E2... due to hsi restraint*/
2330*d14abf15SRobert Mustacchi     if (mc_addrs)
2331*d14abf15SRobert Mustacchi     {
2332*d14abf15SRobert Mustacchi         _init_mcast_macs_list(pdev, mc_addrs, buf_len, &rparam);
2333*d14abf15SRobert Mustacchi     }
2334*d14abf15SRobert Mustacchi     rparam.mcast_obj = &pdev->slowpath_info.mcast_obj[lm_cli_idx];
2335*d14abf15SRobert Mustacchi 
2336*d14abf15SRobert Mustacchi     /* Cookie must be set before sending the ramord, since completion could arrive before
2337*d14abf15SRobert Mustacchi      * we return and the cookie must be in place*/
2338*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] != NULL);
2339*d14abf15SRobert Mustacchi     pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] = cookie;
2340*d14abf15SRobert Mustacchi 
2341*d14abf15SRobert Mustacchi     ecore_status = ecore_config_mcast(pdev, &rparam, (mc_addrs != NULL)? ECORE_MCAST_CMD_ADD : ECORE_MCAST_CMD_DEL);
2342*d14abf15SRobert Mustacchi     lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2343*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_SUCCESS)
2344*d14abf15SRobert Mustacchi     {
2345*d14abf15SRobert Mustacchi         pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] = NULL;
2346*d14abf15SRobert Mustacchi         }
2347*d14abf15SRobert Mustacchi 
2348*d14abf15SRobert Mustacchi     if (mc_addrs)
2349*d14abf15SRobert Mustacchi     {
2350*d14abf15SRobert Mustacchi         __free_mcast_macs_list(pdev, &rparam);
2351*d14abf15SRobert Mustacchi     }
2352*d14abf15SRobert Mustacchi 
2353*d14abf15SRobert Mustacchi     return lm_status;
2354*d14abf15SRobert Mustacchi } /* lm_set_mc */
2355*d14abf15SRobert Mustacchi 
lm_set_mc_list(struct _lm_device_t * pdev,d_list_t * mc_addrs,void * cookie,lm_cli_idx_t lm_cli_idx)2356*d14abf15SRobert Mustacchi lm_status_t lm_set_mc_list(struct _lm_device_t *pdev,
2357*d14abf15SRobert Mustacchi                            d_list_t * mc_addrs, /* may be NULL (for unset) */
2358*d14abf15SRobert Mustacchi                            void * cookie,
2359*d14abf15SRobert Mustacchi                            lm_cli_idx_t lm_cli_idx)
2360*d14abf15SRobert Mustacchi {
2361*d14abf15SRobert Mustacchi     struct ecore_mcast_ramrod_params rparam       = {0};
2362*d14abf15SRobert Mustacchi     lm_status_t                      lm_status    = LM_STATUS_SUCCESS;
2363*d14abf15SRobert Mustacchi     ecore_status_t                   ecore_status = ECORE_SUCCESS;
2364*d14abf15SRobert Mustacchi 
2365*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
2366*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
2367*d14abf15SRobert Mustacchi     {
2368*d14abf15SRobert Mustacchi         return lm_vf_pf_set_q_filters_list(pdev, lm_cli_idx, cookie,
2369*d14abf15SRobert Mustacchi                                       Q_FILTER_MC, mc_addrs,
2370*d14abf15SRobert Mustacchi                                       LM_SET_CAM_NO_VLAN_FILTER, FALSE);
2371*d14abf15SRobert Mustacchi     }
2372*d14abf15SRobert Mustacchi #endif
2373*d14abf15SRobert Mustacchi 
2374*d14abf15SRobert Mustacchi     rparam.mcast_list = *mc_addrs;
2375*d14abf15SRobert Mustacchi     rparam.mcast_list_len = d_list_entry_cnt(mc_addrs);
2376*d14abf15SRobert Mustacchi 
2377*d14abf15SRobert Mustacchi     rparam.mcast_obj = &pdev->slowpath_info.mcast_obj[lm_cli_idx];
2378*d14abf15SRobert Mustacchi 
2379*d14abf15SRobert Mustacchi     /* Cookie must be set before sending the ramord, since completion could arrive before
2380*d14abf15SRobert Mustacchi      * we return and the cookie must be in place*/
2381*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] != NULL);
2382*d14abf15SRobert Mustacchi     pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] = cookie;
2383*d14abf15SRobert Mustacchi 
2384*d14abf15SRobert Mustacchi     ecore_status = ecore_config_mcast(pdev, &rparam,
2385*d14abf15SRobert Mustacchi                                       (mc_addrs != NULL) ? ECORE_MCAST_CMD_ADD :
2386*d14abf15SRobert Mustacchi                                                            ECORE_MCAST_CMD_DEL);
2387*d14abf15SRobert Mustacchi 
2388*d14abf15SRobert Mustacchi     lm_status = lm_ecore_status_to_lm_status(ecore_status);
2389*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_SUCCESS)
2390*d14abf15SRobert Mustacchi     {
2391*d14abf15SRobert Mustacchi         pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] = NULL;
2392*d14abf15SRobert Mustacchi     }
2393*d14abf15SRobert Mustacchi 
2394*d14abf15SRobert Mustacchi     return lm_status;
2395*d14abf15SRobert Mustacchi }
2396*d14abf15SRobert Mustacchi 
2397*d14abf15SRobert Mustacchi /**
2398*d14abf15SRobert Mustacchi  * Description
2399*d14abf15SRobert Mustacchi  *      This routine is called to wait for the multicast set
2400*d14abf15SRobert Mustacchi  *      completion. It must be called in passive level since it
2401*d14abf15SRobert Mustacchi  *      may sleep
2402*d14abf15SRobert Mustacchi  * @param pdev
2403*d14abf15SRobert Mustacchi  * @param lm_cli_idx the cli-idx that the multicast was sent on.
2404*d14abf15SRobert Mustacchi  *
2405*d14abf15SRobert Mustacchi  * @return lm_status SUCCESS on done, TIMEOUT o/w
2406*d14abf15SRobert Mustacchi  */
lm_wait_set_mc_done(struct _lm_device_t * pdev,lm_cli_idx_t lm_cli_idx)2407*d14abf15SRobert Mustacchi lm_status_t lm_wait_set_mc_done(struct _lm_device_t *pdev, lm_cli_idx_t lm_cli_idx)
2408*d14abf15SRobert Mustacchi {
2409*d14abf15SRobert Mustacchi     struct ecore_mcast_obj * mcast_obj    = &pdev->slowpath_info.mcast_obj[lm_cli_idx];
2410*d14abf15SRobert Mustacchi     ecore_status_t           ecore_status = mcast_obj->wait_comp(pdev, mcast_obj);
2411*d14abf15SRobert Mustacchi     lm_status_t              lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2412*d14abf15SRobert Mustacchi 
2413*d14abf15SRobert Mustacchi     return lm_status;
2414*d14abf15SRobert Mustacchi }
2415*d14abf15SRobert Mustacchi 
2416*d14abf15SRobert Mustacchi /*************************  RSS ***********************************************/
2417*d14abf15SRobert Mustacchi 
2418*d14abf15SRobert Mustacchi /**
2419*d14abf15SRobert Mustacchi  * Description: update RSS key in slowpath
2420*d14abf15SRobert Mustacchi  * Assumptions:
2421*d14abf15SRobert Mustacchi  *  - given key_size is promised to be either 40 or 16 (promised by NDIS)
2422*d14abf15SRobert Mustacchi  * Return:
2423*d14abf15SRobert Mustacchi  */
2424*d14abf15SRobert Mustacchi 
2425*d14abf15SRobert Mustacchi /**
2426*d14abf15SRobert Mustacchi  * @Description: Update RSS key in driver rss_hash_key array and
2427*d14abf15SRobert Mustacchi  *             check if it has changed from previous key.
2428*d14abf15SRobert Mustacchi  *
2429*d14abf15SRobert Mustacchi  * @param pdev
2430*d14abf15SRobert Mustacchi  * @param hash_key  - hash_key received from NDIS
2431*d14abf15SRobert Mustacchi  * @param key_size
2432*d14abf15SRobert Mustacchi  *
2433*d14abf15SRobert Mustacchi  * @return u8_t     TRUE if changed, FALSE o/w
2434*d14abf15SRobert Mustacchi  */
lm_update_rss_key(struct _lm_device_t * pdev,u8_t * hash_key,u32_t key_size)2435*d14abf15SRobert Mustacchi static u8_t lm_update_rss_key(struct _lm_device_t *pdev, u8_t *hash_key,
2436*d14abf15SRobert Mustacchi                                      u32_t key_size)
2437*d14abf15SRobert Mustacchi {
2438*d14abf15SRobert Mustacchi     u32_t val        = 0;
2439*d14abf15SRobert Mustacchi     u32_t i          = 0;
2440*d14abf15SRobert Mustacchi     s32_t rss_reg    = 0;
2441*d14abf15SRobert Mustacchi     u8_t key_changed = FALSE;
2442*d14abf15SRobert Mustacchi 
2443*d14abf15SRobert Mustacchi     /* check params */
2444*d14abf15SRobert Mustacchi     if ERR_IF(!(pdev && hash_key))
2445*d14abf15SRobert Mustacchi     {
2446*d14abf15SRobert Mustacchi         DbgBreak();
2447*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
2448*d14abf15SRobert Mustacchi     }
2449*d14abf15SRobert Mustacchi 
2450*d14abf15SRobert Mustacchi     /* Note: MSB (that is hash_key[0]) should be placed in MSB of register KEYRSS9, regardless the key size */
2451*d14abf15SRobert Mustacchi     /* GilR 4/4/2007 - assert on key_size==16/40? */
2452*d14abf15SRobert Mustacchi     for (rss_reg = 9, i = 0; rss_reg >= 0; rss_reg--)
2453*d14abf15SRobert Mustacchi     {
2454*d14abf15SRobert Mustacchi         val = 0;
2455*d14abf15SRobert Mustacchi         if (i < key_size)
2456*d14abf15SRobert Mustacchi         {
2457*d14abf15SRobert Mustacchi             val = ((hash_key[i] << 24) | (hash_key[i+1] << 16) | (hash_key[i+2] << 8) | hash_key[i+3]);
2458*d14abf15SRobert Mustacchi             DbgMessage(pdev, INFORMl2sp,
2459*d14abf15SRobert Mustacchi                         "KEYRSS[%d:%d]=0x%x, written to RSS_REG=%d\n",
2460*d14abf15SRobert Mustacchi                         i, i+3, val, rss_reg);
2461*d14abf15SRobert Mustacchi             i += 4;
2462*d14abf15SRobert Mustacchi         }
2463*d14abf15SRobert Mustacchi         else
2464*d14abf15SRobert Mustacchi         {
2465*d14abf15SRobert Mustacchi             DbgMessage(pdev, INFORMl2sp,
2466*d14abf15SRobert Mustacchi                         "OUT OF KEY size, writing 0x%x to RSS_REG=%d\n",
2467*d14abf15SRobert Mustacchi                         val, rss_reg);
2468*d14abf15SRobert Mustacchi         }
2469*d14abf15SRobert Mustacchi         if (pdev->slowpath_info.rss_hash_key[rss_reg] != val)
2470*d14abf15SRobert Mustacchi         { /* key changed */
2471*d14abf15SRobert Mustacchi             pdev->slowpath_info.rss_hash_key[rss_reg] = val;
2472*d14abf15SRobert Mustacchi             key_changed = TRUE;
2473*d14abf15SRobert Mustacchi         }
2474*d14abf15SRobert Mustacchi     }
2475*d14abf15SRobert Mustacchi 
2476*d14abf15SRobert Mustacchi     if (key_changed)
2477*d14abf15SRobert Mustacchi     {
2478*d14abf15SRobert Mustacchi         DbgMessage(pdev, WARNl2, "update rss: KEY CHANGED\n");
2479*d14abf15SRobert Mustacchi     }
2480*d14abf15SRobert Mustacchi 
2481*d14abf15SRobert Mustacchi     return key_changed;
2482*d14abf15SRobert Mustacchi }
2483*d14abf15SRobert Mustacchi 
2484*d14abf15SRobert Mustacchi /**
2485*d14abf15SRobert Mustacchi  * @Description
2486*d14abf15SRobert Mustacchi  *      Enable RSS for Eth with given indirection table also updates the rss key
2487*d14abf15SRobert Mustacchi  *      in searcher (for previous chips...- done by sp-verbs)
2488*d14abf15SRobert Mustacchi  *
2489*d14abf15SRobert Mustacchi  * @Assumptions
2490*d14abf15SRobert Mustacchi  *  - given table_size is promised to be power of 2 (promised by NDIS),
2491*d14abf15SRobert Mustacchi  *    or 1 in case of RSS disabling
2492*d14abf15SRobert Mustacchi  *  - the indices in the given chain_indirection_table are chain
2493*d14abf15SRobert Mustacchi  *    indices converted by UM layer...
2494*d14abf15SRobert Mustacchi  *  - given key_size is promised to be either 40 or 16 (promised by NDIS)
2495*d14abf15SRobert Mustacchi  *
2496*d14abf15SRobert Mustacchi  * @param pdev
2497*d14abf15SRobert Mustacchi  * @param chain_indirection_table - array of size @table_size containing chain numbers
2498*d14abf15SRobert Mustacchi  * @param table_size - size of @indirection_table
2499*d14abf15SRobert Mustacchi  * @param hash_key - new hash_key to be configured. 0 means no key
2500*d14abf15SRobert Mustacchi  * @param key_size
2501*d14abf15SRobert Mustacchi  * @param hash_type
2502*d14abf15SRobert Mustacchi  * @param sync_with_toe - This field indicates that the completion to the mm layer
2503*d14abf15SRobert Mustacchi  *                        should take into account the fact that toe rss update will
2504*d14abf15SRobert Mustacchi  *                        be sent as well. A counter will be increased in lm for this purpose
2505*d14abf15SRobert Mustacchi  * @param cookie        - will be returned on completion
2506*d14abf15SRobert Mustacchi  *
2507*d14abf15SRobert Mustacchi  * @return lm_status_t - SUCCESS on syncrounous completion
2508*d14abf15SRobert Mustacchi  *                       PENDING on asyncounous completion
2509*d14abf15SRobert Mustacchi  *                       FAILURE o/w
2510*d14abf15SRobert Mustacchi  */
lm_enable_rss(struct _lm_device_t * pdev,u8_t * chain_indirection_table,u32_t table_size,u8_t * hash_key,u32_t key_size,lm_rss_hash_t hash_type,u8 sync_with_toe,void * cookie)2511*d14abf15SRobert Mustacchi lm_status_t lm_enable_rss(struct _lm_device_t *pdev, u8_t *chain_indirection_table,
2512*d14abf15SRobert Mustacchi                           u32_t table_size, u8_t *hash_key, u32_t key_size, lm_rss_hash_t hash_type,
2513*d14abf15SRobert Mustacchi                           u8 sync_with_toe, void * cookie)
2514*d14abf15SRobert Mustacchi {
2515*d14abf15SRobert Mustacchi     struct ecore_config_rss_params params      = {0};
2516*d14abf15SRobert Mustacchi     lm_status_t                    lm_status   = LM_STATUS_SUCCESS;
2517*d14abf15SRobert Mustacchi     ecore_status_t                 ecore_status = ECORE_SUCCESS;
2518*d14abf15SRobert Mustacchi     u8_t                           value       = 0;
2519*d14abf15SRobert Mustacchi     u8_t                           reconfigure = FALSE;
2520*d14abf15SRobert Mustacchi     u8_t                           key_changed = FALSE;
2521*d14abf15SRobert Mustacchi     u8_t                           i           = 0;
2522*d14abf15SRobert Mustacchi 
2523*d14abf15SRobert Mustacchi     /* check params */
2524*d14abf15SRobert Mustacchi     if ERR_IF(!(pdev && chain_indirection_table))
2525*d14abf15SRobert Mustacchi     {
2526*d14abf15SRobert Mustacchi         DbgBreak();
2527*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
2528*d14abf15SRobert Mustacchi     }
2529*d14abf15SRobert Mustacchi 
2530*d14abf15SRobert Mustacchi     if (hash_type &
2531*d14abf15SRobert Mustacchi         ~(LM_RSS_HASH_IPV4 | LM_RSS_HASH_TCP_IPV4 | LM_RSS_HASH_IPV6 | LM_RSS_HASH_TCP_IPV6))
2532*d14abf15SRobert Mustacchi     {
2533*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
2534*d14abf15SRobert Mustacchi     }
2535*d14abf15SRobert Mustacchi 
2536*d14abf15SRobert Mustacchi     params.rss_obj = &pdev->slowpath_info.rss_conf_obj;
2537*d14abf15SRobert Mustacchi 
2538*d14abf15SRobert Mustacchi     /* RSS mode */
2539*d14abf15SRobert Mustacchi     /* Fixme --> anything else ?*/
2540*d14abf15SRobert Mustacchi     ECORE_SET_BIT(ECORE_RSS_MODE_REGULAR, &params.rss_flags);
2541*d14abf15SRobert Mustacchi 
2542*d14abf15SRobert Mustacchi     /* Translate the hash type to "ecore" */
2543*d14abf15SRobert Mustacchi     if (GET_FLAGS(hash_type, LM_RSS_HASH_IPV4))
2544*d14abf15SRobert Mustacchi     {
2545*d14abf15SRobert Mustacchi         ECORE_SET_BIT(ECORE_RSS_IPV4, &params.rss_flags);
2546*d14abf15SRobert Mustacchi     }
2547*d14abf15SRobert Mustacchi     if (GET_FLAGS(hash_type, LM_RSS_HASH_TCP_IPV4))
2548*d14abf15SRobert Mustacchi     {
2549*d14abf15SRobert Mustacchi         ECORE_SET_BIT(ECORE_RSS_IPV4_TCP, &params.rss_flags);
2550*d14abf15SRobert Mustacchi     }
2551*d14abf15SRobert Mustacchi     if (GET_FLAGS(hash_type, LM_RSS_HASH_IPV6))
2552*d14abf15SRobert Mustacchi     {
2553*d14abf15SRobert Mustacchi         ECORE_SET_BIT(ECORE_RSS_IPV6, &params.rss_flags);
2554*d14abf15SRobert Mustacchi     }
2555*d14abf15SRobert Mustacchi     if (GET_FLAGS(hash_type, LM_RSS_HASH_TCP_IPV6))
2556*d14abf15SRobert Mustacchi     {
2557*d14abf15SRobert Mustacchi         ECORE_SET_BIT(ECORE_RSS_IPV6_TCP, &params.rss_flags);
2558*d14abf15SRobert Mustacchi     }
2559*d14abf15SRobert Mustacchi 
2560*d14abf15SRobert Mustacchi     if (pdev->slowpath_info.last_set_rss_flags != params.rss_flags)
2561*d14abf15SRobert Mustacchi     {
2562*d14abf15SRobert Mustacchi         pdev->slowpath_info.last_set_rss_flags = params.rss_flags;
2563*d14abf15SRobert Mustacchi         reconfigure = TRUE;
2564*d14abf15SRobert Mustacchi     }
2565*d14abf15SRobert Mustacchi 
2566*d14abf15SRobert Mustacchi     /* set rss result mask according to table size
2567*d14abf15SRobert Mustacchi        (table_size is promised to be power of 2) */
2568*d14abf15SRobert Mustacchi     params.rss_result_mask = (u8_t)table_size - 1;
2569*d14abf15SRobert Mustacchi     if (pdev->slowpath_info.last_set_rss_result_mask != params.rss_result_mask)
2570*d14abf15SRobert Mustacchi     {
2571*d14abf15SRobert Mustacchi         /* Hash bits */
2572*d14abf15SRobert Mustacchi         pdev->slowpath_info.last_set_rss_result_mask = params.rss_result_mask;
2573*d14abf15SRobert Mustacchi         reconfigure = TRUE;
2574*d14abf15SRobert Mustacchi     }
2575*d14abf15SRobert Mustacchi 
2576*d14abf15SRobert Mustacchi     for (i = 0; i < table_size; i++)
2577*d14abf15SRobert Mustacchi     {
2578*d14abf15SRobert Mustacchi 
2579*d14abf15SRobert Mustacchi         value = LM_CHAIN_TO_FW_CLIENT(pdev,chain_indirection_table[i]);
2580*d14abf15SRobert Mustacchi 
2581*d14abf15SRobert Mustacchi         if (pdev->slowpath_info.last_set_indirection_table[i] != value)
2582*d14abf15SRobert Mustacchi         {
2583*d14abf15SRobert Mustacchi             DbgMessage(pdev, INFORMl2sp, "RssIndTable[%02d]=0x%x (Changed from 0x%x)\n", i, value, pdev->slowpath_info.last_set_indirection_table[i]);
2584*d14abf15SRobert Mustacchi             pdev->slowpath_info.last_set_indirection_table[i] = value;
2585*d14abf15SRobert Mustacchi             reconfigure = TRUE;
2586*d14abf15SRobert Mustacchi         }
2587*d14abf15SRobert Mustacchi     }
2588*d14abf15SRobert Mustacchi     mm_memcpy(params.ind_table, pdev->slowpath_info.last_set_indirection_table, sizeof(params.ind_table));
2589*d14abf15SRobert Mustacchi 
2590*d14abf15SRobert Mustacchi     if (hash_key)
2591*d14abf15SRobert Mustacchi     {
2592*d14abf15SRobert Mustacchi         key_changed = lm_update_rss_key(pdev, hash_key, key_size);
2593*d14abf15SRobert Mustacchi         if (key_changed)
2594*d14abf15SRobert Mustacchi         {
2595*d14abf15SRobert Mustacchi             reconfigure = TRUE;
2596*d14abf15SRobert Mustacchi         }
2597*d14abf15SRobert Mustacchi         mm_memcpy(params.rss_key, pdev->slowpath_info.rss_hash_key, sizeof(params.rss_key));
2598*d14abf15SRobert Mustacchi         ECORE_SET_BIT(ECORE_RSS_SET_SRCH, &params.rss_flags);
2599*d14abf15SRobert Mustacchi     }
2600*d14abf15SRobert Mustacchi 
2601*d14abf15SRobert Mustacchi     DbgBreakIf(!reconfigure && sync_with_toe);
2602*d14abf15SRobert Mustacchi     /* Not expected, that toe will update and ETH not, but just to make sure, if sync_with_toe
2603*d14abf15SRobert Mustacchi      * is true it means toe reconfigured... so eth must to to take care of sync... */
2604*d14abf15SRobert Mustacchi     if (reconfigure || sync_with_toe)
2605*d14abf15SRobert Mustacchi     {
2606*d14abf15SRobert Mustacchi         /* If we're not syncing with toe, it means that these counters have not
2607*d14abf15SRobert Mustacchi          * been increased by toe, and need to be increased here. */
2608*d14abf15SRobert Mustacchi         if (!sync_with_toe)
2609*d14abf15SRobert Mustacchi         {
2610*d14abf15SRobert Mustacchi             DbgBreakIf(pdev->params.update_comp_cnt);
2611*d14abf15SRobert Mustacchi             mm_atomic_inc(&pdev->params.update_comp_cnt);
2612*d14abf15SRobert Mustacchi             mm_atomic_inc(&pdev->params.update_suspend_cnt);
2613*d14abf15SRobert Mustacchi         }
2614*d14abf15SRobert Mustacchi 
2615*d14abf15SRobert Mustacchi         DbgBreakIf(pdev->slowpath_info.set_rss_cookie);
2616*d14abf15SRobert Mustacchi         pdev->slowpath_info.set_rss_cookie = cookie;
2617*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
2618*d14abf15SRobert Mustacchi         if (IS_CHANNEL_VFDEV(pdev))
2619*d14abf15SRobert Mustacchi         {
2620*d14abf15SRobert Mustacchi             lm_status = lm_vf_pf_update_rss(pdev, NULL, params.rss_flags, params.rss_result_mask, params.ind_table, params.rss_key);
2621*d14abf15SRobert Mustacchi             if (lm_status == LM_STATUS_SUCCESS)
2622*d14abf15SRobert Mustacchi             {
2623*d14abf15SRobert Mustacchi                 lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2624*d14abf15SRobert Mustacchi                 mm_atomic_dec(&pdev->params.update_comp_cnt);
2625*d14abf15SRobert Mustacchi                 mm_atomic_dec(&pdev->params.update_suspend_cnt);
2626*d14abf15SRobert Mustacchi 
2627*d14abf15SRobert Mustacchi             }
2628*d14abf15SRobert Mustacchi         }
2629*d14abf15SRobert Mustacchi         else
2630*d14abf15SRobert Mustacchi #endif
2631*d14abf15SRobert Mustacchi         {
2632*d14abf15SRobert Mustacchi             ecore_status = ecore_config_rss(pdev, &params);
2633*d14abf15SRobert Mustacchi             lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2634*d14abf15SRobert Mustacchi         }
2635*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_SUCCESS)
2636*d14abf15SRobert Mustacchi         {
2637*d14abf15SRobert Mustacchi             lm_status = LM_STATUS_PENDING;
2638*d14abf15SRobert Mustacchi         }
2639*d14abf15SRobert Mustacchi     }
2640*d14abf15SRobert Mustacchi 
2641*d14abf15SRobert Mustacchi     return lm_status;
2642*d14abf15SRobert Mustacchi }
2643*d14abf15SRobert Mustacchi 
2644*d14abf15SRobert Mustacchi 
2645*d14abf15SRobert Mustacchi /**
2646*d14abf15SRobert Mustacchi  * @Description
2647*d14abf15SRobert Mustacchi  *      This routine disables rss functionality by sending a
2648*d14abf15SRobert Mustacchi  *      ramrod to FW.
2649*d14abf15SRobert Mustacchi  *
2650*d14abf15SRobert Mustacchi  * @param pdev
2651*d14abf15SRobert Mustacchi  * @param cookie - will be returned on completion
2652*d14abf15SRobert Mustacchi  * @param sync_with_toe - true means this call is synced with
2653*d14abf15SRobert Mustacchi  *                      toe, and completion will be called only
2654*d14abf15SRobert Mustacchi  *                      when both toe + eth complete. Eth needs
2655*d14abf15SRobert Mustacchi  *                      to know this (reason in code) *
2656*d14abf15SRobert Mustacchi  *
2657*d14abf15SRobert Mustacchi  * @return lm_status_t - SUCCESS on syncrounous completion
2658*d14abf15SRobert Mustacchi  *                       PENDING on asyncounous completion
2659*d14abf15SRobert Mustacchi  *                       FAILURE o/w
2660*d14abf15SRobert Mustacchi  */
lm_disable_rss(struct _lm_device_t * pdev,u8_t sync_with_toe,void * cookie)2661*d14abf15SRobert Mustacchi lm_status_t lm_disable_rss(struct _lm_device_t *pdev, u8_t sync_with_toe, void * cookie)
2662*d14abf15SRobert Mustacchi {
2663*d14abf15SRobert Mustacchi     struct ecore_config_rss_params params       = {0};
2664*d14abf15SRobert Mustacchi     lm_status_t                    lm_status    = LM_STATUS_FAILURE;
2665*d14abf15SRobert Mustacchi     ecore_status_t                 ecore_status = ECORE_SUCCESS;
2666*d14abf15SRobert Mustacchi     u8_t                           value        = 0;
2667*d14abf15SRobert Mustacchi     u8_t                           i            = 0;
2668*d14abf15SRobert Mustacchi 
2669*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMl2sp, "lm_disable_rss sync_with_toe = %d\n", sync_with_toe);
2670*d14abf15SRobert Mustacchi 
2671*d14abf15SRobert Mustacchi     DbgBreakIf(pdev->slowpath_info.set_rss_cookie);
2672*d14abf15SRobert Mustacchi     pdev->slowpath_info.set_rss_cookie = cookie;
2673*d14abf15SRobert Mustacchi 
2674*d14abf15SRobert Mustacchi     params.rss_obj = &pdev->slowpath_info.rss_conf_obj;
2675*d14abf15SRobert Mustacchi 
2676*d14abf15SRobert Mustacchi     /* RSS mode */
2677*d14abf15SRobert Mustacchi     ECORE_SET_BIT(ECORE_RSS_MODE_DISABLED, &params.rss_flags);
2678*d14abf15SRobert Mustacchi     pdev->slowpath_info.last_set_rss_flags = params.rss_flags;
2679*d14abf15SRobert Mustacchi 
2680*d14abf15SRobert Mustacchi     /* If we're not syncing with toe, it means that these counters have not
2681*d14abf15SRobert Mustacchi      * been increased by toe, and need to be increased here. */
2682*d14abf15SRobert Mustacchi     if (!sync_with_toe)
2683*d14abf15SRobert Mustacchi     {
2684*d14abf15SRobert Mustacchi         mm_atomic_inc(&pdev->params.update_comp_cnt);
2685*d14abf15SRobert Mustacchi         mm_atomic_inc(&pdev->params.update_suspend_cnt);
2686*d14abf15SRobert Mustacchi     }
2687*d14abf15SRobert Mustacchi 
2688*d14abf15SRobert Mustacchi     value = LM_CHAIN_TO_FW_CLIENT(pdev,LM_SW_LEADING_RSS_CID(pdev));
2689*d14abf15SRobert Mustacchi     for (i = 0; i < ARRSIZE(params.ind_table); i++)
2690*d14abf15SRobert Mustacchi     {
2691*d14abf15SRobert Mustacchi         pdev->slowpath_info.last_set_indirection_table[i] = value;
2692*d14abf15SRobert Mustacchi         params.ind_table[i] = value;
2693*d14abf15SRobert Mustacchi     }
2694*d14abf15SRobert Mustacchi 
2695*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
2696*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VFDEV(pdev))
2697*d14abf15SRobert Mustacchi     {
2698*d14abf15SRobert Mustacchi         lm_status = lm_vf_pf_update_rss(pdev, NULL, params.rss_flags, params.rss_result_mask, params.ind_table, params.rss_key);
2699*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_SUCCESS)
2700*d14abf15SRobert Mustacchi         {
2701*d14abf15SRobert Mustacchi             lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2702*d14abf15SRobert Mustacchi             mm_atomic_dec(&pdev->params.update_comp_cnt);
2703*d14abf15SRobert Mustacchi             mm_atomic_dec(&pdev->params.update_suspend_cnt);
2704*d14abf15SRobert Mustacchi         }
2705*d14abf15SRobert Mustacchi     }
2706*d14abf15SRobert Mustacchi     else
2707*d14abf15SRobert Mustacchi #endif
2708*d14abf15SRobert Mustacchi     {
2709*d14abf15SRobert Mustacchi         ecore_status = ecore_config_rss(pdev, &params);
2710*d14abf15SRobert Mustacchi         lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2711*d14abf15SRobert Mustacchi     }
2712*d14abf15SRobert Mustacchi 
2713*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_SUCCESS)
2714*d14abf15SRobert Mustacchi     {
2715*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_PENDING;
2716*d14abf15SRobert Mustacchi     }
2717*d14abf15SRobert Mustacchi     return lm_status;
2718*d14abf15SRobert Mustacchi 
2719*d14abf15SRobert Mustacchi } /* lm_disable_rss */
2720*d14abf15SRobert Mustacchi 
2721*d14abf15SRobert Mustacchi /**
2722*d14abf15SRobert Mustacchi  * @Description
2723*d14abf15SRobert Mustacchi  *      Wait for the rss disable/enable configuration to
2724*d14abf15SRobert Mustacchi  *      complete
2725*d14abf15SRobert Mustacchi  *
2726*d14abf15SRobert Mustacchi  * @param pdev
2727*d14abf15SRobert Mustacchi  *
2728*d14abf15SRobert Mustacchi  * @return lm_status_t lm_status_t SUCCESS or TIMEOUT
2729*d14abf15SRobert Mustacchi  */
lm_wait_config_rss_done(struct _lm_device_t * pdev)2730*d14abf15SRobert Mustacchi lm_status_t lm_wait_config_rss_done(struct _lm_device_t *pdev)
2731*d14abf15SRobert Mustacchi {
2732*d14abf15SRobert Mustacchi     struct ecore_raw_obj   *raw         = &pdev->slowpath_info.rss_conf_obj.raw;
2733*d14abf15SRobert Mustacchi     lm_status_t            lm_status    = LM_STATUS_FAILURE;
2734*d14abf15SRobert Mustacchi     ecore_status_t         ecore_status = raw->wait_comp(pdev, raw);
2735*d14abf15SRobert Mustacchi 
2736*d14abf15SRobert Mustacchi     lm_status = lm_ecore_status_to_lm_status(ecore_status);
2737*d14abf15SRobert Mustacchi 
2738*d14abf15SRobert Mustacchi     return lm_status;
2739*d14abf15SRobert Mustacchi }
2740*d14abf15SRobert Mustacchi 
2741*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
lm_wait_vf_config_rss_done(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)2742*d14abf15SRobert Mustacchi lm_status_t lm_wait_vf_config_rss_done(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
2743*d14abf15SRobert Mustacchi {
2744*d14abf15SRobert Mustacchi     struct ecore_raw_obj *raw = &vf_info->vf_slowpath_info.rss_conf_obj.raw;
2745*d14abf15SRobert Mustacchi     lm_status_t            lm_status    = LM_STATUS_FAILURE;
2746*d14abf15SRobert Mustacchi     ecore_status_t         ecore_status = raw->wait_comp(pdev, raw);
2747*d14abf15SRobert Mustacchi 
2748*d14abf15SRobert Mustacchi     lm_status = lm_ecore_status_to_lm_status(ecore_status);
2749*d14abf15SRobert Mustacchi 
2750*d14abf15SRobert Mustacchi     return lm_status;
2751*d14abf15SRobert Mustacchi }
2752*d14abf15SRobert Mustacchi #endif
2753*d14abf15SRobert Mustacchi 
2754*d14abf15SRobert Mustacchi /************************** EQ HANDLING *******************************************/
2755*d14abf15SRobert Mustacchi 
lm_eq_handle_function_start_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2756*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_function_start_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2757*d14abf15SRobert Mustacchi {
2758*d14abf15SRobert Mustacchi     pdev->eq_info.function_state = FUNCTION_START_COMPLETED;
2759*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_COMMON_FUNCTION_START,
2760*d14abf15SRobert Mustacchi                    NONE_CONNECTION_TYPE, 0);
2761*d14abf15SRobert Mustacchi }
2762*d14abf15SRobert Mustacchi 
lm_eq_handle_function_stop_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2763*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_function_stop_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2764*d14abf15SRobert Mustacchi {
2765*d14abf15SRobert Mustacchi     pdev->eq_info.function_state = FUNCTION_STOP_COMPLETED;
2766*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_COMMON_FUNCTION_STOP,
2767*d14abf15SRobert Mustacchi                    NONE_CONNECTION_TYPE, 0);
2768*d14abf15SRobert Mustacchi 
2769*d14abf15SRobert Mustacchi }
2770*d14abf15SRobert Mustacchi 
lm_eq_handle_cfc_del_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2771*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_cfc_del_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2772*d14abf15SRobert Mustacchi {
2773*d14abf15SRobert Mustacchi     u32_t cid   = 0;
2774*d14abf15SRobert Mustacchi     u8_t  error = 0;
2775*d14abf15SRobert Mustacchi 
2776*d14abf15SRobert Mustacchi     cid = mm_le32_to_cpu(elem->message.data.cfc_del_event.cid);
2777*d14abf15SRobert Mustacchi     cid = SW_CID(cid);
2778*d14abf15SRobert Mustacchi 
2779*d14abf15SRobert Mustacchi     error = elem->message.error;
2780*d14abf15SRobert Mustacchi 
2781*d14abf15SRobert Mustacchi     if (cid < pdev->context_info->proto_start[TOE_CONNECTION_TYPE]) //(MAX_ETH_CONS + MAX_VF_ETH_CONS))
2782*d14abf15SRobert Mustacchi     {   /* cfc del completion for eth cid */
2783*d14abf15SRobert Mustacchi         DbgBreakIf(lm_get_con_state(pdev, cid) != LM_CON_STATE_TERMINATE);
2784*d14abf15SRobert Mustacchi         lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
2785*d14abf15SRobert Mustacchi         DbgMessage(pdev, WARNeq, "lm_service_eq_intr: EVENT_RING_OPCODE_CFC_DEL_WB - calling lm_extract_ramrod_req!\n");
2786*d14abf15SRobert Mustacchi     }
2787*d14abf15SRobert Mustacchi     else
2788*d14abf15SRobert Mustacchi     {   /* cfc del completion for toe cid */
2789*d14abf15SRobert Mustacchi         if (error) {
2790*d14abf15SRobert Mustacchi 
2791*d14abf15SRobert Mustacchi             if (lm_map_cid_to_proto(pdev, cid) != TOE_CONNECTION_TYPE)
2792*d14abf15SRobert Mustacchi             {
2793*d14abf15SRobert Mustacchi                 DbgMessage(pdev, FATAL, "ERROR completion is not valid for cid=0x%x\n",cid);
2794*d14abf15SRobert Mustacchi                 DbgBreakIfAll(1);
2795*d14abf15SRobert Mustacchi             }
2796*d14abf15SRobert Mustacchi             pdev->toe_info.stats.total_cfc_delete_error++;
2797*d14abf15SRobert Mustacchi             if (pdev->context_info->array[cid].cfc_delete_cnt++ < LM_MAX_VALID_CFC_DELETIONS)
2798*d14abf15SRobert Mustacchi             {
2799*d14abf15SRobert Mustacchi                 DbgMessage(pdev, WARNl4sp, "lm_eth_comp_cb: RAMROD_CMD_ID_ETH_CFC_DEL(0x%x) - %d resending!\n", cid,
2800*d14abf15SRobert Mustacchi                             pdev->context_info->array[cid].cfc_delete_cnt);
2801*d14abf15SRobert Mustacchi                 lm_command_post(pdev,
2802*d14abf15SRobert Mustacchi                                 cid,
2803*d14abf15SRobert Mustacchi                                 RAMROD_CMD_ID_COMMON_CFC_DEL,
2804*d14abf15SRobert Mustacchi                                 CMD_PRIORITY_NORMAL,
2805*d14abf15SRobert Mustacchi                                 NONE_CONNECTION_TYPE,
2806*d14abf15SRobert Mustacchi                                 0 );
2807*d14abf15SRobert Mustacchi             }
2808*d14abf15SRobert Mustacchi             else
2809*d14abf15SRobert Mustacchi             {
2810*d14abf15SRobert Mustacchi                 DbgMessage(pdev, FATAL, "A number of CFC deletions exceeded valid number of attempts\n");
2811*d14abf15SRobert Mustacchi                 DbgBreakIfAll(1);
2812*d14abf15SRobert Mustacchi             }
2813*d14abf15SRobert Mustacchi         }
2814*d14abf15SRobert Mustacchi         else
2815*d14abf15SRobert Mustacchi         {
2816*d14abf15SRobert Mustacchi             lm_recycle_cid(pdev, cid);
2817*d14abf15SRobert Mustacchi         }
2818*d14abf15SRobert Mustacchi     }
2819*d14abf15SRobert Mustacchi 
2820*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL,
2821*d14abf15SRobert Mustacchi                    (elem->message.opcode == EVENT_RING_OPCODE_CFC_DEL)? RAMROD_CMD_ID_COMMON_CFC_DEL : RAMROD_CMD_ID_COMMON_CFC_DEL_WB,
2822*d14abf15SRobert Mustacchi                    NONE_CONNECTION_TYPE, cid);
2823*d14abf15SRobert Mustacchi }
2824*d14abf15SRobert Mustacchi 
lm_eq_handle_fwd_setup_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2825*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_fwd_setup_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2826*d14abf15SRobert Mustacchi {
2827*d14abf15SRobert Mustacchi     DbgBreakIf(lm_get_con_state(pdev, FWD_CID(pdev)) != LM_CON_STATE_OPEN_SENT);
2828*d14abf15SRobert Mustacchi     lm_set_con_state(pdev, FWD_CID(pdev), LM_CON_STATE_OPEN);
2829*d14abf15SRobert Mustacchi 
2830*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARNl2sp, "comp of FWD SETUP -calling lm_extract_ramrod_req!\n");
2831*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_ETH_FORWARD_SETUP,
2832*d14abf15SRobert Mustacchi                    ETH_CONNECTION_TYPE, FWD_CID(pdev));
2833*d14abf15SRobert Mustacchi 
2834*d14abf15SRobert Mustacchi }
2835*d14abf15SRobert Mustacchi 
lm_eq_handle_mcast_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2836*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_mcast_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2837*d14abf15SRobert Mustacchi {
2838*d14abf15SRobert Mustacchi     struct ecore_mcast_ramrod_params  rparam         = {0};
2839*d14abf15SRobert Mustacchi     void                            * cookie         = NULL;
2840*d14abf15SRobert Mustacchi     lm_status_t                       lm_status      = LM_STATUS_FAILURE;
2841*d14abf15SRobert Mustacchi     ecore_status_t                    ecore_status   = ECORE_SUCCESS;
2842*d14abf15SRobert Mustacchi     u32_t                             cid            = mm_le32_to_cpu(elem->message.data.eth_event.echo) & ECORE_SWCID_MASK;
2843*d14abf15SRobert Mustacchi     const u8_t                        lm_cli_idx     = LM_CHAIN_IDX_CLI(pdev, cid);
2844*d14abf15SRobert Mustacchi     struct ecore_mcast_obj          * obj            = &pdev->slowpath_info.mcast_obj[lm_cli_idx];
2845*d14abf15SRobert Mustacchi     u8_t                              indicate_done  = TRUE;
2846*d14abf15SRobert Mustacchi 
2847*d14abf15SRobert Mustacchi     if(LM_CLI_IDX_MAX <= lm_cli_idx)
2848*d14abf15SRobert Mustacchi     {
2849*d14abf15SRobert Mustacchi         DbgBreakMsg(" lm_eq_handle_mcast_eqe lm_cli_idx is invalid ");
2850*d14abf15SRobert Mustacchi         return;
2851*d14abf15SRobert Mustacchi     }
2852*d14abf15SRobert Mustacchi 
2853*d14abf15SRobert Mustacchi     /* Clear pending state for the last command */
2854*d14abf15SRobert Mustacchi     obj->raw.clear_pending(&obj->raw);
2855*d14abf15SRobert Mustacchi 
2856*d14abf15SRobert Mustacchi     rparam.mcast_obj = obj;
2857*d14abf15SRobert Mustacchi 
2858*d14abf15SRobert Mustacchi     /* If there are pending mcast commands - send them */
2859*d14abf15SRobert Mustacchi     if (obj->check_pending(obj))
2860*d14abf15SRobert Mustacchi     {
2861*d14abf15SRobert Mustacchi         ecore_status = ecore_config_mcast(pdev, &rparam, ECORE_MCAST_CMD_CONT);
2862*d14abf15SRobert Mustacchi         lm_status    = lm_ecore_status_to_lm_status(ecore_status);
2863*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_PENDING)
2864*d14abf15SRobert Mustacchi         {
2865*d14abf15SRobert Mustacchi             indicate_done = FALSE;
2866*d14abf15SRobert Mustacchi         }
2867*d14abf15SRobert Mustacchi         else if (lm_status != LM_STATUS_SUCCESS)
2868*d14abf15SRobert Mustacchi         {
2869*d14abf15SRobert Mustacchi             DbgMessage(pdev, FATAL, "Failed to send pending mcast commands: %d\n", lm_status);
2870*d14abf15SRobert Mustacchi             DbgBreakMsg("Unexpected pending mcast command failed\n");
2871*d14abf15SRobert Mustacchi         }
2872*d14abf15SRobert Mustacchi     }
2873*d14abf15SRobert Mustacchi 
2874*d14abf15SRobert Mustacchi     if (indicate_done)
2875*d14abf15SRobert Mustacchi     {
2876*d14abf15SRobert Mustacchi         if (pdev->slowpath_info.set_mcast_cookie[lm_cli_idx])
2877*d14abf15SRobert Mustacchi         {
2878*d14abf15SRobert Mustacchi             cookie = (void *)pdev->slowpath_info.set_mcast_cookie[lm_cli_idx];
2879*d14abf15SRobert Mustacchi             pdev->slowpath_info.set_mcast_cookie[lm_cli_idx] = NULL;
2880*d14abf15SRobert Mustacchi             mm_set_done(pdev, cid, cookie);
2881*d14abf15SRobert Mustacchi         }
2882*d14abf15SRobert Mustacchi     }
2883*d14abf15SRobert Mustacchi 
2884*d14abf15SRobert Mustacchi     if (CHIP_IS_E1(pdev))
2885*d14abf15SRobert Mustacchi     {
2886*d14abf15SRobert Mustacchi         lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_ETH_SET_MAC,
2887*d14abf15SRobert Mustacchi                        ETH_CONNECTION_TYPE, cid);
2888*d14abf15SRobert Mustacchi     }
2889*d14abf15SRobert Mustacchi     else
2890*d14abf15SRobert Mustacchi     {
2891*d14abf15SRobert Mustacchi         lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_ETH_MULTICAST_RULES,
2892*d14abf15SRobert Mustacchi                        ETH_CONNECTION_TYPE, cid);
2893*d14abf15SRobert Mustacchi     }
2894*d14abf15SRobert Mustacchi }
2895*d14abf15SRobert Mustacchi 
lm_eq_handle_classification_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)2896*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_classification_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
2897*d14abf15SRobert Mustacchi {
2898*d14abf15SRobert Mustacchi     struct ecore_raw_obj        *raw                 = NULL;
2899*d14abf15SRobert Mustacchi     void                        *cookie              = NULL;
2900*d14abf15SRobert Mustacchi     u32_t                       cid                  = GET_FLAGS( mm_le32_to_cpu(elem->message.data.eth_event.echo), ECORE_SWCID_MASK );
2901*d14abf15SRobert Mustacchi     u8_t                        type                 = mm_le32_to_cpu(elem->message.data.eth_event.echo) >> ECORE_SWCID_SHIFT;
2902*d14abf15SRobert Mustacchi     u32_t                       client_info_idx      = 0;
2903*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_obj*  p_ecore_vlan_mac_obj = NULL;
2904*d14abf15SRobert Mustacchi     unsigned long               ramrod_flags         = 0;
2905*d14abf15SRobert Mustacchi     ecore_status_t              ecore_status         = ECORE_SUCCESS;
2906*d14abf15SRobert Mustacchi     int i;
2907*d14abf15SRobert Mustacchi 
2908*d14abf15SRobert Mustacchi     client_info_idx = lm_get_sw_client_idx_from_cid(pdev,cid);
2909*d14abf15SRobert Mustacchi 
2910*d14abf15SRobert Mustacchi     /* Relevant to 57710, mcast is implemented as "set-macs"*/
2911*d14abf15SRobert Mustacchi     if (type == ECORE_FILTER_MCAST_PENDING)
2912*d14abf15SRobert Mustacchi     {
2913*d14abf15SRobert Mustacchi         DbgBreakIf(!CHIP_IS_E1(pdev));
2914*d14abf15SRobert Mustacchi         lm_eq_handle_mcast_eqe(pdev, elem);
2915*d14abf15SRobert Mustacchi         return;
2916*d14abf15SRobert Mustacchi     }
2917*d14abf15SRobert Mustacchi 
2918*d14abf15SRobert Mustacchi     switch (type)
2919*d14abf15SRobert Mustacchi     {
2920*d14abf15SRobert Mustacchi     case ECORE_FILTER_MAC_PENDING:
2921*d14abf15SRobert Mustacchi         raw                  = &pdev->client_info[client_info_idx].mac_obj.raw;
2922*d14abf15SRobert Mustacchi         p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].mac_obj;
2923*d14abf15SRobert Mustacchi         break;
2924*d14abf15SRobert Mustacchi     case ECORE_FILTER_VLAN_MAC_PENDING:
2925*d14abf15SRobert Mustacchi         raw                  = &pdev->client_info[client_info_idx].mac_vlan_obj.raw;
2926*d14abf15SRobert Mustacchi         p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].mac_vlan_obj;
2927*d14abf15SRobert Mustacchi         break;
2928*d14abf15SRobert Mustacchi     case ECORE_FILTER_VLAN_PENDING:
2929*d14abf15SRobert Mustacchi         raw = &pdev->client_info[client_info_idx].vlan_obj.raw;
2930*d14abf15SRobert Mustacchi         p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].vlan_obj;
2931*d14abf15SRobert Mustacchi         SET_BIT( ramrod_flags, RAMROD_CONT );
2932*d14abf15SRobert Mustacchi         break;
2933*d14abf15SRobert Mustacchi     default:
2934*d14abf15SRobert Mustacchi         /* unknown ER handling*/
2935*d14abf15SRobert Mustacchi         /* Special handling for case that type is unknown (error recovery flow)
2936*d14abf15SRobert Mustacchi          * check which object is pending, and clear the relevant one. */
2937*d14abf15SRobert Mustacchi         raw                  = &pdev->client_info[client_info_idx].mac_obj.raw;
2938*d14abf15SRobert Mustacchi         p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].mac_obj;
2939*d14abf15SRobert Mustacchi         type                 = ECORE_FILTER_MAC_PENDING;
2940*d14abf15SRobert Mustacchi         if (!raw->check_pending(raw))
2941*d14abf15SRobert Mustacchi         {
2942*d14abf15SRobert Mustacchi             raw                  = &pdev->client_info[client_info_idx].mac_vlan_obj.raw;
2943*d14abf15SRobert Mustacchi             p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].mac_vlan_obj;
2944*d14abf15SRobert Mustacchi             type                 = ECORE_FILTER_VLAN_MAC_PENDING;
2945*d14abf15SRobert Mustacchi         }
2946*d14abf15SRobert Mustacchi         if (!raw->check_pending(raw))
2947*d14abf15SRobert Mustacchi         {
2948*d14abf15SRobert Mustacchi             raw                  = &pdev->client_info[client_info_idx].vlan_obj.raw;
2949*d14abf15SRobert Mustacchi             p_ecore_vlan_mac_obj = &pdev->client_info[client_info_idx].vlan_obj;
2950*d14abf15SRobert Mustacchi             type                 = ECORE_FILTER_VLAN_PENDING;
2951*d14abf15SRobert Mustacchi         }
2952*d14abf15SRobert Mustacchi         break;
2953*d14abf15SRobert Mustacchi     }
2954*d14abf15SRobert Mustacchi 
2955*d14abf15SRobert Mustacchi     ecore_status = p_ecore_vlan_mac_obj->complete( pdev, p_ecore_vlan_mac_obj, elem, &ramrod_flags );
2956*d14abf15SRobert Mustacchi 
2957*d14abf15SRobert Mustacchi     // We expect here only these 2 status (CQ61418)
2958*d14abf15SRobert Mustacchi     DbgBreakIf ( ( ECORE_SUCCESS != ecore_status ) && ( ECORE_PENDING != ecore_status ) );
2959*d14abf15SRobert Mustacchi 
2960*d14abf15SRobert Mustacchi     if (( ECORE_SUCCESS != ecore_status ) && (!CHIP_IS_E1x(pdev)))
2961*d14abf15SRobert Mustacchi     {
2962*d14abf15SRobert Mustacchi         DbgMessage(pdev, WARN,
2963*d14abf15SRobert Mustacchi         "lm_eq_handle_classification_eqe: commands' length is above CLASSIFY_RULES_COUNT (the maximum length of commands' list for one execution), ecore_status = %d", ecore_status);
2964*d14abf15SRobert Mustacchi     }
2965*d14abf15SRobert Mustacchi 
2966*d14abf15SRobert Mustacchi     // verify that the mac_local mac_add1 & mac_add2 are continuous
2967*d14abf15SRobert Mustacchi     ASSERT_STATIC( OFFSETOF( eth_stats_info_t, mac_local )+ sizeof(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats.mac_local) ==  OFFSETOF( eth_stats_info_t, mac_add1 ) );
2968*d14abf15SRobert Mustacchi     ASSERT_STATIC( OFFSETOF( eth_stats_info_t, mac_add1 ) + sizeof(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats.mac_add1) ==   OFFSETOF( eth_stats_info_t, mac_add2 ) );
2969*d14abf15SRobert Mustacchi 
2970*d14abf15SRobert Mustacchi     if( (NDIS_CID(pdev) == client_info_idx) && (type == ECORE_FILTER_MAC_PENDING) )
2971*d14abf15SRobert Mustacchi     {
2972*d14abf15SRobert Mustacchi         if ( NULL == p_ecore_vlan_mac_obj->get_n_elements )
2973*d14abf15SRobert Mustacchi         {
2974*d14abf15SRobert Mustacchi             DbgBreakIf( !CHIP_IS_E1x(pdev) );
2975*d14abf15SRobert Mustacchi         }
2976*d14abf15SRobert Mustacchi         else
2977*d14abf15SRobert Mustacchi         {
2978*d14abf15SRobert Mustacchi             // We want to keep only eth mac this is for E3 only but we keep it anyway also for E2...
2979*d14abf15SRobert Mustacchi             for (i = 0; i < 3; i++)
2980*d14abf15SRobert Mustacchi                 mm_mem_zero(pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats.mac_local + i, sizeof(u8_t));
2981*d14abf15SRobert Mustacchi             p_ecore_vlan_mac_obj->get_n_elements(pdev, p_ecore_vlan_mac_obj ,3, pdev->vars.stats.stats_mirror.stats_drv.drv_info_to_mfw.eth_stats.mac_local + MAC_PAD, MAC_PAD, ETH_ALEN);
2982*d14abf15SRobert Mustacchi         }
2983*d14abf15SRobert Mustacchi     }
2984*d14abf15SRobert Mustacchi 
2985*d14abf15SRobert Mustacchi     if (pdev->client_info[client_info_idx].set_mac_cookie)
2986*d14abf15SRobert Mustacchi     {
2987*d14abf15SRobert Mustacchi         cookie = (void *)pdev->client_info[client_info_idx].set_mac_cookie;
2988*d14abf15SRobert Mustacchi         pdev->client_info[client_info_idx].set_mac_cookie = NULL;
2989*d14abf15SRobert Mustacchi         mm_set_done(pdev, cid, cookie);
2990*d14abf15SRobert Mustacchi     }
2991*d14abf15SRobert Mustacchi 
2992*d14abf15SRobert Mustacchi     if (CHIP_IS_E1x(pdev))
2993*d14abf15SRobert Mustacchi     {
2994*d14abf15SRobert Mustacchi         lm_sq_complete(pdev, CMD_PRIORITY_NORMAL,
2995*d14abf15SRobert Mustacchi                        RAMROD_CMD_ID_ETH_SET_MAC, ETH_CONNECTION_TYPE, cid);
2996*d14abf15SRobert Mustacchi     }
2997*d14abf15SRobert Mustacchi     else
2998*d14abf15SRobert Mustacchi     {
2999*d14abf15SRobert Mustacchi         lm_sq_complete(pdev, CMD_PRIORITY_NORMAL,
3000*d14abf15SRobert Mustacchi                        RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES, ETH_CONNECTION_TYPE, cid);
3001*d14abf15SRobert Mustacchi     }
3002*d14abf15SRobert Mustacchi }
3003*d14abf15SRobert Mustacchi 
lm_eq_handle_stats_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3004*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_stats_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3005*d14abf15SRobert Mustacchi {
3006*d14abf15SRobert Mustacchi     /* Order is important!!!
3007*d14abf15SRobert Mustacchi      * stats use a predefined ramrod. We need to make sure that we first complete the ramrod, which will
3008*d14abf15SRobert Mustacchi      * take it out of sq-completed list, and only after that mark the ramrod as completed, so that a new
3009*d14abf15SRobert Mustacchi      * ramrod can be sent!.
3010*d14abf15SRobert Mustacchi      */
3011*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_HIGH,
3012*d14abf15SRobert Mustacchi                    RAMROD_CMD_ID_COMMON_STAT_QUERY, NONE_CONNECTION_TYPE, 0);
3013*d14abf15SRobert Mustacchi 
3014*d14abf15SRobert Mustacchi     mm_write_barrier(); /* barrier to make sure command before this line completes before executing the next line! */
3015*d14abf15SRobert Mustacchi     pdev->vars.stats.stats_collect.stats_fw.b_ramrod_completed = TRUE;
3016*d14abf15SRobert Mustacchi 
3017*d14abf15SRobert Mustacchi }
3018*d14abf15SRobert Mustacchi 
lm_eq_handle_filter_rules_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3019*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_filter_rules_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3020*d14abf15SRobert Mustacchi {
3021*d14abf15SRobert Mustacchi     struct ecore_vlan_mac_ramrod_params p;
3022*d14abf15SRobert Mustacchi     void  * cookie = NULL;
3023*d14abf15SRobert Mustacchi     u32_t   cid    = 0;
3024*d14abf15SRobert Mustacchi 
3025*d14abf15SRobert Mustacchi     cid = mm_le32_to_cpu(elem->message.data.eth_event.echo) & ECORE_SWCID_MASK;
3026*d14abf15SRobert Mustacchi 
3027*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMeq | INFORMl2sp, "Filter rule completion: cid %d, client_info %d\n",cid);
3028*d14abf15SRobert Mustacchi 
3029*d14abf15SRobert Mustacchi     // FIXME: pdev->client_info[cid].mac_obj.raw.clear_pending(&pdev->client_info[cid].mac_obj.raw);
3030*d14abf15SRobert Mustacchi     ECORE_CLEAR_BIT(ECORE_FILTER_RX_MODE_PENDING, &pdev->client_info[cid].sp_rxmode_state);
3031*d14abf15SRobert Mustacchi 
3032*d14abf15SRobert Mustacchi     if (pdev->client_info[cid].set_rx_mode_cookie)
3033*d14abf15SRobert Mustacchi     {
3034*d14abf15SRobert Mustacchi         cookie = (void *)pdev->client_info[cid].set_rx_mode_cookie;
3035*d14abf15SRobert Mustacchi         pdev->client_info[cid].set_rx_mode_cookie = NULL;
3036*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORMl2sp, "Filter rule calling mm_set_done... \n");
3037*d14abf15SRobert Mustacchi         mm_set_done(pdev, cid, cookie);
3038*d14abf15SRobert Mustacchi     }
3039*d14abf15SRobert Mustacchi 
3040*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_ETH_FILTER_RULES, ETH_CONNECTION_TYPE, cid);
3041*d14abf15SRobert Mustacchi 
3042*d14abf15SRobert Mustacchi     if (pdev->client_info[cid].b_vlan_only_in_process)
3043*d14abf15SRobert Mustacchi     {
3044*d14abf15SRobert Mustacchi         pdev->client_info[cid].b_vlan_only_in_process = FALSE;
3045*d14abf15SRobert Mustacchi 
3046*d14abf15SRobert Mustacchi            p.vlan_mac_obj = &pdev->client_info[cid].vlan_obj;
3047*d14abf15SRobert Mustacchi         p.ramrod_flags = 0;
3048*d14abf15SRobert Mustacchi         SET_BIT( (p.ramrod_flags), RAMROD_CONT );
3049*d14abf15SRobert Mustacchi 
3050*d14abf15SRobert Mustacchi         ecore_config_vlan_mac(pdev, &p);
3051*d14abf15SRobert Mustacchi     }
3052*d14abf15SRobert Mustacchi }
3053*d14abf15SRobert Mustacchi 
lm_eq_handle_rss_update_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3054*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_rss_update_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3055*d14abf15SRobert Mustacchi {
3056*d14abf15SRobert Mustacchi     struct ecore_raw_obj  * raw    = NULL;
3057*d14abf15SRobert Mustacchi     void                  * cookie = NULL;
3058*d14abf15SRobert Mustacchi     u32_t                   cid    = LM_SW_LEADING_RSS_CID(pdev);
3059*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
3060*d14abf15SRobert Mustacchi     u8_t abs_vf_id;
3061*d14abf15SRobert Mustacchi     lm_vf_info_t * vf_info;
3062*d14abf15SRobert Mustacchi #endif
3063*d14abf15SRobert Mustacchi 
3064*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORMeq | INFORMl2sp, "lm_eth_comp_cb: EVENT_RING_OPCODE_RSS_UPDATE_RULES\n");
3065*d14abf15SRobert Mustacchi 
3066*d14abf15SRobert Mustacchi 
3067*d14abf15SRobert Mustacchi     cid = mm_le32_to_cpu(elem->message.data.eth_event.echo) & ECORE_SWCID_MASK;
3068*d14abf15SRobert Mustacchi 
3069*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
3070*d14abf15SRobert Mustacchi     if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev) && (cid >= MAX_RX_CHAIN(pdev)))
3071*d14abf15SRobert Mustacchi     {
3072*d14abf15SRobert Mustacchi         abs_vf_id = GET_ABS_VF_ID_FROM_PF_CID(cid);
3073*d14abf15SRobert Mustacchi         vf_info = lm_pf_find_vf_info_by_abs_id(pdev, abs_vf_id);
3074*d14abf15SRobert Mustacchi         DbgBreakIf(!vf_info);
3075*d14abf15SRobert Mustacchi         raw = &vf_info->vf_slowpath_info.rss_conf_obj.raw;
3076*d14abf15SRobert Mustacchi         raw->clear_pending(raw);
3077*d14abf15SRobert Mustacchi     }
3078*d14abf15SRobert Mustacchi     else
3079*d14abf15SRobert Mustacchi #endif
3080*d14abf15SRobert Mustacchi     {
3081*d14abf15SRobert Mustacchi 
3082*d14abf15SRobert Mustacchi         raw = &pdev->slowpath_info.rss_conf_obj.raw;
3083*d14abf15SRobert Mustacchi         raw->clear_pending(raw);
3084*d14abf15SRobert Mustacchi         mm_atomic_dec(&pdev->params.update_comp_cnt);
3085*d14abf15SRobert Mustacchi         if (mm_atomic_dec(&pdev->params.update_suspend_cnt) == 0)
3086*d14abf15SRobert Mustacchi         {
3087*d14abf15SRobert Mustacchi             if (pdev->slowpath_info.set_rss_cookie != NULL)
3088*d14abf15SRobert Mustacchi             {
3089*d14abf15SRobert Mustacchi                 cookie = (void *)pdev->slowpath_info.set_rss_cookie;
3090*d14abf15SRobert Mustacchi                 pdev->slowpath_info.set_rss_cookie = NULL;
3091*d14abf15SRobert Mustacchi                 mm_set_done(pdev, cid, cookie);
3092*d14abf15SRobert Mustacchi             }
3093*d14abf15SRobert Mustacchi         }
3094*d14abf15SRobert Mustacchi     }
3095*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_ETH_RSS_UPDATE, ETH_CONNECTION_TYPE, cid);
3096*d14abf15SRobert Mustacchi }
3097*d14abf15SRobert Mustacchi 
3098*d14abf15SRobert Mustacchi /**lm_eq_handle_niv_function_update_eqe
3099*d14abf15SRobert Mustacchi  * handle a NIV function update completion.
3100*d14abf15SRobert Mustacchi  *
3101*d14abf15SRobert Mustacchi  * @param pdev the device
3102*d14abf15SRobert Mustacchi  * @param elem the CQE
3103*d14abf15SRobert Mustacchi  */
lm_eq_handle_function_update_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3104*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_function_update_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3105*d14abf15SRobert Mustacchi {
3106*d14abf15SRobert Mustacchi     DbgBreakIf((FUNC_UPDATE_RAMROD_SOURCE_NIV != elem->message.data.function_update_event.echo) &&
3107*d14abf15SRobert Mustacchi                (FUNC_UPDATE_RAMROD_SOURCE_L2MP != elem->message.data.function_update_event.echo) &&
3108*d14abf15SRobert Mustacchi                (FUNC_UPDATE_RAMROD_SOURCE_ENCAP != elem->message.data.function_update_event.echo) &&
3109*d14abf15SRobert Mustacchi                (FUNC_UPDATE_RAMROD_SOURCE_UFP != elem->message.data.function_update_event.echo));
3110*d14abf15SRobert Mustacchi 
3111*d14abf15SRobert Mustacchi     switch(elem->message.data.function_update_event.echo)
3112*d14abf15SRobert Mustacchi     {
3113*d14abf15SRobert Mustacchi     case FUNC_UPDATE_RAMROD_SOURCE_NIV:
3114*d14abf15SRobert Mustacchi         DbgBreakIf((pdev->slowpath_info.niv_ramrod_state == NIV_RAMROD_COMPLETED)||
3115*d14abf15SRobert Mustacchi                    (pdev->slowpath_info.niv_ramrod_state == NIV_RAMROD_NOT_POSTED));
3116*d14abf15SRobert Mustacchi 
3117*d14abf15SRobert Mustacchi         if ( NIV_RAMROD_SET_LOOPBACK_POSTED == pdev->slowpath_info.niv_ramrod_state )
3118*d14abf15SRobert Mustacchi         {
3119*d14abf15SRobert Mustacchi             MM_ACQUIRE_PHY_LOCK(pdev);
3120*d14abf15SRobert Mustacchi             pdev->vars.link_status = LM_STATUS_LINK_ACTIVE;
3121*d14abf15SRobert Mustacchi             mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium);
3122*d14abf15SRobert Mustacchi             MM_RELEASE_PHY_LOCK(pdev);
3123*d14abf15SRobert Mustacchi         }
3124*d14abf15SRobert Mustacchi         else if (NIV_RAMROD_CLEAR_LOOPBACK_POSTED == pdev->slowpath_info.niv_ramrod_state)
3125*d14abf15SRobert Mustacchi         {
3126*d14abf15SRobert Mustacchi             MM_ACQUIRE_PHY_LOCK(pdev);
3127*d14abf15SRobert Mustacchi             pdev->vars.link_status = LM_STATUS_LINK_DOWN;
3128*d14abf15SRobert Mustacchi             mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium);
3129*d14abf15SRobert Mustacchi             MM_RELEASE_PHY_LOCK(pdev);
3130*d14abf15SRobert Mustacchi         }
3131*d14abf15SRobert Mustacchi 
3132*d14abf15SRobert Mustacchi         pdev->slowpath_info.niv_ramrod_state = NIV_RAMROD_COMPLETED;
3133*d14abf15SRobert Mustacchi 
3134*d14abf15SRobert Mustacchi         break;
3135*d14abf15SRobert Mustacchi 
3136*d14abf15SRobert Mustacchi     case FUNC_UPDATE_RAMROD_SOURCE_L2MP:
3137*d14abf15SRobert Mustacchi         pdev->slowpath_info.l2mp_func_update_ramrod_state = L2MP_FUNC_UPDATE_RAMROD_COMPLETED;
3138*d14abf15SRobert Mustacchi 
3139*d14abf15SRobert Mustacchi         break;
3140*d14abf15SRobert Mustacchi 
3141*d14abf15SRobert Mustacchi     case FUNC_UPDATE_RAMROD_SOURCE_ENCAP:
3142*d14abf15SRobert Mustacchi         pdev->encap_info.current_encap_offload_state =
3143*d14abf15SRobert Mustacchi             pdev->encap_info.new_encap_offload_state;
3144*d14abf15SRobert Mustacchi         if (pdev->encap_info.update_cookie)
3145*d14abf15SRobert Mustacchi         {
3146*d14abf15SRobert Mustacchi             void* cookie = (void*)pdev->encap_info.update_cookie;
3147*d14abf15SRobert Mustacchi             pdev->encap_info.update_cookie = NULL;
3148*d14abf15SRobert Mustacchi             mm_set_done(pdev, LM_CLI_IDX_NDIS, cookie);
3149*d14abf15SRobert Mustacchi         }
3150*d14abf15SRobert Mustacchi 
3151*d14abf15SRobert Mustacchi         break;
3152*d14abf15SRobert Mustacchi     case FUNC_UPDATE_RAMROD_SOURCE_UFP:
3153*d14abf15SRobert Mustacchi         DbgBreakIf((pdev->slowpath_info.ufp_func_ramrod_state == UFP_RAMROD_COMPLETED)||
3154*d14abf15SRobert Mustacchi                    (pdev->slowpath_info.ufp_func_ramrod_state == UFP_RAMROD_NOT_POSTED));
3155*d14abf15SRobert Mustacchi 
3156*d14abf15SRobert Mustacchi         // In case of link update, indicate the link status to miniport, else it is just
3157*d14abf15SRobert Mustacchi         // svid update which doesnt need anymore processing.
3158*d14abf15SRobert Mustacchi         if ( UFP_RAMROD_PF_LINK_UPDATE_POSTED == pdev->slowpath_info.ufp_func_ramrod_state )
3159*d14abf15SRobert Mustacchi         {
3160*d14abf15SRobert Mustacchi             MM_ACQUIRE_PHY_LOCK(pdev);
3161*d14abf15SRobert Mustacchi             pdev->vars.link_status = LM_STATUS_LINK_ACTIVE;
3162*d14abf15SRobert Mustacchi             mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium);
3163*d14abf15SRobert Mustacchi             MM_RELEASE_PHY_LOCK(pdev);
3164*d14abf15SRobert Mustacchi         }
3165*d14abf15SRobert Mustacchi         else if (UFP_RAMROD_PF_UPDATE_POSTED != pdev->slowpath_info.ufp_func_ramrod_state)
3166*d14abf15SRobert Mustacchi         {
3167*d14abf15SRobert Mustacchi             DbgBreak();
3168*d14abf15SRobert Mustacchi         }
3169*d14abf15SRobert Mustacchi         pdev->slowpath_info.ufp_func_ramrod_state = UFP_RAMROD_COMPLETED;
3170*d14abf15SRobert Mustacchi         break;
3171*d14abf15SRobert Mustacchi     default:
3172*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_eq_handle_function_update_eqe unknown source");
3173*d14abf15SRobert Mustacchi         break;
3174*d14abf15SRobert Mustacchi     }
3175*d14abf15SRobert Mustacchi 
3176*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE,
3177*d14abf15SRobert Mustacchi                    NONE_CONNECTION_TYPE, 0);
3178*d14abf15SRobert Mustacchi }
3179*d14abf15SRobert Mustacchi 
3180*d14abf15SRobert Mustacchi /**lm_eq_handle_niv_function_update_eqe
3181*d14abf15SRobert Mustacchi  * handle a NIV lists update completion.
3182*d14abf15SRobert Mustacchi  *
3183*d14abf15SRobert Mustacchi  * @param pdev the device
3184*d14abf15SRobert Mustacchi  * @param elem the CQE
3185*d14abf15SRobert Mustacchi  */
lm_eq_handle_niv_vif_lists_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3186*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_niv_vif_lists_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3187*d14abf15SRobert Mustacchi {
3188*d14abf15SRobert Mustacchi     DbgBreakIf((pdev->slowpath_info.niv_ramrod_state != NIV_RAMROD_VIF_LISTS_POSTED) &&
3189*d14abf15SRobert Mustacchi                 (!lm_reset_is_inprogress(pdev)));
3190*d14abf15SRobert Mustacchi 
3191*d14abf15SRobert Mustacchi     DbgBreakIf((elem->message.data.vif_list_event.echo != VIF_LIST_RULE_CLEAR_ALL) &&
3192*d14abf15SRobert Mustacchi                (elem->message.data.vif_list_event.echo != VIF_LIST_RULE_CLEAR_FUNC) &&
3193*d14abf15SRobert Mustacchi                (elem->message.data.vif_list_event.echo != VIF_LIST_RULE_GET) &&
3194*d14abf15SRobert Mustacchi                (elem->message.data.vif_list_event.echo != VIF_LIST_RULE_SET));
3195*d14abf15SRobert Mustacchi 
3196*d14abf15SRobert Mustacchi     if (elem->message.data.vif_list_event.echo == VIF_LIST_RULE_GET)
3197*d14abf15SRobert Mustacchi     {
3198*d14abf15SRobert Mustacchi         pdev->slowpath_info.last_vif_list_bitmap = (u8_t)elem->message.data.vif_list_event.func_bit_map;
3199*d14abf15SRobert Mustacchi     }
3200*d14abf15SRobert Mustacchi 
3201*d14abf15SRobert Mustacchi     if(!lm_reset_is_inprogress(pdev))
3202*d14abf15SRobert Mustacchi     {
3203*d14abf15SRobert Mustacchi         pdev->slowpath_info.niv_ramrod_state = NIV_RAMROD_COMPLETED;
3204*d14abf15SRobert Mustacchi     }
3205*d14abf15SRobert Mustacchi 
3206*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, RAMROD_CMD_ID_COMMON_AFEX_VIF_LISTS,
3207*d14abf15SRobert Mustacchi                    NONE_CONNECTION_TYPE, 0);
3208*d14abf15SRobert Mustacchi }
3209*d14abf15SRobert Mustacchi 
3210*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
lm_eq_handle_vf_flr_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3211*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_vf_flr_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3212*d14abf15SRobert Mustacchi {
3213*d14abf15SRobert Mustacchi     lm_vf_info_t * vf_info = NULL;
3214*d14abf15SRobert Mustacchi     u8_t abs_vf_id;
3215*d14abf15SRobert Mustacchi 
3216*d14abf15SRobert Mustacchi     abs_vf_id = elem->message.data.vf_flr_event.vf_id;
3217*d14abf15SRobert Mustacchi 
3218*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARN, "lm_eq_handle_vf_flr_eqe(%d)\n",elem->message.data.vf_flr_event.vf_id);
3219*d14abf15SRobert Mustacchi     vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3220*d14abf15SRobert Mustacchi     if (!vf_info) {
3221*d14abf15SRobert Mustacchi         DbgBreakMsg("lm_eq_handle_vf_flr_eqe: vf_info is not found\n");
3222*d14abf15SRobert Mustacchi         return;
3223*d14abf15SRobert Mustacchi     }
3224*d14abf15SRobert Mustacchi     vf_info->was_flred = TRUE;
3225*d14abf15SRobert Mustacchi     MM_ACQUIRE_VFS_STATS_LOCK_DPC(pdev);
3226*d14abf15SRobert Mustacchi     if ((vf_info->vf_stats.vf_stats_state != VF_STATS_NONE) && (vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_IN_PROCESSING)) {
3227*d14abf15SRobert Mustacchi         vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
3228*d14abf15SRobert Mustacchi     }
3229*d14abf15SRobert Mustacchi     vf_info->vf_stats.stop_collect_stats = TRUE;
3230*d14abf15SRobert Mustacchi     vf_info->vf_stats.vf_stats_flag = 0;
3231*d14abf15SRobert Mustacchi     MM_RELEASE_VFS_STATS_LOCK_DPC(pdev);
3232*d14abf15SRobert Mustacchi }
3233*d14abf15SRobert Mustacchi 
lm_eq_handle_malicious_vf_eqe(struct _lm_device_t * pdev,union event_ring_elem * elem)3234*d14abf15SRobert Mustacchi static INLINE void lm_eq_handle_malicious_vf_eqe(struct _lm_device_t * pdev, union event_ring_elem * elem)
3235*d14abf15SRobert Mustacchi {
3236*d14abf15SRobert Mustacchi     lm_vf_info_t * vf_info = NULL;
3237*d14abf15SRobert Mustacchi     u8_t abs_vf_id;
3238*d14abf15SRobert Mustacchi 
3239*d14abf15SRobert Mustacchi     abs_vf_id = elem->message.data.malicious_vf_event.vf_id;
3240*d14abf15SRobert Mustacchi     vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3241*d14abf15SRobert Mustacchi     if (vf_info) {
3242*d14abf15SRobert Mustacchi         vf_info->was_malicious = TRUE;
3243*d14abf15SRobert Mustacchi         mm_report_malicious_vf(pdev, vf_info);
3244*d14abf15SRobert Mustacchi     }
3245*d14abf15SRobert Mustacchi     DbgMessage(pdev, FATAL, "lm_eq_handle_malicious_vf_eqe(%d)\n",abs_vf_id);
3246*d14abf15SRobert Mustacchi }
3247*d14abf15SRobert Mustacchi 
3248*d14abf15SRobert Mustacchi #endif
lm_service_eq_elem(struct _lm_device_t * pdev,union event_ring_elem * elem)3249*d14abf15SRobert Mustacchi static INLINE lm_status_t lm_service_eq_elem(struct _lm_device_t * pdev, union event_ring_elem * elem)
3250*d14abf15SRobert Mustacchi {
3251*d14abf15SRobert Mustacchi     /* handle eq element */
3252*d14abf15SRobert Mustacchi     switch(elem->message.opcode)
3253*d14abf15SRobert Mustacchi     {
3254*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_FUNCTION_START:
3255*d14abf15SRobert Mustacchi             lm_eq_handle_function_start_eqe(pdev, elem);
3256*d14abf15SRobert Mustacchi             break;
3257*d14abf15SRobert Mustacchi 
3258*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_FUNCTION_STOP:
3259*d14abf15SRobert Mustacchi             lm_eq_handle_function_stop_eqe(pdev, elem);
3260*d14abf15SRobert Mustacchi             break;
3261*d14abf15SRobert Mustacchi 
3262*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_CFC_DEL:
3263*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_CFC_DEL_WB:
3264*d14abf15SRobert Mustacchi             lm_eq_handle_cfc_del_eqe(pdev, elem);
3265*d14abf15SRobert Mustacchi             break;
3266*d14abf15SRobert Mustacchi 
3267*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_SET_MAC:
3268*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_CLASSIFICATION_RULES:
3269*d14abf15SRobert Mustacchi             lm_eq_handle_classification_eqe(pdev, elem);
3270*d14abf15SRobert Mustacchi             break;
3271*d14abf15SRobert Mustacchi 
3272*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_STAT_QUERY:
3273*d14abf15SRobert Mustacchi             lm_eq_handle_stats_eqe(pdev, elem);
3274*d14abf15SRobert Mustacchi             break;
3275*d14abf15SRobert Mustacchi 
3276*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_STOP_TRAFFIC:
3277*d14abf15SRobert Mustacchi             pdev->dcbx_info.dcbx_ramrod_state = FUNCTION_DCBX_STOP_COMPLETED;
3278*d14abf15SRobert Mustacchi             lm_sq_complete(pdev, CMD_PRIORITY_MEDIUM,
3279*d14abf15SRobert Mustacchi                        RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, NONE_CONNECTION_TYPE, 0);
3280*d14abf15SRobert Mustacchi             break;
3281*d14abf15SRobert Mustacchi 
3282*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_START_TRAFFIC:
3283*d14abf15SRobert Mustacchi             pdev->dcbx_info.dcbx_ramrod_state = FUNCTION_DCBX_START_COMPLETED;
3284*d14abf15SRobert Mustacchi             lm_sq_complete(pdev, CMD_PRIORITY_HIGH,
3285*d14abf15SRobert Mustacchi                        RAMROD_CMD_ID_COMMON_START_TRAFFIC, NONE_CONNECTION_TYPE, 0);
3286*d14abf15SRobert Mustacchi             break;
3287*d14abf15SRobert Mustacchi 
3288*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_FORWARD_SETUP:
3289*d14abf15SRobert Mustacchi             lm_eq_handle_fwd_setup_eqe(pdev, elem);
3290*d14abf15SRobert Mustacchi             break;
3291*d14abf15SRobert Mustacchi 
3292*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_MULTICAST_RULES:
3293*d14abf15SRobert Mustacchi             lm_eq_handle_mcast_eqe(pdev, elem);
3294*d14abf15SRobert Mustacchi             break;
3295*d14abf15SRobert Mustacchi 
3296*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_FILTERS_RULES:
3297*d14abf15SRobert Mustacchi             lm_eq_handle_filter_rules_eqe(pdev, elem);
3298*d14abf15SRobert Mustacchi             break;
3299*d14abf15SRobert Mustacchi 
3300*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_RSS_UPDATE_RULES:
3301*d14abf15SRobert Mustacchi             lm_eq_handle_rss_update_eqe(pdev, elem);
3302*d14abf15SRobert Mustacchi             break;
3303*d14abf15SRobert Mustacchi 
3304*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_FUNCTION_UPDATE:
3305*d14abf15SRobert Mustacchi             lm_eq_handle_function_update_eqe(pdev, elem);
3306*d14abf15SRobert Mustacchi             break;
3307*d14abf15SRobert Mustacchi 
3308*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_AFEX_VIF_LISTS:
3309*d14abf15SRobert Mustacchi             lm_eq_handle_niv_vif_lists_eqe(pdev, elem);
3310*d14abf15SRobert Mustacchi             break;
3311*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
3312*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_VF_FLR:
3313*d14abf15SRobert Mustacchi             lm_eq_handle_vf_flr_eqe(pdev, elem);
3314*d14abf15SRobert Mustacchi             break;
3315*d14abf15SRobert Mustacchi         case EVENT_RING_OPCODE_MALICIOUS_VF:
3316*d14abf15SRobert Mustacchi             lm_eq_handle_malicious_vf_eqe(pdev, elem);
3317*d14abf15SRobert Mustacchi             break;
3318*d14abf15SRobert Mustacchi #endif
3319*d14abf15SRobert Mustacchi         default:
3320*d14abf15SRobert Mustacchi             DbgBreakMsg("Unknown elem type received on eq\n");
3321*d14abf15SRobert Mustacchi             return LM_STATUS_FAILURE;
3322*d14abf15SRobert Mustacchi         }
3323*d14abf15SRobert Mustacchi 
3324*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
3325*d14abf15SRobert Mustacchi }
3326*d14abf15SRobert Mustacchi 
3327*d14abf15SRobert Mustacchi /**
3328*d14abf15SRobert Mustacchi  * @Description
3329*d14abf15SRobert Mustacchi  *      handle cqes of the event-ring, should be called from dpc if index in status block was changed
3330*d14abf15SRobert Mustacchi  * @param pdev
3331*d14abf15SRobert Mustacchi  *
3332*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS or FAILURE (if unknown completion)
3333*d14abf15SRobert Mustacchi  */
lm_service_eq_intr(struct _lm_device_t * pdev)3334*d14abf15SRobert Mustacchi lm_status_t lm_service_eq_intr(struct _lm_device_t * pdev)
3335*d14abf15SRobert Mustacchi {
3336*d14abf15SRobert Mustacchi     union event_ring_elem * elem       = NULL;
3337*d14abf15SRobert Mustacchi     lm_eq_chain_t         * eq_chain   = &pdev->eq_info.eq_chain;
3338*d14abf15SRobert Mustacchi     lm_status_t             lm_status  = LM_STATUS_SUCCESS;
3339*d14abf15SRobert Mustacchi     u16_t                   cq_new_idx = 0;
3340*d14abf15SRobert Mustacchi     u16_t                   cq_old_idx = 0;
3341*d14abf15SRobert Mustacchi 
3342*d14abf15SRobert Mustacchi     cq_new_idx = mm_le16_to_cpu(*(eq_chain->hw_con_idx_ptr));
3343*d14abf15SRobert Mustacchi     if((cq_new_idx & lm_bd_chain_usable_bds_per_page(&eq_chain->bd_chain))
3344*d14abf15SRobert Mustacchi        == lm_bd_chain_usable_bds_per_page(&eq_chain->bd_chain))
3345*d14abf15SRobert Mustacchi     {
3346*d14abf15SRobert Mustacchi         cq_new_idx+=lm_bd_chain_bds_skip_eop(&eq_chain->bd_chain);
3347*d14abf15SRobert Mustacchi     }
3348*d14abf15SRobert Mustacchi     cq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain);
3349*d14abf15SRobert Mustacchi 
3350*d14abf15SRobert Mustacchi     /* there is no change in the EQ consumer index so exit! */
3351*d14abf15SRobert Mustacchi     if (cq_old_idx == cq_new_idx)
3352*d14abf15SRobert Mustacchi     {
3353*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORMeq , "there is no change in the EQ consumer index so exit!\n");
3354*d14abf15SRobert Mustacchi         return LM_STATUS_SUCCESS;
3355*d14abf15SRobert Mustacchi     } else {
3356*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORMeq , "EQ consumer index: cq_old_idx=0x%x, cq_new_idx=0x%x!\n",cq_old_idx,cq_new_idx);
3357*d14abf15SRobert Mustacchi     }
3358*d14abf15SRobert Mustacchi 
3359*d14abf15SRobert Mustacchi     while(cq_old_idx != cq_new_idx)
3360*d14abf15SRobert Mustacchi     {
3361*d14abf15SRobert Mustacchi         DbgBreakIfFastPath(S16_SUB(cq_new_idx, cq_old_idx) <= 0);
3362*d14abf15SRobert Mustacchi         /* get hold of the cqe, and find out what it's type corresponds to */
3363*d14abf15SRobert Mustacchi         elem = (union event_ring_elem *)lm_bd_chain_consume_bd(&eq_chain->bd_chain);
3364*d14abf15SRobert Mustacchi 
3365*d14abf15SRobert Mustacchi         if (elem == NULL)
3366*d14abf15SRobert Mustacchi         {
3367*d14abf15SRobert Mustacchi             DbgBreakIfFastPath(elem == NULL);
3368*d14abf15SRobert Mustacchi             return LM_STATUS_FAILURE;
3369*d14abf15SRobert Mustacchi         }
3370*d14abf15SRobert Mustacchi 
3371*d14abf15SRobert Mustacchi         cq_old_idx = lm_bd_chain_cons_idx(&eq_chain->bd_chain);
3372*d14abf15SRobert Mustacchi 
3373*d14abf15SRobert Mustacchi         lm_status = lm_service_eq_elem(pdev, elem);
3374*d14abf15SRobert Mustacchi         if (lm_status != LM_STATUS_SUCCESS)
3375*d14abf15SRobert Mustacchi         {
3376*d14abf15SRobert Mustacchi             return lm_status;
3377*d14abf15SRobert Mustacchi         }
3378*d14abf15SRobert Mustacchi 
3379*d14abf15SRobert Mustacchi #ifdef __LINUX
3380*d14abf15SRobert Mustacchi         mm_common_ramrod_comp_cb(pdev, &elem->message);
3381*d14abf15SRobert Mustacchi #endif //__LINUX
3382*d14abf15SRobert Mustacchi         /* Recycle the cqe */
3383*d14abf15SRobert Mustacchi         lm_bd_chain_bd_produced(&eq_chain->bd_chain);
3384*d14abf15SRobert Mustacchi     } /* while */
3385*d14abf15SRobert Mustacchi 
3386*d14abf15SRobert Mustacchi     /* update producer */
3387*d14abf15SRobert Mustacchi     LM_INTMEM_WRITE16(pdev,
3388*d14abf15SRobert Mustacchi                       eq_chain->iro_prod_offset,
3389*d14abf15SRobert Mustacchi                       lm_bd_chain_prod_idx(&eq_chain->bd_chain),
3390*d14abf15SRobert Mustacchi                       BAR_CSTRORM_INTMEM);
3391*d14abf15SRobert Mustacchi 
3392*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
3393*d14abf15SRobert Mustacchi } /* lm_service_eq_intr */
3394*d14abf15SRobert Mustacchi 
3395*d14abf15SRobert Mustacchi /**
3396*d14abf15SRobert Mustacchi  * @Description
3397*d14abf15SRobert Mustacchi  *     This function completes eq completions immediately
3398*d14abf15SRobert Mustacchi  *     (without fw completion).
3399*d14abf15SRobert Mustacchi  *
3400*d14abf15SRobert Mustacchi  * @param pdev
3401*d14abf15SRobert Mustacchi  * @param spe
3402*d14abf15SRobert Mustacchi  */
lm_eq_comp_cb(struct _lm_device_t * pdev,struct sq_pending_command * pending)3403*d14abf15SRobert Mustacchi void lm_eq_comp_cb(struct _lm_device_t *pdev, struct sq_pending_command * pending)
3404*d14abf15SRobert Mustacchi {
3405*d14abf15SRobert Mustacchi     union event_ring_elem elem = {{0}};
3406*d14abf15SRobert Mustacchi     u32_t                 cid  = pending->cid;
3407*d14abf15SRobert Mustacchi     u8_t                  cmd  = pending->cmd;
3408*d14abf15SRobert Mustacchi 
3409*d14abf15SRobert Mustacchi 
3410*d14abf15SRobert Mustacchi     /* We need to build the "elem" based on the spe */
3411*d14abf15SRobert Mustacchi     if ((pending->type & SPE_HDR_T_CONN_TYPE) == ETH_CONNECTION_TYPE) /* Some Ethernets complete on Eq. */
3412*d14abf15SRobert Mustacchi     {
3413*d14abf15SRobert Mustacchi         switch (cmd)
3414*d14abf15SRobert Mustacchi         {
3415*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_SET_MAC:
3416*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_SET_MAC;
3417*d14abf15SRobert Mustacchi             elem.message.data.eth_event.echo = (0xff << ECORE_SWCID_SHIFT | cid); /*unknown type*/
3418*d14abf15SRobert Mustacchi 
3419*d14abf15SRobert Mustacchi             break;
3420*d14abf15SRobert Mustacchi 
3421*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES:
3422*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_CLASSIFICATION_RULES;
3423*d14abf15SRobert Mustacchi             elem.message.data.eth_event.echo = (0xff << ECORE_SWCID_SHIFT | cid); /*unknown type*/
3424*d14abf15SRobert Mustacchi             break;
3425*d14abf15SRobert Mustacchi 
3426*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_FORWARD_SETUP:
3427*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_FORWARD_SETUP;
3428*d14abf15SRobert Mustacchi             break;
3429*d14abf15SRobert Mustacchi 
3430*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_MULTICAST_RULES:
3431*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_MULTICAST_RULES;
3432*d14abf15SRobert Mustacchi             elem.message.data.eth_event.echo = cid;
3433*d14abf15SRobert Mustacchi             break;
3434*d14abf15SRobert Mustacchi 
3435*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_FILTER_RULES:
3436*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_FILTERS_RULES;
3437*d14abf15SRobert Mustacchi             elem.message.data.eth_event.echo = cid;
3438*d14abf15SRobert Mustacchi             break;
3439*d14abf15SRobert Mustacchi 
3440*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_RSS_UPDATE:
3441*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_RSS_UPDATE_RULES;
3442*d14abf15SRobert Mustacchi             break;
3443*d14abf15SRobert Mustacchi 
3444*d14abf15SRobert Mustacchi         default:
3445*d14abf15SRobert Mustacchi             DbgBreakMsg("Unknown elem type received on eq\n");
3446*d14abf15SRobert Mustacchi         }
3447*d14abf15SRobert Mustacchi     }
3448*d14abf15SRobert Mustacchi     else if ((pending->type & SPE_HDR_T_CONN_TYPE)== NONE_CONNECTION_TYPE)
3449*d14abf15SRobert Mustacchi     {
3450*d14abf15SRobert Mustacchi         switch (cmd)
3451*d14abf15SRobert Mustacchi         {
3452*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_FUNCTION_START:
3453*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_FUNCTION_START;
3454*d14abf15SRobert Mustacchi             break;
3455*d14abf15SRobert Mustacchi 
3456*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_FUNCTION_STOP:
3457*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_FUNCTION_STOP;
3458*d14abf15SRobert Mustacchi             break;
3459*d14abf15SRobert Mustacchi 
3460*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_CFC_DEL:
3461*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_CFC_DEL;
3462*d14abf15SRobert Mustacchi             elem.message.data.cfc_del_event.cid = cid;
3463*d14abf15SRobert Mustacchi             break;
3464*d14abf15SRobert Mustacchi 
3465*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_CFC_DEL_WB:
3466*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_CFC_DEL_WB;
3467*d14abf15SRobert Mustacchi             elem.message.data.cfc_del_event.cid = cid;
3468*d14abf15SRobert Mustacchi             break;
3469*d14abf15SRobert Mustacchi 
3470*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_STAT_QUERY:
3471*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_STAT_QUERY;
3472*d14abf15SRobert Mustacchi             break;
3473*d14abf15SRobert Mustacchi 
3474*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_STOP_TRAFFIC:
3475*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_STOP_TRAFFIC;
3476*d14abf15SRobert Mustacchi             break;
3477*d14abf15SRobert Mustacchi 
3478*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_START_TRAFFIC:
3479*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_START_TRAFFIC;
3480*d14abf15SRobert Mustacchi             break;
3481*d14abf15SRobert Mustacchi 
3482*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE:
3483*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_FUNCTION_UPDATE;
3484*d14abf15SRobert Mustacchi             break;
3485*d14abf15SRobert Mustacchi 
3486*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_COMMON_AFEX_VIF_LISTS:
3487*d14abf15SRobert Mustacchi             elem.message.opcode = EVENT_RING_OPCODE_AFEX_VIF_LISTS;
3488*d14abf15SRobert Mustacchi             break;
3489*d14abf15SRobert Mustacchi 
3490*d14abf15SRobert Mustacchi         default:
3491*d14abf15SRobert Mustacchi             DbgBreakMsg("Unknown elem type received on eq\n");
3492*d14abf15SRobert Mustacchi         }
3493*d14abf15SRobert Mustacchi     }
3494*d14abf15SRobert Mustacchi 
3495*d14abf15SRobert Mustacchi     lm_service_eq_elem(pdev, &elem);
3496*d14abf15SRobert Mustacchi }
3497*d14abf15SRobert Mustacchi 
3498*d14abf15SRobert Mustacchi /*********************** SQ RELATED FUNCTIONS ***************************/
3499*d14abf15SRobert Mustacchi /* TODO: move more functions from command.h to here.                    */
lm_cid_recycled_cb_register(struct _lm_device_t * pdev,u8_t type,lm_cid_recycled_cb_t cb)3500*d14abf15SRobert Mustacchi void lm_cid_recycled_cb_register(struct _lm_device_t *pdev, u8_t type, lm_cid_recycled_cb_t cb)
3501*d14abf15SRobert Mustacchi {
3502*d14abf15SRobert Mustacchi 
3503*d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
3504*d14abf15SRobert Mustacchi          CHK_NULL(cb) ||
3505*d14abf15SRobert Mustacchi          ERR_IF( type >= ARRSIZE( pdev->cid_recycled_callbacks ) ) ||
3506*d14abf15SRobert Mustacchi          ERR_IF( NULL != pdev->cid_recycled_callbacks[type] ) )
3507*d14abf15SRobert Mustacchi     {
3508*d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
3509*d14abf15SRobert Mustacchi         DbgBreakIf(!cb) ;
3510*d14abf15SRobert Mustacchi         DbgBreakIf( type >= ARRSIZE( pdev->cid_recycled_callbacks ) );
3511*d14abf15SRobert Mustacchi         DbgBreakIf( NULL != pdev->cid_recycled_callbacks[type] ) ;
3512*d14abf15SRobert Mustacchi         return;
3513*d14abf15SRobert Mustacchi     }
3514*d14abf15SRobert Mustacchi     pdev->cid_recycled_callbacks[type]= cb;
3515*d14abf15SRobert Mustacchi }
3516*d14abf15SRobert Mustacchi 
lm_cid_recycled_cb_deregister(struct _lm_device_t * pdev,u8_t type)3517*d14abf15SRobert Mustacchi void lm_cid_recycled_cb_deregister(struct _lm_device_t *pdev, u8_t type)
3518*d14abf15SRobert Mustacchi {
3519*d14abf15SRobert Mustacchi 
3520*d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
3521*d14abf15SRobert Mustacchi          ERR_IF( type >= ARRSIZE( pdev->cid_recycled_callbacks ) ) ||
3522*d14abf15SRobert Mustacchi          CHK_NULL(pdev->cid_recycled_callbacks[type]) )
3523*d14abf15SRobert Mustacchi 
3524*d14abf15SRobert Mustacchi     {
3525*d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
3526*d14abf15SRobert Mustacchi         DbgBreakIf( type >= ARRSIZE( pdev->cid_recycled_callbacks ) );
3527*d14abf15SRobert Mustacchi         return;
3528*d14abf15SRobert Mustacchi     }
3529*d14abf15SRobert Mustacchi     pdev->cid_recycled_callbacks[type] = (lm_cid_recycled_cb_t)NULL;
3530*d14abf15SRobert Mustacchi }
3531*d14abf15SRobert Mustacchi 
lm_sq_change_state(struct _lm_device_t * pdev,lm_sq_state_t state)3532*d14abf15SRobert Mustacchi void lm_sq_change_state(struct _lm_device_t *pdev, lm_sq_state_t state)
3533*d14abf15SRobert Mustacchi {
3534*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORM, "Changing sq state from %d to %d\n", pdev->sq_info.sq_state, state);
3535*d14abf15SRobert Mustacchi 
3536*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3537*d14abf15SRobert Mustacchi 
3538*d14abf15SRobert Mustacchi     pdev->sq_info.sq_state = state;
3539*d14abf15SRobert Mustacchi 
3540*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
3541*d14abf15SRobert Mustacchi }
3542*d14abf15SRobert Mustacchi 
3543*d14abf15SRobert Mustacchi /**
3544*d14abf15SRobert Mustacchi  * @Description
3545*d14abf15SRobert Mustacchi  *     function completes pending slow path requests instead of
3546*d14abf15SRobert Mustacchi  *     FW. Used in error recovery flow.
3547*d14abf15SRobert Mustacchi  *
3548*d14abf15SRobert Mustacchi  * @Assumptions:
3549*d14abf15SRobert Mustacchi  *      interrupts at this point are disabled and dpcs are
3550*d14abf15SRobert Mustacchi  *      flushed, thus no one else can complete these...
3551*d14abf15SRobert Mustacchi  *
3552*d14abf15SRobert Mustacchi  * @param pdev
3553*d14abf15SRobert Mustacchi  */
lm_sq_complete_pending_requests(struct _lm_device_t * pdev)3554*d14abf15SRobert Mustacchi void lm_sq_complete_pending_requests(struct _lm_device_t *pdev)
3555*d14abf15SRobert Mustacchi {
3556*d14abf15SRobert Mustacchi     enum connection_type        type      = 0;
3557*d14abf15SRobert Mustacchi     struct sq_pending_command * pending   = NULL;
3558*d14abf15SRobert Mustacchi 
3559*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARN, "lm_sq_complete_pending_requests\n");
3560*d14abf15SRobert Mustacchi 
3561*d14abf15SRobert Mustacchi     /* unexpected if not under error recovery */
3562*d14abf15SRobert Mustacchi     DbgBreakIf(!pdev->params.enable_error_recovery);
3563*d14abf15SRobert Mustacchi 
3564*d14abf15SRobert Mustacchi     do
3565*d14abf15SRobert Mustacchi     {
3566*d14abf15SRobert Mustacchi         MM_ACQUIRE_SPQ_LOCK(pdev);
3567*d14abf15SRobert Mustacchi 
3568*d14abf15SRobert Mustacchi         /* Find the first entry that hasn't been handled yet. */
3569*d14abf15SRobert Mustacchi         /* We just peek and don't pop since completion of this pending request should contain removing
3570*d14abf15SRobert Mustacchi          * it from the completion list. However, it may not happen immediately */
3571*d14abf15SRobert Mustacchi         pending = (struct sq_pending_command *)d_list_peek_head(&pdev->sq_info.pending_complete);
3572*d14abf15SRobert Mustacchi 
3573*d14abf15SRobert Mustacchi         /* Look for the first entry that is "pending" but not completion_called yet. */
3574*d14abf15SRobert Mustacchi         while (pending && GET_FLAGS(pending->flags, SQ_PEND_COMP_CALLED))
3575*d14abf15SRobert Mustacchi         {
3576*d14abf15SRobert Mustacchi             pending = (struct sq_pending_command *)d_list_next_entry(&pending->list);
3577*d14abf15SRobert Mustacchi         }
3578*d14abf15SRobert Mustacchi 
3579*d14abf15SRobert Mustacchi         /* Mark pending completion as "handled" so that we don't handle it again...  */
3580*d14abf15SRobert Mustacchi         if (pending)
3581*d14abf15SRobert Mustacchi         {
3582*d14abf15SRobert Mustacchi             SET_FLAGS(pending->flags, SQ_PEND_COMP_CALLED);
3583*d14abf15SRobert Mustacchi         }
3584*d14abf15SRobert Mustacchi 
3585*d14abf15SRobert Mustacchi         MM_RELEASE_SPQ_LOCK(pdev);
3586*d14abf15SRobert Mustacchi 
3587*d14abf15SRobert Mustacchi         if (pending)
3588*d14abf15SRobert Mustacchi         {
3589*d14abf15SRobert Mustacchi             type = pending->type & SPE_HDR_T_CONN_TYPE;
3590*d14abf15SRobert Mustacchi 
3591*d14abf15SRobert Mustacchi             if (pdev->sq_info.sq_comp_cb[type])
3592*d14abf15SRobert Mustacchi             {
3593*d14abf15SRobert Mustacchi                 pdev->sq_info.sq_comp_cb[type](pdev, pending);
3594*d14abf15SRobert Mustacchi             }
3595*d14abf15SRobert Mustacchi             else
3596*d14abf15SRobert Mustacchi             {
3597*d14abf15SRobert Mustacchi                 DbgBreakMsg("unsupported pending sq: Not implemented yet\n");
3598*d14abf15SRobert Mustacchi             }
3599*d14abf15SRobert Mustacchi         }
3600*d14abf15SRobert Mustacchi 
3601*d14abf15SRobert Mustacchi         /*
3602*d14abf15SRobert Mustacchi          * lm_sq_post_pending can only cause (via lm_sq_flush)
3603*d14abf15SRobert Mustacchi          * lm_sq_complete_pending_requests DPC to be scheduled if
3604*d14abf15SRobert Mustacchi          * pdev->sq_info.sq_comp_scheduled==FALSE. Such scheduling
3605*d14abf15SRobert Mustacchi          * is acompnied by sq_comp_scheduled being set to TRUE.
3606*d14abf15SRobert Mustacchi          *
3607*d14abf15SRobert Mustacchi          * If we avoid setting pdev->sq_info.sq_comp_scheduled to FALSE,
3608*d14abf15SRobert Mustacchi          * we are gurenteed lm_sq_complete_pending_requests will not be
3609*d14abf15SRobert Mustacchi          * re-scheduled here.
3610*d14abf15SRobert Mustacchi          */
3611*d14abf15SRobert Mustacchi 
3612*d14abf15SRobert Mustacchi         lm_sq_post_pending(pdev);
3613*d14abf15SRobert Mustacchi 
3614*d14abf15SRobert Mustacchi     } while (!d_list_is_empty(&pdev->sq_info.pending_complete));
3615*d14abf15SRobert Mustacchi 
3616*d14abf15SRobert Mustacchi     /*
3617*d14abf15SRobert Mustacchi      * We are done completing pending requests in pending_list. However, any
3618*d14abf15SRobert Mustacchi      * new sp requests created by callbacks, need service.
3619*d14abf15SRobert Mustacchi      *
3620*d14abf15SRobert Mustacchi      * As we are outside the SPQ lock, this DPC may be preempted,
3621*d14abf15SRobert Mustacchi      * lm_sq_flush may have been called somewhere before this point.
3622*d14abf15SRobert Mustacchi      */
3623*d14abf15SRobert Mustacchi 
3624*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3625*d14abf15SRobert Mustacchi 
3626*d14abf15SRobert Mustacchi     pdev->sq_info.sq_comp_scheduled = FALSE;
3627*d14abf15SRobert Mustacchi 
3628*d14abf15SRobert Mustacchi     /*
3629*d14abf15SRobert Mustacchi      * check if there is more to be flushed (new SPQ that entered after
3630*d14abf15SRobert Mustacchi      * the "while".)
3631*d14abf15SRobert Mustacchi      */
3632*d14abf15SRobert Mustacchi 
3633*d14abf15SRobert Mustacchi     if ((pdev->sq_info.sq_state == SQ_STATE_PENDING) && !d_list_is_empty(&pdev->sq_info.pending_complete))
3634*d14abf15SRobert Mustacchi     {
3635*d14abf15SRobert Mustacchi         MM_RELEASE_SPQ_LOCK(pdev);
3636*d14abf15SRobert Mustacchi         lm_sq_flush(pdev);
3637*d14abf15SRobert Mustacchi     }
3638*d14abf15SRobert Mustacchi     else
3639*d14abf15SRobert Mustacchi     {
3640*d14abf15SRobert Mustacchi         MM_RELEASE_SPQ_LOCK(pdev);
3641*d14abf15SRobert Mustacchi     }
3642*d14abf15SRobert Mustacchi }
3643*d14abf15SRobert Mustacchi 
3644*d14abf15SRobert Mustacchi 
lm_sq_flush(struct _lm_device_t * pdev)3645*d14abf15SRobert Mustacchi lm_status_t lm_sq_flush(struct _lm_device_t *pdev)
3646*d14abf15SRobert Mustacchi {
3647*d14abf15SRobert Mustacchi     lm_status_t lm_status   = LM_STATUS_SUCCESS;
3648*d14abf15SRobert Mustacchi     u8_t        schedule_wi = FALSE;
3649*d14abf15SRobert Mustacchi 
3650*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3651*d14abf15SRobert Mustacchi 
3652*d14abf15SRobert Mustacchi     if ((pdev->sq_info.sq_comp_scheduled == FALSE) &&
3653*d14abf15SRobert Mustacchi         ((pdev->sq_info.num_pending_high != MAX_HIGH_PRIORITY_SPE) ||
3654*d14abf15SRobert Mustacchi         (pdev->sq_info.num_pending_normal != MAX_NORMAL_PRIORITY_SPE)))
3655*d14abf15SRobert Mustacchi     {
3656*d14abf15SRobert Mustacchi         schedule_wi = TRUE;
3657*d14abf15SRobert Mustacchi         pdev->sq_info.sq_comp_scheduled = TRUE;
3658*d14abf15SRobert Mustacchi     }
3659*d14abf15SRobert Mustacchi 
3660*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
3661*d14abf15SRobert Mustacchi 
3662*d14abf15SRobert Mustacchi     if (schedule_wi)
3663*d14abf15SRobert Mustacchi     {
3664*d14abf15SRobert Mustacchi         lm_status = MM_REGISTER_DPC(pdev, lm_sq_complete_pending_requests);
3665*d14abf15SRobert Mustacchi         /* Alternative: WorkItem...
3666*d14abf15SRobert Mustacchi         lm_status = MM_REGISTER_LPME(pdev, lm_sq_complete_pending_requests, FALSE, FALSE);
3667*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_SUCCESS)
3668*d14abf15SRobert Mustacchi         {
3669*d14abf15SRobert Mustacchi             return LM_STATUS_PENDING;
3670*d14abf15SRobert Mustacchi         }
3671*d14abf15SRobert Mustacchi         */
3672*d14abf15SRobert Mustacchi         if (lm_status == LM_STATUS_SUCCESS)
3673*d14abf15SRobert Mustacchi         {
3674*d14abf15SRobert Mustacchi             lm_status = LM_STATUS_PENDING;
3675*d14abf15SRobert Mustacchi         }
3676*d14abf15SRobert Mustacchi     }
3677*d14abf15SRobert Mustacchi 
3678*d14abf15SRobert Mustacchi     return lm_status;
3679*d14abf15SRobert Mustacchi }
3680*d14abf15SRobert Mustacchi 
lm_sq_comp_cb_register(struct _lm_device_t * pdev,u8_t type,lm_sq_comp_cb_t cb)3681*d14abf15SRobert Mustacchi lm_status_t lm_sq_comp_cb_register(struct _lm_device_t *pdev, u8_t type, lm_sq_comp_cb_t cb)
3682*d14abf15SRobert Mustacchi {
3683*d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
3684*d14abf15SRobert Mustacchi          CHK_NULL(cb) ||
3685*d14abf15SRobert Mustacchi          ERR_IF( type >= ARRSIZE( pdev->sq_info.sq_comp_cb ) ) ||
3686*d14abf15SRobert Mustacchi          ERR_IF( NULL != pdev->sq_info.sq_comp_cb[type] ) )
3687*d14abf15SRobert Mustacchi     {
3688*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
3689*d14abf15SRobert Mustacchi     }
3690*d14abf15SRobert Mustacchi     pdev->sq_info.sq_comp_cb[type]= cb;
3691*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
3692*d14abf15SRobert Mustacchi }
3693*d14abf15SRobert Mustacchi 
lm_sq_comp_cb_deregister(struct _lm_device_t * pdev,u8_t type)3694*d14abf15SRobert Mustacchi lm_status_t lm_sq_comp_cb_deregister(struct _lm_device_t *pdev, u8_t type)
3695*d14abf15SRobert Mustacchi {
3696*d14abf15SRobert Mustacchi 
3697*d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) ||
3698*d14abf15SRobert Mustacchi          ERR_IF( type >= ARRSIZE( pdev->sq_info.sq_comp_cb ) ) ||
3699*d14abf15SRobert Mustacchi          CHK_NULL(pdev->sq_info.sq_comp_cb[type]) )
3700*d14abf15SRobert Mustacchi 
3701*d14abf15SRobert Mustacchi     {
3702*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
3703*d14abf15SRobert Mustacchi     }
3704*d14abf15SRobert Mustacchi     pdev->sq_info.sq_comp_cb[type] = (lm_sq_comp_cb_t)NULL;
3705*d14abf15SRobert Mustacchi 
3706*d14abf15SRobert Mustacchi     return LM_STATUS_SUCCESS;
3707*d14abf15SRobert Mustacchi }
3708*d14abf15SRobert Mustacchi 
lm_sq_is_empty(struct _lm_device_t * pdev)3709*d14abf15SRobert Mustacchi u8_t lm_sq_is_empty(struct _lm_device_t *pdev)
3710*d14abf15SRobert Mustacchi {
3711*d14abf15SRobert Mustacchi     u8_t empty = TRUE;
3712*d14abf15SRobert Mustacchi 
3713*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3714*d14abf15SRobert Mustacchi 
3715*d14abf15SRobert Mustacchi     if ((pdev->sq_info.num_pending_high != MAX_HIGH_PRIORITY_SPE) ||
3716*d14abf15SRobert Mustacchi         (pdev->sq_info.num_pending_normal != MAX_NORMAL_PRIORITY_SPE))
3717*d14abf15SRobert Mustacchi     {
3718*d14abf15SRobert Mustacchi         empty = FALSE;
3719*d14abf15SRobert Mustacchi     }
3720*d14abf15SRobert Mustacchi 
3721*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
3722*d14abf15SRobert Mustacchi 
3723*d14abf15SRobert Mustacchi     return empty;
3724*d14abf15SRobert Mustacchi }
3725*d14abf15SRobert Mustacchi 
3726*d14abf15SRobert Mustacchi 
3727*d14abf15SRobert Mustacchi /**
3728*d14abf15SRobert Mustacchi  * @Description
3729*d14abf15SRobert Mustacchi  *     Posts from the normal + high priority lists as much as it
3730*d14abf15SRobert Mustacchi  *     can towards the FW.
3731*d14abf15SRobert Mustacchi  *
3732*d14abf15SRobert Mustacchi  * @Assumptions
3733*d14abf15SRobert Mustacchi  *     called under SQ_LOCK!!!
3734*d14abf15SRobert Mustacchi  *
3735*d14abf15SRobert Mustacchi  * @param pdev
3736*d14abf15SRobert Mustacchi  *
3737*d14abf15SRobert Mustacchi  * @return lm_status_t PENDING: if indeed requests were posted,
3738*d14abf15SRobert Mustacchi  *         SUCCESS o/w
3739*d14abf15SRobert Mustacchi  */
lm_sq_post_from_list(struct _lm_device_t * pdev)3740*d14abf15SRobert Mustacchi static lm_status_t lm_sq_post_from_list(struct _lm_device_t *pdev)
3741*d14abf15SRobert Mustacchi {
3742*d14abf15SRobert Mustacchi     lm_status_t                 lm_status = LM_STATUS_SUCCESS;
3743*d14abf15SRobert Mustacchi     struct sq_pending_command * pending   = NULL;
3744*d14abf15SRobert Mustacchi 
3745*d14abf15SRobert Mustacchi     while (pdev->sq_info.num_pending_normal)
3746*d14abf15SRobert Mustacchi     {
3747*d14abf15SRobert Mustacchi         pending = (void*)d_list_pop_head(&pdev->sq_info.pending_normal);
3748*d14abf15SRobert Mustacchi 
3749*d14abf15SRobert Mustacchi         if(!pending)
3750*d14abf15SRobert Mustacchi             break;
3751*d14abf15SRobert Mustacchi 
3752*d14abf15SRobert Mustacchi         pdev->sq_info.num_pending_normal --;
3753*d14abf15SRobert Mustacchi 
3754*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORM, "lm_sq_post: priority=%d, command=%d, type=%d, cid=%d num_pending_normal=%d\n",
3755*d14abf15SRobert Mustacchi                CMD_PRIORITY_NORMAL, pending->cmd, pending->type, pending->cid, pdev->sq_info.num_pending_normal);
3756*d14abf15SRobert Mustacchi 
3757*d14abf15SRobert Mustacchi         d_list_push_tail(&pdev->sq_info.pending_complete, &pending->list);
3758*d14abf15SRobert Mustacchi 
3759*d14abf15SRobert Mustacchi         _lm_sq_post(pdev,pending);
3760*d14abf15SRobert Mustacchi 
3761*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_PENDING;
3762*d14abf15SRobert Mustacchi 
3763*d14abf15SRobert Mustacchi     }
3764*d14abf15SRobert Mustacchi 
3765*d14abf15SRobert Mustacchi     /* post high priority sp */
3766*d14abf15SRobert Mustacchi     while (pdev->sq_info.num_pending_high)
3767*d14abf15SRobert Mustacchi     {
3768*d14abf15SRobert Mustacchi         pending = (void*)d_list_pop_head(&pdev->sq_info.pending_high);
3769*d14abf15SRobert Mustacchi 
3770*d14abf15SRobert Mustacchi         if(!pending)
3771*d14abf15SRobert Mustacchi             break;
3772*d14abf15SRobert Mustacchi 
3773*d14abf15SRobert Mustacchi         pdev->sq_info.num_pending_high --;
3774*d14abf15SRobert Mustacchi         DbgMessage(pdev, INFORM, "lm_sq_post: priority=%d, command=%d, type=%d, cid=%d num_pending_normal=%d\n",
3775*d14abf15SRobert Mustacchi                CMD_PRIORITY_HIGH, pending->cmd, pending->type, pending->cid, pdev->sq_info.num_pending_normal);
3776*d14abf15SRobert Mustacchi 
3777*d14abf15SRobert Mustacchi         d_list_push_tail(&pdev->sq_info.pending_complete, &pending->list);
3778*d14abf15SRobert Mustacchi 
3779*d14abf15SRobert Mustacchi         _lm_sq_post(pdev, pending);
3780*d14abf15SRobert Mustacchi 
3781*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_PENDING;
3782*d14abf15SRobert Mustacchi     }
3783*d14abf15SRobert Mustacchi 
3784*d14abf15SRobert Mustacchi     return lm_status;
3785*d14abf15SRobert Mustacchi }
3786*d14abf15SRobert Mustacchi 
3787*d14abf15SRobert Mustacchi /**
3788*d14abf15SRobert Mustacchi  * Description
3789*d14abf15SRobert Mustacchi  *  Add the entry to the pending SP list.
3790*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)
3791*d14abf15SRobert Mustacchi  *
3792*d14abf15SRobert Mustacchi  * @param pdev
3793*d14abf15SRobert Mustacchi  * @param pending  - The pending list entry.
3794*d14abf15SRobert Mustacchi  * @param priority - (high or low) to witch list to insert the pending list entry.
3795*d14abf15SRobert Mustacchi  *
3796*d14abf15SRobert Mustacchi  * @return lm_status_t: LM_STATUS_SUCCESS on success or
3797*d14abf15SRobert Mustacchi  *         LM_STATUS_REQUEST_NOT_ACCEPTED if slowpath queue is
3798*d14abf15SRobert Mustacchi  *         in blocked state.
3799*d14abf15SRobert Mustacchi  */
lm_sq_post_entry(struct _lm_device_t * pdev,struct sq_pending_command * pending,u8_t priority)3800*d14abf15SRobert Mustacchi lm_status_t lm_sq_post_entry(struct _lm_device_t       * pdev,
3801*d14abf15SRobert Mustacchi                              struct sq_pending_command * pending,
3802*d14abf15SRobert Mustacchi                              u8_t                        priority)
3803*d14abf15SRobert Mustacchi {
3804*d14abf15SRobert Mustacchi     lm_status_t lm_status = LM_STATUS_FAILURE;
3805*d14abf15SRobert Mustacchi     u8_t        sq_flush  = FALSE;
3806*d14abf15SRobert Mustacchi 
3807*d14abf15SRobert Mustacchi     DbgBreakIf(! pdev);
3808*d14abf15SRobert Mustacchi 
3809*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3810*d14abf15SRobert Mustacchi 
3811*d14abf15SRobert Mustacchi     if (pdev->sq_info.sq_state == SQ_STATE_BLOCKED)
3812*d14abf15SRobert Mustacchi     {
3813*d14abf15SRobert Mustacchi         // This state is valid in case hw failure such as fan failure happened.
3814*d14abf15SRobert Mustacchi         // so we removed assert was here before and changed only to trace CQ62337
3815*d14abf15SRobert Mustacchi         DbgMessage(pdev, FATAL, "lm_sq_post_entry: Unexpected slowpath command SQ_STATE_BLOCKED\n");
3816*d14abf15SRobert Mustacchi 
3817*d14abf15SRobert Mustacchi         MM_RELEASE_SPQ_LOCK(pdev);
3818*d14abf15SRobert Mustacchi 
3819*d14abf15SRobert Mustacchi         return LM_STATUS_REQUEST_NOT_ACCEPTED;
3820*d14abf15SRobert Mustacchi     }
3821*d14abf15SRobert Mustacchi 
3822*d14abf15SRobert Mustacchi     /* We shouldn't be posting any entries if the function-stop has already been posted... */
3823*d14abf15SRobert Mustacchi     if (((mm_le32_to_cpu(pending->command.hdr.conn_and_cmd_data) & SPE_HDR_T_CMD_ID)>>SPE_HDR_T_CMD_ID_SHIFT) != RAMROD_CMD_ID_COMMON_FUNCTION_STOP)
3824*d14abf15SRobert Mustacchi     {
3825*d14abf15SRobert Mustacchi         DbgBreakIf((pdev->eq_info.function_state == FUNCTION_STOP_POSTED) || (pdev->eq_info.function_state == FUNCTION_STOP_COMPLETED));
3826*d14abf15SRobert Mustacchi     }
3827*d14abf15SRobert Mustacchi 
3828*d14abf15SRobert Mustacchi     switch( priority )
3829*d14abf15SRobert Mustacchi     {
3830*d14abf15SRobert Mustacchi     case CMD_PRIORITY_NORMAL:
3831*d14abf15SRobert Mustacchi         /* add the request to the list tail*/
3832*d14abf15SRobert Mustacchi         d_list_push_tail(&pdev->sq_info.pending_normal, &pending->list);
3833*d14abf15SRobert Mustacchi         break;
3834*d14abf15SRobert Mustacchi     case CMD_PRIORITY_MEDIUM:
3835*d14abf15SRobert Mustacchi         /* add the request to the list head*/
3836*d14abf15SRobert Mustacchi         d_list_push_head(&pdev->sq_info.pending_normal, &pending->list);
3837*d14abf15SRobert Mustacchi         break;
3838*d14abf15SRobert Mustacchi     case CMD_PRIORITY_HIGH:
3839*d14abf15SRobert Mustacchi         /* add the request to the list head*/
3840*d14abf15SRobert Mustacchi         d_list_push_head(&pdev->sq_info.pending_high, &pending->list);
3841*d14abf15SRobert Mustacchi         break;
3842*d14abf15SRobert Mustacchi     default:
3843*d14abf15SRobert Mustacchi         DbgBreakIf( 1 ) ;
3844*d14abf15SRobert Mustacchi         // TODO_ROLLBACK - free sq_pending_command
3845*d14abf15SRobert Mustacchi         MM_RELEASE_SPQ_LOCK(pdev);
3846*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER ;
3847*d14abf15SRobert Mustacchi     }
3848*d14abf15SRobert Mustacchi 
3849*d14abf15SRobert Mustacchi     if(!(pdev->sq_info.num_pending_normal))
3850*d14abf15SRobert Mustacchi     {
3851*d14abf15SRobert Mustacchi         LM_COMMON_DRV_STATS_ATOMIC_INC_ETH(pdev, tx_no_sq_wqe);
3852*d14abf15SRobert Mustacchi     }
3853*d14abf15SRobert Mustacchi 
3854*d14abf15SRobert Mustacchi     lm_status = lm_sq_post_from_list(pdev);
3855*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_PENDING)
3856*d14abf15SRobert Mustacchi     {
3857*d14abf15SRobert Mustacchi         /* New slowpath was posted in pending state... make sure to flush sq
3858*d14abf15SRobert Mustacchi          * after this... */
3859*d14abf15SRobert Mustacchi         if (pdev->sq_info.sq_state == SQ_STATE_PENDING)
3860*d14abf15SRobert Mustacchi         {
3861*d14abf15SRobert Mustacchi             sq_flush = TRUE;
3862*d14abf15SRobert Mustacchi         }
3863*d14abf15SRobert Mustacchi 
3864*d14abf15SRobert Mustacchi         lm_status = LM_STATUS_SUCCESS;
3865*d14abf15SRobert Mustacchi     }
3866*d14abf15SRobert Mustacchi 
3867*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
3868*d14abf15SRobert Mustacchi 
3869*d14abf15SRobert Mustacchi     if (sq_flush)
3870*d14abf15SRobert Mustacchi     {
3871*d14abf15SRobert Mustacchi         lm_sq_flush(pdev);
3872*d14abf15SRobert Mustacchi     }
3873*d14abf15SRobert Mustacchi     return lm_status ;
3874*d14abf15SRobert Mustacchi }
3875*d14abf15SRobert Mustacchi 
3876*d14abf15SRobert Mustacchi 
3877*d14abf15SRobert Mustacchi /*
3878*d14abf15SRobert Mustacchi     post a ramrod to the sq
3879*d14abf15SRobert Mustacchi     takes the sq pending list spinlock and adds the request
3880*d14abf15SRobert Mustacchi     will not block
3881*d14abf15SRobert Mustacchi     but the actuall posting to the sq might be deffered until there is room
3882*d14abf15SRobert Mustacchi     MUST only have one request pending per CID (this is up to the caller to enforce)
3883*d14abf15SRobert Mustacchi */
lm_sq_post(struct _lm_device_t * pdev,u32_t cid,u8_t command,u8_t priority,u16_t type,u64_t data)3884*d14abf15SRobert Mustacchi lm_status_t lm_sq_post(struct _lm_device_t *pdev,
3885*d14abf15SRobert Mustacchi                        u32_t                cid,
3886*d14abf15SRobert Mustacchi                        u8_t                 command,
3887*d14abf15SRobert Mustacchi                        u8_t                 priority,
3888*d14abf15SRobert Mustacchi                        u16_t                type,
3889*d14abf15SRobert Mustacchi                        u64_t                data)
3890*d14abf15SRobert Mustacchi {
3891*d14abf15SRobert Mustacchi     struct sq_pending_command *pending  = NULL;
3892*d14abf15SRobert Mustacchi     lm_status_t               lm_status = LM_STATUS_SUCCESS;
3893*d14abf15SRobert Mustacchi     DbgBreakIf(! pdev);
3894*d14abf15SRobert Mustacchi     DbgBreakIf(! command); /* todo: make this more detailed*/
3895*d14abf15SRobert Mustacchi 
3896*d14abf15SRobert Mustacchi     /* allocate a new command struct and fill it */
3897*d14abf15SRobert Mustacchi     pending = mm_get_sq_pending_command(pdev);
3898*d14abf15SRobert Mustacchi     if( !pending )
3899*d14abf15SRobert Mustacchi     {
3900*d14abf15SRobert Mustacchi         DbgBreakIf(1);
3901*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE ;
3902*d14abf15SRobert Mustacchi     }
3903*d14abf15SRobert Mustacchi 
3904*d14abf15SRobert Mustacchi     lm_sq_post_fill_entry(pdev,pending,cid,command,type,data,TRUE);
3905*d14abf15SRobert Mustacchi 
3906*d14abf15SRobert Mustacchi     lm_status = lm_sq_post_entry(pdev,pending,priority);
3907*d14abf15SRobert Mustacchi 
3908*d14abf15SRobert Mustacchi     return lm_status ;
3909*d14abf15SRobert Mustacchi }
3910*d14abf15SRobert Mustacchi 
3911*d14abf15SRobert Mustacchi /*
3912*d14abf15SRobert Mustacchi     inform the sq mechanism of completed ramrods
3913*d14abf15SRobert Mustacchi     because the completions arrive on the fast-path rings
3914*d14abf15SRobert Mustacchi     the fast-path needs to inform the sq that the ramrod has been serviced
3915*d14abf15SRobert Mustacchi     will not block
3916*d14abf15SRobert Mustacchi     does not take any locks
3917*d14abf15SRobert Mustacchi */
lm_sq_complete(struct _lm_device_t * pdev,u8_t priority,u8_t command,u16_t type,u32_t cid)3918*d14abf15SRobert Mustacchi void lm_sq_complete(struct _lm_device_t *pdev, u8_t priority,
3919*d14abf15SRobert Mustacchi                     u8_t command, u16_t type, u32_t cid )
3920*d14abf15SRobert Mustacchi {
3921*d14abf15SRobert Mustacchi 
3922*d14abf15SRobert Mustacchi     struct sq_pending_command *pending = NULL;
3923*d14abf15SRobert Mustacchi 
3924*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
3925*d14abf15SRobert Mustacchi 
3926*d14abf15SRobert Mustacchi     DbgMessage(pdev, INFORM, "lm_sq_complete: priority=%d, command=%d, type=%d, cid=%d num_pending_normal=%d\n",
3927*d14abf15SRobert Mustacchi                priority, command, type, cid, pdev->sq_info.num_pending_normal);
3928*d14abf15SRobert Mustacchi 
3929*d14abf15SRobert Mustacchi     switch( priority )
3930*d14abf15SRobert Mustacchi     {
3931*d14abf15SRobert Mustacchi     case CMD_PRIORITY_NORMAL:
3932*d14abf15SRobert Mustacchi     case CMD_PRIORITY_MEDIUM:
3933*d14abf15SRobert Mustacchi         pdev->sq_info.num_pending_normal ++;
3934*d14abf15SRobert Mustacchi         DbgBreakIf(pdev->sq_info.num_pending_normal > MAX_NORMAL_PRIORITY_SPE);
3935*d14abf15SRobert Mustacchi         break;
3936*d14abf15SRobert Mustacchi     case CMD_PRIORITY_HIGH:
3937*d14abf15SRobert Mustacchi         pdev->sq_info.num_pending_high ++;
3938*d14abf15SRobert Mustacchi         DbgBreakIf(pdev->sq_info.num_pending_high > MAX_HIGH_PRIORITY_SPE);
3939*d14abf15SRobert Mustacchi         break;
3940*d14abf15SRobert Mustacchi     default:
3941*d14abf15SRobert Mustacchi         DbgBreakIf( 1 ) ;
3942*d14abf15SRobert Mustacchi         break;
3943*d14abf15SRobert Mustacchi     }
3944*d14abf15SRobert Mustacchi 
3945*d14abf15SRobert Mustacchi     /* update sq consumer */
3946*d14abf15SRobert Mustacchi     pdev->sq_info.sq_chain.con_idx ++;
3947*d14abf15SRobert Mustacchi     pdev->sq_info.sq_chain.bd_left ++;
3948*d14abf15SRobert Mustacchi 
3949*d14abf15SRobert Mustacchi     /* Search for the completion in the pending_complete list*/
3950*d14abf15SRobert Mustacchi     /* Currently only supported if error recovery is supported */
3951*d14abf15SRobert Mustacchi     pending = (void*)d_list_peek_head(&pdev->sq_info.pending_complete);
3952*d14abf15SRobert Mustacchi 
3953*d14abf15SRobert Mustacchi     if (pdev->params.validate_sq_complete)
3954*d14abf15SRobert Mustacchi     {
3955*d14abf15SRobert Mustacchi         DbgBreakIf(!pending); /* not expected, but will deal with it... just won't  */
3956*d14abf15SRobert Mustacchi     }
3957*d14abf15SRobert Mustacchi 
3958*d14abf15SRobert Mustacchi     if (pdev->params.validate_sq_complete)
3959*d14abf15SRobert Mustacchi     {
3960*d14abf15SRobert Mustacchi         while (pending)
3961*d14abf15SRobert Mustacchi         {
3962*d14abf15SRobert Mustacchi             if (((pending->type & SPE_HDR_T_CONN_TYPE) == type) &&
3963*d14abf15SRobert Mustacchi                 (pending->cmd == command) &&
3964*d14abf15SRobert Mustacchi                 (pending->cid == cid))
3965*d14abf15SRobert Mustacchi             {
3966*d14abf15SRobert Mustacchi                 /* got it... remove from list and free it */
3967*d14abf15SRobert Mustacchi                 d_list_remove_entry(&pdev->sq_info.pending_complete, &pending->list);
3968*d14abf15SRobert Mustacchi                 if(GET_FLAGS(pending->flags, SQ_PEND_RELEASE_MEM))
3969*d14abf15SRobert Mustacchi                 {
3970*d14abf15SRobert Mustacchi                     mm_return_sq_pending_command(pdev, pending);
3971*d14abf15SRobert Mustacchi                 }
3972*d14abf15SRobert Mustacchi                 break;
3973*d14abf15SRobert Mustacchi             }
3974*d14abf15SRobert Mustacchi             pending = (void*)d_list_next_entry(&pending->list);
3975*d14abf15SRobert Mustacchi         }
3976*d14abf15SRobert Mustacchi     }
3977*d14abf15SRobert Mustacchi     else
3978*d14abf15SRobert Mustacchi     {
3979*d14abf15SRobert Mustacchi         /* TODO_ER: on no validation, just take the head... Workaround for mc-diag */
3980*d14abf15SRobert Mustacchi         pending = (void*)d_list_pop_head(&pdev->sq_info.pending_complete);
3981*d14abf15SRobert Mustacchi         if(CHK_NULL(pending))
3982*d14abf15SRobert Mustacchi         {
3983*d14abf15SRobert Mustacchi             DbgBreakMsg("lm_sq_complete pending is NULL");
3984*d14abf15SRobert Mustacchi         }
3985*d14abf15SRobert Mustacchi         else
3986*d14abf15SRobert Mustacchi         {
3987*d14abf15SRobert Mustacchi             if((GET_FLAGS(pending->flags, SQ_PEND_RELEASE_MEM)))
3988*d14abf15SRobert Mustacchi             {
3989*d14abf15SRobert Mustacchi                 mm_return_sq_pending_command(pdev, pending);
3990*d14abf15SRobert Mustacchi             }
3991*d14abf15SRobert Mustacchi         }
3992*d14abf15SRobert Mustacchi     }
3993*d14abf15SRobert Mustacchi 
3994*d14abf15SRobert Mustacchi     DbgBreakIf(!pending); /* means none were found, assert but can deal with it... */
3995*d14abf15SRobert Mustacchi 
3996*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
3997*d14abf15SRobert Mustacchi }
3998*d14abf15SRobert Mustacchi 
3999*d14abf15SRobert Mustacchi /**
4000*d14abf15SRobert Mustacchi  * @description
4001*d14abf15SRobert Mustacchi  *    do any deffered posting pending on the sq, will take the list spinlock
4002*d14abf15SRobert Mustacchi  *    will not block. Check sq state, if its pending (it means no hw...) call flush
4003*d14abf15SRobert Mustacchi  *    at the end, which will take care of completing these completions internally.
4004*d14abf15SRobert Mustacchi  * @param pdev
4005*d14abf15SRobert Mustacchi  *
4006*d14abf15SRobert Mustacchi  * @return lm_status_t SUCCESS: is no pending requests were sent. PENDING if a
4007*d14abf15SRobert Mustacchi  *                              if pending request was sent.
4008*d14abf15SRobert Mustacchi  */
lm_sq_post_pending(struct _lm_device_t * pdev)4009*d14abf15SRobert Mustacchi lm_status_t lm_sq_post_pending(struct _lm_device_t *pdev)
4010*d14abf15SRobert Mustacchi {
4011*d14abf15SRobert Mustacchi     lm_status_t                 lm_status = LM_STATUS_SUCCESS;
4012*d14abf15SRobert Mustacchi     u8_t                        sq_flush  = FALSE;
4013*d14abf15SRobert Mustacchi 
4014*d14abf15SRobert Mustacchi     if ( CHK_NULL(pdev) )
4015*d14abf15SRobert Mustacchi     {
4016*d14abf15SRobert Mustacchi         DbgBreakIf(!pdev);
4017*d14abf15SRobert Mustacchi         return LM_STATUS_INVALID_PARAMETER;
4018*d14abf15SRobert Mustacchi     }
4019*d14abf15SRobert Mustacchi 
4020*d14abf15SRobert Mustacchi     MM_ACQUIRE_SPQ_LOCK(pdev);
4021*d14abf15SRobert Mustacchi 
4022*d14abf15SRobert Mustacchi     lm_status = lm_sq_post_from_list(pdev);
4023*d14abf15SRobert Mustacchi 
4024*d14abf15SRobert Mustacchi     if (lm_status == LM_STATUS_PENDING)
4025*d14abf15SRobert Mustacchi     {
4026*d14abf15SRobert Mustacchi         /* New slowpath was posted in pending state... make sure to flush sq
4027*d14abf15SRobert Mustacchi          * after this... */
4028*d14abf15SRobert Mustacchi         if (pdev->sq_info.sq_state == SQ_STATE_PENDING)
4029*d14abf15SRobert Mustacchi         {
4030*d14abf15SRobert Mustacchi             sq_flush = TRUE;
4031*d14abf15SRobert Mustacchi         }
4032*d14abf15SRobert Mustacchi     }
4033*d14abf15SRobert Mustacchi 
4034*d14abf15SRobert Mustacchi     MM_RELEASE_SPQ_LOCK(pdev);
4035*d14abf15SRobert Mustacchi 
4036*d14abf15SRobert Mustacchi     if (sq_flush)
4037*d14abf15SRobert Mustacchi     {
4038*d14abf15SRobert Mustacchi         lm_sq_flush(pdev);
4039*d14abf15SRobert Mustacchi     }
4040*d14abf15SRobert Mustacchi     return lm_status;
4041*d14abf15SRobert Mustacchi }
4042*d14abf15SRobert Mustacchi 
4043*d14abf15SRobert Mustacchi 
4044*d14abf15SRobert Mustacchi /*********************** ETH SLOWPATH RELATED FUNCTIONS ***************************/
4045*d14abf15SRobert Mustacchi 
lm_eth_init_command_comp(struct _lm_device_t * pdev,struct common_ramrod_eth_rx_cqe * cqe)4046*d14abf15SRobert Mustacchi void lm_eth_init_command_comp(struct _lm_device_t *pdev, struct common_ramrod_eth_rx_cqe *cqe)
4047*d14abf15SRobert Mustacchi {
4048*d14abf15SRobert Mustacchi     lm_tpa_info_t* tpa_info   = &LM_TPA_INFO(pdev);
4049*d14abf15SRobert Mustacchi     void *         cookie             = NULL;
4050*d14abf15SRobert Mustacchi     u32_t          conn_and_cmd_data   = mm_le32_to_cpu(cqe->conn_and_cmd_data);
4051*d14abf15SRobert Mustacchi     u32_t          cid                 = SW_CID(conn_and_cmd_data);
4052*d14abf15SRobert Mustacchi     enum           eth_spqe_cmd_id  command   = conn_and_cmd_data >> COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT;
4053*d14abf15SRobert Mustacchi     u8_t           ramrod_type         = cqe->ramrod_type;
4054*d14abf15SRobert Mustacchi     u32_t          empty_data          = 0;
4055*d14abf15SRobert Mustacchi     u32_t          connection_info_idx = 0;
4056*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
4057*d14abf15SRobert Mustacchi     u32_t          max_eth_cid;
4058*d14abf15SRobert Mustacchi #endif
4059*d14abf15SRobert Mustacchi 
4060*d14abf15SRobert Mustacchi     DbgBreakIf(!pdev);
4061*d14abf15SRobert Mustacchi 
4062*d14abf15SRobert Mustacchi     DbgMessage(pdev, WARNl2sp,
4063*d14abf15SRobert Mustacchi                 "lm_eth_comp_cb: completion for cid=%d, command %d(0x%x)\n", cid, command, command);
4064*d14abf15SRobert Mustacchi 
4065*d14abf15SRobert Mustacchi     DbgBreakIfAll(ramrod_type & COMMON_RAMROD_ETH_RX_CQE_ERROR);
4066*d14abf15SRobert Mustacchi 
4067*d14abf15SRobert Mustacchi     connection_info_idx = lm_get_sw_client_idx_from_cid(pdev,cid);
4068*d14abf15SRobert Mustacchi 
4069*d14abf15SRobert Mustacchi     switch (command)
4070*d14abf15SRobert Mustacchi     {
4071*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_CLIENT_SETUP:
4072*d14abf15SRobert Mustacchi             DbgBreakIf(lm_get_con_state(pdev, cid) != LM_CON_STATE_OPEN_SENT);
4073*d14abf15SRobert Mustacchi             lm_set_con_state(pdev, cid, LM_CON_STATE_OPEN);
4074*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp,
4075*d14abf15SRobert Mustacchi                         "lm_eth_comp_cb: RAMROD ETH SETUP completed for cid=%d, - calling lm_extract_ramrod_req!\n", cid);
4076*d14abf15SRobert Mustacchi             break;
4077*d14abf15SRobert Mustacchi 
4078*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP:
4079*d14abf15SRobert Mustacchi             DbgBreakIf(lm_get_con_state(pdev, cid) != LM_CON_STATE_OPEN_SENT);
4080*d14abf15SRobert Mustacchi             lm_set_con_state(pdev, cid, LM_CON_STATE_OPEN);
4081*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp,
4082*d14abf15SRobert Mustacchi                         "lm_eth_comp_cb: RAMROD ETH SETUP completed for cid=%d, - calling lm_extract_ramrod_req!\n", cid);
4083*d14abf15SRobert Mustacchi             break;
4084*d14abf15SRobert Mustacchi 
4085*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_CLIENT_UPDATE:
4086*d14abf15SRobert Mustacchi             DbgBreakIf(PFDEV(pdev)->client_info[connection_info_idx].update.state != LM_CLI_UPDATE_USED);
4087*d14abf15SRobert Mustacchi             PFDEV(pdev)->client_info[connection_info_idx].update.state = LM_CLI_UPDATE_RECV;
4088*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp,
4089*d14abf15SRobert Mustacchi                         "lm_eth_comp_cb: RAMROD ETH Update completed for cid=%d, - calling lm_extract_ramrod_req!\n", cid);
4090*d14abf15SRobert Mustacchi             break;
4091*d14abf15SRobert Mustacchi 
4092*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_HALT:
4093*d14abf15SRobert Mustacchi             DbgBreakIf(lm_get_con_state(pdev, cid) != LM_CON_STATE_HALT_SENT);
4094*d14abf15SRobert Mustacchi             lm_set_con_state(pdev, cid, LM_CON_STATE_HALT);
4095*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp, "lm_eth_comp_cb:RAMROD_CMD_ID_ETH_HALT- calling lm_extract_ramrod_req!\n");
4096*d14abf15SRobert Mustacchi             break;
4097*d14abf15SRobert Mustacchi 
4098*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_EMPTY:
4099*d14abf15SRobert Mustacchi             empty_data        = mm_le32_to_cpu(cqe->protocol_data.data_lo);
4100*d14abf15SRobert Mustacchi             MM_EMPTY_RAMROD_RECEIVED(pdev,empty_data);
4101*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp, "lm_eth_comp_cb:RAMROD_CMD_ID_ETH_EMPTY- calling lm_extract_ramrod_req!\n");
4102*d14abf15SRobert Mustacchi             break;
4103*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_TPA_UPDATE:
4104*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp, "lm_eth_comp_cb:RAMROD_CMD_ID_ETH_TPA_UPDATE- calling lm_extract_ramrod_req!\n");
4105*d14abf15SRobert Mustacchi #ifdef VF_INVOLVED
4106*d14abf15SRobert Mustacchi             if (MM_DCB_MP_L2_IS_ENABLE(pdev))
4107*d14abf15SRobert Mustacchi             {
4108*d14abf15SRobert Mustacchi                 max_eth_cid = lm_mp_max_cos_chain_used(pdev);
4109*d14abf15SRobert Mustacchi             }
4110*d14abf15SRobert Mustacchi             else
4111*d14abf15SRobert Mustacchi             {
4112*d14abf15SRobert Mustacchi                 max_eth_cid = LM_SB_CNT(pdev) + MAX_NON_RSS_CHAINS;
4113*d14abf15SRobert Mustacchi             }
4114*d14abf15SRobert Mustacchi             if (IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev) && (cid >= max_eth_cid))
4115*d14abf15SRobert Mustacchi             {
4116*d14abf15SRobert Mustacchi                 u8_t           abs_vf_id = 0xff;
4117*d14abf15SRobert Mustacchi                 u8_t           vf_q_id   = 0xff;
4118*d14abf15SRobert Mustacchi                 lm_vf_info_t * vf_info   = NULL;
4119*d14abf15SRobert Mustacchi 
4120*d14abf15SRobert Mustacchi                 abs_vf_id = GET_ABS_VF_ID_FROM_PF_CID(cid);
4121*d14abf15SRobert Mustacchi                 vf_q_id = GET_VF_Q_ID_FROM_PF_CID(cid);
4122*d14abf15SRobert Mustacchi                 vf_info = lm_pf_find_vf_info_by_abs_id(pdev, abs_vf_id);
4123*d14abf15SRobert Mustacchi                 DbgBreakIf(!vf_info);
4124*d14abf15SRobert Mustacchi                 mm_atomic_dec((u32_t*)(&vf_info->vf_tpa_info.ramrod_recv_cnt));
4125*d14abf15SRobert Mustacchi             }
4126*d14abf15SRobert Mustacchi             else
4127*d14abf15SRobert Mustacchi #endif
4128*d14abf15SRobert Mustacchi             {
4129*d14abf15SRobert Mustacchi                 if (IS_VFDEV(pdev))
4130*d14abf15SRobert Mustacchi                 {
4131*d14abf15SRobert Mustacchi                     cid = GET_VF_Q_ID_FROM_PF_CID(cid);
4132*d14abf15SRobert Mustacchi                 }
4133*d14abf15SRobert Mustacchi                 if (0 == mm_atomic_dec((u32_t*)(&tpa_info->ramrod_recv_cnt)))
4134*d14abf15SRobert Mustacchi                 {
4135*d14abf15SRobert Mustacchi                         tpa_info->ipvx_enabled_current = tpa_info->ipvx_enabled_required;
4136*d14abf15SRobert Mustacchi                         tpa_info->state = TPA_STATE_NONE; /* Done with ramrods... */
4137*d14abf15SRobert Mustacchi                         if (tpa_info->update_cookie)
4138*d14abf15SRobert Mustacchi                         {
4139*d14abf15SRobert Mustacchi                             cookie = (void *)tpa_info->update_cookie;
4140*d14abf15SRobert Mustacchi                             tpa_info->update_cookie = NULL;
4141*d14abf15SRobert Mustacchi                             mm_set_done(pdev, cid, cookie);
4142*d14abf15SRobert Mustacchi                         }
4143*d14abf15SRobert Mustacchi 
4144*d14abf15SRobert Mustacchi                 }
4145*d14abf15SRobert Mustacchi             }
4146*d14abf15SRobert Mustacchi             if (!IS_PFDEV(pdev))
4147*d14abf15SRobert Mustacchi             {
4148*d14abf15SRobert Mustacchi                 return; /*To prevent lm_sq_completion processing for non existing (not submited) pending item*/
4149*d14abf15SRobert Mustacchi             }
4150*d14abf15SRobert Mustacchi             break;
4151*d14abf15SRobert Mustacchi         case RAMROD_CMD_ID_ETH_TERMINATE:
4152*d14abf15SRobert Mustacchi             DbgBreakIf(lm_get_con_state(pdev, cid) != LM_CON_STATE_HALT);
4153*d14abf15SRobert Mustacchi             lm_set_con_state(pdev, cid, LM_CON_STATE_TERMINATE);
4154*d14abf15SRobert Mustacchi             DbgMessage(pdev, WARNl2sp, "lm_eth_comp_cb:RAMROD_CMD_ID_ETH_TERMINATE- calling lm_extract_ramrod_req!\n");
4155*d14abf15SRobert Mustacchi             break;
4156*d14abf15SRobert Mustacchi 
4157*d14abf15SRobert Mustacchi         default:
4158*d14abf15SRobert Mustacchi             DbgMessage(pdev, FATAL,"lm_eth_init_command_comp_cb unhandled ramrod comp command=%d\n",command);
4159*d14abf15SRobert Mustacchi             DbgBreakIf(1); // unhandled ramrod!
4160*d14abf15SRobert Mustacchi             break;
4161*d14abf15SRobert Mustacchi     }
4162*d14abf15SRobert Mustacchi #ifdef __LINUX
4163*d14abf15SRobert Mustacchi     mm_eth_ramrod_comp_cb(pdev, cqe);
4164*d14abf15SRobert Mustacchi #endif //__LINUX
4165*d14abf15SRobert Mustacchi     lm_sq_complete(pdev, CMD_PRIORITY_NORMAL, command, ETH_CONNECTION_TYPE, cid);
4166*d14abf15SRobert Mustacchi }
4167*d14abf15SRobert Mustacchi 
4168*d14abf15SRobert Mustacchi /**
4169*d14abf15SRobert Mustacchi  * @Description
4170*d14abf15SRobert Mustacchi  *      Function is the callback function for completing eth
4171*d14abf15SRobert Mustacchi  *      completions when no chip access exists. Part of
4172*d14abf15SRobert Mustacchi  *      "complete-pending-sq" flow
4173*d14abf15SRobert Mustacchi  * @param pdev
4174*d14abf15SRobert Mustacchi  * @param spe
4175*d14abf15SRobert Mustacchi  */
lm_eth_comp_cb(struct _lm_device_t * pdev,struct sq_pending_command * pending)4176*d14abf15SRobert Mustacchi void lm_eth_comp_cb(struct _lm_device_t *pdev, struct sq_pending_command * pending)
4177*d14abf15SRobert Mustacchi {
4178*d14abf15SRobert Mustacchi     struct common_ramrod_eth_rx_cqe cqe;
4179*d14abf15SRobert Mustacchi 
4180*d14abf15SRobert Mustacchi     /* The idea is to prepare a cqe and call: common_ramrod_eth_rx_cqe */
4181*d14abf15SRobert Mustacchi     cqe.conn_and_cmd_data     = pending->command.hdr.conn_and_cmd_data;
4182*d14abf15SRobert Mustacchi     cqe.ramrod_type           = RX_ETH_CQE_TYPE_ETH_RAMROD;
4183*d14abf15SRobert Mustacchi     cqe.protocol_data.data_hi = pending->command.protocol_data.hi;
4184*d14abf15SRobert Mustacchi     cqe.protocol_data.data_lo = pending->command.protocol_data.lo;
4185*d14abf15SRobert Mustacchi 
4186*d14abf15SRobert Mustacchi     switch (pending->cmd)
4187*d14abf15SRobert Mustacchi     {
4188*d14abf15SRobert Mustacchi         /* Ramrods that complete on the EQ */
4189*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_RSS_UPDATE:
4190*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_FILTER_RULES:
4191*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_MULTICAST_RULES:
4192*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_FORWARD_SETUP:
4193*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES:
4194*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_SET_MAC:
4195*d14abf15SRobert Mustacchi         lm_eq_comp_cb(pdev, pending);
4196*d14abf15SRobert Mustacchi         break;
4197*d14abf15SRobert Mustacchi 
4198*d14abf15SRobert Mustacchi         /* Ramrods that complete on the RCQ */
4199*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_CLIENT_SETUP:
4200*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP:
4201*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_CLIENT_UPDATE:
4202*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_HALT:
4203*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_EMPTY:
4204*d14abf15SRobert Mustacchi     case RAMROD_CMD_ID_ETH_TERMINATE:
4205*d14abf15SRobert Mustacchi         lm_eth_init_command_comp(pdev, &cqe);
4206*d14abf15SRobert Mustacchi         break;
4207*d14abf15SRobert Mustacchi 
4208*d14abf15SRobert Mustacchi     default:
4209*d14abf15SRobert Mustacchi         DbgBreakMsg("Unknown cmd");
4210*d14abf15SRobert Mustacchi     }
4211*d14abf15SRobert Mustacchi }
4212*d14abf15SRobert Mustacchi 
lm_check_mac_addr_exist(struct _lm_device_t * pdev,u8_t chain_idx,u8_t * mac_addr,u16_t vlan_tag,u8_t is_encap_inner_mac_filter)4213*d14abf15SRobert Mustacchi u8_t lm_check_mac_addr_exist(struct _lm_device_t *pdev, u8_t chain_idx, u8_t *mac_addr, u16_t vlan_tag, u8_t is_encap_inner_mac_filter)
4214*d14abf15SRobert Mustacchi {
4215*d14abf15SRobert Mustacchi 	struct ecore_vlan_mac_obj          *dest_obj     = NULL;
4216*d14abf15SRobert Mustacchi 	ecore_status_t                      ecore_status = ECORE_SUCCESS;
4217*d14abf15SRobert Mustacchi 	u8_t                                is_exist       = FALSE;
4218*d14abf15SRobert Mustacchi 	union ecore_classification_ramrod_data
4219*d14abf15SRobert Mustacchi 					classification_ramrod_data = {{{0}}};
4220*d14abf15SRobert Mustacchi 
4221*d14abf15SRobert Mustacchi 	if ERR_IF(!pdev || !mac_addr)
4222*d14abf15SRobert Mustacchi 	{
4223*d14abf15SRobert Mustacchi 	    DbgBreakMsg("lm_move_mac_addr: invalid params\n");
4224*d14abf15SRobert Mustacchi 	    return LM_STATUS_INVALID_PARAMETER;
4225*d14abf15SRobert Mustacchi 	}
4226*d14abf15SRobert Mustacchi #if 0
4227*d14abf15SRobert Mustacchi 	if (lm_reset_is_inprogress(pdev))
4228*d14abf15SRobert Mustacchi 	{
4229*d14abf15SRobert Mustacchi 	    DbgMessage(pdev, FATAL, "lm_move_mac_addr: Under FLR!!!\n");
4230*d14abf15SRobert Mustacchi 	    return  LM_STATUS_SUCCESS;
4231*d14abf15SRobert Mustacchi 	}
4232*d14abf15SRobert Mustacchi #endif
4233*d14abf15SRobert Mustacchi 
4234*d14abf15SRobert Mustacchi 	if (vlan_tag != LM_SET_CAM_NO_VLAN_FILTER)
4235*d14abf15SRobert Mustacchi 	{
4236*d14abf15SRobert Mustacchi 	    dest_obj = &pdev->client_info[chain_idx].mac_vlan_obj;
4237*d14abf15SRobert Mustacchi 	    mm_memcpy(classification_ramrod_data.vlan_mac.mac, mac_addr, sizeof(classification_ramrod_data.vlan_mac.mac));
4238*d14abf15SRobert Mustacchi 	    classification_ramrod_data.vlan_mac.vlan = vlan_tag;
4239*d14abf15SRobert Mustacchi 	    classification_ramrod_data.vlan_mac.is_inner_mac = is_encap_inner_mac_filter;
4240*d14abf15SRobert Mustacchi 	}
4241*d14abf15SRobert Mustacchi 	else
4242*d14abf15SRobert Mustacchi 	{
4243*d14abf15SRobert Mustacchi 	    dest_obj = &pdev->client_info[chain_idx].mac_obj;
4244*d14abf15SRobert Mustacchi             mm_memcpy(classification_ramrod_data.mac.mac, mac_addr, sizeof(classification_ramrod_data.mac.mac) );
4245*d14abf15SRobert Mustacchi             classification_ramrod_data.mac.is_inner_mac = is_encap_inner_mac_filter;
4246*d14abf15SRobert Mustacchi 	}
4247*d14abf15SRobert Mustacchi 
4248*d14abf15SRobert Mustacchi 	ecore_status = dest_obj->check_add(pdev,dest_obj,&classification_ramrod_data);
4249*d14abf15SRobert Mustacchi 	if (ecore_status == ECORE_EXISTS)
4250*d14abf15SRobert Mustacchi 	{
4251*d14abf15SRobert Mustacchi             is_exist = TRUE;
4252*d14abf15SRobert Mustacchi 	}
4253*d14abf15SRobert Mustacchi 	else if (ecore_status == ECORE_SUCCESS)
4254*d14abf15SRobert Mustacchi 	{
4255*d14abf15SRobert Mustacchi 	    is_exist = FALSE;
4256*d14abf15SRobert Mustacchi 	}
4257*d14abf15SRobert Mustacchi 	else
4258*d14abf15SRobert Mustacchi 	{
4259*d14abf15SRobert Mustacchi 	    DbgBreak();
4260*d14abf15SRobert Mustacchi 	}
4261*d14abf15SRobert Mustacchi 	return is_exist;
4262*d14abf15SRobert Mustacchi }
4263*d14abf15SRobert Mustacchi 
lm_update_default_vlan(IN struct _lm_device_t * pdev,IN u8_t client_idx,IN const u16_t silent_vlan_value,IN const u16_t silent_vlan_mask,IN const u8_t silent_vlan_removal_flg,IN const u8_t silent_vlan_change_flg,IN const u16_t default_vlan,IN const u8_t default_vlan_enable_flg,IN const u8_t default_vlan_change_flg)4264*d14abf15SRobert Mustacchi lm_status_t lm_update_default_vlan(IN struct _lm_device_t    *pdev, IN u8_t client_idx,
4265*d14abf15SRobert Mustacchi                               IN const u16_t            silent_vlan_value,
4266*d14abf15SRobert Mustacchi                               IN const u16_t            silent_vlan_mask,
4267*d14abf15SRobert Mustacchi                               IN const u8_t             silent_vlan_removal_flg,
4268*d14abf15SRobert Mustacchi                               IN const u8_t             silent_vlan_change_flg,
4269*d14abf15SRobert Mustacchi                               IN const u16_t            default_vlan,
4270*d14abf15SRobert Mustacchi                               IN const u8_t             default_vlan_enable_flg,
4271*d14abf15SRobert Mustacchi                               IN const u8_t             default_vlan_change_flg)
4272*d14abf15SRobert Mustacchi {
4273*d14abf15SRobert Mustacchi     struct client_update_ramrod_data * client_update_data_virt = pdev->client_info[client_idx].update.data_virt;
4274*d14abf15SRobert Mustacchi     lm_status_t                        lm_status               = LM_STATUS_FAILURE;
4275*d14abf15SRobert Mustacchi     u32_t                              con_state               = 0;
4276*d14abf15SRobert Mustacchi     const u32_t                        cid                     = client_idx; //lm_get_cid_from_sw_client_idx(pdev);
4277*d14abf15SRobert Mustacchi 
4278*d14abf15SRobert Mustacchi     if CHK_NULL(client_update_data_virt)
4279*d14abf15SRobert Mustacchi     {
4280*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
4281*d14abf15SRobert Mustacchi     }
4282*d14abf15SRobert Mustacchi 
4283*d14abf15SRobert Mustacchi     mm_mem_zero(client_update_data_virt , sizeof(struct client_update_ramrod_data));
4284*d14abf15SRobert Mustacchi 
4285*d14abf15SRobert Mustacchi     MM_ACQUIRE_ETH_CON_LOCK(pdev);
4286*d14abf15SRobert Mustacchi 
4287*d14abf15SRobert Mustacchi     // We will send a client update ramrod in any case we can we don't optimize this flow.
4288*d14abf15SRobert Mustacchi     // Client setup may already took the correct NIV value but the ramrod will be sent anyway
4289*d14abf15SRobert Mustacchi     con_state = lm_get_con_state(pdev, cid);
4290*d14abf15SRobert Mustacchi     if((LM_CON_STATE_OPEN != con_state) &&
4291*d14abf15SRobert Mustacchi         (LM_CON_STATE_OPEN_SENT != con_state))
4292*d14abf15SRobert Mustacchi     {
4293*d14abf15SRobert Mustacchi         // Clinet is not in a state that it can recieve the ramrod
4294*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
4295*d14abf15SRobert Mustacchi         return LM_STATUS_ABORTED;
4296*d14abf15SRobert Mustacchi     }
4297*d14abf15SRobert Mustacchi 
4298*d14abf15SRobert Mustacchi     /* We don't expect this function to be called for non eth regular connections.
4299*d14abf15SRobert Mustacchi      * If we hit this assert it means we need support for SRIOV +  AFEX
4300*d14abf15SRobert Mustacchi      */
4301*d14abf15SRobert Mustacchi     if (cid >= MAX_RX_CHAIN(pdev))
4302*d14abf15SRobert Mustacchi     {
4303*d14abf15SRobert Mustacchi         DbgBreakIf(cid >= MAX_RX_CHAIN(pdev));
4304*d14abf15SRobert Mustacchi         MM_RELEASE_ETH_CON_LOCK(pdev);
4305*d14abf15SRobert Mustacchi         return LM_STATUS_FAILURE;
4306*d14abf15SRobert Mustacchi     }
4307*d14abf15SRobert Mustacchi 
4308*d14abf15SRobert Mustacchi     DbgBreakIf( LM_CLI_UPDATE_NOT_USED != pdev->client_info[client_idx].update.state);
4309*d14abf15SRobert Mustacchi 
4310*d14abf15SRobert Mustacchi     pdev->client_info[client_idx].update.state = LM_CLI_UPDATE_USED;
4311*d14abf15SRobert Mustacchi 
4312*d14abf15SRobert Mustacchi     client_update_data_virt->client_id  = LM_FW_CLI_ID(pdev, client_idx);
4313*d14abf15SRobert Mustacchi     client_update_data_virt->func_id    = FUNC_ID(pdev); /* FIXME: VFID needs to be given here for VFs... */
4314*d14abf15SRobert Mustacchi 
4315*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_value          = mm_cpu_to_le16(silent_vlan_value);
4316*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_mask           = mm_cpu_to_le16(silent_vlan_mask);
4317*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_removal_flg    = silent_vlan_removal_flg;
4318*d14abf15SRobert Mustacchi     client_update_data_virt->silent_vlan_change_flg     = silent_vlan_change_flg;
4319*d14abf15SRobert Mustacchi 
4320*d14abf15SRobert Mustacchi     client_update_data_virt->refuse_outband_vlan_flg        = 0;
4321*d14abf15SRobert Mustacchi     client_update_data_virt->refuse_outband_vlan_change_flg = 0;
4322*d14abf15SRobert Mustacchi     client_update_data_virt->default_vlan = default_vlan;
4323*d14abf15SRobert Mustacchi     client_update_data_virt->default_vlan_enable_flg    = default_vlan_enable_flg;
4324*d14abf15SRobert Mustacchi     client_update_data_virt->default_vlan_change_flg    = default_vlan_change_flg;
4325*d14abf15SRobert Mustacchi 
4326*d14abf15SRobert Mustacchi     lm_status = lm_sq_post(pdev,
4327*d14abf15SRobert Mustacchi                            cid,
4328*d14abf15SRobert Mustacchi                            RAMROD_CMD_ID_ETH_CLIENT_UPDATE,
4329*d14abf15SRobert Mustacchi                            CMD_PRIORITY_MEDIUM,
4330*d14abf15SRobert Mustacchi                            ETH_CONNECTION_TYPE,
4331*d14abf15SRobert Mustacchi                            pdev->client_info[client_idx].update.data_phys.as_u64);
4332*d14abf15SRobert Mustacchi 
4333*d14abf15SRobert Mustacchi     MM_RELEASE_ETH_CON_LOCK(pdev);
4334*d14abf15SRobert Mustacchi 
4335*d14abf15SRobert Mustacchi 
4336*d14abf15SRobert Mustacchi     if (lm_status != LM_STATUS_SUCCESS)
4337*d14abf15SRobert Mustacchi     {
4338*d14abf15SRobert Mustacchi         return lm_status;
4339*d14abf15SRobert Mustacchi     }
4340*d14abf15SRobert Mustacchi 
4341*d14abf15SRobert Mustacchi     lm_status = lm_wait_state_change(pdev, &pdev->client_info[client_idx].update.state, LM_CLI_UPDATE_RECV);
4342*d14abf15SRobert Mustacchi 
4343*d14abf15SRobert Mustacchi     pdev->client_info[client_idx].update.state = LM_CLI_UPDATE_NOT_USED;
4344*d14abf15SRobert Mustacchi 
4345*d14abf15SRobert Mustacchi     return lm_status;
4346*d14abf15SRobert Mustacchi }
4347*d14abf15SRobert Mustacchi 
4348