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 alligned */
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 alligned */
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 alligned */
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 alligned */
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 alligned */
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 alligned */
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 alligned */
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 alligned */
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 /*
964 * assumes that the base mask and relocation are computed somewhere
965 * and kept in the state data structure. Alternativiely, one can pass
966 * a partition size and a starting address and this routine can compute
967 * the mask and reloc vlaues.
968 */
969
970 flow_prt_sel_t sel;
971 uint64_t offset;
972
973 ASSERT(FCRAM_PARTITION_VALID(partid));
974 if (!FCRAM_PARTITION_VALID(partid)) {
975 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
976 " npi_fflp_cfg_fcram_partition:"
977 " Invalid Partition %d \n",
978 partid));
979 return (NPI_FFLP_FCRAM_PART_INVALID);
980 }
981
982 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
983 sel.value = 0;
984 sel.bits.ldw.mask = base_mask;
985 sel.bits.ldw.base = base_reloc;
986 sel.bits.ldw.ext = BIT_DISABLE; /* disable */
987 REG_PIO_WRITE64(handle, offset, sel.value);
988 return (NPI_SUCCESS);
989
990 }
991
992 /*
993 * npi_fflp_fcram_partition_enable
994 * Enable previously configured FCRAM partition
995 *
996 * Input
997 * handle: opaque handle interpreted by the underlying OS
998 * partid: partition ID, Corresponds to the RDC table
999 *
1000 * Return
1001 * 0 Successful
1002 * Non zero error code Enable failed, and reason.
1003 *
1004 */
1005 npi_status_t
npi_fflp_cfg_fcram_partition_enable(npi_handle_t handle,part_id_t partid)1006 npi_fflp_cfg_fcram_partition_enable (npi_handle_t handle, part_id_t partid)
1007
1008 {
1009
1010 flow_prt_sel_t sel;
1011 uint64_t offset;
1012
1013 ASSERT(FCRAM_PARTITION_VALID(partid));
1014 if (!FCRAM_PARTITION_VALID(partid)) {
1015 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1016 " fcram_partition enable:"
1017 " Invalid Partition %d \n",
1018 partid));
1019 return (NPI_FFLP_FCRAM_PART_INVALID);
1020 }
1021
1022 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
1023
1024 REG_PIO_READ64(handle, offset, &sel.value);
1025 sel.bits.ldw.ext = BIT_ENABLE; /* enable */
1026 REG_PIO_WRITE64(handle, offset, sel.value);
1027
1028 return (NPI_SUCCESS);
1029
1030 }
1031
1032 /*
1033 * npi_fflp_fcram_partition_disable
1034 * Disable previously configured FCRAM partition
1035 *
1036 * Input
1037 * handle: opaque handle interpreted by the underlying OS
1038 * partid: partition ID, Corresponds to the RDC table
1039 *
1040 * Return:
1041 * NPI Success/Failure status code
1042 */
1043 npi_status_t
npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle,part_id_t partid)1044 npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid)
1045
1046 {
1047
1048 flow_prt_sel_t sel;
1049 uint64_t offset;
1050
1051 ASSERT(FCRAM_PARTITION_VALID(partid));
1052 if (!FCRAM_PARTITION_VALID(partid)) {
1053 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1054 " fcram_partition disable:"
1055 " Invalid Partition %d \n",
1056 partid));
1057 return (NPI_FFLP_FCRAM_PART_INVALID);
1058 }
1059 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG);
1060 REG_PIO_READ64(handle, offset, &sel.value);
1061 sel.bits.ldw.ext = BIT_DISABLE; /* disable */
1062 REG_PIO_WRITE64(handle, offset, sel.value);
1063 return (NPI_SUCCESS);
1064 }
1065
1066 /*
1067 * npi_fflp_cam_errorcheck_disable
1068 * Disables FCRAM and TCAM error checking
1069 */
1070 npi_status_t
npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)1071 npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle)
1072
1073 {
1074
1075 fflp_cfg_1_t fflp_cfg;
1076 uint64_t offset;
1077 offset = FFLP_CFG_1_REG;
1078
1079 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1080
1081 fflp_cfg.bits.ldw.errordis = BIT_ENABLE;
1082 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1083
1084 return (NPI_SUCCESS);
1085
1086 }
1087
1088 /*
1089 * npi_fflp_cam_errorcheck_enable
1090 * Enables FCRAM and TCAM error checking
1091 */
1092 npi_status_t
npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)1093 npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle)
1094
1095 {
1096 fflp_cfg_1_t fflp_cfg;
1097 uint64_t offset;
1098 offset = FFLP_CFG_1_REG;
1099
1100 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1101
1102 fflp_cfg.bits.ldw.errordis = BIT_DISABLE;
1103 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1104
1105 return (NPI_SUCCESS);
1106
1107 }
1108
1109 /*
1110 * npi_fflp_cam_llcsnap_enable
1111 * Enables input parser llcsnap recognition
1112 */
1113 npi_status_t
npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)1114 npi_fflp_cfg_llcsnap_enable(npi_handle_t handle)
1115
1116 {
1117
1118 fflp_cfg_1_t fflp_cfg;
1119 uint64_t offset;
1120 offset = FFLP_CFG_1_REG;
1121
1122 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1123
1124 fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE;
1125 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1126
1127 return (NPI_SUCCESS);
1128
1129 }
1130
1131 /*
1132 * npi_fflp_cam_llcsnap_disable
1133 * Disables input parser llcsnap recognition
1134 */
1135 npi_status_t
npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)1136 npi_fflp_cfg_llcsnap_disable(npi_handle_t handle)
1137
1138 {
1139
1140
1141 fflp_cfg_1_t fflp_cfg;
1142 uint64_t offset;
1143 offset = FFLP_CFG_1_REG;
1144
1145 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
1146
1147 fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE;
1148 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
1149
1150 return (NPI_SUCCESS);
1151
1152 }
1153
1154 /*
1155 * npi_fflp_config_fcram_refresh
1156 * Set FCRAM min and max refresh time.
1157 *
1158 * Input
1159 * handle opaque handle interpreted by the underlying OS
1160 * min_time Minimum Refresh time count
1161 * max_time maximum Refresh Time count
1162 * sys_time System Clock rate
1163 *
1164 * The counters are 16 bit counters. The maximum refresh time is
1165 * 3.9us/clock cycle. The minimum is 400ns/clock cycle.
1166 * Clock cycle is the FCRAM clock cycle?????
1167 * If the cycle is FCRAM clock cycle, then sys_time parameter
1168 * is not needed as there wont be configuration variation due to
1169 * system clock cycle.
1170 *
1171 * Return:
1172 * NPI Success/Failure status code
1173 */
1174 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)1175 npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time,
1176 uint32_t max_time, uint32_t sys_time)
1177
1178 {
1179
1180 uint64_t offset;
1181 fcram_ref_tmr_t refresh_timer_reg;
1182 uint16_t max, min;
1183
1184 offset = FFLP_FCRAM_REF_TMR_REG;
1185 /* need to figure out how to dervive the numbers */
1186 max = max_time * sys_time;
1187 min = min_time * sys_time;
1188 /* for now, just set with #def values */
1189
1190 max = FCRAM_REFRESH_DEFAULT_MAX_TIME;
1191 min = FCRAM_REFRESH_DEFAULT_MIN_TIME;
1192 REG_PIO_READ64(handle, offset, &refresh_timer_reg.value);
1193 refresh_timer_reg.bits.ldw.min = min;
1194 refresh_timer_reg.bits.ldw.max = max;
1195 REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value);
1196 return (NPI_SUCCESS);
1197 }
1198
1199 /*
1200 * npi_fflp_hash_lookup_err_report
1201 * Reports hash table (fcram) lookup errors
1202 *
1203 * Input
1204 * handle opaque handle interpreted by the underlying OS
1205 * err_stat Pointer to return Error bits
1206 *
1207 *
1208 * Return:
1209 * NPI success/failure status code
1210 */
1211 npi_status_t
npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,hash_lookup_err_log_t * err_stat)1212 npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle,
1213 hash_lookup_err_log_t *err_stat)
1214
1215 {
1216
1217 hash_lookup_err_log1_t err_log1;
1218 hash_lookup_err_log2_t err_log2;
1219 uint64_t err_log1_offset, err_log2_offset;
1220 err_log1.value = 0;
1221 err_log2.value = 0;
1222
1223 err_log1_offset = HASH_LKUP_ERR_LOG1_REG;
1224 err_log2_offset = HASH_LKUP_ERR_LOG2_REG;
1225
1226 REG_PIO_READ64(handle, err_log1_offset, &err_log1.value);
1227 REG_PIO_READ64(handle, err_log2_offset, &err_log2.value);
1228
1229 if (err_log1.value) {
1230 /* nonzero means there are some errors */
1231 err_stat->lookup_err = BIT_ENABLE;
1232 err_stat->syndrome = err_log2.bits.ldw.syndrome;
1233 err_stat->subarea = err_log2.bits.ldw.subarea;
1234 err_stat->h1 = err_log2.bits.ldw.h1;
1235 err_stat->multi_bit = err_log1.bits.ldw.mult_bit;
1236 err_stat->multi_lkup = err_log1.bits.ldw.mult_lk;
1237 err_stat->ecc_err = err_log1.bits.ldw.ecc_err;
1238 err_stat->uncor_err = err_log1.bits.ldw.cu;
1239 } else {
1240 err_stat->lookup_err = BIT_DISABLE;
1241 }
1242
1243 return (NPI_SUCCESS);
1244
1245 }
1246
1247 /*
1248 * npi_fflp_fcram_get_pio_err_log
1249 * Reports hash table PIO read errors for the given partition.
1250 * by default, it clears the error bit which was set by the HW.
1251 *
1252 * Input
1253 * handle: opaque handle interpreted by the underlying OS
1254 * partid: partition ID
1255 * err_stat Pointer to return Error bits
1256 *
1257 * Return
1258 * NPI success/failure status code
1259 */
1260 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)1261 npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid,
1262 hash_pio_err_log_t *err_stat)
1263 {
1264
1265 hash_tbl_data_log_t err_log;
1266 uint64_t offset;
1267
1268 ASSERT(FCRAM_PARTITION_VALID(partid));
1269 if (!FCRAM_PARTITION_VALID(partid)) {
1270 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1271 " fcram_get_pio_err_log:"
1272 " Invalid Partition %d \n",
1273 partid));
1274 return (NPI_FFLP_FCRAM_PART_INVALID);
1275 }
1276
1277 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
1278 FFLP_HASH_TBL_DATA_LOG_REG);
1279
1280 REG_PIO_READ64(handle, offset, &err_log.value);
1281
1282 if (err_log.bits.ldw.pio_err == BIT_ENABLE) {
1283 /* nonzero means there are some errors */
1284 err_stat->pio_err = BIT_ENABLE;
1285 err_stat->syndrome = err_log.bits.ldw.syndrome;
1286 err_stat->addr = err_log.bits.ldw.fcram_addr;
1287 err_log.value = 0;
1288 REG_PIO_WRITE64(handle, offset, err_log.value);
1289 } else {
1290 err_stat->pio_err = BIT_DISABLE;
1291 }
1292
1293 return (NPI_SUCCESS);
1294
1295 }
1296
1297 /*
1298 * npi_fflp_fcram_clr_pio_err_log
1299 * Clears FCRAM PIO error status for the partition.
1300 * If there are TCAM errors as indicated by err bit set by HW,
1301 * then the SW will clear it by clearing the bit.
1302 *
1303 * Input
1304 * handle: opaque handle interpreted by the underlying OS
1305 * partid: partition ID
1306 *
1307 *
1308 * Return
1309 * NPI success/failure status code
1310 */
1311 npi_status_t
npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle,part_id_t partid)1312 npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid)
1313 {
1314 uint64_t offset;
1315
1316 hash_tbl_data_log_t err_log;
1317
1318 ASSERT(FCRAM_PARTITION_VALID(partid));
1319 if (!FCRAM_PARTITION_VALID(partid)) {
1320 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1321 " fcram_clr_pio_err_log:"
1322 " Invalid Partition %d \n",
1323 partid));
1324
1325 return (NPI_FFLP_FCRAM_PART_INVALID);
1326 }
1327
1328 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid,
1329 FFLP_HASH_TBL_DATA_LOG_REG);
1330
1331 err_log.value = 0;
1332 REG_PIO_WRITE64(handle, offset, err_log.value);
1333
1334
1335 return (NPI_SUCCESS);
1336
1337 }
1338
1339 /*
1340 * npi_fflp_tcam_get_err_log
1341 * Reports TCAM PIO read and lookup errors.
1342 * If there are TCAM errors as indicated by err bit set by HW,
1343 * then the SW will clear it by clearing the bit.
1344 *
1345 * Input
1346 * handle: opaque handle interpreted by the underlying OS
1347 * err_stat: structure to report various TCAM errors.
1348 * will be updated if there are TCAM errors.
1349 *
1350 *
1351 * Return
1352 * NPI_SUCCESS Success
1353 *
1354 *
1355 */
1356 npi_status_t
npi_fflp_tcam_get_err_log(npi_handle_t handle,tcam_err_log_t * err_stat)1357 npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat)
1358 {
1359 tcam_err_t err_log;
1360 uint64_t offset;
1361
1362 offset = FFLP_TCAM_ERR_REG;
1363 err_log.value = 0;
1364
1365 REG_PIO_READ64(handle, offset, &err_log.value);
1366
1367 if (err_log.bits.ldw.err == BIT_ENABLE) {
1368 /* non-zero means err */
1369 err_stat->tcam_err = BIT_ENABLE;
1370 if (err_log.bits.ldw.p_ecc) {
1371 err_stat->parity_err = 0;
1372 err_stat->ecc_err = 1;
1373 } else {
1374 err_stat->parity_err = 1;
1375 err_stat->ecc_err = 0;
1376
1377 }
1378 err_stat->syndrome = err_log.bits.ldw.syndrome;
1379 err_stat->location = err_log.bits.ldw.addr;
1380
1381
1382 err_stat->multi_lkup = err_log.bits.ldw.mult;
1383 /* now clear the error */
1384 err_log.value = 0;
1385 REG_PIO_WRITE64(handle, offset, err_log.value);
1386
1387 } else {
1388 err_stat->tcam_err = 0;
1389 }
1390 return (NPI_SUCCESS);
1391
1392 }
1393
1394 /*
1395 * npi_fflp_tcam_clr_err_log
1396 * Clears TCAM PIO read and lookup error status.
1397 * If there are TCAM errors as indicated by err bit set by HW,
1398 * then the SW will clear it by clearing the bit.
1399 *
1400 * Input
1401 * handle: opaque handle interpreted by the underlying OS
1402 *
1403 *
1404 * Return
1405 * NPI_SUCCESS Success
1406 *
1407 *
1408 */
1409 npi_status_t
npi_fflp_tcam_clr_err_log(npi_handle_t handle)1410 npi_fflp_tcam_clr_err_log(npi_handle_t handle)
1411 {
1412 tcam_err_t err_log;
1413 uint64_t offset;
1414
1415 offset = FFLP_TCAM_ERR_REG;
1416 err_log.value = 0;
1417 REG_PIO_WRITE64(handle, offset, err_log.value);
1418
1419 return (NPI_SUCCESS);
1420
1421 }
1422
1423 /*
1424 * npi_fflp_fcram_err_synd_test
1425 * Tests the FCRAM error detection logic.
1426 * The error detection logic for the syndrome is tested.
1427 * tst0->synd (8bits) are set to select the syndrome bits
1428 * to be XOR'ed
1429 *
1430 * Input
1431 * handle: opaque handle interpreted by the underlying OS
1432 * syndrome_bits: Syndrome bits to select bits to be xor'ed
1433 *
1434 *
1435 * Return
1436 * NPI_SUCCESS Success
1437 *
1438 *
1439 */
1440 npi_status_t
npi_fflp_fcram_err_synd_test(npi_handle_t handle,uint8_t syndrome_bits)1441 npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits)
1442 {
1443
1444 uint64_t t0_offset;
1445 fcram_err_tst0_t tst0;
1446 t0_offset = FFLP_FCRAM_ERR_TST0_REG;
1447
1448 tst0.value = 0;
1449 tst0.bits.ldw.syndrome_mask = syndrome_bits;
1450
1451 REG_PIO_WRITE64(handle, t0_offset, tst0.value);
1452
1453 return (NPI_SUCCESS);
1454
1455 }
1456
1457 /*
1458 * npi_fflp_fcram_err_data_test
1459 * Tests the FCRAM error detection logic.
1460 * The error detection logic for the datapath is tested.
1461 * bits [63:0] are set to select the data bits to be xor'ed
1462 *
1463 * Input
1464 * handle: opaque handle interpreted by the underlying OS
1465 * data: data bits to select bits to be xor'ed
1466 *
1467 *
1468 * Return
1469 * NPI_SUCCESS Success
1470 *
1471 *
1472 */
1473 npi_status_t
npi_fflp_fcram_err_data_test(npi_handle_t handle,fcram_err_data_t * data)1474 npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data)
1475 {
1476
1477 uint64_t t1_offset, t2_offset;
1478 fcram_err_tst1_t tst1; /* for data bits [31:0] */
1479 fcram_err_tst2_t tst2; /* for data bits [63:32] */
1480
1481 t1_offset = FFLP_FCRAM_ERR_TST1_REG;
1482 t2_offset = FFLP_FCRAM_ERR_TST2_REG;
1483 tst1.value = 0;
1484 tst2.value = 0;
1485 tst1.bits.ldw.dat = data->bits.ldw.dat;
1486 tst2.bits.ldw.dat = data->bits.hdw.dat;
1487
1488 REG_PIO_WRITE64(handle, t1_offset, tst1.value);
1489 REG_PIO_WRITE64(handle, t2_offset, tst2.value);
1490
1491 return (NPI_SUCCESS);
1492
1493 }
1494
1495 /*
1496 * npi_fflp_cfg_enet_vlan_table_assoc
1497 * associates port vlan id to rdc table.
1498 *
1499 * Input
1500 * handle opaque handle interpreted by the underlying OS
1501 * mac_portn port number
1502 * vlan_id VLAN ID
1503 * rdc_table RDC Table #
1504 * priority priority
1505 *
1506 * Output
1507 *
1508 * NPI success/failure status code
1509 *
1510 */
1511 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)1512 npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn,
1513 vlan_id_t vlan_id, uint8_t rdc_table,
1514 uint8_t priority)
1515 {
1516
1517 fflp_enet_vlan_tbl_t cfg;
1518 uint64_t offset;
1519 uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3};
1520 uint8_t parity_bit;
1521
1522 ASSERT(FFLP_VLAN_VALID(vlan_id));
1523 if (!FFLP_VLAN_VALID(vlan_id)) {
1524 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1525 " fflp_cfg_enet_vlan_table:"
1526 " Invalid vlan ID %d \n",
1527 vlan_id));
1528 return (NPI_FFLP_VLAN_INVALID);
1529 }
1530
1531 ASSERT(FFLP_PORT_VALID(mac_portn));
1532 if (!FFLP_PORT_VALID(mac_portn)) {
1533 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1534 " fflp_cfg_enet_vlan_table:"
1535 " Invalid port num %d \n",
1536 mac_portn));
1537 return (NPI_FFLP_PORT_INVALID);
1538 }
1539
1540 ASSERT(FFLP_RDC_TABLE_VALID(rdc_table));
1541 if (!FFLP_RDC_TABLE_VALID(rdc_table)) {
1542 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1543 " fflp_cfg_enet_vlan_table:"
1544 " Invalid RDC Table %d \n",
1545 rdc_table));
1546 return (NPI_FFLP_RDC_TABLE_INVALID);
1547 }
1548
1549 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
1550 REG_PIO_READ64(handle, offset, &cfg.value);
1551
1552 switch (mac_portn) {
1553 case 0:
1554 cfg.bits.ldw.vlanrdctbln0 = rdc_table;
1555 if (priority)
1556 cfg.bits.ldw.vpr0 = BIT_ENABLE;
1557 else
1558 cfg.bits.ldw.vpr0 = BIT_DISABLE;
1559 /* set the parity bits */
1560 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
1561 vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
1562 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
1563 cfg.bits.ldw.parity0 = parity_bit & 0x1;
1564 break;
1565 case 1:
1566 cfg.bits.ldw.vlanrdctbln1 = rdc_table;
1567 if (priority)
1568 cfg.bits.ldw.vpr1 = BIT_ENABLE;
1569 else
1570 cfg.bits.ldw.vpr1 = BIT_DISABLE;
1571 /* set the parity bits */
1572 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] +
1573 vlan_parity[cfg.bits.ldw.vlanrdctbln1] +
1574 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1;
1575 cfg.bits.ldw.parity0 = parity_bit & 0x1;
1576
1577 break;
1578 case 2:
1579 cfg.bits.ldw.vlanrdctbln2 = rdc_table;
1580 if (priority)
1581 cfg.bits.ldw.vpr2 = BIT_ENABLE;
1582 else
1583 cfg.bits.ldw.vpr2 = BIT_DISABLE;
1584 /* set the parity bits */
1585 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
1586 vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
1587 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
1588 cfg.bits.ldw.parity1 = parity_bit & 0x1;
1589
1590 break;
1591 case 3:
1592 cfg.bits.ldw.vlanrdctbln3 = rdc_table;
1593 if (priority)
1594 cfg.bits.ldw.vpr3 = BIT_ENABLE;
1595 else
1596 cfg.bits.ldw.vpr3 = BIT_DISABLE;
1597 /* set the parity bits */
1598 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] +
1599 vlan_parity[cfg.bits.ldw.vlanrdctbln3] +
1600 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3;
1601 cfg.bits.ldw.parity1 = parity_bit & 0x1;
1602 break;
1603 default:
1604 return (NPI_FFLP_SW_PARAM_ERROR);
1605 }
1606
1607 REG_PIO_WRITE64(handle, offset, cfg.value);
1608 return (NPI_SUCCESS);
1609 }
1610
1611 /*
1612 * npi_fflp_cfg_enet_vlan_table_set_pri
1613 * sets the vlan based classification priority in respect to L2DA
1614 * classification.
1615 *
1616 * Input
1617 * handle opaque handle interpreted by the underlying OS
1618 * mac_portn port number
1619 * vlan_id VLAN ID
1620 * priority priority
1621 * 1: vlan classification has higher priority
1622 * 0: l2da classification has higher priority
1623 *
1624 * Output
1625 *
1626 * NPI success/failure status code
1627 */
1628 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)1629 npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn,
1630 vlan_id_t vlan_id, uint8_t priority)
1631 {
1632
1633 fflp_enet_vlan_tbl_t cfg;
1634 uint64_t offset;
1635 uint64_t old_value;
1636
1637 ASSERT(FFLP_VLAN_VALID(vlan_id));
1638 if (!FFLP_VLAN_VALID(vlan_id)) {
1639 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1640 " enet_vlan_table set pri:"
1641 " Invalid vlan ID %d \n",
1642 vlan_id));
1643 return (NPI_FFLP_VLAN_INVALID);
1644 }
1645
1646 ASSERT(FFLP_PORT_VALID(mac_portn));
1647 if (!FFLP_PORT_VALID(mac_portn)) {
1648 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1649 " enet_vlan_table set pri:"
1650 " Invalid port num %d \n",
1651 mac_portn));
1652 return (NPI_FFLP_PORT_INVALID);
1653 }
1654
1655
1656 offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id << 3);
1657 REG_PIO_READ64(handle, offset, &cfg.value);
1658 old_value = cfg.value;
1659 switch (mac_portn) {
1660 case 0:
1661 if (priority)
1662 cfg.bits.ldw.vpr0 = BIT_ENABLE;
1663 else
1664 cfg.bits.ldw.vpr0 = BIT_DISABLE;
1665 break;
1666 case 1:
1667 if (priority)
1668 cfg.bits.ldw.vpr1 = BIT_ENABLE;
1669 else
1670 cfg.bits.ldw.vpr1 = BIT_DISABLE;
1671 break;
1672 case 2:
1673 if (priority)
1674 cfg.bits.ldw.vpr2 = BIT_ENABLE;
1675 else
1676 cfg.bits.ldw.vpr2 = BIT_DISABLE;
1677 break;
1678 case 3:
1679 if (priority)
1680 cfg.bits.ldw.vpr3 = BIT_ENABLE;
1681 else
1682 cfg.bits.ldw.vpr3 = BIT_DISABLE;
1683 break;
1684 default:
1685 return (NPI_FFLP_SW_PARAM_ERROR);
1686 }
1687 if (old_value != cfg.value) {
1688 if (mac_portn > 1)
1689 cfg.bits.ldw.parity1++;
1690 else
1691 cfg.bits.ldw.parity0++;
1692
1693 REG_PIO_WRITE64(handle, offset, cfg.value);
1694 }
1695 return (NPI_SUCCESS);
1696 }
1697
1698 /*
1699 * npi_fflp_cfg_vlan_table_clear
1700 * Clears the vlan RDC table
1701 *
1702 * Input
1703 * handle opaque handle interpreted by the underlying OS
1704 * vlan_id VLAN ID
1705 *
1706 * Output
1707 *
1708 * NPI success/failure status code
1709 *
1710 */
1711 npi_status_t
npi_fflp_cfg_vlan_table_clear(npi_handle_t handle,vlan_id_t vlan_id)1712 npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id)
1713 {
1714
1715 uint64_t offset;
1716 uint64_t clear = 0ULL;
1717 vlan_id_t start_vlan = 0;
1718
1719 if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) {
1720 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1721 " enet_vlan_table clear:"
1722 " Invalid vlan ID %d \n",
1723 vlan_id));
1724 return (NPI_FFLP_VLAN_INVALID);
1725 }
1726
1727
1728 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG);
1729
1730 REG_PIO_WRITE64(handle, offset, clear);
1731 return (NPI_SUCCESS);
1732 }
1733
1734 /*
1735 * npi_fflp_vlan_tbl_get_err_log
1736 * Reports VLAN Table errors.
1737 * If there are VLAN Table errors as indicated by err bit set by HW,
1738 * then the SW will clear it by clearing the bit.
1739 *
1740 * Input
1741 * handle: opaque handle interpreted by the underlying OS
1742 * err_stat: structure to report various VLAN table errors.
1743 * will be updated if there are errors.
1744 *
1745 *
1746 * Return
1747 * NPI_SUCCESS Success
1748 *
1749 *
1750 */
1751 npi_status_t
npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle,vlan_tbl_err_log_t * err_stat)1752 npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat)
1753 {
1754 vlan_par_err_t err_log;
1755 uint64_t offset;
1756
1757
1758 offset = FFLP_VLAN_PAR_ERR_REG;
1759 err_log.value = 0;
1760
1761 REG_PIO_READ64(handle, offset, &err_log.value);
1762
1763 if (err_log.bits.ldw.err == BIT_ENABLE) {
1764 /* non-zero means err */
1765 err_stat->err = BIT_ENABLE;
1766 err_stat->multi = err_log.bits.ldw.m_err;
1767 err_stat->addr = err_log.bits.ldw.addr;
1768 err_stat->data = err_log.bits.ldw.data;
1769 /* now clear the error */
1770 err_log.value = 0;
1771 REG_PIO_WRITE64(handle, offset, err_log.value);
1772
1773 } else {
1774 err_stat->err = 0;
1775 }
1776
1777 return (NPI_SUCCESS);
1778 }
1779
1780 /*
1781 * npi_fflp_vlan_tbl_clr_err_log
1782 * Clears VLAN Table PIO error status.
1783 * If there are VLAN Table errors as indicated by err bit set by HW,
1784 * then the SW will clear it by clearing the bit.
1785 *
1786 * Input
1787 * handle: opaque handle interpreted by the underlying OS
1788 *
1789 *
1790 * Return
1791 * NPI_SUCCESS Success
1792 *
1793 *
1794 */
1795 npi_status_t
npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)1796 npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle)
1797 {
1798 vlan_par_err_t err_log;
1799 uint64_t offset;
1800
1801 offset = FFLP_VLAN_PAR_ERR_REG;
1802 err_log.value = 0;
1803
1804 REG_PIO_WRITE64(handle, offset, err_log.value);
1805
1806 return (NPI_SUCCESS);
1807 }
1808
1809 /*
1810 * npi_fflp_cfg_enet_usr_cls_set()
1811 * Configures a user configurable ethernet class
1812 *
1813 * Input
1814 * handle: opaque handle interpreted by the underlying OS
1815 * class: Ethernet Class class
1816 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1817 * enet_type: 16 bit Ethernet Type value, corresponding ethernet bytes
1818 * [13:14] in the frame.
1819 *
1820 * by default, the class will be disabled until explicitly enabled.
1821 *
1822 * Return
1823 * NPI success/failure status code
1824 */
1825 npi_status_t
npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,tcam_class_t class,uint16_t enet_type)1826 npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle,
1827 tcam_class_t class, uint16_t enet_type)
1828 {
1829 uint64_t offset;
1830 tcam_class_prg_ether_t cls_cfg;
1831 cls_cfg.value = 0x0;
1832
1833 /* check if etype is valid */
1834 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1835 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1836 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1837 " npi_fflp_cfg_enet_usr_cls_set:"
1838 " Invalid class %d \n",
1839 class));
1840 return (NPI_FFLP_TCAM_CLASS_INVALID);
1841 }
1842 offset = GET_TCAM_CLASS_OFFSET(class);
1843
1844 /*
1845 * etype check code
1846 *
1847 * if (check_fail)
1848 * return (NPI_FAILURE | NPI_SW_ERROR);
1849 */
1850
1851 cls_cfg.bits.ldw.etype = enet_type;
1852 cls_cfg.bits.ldw.valid = BIT_DISABLE;
1853 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1854 return (NPI_SUCCESS);
1855 }
1856
1857 /*
1858 * npi_fflp_cfg_enet_usr_cls_enable()
1859 * Enable previously configured TCAM user configurable Ethernet classes.
1860 *
1861 * Input
1862 * handle: opaque handle interpreted by the underlying OS
1863 * class: Ethernet Class class
1864 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1865 *
1866 * Return
1867 * NPI success/failure status code
1868 */
1869 npi_status_t
npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle,tcam_class_t class)1870 npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
1871 {
1872 uint64_t offset;
1873 tcam_class_prg_ether_t cls_cfg;
1874
1875 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1876 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1877 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1878 " npi_fflp_cfg_enet_usr_cls_enable:"
1879 " Invalid class %d \n",
1880 class));
1881 return (NPI_FFLP_TCAM_CLASS_INVALID);
1882 }
1883
1884 offset = GET_TCAM_CLASS_OFFSET(class);
1885
1886 REG_PIO_READ64(handle, offset, &cls_cfg.value);
1887 cls_cfg.bits.ldw.valid = BIT_ENABLE;
1888 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1889 return (NPI_SUCCESS);
1890 }
1891
1892 /*
1893 * npi_fflp_cfg_enet_usr_cls_disable()
1894 * Disables previously configured TCAM user configurable Ethernet classes.
1895 *
1896 * Input
1897 * handle: opaque handle interpreted by the underlying OS
1898 * class: Ethernet Class class
1899 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2)
1900 *
1901 * Return
1902 * NPI success/failure status code
1903 */
1904 npi_status_t
npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle,tcam_class_t class)1905 npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
1906 {
1907 uint64_t offset;
1908 tcam_class_prg_ether_t cls_cfg;
1909
1910 ASSERT(TCAM_L2_USR_CLASS_VALID(class));
1911 if (!TCAM_L2_USR_CLASS_VALID(class)) {
1912 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1913 " npi_fflp_cfg_enet_usr_cls_disable:"
1914 " Invalid class %d \n",
1915 class));
1916 return (NPI_FFLP_TCAM_CLASS_INVALID);
1917 }
1918
1919 offset = GET_TCAM_CLASS_OFFSET(class);
1920
1921 REG_PIO_READ64(handle, offset, &cls_cfg.value);
1922 cls_cfg.bits.ldw.valid = BIT_DISABLE;
1923
1924 REG_PIO_WRITE64(handle, offset, cls_cfg.value);
1925 return (NPI_SUCCESS);
1926 }
1927
1928 /*
1929 * npi_fflp_cfg_ip_usr_cls_set()
1930 * Configures the TCAM user configurable IP classes.
1931 *
1932 * Input
1933 * handle: opaque handle interpreted by the underlying OS
1934 * class: IP Class class
1935 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
1936 * tos: IP TOS bits
1937 * tos_mask: IP TOS bits mask. bits with mask bits set will be used
1938 * proto: IP Proto
1939 * ver: IP Version
1940 * by default, will the class is disabled until explicitly enabled
1941 *
1942 * Return
1943 * NPI success/failure status code
1944 */
1945 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)1946 npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class,
1947 uint8_t tos, uint8_t tos_mask,
1948 uint8_t proto, uint8_t ver)
1949 {
1950 uint64_t offset;
1951 tcam_class_prg_ip_t ip_cls_cfg;
1952
1953 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
1954 if (!TCAM_L3_USR_CLASS_VALID(class)) {
1955 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1956 " npi_fflp_cfg_ip_usr_cls_set:"
1957 " Invalid class %d \n",
1958 class));
1959 return (NPI_FFLP_TCAM_CLASS_INVALID);
1960 }
1961
1962 offset = GET_TCAM_CLASS_OFFSET(class);
1963
1964 ip_cls_cfg.bits.ldw.pid = proto;
1965 ip_cls_cfg.bits.ldw.ipver = ver;
1966 ip_cls_cfg.bits.ldw.tos = tos;
1967 ip_cls_cfg.bits.ldw.tosmask = tos_mask;
1968 ip_cls_cfg.bits.ldw.valid = 0;
1969 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
1970 return (NPI_SUCCESS);
1971
1972 }
1973
1974 /*
1975 * npi_fflp_cfg_ip_usr_cls_set_iptun()
1976 * Configures the TCAM user configurable IP classes. This function sets the
1977 * new fields that were added for IP tunneling support
1978 *
1979 * Input
1980 * handle: opaque handle interpreted by the underlying OS
1981 * class: IP Class class
1982 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
1983 * l4b0_val value of the first L4 byte to be compared
1984 * l4b0_msk mask to apply to compare byte 0 of L4
1985 * l4b23_val values of L4 bytes 2 and 3 to compare
1986 * l4b23_sel set to 1 to compare L4 bytes 2 and 3.
1987 * by default, the class is disabled until explicitly enabled
1988 *
1989 * Return
1990 * NPI success/failure status code
1991 */
1992 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)1993 npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class,
1994 uint8_t l4b0_val, uint8_t l4b0_msk,
1995 uint16_t l4b23_val, uint8_t l4b23_sel)
1996 {
1997 uint64_t offset, val;
1998 tcam_class_prg_ip_t ip_cls_cfg;
1999
2000 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2001 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2002 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2003 " npi_fflp_cfg_ip_usr_cls_set:"
2004 " Invalid class %d \n",
2005 class));
2006 return (NPI_FFLP_TCAM_CLASS_INVALID);
2007 }
2008
2009 offset = GET_TCAM_CLASS_OFFSET(class);
2010 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2011
2012 val = 1;
2013 ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH);
2014 val = l4b0_val;
2015 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH);
2016 val = l4b0_msk;
2017 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH);
2018 val = l4b23_sel;
2019 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH);
2020 val = l4b23_val;
2021 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH);
2022
2023 ip_cls_cfg.bits.ldw.valid = 0;
2024 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2025 return (NPI_SUCCESS);
2026 }
2027
2028 /*
2029 * npi_fflp_cfg_ip_usr_cls_get_iptun()
2030 * Retrieves the IP tunneling related settings for the given TCAM user
2031 * configurable IP classe.
2032 *
2033 * Input
2034 * handle: opaque handle interpreted by the underlying OS
2035 * class: IP Class class
2036 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2037 * l4b0_val value of the first L4 byte to be compared
2038 * l4b0_msk mask to apply to compare byte 0 of L4
2039 * l4b23_val values of L4 bytes 2 and 3 to compare
2040 * l4b23_sel set to 1 to compare L4 bytes 2 and 3.
2041 * by default, the class is disabled until explicitly enabled
2042 *
2043 * Return
2044 * NPI success/failure status code
2045 */
2046 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)2047 npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class,
2048 uint8_t *l4b0_val, uint8_t *l4b0_msk,
2049 uint16_t *l4b23_val, uint8_t *l4b23_sel)
2050 {
2051 uint64_t offset;
2052 tcam_class_prg_ip_t ip_cls_cfg;
2053
2054 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2055 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2056 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2057 " npi_fflp_cfg_ip_usr_cls_set:"
2058 " Invalid class %d \n",
2059 class));
2060 return (NPI_FFLP_TCAM_CLASS_INVALID);
2061 }
2062
2063 offset = GET_TCAM_CLASS_OFFSET(class);
2064 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2065
2066 *l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) &
2067 L3_UCLS_L4B0_VAL_MSK;
2068 *l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) &
2069 L3_UCLS_L4B0_MASK_MSK;
2070 *l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) &
2071 L3_UCLS_L4B23_SEL_MSK;
2072 *l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) &
2073 L3_UCLS_L4B23_VAL_MSK;
2074
2075 return (NPI_SUCCESS);
2076
2077 }
2078
2079 /*
2080 * npi_fflp_cfg_ip_usr_cls_enable()
2081 * Enable previously configured TCAM user configurable IP classes.
2082 *
2083 * Input
2084 * handle: opaque handle interpreted by the underlying OS
2085 * class: IP Class class
2086 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2087 *
2088 * Return
2089 * NPI success/failure status code
2090 */
2091 npi_status_t
npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle,tcam_class_t class)2092 npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class)
2093 {
2094 uint64_t offset;
2095 tcam_class_prg_ip_t ip_cls_cfg;
2096
2097 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2098 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2099 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2100 " npi_fflp_cfg_ip_usr_cls_enable:"
2101 " Invalid class %d \n",
2102 class));
2103 return (NPI_FFLP_TCAM_CLASS_INVALID);
2104 }
2105
2106 offset = GET_TCAM_CLASS_OFFSET(class);
2107 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2108 ip_cls_cfg.bits.ldw.valid = 1;
2109
2110 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2111 return (NPI_SUCCESS);
2112
2113 }
2114
2115 /*
2116 * npi_fflp_cfg_ip_usr_cls_disable()
2117 * Disables previously configured TCAM user configurable IP classes.
2118 *
2119 * Input
2120 * handle: opaque handle interpreted by the underlying OS
2121 * class: IP Class class
2122 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7)
2123 *
2124 * Return
2125 * NPI success/failure status code
2126 */
2127 npi_status_t
npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle,tcam_class_t class)2128 npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class)
2129 {
2130 uint64_t offset;
2131 tcam_class_prg_ip_t ip_cls_cfg;
2132
2133 ASSERT(TCAM_L3_USR_CLASS_VALID(class));
2134 if (!TCAM_L3_USR_CLASS_VALID(class)) {
2135 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2136 " npi_fflp_cfg_ip_usr_cls_disable:"
2137 " Invalid class %d \n",
2138 class));
2139 return (NPI_FFLP_TCAM_CLASS_INVALID);
2140 }
2141
2142 offset = GET_TCAM_CLASS_OFFSET(class);
2143
2144 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value);
2145 ip_cls_cfg.bits.ldw.valid = 0;
2146
2147 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value);
2148 return (NPI_SUCCESS);
2149
2150 }
2151
2152 /*
2153 * npi_fflp_cfg_ip_cls_tcam_key ()
2154 *
2155 * Configures the TCAM key generation for the IP classes
2156 *
2157 * Input
2158 * handle: opaque handle interpreted by the underlying OS
2159 * l3_class: IP class to configure key generation
2160 * cfg: Configuration bits:
2161 * discard: Discard all frames of this class
2162 * use_ip_saddr: use ip src address (for ipv6)
2163 * use_ip_daddr: use ip dest address (for ipv6)
2164 * lookup_enable: Enable Lookup
2165 *
2166 *
2167 * Return
2168 * NPI success/failure status code
2169 */
2170 npi_status_t
npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,tcam_class_t l3_class,tcam_key_cfg_t * cfg)2171 npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle,
2172 tcam_class_t l3_class, tcam_key_cfg_t *cfg)
2173 {
2174 uint64_t offset;
2175 tcam_class_key_ip_t tcam_cls_cfg;
2176
2177 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2178 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2179 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2180 " npi_fflp_cfg_ip_cls_tcam_key:"
2181 " Invalid class %d \n",
2182 l3_class));
2183 return (NPI_FFLP_TCAM_CLASS_INVALID);
2184 }
2185
2186 if ((cfg->use_ip_daddr) &&
2187 (cfg->use_ip_saddr == cfg->use_ip_daddr)) {
2188 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2189 " npi_fflp_cfg_ip_cls_tcam_key:"
2190 " Invalid configuration %x for class %d \n",
2191 *cfg, l3_class));
2192 return (NPI_FFLP_SW_PARAM_ERROR);
2193 }
2194
2195
2196 offset = GET_TCAM_KEY_OFFSET(l3_class);
2197 tcam_cls_cfg.value = 0;
2198
2199 if (cfg->discard) {
2200 tcam_cls_cfg.bits.ldw.discard = 1;
2201 }
2202
2203 if (cfg->use_ip_saddr) {
2204 tcam_cls_cfg.bits.ldw.ipaddr = 1;
2205 }
2206
2207 if (cfg->use_ip_daddr) {
2208 tcam_cls_cfg.bits.ldw.ipaddr = 0;
2209 }
2210
2211 if (cfg->lookup_enable) {
2212 tcam_cls_cfg.bits.ldw.tsel = 1;
2213 }
2214
2215 REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value);
2216 return (NPI_SUCCESS);
2217 }
2218
2219 /*
2220 * npi_fflp_cfg_ip_cls_flow_key ()
2221 *
2222 * Configures the flow key generation for the IP classes
2223 * Flow key is used to generate the H1 hash function value
2224 * The fields used for the generation are configured using this
2225 * NPI function.
2226 *
2227 * Input
2228 * handle: opaque handle interpreted by the underlying OS
2229 * l3_class: IP class to configure flow key generation
2230 * cfg: Configuration bits:
2231 * use_proto: Use IP proto field
2232 * use_dport: use l4 destination port
2233 * use_sport: use l4 source port
2234 * ip_opts_exist: IP Options Present
2235 * use_daddr: use ip dest address
2236 * use_saddr: use ip source address
2237 * use_vlan: use VLAN ID
2238 * use_l2da: use L2 Dest MAC Address
2239 * use_portnum: use L2 virtual port number
2240 *
2241 *
2242 * Return
2243 * NPI success/failure status code
2244 */
2245 npi_status_t
npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,flow_key_cfg_t * cfg)2246 npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
2247 flow_key_cfg_t *cfg)
2248 {
2249 uint64_t offset;
2250 flow_class_key_ip_t flow_cfg_reg;
2251
2252 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2253 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2254 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2255 " npi_fflp_cfg_ip_cls_flow_key:"
2256 " Invalid class %d \n",
2257 l3_class));
2258 return (NPI_FFLP_TCAM_CLASS_INVALID);
2259 }
2260
2261
2262 offset = GET_FLOW_KEY_OFFSET(l3_class);
2263 flow_cfg_reg.value = 0; /* default */
2264
2265 if (cfg->use_proto) {
2266 flow_cfg_reg.bits.ldw.proto = 1;
2267 }
2268
2269 if (cfg->use_dport) {
2270 flow_cfg_reg.bits.ldw.l4_1 = 2;
2271 if (cfg->ip_opts_exist)
2272 flow_cfg_reg.bits.ldw.l4_1 = 3;
2273 }
2274
2275 if (cfg->use_sport) {
2276 flow_cfg_reg.bits.ldw.l4_0 = 2;
2277 if (cfg->ip_opts_exist)
2278 flow_cfg_reg.bits.ldw.l4_0 = 3;
2279 }
2280
2281 if (cfg->use_daddr) {
2282 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
2283 }
2284
2285 if (cfg->use_saddr) {
2286 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
2287 }
2288
2289 if (cfg->use_vlan) {
2290 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
2291 }
2292
2293 if (cfg->use_l2da) {
2294 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
2295 }
2296
2297 if (cfg->use_portnum) {
2298 flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
2299 }
2300
2301 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2302 return (NPI_SUCCESS);
2303
2304 }
2305
2306 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)2307 npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle,
2308 tcam_class_t l3_class,
2309 flow_key_cfg_t *cfg)
2310 {
2311 uint64_t offset;
2312 flow_class_key_ip_t flow_cfg_reg;
2313
2314 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2315 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2316 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2317 " npi_fflp_cfg_ip_cls_flow_key:"
2318 " Invalid class %d \n",
2319 l3_class));
2320 return (NPI_FFLP_TCAM_CLASS_INVALID);
2321 }
2322
2323 offset = GET_FLOW_KEY_OFFSET(l3_class);
2324
2325 cfg->use_proto = 0;
2326 cfg->use_dport = 0;
2327 cfg->use_sport = 0;
2328 cfg->ip_opts_exist = 0;
2329 cfg->use_daddr = 0;
2330 cfg->use_saddr = 0;
2331 cfg->use_vlan = 0;
2332 cfg->use_l2da = 0;
2333 cfg->use_portnum = 0;
2334
2335 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2336
2337 if (flow_cfg_reg.bits.ldw.proto) {
2338 cfg->use_proto = 1;
2339 }
2340
2341 if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
2342 cfg->use_dport = 1;
2343 }
2344
2345 if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
2346 cfg->use_dport = 1;
2347 cfg->ip_opts_exist = 1;
2348 }
2349
2350 if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
2351 cfg->use_sport = 1;
2352 }
2353
2354 if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
2355 cfg->use_sport = 1;
2356 cfg->ip_opts_exist = 1;
2357 }
2358
2359 if (flow_cfg_reg.bits.ldw.ipda) {
2360 cfg->use_daddr = 1;
2361 }
2362
2363 if (flow_cfg_reg.bits.ldw.ipsa) {
2364 cfg->use_saddr = 1;
2365 }
2366
2367 if (flow_cfg_reg.bits.ldw.vlan) {
2368 cfg->use_vlan = 1;
2369 }
2370
2371 if (flow_cfg_reg.bits.ldw.l2da) {
2372 cfg->use_l2da = 1;
2373 }
2374
2375 if (flow_cfg_reg.bits.ldw.port) {
2376 cfg->use_portnum = 1;
2377 }
2378
2379 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
2380 " npi_fflp_cfg_ip_cls_flow_get %llx \n",
2381 flow_cfg_reg.value));
2382
2383 return (NPI_SUCCESS);
2384
2385 }
2386
2387 /*
2388 * npi_fflp_cfg_ip_cls_flow_key_rfnl ()
2389 *
2390 * Configures the flow key generation for the IP classes
2391 * Flow key is used to generate the H1 hash function value
2392 * The fields used for the generation are configured using this
2393 * NPI function.
2394 *
2395 * Input
2396 * handle: opaque handle interpreted by the underlying OS
2397 * l3_class: IP class to configure flow key generation
2398 * cfg: Configuration bits:
2399 * l4_xor_sel: bit field to select the L4 payload
2400 * bytes for X-OR to get hash key.
2401 * use_l4_md: Set to 1 for enabling L4-mode.
2402 * use_sym: Set to 1 to use symmetric mode.
2403 * use_proto: Use IP proto field
2404 * use_dport: use l4 destination port
2405 * use_sport: use l4 source port
2406 * ip_opts_exist: IP Options Present
2407 * use_daddr: use ip dest address
2408 * use_saddr: use ip source address
2409 * use_vlan: use VLAN ID
2410 * use_l2da: use L2 Dest MAC Address
2411 * use_portnum: use L2 virtual port number
2412 *
2413 *
2414 * Return
2415 * NPI success/failure status code
2416 */
2417 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)2418 npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class,
2419 flow_key_cfg_t *cfg)
2420 {
2421 uint64_t offset;
2422 flow_class_key_ip_t flow_cfg_reg;
2423
2424 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2425 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2426 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2427 " npi_fflp_cfg_ip_cls_flow_key_rfnl:"
2428 " Invalid class %d \n",
2429 l3_class));
2430 return (NPI_FFLP_TCAM_CLASS_INVALID);
2431 }
2432
2433 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2434 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2435 } else {
2436 offset = GET_FLOW_KEY_OFFSET(l3_class);
2437 }
2438
2439 flow_cfg_reg.value = 0;
2440
2441 flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel;
2442
2443 if (cfg->use_l4_md)
2444 flow_cfg_reg.bits.ldw.l4_mode = 1;
2445
2446 if (cfg->use_sym)
2447 flow_cfg_reg.bits.ldw.sym = 1;
2448
2449 if (cfg->use_proto) {
2450 flow_cfg_reg.bits.ldw.proto = 1;
2451 }
2452
2453 if (cfg->use_dport) {
2454 flow_cfg_reg.bits.ldw.l4_1 = 2;
2455 if (cfg->ip_opts_exist)
2456 flow_cfg_reg.bits.ldw.l4_1 = 3;
2457 }
2458
2459 if (cfg->use_sport) {
2460 flow_cfg_reg.bits.ldw.l4_0 = 2;
2461 if (cfg->ip_opts_exist)
2462 flow_cfg_reg.bits.ldw.l4_0 = 3;
2463 }
2464
2465 if (cfg->use_daddr) {
2466 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE;
2467 }
2468
2469 if (cfg->use_saddr) {
2470 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE;
2471 }
2472
2473 if (cfg->use_vlan) {
2474 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE;
2475 }
2476
2477 if (cfg->use_l2da) {
2478 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE;
2479 }
2480
2481 if (cfg->use_portnum) {
2482 flow_cfg_reg.bits.ldw.port = BIT_ENABLE;
2483 }
2484
2485 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2486 return (NPI_SUCCESS);
2487
2488 }
2489
2490 npi_status_t
npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle,tcam_class_t l3_class,boolean_t enable)2491 npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class,
2492 boolean_t enable)
2493 {
2494 uint64_t offset;
2495 flow_class_key_ip_t flow_cfg_reg;
2496
2497 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2498 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2499 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2500 " npi_fflp_cfg_sym_ip_cls_flow_key:"
2501 " Invalid class %d \n",
2502 l3_class));
2503 return (NPI_FFLP_TCAM_CLASS_INVALID);
2504 }
2505
2506 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2507 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2508 } else {
2509 offset = GET_FLOW_KEY_OFFSET(l3_class);
2510 }
2511
2512 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2513
2514 if (enable && flow_cfg_reg.bits.ldw.sym == 0) {
2515 flow_cfg_reg.bits.ldw.sym = 1;
2516 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2517 } else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) {
2518 flow_cfg_reg.bits.ldw.sym = 0;
2519 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value);
2520 }
2521
2522 return (NPI_SUCCESS);
2523
2524 }
2525
2526 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)2527 npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle,
2528 tcam_class_t l3_class,
2529 flow_key_cfg_t *cfg)
2530 {
2531 uint64_t offset;
2532 flow_class_key_ip_t flow_cfg_reg;
2533
2534 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class));
2535 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) {
2536 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2537 " npi_fflp_cfg_ip_cls_flow_key_get_rfnl:"
2538 " Invalid class %d \n",
2539 l3_class));
2540 return (NPI_FFLP_TCAM_CLASS_INVALID);
2541 }
2542
2543 if (l3_class == TCAM_CLASS_IPV6_FRAG) {
2544 offset = FFLP_FLOW_KEY_IP6_FRAG_REG;
2545 } else {
2546 offset = GET_FLOW_KEY_OFFSET(l3_class);
2547 }
2548
2549 cfg->l4_xor_sel = 0;
2550 cfg->use_l4_md = 0;
2551 cfg->use_sym = 0;
2552 cfg->use_proto = 0;
2553 cfg->use_dport = 0;
2554 cfg->use_sport = 0;
2555 cfg->ip_opts_exist = 0;
2556 cfg->use_daddr = 0;
2557 cfg->use_saddr = 0;
2558 cfg->use_vlan = 0;
2559 cfg->use_l2da = 0;
2560 cfg->use_portnum = 0;
2561
2562 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value);
2563
2564 cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor;
2565
2566 if (flow_cfg_reg.bits.ldw.l4_mode)
2567 cfg->use_l4_md = 1;
2568
2569 if (flow_cfg_reg.bits.ldw.sym)
2570 cfg->use_sym = 1;
2571
2572 if (flow_cfg_reg.bits.ldw.proto) {
2573 cfg->use_proto = 1;
2574 }
2575
2576 if (flow_cfg_reg.bits.ldw.l4_1 == 2) {
2577 cfg->use_dport = 1;
2578 }
2579
2580 if (flow_cfg_reg.bits.ldw.l4_1 == 3) {
2581 cfg->use_dport = 1;
2582 cfg->ip_opts_exist = 1;
2583 }
2584
2585 if (flow_cfg_reg.bits.ldw.l4_0 == 2) {
2586 cfg->use_sport = 1;
2587 }
2588
2589 if (flow_cfg_reg.bits.ldw.l4_0 == 3) {
2590 cfg->use_sport = 1;
2591 cfg->ip_opts_exist = 1;
2592 }
2593
2594 if (flow_cfg_reg.bits.ldw.ipda) {
2595 cfg->use_daddr = 1;
2596 }
2597
2598 if (flow_cfg_reg.bits.ldw.ipsa) {
2599 cfg->use_saddr = 1;
2600 }
2601
2602 if (flow_cfg_reg.bits.ldw.vlan) {
2603 cfg->use_vlan = 1;
2604 }
2605
2606 if (flow_cfg_reg.bits.ldw.l2da) {
2607 cfg->use_l2da = 1;
2608 }
2609
2610 if (flow_cfg_reg.bits.ldw.port) {
2611 cfg->use_portnum = 1;
2612 }
2613
2614 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL,
2615 " npi_fflp_cfg_ip_cls_flow_get %llx \n",
2616 flow_cfg_reg.value));
2617
2618 return (NPI_SUCCESS);
2619
2620 }
2621
2622 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)2623 npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle,
2624 tcam_class_t l3_class, tcam_key_cfg_t *cfg)
2625 {
2626 uint64_t offset;
2627 tcam_class_key_ip_t tcam_cls_cfg;
2628
2629 ASSERT(TCAM_L3_CLASS_VALID(l3_class));
2630 if (!(TCAM_L3_CLASS_VALID(l3_class))) {
2631 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2632 " npi_fflp_cfg_ip_cls_tcam_key_get:"
2633 " Invalid class %d \n",
2634 l3_class));
2635 return (NPI_FFLP_TCAM_CLASS_INVALID);
2636 }
2637
2638
2639 offset = GET_TCAM_KEY_OFFSET(l3_class);
2640
2641 REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value);
2642
2643 cfg->discard = 0;
2644 cfg->use_ip_saddr = 0;
2645 cfg->use_ip_daddr = 1;
2646 cfg->lookup_enable = 0;
2647
2648 if (tcam_cls_cfg.bits.ldw.discard)
2649 cfg->discard = 1;
2650
2651 if (tcam_cls_cfg.bits.ldw.ipaddr) {
2652 cfg->use_ip_saddr = 1;
2653 cfg->use_ip_daddr = 0;
2654 }
2655
2656 if (tcam_cls_cfg.bits.ldw.tsel) {
2657 cfg->lookup_enable = 1;
2658 }
2659
2660 NPI_DEBUG_MSG((handle.function, NPI_CTL,
2661 " npi_fflp_cfg_ip_cls_tcam_key_get %llx \n",
2662 tcam_cls_cfg.value));
2663 return (NPI_SUCCESS);
2664 }
2665
2666 /*
2667 * npi_fflp_cfg_fcram_access ()
2668 *
2669 * Sets the ratio between the FCRAM pio and lookup access
2670 * Input:
2671 * handle: opaque handle interpreted by the underlying OS
2672 * access_ratio: 0 Lookup has the highest priority
2673 * 15 PIO has maximum possible priority
2674 *
2675 * Return
2676 * NPI success/failure status code
2677 */
2678 npi_status_t
npi_fflp_cfg_fcram_access(npi_handle_t handle,uint8_t access_ratio)2679 npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio)
2680 {
2681
2682 fflp_cfg_1_t fflp_cfg;
2683 uint64_t offset;
2684 offset = FFLP_CFG_1_REG;
2685
2686 if (access_ratio > 0xf) {
2687 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2688 " npi_fflp_cfg_fcram_access:"
2689 " Invalid access ratio %d \n",
2690 access_ratio));
2691 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2692 }
2693
2694 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2695 fflp_cfg.bits.ldw.fflpinitdone = 0;
2696 fflp_cfg.bits.ldw.fcramratio = access_ratio;
2697 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2698 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2699 fflp_cfg.bits.ldw.fflpinitdone = 1;
2700 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2701 return (NPI_SUCCESS);
2702
2703 }
2704
2705 /*
2706 * npi_fflp_cfg_tcam_access ()
2707 *
2708 * Sets the ratio between the TCAM pio and lookup access
2709 * Input:
2710 * handle: opaque handle interpreted by the underlying OS
2711 * access_ratio: 0 Lookup has the highest priority
2712 * 15 PIO has maximum possible priority
2713 * Return
2714 * NPI success/failure status code
2715 */
2716 npi_status_t
npi_fflp_cfg_tcam_access(npi_handle_t handle,uint8_t access_ratio)2717 npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio)
2718 {
2719 fflp_cfg_1_t fflp_cfg;
2720 uint64_t offset;
2721 offset = FFLP_CFG_1_REG;
2722
2723 if (access_ratio > 0xf) {
2724 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2725 " npi_fflp_cfg_tcram_access:"
2726 " Invalid access ratio %d \n",
2727 access_ratio));
2728 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2729 }
2730
2731 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2732 fflp_cfg.bits.ldw.fflpinitdone = 0;
2733 fflp_cfg.bits.ldw.camratio = access_ratio;
2734
2735 /* since the cam latency is fixed, we might set it here */
2736 fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY;
2737 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2738 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2739 fflp_cfg.bits.ldw.fflpinitdone = 1;
2740 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2741
2742 return (NPI_SUCCESS);
2743 }
2744
2745 /*
2746 * npi_fflp_cfg_hash_h1poly()
2747 * Initializes the H1 hash generation logic.
2748 *
2749 * Input
2750 * handle: opaque handle interpreted by the underlying OS
2751 * init_value: The initial value (seed)
2752 *
2753 * Return
2754 * NPI success/failure status code
2755 */
2756 npi_status_t
npi_fflp_cfg_hash_h1poly(npi_handle_t handle,uint32_t init_value)2757 npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value)
2758 {
2759
2760
2761 hash_h1poly_t h1_cfg;
2762 uint64_t offset;
2763 offset = FFLP_H1POLY_REG;
2764
2765 h1_cfg.value = 0;
2766 h1_cfg.bits.ldw.init_value = init_value;
2767
2768 REG_PIO_WRITE64(handle, offset, h1_cfg.value);
2769 return (NPI_SUCCESS);
2770 }
2771
2772 /*
2773 * npi_fflp_cfg_hash_h2poly()
2774 * Initializes the H2 hash generation logic.
2775 *
2776 * Input
2777 * handle: opaque handle interpreted by the underlying OS
2778 * init_value: The initial value (seed)
2779 *
2780 * Return
2781 * NPI_SUCCESS
2782 *
2783 */
2784 npi_status_t
npi_fflp_cfg_hash_h2poly(npi_handle_t handle,uint16_t init_value)2785 npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value)
2786 {
2787
2788
2789 hash_h2poly_t h2_cfg;
2790 uint64_t offset;
2791 offset = FFLP_H2POLY_REG;
2792
2793 h2_cfg.value = 0;
2794 h2_cfg.bits.ldw.init_value = init_value;
2795
2796 REG_PIO_WRITE64(handle, offset, h2_cfg.value);
2797 return (NPI_SUCCESS);
2798
2799
2800 }
2801
2802 /*
2803 * npi_fflp_cfg_reset
2804 * Initializes the FCRAM reset sequence.
2805 *
2806 * Input
2807 * handle: opaque handle interpreted by the underlying OS
2808 * strength: FCRAM Drive strength
2809 * strong, weak or normal
2810 * HW recommended value:
2811 * qs: FCRAM QS mode selection
2812 * qs mode or free running
2813 * HW recommended value is:
2814 *
2815 * Return:
2816 * NPI success/failure status code
2817 */
2818
2819 npi_status_t
npi_fflp_cfg_fcram_reset(npi_handle_t handle,fflp_fcram_output_drive_t strength,fflp_fcram_qs_t qs)2820 npi_fflp_cfg_fcram_reset(npi_handle_t handle,
2821 fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs)
2822 {
2823 fflp_cfg_1_t fflp_cfg;
2824 uint64_t offset;
2825 offset = FFLP_CFG_1_REG;
2826
2827 /* These bits have to be configured before FCRAM reset is issued */
2828 fflp_cfg.value = 0;
2829 fflp_cfg.bits.ldw.pio_fio_rst = 1;
2830 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2831
2832 NXGE_DELAY(5); /* TODO: What is the correct delay? */
2833
2834 fflp_cfg.bits.ldw.pio_fio_rst = 0;
2835 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2836 fflp_cfg.bits.ldw.fcramqs = qs;
2837 fflp_cfg.bits.ldw.fcramoutdr = strength;
2838 fflp_cfg.bits.ldw.fflpinitdone = 1;
2839 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2840
2841 return (NPI_SUCCESS);
2842 }
2843
2844 npi_status_t
npi_fflp_cfg_init_done(npi_handle_t handle)2845 npi_fflp_cfg_init_done(npi_handle_t handle)
2846
2847 {
2848
2849 fflp_cfg_1_t fflp_cfg;
2850 uint64_t offset;
2851 offset = FFLP_CFG_1_REG;
2852
2853 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2854 fflp_cfg.bits.ldw.fflpinitdone = 1;
2855 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2856 return (NPI_SUCCESS);
2857
2858 }
2859
2860 npi_status_t
npi_fflp_cfg_init_start(npi_handle_t handle)2861 npi_fflp_cfg_init_start(npi_handle_t handle)
2862
2863 {
2864
2865 fflp_cfg_1_t fflp_cfg;
2866 uint64_t offset;
2867 offset = FFLP_CFG_1_REG;
2868
2869 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2870 fflp_cfg.bits.ldw.fflpinitdone = 0;
2871 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2872 return (NPI_SUCCESS);
2873
2874 }
2875
2876 /*
2877 * Enables the TCAM search function.
2878 *
2879 */
2880 npi_status_t
npi_fflp_cfg_tcam_enable(npi_handle_t handle)2881 npi_fflp_cfg_tcam_enable(npi_handle_t handle)
2882
2883 {
2884
2885 fflp_cfg_1_t fflp_cfg;
2886 uint64_t offset;
2887 offset = FFLP_CFG_1_REG;
2888 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2889 fflp_cfg.bits.ldw.tcam_disable = 0;
2890 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2891 return (NPI_SUCCESS);
2892
2893 }
2894
2895 /*
2896 * Disables the TCAM search function.
2897 * While the TCAM is in disabled state, all TCAM matches would return NO_MATCH
2898 *
2899 */
2900 npi_status_t
npi_fflp_cfg_tcam_disable(npi_handle_t handle)2901 npi_fflp_cfg_tcam_disable(npi_handle_t handle)
2902
2903 {
2904
2905 fflp_cfg_1_t fflp_cfg;
2906 uint64_t offset;
2907 offset = FFLP_CFG_1_REG;
2908 REG_PIO_READ64(handle, offset, &fflp_cfg.value);
2909 fflp_cfg.bits.ldw.tcam_disable = 1;
2910 REG_PIO_WRITE64(handle, offset, fflp_cfg.value);
2911 return (NPI_SUCCESS);
2912
2913 }
2914
2915 /*
2916 * npi_rxdma_event_mask_config():
2917 * This function is called to operate on the event mask
2918 * register which is used for generating interrupts
2919 * and status register.
2920 */
2921 npi_status_t
npi_fflp_event_mask_config(npi_handle_t handle,io_op_t op_mode,fflp_event_mask_cfg_t * mask_cfgp)2922 npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode,
2923 fflp_event_mask_cfg_t *mask_cfgp)
2924 {
2925 int status = NPI_SUCCESS;
2926 fflp_err_mask_t mask_reg;
2927
2928 switch (op_mode) {
2929 case OP_GET:
2930
2931 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
2932 *mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL;
2933 break;
2934
2935 case OP_SET:
2936 mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
2937 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2938 break;
2939
2940 case OP_UPDATE:
2941 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value);
2942 mask_reg.value |= (~(*mask_cfgp) & FFLP_ERR_MASK_ALL);
2943 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2944 break;
2945
2946 case OP_CLEAR:
2947 mask_reg.value = FFLP_ERR_MASK_ALL;
2948 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value);
2949 break;
2950 default:
2951 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2952 " npi_fflp_event_mask_config",
2953 " eventmask <0x%x>", op_mode));
2954 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR);
2955 }
2956
2957 return (status);
2958 }
2959
2960 /*
2961 * Read vlan error bits
2962 */
2963 void
npi_fflp_vlan_error_get(npi_handle_t handle,p_vlan_par_err_t p_err)2964 npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err)
2965 {
2966 REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value);
2967 }
2968
2969 /*
2970 * clear vlan error bits
2971 */
2972 void
npi_fflp_vlan_error_clear(npi_handle_t handle)2973 npi_fflp_vlan_error_clear(npi_handle_t handle)
2974 {
2975 vlan_par_err_t p_err;
2976 p_err.value = 0;
2977 p_err.bits.ldw.m_err = 0;
2978 p_err.bits.ldw.err = 0;
2979 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value);
2980
2981 }
2982
2983 /*
2984 * Read TCAM error bits
2985 */
2986 void
npi_fflp_tcam_error_get(npi_handle_t handle,p_tcam_err_t p_err)2987 npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err)
2988 {
2989 REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value);
2990 }
2991
2992 /*
2993 * clear TCAM error bits
2994 */
2995 void
npi_fflp_tcam_error_clear(npi_handle_t handle)2996 npi_fflp_tcam_error_clear(npi_handle_t handle)
2997 {
2998 tcam_err_t p_err;
2999
3000 p_err.value = 0;
3001 p_err.bits.ldw.p_ecc = 0;
3002 p_err.bits.ldw.mult = 0;
3003 p_err.bits.ldw.err = 0;
3004 REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value);
3005
3006 }
3007
3008 /*
3009 * Read FCRAM error bits
3010 */
3011 void
npi_fflp_fcram_error_get(npi_handle_t handle,p_hash_tbl_data_log_t p_err,uint8_t partition)3012 npi_fflp_fcram_error_get(npi_handle_t handle,
3013 p_hash_tbl_data_log_t p_err, uint8_t partition)
3014 {
3015 uint64_t offset;
3016
3017 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
3018 REG_PIO_READ64(handle, offset, &p_err->value);
3019 }
3020
3021 /*
3022 * clear FCRAM error bits
3023 */
3024 void
npi_fflp_fcram_error_clear(npi_handle_t handle,uint8_t partition)3025 npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition)
3026 {
3027 hash_tbl_data_log_t p_err;
3028 uint64_t offset;
3029
3030 p_err.value = 0;
3031 p_err.bits.ldw.pio_err = 0;
3032 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192;
3033
3034 REG_PIO_WRITE64(handle, offset,
3035 p_err.value);
3036
3037 }
3038
3039 /*
3040 * Read FCRAM lookup error log1 bits
3041 */
3042 void
npi_fflp_fcram_error_log1_get(npi_handle_t handle,p_hash_lookup_err_log1_t log1)3043 npi_fflp_fcram_error_log1_get(npi_handle_t handle,
3044 p_hash_lookup_err_log1_t log1)
3045 {
3046 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG,
3047 &log1->value);
3048 }
3049
3050 /*
3051 * Read FCRAM lookup error log2 bits
3052 */
3053 void
npi_fflp_fcram_error_log2_get(npi_handle_t handle,p_hash_lookup_err_log2_t log2)3054 npi_fflp_fcram_error_log2_get(npi_handle_t handle,
3055 p_hash_lookup_err_log2_t log2)
3056 {
3057 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG,
3058 &log2->value);
3059 }
3060