Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / rxc_sat / vera / checkers / mem_checker / niu_rxdma_pktchk.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_rxdma_pktchk.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include <vera_defines.vrh>
36#include <ListMacros.vrh>
37#include "niu_rx_crentry.vrh"
38#include "niu_rxdmc.vrh"
39#include "niu_rxtoken.vrh"
40#include "niu_rxdma_pkttab.vrh"
41#include "niu_byte_array.vrh"
42#include "niu_mem.vrh"
43#include "mbox_class.vrh"
44#include "get_mbox_id.vrh"
45#include "niu_rxtoken.vrh"
46#include "dmc_memory_map.vri"
47#include "cMesg.vrh"
48#include "niu_rx_test_util.vrh"
49#include "niu_int_mgr.vrh"
50#include "niu_rx_exit_tools.vrh"
51
52#ifdef NEPTUNE
53 #define MAX_PORTS 4
54#else
55 #define MAX_PORTS 2
56#endif
57
58extern niu_gen_pio gen_pio_drv;
59extern Mesg be_msg;
60extern mbox_class mbox_id;
61extern CSparseMem SparseMem;
62extern CRDMC rdmc;
63extern event RX_chk_done;
64extern integer RX_TEST_REACHED_END;
65
66extern CNiuIntrMgr NiuIntrMgr;
67
68#define CR_L2_ERROR 1
69
70class CRxDmaPktChk {
71 bit[3:0] last_packet_seen;
72 bit[3:0] ports_active;
73 integer debug_en=0;
74 integer packets_remaining[4];
75 integer packets_checked[4], total_packets_sent[4];
76 integer packets_dropped[4], packets_l2_errors[4];
77 integer check_done = 0;
78 integer interrupts_enabled;
79 integer ignore_address_mismatch = 0;
80 CRxPacketScoreBoard PacketScoreBoard[4];
81 niu_rx_test_util niu_rx_test_util;
82 rx_exit_tools rx_exit_tools;
83 task watch_for_last_pkt_and_flush();
84 task SpCRCheckPacket();
85 task check_packet(Ccr_entry cr[*], integer dma_no, integer no_of_scatters, integer index);
86 task readPacketfromMem(bit[63:0] address, integer length, var byte_array readpacket, integer offset);
87 task check_for_last_packet(CRxToken RxToken);
88 task check_control_header(CRxToken RxToken, byte_array readpacket);
89 task collectStats();
90 task UpdateRCRStat( integer no_of_entries_to_check,integer pkts_checked, integer scatters[*],integer dma_no) ;
91 task RCR_FLUSH_START_pio_wr(bit [63:0] address, bit [63:0] data, integer dma);
92 local function integer WaitForCrTobeWritten(var integer dma_no) ;
93
94 local task free_memory(CRxToken RxToken ,integer dma_no);
95 task rx_exit_routine(integer mac_id);
96 task match_xmac_status(integer mac_id, bit[31:0] status);
97 task match_bmac_status(integer mac_id, bit[31:0] status);
98
99
100 task new() {
101 string init_mac_ports,temp_port;
102 bit[31:0] get_mac_port;
103 integer i;
104 integer rxdma_pthres_intr,rxdma_timer_intr;
105 interrupts_enabled = 0;
106
107 niu_rx_test_util = new;
108
109
110 if(mbox_id.niu_rxpath_cr == -1) {
111 mbox_id.niu_rxpath_cr = alloc(MAILBOX,0,1);
112 }
113
114 fork
115 SpCRCheckPacket();
116 join none
117
118 fork
119 watch_for_last_pkt_and_flush();
120 join none
121
122 ports_active = 0;
123 last_packet_seen =0;
124 if(get_plus_arg( CHECK, "SKIP_ADDRESS_CHECK")) {
125 // This flag has to be used for randoms only for cases where
126 // descriptor ring is getting empty. For all other cases this flag should not be used
127 ignore_address_mismatch = 1;
128 } else ignore_address_mismatch = 0;
129 if(get_plus_arg( CHECK, "GET_MAC_PORTS="))
130 get_mac_port = get_plus_arg( STR, "GET_MAC_PORTS=");
131
132 init_mac_ports.bittostr(get_mac_port);
133 for(i=0; i<init_mac_ports.len();i++) {
134 temp_port =init_mac_ports.substr(i,i);
135 ports_active = ports_active | ( 1<<temp_port.atoi());
136 }
137 for(i=0;i<4;i++) {
138 packets_remaining[i] = 0;
139 packets_checked[i] = 0;
140 total_packets_sent[i] =0;
141 packets_dropped[i] = 0;
142 packets_l2_errors[i] = 0;
143 if(ports_active[i]) PacketScoreBoard[i] = new(i);
144 }
145 if(get_plus_arg( CHECK, "RXDMA_PTHRESH_INTR_CHKR="))
146 rxdma_pthres_intr = get_plus_arg(HNUM,"RXDMA_PTHRESH_INTR_CHKR=");
147 else rxdma_pthres_intr=0;
148 if(get_plus_arg (CHECK,"RXDMA_TIMER_INTR_CHKR="))
149 rxdma_timer_intr = get_plus_arg(HNUM,"RXDMA_TIMER_INTR_CHKR=");
150 else rxdma_timer_intr = 0;
151
152 interrupts_enabled = ( rxdma_pthres_intr | rxdma_timer_intr) ;
153 printf ("rxdma_pthres_intr=0x%h, rxdma_timer_intr=0x%h, interrupts_enabled=0x%h\n", rxdma_pthres_intr,rxdma_timer_intr,interrupts_enabled);
154 } // new
155} //class
156
157
158function integer CRxDmaPktChk::WaitForCrTobeWritten(var integer dma_no) {
159 integer no_of_entries;
160 Ccr_update cr_update;
161
162 no_of_entries = mailbox_get(WAIT,mbox_id.niu_rxpath_cr, cr_update);
163 dma_no = cr_update.dma_no;
164 WaitForCrTobeWritten = cr_update.no_of_entries;
165}
166
167task CRxDmaPktChk::watch_for_last_pkt_and_flush() {
168 bit[3:0] last_seen=4'b0000;
169 shadow integer dma;
170
171 repeat(1000) @(posedge CLOCK); // This delay is a MUST
172
173 while(last_seen !== ports_active ) {
174 if(ports_active[0]) last_seen[0]=PacketScoreBoard[0].last_pkt_rcvd;
175 if(ports_active[1]) last_seen[1]=PacketScoreBoard[1].last_pkt_rcvd;
176 if(ports_active[2]) last_seen[2]=PacketScoreBoard[2].last_pkt_rcvd;
177 if(ports_active[3]) last_seen[3]=PacketScoreBoard[3].last_pkt_rcvd;
178 repeat(1000) @(posedge CLOCK);
179 }
180 if(get_plus_arg( CHECK, "RX_LAST_PKT_LATENCY="))
181 repeat( get_plus_arg( NUM, "RX_LAST_PKT_LATENCY=") ) @(posedge CLOCK);
182 else
183 repeat(5000) @(posedge CLOCK);
184
185 // RCR flush of all 16 DMAs
186 for(dma=0;dma<16;dma++) {
187 fork {
188 rdmc.rx_dma[dma].flush_rcr(1);
189 } join all
190 }
191
192 // kick in the timer interrupt to flush out the residual interrupts from all DMAs
193 niu_rx_test_util.cleanup_dma_interrupts(interrupts_enabled) ;
194
195 printf("check_packet RX_TEST_REACHED_END (all dmas flushed) time=%0d\n", {get_time(HI),get_time(LO)});
196 RX_TEST_REACHED_END = 1;
197}
198
199
200task CRxDmaPktChk::SpCRCheckPacket() {
201 Ccr_entry cr[*];
202 integer i, no_of_entries;
203 integer status, dma_no;
204 integer start_index, no_of_scatter;
205 integer prev_remaining_entries[32];
206 integer no_of_entries_to_check;
207 integer pkts_checked;
208 bit [63:0] rd_data_;
209 integer scatters[*];
210 integer none_found;
211 integer done_with_while;
212
213
214 for(i=0; i<32; i++) prev_remaining_entries[i]=0;
215
216 while(1) {
217 no_of_entries = WaitForCrTobeWritten(dma_no); //get dma_no and no_of_entries
218 //printf("check_packet dma=%0d no_of_entries=%0d prev_remaining_entries=%0d\n", dma_no, no_of_entries, prev_remaining_entries[dma_no]);
219 no_of_entries = no_of_entries + prev_remaining_entries[dma_no];
220
221if(no_of_entries >rdmc.rx_dma[dma_no].completionring.ring_length ) {
222 be_msg.print(e_mesg_error,"CRxDmaPktChk","SpCRCheckPacket","CR_no_of_entries > RCR_RING_LEN at time %0d. Exiting the simulation \n", get_time(LO));
223 repeat(300) @(posedge CLOCK);
224 exit(0);
225}
226 status = rdmc.rx_dma[dma_no].completionring.ReadCrEntry(no_of_entries,cr);
227
228 // parse entries
229 if(cr[no_of_entries-1].multi==0) {
230 prev_remaining_entries[dma_no] =0;
231 no_of_entries_to_check = no_of_entries;
232 }
233 else { //scan through the list and get the complete packet
234 if(no_of_entries ==1) {
235 no_of_entries_to_check =0;
236 prev_remaining_entries[dma_no] =1;
237 }
238 else {
239 i= no_of_entries-1;
240 none_found = 0;
241 done_with_while = 0;
242 while( (done_with_while==0) && ( none_found==0) ) {
243 if(cr[i].multi==0 ) {
244 done_with_while = 1;
245 i++;
246 }
247 i--;
248 if(i<0) none_found = 1;
249 }
250 if(none_found) {
251 no_of_entries_to_check = 0;
252 } else {
253 no_of_entries_to_check = i + 1;
254 }
255 prev_remaining_entries[dma_no] = no_of_entries - no_of_entries_to_check ;
256 }
257 }
258 printf("check_packet dma=%0d num_entries_to_check=%0d num_entries=%0d prev_remaining_entries=%0d\n", dma_no, no_of_entries_to_check, no_of_entries, prev_remaining_entries[dma_no]);
259
260 rdmc.rx_dma[dma_no].completionring.UpdateCRLastAddress(no_of_entries_to_check);
261
262 pkts_checked = 0;
263 scatters = new[no_of_entries_to_check];
264
265 for(i=0; i<no_of_entries_to_check; i++) {
266 if(cr[i].multi==0) {
267 check_packet(cr, dma_no, 1, i);
268 scatters[pkts_checked] = 1;
269 pkts_checked++;
270 }
271 else { // jumbo packets - collect all the cr entries
272 no_of_scatter = 1;
273 start_index = i;
274 while(cr[i].multi==1) {
275 no_of_scatter ++;
276 i++;
277 }
278 check_packet(cr, dma_no, no_of_scatter, start_index);
279 scatters[pkts_checked] = no_of_scatter;
280 pkts_checked++;
281 }
282 }
283 @(posedge CLOCK);
284 UpdateRCRStat(no_of_entries_to_check,pkts_checked,scatters,dma_no);
285
286 }
287}
288
289task CRxDmaPktChk::UpdateRCRStat( integer no_of_entries_to_check,integer pkts_checked, integer scatters[*],integer dma_no) {
290Crcr_update rcr_update;
291integer i;
292
293 if (get_plus_arg( CHECK, "CHKR_AUTO_UPDATE_RCR_HEAD")) {
294 rcr_update = new();
295 rcr_update.no_of_entries = no_of_entries_to_check;
296 rcr_update.dma_no = dma_no;
297 rcr_update.pkts_checked = pkts_checked;
298 rcr_update.scatters= new[no_of_entries_to_check];
299 for(i=0;i<pkts_checked;i++) {
300 rcr_update.scatters[i] = scatters[i];
301 }
302 mailbox_put(mbox_id.niu_rxpath_rcr_update[dma_no], rcr_update);
303 }
304
305}
306
307task CRxDmaPktChk::check_control_header( CRxToken RxToken, byte_array readpacket ) {
308 bit [7:0] exp_cntl_hdr_B0, exp_cntl_hdr_B1, rtl_cntl_hdr_B0, rtl_cntl_hdr_B1;
309 bit [1:0] exp_port_num, rtl_port_num, exp_tres, rtl_tres;
310 bit exp_maccheck, rtl_maccheck;
311 bit [4:0] exp_packet_class, rtl_packet_class;
312 bit exp_vlan,exp_llcsnap,exp_noport,exp_badip,exp_tcamhit,exp_tzfvld;
313 bit rtl_vlan,rtl_llcsnap,rtl_noport,rtl_badip,rtl_tcamhit,rtl_tzfvld;
314
315 // Collect the expected control header fields
316 exp_cntl_hdr_B0 = RxToken.rx_cntl_hdr.val[0];
317 exp_cntl_hdr_B1 = RxToken.rx_cntl_hdr.val[1];
318
319 exp_port_num = exp_cntl_hdr_B0[7:6];
320 exp_maccheck = exp_cntl_hdr_B0[5];
321 exp_packet_class = exp_cntl_hdr_B0[4:0];
322 exp_vlan = exp_cntl_hdr_B1[7];
323 exp_llcsnap = exp_cntl_hdr_B1[6];
324 exp_noport = exp_cntl_hdr_B1[5];
325 exp_badip = exp_cntl_hdr_B1[4];
326 exp_tcamhit = exp_cntl_hdr_B1[3];
327 exp_tres = exp_cntl_hdr_B1[2:1];
328 exp_tzfvld = exp_cntl_hdr_B1[0];
329
330
331 // Collect the RTL control header fields got from memory
332 rtl_cntl_hdr_B0 = readpacket.val[0];
333 rtl_cntl_hdr_B1 = readpacket.val[1];
334
335 rtl_port_num = rtl_cntl_hdr_B0[7:6];
336 rtl_maccheck = rtl_cntl_hdr_B0[5];
337 rtl_packet_class = rtl_cntl_hdr_B0[4:0];
338 rtl_vlan = rtl_cntl_hdr_B1[7];
339 rtl_llcsnap = rtl_cntl_hdr_B1[6];
340 rtl_noport = rtl_cntl_hdr_B1[5];
341 rtl_badip = rtl_cntl_hdr_B1[4];
342 rtl_tcamhit = rtl_cntl_hdr_B1[3];
343 rtl_tres = rtl_cntl_hdr_B1[2:1];
344 rtl_tzfvld = rtl_cntl_hdr_B1[0];
345
346
347
348 printf("CNTL_HDR_CHECK: ---------------------------------------------------\n");
349 printf("CNTL_HDR_CHECK: RX CONTROL HEADER CHECK IN PKT_DROP CHECKER \n");
350 printf("CNTL_HDR_CHECK: ---------------------------------------------------\n");
351 printf("CNTL_HDR_CHECK: RTL MODEL \n");
352 printf("CNTL_HDR_CHECK: ---------------------------------------------------\n");
353
354 if (rtl_tzfvld!==exp_tzfvld)
355 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "TZFVLD = %0h\t\t%0h\n", rtl_tzfvld, exp_tzfvld);
356 else
357 printf("CNTL_HDR_CHECK: TZFVLD = %0h\t\t%0h\n", rtl_tzfvld, exp_tzfvld);
358 if (rtl_tres!==exp_tres)
359 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "TRES = %0h\t\t%0h\n", rtl_tres, exp_tres);
360 else
361 printf("CNTL_HDR_CHECK: TRES = %0h\t\t%0h\n", rtl_tres, exp_tres);
362 if (rtl_tcamhit!==exp_tcamhit)
363 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "TCAM-Hit = %0h\t\t%0h\n", rtl_tcamhit, exp_tcamhit);
364 else
365 printf("CNTL_HDR_CHECK: TCAM-Hit = %0h\t\t%0h\n", rtl_tcamhit, exp_tcamhit);
366 if (exp_badip!==exp_badip)
367 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "Bad-IP = %0h\t\t%0h\n", exp_badip, exp_badip);
368 else
369 printf("CNTL_HDR_CHECK: Bad-IP = %0h\t\t%0h\n", exp_badip, exp_badip);
370 if (rtl_noport!==exp_noport)
371 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "No-port = %0h\t\t%0h\n", rtl_noport, exp_noport);
372 else
373 printf("CNTL_HDR_CHECK: No-port = %0h\t\t%0h\n", rtl_noport, exp_noport);
374 if (rtl_llcsnap!==exp_llcsnap)
375 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "LLC-SNAP = %0h\t\t%0h\n", rtl_llcsnap, exp_llcsnap);
376 else
377 printf("CNTL_HDR_CHECK: LLC-SNAP = %0h\t\t%0h\n", rtl_llcsnap, exp_llcsnap);
378 if (rtl_vlan!==exp_vlan)
379 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "VLAN = %0h\t\t%0h\n", rtl_vlan, exp_vlan);
380 else
381 printf("CNTL_HDR_CHECK: VLAN = %0h\t\t%0h\n", rtl_vlan, exp_vlan);
382 if (rtl_packet_class!==exp_packet_class)
383 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "CLASS = %0h\t\t%0h\n", rtl_packet_class, exp_packet_class);
384 else
385 printf("CNTL_HDR_CHECK: CLASS = %0h\t\t%0h\n", rtl_packet_class, exp_packet_class);
386 if (rtl_maccheck!==exp_maccheck)
387 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "MAC-check = %0h\t\t%0h\n", rtl_maccheck, exp_maccheck);
388 else
389 printf("CNTL_HDR_CHECK: MAC-check = %0h\t\t%0h\n", rtl_maccheck, exp_maccheck);
390 if (rtl_port_num!==exp_port_num)
391 be_msg.print(e_mesg_error,"CNTL_HDR_CHECK", "", "MAC-PORT = %0h\t\t%0h\n", rtl_port_num, exp_port_num);
392 else
393 printf("CNTL_HDR_CHECK: MAC-PORT = %0h\t\t%0h\n", rtl_port_num, exp_port_num);
394 printf("CNTL_HDR_CHECK: ---------------------------------------------------\n");
395
396
397}
398
399task CRxDmaPktChk::check_packet(Ccr_entry cr[*], integer dma_no, integer no_of_scatters, integer index) {
400 bit[63:0] packet_address;
401 bit[63:0] xlate_packet_address;
402 integer length, total_length;
403 integer i, block_size, page_id;
404 byte_array readpacket, expected_packet;
405 bit[15:0] packet_id;
406 CRxToken RxToken;
407 integer mac_id, gId;
408 integer status;
409 integer n, bytes_mismatched, total_offset;
410 byte_array ctrlhdr;
411 integer port_num_from_pkt;
412 integer error_status;
413 integer skip_checking;
414 integer getaddr_status;
415 integer offset = 0;
416 integer expected_dma_no,expected_port_no,dma_no_from_pkt;
417
418 total_offset = rdmc.rx_dma[dma_no].ctrl_hdr_len + rdmc.rx_dma[dma_no].buffer_offset;
419 total_length = cr[index].length + total_offset/*header_length*/;
420 block_size = rdmc.rx_dma[dma_no].dma_block_size;
421
422 readpacket = new();
423 printf("check_packet index=%0d num_scatters=%0d length=%0d\n", index, no_of_scatters, total_length);
424
425 length = total_length;
426 for(i=0;i<no_of_scatters;i++) {
427 xlate_packet_address=64'h0;
428 packet_address = cr[i+index].pkt_buf_address;
429 page_id = rdmc.rx_dma[dma_no].getPageId(packet_address);
430 // page_id = 64 + 2*dma_no;
431 if(page_id==-1)
432 be_msg.print(e_mesg_error, "niu_rx_chkr", "check_packet", "PacketBuf Addr in CR doesnt Match Any valid page!!\n");
433 else {
434 xlate_packet_address = SparseMem.xlate_addr( packet_address[39:0], page_id );
435 }
436 // length = min(block_size, total_length);
437 if(block_size<length)
438 length = block_size;
439 //printf("check_packet dma=%0d min block_size=%0d length=%0d\n", dma_no, block_size, length);
440 printf("check_packet xlated_addr=0x%0h orig_addr=0x%0h page_id=%0d\n", xlate_packet_address, packet_address, page_id);
441
442 // length = (block_size<length) ? block_size: length;
443 readPacketfromMem(xlate_packet_address, length, readpacket, offset);
444 offset = offset + length;
445 length = total_length - offset;
446 }
447
448 ctrlhdr = new();
449 for(i=0; i<total_offset; i++) {
450 ctrlhdr.val[i] = readpacket.val[i];
451 }
452
453 if (rdmc.rx_dma[dma_no].ctrl_hdr_len == 2)
454 port_num_from_pkt = ( ctrlhdr.val[0] & 8'hc0)>>6;
455 else if (rdmc.rx_dma[dma_no].ctrl_hdr_len == 18) // for 18B hdr, second cycle has the port_num info
456 port_num_from_pkt = ( ctrlhdr.val[16] & 8'hc0)>>6;
457
458 packet_id = {readpacket.val[total_offset+6+4],readpacket.val[total_offset+6+5]};
459
460
461 expected_port_no = readpacket.val[total_offset + 6 + 3] & 8'h3;
462 expected_dma_no = ({readpacket.val[total_offset + 6 + 2], readpacket.val[total_offset + 6 + 3]}>>2) & 8'h3f;
463 dma_no_from_pkt = ({readpacket.val[total_offset + 6 + 2], readpacket.val[total_offset + 6 + 3]}>>2) & 8'h3f;
464
465 error_status = cr[index].errors;
466 skip_checking = 0;
467
468 if(error_status == CR_L2_ERROR) {
469 // for L2 Error the expected DMA is the port default DMA
470 expected_dma_no = rdmc.getPortDefDma(expected_port_no);
471 rdmc.rx_dma[expected_dma_no].incDefPktCnt();
472 } else {
473 rdmc.rx_dma[dma_no].incPktCnt();
474 }
475
476 if(expected_dma_no!=dma_no) {
477 printf(" RTL_MODEL DMA PREDICTION MISMATCH ERROR!!! packet_id - %0d, Mismatch in DMA no exp - %0d, got - %0d port_num %0d\n",
478 packet_id, expected_dma_no, dma_no, expected_port_no);
479 }
480
481 if(expected_port_no!=port_num_from_pkt) {
482 printf(" RTL_MODEL PORT MISMATCH ERROR!!! packet_id - %0d, Mismatch in Port No exp - %0d, got - %0d port_num %0d\n",
483 packet_id, expected_port_no, port_num_from_pkt, expected_port_no);
484 }
485
486 printf("check_packet mac.seq=%0d.%0d\n", port_num_from_pkt, packet_id);
487
488 if(error_status == CR_L2_ERROR) { //for unexpected L2 Error cases only due to runts
489 //caused by ipp back pressure
490 PacketScoreBoard[port_num_from_pkt].no_of_packets_l2_errors++;
491 PacketScoreBoard[port_num_from_pkt].no_of_bytes_l2_errors = PacketScoreBoard[port_num_from_pkt].no_of_bytes_l2_errors + cr[index].length;
492 printf("check_packet Packet at addr=0x%x cr_address=0x%x received with L2 error\n", packet_address, cr[index].address);
493 //printf("check_packet PACKET_CHECKING SKIPPED!! \n");
494 skip_checking = 1;
495 }
496
497 status = PacketScoreBoard[port_num_from_pkt].getPacket(packet_id, RxToken, dma_no,dma_no_from_pkt);
498
499 // At this point, we have RxToken. Check the control header here.
500 if(get_plus_arg (CHECK, "ENABLE_RX_CNTL_HDR_CHECK")) {
501 check_control_header(RxToken,readpacket);
502 }
503
504 // calculate expected address
505 // calculate expected completion ring entry
506
507// #ifdef 0
508 if(status==1) {
509 RxToken.pkt_length = total_length - total_offset;
510 getaddr_status = rdmc.rx_dma[dma_no].getPacketAddress(RxToken);
511 // various compare points
512 if(RxToken.NoOfScatter!==no_of_scatters) {
513 printf("ERROR Expected RxToken.NoOfScatter - %d Actual no_of_scatters - %d \n",RxToken.NoOfScatter,no_of_scatters);
514 }
515 for(i=0;i<RxToken.NoOfScatter;i++) {
516 if(RxToken.packet_virtaddress[i]!== cr[i+index].pkt_buf_address) {
517 if(ignore_address_mismatch)
518 printf("ADDRESS MISMATCH WARNING !!! RxToken.packet_virtaddr[%0d]=0x%x, cr[%0d].pkt_buf_address=0x%x\n", i, RxToken.packet_virtaddress[i], i+index, cr[i+index].pkt_buf_address);
519 else
520 printf("ADDRESS MISMATCH ERROR !!! RxToken.packet_virtaddr[%0d]=0x%x, cr[%0d].pkt_buf_address=0x%x\n", i, RxToken.packet_virtaddress[i], i+index, cr[i+index].pkt_buf_address);
521 }
522 }
523 }
524// #endif
525
526 if(skip_checking) printf("check_packet PACKET_CHECKING SKIPPED!! FIX IT \n");
527 else if(status == -1) be_msg.print(e_mesg_error, "niu_rx_chkr", "check_packet", "Illegal Packet received Id=%0d\n", packet_id);
528 // do a sanity check on the status
529 else {
530 expected_packet = RxToken.pgToken.buf;
531 mac_id = RxToken.port_num;
532 gId = RxToken.id;
533 if(port_num_from_pkt!==mac_id) be_msg.print(e_mesg_error, "niu_rx_chkr", "check_packet", "PortNum from Packet=%0d Exp Port Num=%0d\n", port_num_from_pkt, mac_id);
534
535 for(n=0; n<total_length-total_offset;n =n+1) {
536 if(expected_packet.val[n] !== readpacket.val [n+total_offset]) { // check after "total_offset" number of Bytes
537 be_msg.print(e_mesg_error, "niu_rx_chkr", "check_packet", "DATA_MISMATCH:niu_rx_chkr[%0d]: Token=%0d Word[%0d] Got=0x%0h Exp=0x%0h\n", mac_id, gId, n,readpacket.val[n+total_offset], expected_packet.val[n] );
538 bytes_mismatched ++;
539 }
540 else {
541 if(debug_en) {
542 be_msg.print(e_mesg_info, "niu_rx_chkr", "check_packet", "Packet Successfully Written:niu_rx_chkr[%0d]: Token=%0d Word[%0d] Got=0x%0h Exp=0x%0h\n", mac_id, gId, n,readpacket.val[n+total_offset], expected_packet.val[n] );
543 }
544 }
545 }
546 }
547 fork {
548 check_for_last_packet(RxToken);
549 } join none
550
551 if(status==1)
552 free_memory(RxToken,expected_dma_no);
553 printf("check_packet ========== done with entry \n");
554}
555
556 task CRxDmaPktChk::free_memory(CRxToken RxToken ,integer dma_no){
557 rdmc.rx_dma[dma_no ].free_memory(RxToken);
558}
559
560task CRxDmaPktChk::readPacketfromMem(bit[63:0] address, integer length, var byte_array readpacket, integer offset) {
561 integer NoOf8Bytes, index, j;
562 bit[63:0] mem_rd_data;
563 bit[63:0] mem_rd_addr;
564
565 mem_rd_addr = address;
566 NoOf8Bytes = ( (length)/8) + ( ((length) %8) ? 1 :0 ) ;
567 printf("check_packet readPacketfromMem length=%0d addr=0x%x offset=%0d\n", length, address, offset);
568 for(index=0; index<NoOf8Bytes; index ++) {
569 SparseMem.ReadMem(mem_rd_addr + 8*index, mem_rd_data, 8'hff);
570 for(j=0; j<8; j++) {
571 readpacket.val[offset+ 8*index +j] = mem_rd_data[ 8*j + 7: 8*j];
572 // printf("CRxDmaPktChk::readPacketfromMem index - %d byte - %x \n",(offset+ 8*index + j),readpacket.val[offset+ 8*index + j]);
573 }
574 }
575}
576
577
578task CRxDmaPktChk::check_for_last_packet(CRxToken RxToken) {
579 shadow integer dma;
580 integer port_num, dma_num;
581
582 bit[31:0] dma_active_list;
583 bit[31:0] dma_done_list;
584
585 if(RxToken.last_packet) {
586 last_packet_seen[RxToken.port_num] = 1;
587
588 printf("check_packet port_active=0x%0h last_packet_seen=%0d\n", ports_active, last_packet_seen);
589 if(last_packet_seen == ports_active) {
590 printf("check_packet Last Packet token received from all active ports time=%d \n",{get_time(HI), get_time(LO)});
591 repeat(500) @(posedge CLOCK);
592 check_done = 1;
593 repeat(500) @(posedge CLOCK);
594
595 if(get_plus_arg(CHECK, "RX_LAST_PKT_LATENCY="))
596 repeat(get_plus_arg( NUM, "RX_LAST_PKT_LATENCY=")) @(posedge CLOCK);
597 else
598 repeat(5000) @(posedge CLOCK);
599
600 // Wait for All the active CR Polls to be done before exiting
601
602
603 for(dma=0; dma<16; dma++) {
604 dma_active_list = (rdmc.rx_dma[dma].poll_cr_active)<<dma;
605 dma_done_list = (rdmc.rx_dma[dma].poll_cr_done)<<dma;
606 }
607
608 while((dma_active_list != dma_done_list)) {
609 for(dma=0; dma<16; dma++) {
610 dma_active_list = (rdmc.rx_dma[dma].poll_cr_active)<<dma;
611 dma_done_list = (rdmc.rx_dma[dma].poll_cr_done)<<dma;
612 }
613 repeat(100)@(posedge CLOCK);
614 }
615
616 for(dma=0; dma<16; dma++) { //flush all 16 DMA Crings
617 fork {
618 rdmc.rx_dma[dma].flush_rcr(1);
619 } join all
620 }
621
622 repeat(1000) @(posedge CLOCK); //
623
624 printf ("interrupts_enabled=0x%h\n", interrupts_enabled);
625 if (interrupts_enabled) {
626 niu_rx_test_util.cleanup_dma_interrupts(interrupts_enabled) ;
627 repeat(1000) @(posedge CLOCK); //
628 repeat(1000) @(posedge CLOCK); //
629 NiuIntrMgr.CheckPendingFlags();
630 repeat(1000) @(posedge CLOCK); //
631 NiuIntrMgr.CheckPendingFlags();
632 }
633
634
635 collectStats(); // for all ports
636
637 trigger (ON, RX_chk_done);
638 }
639 }
640 // Do stats collection at this point
641}
642task CRxDmaPktChk::collectStats() {
643 integer total_rtl_drop_count=0, rtl_mac_drop_count=0, rtl_ipp_drop_count=0, rtl_rdma_drop_count=0;
644 integer total_env_drop_count=0;
645 integer port_num, dma_num, TotalNoOfEntries=0;
646 bit pkt_drop_expected,
647 pkt_drop_may_be_expected,
648 env_rtl_mismatch_expected,
649 rtl_pkt_drop_count_non_zero,
650 env_pkt_drop_count_non_zero,
651 rtl_and_env_drop_count_matched;
652
653
654 // collect total env drop count
655 for(port_num=0;port_num<4;port_num++) {
656 if(ports_active[port_num])
657 total_env_drop_count += PacketScoreBoard[port_num].getNoOfEntries();
658 }
659
660 // collect rtl mac drop count
661 for(port_num=0;port_num<4;port_num++) {
662 if(ports_active[port_num])
663 rtl_mac_drop_count += niu_rx_test_util.getMacDropCnt(port_num,
664 PacketScoreBoard[port_num].no_of_packets_qued);
665 }
666
667 // collect rtl ipp drop count
668 for(port_num=0;port_num<4;port_num++) {
669 if(ports_active[port_num])
670 rtl_ipp_drop_count += niu_rx_test_util.getIppDropCnt(port_num);
671 }
672
673 //printf("<%0d> collectStats: setting rtl_ipp_drop_count=0 mac and ipp increments cnt for the same pkt\n",
674 // get_time(LO));
675 //rtl_ipp_drop_count = 0;
676
677 // collect rtl rdma drop count
678 for(dma_num=0;dma_num<16;dma_num++) {
679 rtl_rdma_drop_count += niu_rx_test_util.getRdmcDropCnt(dma_num);
680 }
681
682
683
684 total_rtl_drop_count = rtl_mac_drop_count + rtl_ipp_drop_count + rtl_rdma_drop_count;
685
686 // print PacketScoreBoard
687 //for(port_num=0;port_num<4 && ports_active[port_num];port_num++) {
688 // PacketScoreBoard[port_num].print_stats();
689 //}
690
691
692
693 if (get_plus_arg(CHECK, "PKT_DROPS_EXPECTED")) pkt_drop_expected = 1;
694 else pkt_drop_expected = 0;
695 if (get_plus_arg(CHECK, "PKT_DROPS_MAY_BE_EXPECTED")) pkt_drop_may_be_expected = 1;
696 else pkt_drop_may_be_expected = 0;
697 if (get_plus_arg(CHECK, "ENV_RTL_MISMATCH_EXPECTED")) env_rtl_mismatch_expected = 1;
698 else env_rtl_mismatch_expected = 0;
699
700 rtl_pkt_drop_count_non_zero = total_rtl_drop_count ? 1: 0;
701 env_pkt_drop_count_non_zero = total_env_drop_count ? 1: 0;
702 rtl_and_env_drop_count_matched = (total_rtl_drop_count == total_env_drop_count) ? 1: 0;
703
704 // print drop statistics
705 printf("============================ check_packet : collectStats ========================\n");
706 printf("collectStats rtl_mac_drop_count:%0d rtl_ipp_drop_count:%0d rtl_rdma_drop_count:%0d\n",
707 rtl_mac_drop_count, rtl_ipp_drop_count, rtl_rdma_drop_count);
708 printf("collectStats total_rtl_drop_count:%0d total_env_drop_count:%0d\n",
709 total_rtl_drop_count, total_env_drop_count);
710 printf("collectStats pkt_drop_expected:%b pkt_drop_may_be_expected:%b\n",
711 pkt_drop_expected, pkt_drop_may_be_expected);
712 printf("rtl_pkt_drop_cnt_non_zero:%b, env_pkt_drop_cnt_non_zero:%b, rtl_and_env_drop_cnt_matched:%b\n",
713 rtl_pkt_drop_count_non_zero, env_pkt_drop_count_non_zero, rtl_and_env_drop_count_matched);
714
715 // Analyze all the counters
716 case ({pkt_drop_expected,
717 rtl_pkt_drop_count_non_zero,
718 env_pkt_drop_count_non_zero,
719 rtl_and_env_drop_count_matched}) {
720 4'b0001, // PASS -- No pkts tests
721 4'b1111: {} // PASS -- normal pkt drop not allowed tests
722 4'b001X, // FAIL -- drops are not allowed
723 4'b0110, // FAIL -- drop count mismatch
724 4'b010X: { // FAIL -- drop count mismatch
725 if(!env_rtl_mismatch_expected)
726 be_msg.print(e_mesg_error, "niu_rxdma_pktchk",
727 "collectStats",
728 "ERROR : drop count mismatch between env and rtl!\n");
729 else
730 be_msg.print(e_mesg_info, "niu_rxdma_pktchk",
731 "collectStats",
732 "drop count mismatch between env and rtl found, but is expected by the TEST!\n");
733 }
734 4'b0111: { // FAIL -- drops are not allowed unless pkt_drop_may_be_expected is set
735 if(!pkt_drop_may_be_expected)
736 be_msg.print(e_mesg_error, "niu_rxdma_pktchk",
737 "collectStats",
738 "drops are not allowed in this test. use PKT_DROPS_EXPECTED to allow drops\n");
739 else
740 be_msg.print(e_mesg_info, "niu_rxdma_pktchk",
741 "collectStats",
742 "there are few drops in this test. PKT_DROPS_MAY_BE_EXPECTED is set\n");
743 }
744 4'b100X: { // FAIL -- expecting pkt drops unless pkt_drop_may_be_expected is set
745 if(!pkt_drop_may_be_expected)
746 be_msg.print(e_mesg_error, "niu_rxdma_pktchk",
747 "collectStats",
748 "expecting pkts drops in this test\n");
749 else
750 be_msg.print(e_mesg_info, "niu_rxdma_pktchk",
751 "collectStats",
752 "expecting pkts drops in this test but PKT_DROPS_MAY_BE_EXPECTED is set\n");
753
754 }
755 4'b101X,
756 4'b110X,
757 4'b1110: { // FAIL -- rtl and env drop counts did not match
758 if(!env_rtl_mismatch_expected)
759 be_msg.print(e_mesg_error, "niu_rxdma_pktchk",
760 "collectStats",
761 "env and rtl drop counts does not match\n");
762 else
763 be_msg.print(e_mesg_info, "niu_rxdma_pktchk",
764 "collectStats",
765 "drop count mismatch between env and rtl found, but is expected by the TEST!\n");
766 }
767 } // case
768
769 // Fatal error if there is any packet in the env which is not accounted for
770 for(port_num=0;port_num<4;port_num++) {
771 if(ports_active[port_num]) {
772 TotalNoOfEntries += PacketScoreBoard[port_num].getNoOfEntries();
773 be_msg.print(e_mesg_info, "niu_rxdma_pktchk",
774 "collectStats",
775 "PacketScoreBoard[%0d].getNoOfEntries:%0d\n",
776 port_num,PacketScoreBoard[port_num].getNoOfEntries());
777 }
778 }
779
780 // rtl pkt drop better match with noOfEntries in score board
781 if(TotalNoOfEntries != total_rtl_drop_count) {
782 if(!env_rtl_mismatch_expected)
783 be_msg.print(e_mesg_error, "niu_rxdma_pktchk", "collectStats",
784 "noOfEntries:%0d in PacketScoreBoard does not match with total_rtl_drop_cnt:%0d\n",
785 TotalNoOfEntries, total_rtl_drop_count);
786 else
787 be_msg.print(e_mesg_info, "niu_rxdma_pktchk", "collectStats",
788 "noOfEntries:%0d in PacketScoreBoard does not match with total_rtl_drop_cnt:%0d, as expected by TEST\n",
789 TotalNoOfEntries, total_rtl_drop_count);
790 }
791
792 for(port_num=0;port_num<4;port_num++) {
793 if(ports_active[port_num]) {
794 PacketScoreBoard[port_num].print_stats(*, 1);
795 }
796 }
797 printf("============================ check_packet : collectStats ========================\n");
798
799if (get_plus_arg(CHECK, "ENABLE_RX_EXIT_ROUTINE")) {
800 // do exit check here
801 for(port_num=0;port_num<4;port_num++) {
802 if(ports_active[port_num]) {
803 printf("CRxDmaPktChk: Doing RX Exit Routine for port %0d\n", port_num);
804 rx_exit_routine(port_num);
805 }
806 }
807}
808
809}
810
811task CRxDmaPktChk::RCR_FLUSH_START_pio_wr(bit [63:0] address, bit [63:0] data, integer dma) {
812 gen_pio_drv.pio_wr(rdmc.rx_dma[dma].getPIOAddress(address,rdmc.rx_dma[dma].dis_pio_virt), data);
813}
814
815task CRxDmaPktChk::rx_exit_routine(integer mac_id) {
816
817 bit [31:0] xmac_exp_status0,xmac_exp_status1;
818 bit [31:0] bmac_exp_status2,bmac_exp_status3;
819 rx_counters env_counters, rtl_counters;
820
821 env_counters = new(mac_id);
822
823 if (mac_id==0 || mac_id==1){
824 env_counters.mac_crc_cntr=PacketScoreBoard[mac_id].no_of_packets_ext_l2_errors;
825 env_counters.xmac_hist1_cntr=PacketScoreBoard[mac_id].hist1_count;
826 env_counters.xmac_hist2_cntr=PacketScoreBoard[mac_id].hist2_count;
827 env_counters.xmac_hist3_cntr=PacketScoreBoard[mac_id].hist3_count;
828 env_counters.xmac_hist4_cntr=PacketScoreBoard[mac_id].hist4_count;
829 env_counters.xmac_hist5_cntr=PacketScoreBoard[mac_id].hist5_count;
830 env_counters.xmac_hist6_cntr=PacketScoreBoard[mac_id].hist6_count;
831 env_counters.xmac_hist7_cntr=PacketScoreBoard[mac_id].hist7_count;
832 env_counters.mac_mpszer_cntr=PacketScoreBoard[mac_id].max_pkt_err_count;
833 env_counters.xmac_frag_cntr=PacketScoreBoard[mac_id].min_pkt_err_count;
834 env_counters.xmac_byte_cntr=PacketScoreBoard[mac_id].xmac_byte_cnt;
835 env_counters.xmac_mcast_cntr=PacketScoreBoard[mac_id].mcast_pkt_count;
836 env_counters.xmac_bcast_cntr=PacketScoreBoard[mac_id].bcast_pkt_count;
837 env_counters.mac_codevio_cntr=PacketScoreBoard[mac_id].code_viol_err_count;
838 // Now, check the xmac status only if given the expected result
839 if (get_plus_arg(CHECK, "EXPECTED_XMAC_EXIT_STATUS0="))
840 xmac_exp_status0 = get_plus_arg(HNUM,"EXPECTED_XMAC_EXIT_STATUS0=");
841 else
842 xmac_exp_status0 = 32'h00080001; // Expecting linkUpDown=1, FrameRcvd=1
843 if (get_plus_arg(CHECK, "EXPECTED_XMAC_EXIT_STATUS1="))
844 xmac_exp_status1 = get_plus_arg(HNUM,"EXPECTED_XMAC_EXIT_STATUS1=");
845 else
846 xmac_exp_status1 = 32'h00080001; // Expecting linkUpDown=1, FrameRcvd=1
847 if (mac_id==0)
848 match_xmac_status(0, xmac_exp_status0);
849 else if (mac_id==1)
850 match_xmac_status(1, xmac_exp_status1);
851 }
852 else if (mac_id==2 || mac_id==3){
853 env_counters.bmac_frame_cntr=PacketScoreBoard[mac_id].hist7_count;
854 env_counters.bmac_alignerr_cntr=PacketScoreBoard[mac_id].bmac_align_err_count;
855 env_counters.mac_crc_cntr=PacketScoreBoard[mac_id].no_of_packets_ext_l2_errors;
856 env_counters.mac_codevio_cntr=PacketScoreBoard[mac_id].code_viol_err_count;
857 env_counters.mac_mpszer_cntr=PacketScoreBoard[mac_id].max_pkt_err_count;
858 // Now, check the bmac status only if given the expected result
859 if (get_plus_arg(CHECK, "EXPECTED_BMAC_EXIT_STATUS2="))
860 bmac_exp_status2 = get_plus_arg(HNUM,"EXPECTED_BMAC_EXIT_STATUS2=");
861 else
862 bmac_exp_status2 = 32'h1; // Expecting FrameRcvd=1
863 if (get_plus_arg(CHECK, "EXPECTED_BMAC_EXIT_STATUS3="))
864 bmac_exp_status3 = get_plus_arg(HNUM,"EXPECTED_BMAC_EXIT_STATUS3=");
865 else
866 bmac_exp_status3 = 32'h1; // Expecting FrameRcvd=1
867 if (mac_id==2)
868 match_bmac_status(2, bmac_exp_status2);
869 else if (mac_id==3)
870 match_bmac_status(3, bmac_exp_status3);
871 }
872
873 rtl_counters = rx_exit_tools.read_rx_rtl_cntrs(mac_id);
874 if(mac_id==0 | mac_id==1)
875 rtl_counters.xmac_hist7_cntr=niu_rx_test_util.xmac_hist7_cntr[mac_id]; // correct rtl value
876 rx_exit_tools.match_rtl_env_cntrs(rtl_counters, env_counters);
877
878}
879
880task CRxDmaPktChk::match_xmac_status(integer mac_id, bit[31:0] status) {
881bit [63:0] xmac_stat;
882 niu_rx_test_util.XMAC_STATUS_pio_rd(mac_id, xmac_stat);
883 if (xmac_stat[20:0] !== status[20:0])
884 printf("ERROR xmac status for port %0d did not match in the exit check. Exp 0x%h, Got 0x%h\n",
885 mac_id, status[20:0], xmac_stat[20:0]);
886 else
887 printf("EXIT-CHECK xmac status 0x%h for port %0d matched in the exit check.\n", status[20:0], mac_id);
888}
889
890task CRxDmaPktChk::match_bmac_status(integer mac_id, bit[31:0] status) {
891bit [63:0] bmac_stat;
892 niu_rx_test_util.BMAC_STATUS_pio_rd(mac_id, bmac_stat);
893 if (bmac_stat[7:0] !== status[7:0])
894 printf("ERROR bmac status for port %0d did not match in the exit check. Exp 0x%h, Got 0x%h\n",
895 mac_id, status[7:0], bmac_stat[7:0]);
896 else
897 printf("EXIT-CHECK bmac status 0x%h for port %0d matched in the exit check.\n", status[7:0], mac_id);
898}