Commit | Line | Data |
---|---|---|
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 | ||
58 | extern niu_gen_pio gen_pio_drv; | |
59 | extern Mesg be_msg; | |
60 | extern mbox_class mbox_id; | |
61 | extern CSparseMem SparseMem; | |
62 | extern CRDMC rdmc; | |
63 | extern event RX_chk_done; | |
64 | extern integer RX_TEST_REACHED_END; | |
65 | ||
66 | extern CNiuIntrMgr NiuIntrMgr; | |
67 | ||
68 | #define CR_L2_ERROR 1 | |
69 | ||
70 | class 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 | ||
158 | function 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 | ||
167 | task 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 | ||
200 | task 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 | ||
221 | if(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 | ||
289 | task CRxDmaPktChk::UpdateRCRStat( integer no_of_entries_to_check,integer pkts_checked, integer scatters[*],integer dma_no) { | |
290 | Crcr_update rcr_update; | |
291 | integer 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 | ||
307 | task 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 | ||
399 | task 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 | ||
560 | task 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 | ||
578 | task 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 | } | |
642 | task 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 | ||
799 | if (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 | ||
811 | task 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 | ||
815 | task 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 | ||
880 | task CRxDmaPktChk::match_xmac_status(integer mac_id, bit[31:0] status) { | |
881 | bit [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 | ||
890 | task CRxDmaPktChk::match_bmac_status(integer mac_id, bit[31:0] status) { | |
891 | bit [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 | } |