1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <npi_fflp.h>
27 #include <nxge_common.h>
28
29 /* macros to compute calss configuration register offset */
30
31 #define GET_TCAM_CLASS_OFFSET(cls) \
32 (FFLP_TCAM_CLS_BASE_OFFSET + (cls - 2) * 8)
33 #define GET_TCAM_KEY_OFFSET(cls) \
34 (FFLP_TCAM_KEY_BASE_OFFSET + (cls - 4) * 8)
35 #define GET_FLOW_KEY_OFFSET(cls) \
36 (FFLP_FLOW_KEY_BASE_OFFSET + (cls - 4) * 8)
37
38 #define HASHTBL_PART_REG_STEP 8192
39 #define HASHTBL_PART_REG_VIR_OFFSET 0x2100
40 #define HASHTBL_PART_REG_VIR_STEP 0x4000
41 #define GET_HASHTBL_PART_OFFSET_NVIR(partid, reg) \
42 ((partid * HASHTBL_PART_REG_STEP) + reg)
43
44 #define GET_HASHTBL_PART_OFFSET(handle, partid, reg) \
45 (handle.is_vraddr ? \
46 (((partid & 0x1) * HASHTBL_PART_REG_VIR_STEP) + \
47 (reg & 0x8) + (HASHTBL_PART_REG_VIR_OFFSET)) : \
48 (partid * HASHTBL_PART_REG_STEP) + reg)
49
50 #define FFLP_PART_OFFSET(partid, reg) ((partid * 8) + reg)
51 #define FFLP_VLAN_OFFSET(vid, reg) ((vid * 8) + reg)
52
53 #define TCAM_COMPLETION_TRY_COUNT 10
54 #define BIT_ENABLE 0x1
55 #define BIT_DISABLE 0x0
56
57 #define FCRAM_PARTITION_VALID(partid) \
58 ((partid < NXGE_MAX_RDC_GRPS))
59 #define FFLP_VLAN_VALID(vid) \
60 ((vid > 0) && (vid < NXGE_MAX_VLANS))
61 #define FFLP_PORT_VALID(port) \
62 ((port < MAX_PORTS_PER_NXGE))
63 #define FFLP_RDC_TABLE_VALID(table) \
64 ((table < NXGE_MAX_RDC_GRPS))
65 #define TCAM_L3_USR_CLASS_VALID(class) \
66 ((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_IP_USER_7))
67 #define TCAM_L2_USR_CLASS_VALID(class) \
68 ((class == TCAM_CLASS_ETYPE_1) || (class == TCAM_CLASS_ETYPE_2))
69 #define TCAM_L3_CLASS_VALID(class) \
70 ((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_SCTP_IPV6))
71 #define TCAM_L3_CLASS_VALID_RFNL(class) \
72 ((TCAM_L3_CLASS_VALID(class)) || class == TCAM_CLASS_IPV6_FRAG)
73 #define TCAM_CLASS_VALID(class) \
74 ((class >= TCAM_CLASS_ETYPE_1) && (class <= TCAM_CLASS_RARP))
75
76
77 uint64_t fflp_fzc_offset[] = {
78 FFLP_ENET_VLAN_TBL_REG, FFLP_L2_CLS_ENET1_REG, FFLP_L2_CLS_ENET2_REG,
79 FFLP_TCAM_KEY_IP_USR4_REG, FFLP_TCAM_KEY_IP_USR5_REG,
80 FFLP_TCAM_KEY_IP_USR6_REG, FFLP_TCAM_KEY_IP_USR7_REG,
81 FFLP_TCAM_KEY_IP4_TCP_REG, FFLP_TCAM_KEY_IP4_UDP_REG,
82 FFLP_TCAM_KEY_IP4_AH_ESP_REG, FFLP_TCAM_KEY_IP4_SCTP_REG,
83 FFLP_TCAM_KEY_IP6_TCP_REG, FFLP_TCAM_KEY_IP6_UDP_REG,
84 FFLP_TCAM_KEY_IP6_AH_ESP_REG, FFLP_TCAM_KEY_IP6_SCTP_REG,
85 FFLP_TCAM_KEY_0_REG, FFLP_TCAM_KEY_1_REG, FFLP_TCAM_KEY_2_REG,
86 FFLP_TCAM_KEY_3_REG, FFLP_TCAM_MASK_0_REG, FFLP_TCAM_MASK_1_REG,
87 FFLP_TCAM_MASK_2_REG, FFLP_TCAM_MASK_3_REG, FFLP_TCAM_CTL_REG,
88 FFLP_VLAN_PAR_ERR_REG, FFLP_TCAM_ERR_REG, HASH_LKUP_ERR_LOG1_REG,
89 HASH_LKUP_ERR_LOG2_REG, FFLP_FCRAM_ERR_TST0_REG,
90 FFLP_FCRAM_ERR_TST1_REG, FFLP_FCRAM_ERR_TST2_REG, FFLP_ERR_MSK_REG,
91 FFLP_CFG_1_REG, FFLP_DBG_TRAIN_VCT_REG, FFLP_TCP_CFLAG_MSK_REG,
92 FFLP_FCRAM_REF_TMR_REG, FFLP_FLOW_KEY_IP_USR4_REG,
93 FFLP_FLOW_KEY_IP_USR5_REG, FFLP_FLOW_KEY_IP_USR6_REG,
94 FFLP_FLOW_KEY_IP_USR7_REG, FFLP_FLOW_KEY_IP4_TCP_REG,
95 FFLP_FLOW_KEY_IP4_UDP_REG, FFLP_FLOW_KEY_IP4_AH_ESP_REG,
96 FFLP_FLOW_KEY_IP4_SCTP_REG, FFLP_FLOW_KEY_IP6_TCP_REG,
97 FFLP_FLOW_KEY_IP6_UDP_REG, FFLP_FLOW_KEY_IP6_AH_ESP_REG,
98 FFLP_FLOW_KEY_IP6_SCTP_REG, FFLP_H1POLY_REG, FFLP_H2POLY_REG,
99 FFLP_FLW_PRT_SEL_REG
100 };
101
102 const char *fflp_fzc_name[] = {
103 "FFLP_ENET_VLAN_TBL_REG", "FFLP_L2_CLS_ENET1_REG",
104 "FFLP_L2_CLS_ENET2_REG", "FFLP_TCAM_KEY_IP_USR4_REG",
105 "FFLP_TCAM_KEY_IP_USR5_REG", "FFLP_TCAM_KEY_IP_USR6_REG",
106 "FFLP_TCAM_KEY_IP_USR7_REG", "FFLP_TCAM_KEY_IP4_TCP_REG",
107 "FFLP_TCAM_KEY_IP4_UDP_REG", "FFLP_TCAM_KEY_IP4_AH_ESP_REG",
108 "FFLP_TCAM_KEY_IP4_SCTP_REG", "FFLP_TCAM_KEY_IP6_TCP_REG",
109 "FFLP_TCAM_KEY_IP6_UDP_REG", "FFLP_TCAM_KEY_IP6_AH_ESP_REG",
110 "FFLP_TCAM_KEY_IP6_SCTP_REG", "FFLP_TCAM_KEY_0_REG",
111 "FFLP_TCAM_KEY_1_REG", "FFLP_TCAM_KEY_2_REG", "FFLP_TCAM_KEY_3_REG",
112 "FFLP_TCAM_MASK_0_REG", "FFLP_TCAM_MASK_1_REG", "FFLP_TCAM_MASK_2_REG",
113 "FFLP_TCAM_MASK_3_REG", "FFLP_TCAM_CTL_REG", "FFLP_VLAN_PAR_ERR_REG",
114 "FFLP_TCAM_ERR_REG", "HASH_LKUP_ERR_LOG1_REG",
115 "HASH_LKUP_ERR_LOG2_REG", "FFLP_FCRAM_ERR_TST0_REG",
116 "FFLP_FCRAM_ERR_TST1_REG", "FFLP_FCRAM_ERR_TST2_REG",
117 "FFLP_ERR_MSK_REG", "FFLP_CFG_1_REG", "FFLP_DBG_TRAIN_VCT_REG",
118 "FFLP_TCP_CFLAG_MSK_REG", "FFLP_FCRAM_REF_TMR_REG",
119 "FFLP_FLOW_KEY_IP_USR4_REG", "FFLP_FLOW_KEY_IP_USR5_REG",
120 "FFLP_FLOW_KEY_IP_USR6_REG", "FFLP_FLOW_KEY_IP_USR7_REG",
121 "FFLP_FLOW_KEY_IP4_TCP_REG", "FFLP_FLOW_KEY_IP4_UDP_REG",
122 "FFLP_FLOW_KEY_IP4_AH_ESP_REG", "FFLP_FLOW_KEY_IP4_SCTP_REG",
123 "FFLP_FLOW_KEY_IP6_TCP_REG", "FFLP_FLOW_KEY_IP6_UDP_REG",
124 "FFLP_FLOW_KEY_IP6_AH_ESP_REG",
125 "FFLP_FLOW_KEY_IP6_SCTP_REG", "FFLP_H1POLY_REG", "FFLP_H2POLY_REG",
126 "FFLP_FLW_PRT_SEL_REG"
127 };
128
129 uint64_t fflp_reg_offset[] = {
130 FFLP_HASH_TBL_ADDR_REG, FFLP_HASH_TBL_DATA_REG,
131 FFLP_HASH_TBL_DATA_LOG_REG
132 };
133
134 const char *fflp_reg_name[] = {
135 "FFLP_HASH_TBL_ADDR_REG", "FFLP_HASH_TBL_DATA_REG",
136 "FFLP_HASH_TBL_DATA_LOG_REG"
137 };
138
139
140
141
142 npi_status_t
npi_fflp_dump_regs(npi_handle_t handle)143 npi_fflp_dump_regs(npi_handle_t handle)
144 {
145
146 uint64_t value;
147 int num_regs, i;
148
149 num_regs = sizeof (fflp_fzc_offset) / sizeof (uint64_t);
150 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
151 "\nFFLP_FZC Register Dump \n"));
152 for (i = 0; i < num_regs; i++) {
153 REG_PIO_READ64(handle, fflp_fzc_offset[i], &value);
154 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
155 " %8llx %s\t %8llx \n",
156 fflp_fzc_offset[i], fflp_fzc_name[i], value));
157
158 }
159
160 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
161 "\nFFLP Register Dump\n"));
162 num_regs = sizeof (fflp_reg_offset) / sizeof (uint64_t);
163
164 for (i = 0; i < num_regs; i++) {
165 REG_PIO_READ64(handle, fflp_reg_offset[i], &value);
166 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
167 " %8llx %s\t %8llx \n",
168 fflp_reg_offset[i], fflp_reg_name[i], value));
169
170 }
171
172 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
173 "\n FFLP Register Dump done\n"));
174
175 return (NPI_SUCCESS);
176 }
177
178 void
npi_fflp_vlan_tbl_dump(npi_handle_t handle)179 npi_fflp_vlan_tbl_dump(npi_handle_t handle)
180 {
181 uint64_t offset;
182 vlan_id_t vlan_id;
183 uint64_t value;
184 vlan_id_t start = 0, stop = NXGE_MAX_VLANS;
185
186 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
187 "\nVlan Table Dump \n"));
188
189 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
190 "VID\t Offset\t Value\n"));
191
192 for (vlan_id = start; vlan_id < stop; vlan_id++) {
193 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
194 REG_PIO_READ64(handle, offset, &value);
195 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
196 "%x\t %llx\t %llx\n", vlan_id, offset, value));
197 }
198
199 }
200
201 static uint64_t
202 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type);
203
204 /*
205 * npi_fflp_tcam_check_completion()
206 * Returns TCAM completion status.
207 *
208 * Input:
209 * op_type : Read, Write, Compare
210 * handle : OS specific handle
211 *
212 * Output:
213 * For Read and write operations:
214 * 0 Successful
215 * -1 Fail/timeout
216 *
217 * For Compare operations (debug only )
218 * TCAM_REG_CTL read value on success
219 * value contains match location
220 * NPI_TCAM_COMP_NO_MATCH no match
221 *
222 */
223 static uint64_t
npi_fflp_tcam_check_completion(npi_handle_t handle,tcam_op_t op_type)224 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type)
225 {
226
227 uint32_t try_counter, tcam_delay = 10;
228 tcam_ctl_t tctl;
229
230 try_counter = TCAM_COMPLETION_TRY_COUNT;
231
232 switch (op_type) {
233 case TCAM_RWC_STAT:
234
235 READ_TCAM_REG_CTL(handle, &tctl.value);
236 while ((try_counter) &&
237 (tctl.bits.ldw.stat != TCAM_CTL_RWC_RWC_STAT)) {
238 try_counter--;
239 NXGE_DELAY(tcam_delay);
240 READ_TCAM_REG_CTL(handle, &tctl.value);
241 }
242
243 if (!try_counter) {
244 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
245 " TCAM RWC_STAT operation"
246 " failed to complete \n"));
247 return (NPI_FFLP_TCAM_HW_ERROR);
248 }
249
250 tctl.value = 0;
251 break;
252
253 case TCAM_RWC_MATCH:
254 READ_TCAM_REG_CTL(handle, &tctl.value);
255
256 while ((try_counter) &&
257 (tctl.bits.ldw.match != TCAM_CTL_RWC_RWC_MATCH)) {
258 try_counter--;
259 NXGE_DELAY(tcam_delay);
260 READ_TCAM_REG_CTL(handle, &tctl.value);
261 }
262
263 if (!try_counter) {
264 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
265 " TCAM Match operation"
266 "failed to find match \n"));
267 tctl.value = NPI_TCAM_COMP_NO_MATCH;
268 }
269
270
271 break;
272
273 default:
274 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
275 " Invalid TCAM completion Request \n"));
276 return (NPI_FFLP_ERROR |
277 NPI_TCAM_ERROR | OPCODE_INVALID);
278 }
279
280 return (tctl.value);
281 }
282
283 /*
284 * npi_fflp_tcam_entry_invalidate()
285 *
286 * invalidates entry at tcam location
287 *
288 * Input
289 * handle : OS specific handle
290 * location : TCAM location
291 *
292 * Return
293 * NPI_SUCCESS
294 * NPI_FFLP_TCAM_HW_ERROR
295 *
296 */
297 npi_status_t
npi_fflp_tcam_entry_invalidate(npi_handle_t handle,tcam_location_t location)298 npi_fflp_tcam_entry_invalidate(npi_handle_t handle, tcam_location_t location)
299 {
300
301 tcam_ctl_t tctl, tctl_stat;
302
303 /*
304 * Need to write zero to class field.
305 * Class field is bits [195:191].
306 * This corresponds to TCAM key 0 register
307 *
308 */
309
310
311 WRITE_TCAM_REG_MASK0(handle, 0xffULL);
312 WRITE_TCAM_REG_KEY0(handle, 0x0ULL);
313 tctl.value = 0;
314 tctl.bits.ldw.location = location;
315 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
316
317 WRITE_TCAM_REG_CTL(handle, tctl.value);
318
319 tctl_stat.value = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
320
321 if (tctl_stat.value & NPI_FAILURE)
322 return (NPI_FFLP_TCAM_HW_ERROR);
323
324 return (NPI_SUCCESS);
325
326 }
327
328 /*
329 * npi_fflp_tcam_entry_match()
330 *
331 * lookup a tcam entry in the TCAM
332 *
333 * Input
334 * handle : OS specific handle
335 * tcam_ptr : TCAM entry ptr
336 *
337 * Return
338 *
339 * NPI_FAILURE | NPI_XX_ERROR: Operational Error (HW etc ...)
340 * NPI_TCAM_NO_MATCH: no match
341 * 0 - TCAM_SIZE: matching entry location (if match)
342 */
343 int
npi_fflp_tcam_entry_match(npi_handle_t handle,tcam_entry_t * tcam_ptr)344 npi_fflp_tcam_entry_match(npi_handle_t handle, tcam_entry_t *tcam_ptr)
345 {
346
347 uint64_t tcam_stat = 0;
348 tcam_ctl_t tctl, tctl_stat;
349
350 WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
351 WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
352 WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
353 WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
354
355 WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
356 WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
357 WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
358 WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
359
360 tctl.value = 0;
361 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_CMP;
362
363 WRITE_TCAM_REG_CTL(handle, tctl.value);
364
365 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
366 if (tcam_stat & NPI_FAILURE) {
367 return ((uint32_t)tcam_stat);
368 }
369
370 tctl_stat.value = npi_fflp_tcam_check_completion(handle,
371 TCAM_RWC_MATCH);
372
373 if (tctl_stat.bits.ldw.match == TCAM_CTL_RWC_RWC_MATCH) {
374 return (uint32_t)(tctl_stat.bits.ldw.location);
375 }
376
377 return ((uint32_t)tctl_stat.value);
378
379 }
380
381 /*
382 * npi_fflp_tcam_entry_read ()
383 *
384 * Reads a tcam entry from the TCAM location, location
385 *
386 * Input:
387 * handle : OS specific handle
388 * location : TCAM location
389 * tcam_ptr : TCAM entry pointer
390 *
391 * Return:
392 * NPI_SUCCESS
393 * NPI_FFLP_TCAM_RD_ERROR
394 *
395 */
396 npi_status_t
npi_fflp_tcam_entry_read(npi_handle_t handle,tcam_location_t location,struct tcam_entry * tcam_ptr)397 npi_fflp_tcam_entry_read(npi_handle_t handle,
398 tcam_location_t location,
399 struct tcam_entry *tcam_ptr)
400 {
401
402 uint64_t tcam_stat;
403 tcam_ctl_t tctl;
404
405 tctl.value = 0;
406 tctl.bits.ldw.location = location;
407 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_RD;
408
409 WRITE_TCAM_REG_CTL(handle, tctl.value);
410
411 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
412
413 if (tcam_stat & NPI_FAILURE) {
414 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
415 "TCAM read failed loc %d \n", location));
416 return (NPI_FFLP_TCAM_RD_ERROR);
417 }
418
419 READ_TCAM_REG_MASK0(handle, &tcam_ptr->mask0);
420 READ_TCAM_REG_MASK1(handle, &tcam_ptr->mask1);
421 READ_TCAM_REG_MASK2(handle, &tcam_ptr->mask2);
422 READ_TCAM_REG_MASK3(handle, &tcam_ptr->mask3);
423
424 READ_TCAM_REG_KEY0(handle, &tcam_ptr->key0);
425 READ_TCAM_REG_KEY1(handle, &tcam_ptr->key1);
426 READ_TCAM_REG_KEY2(handle, &tcam_ptr->key2);
427 READ_TCAM_REG_KEY3(handle, &tcam_ptr->key3);
428
429 return (NPI_SUCCESS);
430 }
431
432 /*
433 * npi_fflp_tcam_entry_write()
434 *
435 * writes a tcam entry to the TCAM location, location
436 *
437 * Input:
438 * handle : OS specific handle
439 * location : TCAM location
440 * tcam_ptr : TCAM entry pointer
441 *
442 * Return:
443 * NPI_SUCCESS
444 * NPI_FFLP_TCAM_WR_ERROR
445 *
446 */
447 npi_status_t
npi_fflp_tcam_entry_write(npi_handle_t handle,tcam_location_t location,tcam_entry_t * tcam_ptr)448 npi_fflp_tcam_entry_write(npi_handle_t handle,
449 tcam_location_t location,
450 tcam_entry_t *tcam_ptr)
451 {
452
453 uint64_t tcam_stat;
454
455 tcam_ctl_t tctl;
456
457 WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0);
458 WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1);
459 WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2);
460 WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3);
461
462 WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0);
463 WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1);
464 WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2);
465 WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3);
466
467 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
468 " tcam write: location %x\n"
469 " key: %llx %llx %llx %llx \n"
470 " mask: %llx %llx %llx %llx \n",
471 location, tcam_ptr->key0, tcam_ptr->key1,
472 tcam_ptr->key2, tcam_ptr->key3,
473 tcam_ptr->mask0, tcam_ptr->mask1,
474 tcam_ptr->mask2, tcam_ptr->mask3));
475 tctl.value = 0;
476 tctl.bits.ldw.location = location;
477 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR;
478 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
479 " tcam write: ctl value %llx \n", tctl.value));
480 WRITE_TCAM_REG_CTL(handle, tctl.value);
481
482 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
483
484 if (tcam_stat & NPI_FAILURE) {
485 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
486 "TCAM Write failed loc %d \n", location));
487 return (NPI_FFLP_TCAM_WR_ERROR);
488 }
489
490 return (NPI_SUCCESS);
491 }
492
493 /*
494 * npi_fflp_tcam_asc_ram_entry_write()
495 *
496 * writes a tcam associatedRAM at the TCAM location, location
497 *
498 * Input:
499 * handle : OS specific handle
500 * location : tcam associatedRAM location
501 * ram_data : Value to write
502 *
503 * Return:
504 * NPI_SUCCESS
505 * NPI_FFLP_ASC_RAM_WR_ERROR
506 *
507 */
508 npi_status_t
npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle,tcam_location_t location,uint64_t ram_data)509 npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle,
510 tcam_location_t location,
511 uint64_t ram_data)
512 {
513
514 uint64_t tcam_stat = 0;
515 tcam_ctl_t tctl;
516
517
518 WRITE_TCAM_REG_KEY1(handle, ram_data);
519
520 tctl.value = 0;
521 tctl.bits.ldw.location = location;
522 tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_WR;
523
524 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
525 " tcam ascr write: location %x data %llx ctl value %llx \n",
526 location, ram_data, tctl.value));
527 WRITE_TCAM_REG_CTL(handle, tctl.value);
528 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
529
530 if (tcam_stat & NPI_FAILURE) {
531 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
532 "TCAM RAM write failed loc %d \n", location));
533 return (NPI_FFLP_ASC_RAM_WR_ERROR);
534 }
535
536 return (NPI_SUCCESS);
537 }
538
539 /*
540 * npi_fflp_tcam_asc_ram_entry_read()
541 *
542 * reads a tcam associatedRAM content at the TCAM location, location
543 *
544 * Input:
545 * handle : OS specific handle
546 * location : tcam associatedRAM location
547 * ram_data : ptr to return contents
548 *
549 * Return:
550 * NPI_SUCCESS
551 * NPI_FFLP_ASC_RAM_RD_ERROR
552 *
553 */
554 npi_status_t
npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle,tcam_location_t location,uint64_t * ram_data)555 npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle,
556 tcam_location_t location,
557 uint64_t *ram_data)
558 {
559
560 uint64_t tcam_stat;
561 tcam_ctl_t tctl;
562
563
564 tctl.value = 0;
565 tctl.bits.ldw.location = location;
566 tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_RD;
567
568 WRITE_TCAM_REG_CTL(handle, tctl.value);
569
570 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT);
571
572 if (tcam_stat & NPI_FAILURE) {
573 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
574 "TCAM RAM read failed loc %d \n", location));
575 return (NPI_FFLP_ASC_RAM_RD_ERROR);
576 }
577
578 READ_TCAM_REG_KEY1(handle, ram_data);
579
580 return (NPI_SUCCESS);
581 }
582
583 /* FFLP FCRAM Related functions */
584 /* The following are FCRAM datapath functions */
585
586 /*
587 * npi_fflp_fcram_entry_write ()
588 * Populates an FCRAM entry
589 * Inputs:
590 * handle: opaque handle interpreted by the underlying OS
591 * partid: Partition ID
592 * location: Index to the FCRAM.
593 * Corresponds to last 20 bits of H1 value
594 * fcram_ptr: Pointer to the FCRAM contents to be used for writing
595 * format: Entry Format. Determines the size of the write.
596 * FCRAM_ENTRY_OPTIM: 8 bytes (a 64 bit write)
597 * FCRAM_ENTRY_EX_IP4: 32 bytes (4 X 64 bit write)
598 * FCRAM_ENTRY_EX_IP6: 56 bytes (7 X 64 bit write)
599 *
600 * Outputs:
601 * NPI success/failure status code
602 */
603 npi_status_t
npi_fflp_fcram_entry_write(npi_handle_t handle,part_id_t partid,uint32_t location,fcram_entry_t * fcram_ptr,fcram_entry_format_t format)604 npi_fflp_fcram_entry_write(npi_handle_t handle, part_id_t partid,
605 uint32_t location, fcram_entry_t *fcram_ptr,
606 fcram_entry_format_t format)
607
608 {
609
610 int num_subareas = 0;
611 uint64_t addr_reg, data_reg;
612 int subarea;
613 int autoinc;
614 hash_tbl_addr_t addr;
615 switch (format) {
616 case FCRAM_ENTRY_OPTIM:
617 if (location % 8) {
618 /* need to be 8 byte aligned */
619
620 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
621 " FCRAM_ENTRY_OOPTIM Write:"
622 " unaligned location %llx \n",
623 location));
624
625 return (NPI_FFLP_FCRAM_LOC_INVALID);
626 }
627
628 num_subareas = 1;
629 autoinc = 0;
630 break;
631
632 case FCRAM_ENTRY_EX_IP4:
633 if (location % 32) {
634 /* need to be 32 byte aligned */
635 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
636 " FCRAM_ENTRY_EX_IP4 Write:"
637 " unaligned location %llx \n",
638 location));
639 return (NPI_FFLP_FCRAM_LOC_INVALID);
640 }
641
642 num_subareas = 4;
643 autoinc = 1;
644
645 break;
646 case FCRAM_ENTRY_EX_IP6:
647 if (location % 64) {
648 /* need to be 64 byte aligned */
649 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
650 " FCRAM_ENTRY_EX_IP6 Write:"
651 " unaligned location %llx \n",
652 location));
653 return (NPI_FFLP_FCRAM_LOC_INVALID);
654
655 }
656 num_subareas = 7;
657 autoinc = 1;
658 break;
659 default:
660 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
661 " fcram_entry_write:"
662 " unknown format param location %llx\n",
663 location));
664 return (NPI_FFLP_ERROR | NPI_FCRAM_ERROR | OPCODE_INVALID);
665 }
666
667 addr.value = 0;
668 addr.bits.ldw.autoinc = autoinc;
669 addr.bits.ldw.addr = location;
670 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
671 FFLP_HASH_TBL_ADDR_REG);
672 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
673 FFLP_HASH_TBL_DATA_REG);
674 /* write to addr reg */
675 REG_PIO_WRITE64(handle, addr_reg, addr.value);
676 /* write data to the data register */
677
678 for (subarea = 0; subarea < num_subareas; subarea++) {
679 REG_PIO_WRITE64(handle, data_reg, fcram_ptr->value[subarea]);
680 }
681
682 return (NPI_SUCCESS);
683 }
684
685 /*
686 * npi_fflp_fcram_read_read ()
687 * Reads an FCRAM entry
688 * Inputs:
689 * handle: opaque handle interpreted by the underlying OS
690 * partid: Partition ID
691 * location: Index to the FCRAM.
692 * Corresponds to last 20 bits of H1 value
693 *
694 * fcram_ptr: Pointer to the FCRAM contents to be updated
695 * format: Entry Format. Determines the size of the read.
696 * FCRAM_ENTRY_OPTIM: 8 bytes (a 64 bit read)
697 * FCRAM_ENTRY_EX_IP4: 32 bytes (4 X 64 bit read )
698 * FCRAM_ENTRY_EX_IP6: 56 bytes (7 X 64 bit read )
699 * Return:
700 * NPI Success/Failure status code
701 *
702 */
703 npi_status_t
npi_fflp_fcram_entry_read(npi_handle_t handle,part_id_t partid,uint32_t location,fcram_entry_t * fcram_ptr,fcram_entry_format_t format)704 npi_fflp_fcram_entry_read(npi_handle_t handle, part_id_t partid,
705 uint32_t location, fcram_entry_t *fcram_ptr,
706 fcram_entry_format_t format)
707 {
708
709 int num_subareas = 0;
710 uint64_t addr_reg, data_reg;
711 int subarea, autoinc;
712 hash_tbl_addr_t addr;
713 switch (format) {
714 case FCRAM_ENTRY_OPTIM:
715 if (location % 8) {
716 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
717 " FCRAM_ENTRY_OOPTIM Read:"
718 " unaligned location %llx \n",
719 location));
720 /* need to be 8 byte aligned */
721 return (NPI_FFLP_FCRAM_LOC_INVALID);
722 }
723 num_subareas = 1;
724 autoinc = 0;
725 break;
726 case FCRAM_ENTRY_EX_IP4:
727 if (location % 32) {
728 /* need to be 32 byte aligned */
729 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
730 " FCRAM_ENTRY_EX_IP4 READ:"
731 " unaligned location %llx \n",
732 location));
733 return (NPI_FFLP_FCRAM_LOC_INVALID);
734 }
735 num_subareas = 4;
736 autoinc = 1;
737
738 break;
739 case FCRAM_ENTRY_EX_IP6:
740 if (location % 64) {
741 /* need to be 64 byte aligned */
742 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
743 " FCRAM_ENTRY_EX_IP6 READ:"
744 " unaligned location %llx \n",
745 location));
746
747 return (NPI_FFLP_FCRAM_LOC_INVALID);
748 }
749 num_subareas = 7;
750 autoinc = 1;
751
752 break;
753 default:
754 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
755 " fcram_entry_read:"
756 " unknown format param location %llx\n",
757 location));
758 return (NPI_FFLP_SW_PARAM_ERROR);
759 }
760
761 addr.value = 0;
762 addr.bits.ldw.autoinc = autoinc;
763 addr.bits.ldw.addr = location;
764 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
765 FFLP_HASH_TBL_ADDR_REG);
766 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
767 FFLP_HASH_TBL_DATA_REG);
768 /* write to addr reg */
769 REG_PIO_WRITE64(handle, addr_reg, addr.value);
770 /* read data from the data register */
771 for (subarea = 0; subarea < num_subareas; subarea++) {
772 REG_PIO_READ64(handle, data_reg, &fcram_ptr->value[subarea]);
773 }
774
775
776 return (NPI_SUCCESS);
777
778 }
779
780 /*
781 * npi_fflp_fcram_entry_invalidate ()
782 * Invalidate FCRAM entry at the given location
783 * Inputs:
784 * handle: opaque handle interpreted by the underlying OS
785 * partid: Partition ID
786 * location: location of the FCRAM/hash entry.
787 *
788 * Return:
789 * NPI Success/Failure status code
790 */
791 npi_status_t
npi_fflp_fcram_entry_invalidate(npi_handle_t handle,part_id_t partid,uint32_t location)792 npi_fflp_fcram_entry_invalidate(npi_handle_t handle, part_id_t partid,
793 uint32_t location)
794 {
795
796 hash_tbl_addr_t addr;
797 uint64_t addr_reg, data_reg;
798 hash_hdr_t hdr;
799
800
801 if (location % 8) {
802 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
803 " FCRAM_ENTRY_Invalidate:"
804 " unaligned location %llx \n",
805 location));
806 /* need to be 8 byte aligned */
807 return (NPI_FFLP_FCRAM_LOC_INVALID);
808 }
809
810 addr.value = 0;
811 addr.bits.ldw.addr = location;
812 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
813 FFLP_HASH_TBL_ADDR_REG);
814 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
815 FFLP_HASH_TBL_DATA_REG);
816
817 /* write to addr reg */
818 REG_PIO_WRITE64(handle, addr_reg, addr.value);
819
820 REG_PIO_READ64(handle, data_reg, &hdr.value);
821 hdr.exact_hdr.valid = 0;
822 REG_PIO_WRITE64(handle, data_reg, hdr.value);
823
824 return (NPI_SUCCESS);
825
826 }
827
828 /*
829 * npi_fflp_fcram_write_subarea ()
830 * Writes to FCRAM entry subarea i.e the 8 bytes within the 64 bytes
831 * pointed by the last 20 bits of H1. Effectively, this accesses
832 * specific 8 bytes within the hash table bucket.
833 *
834 * H1--> |-----------------|
835 * | subarea 0 |
836 * |_________________|
837 * | Subarea 1 |
838 * |_________________|
839 * | ....... |
840 * |_________________|
841 * | Subarea 7 |
842 * |_________________|
843 *
844 * Inputs:
845 * handle: opaque handle interpreted by the underlying OS
846 * partid: Partition ID
847 * location: location of the subarea. It is derived from:
848 * Bucket = [19:15][14:0] (20 bits of H1)
849 * location = (Bucket << 3 ) + subarea * 8
850 * = [22:18][17:3] || subarea * 8
851 * data: Data
852 *
853 * Return:
854 * NPI Success/Failure status code
855 */
856 npi_status_t
npi_fflp_fcram_subarea_write(npi_handle_t handle,part_id_t partid,uint32_t location,uint64_t data)857 npi_fflp_fcram_subarea_write(npi_handle_t handle, part_id_t partid,
858 uint32_t location, uint64_t data)
859 {
860
861 hash_tbl_addr_t addr;
862 uint64_t addr_reg, data_reg;
863
864
865 if (location % 8) {
866 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
867 " fcram_subarea_write:"
868 " unaligned location %llx \n",
869 location));
870 /* need to be 8 byte aligned */
871 return (NPI_FFLP_FCRAM_LOC_INVALID);
872 }
873
874 addr.value = 0;
875 addr.bits.ldw.addr = location;
876 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
877 FFLP_HASH_TBL_ADDR_REG);
878 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
879 FFLP_HASH_TBL_DATA_REG);
880
881 /* write to addr reg */
882 REG_PIO_WRITE64(handle, addr_reg, addr.value);
883 REG_PIO_WRITE64(handle, data_reg, data);
884
885 return (NPI_SUCCESS);
886
887 }
888
889 /*
890 * npi_fflp_fcram_subarea_read ()
891 * Reads an FCRAM entry subarea i.e the 8 bytes within the 64 bytes
892 * pointed by the last 20 bits of H1. Effectively, this accesses
893 * specific 8 bytes within the hash table bucket.
894 *
895 * H1--> |-----------------|
896 * | subarea 0 |
897 * |_________________|
898 * | Subarea 1 |
899 * |_________________|
900 * | ....... |
901 * |_________________|
902 * | Subarea 7 |
903 * |_________________|
904 *
905 * Inputs:
906 * handle: opaque handle interpreted by the underlying OS
907 * partid: Partition ID
908 * location: location of the subarea. It is derived from:
909 * Bucket = [19:15][14:0] (20 bits of H1)
910 * location = (Bucket << 3 ) + subarea * 8
911 * = [22:18][17:3] || subarea * 8
912 * data: ptr do write subarea contents to.
913 *
914 * Return:
915 * NPI Success/Failure status code
916 */
917 npi_status_t
npi_fflp_fcram_subarea_read(npi_handle_t handle,part_id_t partid,uint32_t location,uint64_t * data)918 npi_fflp_fcram_subarea_read(npi_handle_t handle, part_id_t partid,
919 uint32_t location, uint64_t *data)
920
921 {
922
923 hash_tbl_addr_t addr;
924 uint64_t addr_reg, data_reg;
925
926 if (location % 8) {
927 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
928 " fcram_subarea_read:"
929 " unaligned location %llx \n",
930 location));
931 /* need to be 8 byte aligned */
932 return (NPI_FFLP_FCRAM_LOC_INVALID);
933 }
934
935 addr.value = 0;
936 addr.bits.ldw.addr = location;
937 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
938 FFLP_HASH_TBL_ADDR_REG);
939 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid,
940 FFLP_HASH_TBL_DATA_REG);
941
942 /* write to addr reg */
943 REG_PIO_WRITE64(handle, addr_reg, addr.value);
944 REG_PIO_READ64(handle, data_reg, data);
945
946 return (NPI_SUCCESS);
947
948 }
949
950 /*
951 * The following are zero function fflp configuration functions.
952 */
953
954 /*
955 * npi_fflp_fcram_config_partition()
956 * Partitions and configures the FCRAM
957 */
958 npi_status_t
npi_fflp_cfg_fcram_partition(npi_handle_t handle,part_id_t partid,uint8_t base_mask,uint8_t base_reloc)959 npi_fflp_cfg_fcram_partition(npi_handle_t handle, part_id_t partid,
960 uint8_t base_mask, uint8_t base_reloc)
961 {
962 /*
963 * assumes that the base mask and relocation are computed somewhere
964 * and kept in the state data structure. Alternativiely, one can pass
965 * a partition size and a starting address and this routine can compute
966 * the mask and reloc vlaues.
967 */
968
969 flow_prt_sel_t sel;
970 uint64_t offset;
971
972 ASSERT(FCRAM_PARTITION_VALID(partid));
973 if (!FCRAM_PARTITION_VALID(partid)) {
974 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
975 " npi_fflp_cfg_fcram_partition:"
976 " Invalid Partition %d \n",
977 partid));
978 return (NPI_FFLP_FCRAM_PART_INVALID);
979 }
980
981 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
982 sel.value = 0;
983 sel.bits.ldw.mask = base_mask;
984 sel.bits.ldw.base = base_reloc;
985 sel.bits.ldw.ext = BIT_DISABLE; /* disable */
986 REG_PIO_WRITE64(handle, offset, sel.value);
987 return (NPI_SUCCESS);
988 }
989
990 /*
991 * npi_fflp_fcram_partition_enable
992 * Enable previously configured FCRAM partition
993 *
994 * Input
995 * handle: opaque handle interpreted by the underlying OS
996 * partid: partition ID, Corresponds to the RDC table
997 *
998 * Return
999 * 0 Successful
1000 * Non zero error code Enable failed, and reason.
1001 *
1002 */
1003 npi_status_t
npi_fflp_cfg_fcram_partition_enable(npi_handle_t handle,part_id_t partid)1004 npi_fflp_cfg_fcram_partition_enable (npi_handle_t handle, part_id_t partid)
1005
1006 {
1007
1008 flow_prt_sel_t sel;
1009 uint64_t offset;
1010
1011 ASSERT(FCRAM_PARTITION_VALID(partid));
1012 if (!FCRAM_PARTITION_VALID(partid)) {
1013 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1014 " fcram_partition enable:"
1015 " Invalid Partition %d \n",
1016 partid));
1017 return (NPI_FFLP_FCRAM_PART_INVALID);
1018 }
1019
1020 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
1021
1022 REG_PIO_READ64(handle, offset, &sel.value);
1023 sel.bits.ldw.ext = BIT_ENABLE; /* enable */
1024 REG_PIO_WRITE64(handle, offset, sel.value);
1025
1026 return (NPI_SUCCESS);
1027
1028 }
1029
1030 /*
1031 * npi_fflp_fcram_partition_disable
1032 * Disable previously configured FCRAM partition
1033 *
1034 * Input
1035 * handle: opaque handle interpreted by the underlying OS
1036 * partid: partition ID, Corresponds to the RDC table
1037 *
1038 * Return:
1039 * NPI Success/Failure status code
1040 */
1041 npi_status_t
npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle,part_id_t partid)1042 npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid)
1043
1044 {
1045
1046 flow_prt_sel_t sel;
1047 uint64_t offset;
1048
1049 ASSERT(FCRAM_PARTITION_VALID(partid));
1050 if (!FCRAM_PARTITION_VALID(partid)) {
1051 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1052 " fcram_partition disable:"
1053 " Invalid Partition %d \n",
1054 partid));
1055 return (NPI_FFLP_FCRAM_PART_INVALID);
1056 }
1057 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
1058 REG_PIO_READ64(handle, offset, &sel.value);
1059 sel.bits.ldw.ext = BIT_DISABLE; /* disable */
1060 REG_PIO_WRITE64(handle, offset, sel.value);
1061 return (NPI_SUCCESS);
1062 }
1063
1064 /*
1065 * npi_fflp_cam_errorcheck_disable
1066 * Disables FCRAM and TCAM error checking
1067 */
1068 npi_status_t
npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)1069 npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)
1070
1071 {
1072
1073 fflp_cfg_1_t fflp_cfg;
1074 uint64_t offset;
1075 offset = FFLP_CFG_1_REG;
1076
1077 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1078
1079 fflp_cfg.bits.ldw.errordis = BIT_ENABLE;
1080 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1081
1082 return (NPI_SUCCESS);
1083
1084 }
1085
1086 /*
1087 * npi_fflp_cam_errorcheck_enable
1088 * Enables FCRAM and TCAM error checking
1089 */
1090 npi_status_t
npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)1091 npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)
1092
1093 {
1094 fflp_cfg_1_t fflp_cfg;
1095 uint64_t offset;
1096 offset = FFLP_CFG_1_REG;
1097
1098 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1099
1100 fflp_cfg.bits.ldw.errordis = BIT_DISABLE;
1101 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1102
1103 return (NPI_SUCCESS);
1104
1105 }
1106
1107 /*
1108 * npi_fflp_cam_llcsnap_enable
1109 * Enables input parser llcsnap recognition
1110 */
1111 npi_status_t
npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)1112 npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)
1113
1114 {
1115
1116 fflp_cfg_1_t fflp_cfg;
1117 uint64_t offset;
1118 offset = FFLP_CFG_1_REG;
1119
1120 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1121
1122 fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE;
1123 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1124
1125 return (NPI_SUCCESS);
1126
1127 }
1128
1129 /*
1130 * npi_fflp_cam_llcsnap_disable
1131 * Disables input parser llcsnap recognition
1132 */
1133 npi_status_t
npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)1134 npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)
1135
1136 {
1137
1138
1139 fflp_cfg_1_t fflp_cfg;
1140 uint64_t offset;
1141 offset = FFLP_CFG_1_REG;
1142
1143 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1144
1145 fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE;
1146 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1147
1148 return (NPI_SUCCESS);
1149
1150 }
1151
1152 /*
1153 * npi_fflp_config_fcram_refresh
1154 * Set FCRAM min and max refresh time.
1155 *
1156 * Input
1157 * handle opaque handle interpreted by the underlying OS
1158 * min_time Minimum Refresh time count
1159 * max_time maximum Refresh Time count
1160 * sys_time System Clock rate
1161 *
1162 * The counters are 16 bit counters. The maximum refresh time is
1163 * 3.9us/clock cycle. The minimum is 400ns/clock cycle.
1164 * Clock cycle is the FCRAM clock cycle?????
1165 * If the cycle is FCRAM clock cycle, then sys_time parameter
1166 * is not needed as there wont be configuration variation due to
1167 * system clock cycle.
1168 *
1169 * Return:
1170 * NPI Success/Failure status code
1171 */
1172 npi_status_t
npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle,uint32_t min_time,uint32_t max_time,uint32_t sys_time)1173 npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time,
1174 uint32_t max_time, uint32_t sys_time)
1175
1176 {
1177
1178 uint64_t offset;
1179 fcram_ref_tmr_t refresh_timer_reg;
1180 uint16_t max, min;
1181
1182 offset = FFLP_FCRAM_REF_TMR_REG;
1183 /* need to figure out how to dervive the numbers */
1184 max = max_time * sys_time;
1185 min = min_time * sys_time;
1186 /* for now, just set with #def values */
1187
1188 max = FCRAM_REFRESH_DEFAULT_MAX_TIME;
1189 min = FCRAM_REFRESH_DEFAULT_MIN_TIME;
1190 REG_PIO_READ64(handle, offset, &refresh_timer_reg.value);
1191 refresh_timer_reg.bits.ldw.min = min;
1192 refresh_timer_reg.bits.ldw.max = max;
1193 REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value);
1194 return (NPI_SUCCESS);
1195 }
1196
1197 /*
1198 * npi_fflp_hash_lookup_err_report
1199 * Reports hash table (fcram) lookup errors
1200 *
1201 * Input
1202 * handle opaque handle interpreted by the underlying OS
1203 * err_stat Pointer to return Error bits
1204 *
1205 *
1206 * Return:
1207 * NPI success/failure status code
1208 */
1209 npi_status_t
npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,hash_lookup_err_log_t * err_stat)1210 npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,
1211 hash_lookup_err_log_t *err_stat)
1212
1213 {
1214
1215 hash_lookup_err_log1_t err_log1;
1216 hash_lookup_err_log2_t err_log2;
1217 uint64_t err_log1_offset, err_log2_offset;
1218 err_log1.value = 0;
1219 err_log2.value = 0;
1220
1221 err_log1_offset = HASH_LKUP_ERR_LOG1_REG;
1222 err_log2_offset = HASH_LKUP_ERR_LOG2_REG;
1223
1224 REG_PIO_READ64(handle, err_log1_offset, &err_log1.value);
1225 REG_PIO_READ64(handle, err_log2_offset, &err_log2.value);
1226
1227 if (err_log1.value) {
1228 /* nonzero means there are some errors */
1229 err_stat->lookup_err = BIT_ENABLE;
1230 err_stat->syndrome = err_log2.bits.ldw.syndrome;
1231 err_stat->subarea = err_log2.bits.ldw.subarea;
1232 err_stat->h1 = err_log2.bits.ldw.h1;
1233 err_stat->multi_bit = err_log1.bits.ldw.mult_bit;
1234 err_stat->multi_lkup = err_log1.bits.ldw.mult_lk;
1235 err_stat->ecc_err = err_log1.bits.ldw.ecc_err;
1236 err_stat->uncor_err = err_log1.bits.ldw.cu;
1237 } else {
1238 err_stat->lookup_err = BIT_DISABLE;
1239 }
1240
1241 return (NPI_SUCCESS);
1242
1243 }
1244
1245 /*
1246 * npi_fflp_fcram_get_pio_err_log
1247 * Reports hash table PIO read errors for the given partition.
1248 * by default, it clears the error bit which was set by the HW.
1249 *
1250 * Input
1251 * handle: opaque handle interpreted by the underlying OS
1252 * partid: partition ID
1253 * err_stat Pointer to return Error bits
1254 *
1255 * Return
1256 * NPI success/failure status code
1257 */
1258 npi_status_t
npi_fflp_fcram_get_pio_err_log(npi_handle_t handle,part_id_t partid,hash_pio_err_log_t * err_stat)1259 npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid,
1260 hash_pio_err_log_t *err_stat)
1261 {
1262
1263 hash_tbl_data_log_t err_log;
1264 uint64_t offset;
1265
1266 ASSERT(FCRAM_PARTITION_VALID(partid));
1267 if (!FCRAM_PARTITION_VALID(partid)) {
1268 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1269 " fcram_get_pio_err_log:"
1270 " Invalid Partition %d \n",
1271 partid));
1272 return (NPI_FFLP_FCRAM_PART_INVALID);
1273 }
1274
1275 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
1276 FFLP_HASH_TBL_DATA_LOG_REG);
1277
1278 REG_PIO_READ64(handle, offset, &err_log.value);
1279
1280 if (err_log.bits.ldw.pio_err == BIT_ENABLE) {
1281 /* nonzero means there are some errors */
1282 err_stat->pio_err = BIT_ENABLE;
1283 err_stat->syndrome = err_log.bits.ldw.syndrome;
1284 err_stat->addr = err_log.bits.ldw.fcram_addr;
1285 err_log.value = 0;
1286 REG_PIO_WRITE64(handle, offset, err_log.value);
1287 } else {
1288 err_stat->pio_err = BIT_DISABLE;
1289 }
1290
1291 return (NPI_SUCCESS);
1292
1293 }
1294
1295 /*
1296 * npi_fflp_fcram_clr_pio_err_log
1297 * Clears FCRAM PIO error status for the partition.
1298 * If there are TCAM errors as indicated by err bit set by HW,
1299 * then the SW will clear it by clearing the bit.
1300 *
1301 * Input
1302 * handle: opaque handle interpreted by the underlying OS
1303 * partid: partition ID
1304 *
1305 *
1306 * Return
1307 * NPI success/failure status code
1308 */
1309 npi_status_t
npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle,part_id_t partid)1310 npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid)
1311 {
1312 uint64_t offset;
1313
1314 hash_tbl_data_log_t err_log;
1315
1316 ASSERT(FCRAM_PARTITION_VALID(partid));
1317 if (!FCRAM_PARTITION_VALID(partid)) {
1318 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1319 " fcram_clr_pio_err_log:"
1320 " Invalid Partition %d \n",
1321 partid));
1322
1323 return (NPI_FFLP_FCRAM_PART_INVALID);
1324 }
1325
1326 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
1327 FFLP_HASH_TBL_DATA_LOG_REG);
1328
1329 err_log.value = 0;
1330 REG_PIO_WRITE64(handle, offset, err_log.value);
1331
1332
1333 return (NPI_SUCCESS);
1334
1335 }
1336
1337 /*
1338 * npi_fflp_tcam_get_err_log
1339 * Reports TCAM PIO read and lookup errors.
1340 * If there are TCAM errors as indicated by err bit set by HW,
1341 * then the SW will clear it by clearing the bit.
1342 *
1343 * Input
1344 * handle: opaque handle interpreted by the underlying OS
1345 * err_stat: structure to report various TCAM errors.
1346 * will be updated if there are TCAM errors.
1347 *
1348 *
1349 * Return
1350 * NPI_SUCCESS Success
1351 *
1352 *
1353 */
1354 npi_status_t
npi_fflp_tcam_get_err_log(npi_handle_t handle,tcam_err_log_t * err_stat)1355 npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat)
1356 {
1357 tcam_err_t err_log;
1358 uint64_t offset;
1359
1360 offset = FFLP_TCAM_ERR_REG;
1361 err_log.value = 0;
1362
1363 REG_PIO_READ64(handle, offset, &err_log.value);
1364
1365 if (err_log.bits.ldw.err == BIT_ENABLE) {
1366 /* non-zero means err */
1367 err_stat->tcam_err = BIT_ENABLE;
1368 if (err_log.bits.ldw.p_ecc) {
1369 err_stat->parity_err = 0;
1370 err_stat->ecc_err = 1;
1371 } else {
1372 err_stat->parity_err = 1;
1373 err_stat->ecc_err = 0;
1374
1375 }
1376 err_stat->syndrome = err_log.bits.ldw.syndrome;
1377 err_stat->location = err_log.bits.ldw.addr;
1378
1379
1380 err_stat->multi_lkup = err_log.bits.ldw.mult;
1381 /* now clear the error */
1382 err_log.value = 0;
1383 REG_PIO_WRITE64(handle, offset, err_log.value);
1384
1385 } else {
1386 err_stat->tcam_err = 0;
1387 }
1388 return (NPI_SUCCESS);
1389
1390 }
1391
1392 /*
1393 * npi_fflp_tcam_clr_err_log
1394 * Clears TCAM PIO read and lookup error status.
1395 * If there are TCAM errors as indicated by err bit set by HW,
1396 * then the SW will clear it by clearing the bit.
1397 *
1398 * Input
1399 * handle: opaque handle interpreted by the underlying OS
1400 *
1401 *
1402 * Return
1403 * NPI_SUCCESS Success
1404 *
1405 *
1406 */
1407 npi_status_t
npi_fflp_tcam_clr_err_log(npi_handle_t handle)1408 npi_fflp_tcam_clr_err_log(npi_handle_t handle)
1409 {
1410 tcam_err_t err_log;
1411 uint64_t offset;
1412
1413 offset = FFLP_TCAM_ERR_REG;
1414 err_log.value = 0;
1415 REG_PIO_WRITE64(handle, offset, err_log.value);
1416
1417 return (NPI_SUCCESS);
1418
1419 }
1420
1421 /*
1422 * npi_fflp_fcram_err_synd_test
1423 * Tests the FCRAM error detection logic.
1424 * The error detection logic for the syndrome is tested.
1425 * tst0->synd (8bits) are set to select the syndrome bits
1426 * to be XOR'ed
1427 *
1428 * Input
1429 * handle: opaque handle interpreted by the underlying OS
1430 * syndrome_bits: Syndrome bits to select bits to be xor'ed
1431 *
1432 *
1433 * Return
1434 * NPI_SUCCESS Success
1435 *
1436 *
1437 */
1438 npi_status_t
npi_fflp_fcram_err_synd_test(npi_handle_t handle,uint8_t syndrome_bits)1439 npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits)
1440 {
1441
1442 uint64_t t0_offset;
1443 fcram_err_tst0_t tst0;
1444 t0_offset = FFLP_FCRAM_ERR_TST0_REG;
1445
1446 tst0.value = 0;
1447 tst0.bits.ldw.syndrome_mask = syndrome_bits;
1448
1449 REG_PIO_WRITE64(handle, t0_offset, tst0.value);
1450
1451 return (NPI_SUCCESS);
1452
1453 }
1454
1455 /*
1456 * npi_fflp_fcram_err_data_test
1457 * Tests the FCRAM error detection logic.
1458 * The error detection logic for the datapath is tested.
1459 * bits [63:0] are set to select the data bits to be xor'ed
1460 *
1461 * Input
1462 * handle: opaque handle interpreted by the underlying OS
1463 * data: data bits to select bits to be xor'ed
1464 *
1465 *
1466 * Return
1467 * NPI_SUCCESS Success
1468 *
1469 *
1470 */
1471 npi_status_t
npi_fflp_fcram_err_data_test(npi_handle_t handle,fcram_err_data_t * data)1472 npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data)
1473 {
1474
1475 uint64_t t1_offset, t2_offset;
1476 fcram_err_tst1_t tst1; /* for data bits [31:0] */
1477 fcram_err_tst2_t tst2; /* for data bits [63:32] */
1478
1479 t1_offset = FFLP_FCRAM_ERR_TST1_REG;
1480 t2_offset = FFLP_FCRAM_ERR_TST2_REG;
1481 tst1.value = 0;
1482 tst2.value = 0;
1483 tst1.bits.ldw.dat = data->bits.ldw.dat;
1484 tst2.bits.ldw.dat = data->bits.hdw.dat;
1485
1486 REG_PIO_WRITE64(handle, t1_offset, tst1.value);
1487 REG_PIO_WRITE64(handle, t2_offset, tst2.value);
1488
1489 return (NPI_SUCCESS);
1490
1491 }
1492
1493 /*
1494 * npi_fflp_cfg_enet_vlan_table_assoc
1495 * associates port vlan id to rdc table.
1496 *
1497 * Input
1498 * handle opaque handle interpreted by the underlying OS
1499 * mac_portn port number
1500 * vlan_id VLAN ID
1501 * rdc_table RDC Table #
1502 * priority priority
1503 *
1504 * Output
1505 *
1506 * NPI success/failure status code
1507 *
1508 */
1509 npi_status_t
npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle,uint8_t mac_portn,vlan_id_t vlan_id,uint8_t rdc_table,uint8_t priority)1510 npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn,
1511 vlan_id_t vlan_id, uint8_t rdc_table,
1512 uint8_t priority)
1513 {
1514
1515 fflp_enet_vlan_tbl_t cfg;
1516 uint64_t offset;
1517 uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3};
1518 uint8_t parity_bit;
1519
1520 ASSERT(FFLP_VLAN_VALID(vlan_id));
1521 if (!FFLP_VLAN_VALID(vlan_id)) {
1522 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1523 " fflp_cfg_enet_vlan_table:"
1524 " Invalid vlan ID %d \n",
1525 vlan_id));
1526 return (NPI_FFLP_VLAN_INVALID);
1527 }
1528
1529 ASSERT(FFLP_PORT_VALID(mac_portn));
1530 if (!FFLP_PORT_VALID(mac_portn)) {
1531 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1532 " fflp_cfg_enet_vlan_table:"
1533 " Invalid port num %d \n",
1534 mac_portn));
1535 return (NPI_FFLP_PORT_INVALID);
1536 }
1537
1538 ASSERT(FFLP_RDC_TABLE_VALID(rdc_table));
1539 if (!FFLP_RDC_TABLE_VALID(rdc_table)) {
1540 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1541 " fflp_cfg_enet_vlan_table:"
1542 " Invalid RDC Table %d \n",
1543 rdc_table));
1544 return (NPI_FFLP_RDC_TABLE_INVALID);
1545 }
1546
1547 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
1548 REG_PIO_READ64(handle, offset, &cfg.value);
1549
1550 switch (mac_portn) {
1551 case 0:
1552 cfg.bits.ldw.vlanrdctbln0 = rdc_table;
1553 if (priority)
1554 cfg.bits.ldw.vpr0 = BIT_ENABLE;
1555 else
1556 cfg.bits.ldw.vpr0 = BIT_DISABLE;
1557 /* set the parity bits */
1558 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
1559 vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
1560 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
1561 cfg.bits.ldw.parity0 = parity_bit & 0x1;
1562 break;
1563 case 1:
1564 cfg.bits.ldw.vlanrdctbln1 = rdc_table;
1565 if (priority)
1566 cfg.bits.ldw.vpr1 = BIT_ENABLE;
1567 else
1568 cfg.bits.ldw.vpr1 = BIT_DISABLE;
1569 /* set the parity bits */
1570 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
1571 vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
1572 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
1573 cfg.bits.ldw.parity0 = parity_bit & 0x1;
1574
1575 break;
1576 case 2:
1577 cfg.bits.ldw.vlanrdctbln2 = rdc_table;
1578 if (priority)
1579 cfg.bits.ldw.vpr2 = BIT_ENABLE;
1580 else
1581 cfg.bits.ldw.vpr2 = BIT_DISABLE;
1582 /* set the parity bits */
1583 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
1584 vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
1585 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
1586 cfg.bits.ldw.parity1 = parity_bit & 0x1;
1587
1588 break;
1589 case 3:
1590 cfg.bits.ldw.vlanrdctbln3 = rdc_table;
1591 if (priority)
1592 cfg.bits.ldw.vpr3 = BIT_ENABLE;
1593 else
1594 cfg.bits.ldw.vpr3 = BIT_DISABLE;
1595 /* set the parity bits */
1596 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
1597 vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
1598 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
1599 cfg.bits.ldw.parity1 = parity_bit & 0x1;
1600 break;
1601 default:
1602 return (NPI_FFLP_SW_PARAM_ERROR);
1603 }
1604
1605 REG_PIO_WRITE64(handle, offset, cfg.value);
1606 return (NPI_SUCCESS);
1607 }
1608
1609 /*
1610 * npi_fflp_cfg_enet_vlan_table_set_pri
1611 * sets the vlan based classification priority in respect to L2DA
1612 * classification.
1613 *
1614 * Input
1615 * handle opaque handle interpreted by the underlying OS
1616 * mac_portn port number
1617 * vlan_id VLAN ID
1618 * priority priority
1619 * 1: vlan classification has higher priority
1620 * 0: l2da classification has higher priority
1621 *
1622 * Output
1623 *
1624 * NPI success/failure status code
1625 */
1626 npi_status_t
npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle,uint8_t mac_portn,vlan_id_t vlan_id,uint8_t priority)1627 npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn,
1628 vlan_id_t vlan_id, uint8_t priority)
1629 {
1630
1631 fflp_enet_vlan_tbl_t cfg;
1632 uint64_t offset;
1633 uint64_t old_value;
1634
1635 ASSERT(FFLP_VLAN_VALID(vlan_id));
1636 if (!FFLP_VLAN_VALID(vlan_id)) {
1637 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1638 " enet_vlan_table set pri:"
1639 " Invalid vlan ID %d \n",
1640 vlan_id));
1641 return (NPI_FFLP_VLAN_INVALID);
1642 }
1643
1644 ASSERT(FFLP_PORT_VALID(mac_portn));
1645 if (!FFLP_PORT_VALID(mac_portn)) {
1646 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1647 " enet_vlan_table set pri:"
1648 " Invalid port num %d \n",
1649 mac_portn));
1650 return (NPI_FFLP_PORT_INVALID);
1651 }
1652
1653
1654 offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id << 3);
1655 REG_PIO_READ64(handle, offset, &cfg.value);
1656 old_value = cfg.value;
1657 switch (mac_portn) {
1658 case 0:
1659 if (priority)
1660 cfg.bits.ldw.vpr0 = BIT_ENABLE;
1661 else
1662 cfg.bits.ldw.vpr0 = BIT_DISABLE;
1663 break;
1664 case 1:
1665 if (priority)
1666 cfg.bits.ldw.vpr1 = BIT_ENABLE;
1667 else
1668 cfg.bits.ldw.vpr1 = BIT_DISABLE;
1669 break;
1670 case 2:
1671 if (priority)
1672 cfg.bits.ldw.vpr2 = BIT_ENABLE;
1673 else
1674 cfg.bits.ldw.vpr2 = BIT_DISABLE;
1675 break;
1676 case 3:
1677 if (priority)
1678 cfg.bits.ldw.vpr3 = BIT_ENABLE;
1679 else
1680 cfg.bits.ldw.vpr3 = BIT_DISABLE;
1681 break;
1682 default:
1683 return (NPI_FFLP_SW_PARAM_ERROR);
1684 }
1685 if (old_value != cfg.value) {
1686 if (mac_portn > 1)
1687 cfg.bits.ldw.parity1++;
1688 else
1689 cfg.bits.ldw.parity0++;
1690
1691 REG_PIO_WRITE64(handle, offset, cfg.value);
1692 }
1693 return (NPI_SUCCESS);
1694 }
1695
1696 /*
1697 * npi_fflp_cfg_vlan_table_clear
1698 * Clears the vlan RDC table
1699 *
1700 * Input
1701 * handle opaque handle interpreted by the underlying OS
1702 * vlan_id VLAN ID
1703 *
1704 * Output
1705 *
1706 * NPI success/failure status code
1707 *
1708 */
1709 npi_status_t
npi_fflp_cfg_vlan_table_clear(npi_handle_t handle,vlan_id_t vlan_id)1710 npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id)
1711 {
1712
1713 uint64_t offset;
1714 uint64_t clear = 0ULL;
1715 vlan_id_t start_vlan = 0;
1716
1717 if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) {
1718 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1719 " enet_vlan_table clear:"
1720 " Invalid vlan ID %d \n",
1721 vlan_id));
1722 return (NPI_FFLP_VLAN_INVALID);
1723 }
1724
1725
1726 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
1727
1728 REG_PIO_WRITE64(handle, offset, clear);
1729 return (NPI_SUCCESS);
1730 }
1731
1732 /*
1733 * npi_fflp_vlan_tbl_get_err_log
1734 * Reports VLAN Table errors.
1735 * If there are VLAN Table errors as indicated by err bit set by HW,
1736 * then the SW will clear it by clearing the bit.
1737 *
1738 * Input
1739 * handle: opaque handle interpreted by the underlying OS
1740 * err_stat: structure to report various VLAN table errors.
1741 * will be updated if there are errors.
1742 *
1743 *
1744 * Return
1745 * NPI_SUCCESS Success
1746 *
1747 *
1748 */
1749 npi_status_t
npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle,vlan_tbl_err_log_t * err_stat)1750 npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat)
1751 {
1752 vlan_par_err_t err_log;
1753 uint64_t offset;
1754
1755
1756 offset = FFLP_VLAN_PAR_ERR_REG;
1757 err_log.value = 0;
1758
1759 REG_PIO_READ64(handle, offset, &err_log.value);
1760
1761 if (err_log.bits.ldw.err == BIT_ENABLE) {
1762 /* non-zero means err */
1763 err_stat->err = BIT_ENABLE;
1764 err_stat->multi = err_log.bits.ldw.m_err;
1765 err_stat->addr = err_log.bits.ldw.addr;
1766 err_stat->data = err_log.bits.ldw.data;
1767 /* now clear the error */
1768 err_log.value = 0;
1769 REG_PIO_WRITE64(handle, offset, err_log.value);
1770
1771 } else {
1772 err_stat->err = 0;
1773 }
1774
1775 return (NPI_SUCCESS);
1776 }
1777
1778 /*
1779 * npi_fflp_vlan_tbl_clr_err_log
1780 * Clears VLAN Table PIO error status.
1781 * If there are VLAN Table errors as indicated by err bit set by HW,
1782 * then the SW will clear it by clearing the bit.
1783 *
1784 * Input
1785 * handle: opaque handle interpreted by the underlying OS
1786 *
1787 *
1788 * Return
1789 * NPI_SUCCESS Success
1790 *
1791 *
1792 */
1793 npi_status_t
npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)1794 npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)
1795 {
1796 vlan_par_err_t err_log;
1797 uint64_t offset;
1798
1799 offset = FFLP_VLAN_PAR_ERR_REG;
1800 err_log.value = 0;
1801
1802 REG_PIO_WRITE64(handle, offset, err_log.value);
1803
1804 return (NPI_SUCCESS);
1805 }
1806
1807 /*
1808 * npi_fflp_cfg_enet_usr_cls_set()
1809 * Configures a user configurable ethernet class
1810 *
1811 * Input
1812 * handle: opaque handle interpreted by the underlying OS
1813 * class: Ethernet Class class
1814 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1815 * enet_type: 16 bit Ethernet Type value, corresponding ethernet bytes
1816 * [13:14] in the frame.
1817 *
1818 * by default, the class will be disabled until explicitly enabled.
1819 *
1820 * Return
1821 * NPI success/failure status code
1822 */
1823 npi_status_t
npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,tcam_class_t class,uint16_t enet_type)1824 npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,
1825 tcam_class_t class, uint16_t enet_type)
1826 {
1827 uint64_t offset;
1828 tcam_class_prg_ether_t cls_cfg;
1829 cls_cfg.value = 0x0;
1830
1831 /* check if etype is valid */
1832 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1833 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1834 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1835 " npi_fflp_cfg_enet_usr_cls_set:"
1836 " Invalid class %d \n",
1837 class));
1838 return (NPI_FFLP_TCAM_CLASS_INVALID);
1839 }
1840 offset = GET_TCAM_CLASS_OFFSET(class);
1841
1842 /*
1843 * etype check code
1844 *
1845 * if (check_fail)
1846 * return (NPI_FAILURE | NPI_SW_ERROR);
1847 */
1848
1849 cls_cfg.bits.ldw.etype = enet_type;
1850 cls_cfg.bits.ldw.valid = BIT_DISABLE;
1851 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1852 return (NPI_SUCCESS);
1853 }
1854
1855 /*
1856 * npi_fflp_cfg_enet_usr_cls_enable()
1857 * Enable previously configured TCAM user configurable Ethernet classes.
1858 *
1859 * Input
1860 * handle: opaque handle interpreted by the underlying OS
1861 * class: Ethernet Class class
1862 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1863 *
1864 * Return
1865 * NPI success/failure status code
1866 */
1867 npi_status_t
npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle,tcam_class_t class)1868 npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
1869 {
1870 uint64_t offset;
1871 tcam_class_prg_ether_t cls_cfg;
1872
1873 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1874 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1875 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1876 " npi_fflp_cfg_enet_usr_cls_enable:"
1877 " Invalid class %d \n",
1878 class));
1879 return (NPI_FFLP_TCAM_CLASS_INVALID);
1880 }
1881
1882 offset = GET_TCAM_CLASS_OFFSET(class);
1883
1884 REG_PIO_READ64(handle, offset, &cls_cfg.value);
1885 cls_cfg.bits.ldw.valid = BIT_ENABLE;
1886 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1887 return (NPI_SUCCESS);
1888 }
1889
1890 /*
1891 * npi_fflp_cfg_enet_usr_cls_disable()
1892 * Disables previously configured TCAM user configurable Ethernet classes.
1893 *
1894 * Input
1895 * handle: opaque handle interpreted by the underlying OS
1896 * class: Ethernet Class class
1897 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1898 *
1899 * Return
1900 * NPI success/failure status code
1901 */
1902 npi_status_t
npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle,tcam_class_t class)1903 npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
1904 {
1905 uint64_t offset;
1906 tcam_class_prg_ether_t cls_cfg;
1907
1908 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1909 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1910 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1911 " npi_fflp_cfg_enet_usr_cls_disable:"
1912 " Invalid class %d \n",
1913 class));
1914 return (NPI_FFLP_TCAM_CLASS_INVALID);
1915 }
1916
1917 offset = GET_TCAM_CLASS_OFFSET(class);
1918
1919 REG_PIO_READ64(handle, offset, &cls_cfg.value);
1920 cls_cfg.bits.ldw.valid = BIT_DISABLE;
1921
1922 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1923 return (NPI_SUCCESS);
1924 }
1925
1926 /*
1927 * npi_fflp_cfg_ip_usr_cls_set()
1928 * Configures the TCAM user configurable IP classes.
1929 *
1930 * Input
1931 * handle: opaque handle interpreted by the underlying OS
1932 * class: IP Class class
1933 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
1934 * tos: IP TOS bits
1935 * tos_mask: IP TOS bits mask. bits with mask bits set will be used
1936 * proto: IP Proto
1937 * ver: IP Version
1938 * by default, will the class is disabled until explicitly enabled
1939 *
1940 * Return
1941 * NPI success/failure status code
1942 */
1943 npi_status_t
npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle,tcam_class_t class,uint8_t tos,uint8_t tos_mask,uint8_t proto,uint8_t ver)1944 npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class,
1945 uint8_t tos, uint8_t tos_mask,
1946 uint8_t proto, uint8_t ver)
1947 {
1948 uint64_t offset;
1949 tcam_class_prg_ip_t ip_cls_cfg;
1950
1951 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
1952 if (!TCAM_L3_USR_CLASS_VALID(class)) {
1953 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1954 " npi_fflp_cfg_ip_usr_cls_set:"
1955 " Invalid class %d \n",
1956 class));
1957 return (NPI_FFLP_TCAM_CLASS_INVALID);
1958 }
1959
1960 offset = GET_TCAM_CLASS_OFFSET(class);
1961
1962 ip_cls_cfg.bits.ldw.pid = proto;
1963 ip_cls_cfg.bits.ldw.ipver = ver;
1964 ip_cls_cfg.bits.ldw.tos = tos;
1965 ip_cls_cfg.bits.ldw.tosmask = tos_mask;
1966 ip_cls_cfg.bits.ldw.valid = 0;
1967 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
1968 return (NPI_SUCCESS);
1969
1970 }
1971
1972 /*
1973 * npi_fflp_cfg_ip_usr_cls_set_iptun()
1974 * Configures the TCAM user configurable IP classes. This function sets the
1975 * new fields that were added for IP tunneling support
1976 *
1977 * Input
1978 * handle: opaque handle interpreted by the underlying OS
1979 * class: IP Class class
1980 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
1981 * l4b0_val value of the first L4 byte to be compared
1982 * l4b0_msk mask to apply to compare byte 0 of L4
1983 * l4b23_val values of L4 bytes 2 and 3 to compare
1984 * l4b23_sel set to 1 to compare L4 bytes 2 and 3.
1985 * by default, the class is disabled until explicitly enabled
1986 *
1987 * Return
1988 * NPI success/failure status code
1989 */
1990 npi_status_t
npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle,tcam_class_t class,uint8_t l4b0_val,uint8_t l4b0_msk,uint16_t l4b23_val,uint8_t l4b23_sel)1991 npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class,
1992 uint8_t l4b0_val, uint8_t l4b0_msk,
1993 uint16_t l4b23_val, uint8_t l4b23_sel)
1994 {
1995 uint64_t offset, val;
1996 tcam_class_prg_ip_t ip_cls_cfg;
1997
1998 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
1999 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2000 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2001 " npi_fflp_cfg_ip_usr_cls_set:"
2002 " Invalid class %d \n",
2003 class));
2004 return (NPI_FFLP_TCAM_CLASS_INVALID);
2005 }
2006
2007 offset = GET_TCAM_CLASS_OFFSET(class);
2008 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2009
2010 val = 1;
2011 ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH);
2012 val = l4b0_val;
2013 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH);
2014 val = l4b0_msk;
2015 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH);
2016 val = l4b23_sel;
2017 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH);
2018 val = l4b23_val;
2019 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH);
2020
2021 ip_cls_cfg.bits.ldw.valid = 0;
2022 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2023 return (NPI_SUCCESS);
2024 }
2025
2026 /*
2027 * npi_fflp_cfg_ip_usr_cls_get_iptun()
2028 * Retrieves the IP tunneling related settings for the given TCAM user
2029 * configurable IP classe.
2030 *
2031 * Input
2032 * handle: opaque handle interpreted by the underlying OS
2033 * class: IP Class class
2034 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2035 * l4b0_val value of the first L4 byte to be compared
2036 * l4b0_msk mask to apply to compare byte 0 of L4
2037 * l4b23_val values of L4 bytes 2 and 3 to compare
2038 * l4b23_sel set to 1 to compare L4 bytes 2 and 3.
2039 * by default, the class is disabled until explicitly enabled
2040 *
2041 * Return
2042 * NPI success/failure status code
2043 */
2044 npi_status_t
npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle,tcam_class_t class,uint8_t * l4b0_val,uint8_t * l4b0_msk,uint16_t * l4b23_val,uint8_t * l4b23_sel)2045 npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class,
2046 uint8_t *l4b0_val, uint8_t *l4b0_msk,
2047 uint16_t *l4b23_val, uint8_t *l4b23_sel)
2048 {
2049 uint64_t offset;
2050 tcam_class_prg_ip_t ip_cls_cfg;
2051
2052 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2053 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2054 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2055 " npi_fflp_cfg_ip_usr_cls_set:"
2056 " Invalid class %d \n",
2057 class));
2058 return (NPI_FFLP_TCAM_CLASS_INVALID);
2059 }
2060
2061 offset = GET_TCAM_CLASS_OFFSET(class);
2062 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2063
2064 *l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) &
2065 L3_UCLS_L4B0_VAL_MSK;
2066 *l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) &
2067 L3_UCLS_L4B0_MASK_MSK;
2068 *l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) &
2069 L3_UCLS_L4B23_SEL_MSK;
2070 *l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) &
2071 L3_UCLS_L4B23_VAL_MSK;
2072
2073 return (NPI_SUCCESS);
2074
2075 }
2076
2077 /*
2078 * npi_fflp_cfg_ip_usr_cls_enable()
2079 * Enable previously configured TCAM user configurable IP classes.
2080 *
2081 * Input
2082 * handle: opaque handle interpreted by the underlying OS
2083 * class: IP Class class
2084 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2085 *
2086 * Return
2087 * NPI success/failure status code
2088 */
2089 npi_status_t
npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle,tcam_class_t class)2090 npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
2091 {
2092 uint64_t offset;
2093 tcam_class_prg_ip_t ip_cls_cfg;
2094
2095 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2096 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2097 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2098 " npi_fflp_cfg_ip_usr_cls_enable:"
2099 " Invalid class %d \n",
2100 class));
2101 return (NPI_FFLP_TCAM_CLASS_INVALID);
2102 }
2103
2104 offset = GET_TCAM_CLASS_OFFSET(class);
2105 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2106 ip_cls_cfg.bits.ldw.valid = 1;
2107
2108 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2109 return (NPI_SUCCESS);
2110
2111 }
2112
2113 /*
2114 * npi_fflp_cfg_ip_usr_cls_disable()
2115 * Disables previously configured TCAM user configurable IP classes.
2116 *
2117 * Input
2118 * handle: opaque handle interpreted by the underlying OS
2119 * class: IP Class class
2120 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2121 *
2122 * Return
2123 * NPI success/failure status code
2124 */
2125 npi_status_t
npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle,tcam_class_t class)2126 npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
2127 {
2128 uint64_t offset;
2129 tcam_class_prg_ip_t ip_cls_cfg;
2130
2131 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2132 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2133 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2134 " npi_fflp_cfg_ip_usr_cls_disable:"
2135 " Invalid class %d \n",
2136 class));
2137 return (NPI_FFLP_TCAM_CLASS_INVALID);
2138 }
2139
2140 offset = GET_TCAM_CLASS_OFFSET(class);
2141
2142 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2143 ip_cls_cfg.bits.ldw.valid = 0;
2144
2145 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2146 return (NPI_SUCCESS);
2147
2148 }
2149
2150 /*
2151 * npi_fflp_cfg_ip_cls_tcam_key ()
2152 *
2153 * Configures the TCAM key generation for the IP classes
2154 *
2155 * Input
2156 * handle: opaque handle interpreted by the underlying OS
2157 * l3_class: IP class to configure key generation
2158 * cfg: Configuration bits:
2159 * discard: Discard all frames of this class
2160 * use_ip_saddr: use ip src address (for ipv6)
2161 * use_ip_daddr: use ip dest address (for ipv6)
2162 * lookup_enable: Enable Lookup
2163 *
2164 *
2165 * Return
2166 * NPI success/failure status code
2167 */
2168 npi_status_t
npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,tcam_class_t l3_class,tcam_key_cfg_t * cfg)2169 npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,
2170 tcam_class_t l3_class, tcam_key_cfg_t *cfg)
2171 {
2172 uint64_t offset;
2173 tcam_class_key_ip_t tcam_cls_cfg;
2174
2175 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2176 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2177 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2178 " npi_fflp_cfg_ip_cls_tcam_key:"
2179 " Invalid class %d \n",
2180 l3_class));
2181 return (NPI_FFLP_TCAM_CLASS_INVALID);
2182 }
2183
2184 if ((cfg->use_ip_daddr) &&
2185 (cfg->use_ip_saddr == cfg->use_ip_daddr)) {
2186 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2187 " npi_fflp_cfg_ip_cls_tcam_key:"
2188 " Invalid configuration %x for class %d \n",
2189 *cfg, l3_class));
2190 return (NPI_FFLP_SW_PARAM_ERROR);
2191 }
2192
2193
2194 offset = GET_TCAM_KEY_OFFSET(l3_class);
2195 tcam_cls_cfg.value = 0;
2196
2197 if (cfg->discard) {
2198 tcam_cls_cfg.bits.ldw.discard = 1;
2199 }
2200
2201 if (cfg->use_ip_saddr) {
2202 tcam_cls_cfg.bits.ldw.ipaddr = 1;
2203 }
2204
2205 if (cfg->use_ip_daddr) {
2206 tcam_cls_cfg.bits.ldw.ipaddr = 0;
2207 }
2208
2209 if (cfg->lookup_enable) {
2210 tcam_cls_cfg.bits.ldw.tsel = 1;
2211 }
2212
2213 REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value);
2214 return (NPI_SUCCESS);
2215 }
2216
2217 /*
2218 * npi_fflp_cfg_ip_cls_flow_key ()
2219 *
2220 * Configures the flow key generation for the IP classes
2221 * Flow key is used to generate the H1 hash function value
2222 * The fields used for the generation are configured using this
2223 * NPI function.
2224 *
2225 * Input
2226 * handle: opaque handle interpreted by the underlying OS
2227 * l3_class: IP class to configure flow key generation
2228 * cfg: Configuration bits:
2229 * use_proto: Use IP proto field
2230 * use_dport: use l4 destination port
2231 * use_sport: use l4 source port
2232 * ip_opts_exist: IP Options Present
2233 * use_daddr: use ip dest address
2234 * use_saddr: use ip source address
2235 * use_vlan: use VLAN ID
2236 * use_l2da: use L2 Dest MAC Address
2237 * use_portnum: use L2 virtual port number
2238 *
2239 *
2240 * Return
2241 * NPI success/failure status code
2242 */
2243 npi_status_t
npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)2244 npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
2245 flow_key_cfg_t *cfg)
2246 {
2247 uint64_t offset;
2248 flow_class_key_ip_t flow_cfg_reg;
2249
2250 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2251 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2252 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2253 " npi_fflp_cfg_ip_cls_flow_key:"
2254 " Invalid class %d \n",
2255 l3_class));
2256 return (NPI_FFLP_TCAM_CLASS_INVALID);
2257 }
2258
2259
2260 offset = GET_FLOW_KEY_OFFSET(l3_class);
2261 flow_cfg_reg.value = 0; /* default */
2262
2263 if (cfg->use_proto) {
2264 flow_cfg_reg.bits.ldw.proto = 1;
2265 }
2266
2267 if (cfg->use_dport) {
2268 flow_cfg_reg.bits.ldw.l4_1 = 2;
2269 if (cfg->ip_opts_exist)
2270 flow_cfg_reg.bits.ldw.l4_1 = 3;
2271 }
2272
2273 if (cfg->use_sport) {
2274 flow_cfg_reg.bits.ldw.l4_0 = 2;
2275 if (cfg->ip_opts_exist)
2276 flow_cfg_reg.bits.ldw.l4_0 = 3;
2277 }
2278
2279 if (cfg->use_daddr) {
2280 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
2281 }
2282
2283 if (cfg->use_saddr) {
2284 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
2285 }
2286
2287 if (cfg->use_vlan) {
2288 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
2289 }
2290
2291 if (cfg->use_l2da) {
2292 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
2293 }
2294
2295 if (cfg->use_portnum) {
2296 flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
2297 }
2298
2299 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2300 return (NPI_SUCCESS);
2301
2302 }
2303
2304 npi_status_t
npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)2305 npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle,
2306 tcam_class_t l3_class,
2307 flow_key_cfg_t *cfg)
2308 {
2309 uint64_t offset;
2310 flow_class_key_ip_t flow_cfg_reg;
2311
2312 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2313 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2314 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2315 " npi_fflp_cfg_ip_cls_flow_key:"
2316 " Invalid class %d \n",
2317 l3_class));
2318 return (NPI_FFLP_TCAM_CLASS_INVALID);
2319 }
2320
2321 offset = GET_FLOW_KEY_OFFSET(l3_class);
2322
2323 cfg->use_proto = 0;
2324 cfg->use_dport = 0;
2325 cfg->use_sport = 0;
2326 cfg->ip_opts_exist = 0;
2327 cfg->use_daddr = 0;
2328 cfg->use_saddr = 0;
2329 cfg->use_vlan = 0;
2330 cfg->use_l2da = 0;
2331 cfg->use_portnum = 0;
2332
2333 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2334
2335 if (flow_cfg_reg.bits.ldw.proto) {
2336 cfg->use_proto = 1;
2337 }
2338
2339 if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
2340 cfg->use_dport = 1;
2341 }
2342
2343 if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
2344 cfg->use_dport = 1;
2345 cfg->ip_opts_exist = 1;
2346 }
2347
2348 if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
2349 cfg->use_sport = 1;
2350 }
2351
2352 if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
2353 cfg->use_sport = 1;
2354 cfg->ip_opts_exist = 1;
2355 }
2356
2357 if (flow_cfg_reg.bits.ldw.ipda) {
2358 cfg->use_daddr = 1;
2359 }
2360
2361 if (flow_cfg_reg.bits.ldw.ipsa) {
2362 cfg->use_saddr = 1;
2363 }
2364
2365 if (flow_cfg_reg.bits.ldw.vlan) {
2366 cfg->use_vlan = 1;
2367 }
2368
2369 if (flow_cfg_reg.bits.ldw.l2da) {
2370 cfg->use_l2da = 1;
2371 }
2372
2373 if (flow_cfg_reg.bits.ldw.port) {
2374 cfg->use_portnum = 1;
2375 }
2376
2377 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
2378 " npi_fflp_cfg_ip_cls_flow_get %llx \n",
2379 flow_cfg_reg.value));
2380
2381 return (NPI_SUCCESS);
2382
2383 }
2384
2385 /*
2386 * npi_fflp_cfg_ip_cls_flow_key_rfnl ()
2387 *
2388 * Configures the flow key generation for the IP classes
2389 * Flow key is used to generate the H1 hash function value
2390 * The fields used for the generation are configured using this
2391 * NPI function.
2392 *
2393 * Input
2394 * handle: opaque handle interpreted by the underlying OS
2395 * l3_class: IP class to configure flow key generation
2396 * cfg: Configuration bits:
2397 * l4_xor_sel: bit field to select the L4 payload
2398 * bytes for X-OR to get hash key.
2399 * use_l4_md: Set to 1 for enabling L4-mode.
2400 * use_sym: Set to 1 to use symmetric mode.
2401 * use_proto: Use IP proto field
2402 * use_dport: use l4 destination port
2403 * use_sport: use l4 source port
2404 * ip_opts_exist: IP Options Present
2405 * use_daddr: use ip dest address
2406 * use_saddr: use ip source address
2407 * use_vlan: use VLAN ID
2408 * use_l2da: use L2 Dest MAC Address
2409 * use_portnum: use L2 virtual port number
2410 *
2411 *
2412 * Return
2413 * NPI success/failure status code
2414 */
2415 npi_status_t
npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)2416 npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class,
2417 flow_key_cfg_t *cfg)
2418 {
2419 uint64_t offset;
2420 flow_class_key_ip_t flow_cfg_reg;
2421
2422 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2423 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2424 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2425 " npi_fflp_cfg_ip_cls_flow_key_rfnl:"
2426 " Invalid class %d \n",
2427 l3_class));
2428 return (NPI_FFLP_TCAM_CLASS_INVALID);
2429 }
2430
2431 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2432 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2433 } else {
2434 offset = GET_FLOW_KEY_OFFSET(l3_class);
2435 }
2436
2437 flow_cfg_reg.value = 0;
2438
2439 flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel;
2440
2441 if (cfg->use_l4_md)
2442 flow_cfg_reg.bits.ldw.l4_mode = 1;
2443
2444 if (cfg->use_sym)
2445 flow_cfg_reg.bits.ldw.sym = 1;
2446
2447 if (cfg->use_proto) {
2448 flow_cfg_reg.bits.ldw.proto = 1;
2449 }
2450
2451 if (cfg->use_dport) {
2452 flow_cfg_reg.bits.ldw.l4_1 = 2;
2453 if (cfg->ip_opts_exist)
2454 flow_cfg_reg.bits.ldw.l4_1 = 3;
2455 }
2456
2457 if (cfg->use_sport) {
2458 flow_cfg_reg.bits.ldw.l4_0 = 2;
2459 if (cfg->ip_opts_exist)
2460 flow_cfg_reg.bits.ldw.l4_0 = 3;
2461 }
2462
2463 if (cfg->use_daddr) {
2464 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
2465 }
2466
2467 if (cfg->use_saddr) {
2468 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
2469 }
2470
2471 if (cfg->use_vlan) {
2472 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
2473 }
2474
2475 if (cfg->use_l2da) {
2476 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
2477 }
2478
2479 if (cfg->use_portnum) {
2480 flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
2481 }
2482
2483 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2484 return (NPI_SUCCESS);
2485
2486 }
2487
2488 npi_status_t
npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,boolean_t enable)2489 npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
2490 boolean_t enable)
2491 {
2492 uint64_t offset;
2493 flow_class_key_ip_t flow_cfg_reg;
2494
2495 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2496 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2497 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2498 " npi_fflp_cfg_sym_ip_cls_flow_key:"
2499 " Invalid class %d \n",
2500 l3_class));
2501 return (NPI_FFLP_TCAM_CLASS_INVALID);
2502 }
2503
2504 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2505 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2506 } else {
2507 offset = GET_FLOW_KEY_OFFSET(l3_class);
2508 }
2509
2510 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2511
2512 if (enable && flow_cfg_reg.bits.ldw.sym == 0) {
2513 flow_cfg_reg.bits.ldw.sym = 1;
2514 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2515 } else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) {
2516 flow_cfg_reg.bits.ldw.sym = 0;
2517 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2518 }
2519
2520 return (NPI_SUCCESS);
2521
2522 }
2523
2524 npi_status_t
npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)2525 npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle,
2526 tcam_class_t l3_class,
2527 flow_key_cfg_t *cfg)
2528 {
2529 uint64_t offset;
2530 flow_class_key_ip_t flow_cfg_reg;
2531
2532 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2533 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2534 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2535 " npi_fflp_cfg_ip_cls_flow_key_get_rfnl:"
2536 " Invalid class %d \n",
2537 l3_class));
2538 return (NPI_FFLP_TCAM_CLASS_INVALID);
2539 }
2540
2541 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2542 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2543 } else {
2544 offset = GET_FLOW_KEY_OFFSET(l3_class);
2545 }
2546
2547 cfg->l4_xor_sel = 0;
2548 cfg->use_l4_md = 0;
2549 cfg->use_sym = 0;
2550 cfg->use_proto = 0;
2551 cfg->use_dport = 0;
2552 cfg->use_sport = 0;
2553 cfg->ip_opts_exist = 0;
2554 cfg->use_daddr = 0;
2555 cfg->use_saddr = 0;
2556 cfg->use_vlan = 0;
2557 cfg->use_l2da = 0;
2558 cfg->use_portnum = 0;
2559
2560 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2561
2562 cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor;
2563
2564 if (flow_cfg_reg.bits.ldw.l4_mode)
2565 cfg->use_l4_md = 1;
2566
2567 if (flow_cfg_reg.bits.ldw.sym)
2568 cfg->use_sym = 1;
2569
2570 if (flow_cfg_reg.bits.ldw.proto) {
2571 cfg->use_proto = 1;
2572 }
2573
2574 if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
2575 cfg->use_dport = 1;
2576 }
2577
2578 if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
2579 cfg->use_dport = 1;
2580 cfg->ip_opts_exist = 1;
2581 }
2582
2583 if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
2584 cfg->use_sport = 1;
2585 }
2586
2587 if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
2588 cfg->use_sport = 1;
2589 cfg->ip_opts_exist = 1;
2590 }
2591
2592 if (flow_cfg_reg.bits.ldw.ipda) {
2593 cfg->use_daddr = 1;
2594 }
2595
2596 if (flow_cfg_reg.bits.ldw.ipsa) {
2597 cfg->use_saddr = 1;
2598 }
2599
2600 if (flow_cfg_reg.bits.ldw.vlan) {
2601 cfg->use_vlan = 1;
2602 }
2603
2604 if (flow_cfg_reg.bits.ldw.l2da) {
2605 cfg->use_l2da = 1;
2606 }
2607
2608 if (flow_cfg_reg.bits.ldw.port) {
2609 cfg->use_portnum = 1;
2610 }
2611
2612 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
2613 " npi_fflp_cfg_ip_cls_flow_get %llx \n",
2614 flow_cfg_reg.value));
2615
2616 return (NPI_SUCCESS);
2617
2618 }
2619
2620 npi_status_t
npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle,tcam_class_t l3_class,tcam_key_cfg_t * cfg)2621 npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle,
2622 tcam_class_t l3_class, tcam_key_cfg_t *cfg)
2623 {
2624 uint64_t offset;
2625 tcam_class_key_ip_t tcam_cls_cfg;
2626
2627 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2628 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2629 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2630 " npi_fflp_cfg_ip_cls_tcam_key_get:"
2631 " Invalid class %d \n",
2632 l3_class));
2633 return (NPI_FFLP_TCAM_CLASS_INVALID);
2634 }
2635
2636
2637 offset = GET_TCAM_KEY_OFFSET(l3_class);
2638
2639 REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value);
2640
2641 cfg->discard = 0;
2642 cfg->use_ip_saddr = 0;
2643 cfg->use_ip_daddr = 1;
2644 cfg->lookup_enable = 0;
2645
2646 if (tcam_cls_cfg.bits.ldw.discard)
2647 cfg->discard = 1;
2648
2649 if (tcam_cls_cfg.bits.ldw.ipaddr) {
2650 cfg->use_ip_saddr = 1;
2651 cfg->use_ip_daddr = 0;
2652 }
2653
2654 if (tcam_cls_cfg.bits.ldw.tsel) {
2655 cfg->lookup_enable = 1;
2656 }
2657
2658 NPI_DEBUG_MSG((handle.function, NPI_CTL,
2659 " npi_fflp_cfg_ip_cls_tcam_key_get %llx \n",
2660 tcam_cls_cfg.value));
2661 return (NPI_SUCCESS);
2662 }
2663
2664 /*
2665 * npi_fflp_cfg_fcram_access ()
2666 *
2667 * Sets the ratio between the FCRAM pio and lookup access
2668 * Input:
2669 * handle: opaque handle interpreted by the underlying OS
2670 * access_ratio: 0 Lookup has the highest priority
2671 * 15 PIO has maximum possible priority
2672 *
2673 * Return
2674 * NPI success/failure status code
2675 */
2676 npi_status_t
npi_fflp_cfg_fcram_access(npi_handle_t handle,uint8_t access_ratio)2677 npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio)
2678 {
2679
2680 fflp_cfg_1_t fflp_cfg;
2681 uint64_t offset;
2682 offset = FFLP_CFG_1_REG;
2683
2684 if (access_ratio > 0xf) {
2685 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2686 " npi_fflp_cfg_fcram_access:"
2687 " Invalid access ratio %d \n",
2688 access_ratio));
2689 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2690 }
2691
2692 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2693 fflp_cfg.bits.ldw.fflpinitdone = 0;
2694 fflp_cfg.bits.ldw.fcramratio = access_ratio;
2695 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2696 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2697 fflp_cfg.bits.ldw.fflpinitdone = 1;
2698 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2699 return (NPI_SUCCESS);
2700
2701 }
2702
2703 /*
2704 * npi_fflp_cfg_tcam_access ()
2705 *
2706 * Sets the ratio between the TCAM pio and lookup access
2707 * Input:
2708 * handle: opaque handle interpreted by the underlying OS
2709 * access_ratio: 0 Lookup has the highest priority
2710 * 15 PIO has maximum possible priority
2711 * Return
2712 * NPI success/failure status code
2713 */
2714 npi_status_t
npi_fflp_cfg_tcam_access(npi_handle_t handle,uint8_t access_ratio)2715 npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio)
2716 {
2717 fflp_cfg_1_t fflp_cfg;
2718 uint64_t offset;
2719 offset = FFLP_CFG_1_REG;
2720
2721 if (access_ratio > 0xf) {
2722 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2723 " npi_fflp_cfg_tcram_access:"
2724 " Invalid access ratio %d \n",
2725 access_ratio));
2726 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2727 }
2728
2729 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2730 fflp_cfg.bits.ldw.fflpinitdone = 0;
2731 fflp_cfg.bits.ldw.camratio = access_ratio;
2732
2733 /* since the cam latency is fixed, we might set it here */
2734 fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY;
2735 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2736 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2737 fflp_cfg.bits.ldw.fflpinitdone = 1;
2738 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2739
2740 return (NPI_SUCCESS);
2741 }
2742
2743 /*
2744 * npi_fflp_cfg_hash_h1poly()
2745 * Initializes the H1 hash generation logic.
2746 *
2747 * Input
2748 * handle: opaque handle interpreted by the underlying OS
2749 * init_value: The initial value (seed)
2750 *
2751 * Return
2752 * NPI success/failure status code
2753 */
2754 npi_status_t
npi_fflp_cfg_hash_h1poly(npi_handle_t handle,uint32_t init_value)2755 npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value)
2756 {
2757
2758
2759 hash_h1poly_t h1_cfg;
2760 uint64_t offset;
2761 offset = FFLP_H1POLY_REG;
2762
2763 h1_cfg.value = 0;
2764 h1_cfg.bits.ldw.init_value = init_value;
2765
2766 REG_PIO_WRITE64(handle, offset, h1_cfg.value);
2767 return (NPI_SUCCESS);
2768 }
2769
2770 /*
2771 * npi_fflp_cfg_hash_h2poly()
2772 * Initializes the H2 hash generation logic.
2773 *
2774 * Input
2775 * handle: opaque handle interpreted by the underlying OS
2776 * init_value: The initial value (seed)
2777 *
2778 * Return
2779 * NPI_SUCCESS
2780 *
2781 */
2782 npi_status_t
npi_fflp_cfg_hash_h2poly(npi_handle_t handle,uint16_t init_value)2783 npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value)
2784 {
2785
2786
2787 hash_h2poly_t h2_cfg;
2788 uint64_t offset;
2789 offset = FFLP_H2POLY_REG;
2790
2791 h2_cfg.value = 0;
2792 h2_cfg.bits.ldw.init_value = init_value;
2793
2794 REG_PIO_WRITE64(handle, offset, h2_cfg.value);
2795 return (NPI_SUCCESS);
2796
2797
2798 }
2799
2800 /*
2801 * npi_fflp_cfg_reset
2802 * Initializes the FCRAM reset sequence.
2803 *
2804 * Input
2805 * handle: opaque handle interpreted by the underlying OS
2806 * strength: FCRAM Drive strength
2807 * strong, weak or normal
2808 * HW recommended value:
2809 * qs: FCRAM QS mode selection
2810 * qs mode or free running
2811 * HW recommended value is:
2812 *
2813 * Return:
2814 * NPI success/failure status code
2815 */
2816
2817 npi_status_t
npi_fflp_cfg_fcram_reset(npi_handle_t handle,fflp_fcram_output_drive_t strength,fflp_fcram_qs_t qs)2818 npi_fflp_cfg_fcram_reset(npi_handle_t handle,
2819 fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs)
2820 {
2821 fflp_cfg_1_t fflp_cfg;
2822 uint64_t offset;
2823 offset = FFLP_CFG_1_REG;
2824
2825 /* These bits have to be configured before FCRAM reset is issued */
2826 fflp_cfg.value = 0;
2827 fflp_cfg.bits.ldw.pio_fio_rst = 1;
2828 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2829
2830 NXGE_DELAY(5); /* TODO: What is the correct delay? */
2831
2832 fflp_cfg.bits.ldw.pio_fio_rst = 0;
2833 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2834 fflp_cfg.bits.ldw.fcramqs = qs;
2835 fflp_cfg.bits.ldw.fcramoutdr = strength;
2836 fflp_cfg.bits.ldw.fflpinitdone = 1;
2837 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2838
2839 return (NPI_SUCCESS);
2840 }
2841
2842 npi_status_t
npi_fflp_cfg_init_done(npi_handle_t handle)2843 npi_fflp_cfg_init_done(npi_handle_t handle)
2844
2845 {
2846
2847 fflp_cfg_1_t fflp_cfg;
2848 uint64_t offset;
2849 offset = FFLP_CFG_1_REG;
2850
2851 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2852 fflp_cfg.bits.ldw.fflpinitdone = 1;
2853 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2854 return (NPI_SUCCESS);
2855
2856 }
2857
2858 npi_status_t
npi_fflp_cfg_init_start(npi_handle_t handle)2859 npi_fflp_cfg_init_start(npi_handle_t handle)
2860
2861 {
2862
2863 fflp_cfg_1_t fflp_cfg;
2864 uint64_t offset;
2865 offset = FFLP_CFG_1_REG;
2866
2867 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2868 fflp_cfg.bits.ldw.fflpinitdone = 0;
2869 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2870 return (NPI_SUCCESS);
2871
2872 }
2873
2874 /*
2875 * Enables the TCAM search function.
2876 *
2877 */
2878 npi_status_t
npi_fflp_cfg_tcam_enable(npi_handle_t handle)2879 npi_fflp_cfg_tcam_enable(npi_handle_t handle)
2880
2881 {
2882
2883 fflp_cfg_1_t fflp_cfg;
2884 uint64_t offset;
2885 offset = FFLP_CFG_1_REG;
2886 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2887 fflp_cfg.bits.ldw.tcam_disable = 0;
2888 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2889 return (NPI_SUCCESS);
2890
2891 }
2892
2893 /*
2894 * Disables the TCAM search function.
2895 * While the TCAM is in disabled state, all TCAM matches would return NO_MATCH
2896 *
2897 */
2898 npi_status_t
npi_fflp_cfg_tcam_disable(npi_handle_t handle)2899 npi_fflp_cfg_tcam_disable(npi_handle_t handle)
2900
2901 {
2902
2903 fflp_cfg_1_t fflp_cfg;
2904 uint64_t offset;
2905 offset = FFLP_CFG_1_REG;
2906 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2907 fflp_cfg.bits.ldw.tcam_disable = 1;
2908 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2909 return (NPI_SUCCESS);
2910
2911 }
2912
2913 /*
2914 * npi_rxdma_event_mask_config():
2915 * This function is called to operate on the event mask
2916 * register which is used for generating interrupts
2917 * and status register.
2918 */
2919 npi_status_t
npi_fflp_event_mask_config(npi_handle_t handle,io_op_t op_mode,fflp_event_mask_cfg_t * mask_cfgp)2920 npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode,
2921 fflp_event_mask_cfg_t *mask_cfgp)
2922 {
2923 int status = NPI_SUCCESS;
2924 fflp_err_mask_t mask_reg;
2925
2926 switch (op_mode) {
2927 case OP_GET:
2928
2929 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
2930 *mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL;
2931 break;
2932
2933 case OP_SET:
2934 mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
2935 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2936 break;
2937
2938 case OP_UPDATE:
2939 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
2940 mask_reg.value |= (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
2941 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2942 break;
2943
2944 case OP_CLEAR:
2945 mask_reg.value = FFLP_ERR_MASK_ALL;
2946 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2947 break;
2948 default:
2949 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2950 " npi_fflp_event_mask_config",
2951 " eventmask <0x%x>", op_mode));
2952 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2953 }
2954
2955 return (status);
2956 }
2957
2958 /*
2959 * Read vlan error bits
2960 */
2961 void
npi_fflp_vlan_error_get(npi_handle_t handle,p_vlan_par_err_t p_err)2962 npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err)
2963 {
2964 REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value);
2965 }
2966
2967 /*
2968 * clear vlan error bits
2969 */
2970 void
npi_fflp_vlan_error_clear(npi_handle_t handle)2971 npi_fflp_vlan_error_clear(npi_handle_t handle)
2972 {
2973 vlan_par_err_t p_err;
2974 p_err.value = 0;
2975 p_err.bits.ldw.m_err = 0;
2976 p_err.bits.ldw.err = 0;
2977 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value);
2978
2979 }
2980
2981 /*
2982 * Read TCAM error bits
2983 */
2984 void
npi_fflp_tcam_error_get(npi_handle_t handle,p_tcam_err_t p_err)2985 npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err)
2986 {
2987 REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value);
2988 }
2989
2990 /*
2991 * clear TCAM error bits
2992 */
2993 void
npi_fflp_tcam_error_clear(npi_handle_t handle)2994 npi_fflp_tcam_error_clear(npi_handle_t handle)
2995 {
2996 tcam_err_t p_err;
2997
2998 p_err.value = 0;
2999 p_err.bits.ldw.p_ecc = 0;
3000 p_err.bits.ldw.mult = 0;
3001 p_err.bits.ldw.err = 0;
3002 REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value);
3003
3004 }
3005
3006 /*
3007 * Read FCRAM error bits
3008 */
3009 void
npi_fflp_fcram_error_get(npi_handle_t handle,p_hash_tbl_data_log_t p_err,uint8_t partition)3010 npi_fflp_fcram_error_get(npi_handle_t handle,
3011 p_hash_tbl_data_log_t p_err, uint8_t partition)
3012 {
3013 uint64_t offset;
3014
3015 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
3016 REG_PIO_READ64(handle, offset, &p_err->value);
3017 }
3018
3019 /*
3020 * clear FCRAM error bits
3021 */
3022 void
npi_fflp_fcram_error_clear(npi_handle_t handle,uint8_t partition)3023 npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition)
3024 {
3025 hash_tbl_data_log_t p_err;
3026 uint64_t offset;
3027
3028 p_err.value = 0;
3029 p_err.bits.ldw.pio_err = 0;
3030 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
3031
3032 REG_PIO_WRITE64(handle, offset,
3033 p_err.value);
3034
3035 }
3036
3037 /*
3038 * Read FCRAM lookup error log1 bits
3039 */
3040 void
npi_fflp_fcram_error_log1_get(npi_handle_t handle,p_hash_lookup_err_log1_t log1)3041 npi_fflp_fcram_error_log1_get(npi_handle_t handle,
3042 p_hash_lookup_err_log1_t log1)
3043 {
3044 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG,
3045 &log1->value);
3046 }
3047
3048 /*
3049 * Read FCRAM lookup error log2 bits
3050 */
3051 void
npi_fflp_fcram_error_log2_get(npi_handle_t handle,p_hash_lookup_err_log2_t log2)3052 npi_fflp_fcram_error_log2_get(npi_handle_t handle,
3053 p_hash_lookup_err_log2_t log2)
3054 {
3055 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG,
3056 &log2->value);
3057 }
3058