Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: rx_rand_test.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 "neptune_memory_map.vri" | |
37 | #include "xpcs_memory_map.vri" | |
38 | #include "txc_memory_map.vri" | |
39 | #include "dmc_memory_map.vri" | |
40 | #include "ipp_memory_map.vri" | |
41 | #include "fflp_memory_map.vri" | |
42 | #include "mac_defines.vri" | |
43 | #include "pio_driver.vrh" | |
44 | #include "mac_pio_class.vrh" | |
45 | #include "cMesg.vrh" | |
46 | #include "xmac_util.vrh" | |
47 | #include "bmac_util.vrh" | |
48 | #include "niu_mem.vrh" | |
49 | #include "niu_rx_descp.vrh" | |
50 | #include "niu_rxdmc.vrh" | |
51 | #include "pcg_defines.vri" | |
52 | #include "pcg_types.vri" | |
53 | #include "pack_db.vrh" | |
54 | #include "flow_db.vrh" | |
55 | #include "flow_db_tasks.vrh" | |
56 | #include "pg_top_pp.vrh" | |
57 | #include "pc_top_pp.vrh" | |
58 | #include "mbox_class.vrh" | |
59 | #include "get_mbox_id.vrh" | |
60 | #include "xmac_util.vrh" | |
61 | #include "bmac_util.vrh" | |
62 | #include "pcs_util.vrh" | |
63 | #include "xpcs_util.vrh" | |
64 | #include "pkt_configurator.vrh" | |
65 | #include "rand_packet.vrh" | |
66 | #include "rand_defines.vri" | |
67 | ||
68 | extern mac_util_class mac_util; | |
69 | extern bmac_util_class bmac_util; | |
70 | extern pio_drv pio_driver_class; | |
71 | extern mac_pio_cl mac_pio_class; | |
72 | extern bit[3:0] rtl_mac; | |
73 | extern Mesg be_msg; | |
74 | extern RxDMAChannel rx_dma[32]; | |
75 | extern CRDMC rdmc; | |
76 | extern hdl_task backdoor_init_tcam (); | |
77 | ||
78 | #define BYTES_PER_DESCR 4 | |
79 | #define DO_INTERNAL_RAND_KICKS 1 | |
80 | #define CCODE_V4_TCP 8 | |
81 | #define CCODE_V4_UDP 9 | |
82 | #define CCODE_V4_AHESP 10 | |
83 | #define CCODE_V4_SCTP 11 | |
84 | #define CCODE_V6_TCP 12 | |
85 | #define CCODE_V6_UDP 13 | |
86 | #define CCODE_V6_AHESP 14 | |
87 | #define CCODE_V6_SCTP 15 | |
88 | #define CCODE_ARP 16 | |
89 | #define CCODE_RARP 17 | |
90 | ||
91 | class rx_rand_test { | |
92 | //integer test_gen_rx_pkts_debug, quick_test, test_mac_verbose; | |
93 | rand_packet rx_rand_packet; | |
94 | integer num_of_mac_ports=0; | |
95 | integer num_pkts_port[4]; | |
96 | bit [15:0] initial_kick[16]; | |
97 | integer dring_len[16], cring_len[16]; | |
98 | flow_desc flow0[], flow1[], flow2[], flow3[]; | |
99 | integer port_rate[4]; //in Ghz | |
100 | integer pkt_len_param[4]; | |
101 | integer byte_sweep; | |
102 | integer pkt_max_len[4], pkt_min_len[4]; | |
103 | rx_rand_dma_parameters rand_dma_parameters; //each dma channel can have different parameters | |
104 | pkt_configurator pktC; | |
105 | integer cs_crc_err[4]; | |
106 | integer num_tcam_entries, num_tcam_repeats; | |
107 | integer frag_id, frag_id_tcp; | |
108 | bit hdr_18B_en; | |
109 | bit kick_mul16; | |
110 | static bit[3:0] second_to_last_packet_sent=0; | |
111 | static bit end_flushed=0; | |
112 | bit sending_pkts=1; | |
113 | integer DringMargin; | |
114 | integer kick_more_min, kick_more_max; | |
115 | bit do_frag, do_rand_def_dma, do_rand_vld, do_wred, do_rand_mask; | |
116 | integer wred_thre=0; | |
117 | bit do_rand_key_disc, reset_disc=0; | |
118 | bit do_rand_ad_disc; | |
119 | bit do_rand_hash_mask, set_errchkdisable, corrupt_vlan_parity, promis, da_mismatch; | |
120 | bit no_pad; | |
121 | integer l4_proto_err, send_pause; | |
122 | integer do_flush, do_rand_dis_dma, dma_off_time, poll_interval; | |
123 | integer send_runts=0; | |
124 | bit weights_50_1=0; //50:50:1:1 else 10:10:1:1 | |
125 | integer base_weight01; | |
126 | integer weight_margin; //percent | |
127 | bit[15:0] thr_timer_int_en; //one bit per dma | |
128 | bit[15:0] rcr_pkt_threshold; | |
129 | bit[5:0] rcr_timer_value; | |
130 | bit rx_init_done=0; | |
131 | ||
132 | task new(); | |
133 | task run(); | |
134 | task config_mac(integer mac_id); | |
135 | task config_zvt(); //zcprdc, vlan, tcam | |
136 | task send_rx_pkts(integer mac_id, integer num_pkts); | |
137 | task close(); | |
138 | task rx_control(); | |
139 | task rx_dma_config(integer dma_ch); | |
140 | task reg_access(); | |
141 | task rand_flush(); | |
142 | task rand_weights(); | |
143 | task rand_dis_dma(); | |
144 | task monitor_descriptors(); | |
145 | function integer set_pkt_len(integer len_param, integer max_len, integer min_len, integer num); | |
146 | function integer ipg_in_ns(integer rate_in_Mhz, integer pkt_len, integer header_len); | |
147 | function bit[47:0] get_l2dest_from_Trdc(bit[2:0] Trdc, integer mac_id); | |
148 | function bit[11:0] get_vlan_from_Trdc(bit[2:0] Trdc, integer mac_id); | |
149 | task setup_vlan_table(); //since backdoor vlan does not work right | |
150 | task tcam_compare(); | |
151 | } | |
152 | ///////////////////////////////////////// | |
153 | task rx_rand_test::new() { | |
154 | pktC = new; | |
155 | printf("rxTEST newed\n"); | |
156 | } | |
157 | ///////////////////////////////////////// | |
158 | task rx_rand_test::run() { | |
159 | shadow integer ii; | |
160 | bit[15:0] wred_init; | |
161 | ||
162 | for(ii=0; ii<4; ii++) {if(rtl_mac[ii]) num_of_mac_ports++;} | |
163 | printf("rxTEST number of ports enabled = %0d\n", num_of_mac_ports); | |
164 | ||
165 | rx_control(); | |
166 | ||
167 | if(do_wred) { | |
168 | wred_init=random(); | |
169 | gen_pio_drv.pio_wr(RED_RAN_INIT, {1'b1, wred_init}); | |
170 | } | |
171 | ||
172 | rand_dma_parameters = new(); | |
173 | ||
174 | for(ii=0; ii<16; ii++) { | |
175 | rx_dma_config(ii); | |
176 | if(!DO_INTERNAL_RAND_KICKS) | |
177 | fork | |
178 | rdmc.rx_dma[ii].periodic_kick(); //(interval=3000, num_desc=-1(rand), threshold=256); | |
179 | join none | |
180 | } | |
181 | rand_dma_parameters = null; | |
182 | ||
183 | for(ii=0; ii<4; ii++) if(rtl_mac[ii]) { | |
184 | config_mac(ii); | |
185 | } | |
186 | ||
187 | config_zvt(); | |
188 | repeat (2000) {@(CLOCK);} //delay to allow complete setup | |
189 | rx_init_done=1; | |
190 | printf("rxTEST done setup ======================== time=%0d\n", get_time(LO)); | |
191 | ||
192 | rx_rand_packet = new(); | |
193 | fork | |
194 | { | |
195 | fork | |
196 | if(rtl_mac[0]) { send_rx_pkts(0, num_pkts_port[0]); } | |
197 | if(rtl_mac[1]) { send_rx_pkts(1, num_pkts_port[1]); } | |
198 | if(rtl_mac[2]) { send_rx_pkts(2, num_pkts_port[2]); } | |
199 | if(rtl_mac[3]) { send_rx_pkts(3, num_pkts_port[3]); } | |
200 | join all | |
201 | printf("rxTEST done sending packets %0d\n", get_time(LO)); | |
202 | sending_pkts=0; | |
203 | } | |
204 | if(DO_INTERNAL_RAND_KICKS) monitor_descriptors(); | |
205 | reg_access(); | |
206 | rand_weights(); | |
207 | if(do_flush>0) rand_flush(); | |
208 | if(do_rand_dis_dma>0) rand_dis_dma(); | |
209 | join all | |
210 | ||
211 | close(); | |
212 | ||
213 | printf("rxTEST End time=%0d\n", get_time(LO)); | |
214 | } | |
215 | ////////////////////////////////////////////// | |
216 | task rx_rand_test::send_rx_pkts(integer mac_id, integer num_pkts) { | |
217 | shadow integer n, jj; | |
218 | integer last_packet, dma, ipg=600; | |
219 | integer pkt_len, header_len; | |
220 | integer L2head_len, L3head_len, L4head_len, CRC_len=4; | |
221 | bit[7:0] tmp; | |
222 | flow_desc tmp_flow; | |
223 | integer index; | |
224 | bit[199:0] key; | |
225 | bit[2:0] Trdc; | |
226 | bit[11:0] vlan; | |
227 | bit[47:0] mac_l2_dest; | |
228 | integer llcsnap_max; | |
229 | string type; | |
230 | bit anul_tcam_match; | |
231 | bit is_runt=0; | |
232 | ||
233 | printf("rxTEST send_rx_pkts starting mac_id=%0d time=%0d\n", mac_id, get_time(LO)); | |
234 | delay((random()%550)*mac_id); //stagger port starting time | |
235 | ||
236 | #define CLS_CODE 199:195 | |
237 | #define L2RDC_V4 189:187 | |
238 | #define NOPORT 186 | |
239 | #define ESP_AH 111 | |
240 | #define TOS_V4 111:104 | |
241 | #define PID_V4 103:96 | |
242 | #define TCP_SP_V4 95:80 | |
243 | #define TCP_DP_V4 79:64 | |
244 | #define SPI_V4 95:64 | |
245 | #define IP_SA_V4 63:32 | |
246 | #define IP_DA_V4 31:0 | |
247 | #define L2RDC_V6 189:187 | |
248 | #define TOS_V6 175:168 | |
249 | #define NXT_HDR 167:160 | |
250 | #define TCP_SP_V6 159:144 | |
251 | #define TCP_DP_V6 143:128 | |
252 | #define SPI_V6 159:128 | |
253 | #define IP_V6 127:0 | |
254 | #define B11_AFTER_ETHER 191:104 | |
255 | ||
256 | for(n=0; n<num_pkts; n++) { | |
257 | tmp_flow=new; | |
258 | void=rx_rand_packet.randomize(); | |
259 | ||
260 | last_packet = (n==num_pkts-1); | |
261 | is_runt=0; | |
262 | if(send_runts!==0) { | |
263 | if((random()%100) < send_runts) is_runt=1; | |
264 | } | |
265 | ||
266 | index=random()%num_tcam_entries; | |
267 | if(do_frag) { if(((random()%100)>2) && ((random()%100)<6)) index=frag_id; //3,4,5 | |
268 | if((random()%100)<3) index=frag_id_tcp; //0,1,2 | |
269 | } | |
270 | ||
271 | key=pktC.get_tcam_shadow(index); | |
272 | printf("rxTEST send frame ==========tcam_key: index=%0d cl_code=%0d key=0x%h\n", index, key[CLS_CODE], key); | |
273 | ||
274 | //print information about selected key | |
275 | if(key[CLS_CODE]>=8 && key[CLS_CODE]<=11) //v4 | |
276 | printf("rxTEST send frame v4 Trdc=%0d Tpid=%0d Tnoport=%0d Tl4src=0x%h Tl4dst=0x%h\n", key[L2RDC_V4], key[PID_V4], key[NOPORT], key[TCP_SP_V4], key[TCP_DP_V4]); | |
277 | else if(key[CLS_CODE]>=12 && key[CLS_CODE]<=15) //v6 | |
278 | printf("rxTEST send frame v6 Trdc=%0d Tnxt_hdr=%0d\n", key[L2RDC_V6], key[NXT_HDR]); | |
279 | else printf("rxTEST send frame other (ARP/RARP, userdefined, dummy)\n"); | |
280 | ||
281 | if(do_frag && (index==frag_id || index==frag_id_tcp)) { | |
282 | if(index==frag_id) | |
283 | case(random()%2) { | |
284 | 0: tmp_flow.frame.frame_class = CL_UDP_FRAG; | |
285 | 1: tmp_flow.frame.frame_class = CL_SCTP_FRAG; } | |
286 | else tmp_flow.frame.frame_class = CL_TCP_FRAG; | |
287 | } else | |
288 | case(key[CLS_CODE]) { | |
289 | CCODE_V4_TCP: tmp_flow.frame.frame_class = CL_TCP; | |
290 | CCODE_V4_UDP: tmp_flow.frame.frame_class = CL_UDP; | |
291 | CCODE_V4_AHESP: tmp_flow.frame.frame_class = (key[PID_V4]==51)?CL_IP_SEC_AH:CL_IP_SEC_ESP; | |
292 | CCODE_V4_SCTP: tmp_flow.frame.frame_class = CL_SCTP; | |
293 | CCODE_V6_TCP: tmp_flow.frame.frame_class = CL_TCP_IP_V6; | |
294 | CCODE_V6_UDP: tmp_flow.frame.frame_class = CL_UDP_IP_V6; | |
295 | CCODE_V6_AHESP: tmp_flow.frame.frame_class = (key[NXT_HDR]==51)?CL_IP_V6_SEC_AH:CL_IP_V6_SEC_ESP; | |
296 | CCODE_V6_SCTP: tmp_flow.frame.frame_class = CL_SCTP_IP_V6; | |
297 | CCODE_ARP: tmp_flow.frame.frame_class = CL_ARP; | |
298 | CCODE_RARP: tmp_flow.frame.frame_class = CL_RARP; | |
299 | } | |
300 | ||
301 | case(key[CLS_CODE]) { | |
302 | CCODE_V4_TCP, CCODE_V4_UDP, CCODE_V4_AHESP, CCODE_V4_SCTP: { | |
303 | tmp_flow.src_node.tos = key[TOS_V4]; | |
304 | if(key[CLS_CODE]==CCODE_V4_SCTP) { | |
305 | tmp_flow.sctp.src_sctp_port = key[TCP_SP_V4]; | |
306 | tmp_flow.sctp.dst_sctp_port = key[TCP_DP_V4]; | |
307 | } | |
308 | else { tmp_flow.tup.src_tcp_udp_port = key[TCP_SP_V4]; | |
309 | tmp_flow.tup.dst_tcp_udp_port = key[TCP_DP_V4]; | |
310 | } | |
311 | tmp_flow.src_node.ip_addr = key[IP_SA_V4]; | |
312 | tmp_flow.dst_node.ip_addr = key[IP_DA_V4]; | |
313 | tmp_flow.src_node.spi = key[SPI_V4]; | |
314 | tmp_flow.dst_node.spi = random(); | |
315 | tmp_flow.src_node.nxthdr = random(); | |
316 | tmp_flow.dst_node.nxthdr = random(); | |
317 | tmp_flow.frame.frame_type = 5'b00010; | |
318 | } | |
319 | CCODE_V6_TCP, CCODE_V6_UDP, CCODE_V6_AHESP, CCODE_V6_SCTP: { | |
320 | tmp_flow.src_node.tos = key[TOS_V6]; | |
321 | if(key[CLS_CODE]==CCODE_V6_SCTP) { | |
322 | tmp_flow.sctp.src_sctp_port = key[TCP_SP_V6]; | |
323 | tmp_flow.sctp.dst_sctp_port = key[TCP_DP_V6]; | |
324 | tmp_flow.tup.src_tcp_udp_port = key[TCP_SP_V6]; //for fflp_model | |
325 | tmp_flow.tup.dst_tcp_udp_port = key[TCP_DP_V6]; //for fflp_model | |
326 | } | |
327 | else { tmp_flow.tup.src_tcp_udp_port = key[TCP_SP_V6]; | |
328 | tmp_flow.tup.dst_tcp_udp_port = key[TCP_DP_V6]; | |
329 | } | |
330 | tmp_flow.src_node.ipv6_addr = {random(), random(), random(), random()}; | |
331 | tmp_flow.dst_node.ipv6_addr = {random(), random(), random(), random()}; | |
332 | if(pktC.FFLP_Model.tcam_key_reg[ key[CLS_CODE]-4 ].tcam_ipaddr) | |
333 | tmp_flow.src_node.ipv6_addr = key[IP_V6]; | |
334 | else tmp_flow.dst_node.ipv6_addr = key[IP_V6]; | |
335 | tmp_flow.src_node.spi = key[SPI_V6]; | |
336 | tmp_flow.dst_node.spi = random(); | |
337 | tmp_flow.src_node.nxthdr = random(); | |
338 | tmp_flow.dst_node.nxthdr = random(); | |
339 | tmp_flow.frame.frame_type = 5'b01010; | |
340 | } | |
341 | CCODE_ARP, CCODE_RARP: { | |
342 | } | |
343 | } | |
344 | ||
345 | tmp=random(); | |
346 | if(tmp[0]) tmp_flow.frame.frame_type[0]=1; //llc-snap | |
347 | ||
348 | //find l2_dest_addr from TCAM rdc match////////////////////// | |
349 | Trdc = (tmp_flow.frame.frame_type[3])? key[L2RDC_V6] : key[L2RDC_V4]; | |
350 | mac_l2_dest=get_l2dest_from_Trdc(Trdc, mac_id); | |
351 | if(mac_l2_dest===48'hXXXXXXXXXXXX) { | |
352 | printf("rxTEST send frame mac_l2_dest returned X from Tcam match -> randomize and do vlan\n"); | |
353 | if(mac_id==0 || mac_id==1) mac_l2_dest=rx_rand_packet.xmac_l2_dest_addr; | |
354 | else mac_l2_dest=rx_rand_packet.bmac_l2_dest_addr; | |
355 | } | |
356 | tmp_flow.dst_node.l2_addr = mac_l2_dest; | |
357 | ||
358 | if(da_mismatch) | |
359 | if(random()%100<5) { | |
360 | printf("TEST da_mismatch old=0x%h\n", tmp_flow.dst_node.l2_addr); | |
361 | tmp_flow.dst_node.l2_addr={tmp_flow.dst_node.l2_addr[47:1], ~tmp_flow.dst_node.l2_addr[0]}; //48 bit | |
362 | printf("TEST da_mismatch new=0x%h\n", tmp_flow.dst_node.l2_addr); | |
363 | } | |
364 | ||
365 | //find vlan from TCAM rdc match////////////////////// | |
366 | if(!(key[CLS_CODE]==CCODE_V4_AHESP || key[CLS_CODE]==CCODE_V6_AHESP)) {//if AH/ESP no vlan | |
367 | tmp=random(); | |
368 | if(tmp[1] || tmp[0]) { | |
369 | tmp_flow.frame.frame_type[2]=1; //vlan | |
370 | vlan = get_vlan_from_Trdc(Trdc, mac_id); | |
371 | //tmp_flow.src_node.tci = vlan; | |
372 | tmp_flow.src_node.tci = {random(), vlan}; //randomize upper 4 bits | |
373 | } | |
374 | } | |
375 | ||
376 | tmp_flow.src_node.l2_addr = rx_rand_packet.l2_src_addr; | |
377 | tmp_flow.src_node.src_port = rx_rand_packet.node_src_port; | |
378 | tmp_flow.dst_node.src_port = rx_rand_packet.node_src_port; | |
379 | ||
380 | tmp_flow.frame.type = -1; | |
381 | tmp_flow.frame.class_mask = 0; | |
382 | tmp_flow.frame.class_funct = rx_rand_packet.rx_frame_class_funct; | |
383 | tmp_flow.frame.data_type = rx_rand_packet.rx_frame_data_type; | |
384 | tmp_flow.frame.data_seed = 128; //random(); //128; | |
385 | tmp_flow.rx_param.rcv_isn = rx_rand_packet.rx_param_rcv_isn; | |
386 | tmp_flow.fl_state.tcp_flags = rx_rand_packet.rx_tcp_flags; | |
387 | tmp_flow.flow_no = 0; | |
388 | tmp_flow.frame.l2_pad_length = 0; | |
389 | ||
390 | //checksum computed for L4:TCP,UDP and L3: IPv4, IPv6 - non-frag | |
391 | if(cs_crc_err[mac_id]!==0 & !last_packet & !is_runt) { | |
392 | if((random()%100) < cs_crc_err[mac_id]) { | |
393 | tmp=random()%3; | |
394 | case(tmp) { | |
395 | 0: { tmp_flow.frame.error_code = PG_CHKSUM_ERR; | |
396 | tmp_flow.frame.frame_class = 16; //CL_TCP | |
397 | tmp_flow.frame.frame_type[1] = 1; | |
398 | tmp_flow.frame.frame_type[3] = 0; | |
399 | //tmp_flow.frame.frame_type = 5'b00010; | |
400 | } | |
401 | 1: tmp_flow.frame.error_code = PG_CRC_ERR; | |
402 | 2: { tmp_flow.frame.error_code = PG_CHKSUM_ERR | PG_CRC_ERR; | |
403 | tmp_flow.frame.frame_class = 16; //CL_TCP | |
404 | tmp_flow.frame.frame_type[1] = 1; | |
405 | tmp_flow.frame.frame_type[3] = 0; | |
406 | //tmp_flow.frame.frame_type = 5'b00010; | |
407 | } | |
408 | } | |
409 | printf("rxTEST send frame err %s mac.seq=%0d.%0d\n", (tmp==0)?"CKSUM":(tmp==1)?"CRC":"CKSUM&CRC", mac_id, n); | |
410 | } | |
411 | else tmp_flow.frame.error_code = 0; | |
412 | } | |
413 | ||
414 | // flow.frame.error_type_len = 16'h1234; //type/length field replaced with 0x1234. Use with caution! | |
415 | if(l4_proto_err!==0 & !last_packet & !is_runt) { | |
416 | //printf("TEST loop l4_proto_err=%0d last_packet=%0d is_runt=%0d\n", l4_proto_err, last_packet, is_runt); | |
417 | if((random()%100) < l4_proto_err) { | |
418 | tmp_flow.frame.error_code = PG_L4_PROTO_USER_MODE; | |
419 | tmp_flow.frame.l4_proto_field = 8'd138; // Choose as appropriate | |
420 | printf("rxTEST send frame err %s mac.seq=%0d.%0d\n", "L4_PROTO", mac_id, n); | |
421 | } | |
422 | } | |
423 | if(send_pause!==0) { | |
424 | if((random()%100) < send_pause) { | |
425 | tmp_flow.dst_node.l2_addr = l2_dest_pause; | |
426 | tmp_flow.frame.frame_type = 5'b00000; | |
427 | tmp_flow.frame.frame_class = CL_L2; | |
428 | tmp_flow.frame.data_type = DAT_FC_PAUSE; | |
429 | tmp_flow.frame.data_seed = 32'hffff0100; | |
430 | printf("rxTEST send pause mac.seq=%0d.%0d\n", mac_id, n); | |
431 | } | |
432 | } | |
433 | //////////////////////// | |
434 | ||
435 | //L2head_len | |
436 | L2head_len=14; // DA=6 + SA=2 + len/type=2 | |
437 | if(tmp_flow.frame.frame_type[0]) L2head_len+=8; //llc-snap | |
438 | if(tmp_flow.frame.frame_type[2]) L2head_len+=4; //vlan | |
439 | ||
440 | //L3head_len | |
441 | if( !tmp_flow.frame.frame_type[3] && tmp_flow.frame.frame_type[1] ) { // ipv4 - add options | |
442 | tmp_flow.frame.header_length = (random()%11)+5; // 5<=ipv4_header_len<=15 | |
443 | L3head_len=(tmp_flow.frame.header_length*4); | |
444 | } | |
445 | else { // ipv6 | |
446 | L3head_len=40; | |
447 | } | |
448 | ||
449 | //L4head_len | |
450 | if(tmp_flow.frame.frame_class==CL_TCP || | |
451 | tmp_flow.frame.frame_class==CL_TCP_FRAG || | |
452 | tmp_flow.frame.frame_class==CL_TCP_IP_V6) | |
453 | L4head_len=20; | |
454 | else if(tmp_flow.frame.frame_class==CL_UDP || | |
455 | tmp_flow.frame.frame_class==CL_UDP_FRAG || | |
456 | tmp_flow.frame.frame_class==CL_UDP_IP_V6) | |
457 | L4head_len=8; | |
458 | else if(tmp_flow.frame.frame_class==CL_IP_SEC_AH || | |
459 | tmp_flow.frame.frame_class==CL_IP_V6_SEC_AH) | |
460 | L4head_len=16; | |
461 | else if(tmp_flow.frame.frame_class==CL_IP_SEC_ESP || | |
462 | tmp_flow.frame.frame_class==CL_IP_V6_SEC_ESP ) | |
463 | L4head_len=12; | |
464 | else if(tmp_flow.frame.frame_class==CL_SCTP || | |
465 | tmp_flow.frame.frame_class==CL_SCTP_FRAG || | |
466 | tmp_flow.frame.frame_class==CL_SCTP_IP_V6 ) | |
467 | L4head_len=12; | |
468 | else L4head_len=0; | |
469 | ||
470 | header_len = L2head_len + L3head_len + L4head_len + CRC_len; | |
471 | //printf("rxTEST send frame max=%0d L2head=%0d L3head=%0d L4head=%0d tot(inc crc)=%0d\n", pkt_max_len[mac_id], L2head_len, L3head_len, L4head_len, header_len); | |
472 | ||
473 | ////////////pkt_len | |
474 | if(last_packet) { | |
475 | pkt_len=200; | |
476 | tmp_flow.frame.l2_pad_length = 0; | |
477 | } | |
478 | else if(is_runt) { | |
479 | //pkt_len=(random()%2)+1; | |
480 | pkt_len=(random()%62)+1; // 1<= runt_length < 64 | |
481 | if(pkt_len<18) tmp_flow.frame.frame_class = CL_L2_RUNT; // len < 18 | |
482 | else tmp_flow.frame.frame_class = CL_L2; // 18 <= len < 64 | |
483 | tmp_flow.frame.frame_type = 5'b00000; | |
484 | tmp_flow.frame.l2_pad_length = 0; | |
485 | printf("rxTEST send frame pkt is_runt len=%0d mac.seq=%0d.%0d\n", pkt_len, mac_id, n); | |
486 | } | |
487 | else if(key[CLS_CODE]==CCODE_ARP || key[CLS_CODE]==CCODE_RARP) { //ARP/RARP length=64 | |
488 | //pkt_len=64; | |
489 | pkt_len=pkt_min_len[mac_id]; | |
490 | } | |
491 | else if(tmp_flow.frame.frame_type[0]) { //llc-snap length <600h=1536 | |
492 | if(pkt_min_len[mac_id]>1536) { | |
493 | pkt_len=1536; | |
494 | tmp_flow.frame.l2_pad_length = 0; | |
495 | } | |
496 | else { | |
497 | llcsnap_max=(pkt_max_len[mac_id]<'h600)?pkt_max_len[mac_id]:1536; | |
498 | pkt_len=set_pkt_len(pkt_len_param[mac_id], llcsnap_max, pkt_min_len[mac_id], n); | |
499 | tmp_flow.frame.l2_pad_length = no_pad ? 0 : (random()%(llcsnap_max-pkt_min_len[mac_id]/2)); | |
500 | if(pkt_len+tmp_flow.frame.l2_pad_length>llcsnap_max) tmp_flow.frame.l2_pad_length = 0; | |
501 | } | |
502 | } | |
503 | else { | |
504 | pkt_len=set_pkt_len(pkt_len_param[mac_id], pkt_max_len[mac_id], pkt_min_len[mac_id], n); | |
505 | // TCP/UDP add padding | |
506 | if(!no_pad & ( tmp_flow.frame.frame_class==CCODE_V4_TCP || tmp_flow.frame.frame_class==CCODE_V4_UDP || | |
507 | tmp_flow.frame.frame_class==CCODE_V6_TCP || tmp_flow.frame.frame_class==CCODE_V6_UDP)) { | |
508 | while(pkt_len+tmp_flow.frame.l2_pad_length>pkt_max_len[mac_id]) { | |
509 | tmp_flow.frame.l2_pad_length = (random()%pkt_max_len[mac_id]/2); | |
510 | } | |
511 | } | |
512 | } | |
513 | ||
514 | if((pkt_len<header_len) & !is_runt) { // make sure pkt size does not go negative | |
515 | //adjust pad | |
516 | llcsnap_max=header_len-pkt_len; //reuse variable | |
517 | if(tmp_flow.frame.l2_pad_length-llcsnap_max <0) tmp_flow.frame.l2_pad_length=0; | |
518 | else tmp_flow.frame.l2_pad_length-=llcsnap_max; | |
519 | //adjust pkt_len | |
520 | printf("rxTEST send frame pkt_len<header_len, pkt-len changed was=%0d new=%0d\n", pkt_len, header_len); | |
521 | pkt_len=header_len; | |
522 | } | |
523 | //////////////////////// | |
524 | ||
525 | if(n==num_pkts-2) { | |
526 | second_to_last_packet_sent[mac_id]=1; | |
527 | } | |
528 | ||
529 | ||
530 | ||
531 | ||
532 | anul_tcam_match=random(); | |
533 | if(anul_tcam_match & index!==frag_id & index!==frag_id_tcp & !last_packet) { //sometimes, don't let tcam match - corrupt this key | |
534 | if( tmp_flow.frame.frame_type[3] && tmp_flow.frame.frame_type[1] ) { // ipv6 | |
535 | tmp=key[TOS_V6]; | |
536 | key[TOS_V6]={tmp[7:1],~tmp[0]}; | |
537 | tmp_flow.src_node.tos = key[TOS_V6]; | |
538 | printf("rxTEST send frame anul_tcam_match key[TOS_V6] old=0x%h new=0x%h\n", tmp, tmp_flow.src_node.tos); | |
539 | } | |
540 | else { //ipv4 | |
541 | tmp=key[TOS_V4]; | |
542 | key[TOS_V4]={tmp[7:1],~tmp[0]}; | |
543 | tmp_flow.src_node.tos = key[TOS_V4]; | |
544 | printf("rxTEST send frame anul_tcam_match key[TOS_V4] old=0x%h new=0x%h\n", tmp, tmp_flow.src_node.tos); | |
545 | } | |
546 | } | |
547 | ||
548 | case(tmp_flow.frame.frame_class) { | |
549 | CL_TCP: type = "TCP"; | |
550 | CL_TCP_FRAG: type = "TCP_FRAG"; | |
551 | CL_UDP: type = "UDP"; | |
552 | CL_UDP_FRAG: type = "UDP_FRAG"; | |
553 | CL_IP_SEC_AH: type = "AH"; | |
554 | CL_IP_SEC_ESP: type = "ESP"; | |
555 | CL_SCTP: type = "SCTP"; | |
556 | CL_SCTP_FRAG: type = "SCTP_FRAG"; | |
557 | CL_TCP_IP_V6: type = "TCP_V6"; | |
558 | CL_UDP_IP_V6: type = "UDP_V6"; | |
559 | CL_IP_V6_SEC_AH: type = "AH_V6"; | |
560 | CL_IP_V6_SEC_ESP: type = "ESP_V6"; | |
561 | CL_SCTP_IP_V6: type = "SCTP_V6"; //not defined | |
562 | CL_ARP: type = "ARP"; | |
563 | CL_RARP: type = "RARP"; | |
564 | CL_L2: type = "L2"; | |
565 | CL_L2_RUNT: type = "L2_RUNT"; | |
566 | default: type = "xxxx"; | |
567 | } | |
568 | printf("rxTEST send frame mac.seq=%0d.%0d pad=%3d len=%4d vlan=0x%0x d_l2addr=0x%0h f_class=%s f_type=%b time=%0d\n", mac_id, n, tmp_flow.frame.l2_pad_length, pkt_len, tmp_flow.src_node.tci, tmp_flow.dst_node.l2_addr, type, tmp_flow.frame.frame_type, get_time(LO)); | |
569 | //printf("rxTEST send frame mac.seq=%0d.%0d pad=%3d len=%4d vlan=0x%0x d_l2addr=0x%0h f_class=%s f_type=%b ip_sa=0x%0h ip_da=0x%0h time=%0d\n", mac_id, n, tmp_flow.frame.l2_pad_length, pkt_len, tmp_flow.src_node.tci, tmp_flow.dst_node.l2_addr, type, tmp_flow.frame.frame_type, tmp_flow.src_node.ip_addr, tmp_flow.dst_node.ip_addr, get_time(LO)); | |
570 | case(mac_id) { | |
571 | 0: { flow0[n]=tmp_flow; | |
572 | //pc path dma=not_used | |
573 | pktC.pkt_configurator_genPkt(0, pkt_len, 3'hx, mac_id, last_packet, flow0[n]); | |
574 | } | |
575 | 1: { flow1[n]=tmp_flow; | |
576 | pktC.pkt_configurator_genPkt(0, pkt_len, 3'hx, mac_id, last_packet, flow1[n]); | |
577 | } | |
578 | 2: { flow2[n]=tmp_flow; | |
579 | pktC.pkt_configurator_genPkt(0, pkt_len, 3'hx, mac_id, last_packet, flow2[n]); | |
580 | } | |
581 | 3: { flow3[n]=tmp_flow; | |
582 | pktC.pkt_configurator_genPkt(0, pkt_len, 3'hx, mac_id, last_packet, flow3[n]); | |
583 | } | |
584 | } | |
585 | ||
586 | ipg=ipg_in_ns(port_rate[mac_id], (pkt_len+tmp_flow.frame.l2_pad_length), tmp_flow.frame.header_length); | |
587 | delay(ipg); | |
588 | tmp_flow=null; | |
589 | ||
590 | if(second_to_last_packet_sent==={rtl_mac[3], rtl_mac[2], rtl_mac[1], rtl_mac[0]} && !end_flushed) { | |
591 | if(do_rand_key_disc & !reset_disc) { //don't drop last pkt | |
592 | //don't do tcam lookup (in case as_data.disc=1) | |
593 | printf("rxTEST tcam_key_reg second_to_last_packet disc=0x000 tsel=0x000 ipaddr=0xfff\n"); | |
594 | pktC.program_tcam_key_reg(12'h0, 12'h000, 12'hfff); | |
595 | reset_disc=1; | |
596 | } | |
597 | ||
598 | end_flushed=1; | |
599 | repeat(1000) @(posedge CLOCK); | |
600 | printf("rxTEST flushing all 16 Crings after second to last packet time=%0d\n", get_time(LO)); | |
601 | for(jj=0; jj<16; jj++) | |
602 | rdmc.rx_dma[jj].flush_rcr(1); | |
603 | printf("rxTEST waiting after flushing all 16 Crings after second to last packet time=%0d\n", get_time(LO)); | |
604 | repeat(5000) @(posedge CLOCK); | |
605 | printf("rxTEST done waiting after flushing all 16 Crings after second to last packet time=%0d\n", get_time(LO)); | |
606 | } | |
607 | } | |
608 | } | |
609 | ///////////////////////////////////////// | |
610 | task rx_rand_test::monitor_descriptors() { | |
611 | integer ii; | |
612 | integer kick_more; | |
613 | integer max, min; | |
614 | integer currDringSize, spaceAvail; | |
615 | ||
616 | while(sending_pkts) { | |
617 | for(ii=0; ii<16; ii++) { | |
618 | repeat(40) @(posedge CLOCK); | |
619 | currDringSize=rdmc.rx_dma[ii].get_curr_ring_size(); | |
620 | printf("rxTEST dma=%0d currDringSize=0x%0h DringMargin=0x%0h\n", ii, currDringSize, DringMargin); | |
621 | ||
622 | if(currDringSize < DringMargin) { | |
623 | spaceAvail=dring_len[ii]-currDringSize; | |
624 | max=(kick_more_max>spaceAvail) ? spaceAvail : kick_more_max; | |
625 | min=(kick_more_min>max) ? max : kick_more_min; | |
626 | ||
627 | if(kick_mul16) kick_more=(((random()%(max-min+1)) + min)/16)*16; | |
628 | else kick_more=(random()%(max-min+1)) + min; | |
629 | ||
630 | printf("rxTEST dma=%0d kick_more=0x%0h currDringSize=0x%0h dring_len=0x%0h time=%0d\n", ii, kick_more, currDringSize, dring_len[ii], get_time(LO)); | |
631 | rdmc.rx_dma[ii].setRxRingKick(kick_more); | |
632 | } | |
633 | } | |
634 | } | |
635 | } | |
636 | ////////////////////////////////////////// | |
637 | task rx_rand_test::config_mac(integer mac_id) { | |
638 | shadow integer n; | |
639 | integer jj; | |
640 | bit[39:0] base_addr; | |
641 | bit[31:0] rd_data; | |
642 | bit[63:0] rd_data64; | |
643 | bit[35:0] tmp; | |
644 | bit [31:0] bmac_rd_data; | |
645 | ||
646 | base_addr = bmac_util.get_mac_reg_base(mac_id); | |
647 | //printf("rxTEST config mac_id=%0d base_addr=0x%h\n", mac_id, base_addr); | |
648 | ||
649 | mac_pio_class.xmac_pio_rd( base_addr + XMAC_CONFIG, rd_data, 1'b0 ); | |
650 | if(promis) rd_data[10:9]=2'b01; //promiscuous | |
651 | else rd_data[10:9]=2'b00; //non-promiscuous | |
652 | rd_data[16]=1; //addr_filter_en | |
653 | if(set_errchkdisable) rd_data[11]=1; //ErrChkdisable 1:send to def dma | |
654 | else rd_data[11]=0; //ErrChkdisable 0:set abort(drop) bit | |
655 | rd_data[12]=0; //rx_crc_chk_dis 0:do crc checking | |
656 | mac_pio_class.xmac_pio_wr(base_addr + XMAC_CONFIG, rd_data); | |
657 | printf("rxTEST mac_id=%0d XMAC_CONFIG=0x%0h\n", mac_id, rd_data); | |
658 | ||
659 | //gen_pio_drv.pio_rd(IPP_ADDRESS_RANGE+IPP_CONFIG+(mac_id*32'h8000), rd_data64); | |
660 | //printf("rxTEST mac_id=%0d IPP_CONFIG=0x%0h addr=0x%0h\n", mac_id, rd_data64, IPP_ADDRESS_RANGE+IPP_CONFIG+(mac_id*32'h8000)); | |
661 | ||
662 | // program default dma for each port | |
663 | if(do_rand_def_dma) { | |
664 | jj=random()%16; | |
665 | printf("rxTEST mac_id=%0d default dma=%0d\n", mac_id, jj); | |
666 | rdmc.ProgramPortDefDma(mac_id, jj); | |
667 | } | |
668 | ||
669 | ||
670 | // format: pktC.prog_mac_reg( mac_id, index, {pri,rdc,macda} ) | |
671 | tmp=random(); | |
672 | if(mac_id==0) { | |
673 | pktC.prog_mac_reg(0, 0, {tmp[0], 3'd0, xmac_l2_dest_addr0}); | |
674 | pktC.prog_mac_reg(0, 1, {tmp[1], 3'd1, xmac_l2_dest_addr1}); | |
675 | pktC.prog_mac_reg(0, 2, {tmp[2], 3'd2, xmac_l2_dest_addr2}); | |
676 | pktC.prog_mac_reg(0, 3, {tmp[3], 3'd3, xmac_l2_dest_addr3}); | |
677 | pktC.prog_mac_reg(0, 4, {tmp[4], 3'd4, xmac_l2_dest_addr4}); | |
678 | pktC.prog_mac_reg(0, 5, {tmp[5], 3'd5, xmac_l2_dest_addr5}); | |
679 | pktC.prog_mac_reg(0, 6, {tmp[6], 3'd6, xmac_l2_dest_addr6}); | |
680 | pktC.prog_mac_reg(0, 7, {tmp[7], 3'd7, xmac_l2_dest_addr7}); | |
681 | pktC.prog_mac_reg(0, 8, {tmp[8], 3'd0, xmac_l2_dest_addr8}); | |
682 | pktC.prog_mac_reg(0, 9, {tmp[9], 3'd1, xmac_l2_dest_addr9}); | |
683 | pktC.prog_mac_reg(0, 10,{tmp[10],3'd2, xmac_l2_dest_addr10}); | |
684 | pktC.prog_mac_reg(0, 11,{tmp[11],3'd3, xmac_l2_dest_addr11}); | |
685 | pktC.prog_mac_reg(0, 12,{tmp[12],3'd4, xmac_l2_dest_addr12}); | |
686 | pktC.prog_mac_reg(0, 13,{tmp[13],3'd5, xmac_l2_dest_addr13}); | |
687 | pktC.prog_mac_reg(0, 14,{tmp[14],3'd6, xmac_l2_dest_addr14}); | |
688 | if(send_pause==0) pktC.prog_mac_reg(0, 15,{tmp[15],3'd7, xmac_l2_dest_addr15}); | |
689 | else pktC.prog_mac_reg(0, 15,{tmp[15],3'd7, l2_dest_pause}); | |
690 | } | |
691 | if(mac_id==1) { | |
692 | pktC.prog_mac_reg(1, 0, {tmp[16],3'd7, xmac_l2_dest_addr0}); | |
693 | pktC.prog_mac_reg(1, 1, {tmp[17],3'd6, xmac_l2_dest_addr1}); | |
694 | pktC.prog_mac_reg(1, 2, {tmp[18],3'd5, xmac_l2_dest_addr2}); | |
695 | pktC.prog_mac_reg(1, 3, {tmp[18],3'd4, xmac_l2_dest_addr3}); | |
696 | pktC.prog_mac_reg(1, 4, {tmp[20],3'd3, xmac_l2_dest_addr4}); | |
697 | pktC.prog_mac_reg(1, 5, {tmp[21],3'd2, xmac_l2_dest_addr5}); | |
698 | pktC.prog_mac_reg(1, 6, {tmp[22],3'd1, xmac_l2_dest_addr6}); | |
699 | pktC.prog_mac_reg(1, 7, {tmp[23],3'd0, xmac_l2_dest_addr7}); | |
700 | pktC.prog_mac_reg(1, 8, {tmp[24],3'd7, xmac_l2_dest_addr8}); | |
701 | pktC.prog_mac_reg(1, 9, {tmp[25],3'd6, xmac_l2_dest_addr9}); | |
702 | pktC.prog_mac_reg(1, 10,{tmp[26],3'd5, xmac_l2_dest_addr10}); | |
703 | pktC.prog_mac_reg(1, 11,{tmp[27],3'd4, xmac_l2_dest_addr11}); | |
704 | pktC.prog_mac_reg(1, 12,{tmp[28],3'd3, xmac_l2_dest_addr12}); | |
705 | pktC.prog_mac_reg(1, 13,{tmp[29],3'd2, xmac_l2_dest_addr13}); | |
706 | pktC.prog_mac_reg(1, 14,{tmp[30],3'd1, xmac_l2_dest_addr14}); | |
707 | if(send_pause==0) pktC.prog_mac_reg(1, 15,{tmp[31],3'd0, xmac_l2_dest_addr15}); | |
708 | else pktC.prog_mac_reg(1, 15,{tmp[31],3'd0, l2_dest_pause}); | |
709 | } | |
710 | if(mac_id==2) { | |
711 | pktC.prog_mac_reg(2, 0, {tmp[0], 3'd2, bmac_l2_dest_addr0}); | |
712 | pktC.prog_mac_reg(2, 1, {tmp[1], 3'd4, bmac_l2_dest_addr1}); | |
713 | pktC.prog_mac_reg(2, 2, {tmp[2], 3'd6, bmac_l2_dest_addr2}); | |
714 | pktC.prog_mac_reg(2, 3, {tmp[3], 3'd0, bmac_l2_dest_addr3}); | |
715 | pktC.prog_mac_reg(2, 4, {tmp[4], 3'd3, bmac_l2_dest_addr4}); | |
716 | pktC.prog_mac_reg(2, 5, {tmp[5], 3'd5, bmac_l2_dest_addr5}); | |
717 | pktC.prog_mac_reg(2, 6, {tmp[6], 3'd7, bmac_l2_dest_addr6}); | |
718 | if(send_pause==0) pktC.prog_mac_reg(2, 7, {tmp[7], 3'd1, bmac_l2_dest_addr7}); | |
719 | else pktC.prog_mac_reg(2, 7, {tmp[7], 3'd1, l2_dest_pause}); | |
720 | // Disable ERR_CHK_DIS bit in RxMAC_CONFIG register, so MAC sets abort bit for bad pkts | |
721 | mac_pio_class.bmac_pio_rd(base_addr + RxMAC_CONFIG, bmac_rd_data, 0); | |
722 | bmac_rd_data[7] = 0; // Turn off the ERR_CHK_DIS bit | |
723 | mac_pio_class.bmac_pio_wr(base_addr + RxMAC_CONFIG, bmac_rd_data); | |
724 | // Program the minimum size in bmac to be 64B | |
725 | mac_pio_class.bmac_pio_wr(base_addr + BMAC_MIN, 64'h40); | |
726 | } | |
727 | if(mac_id==3) { | |
728 | pktC.prog_mac_reg(3, 0, {tmp[16],3'd3, bmac_l2_dest_addr0}); | |
729 | pktC.prog_mac_reg(3, 1, {tmp[17],3'd5, bmac_l2_dest_addr1}); | |
730 | pktC.prog_mac_reg(3, 2, {tmp[18],3'd7, bmac_l2_dest_addr2}); | |
731 | pktC.prog_mac_reg(3, 3, {tmp[18],3'd1, bmac_l2_dest_addr3}); | |
732 | pktC.prog_mac_reg(3, 4, {tmp[20],3'd2, bmac_l2_dest_addr4}); | |
733 | pktC.prog_mac_reg(3, 5, {tmp[21],3'd4, bmac_l2_dest_addr5}); | |
734 | pktC.prog_mac_reg(3, 6, {tmp[22],3'd6, bmac_l2_dest_addr6}); | |
735 | if(send_pause==0) pktC.prog_mac_reg(3, 7, {tmp[23],3'd0, bmac_l2_dest_addr7}); | |
736 | else pktC.prog_mac_reg(3, 7, {tmp[23],3'd0, l2_dest_pause}); | |
737 | // Disable ERR_CHK_DIS bit in RxMAC_CONFIG register, so MAC sets abort bit for bad pkts | |
738 | mac_pio_class.bmac_pio_rd(base_addr + RxMAC_CONFIG, bmac_rd_data, 0); | |
739 | bmac_rd_data[7] = 0; // Turn off the ERR_CHK_DIS bit | |
740 | mac_pio_class.bmac_pio_wr(base_addr + RxMAC_CONFIG, bmac_rd_data); | |
741 | // Program the minimum size in bmac to be 64B | |
742 | mac_pio_class.bmac_pio_wr(base_addr + BMAC_MIN, 64'h40); | |
743 | } | |
744 | /* | |
745 | //read to check | |
746 | if(rtl_mac[0] || rtl_mac[1]) { | |
747 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO0, rd_data, 1'b0); | |
748 | printf("rxTEST XMAC_HOST_INFO0 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
749 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO1, rd_data, 1'b0); | |
750 | printf("rxTEST XMAC_HOST_INFO1 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
751 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO2, rd_data, 1'b0); | |
752 | printf("rxTEST XMAC_HOST_INFO2 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
753 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO3, rd_data, 1'b0); | |
754 | printf("rxTEST XMAC_HOST_INFO3 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
755 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO4, rd_data, 1'b0); | |
756 | printf("rxTEST XMAC_HOST_INFO4 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
757 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO5, rd_data, 1'b0); | |
758 | printf("rxTEST XMAC_HOST_INFO5 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
759 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO6, rd_data, 1'b0); | |
760 | printf("rxTEST XMAC_HOST_INFO6 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
761 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO7, rd_data, 1'b0); | |
762 | printf("rxTEST XMAC_HOST_INFO7 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
763 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO8, rd_data, 1'b0); | |
764 | printf("rxTEST XMAC_HOST_INFO8 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
765 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO9, rd_data, 1'b0); | |
766 | printf("rxTEST XMAC_HOST_INFO9 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
767 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO10, rd_data, 1'b0); | |
768 | printf("rxTEST XMAC_HOST_INFO10 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
769 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO11, rd_data, 1'b0); | |
770 | printf("rxTEST XMAC_HOST_INFO11 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
771 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO12, rd_data, 1'b0); | |
772 | printf("rxTEST XMAC_HOST_INFO12 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
773 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO13, rd_data, 1'b0); | |
774 | printf("rxTEST XMAC_HOST_INFO13 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
775 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO14, rd_data, 1'b0); | |
776 | printf("rxTEST XMAC_HOST_INFO14 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
777 | mac_pio_class.xmac_pio_rd(base_addr + XMAC_HOST_INFO15, rd_data, 1'b0); | |
778 | printf("rxTEST XMAC_HOST_INFO15 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
779 | } | |
780 | if(rtl_mac[2] || rtl_mac[3]) { | |
781 | ||
782 | //mac_pio_class.bmac_pio_rd(base_addr + BMAC_HOST_INF0, rd_data, 1'b0); | |
783 | // printf("rxTEST BMAC_HOST_INFO0 read=0x%h time=%0d\n", rd_data, get_time(LO)); | |
784 | } | |
785 | */ | |
786 | } | |
787 | ////////////////////////////////////////// | |
788 | task rx_rand_test::config_zvt() { | |
789 | bit[35:0] tmp; | |
790 | integer Zdma, ii, jj; | |
791 | integer kk; | |
792 | integer tcam_type; | |
793 | bit [2:0] rand_rdc; | |
794 | bit[199:0] key, mask; | |
795 | bit[63:0] rd_data64, assoc_data; | |
796 | bit[9:0] htmp; | |
797 | bit frontdoor=0; | |
798 | ||
799 | ////////////// ZCP-RDC | |
800 | printf("rxTEST program zcp-rdc tables\n"); | |
801 | ii=0; | |
802 | for(jj=0; jj<128; jj++) { | |
803 | if(jj%16==0) Zdma=ii++; | |
804 | else Zdma=random(); | |
805 | pktC.zcp_rdc(jj, Zdma); | |
806 | } | |
807 | ////////////// VLAN | |
808 | printf("rxTEST setup vlan table\n"); | |
809 | //pktC.setup_vlan_table(); | |
810 | setup_vlan_table(); //task in test | |
811 | ||
812 | ////////////// TCAM | |
813 | printf("rxTEST setup tcam tables\n"); | |
814 | backdoor_init_tcam(); //verilog task in n2_niu_tb_task.v, forces keys=0, masks=1 | |
815 | ||
816 | //gen_pio_drv.pio_rd(FFLP_TCP_CFLAG_MASK+FFLP_ADDRESS_RANGE, rd_data64); | |
817 | //printf("rxTEST FFLP flag mask=0x%0h\n", rd_data64); | |
818 | ||
819 | #define CAM_LATENCY 19:16 | |
820 | #define LLCSNAP 0 | |
821 | gen_pio_drv.pio_rd(fullFFLP_CONFIG, rd_data64); | |
822 | rd_data64[CAM_LATENCY] = 4; | |
823 | rd_data64[LLCSNAP] = 1; | |
824 | printf("rxTEST Set FFLP Config cam_lat=%0d llc_snap=%0d\n", rd_data64[CAM_LATENCY], rd_data64[LLCSNAP]); | |
825 | gen_pio_drv.pio_wr(fullFFLP_CONFIG, rd_data64); | |
826 | ||
827 | tmp={12'h000, 12'hfff, 12'hfff}; //disc[34:24], tsel[23:12], ipaddr[11:0] | |
828 | tmp[23:0]=random(); //tsel, ipaddr | |
829 | if(do_frag) tmp[19:16]=4'b1111; //do tcam lookup for frag pkts (frag only v4) | |
830 | if(get_plus_arg(CHECK, "DISABLE_TCAM")) tmp[23:12] = 0; | |
831 | if(do_rand_key_disc) tmp[35:24]=random() && random(); | |
832 | printf("rxTEST tcam_key_reg disc=0x%3h tsel=0x%3h ipaddr=0x%3h\n", tmp[35:24], tmp[23:12], tmp[11:0]); | |
833 | pktC.program_tcam_key_reg(tmp[35:24], tmp[23:12], tmp[11:0]); | |
834 | ||
835 | #define PID_ESP 50 | |
836 | #define PID_AH 51 | |
837 | #define PID_TCP 6 | |
838 | #define PID_UDP 17 | |
839 | #define PID_SCTP 132 | |
840 | ||
841 | for(jj=0; jj<num_tcam_entries; jj++) { | |
842 | //////////////////key | |
843 | key=200'h0; | |
844 | ||
845 | if(do_frag && (jj==frag_id || jj==frag_id_tcp)) { | |
846 | key[NOPORT] = 1; | |
847 | key[CLS_CODE] = CCODE_V4_TCP; | |
848 | key[PID_V4] = PID_TCP; | |
849 | key[L2RDC_V4] = random()%8; //l2_drc_table_num, 0-7 | |
850 | key[TOS_V4] = random(); //TOS | |
851 | key[TCP_SP_V4] = random(); //TCP SPort or SPI_hi | |
852 | key[TCP_DP_V4] = random(); //TCP DPort or SPI_lo | |
853 | key[IP_SA_V4] = random(); //IPv4 SA | |
854 | key[IP_DA_V4] = random(); //IPv4 DA | |
855 | } | |
856 | else { | |
857 | //key[ESP_AH]=random(); | |
858 | tcam_type=random()%6; //give more priority to IPv4 | |
859 | case(tcam_type) { | |
860 | 0,1,2: { //IPv4 | |
861 | key[L2RDC_V4] = random()%8; //l2_drc_table_num, 0-7 | |
862 | key[NOPORT] = 0; //noport | |
863 | key[TOS_V4] = random(); //TOS | |
864 | key[TCP_SP_V4] = random(); //TCP SPort or SPI_hi | |
865 | key[TCP_DP_V4] = random(); //TCP DPort or SPI_lo | |
866 | key[IP_SA_V4] = random(); //IPv4 SA | |
867 | key[IP_DA_V4] = random(); //IPv4 DA | |
868 | key[CLS_CODE] = CCODE_V4_TCP+random()%4; //hdr class index, 8=TCP 9=UDP 10=AH/ESP 11=SCTP | |
869 | case(key[CLS_CODE]) { | |
870 | CCODE_V4_TCP: key[PID_V4] = PID_TCP; | |
871 | CCODE_V4_UDP: key[PID_V4] = PID_UDP; | |
872 | CCODE_V4_AHESP: key[PID_V4] = key[ESP_AH]? PID_ESP:PID_AH; | |
873 | CCODE_V4_SCTP: key[PID_V4] = PID_SCTP; | |
874 | } | |
875 | } | |
876 | 3,4: { //IPv6 | |
877 | key[L2RDC_V6] = random()%8; //l2_drc_table_num, 0-7 | |
878 | key[TOS_V6] = random(); //TOS | |
879 | key[TCP_SP_V6] = random(); //TCP SPort or SPI_hi | |
880 | key[TCP_DP_V6] = random(); //TCP DPort or SPI_lo | |
881 | key[IP_V6] = {random(), random(), random(), random()}; //IPv6 DA or SA | |
882 | key[CLS_CODE] = CCODE_V6_TCP+random()%4; //hdr class index, 12=TCP 13=UDP 14=AH/ESP 15=SCTP | |
883 | case(key[CLS_CODE]) { | |
884 | CCODE_V6_TCP: key[NXT_HDR] = PID_TCP; | |
885 | CCODE_V4_UDP: key[NXT_HDR] = PID_UDP; | |
886 | CCODE_V6_AHESP: key[NXT_HDR] = key[ESP_AH]? PID_ESP:PID_AH; | |
887 | CCODE_V6_SCTP: key[NXT_HDR] = PID_SCTP; | |
888 | } | |
889 | } | |
890 | 5: { //EtherType (ARP/RARP) | |
891 | key[CLS_CODE] = 16+random()%2; //header class index, 16=ARP 17=RARP | |
892 | key[B11_AFTER_ETHER] = {random(),random(),random()}; //first 11B after EtherType | |
893 | } | |
894 | } | |
895 | } | |
896 | //////////////////assoc_data | |
897 | #define ASSOC_RDC 9:7 | |
898 | #define ASSOC_OFFSET 6:2 | |
899 | #define TRES 11:10 | |
900 | #define DISC 12 | |
901 | #define V4_ECC_CHK 13 | |
902 | #define ZFVLD 1 //used in Neptune | |
903 | assoc_data={random(),random()}; | |
904 | assoc_data[ZFVLD]=0; //set zero because we aren't doing zero copy function | |
905 | if(do_rand_ad_disc && (random()%100)<10) assoc_data[DISC]=1; | |
906 | else assoc_data[DISC]=0; | |
907 | if(key[NOPORT]) { | |
908 | assoc_data[TRES]='b11; | |
909 | } | |
910 | else assoc_data[TRES]=random()%4; | |
911 | //b01=use offset specified, terminate flow | |
912 | //b10=override L2 RDC num, continue flow lookup | |
913 | //b11=override L2 RDC num, use offset specified | |
914 | //b00=use L2 RDC num, continue flow lookup | |
915 | //The last entry (=frag_id) which has noport bit set should not | |
916 | //have do_ecc bit set. We dont do ecc for wildcard entries. | |
917 | if(do_frag && (jj==frag_id)) { | |
918 | assoc_data[V4_ECC_CHK]='b0; | |
919 | } | |
920 | //////////////////mask | |
921 | if(do_rand_mask) mask={random(), random(), random(), random(), random(), random(), random()}; | |
922 | else mask={200{1'b1}}; | |
923 | if(do_frag && jj==frag_id) { | |
924 | mask=0; | |
925 | mask[NOPORT]=1; | |
926 | frontdoor=1; //frontdoor load this entry/mask in tcam | |
927 | } | |
928 | else if(do_frag && jj==frag_id_tcp) { | |
929 | mask=0; | |
930 | mask[NOPORT]=1; | |
931 | mask[CLS_CODE]=6'h3f; | |
932 | frontdoor=1; //frontdoor load this entry/mask in tcam | |
933 | } | |
934 | else { frontdoor=0; } | |
935 | ||
936 | //printf("rxTEST program_tcam Index=%0d key=0x%0h data=0x%0h mask=0x%0h time=%0d\n", jj, key, assoc_data, mask, get_time(LO)); | |
937 | pktC.program_tcam_key_asdata(jj, key, assoc_data, mask, frontdoor); | |
938 | } | |
939 | for(jj=0; jj<num_tcam_repeats; jj++) { | |
940 | ii=random()%(num_tcam_entries-2); //just don't do last 2 even if !do_frag | |
941 | key=pktC.get_tcam_shadow(ii); //get from shadows | |
942 | assoc_data=pktC.get_assoc_data(ii); | |
943 | mask=pktC.get_tcam_mask(ii); | |
944 | frontdoor=1; //frontdoor these now | |
945 | ||
946 | Zdma=(random()%4)+1; //(dummy var) number of entries to write to 1-4 | |
947 | printf("rxTEST Index=%0d asdata=0x%0h repeat=%0d\n", ii, assoc_data, Zdma); | |
948 | rand_rdc = random()%8; | |
949 | repeat(Zdma) { //write to 1-4 other locations | |
950 | kk=random()%(num_tcam_entries-2); | |
951 | printf("Avoid Table Aliasing: making sure all identical entries have different TCAM-resulted rdc/offset\n"); | |
952 | assoc_data[ASSOC_RDC] = rand_rdc ++; | |
953 | printf("rxTEST to Index=%0d num_tcam_entries=%0d\n", kk, num_tcam_entries); | |
954 | pktC.program_tcam_key_asdata(kk, key, assoc_data, mask, frontdoor); | |
955 | } | |
956 | } | |
957 | ||
958 | //////////////////HASH1 | |
959 | // program the flow_key_reg for all 8 classes | |
960 | #define L4_0 3:2 // 'b01 is reserved | |
961 | #define L4_1 1:0 // 'b01 is reserved | |
962 | if(do_rand_hash_mask) { | |
963 | htmp=random(); if(htmp[L4_0]=='b01) htmp[L4_0]='b11; | |
964 | if(htmp[L4_1]=='b01) htmp[L4_1]='b10; | |
965 | pktC.prog_flow_key(8, htmp); // TCP | |
966 | printf("rxTEST prog_flow_key 8 TCP=0x%h\n", htmp); | |
967 | ||
968 | htmp={random(), 4'b1010}; pktC.prog_flow_key(9, htmp); | |
969 | printf("rxTEST prog_flow_key 9 TCP=0x%h\n", htmp); | |
970 | ||
971 | htmp={random(), 4'b1111}; pktC.prog_flow_key(10, htmp); | |
972 | printf("rxTEST prog_flow_key 10 TCP=0x%h\n", htmp); | |
973 | ||
974 | htmp=random(); if(htmp[L4_0]=='b01) htmp[L4_0]='b11; | |
975 | if(htmp[L4_1]=='b01) htmp[L4_1]='b00; | |
976 | pktC.prog_flow_key(11, htmp); // SCTP | |
977 | printf("rxTEST prog_flow_key 11 TCP=0x%h\n", htmp); | |
978 | ||
979 | htmp=random(); if(htmp[L4_0]=='b01) htmp[L4_0]='b00; | |
980 | if(htmp[L4_1]=='b01) htmp[L4_1]='b11; | |
981 | pktC.prog_flow_key(12, htmp); // TCPV6 | |
982 | printf("rxTEST prog_flow_key 12 TCP=0x%h\n", htmp); | |
983 | ||
984 | htmp={random(), 4'b1010}; pktC.prog_flow_key(13, htmp); | |
985 | printf("rxTEST prog_flow_key 13 TCP=0x%h\n", htmp); | |
986 | ||
987 | htmp={random(), 4'b1111}; pktC.prog_flow_key(14, htmp); | |
988 | printf("rxTEST prog_flow_key 14 TCP=0x%h\n", htmp); | |
989 | ||
990 | htmp=random(); if(htmp[L4_0]=='b01) htmp[L4_0]='b10; | |
991 | if(htmp[L4_1]=='b01) htmp[L4_1]='b00; | |
992 | pktC.prog_flow_key(15, htmp); // SCTPV6 | |
993 | printf("rxTEST prog_flow_key 15 TCP=0x%h\n", htmp); | |
994 | } | |
995 | else { | |
996 | pktC.prog_flow_key(8, 10'h3ff); // TCP | |
997 | pktC.prog_flow_key(9, 10'h3fa); | |
998 | pktC.prog_flow_key(10, 10'h3ff); | |
999 | pktC.prog_flow_key(11, 10'h3ff); // SCTP | |
1000 | pktC.prog_flow_key(12, 10'h3ff); // TCPV6 | |
1001 | pktC.prog_flow_key(13, 10'h3fa); | |
1002 | pktC.prog_flow_key(14, 10'h3ff); | |
1003 | pktC.prog_flow_key(15, 10'h3ff); // SCTPV6 | |
1004 | } | |
1005 | /* | |
1006 | //check shadow | |
1007 | for(jj=0; jj<12; jj++) { | |
1008 | printf("rxTEST pktC.FFLP_Model.tcam_key_reg %0d disc=%0d sel=%0d, ipaddr=%0d\n", jj, | |
1009 | pktC.FFLP_Model.tcam_key_reg[jj].tcam_disc, \ | |
1010 | pktC.FFLP_Model.tcam_key_reg[jj].tcam_sel, \ | |
1011 | pktC.FFLP_Model.tcam_key_reg[jj].tcam_ipaddr); | |
1012 | } | |
1013 | */ | |
1014 | /* | |
1015 | //read to check | |
1016 | for(jj=0; jj<128; jj++) { | |
1017 | gen_pio_drv.pio_rd(ZCP_RDC_TBL+(8*jj), rd_data64); | |
1018 | printf("rxTEST read ZCP_RDC_TBL %0d=%0d\n", jj, rd_data64); | |
1019 | } | |
1020 | */ | |
1021 | /* | |
1022 | //read to check | |
1023 | for(jj=0; jj<num_tcam_entries; jj++) { | |
1024 | printf("rxTEST shadow %0d = 0x%h\n", jj, pktC.get_tcam_shadow(jj)); | |
1025 | } | |
1026 | */ | |
1027 | } | |
1028 | //////////////////////////////////////////////////////////// | |
1029 | task rx_rand_test::setup_vlan_table() { | |
1030 | bit[2:0] rdctbl0, rdctbl1, rdctbl2, rdctbl3; | |
1031 | bit parity0, parity1; | |
1032 | bit vpr0, vpr1, vpr2, vpr3; | |
1033 | integer ii; | |
1034 | bit[17:0] vlan_entry; | |
1035 | bit[3:0] tmp; | |
1036 | ||
1037 | #define BACKDOOR 1 | |
1038 | for(ii=0; ii<4096; ii++) { | |
1039 | rdctbl0 = random(); | |
1040 | rdctbl1 = random(); | |
1041 | rdctbl2 = random(); | |
1042 | rdctbl3 = random(); | |
1043 | tmp=random(); | |
1044 | vpr3=tmp[3]; vpr2=tmp[2]; vpr1=tmp[1]; vpr0=tmp[0]; | |
1045 | parity0 = ^{vpr1, rdctbl1, vpr0, rdctbl0}; | |
1046 | parity1 = ^{vpr3, rdctbl3, vpr2, rdctbl2}; | |
1047 | if(corrupt_vlan_parity) | |
1048 | if(random()%100<5) { | |
1049 | tmp=random(); | |
1050 | printf("TEST corrupt_vlan_parity old0=%b old1=%b\n", parity0, parity1); | |
1051 | if(tmp[0]) parity0=~parity0; | |
1052 | else parity1=~parity1; | |
1053 | printf("TEST corrupt_vlan_parity new0=%b new1=%b\n", parity0, parity1); | |
1054 | } | |
1055 | vlan_entry = {vpr3,rdctbl3,vpr2,rdctbl2,vpr1,rdctbl1,vpr0,rdctbl0}; | |
1056 | pktC.prog_vlan_entry(ii, vlan_entry, BACKDOOR); | |
1057 | //printf("rxTEST VLAN i=%0d vpr1=%d rdctbl1=%0d vpr0=%d rdctbl0=%0d 0x%h\n", ii, vpr1, rdctbl1, vpr0, rdctbl0, vlan_entry); | |
1058 | //printf("rxTEST VLAN i=%0d vpr3=%d rdctbl3=%0d vpr2=%d rdctbl2=%0d 0x%h\n", ii, vpr3, rdctbl3, vpr2, rdctbl2, vlan_entry); | |
1059 | } | |
1060 | ||
1061 | } | |
1062 | //////////////////////////////////////////////////////////// | |
1063 | function integer rx_rand_test::set_pkt_len(integer param, integer max, integer min, integer pkt_num) { | |
1064 | //printf("rxTEST set_pkt_len min=%0d max=%0d param=%0d\n", min, max, param); | |
1065 | case(param) { | |
1066 | 0: set_pkt_len = min + random()%(max-min); //random between min and max | |
1067 | 1: set_pkt_len = min + ((pkt_num*byte_sweep)%(max-min+1)); //byte sweep between min and max | |
1068 | 2: set_pkt_len = min; //constant size | |
1069 | } | |
1070 | printf("rxTEST set_pkt_len=%0d\n", set_pkt_len); | |
1071 | } | |
1072 | //////////////////////////////////////////////////////////// | |
1073 | task rx_rand_test::close() { | |
1074 | bit[39:0] base_addr; | |
1075 | bit[31:0] rd_data; | |
1076 | bit[63:0] rd_data64; | |
1077 | bit[15:0] ipp_step='h8000; | |
1078 | integer ii, mac_id; | |
1079 | ||
1080 | if(get_plus_arg(CHECK, "RX_LAST_PKT_LATENCY=")) | |
1081 | repeat(get_plus_arg(NUM, "RX_LAST_PKT_LATENCY=")) @(posedge CLOCK); | |
1082 | else repeat(5000) @(posedge CLOCK); | |
1083 | ||
1084 | if(send_runts==0) { | |
1085 | if(rtl_mac[0]) { | |
1086 | base_addr=XPCS0_BASE; | |
1087 | mac_id=0; | |
1088 | gen_pio_drv.pio_rd(FZC_IPP_BASE_ADDRESS+IPP_TCP_CHKSUM_ERR_COUNTER+(mac_id*ipp_step), rd_data64); | |
1089 | printf("rxTEST mac_id=%0d IPP_TCP_CHKSUM_ERR_COUNTER(%0h)=%0d\n", mac_id, FZC_IPP_BASE_ADDRESS+IPP_TCP_CHKSUM_ERR_COUNTER+(mac_id*ipp_step), rd_data64[13:0]); | |
1090 | ||
1091 | mac_pio_class.xmac_pio_rd(base_addr + XPCS_PACKET_COUNTER, rd_data, 1'b0); | |
1092 | printf("rxTEST mac_id=%0d XPCS_PACKET_COUNTER(%0h)=%0d\n", mac_id, base_addr + XPCS_PACKET_COUNTER, rd_data[15:0]); | |
1093 | if(rd_data[15:0] != num_pkts_port[mac_id]) | |
1094 | be_msg.print(e_mesg_error, "niu_rx_rand_template", "close", "mac=%0d XPCS_PACKET_COUNTER exp=%0d got=%0d\n", mac_id, num_pkts_port[mac_id], rd_data[15:0]); | |
1095 | } | |
1096 | if(rtl_mac[1]) { | |
1097 | base_addr=XPCS1_BASE; | |
1098 | mac_id=1; | |
1099 | gen_pio_drv.pio_rd(FZC_IPP_BASE_ADDRESS+IPP_TCP_CHKSUM_ERR_COUNTER+(mac_id*ipp_step), rd_data64); | |
1100 | printf("rxTEST mac_id=%0d IPP_TCP_CHKSUM_ERR_COUNTER(%0h)=%0d\n", mac_id, FZC_IPP_BASE_ADDRESS+IPP_TCP_CHKSUM_ERR_COUNTER+(mac_id*ipp_step), rd_data64[13:0]); | |
1101 | ||
1102 | mac_pio_class.xmac_pio_rd(base_addr + XPCS_PACKET_COUNTER, rd_data, 1'b0); | |
1103 | printf("rxTEST mac_id=%0d XPCS_PACKET_COUNTER(%0h)=%0d\n", mac_id, base_addr + XPCS_PACKET_COUNTER, rd_data[15:0]); | |
1104 | if(rd_data[15:0] != num_pkts_port[mac_id]) | |
1105 | be_msg.print(e_mesg_error, "niu_rx_rand_template", "close", "mac=%0d XPCS_PACKET_COUNTER exp=%0d got=%0d\n", mac_id, num_pkts_port[mac_id], rd_data[15:0]); | |
1106 | } | |
1107 | if(rtl_mac[2] || rtl_mac[3]) { | |
1108 | printf("rxTEST Bmacs(2,3) do not have packet counter\n"); | |
1109 | } | |
1110 | ||
1111 | mac_pio_class.xmac_pio_rd(base_addr+XPCS_STATUS1, rd_data, 1'b0); | |
1112 | printf("rxTEST XPCS_STATUS1 = 0x%h\n", rd_data); | |
1113 | if(rd_data[2] != 1) | |
1114 | be_msg.print(e_mesg_error, "niu_rx_rand_template", "close", "mac=%0d Link not up\n", mac_id); | |
1115 | } | |
1116 | ||
1117 | for(ii=0; ii<16; ii++) { //misc drop counters | |
1118 | rdmc.rx_dma[ii].pio_rd_RX_MISC_DROP(rd_data64); | |
1119 | printf("rxTEST read addr=0x%0h dma%0d_misc_drop data=%0d time=%0d\n", RX_MISC_START + RXDMA_STEP*ii, ii, rd_data64, get_time(LO)); | |
1120 | } | |
1121 | for(ii=0; ii<16; ii++) { | |
1122 | gen_pio_drv.pio_rd(RX_DMA_CTL_STAT_START + RXDMA_STEP*ii, rd_data64); | |
1123 | printf("rxTEST read addr=0x%0h dma%0d_stat data=0x%0h time=%0d\n", RX_DMA_CTL_STAT_START + RXDMA_STEP*ii, ii, rd_data64, get_time(LO)); | |
1124 | } | |
1125 | ||
1126 | ||
1127 | //MAC_CRC_ER_CNT | |
1128 | ||
1129 | if(do_wred) { | |
1130 | for(ii=0; ii<16; ii++) { //wred drop counters | |
1131 | rdmc.rx_dma[ii].pio_rd_RED_DISC(rd_data64); | |
1132 | printf("rxTEST read addr=0x%0h dma%0d_wred_drop data=%0d time=%0d\n", RED_DIS_CNT_START+RED_DIS_CNT_STEP*ii, ii, rd_data64, get_time(LO)); | |
1133 | } | |
1134 | } | |
1135 | } | |
1136 | ///////////////////////////////////////////////////////// | |
1137 | task rx_rand_test::rand_weights() { | |
1138 | integer mac_id; | |
1139 | bit[15:0] weight; | |
1140 | bit is_alive[4]=4'b0; | |
1141 | integer slop=0, base=base_weight01; | |
1142 | bit add_slop=1; | |
1143 | ||
1144 | for(mac_id=0; mac_id<4; mac_id++) is_alive[mac_id]=0; //initialize | |
1145 | if(rtl_mac[0]) is_alive[0]=1; | |
1146 | if(rtl_mac[1]) is_alive[1]=1; | |
1147 | if(rtl_mac[2]) is_alive[2]=1; | |
1148 | if(rtl_mac[3]) is_alive[3]=1; | |
1149 | while(sending_pkts) { // program weights for each port | |
1150 | mac_id=random()%4; | |
1151 | if(is_alive[mac_id]) { //only do for active port | |
1152 | if(!weights_50_1) { //10:10:1:1 | |
1153 | base=base_weight01; | |
1154 | if(mac_id==2 || mac_id==3) base=base_weight01/10; | |
1155 | } | |
1156 | else { //50:50:1:1 | |
1157 | base=base_weight01; | |
1158 | if(mac_id==2 || mac_id==3) base=base_weight01/50; | |
1159 | } | |
1160 | ||
1161 | slop=(base*weight_margin)/100; | |
1162 | add_slop=random(); | |
1163 | if(add_slop) weight=base+(random()%slop); | |
1164 | else weight=base-(random()%slop); | |
1165 | ||
1166 | printf("rxTEST mac_id=%0d base=0x%0h slop=0x%0d weight=0x%0h time=%0d\n", mac_id, base, slop, weight, get_time(LO)); | |
1167 | //printf("rxTEST mac_id=%0d weight=0x%0h time=%0d\n", mac_id, weight, get_time(LO)); | |
1168 | rdmc.RxDrrIntf.ProgramDRRWeight(mac_id, weight); | |
1169 | } | |
1170 | delay(random()%2000); | |
1171 | } | |
1172 | } | |
1173 | ///////////////////////////////////////////////////////// | |
1174 | task rx_rand_test::rand_flush() { | |
1175 | integer dma; | |
1176 | ||
1177 | while(sending_pkts) { | |
1178 | delay(do_flush); | |
1179 | dma=random()%16; | |
1180 | printf("rxTEST rand flush dma=%0d time=%0d\n", dma, get_time(LO)); | |
1181 | rdmc.rx_dma[dma].flush_rcr(1); | |
1182 | } | |
1183 | } | |
1184 | ///////////////////////////////////////////////////////// | |
1185 | task rx_rand_test::rand_dis_dma() { | |
1186 | integer dma; | |
1187 | bit[63:0] rd_data64; | |
1188 | #define EN 31 | |
1189 | #define QST 29 | |
1190 | ||
1191 | //while(sending_pkts) { | |
1192 | while(second_to_last_packet_sent!=={rtl_mac[3], rtl_mac[2], rtl_mac[1], rtl_mac[0]}) { | |
1193 | dma=random()%16; | |
1194 | delay(do_rand_dis_dma); | |
1195 | printf("rxTEST rand_disable dma=%0d disable time=%0d\n", dma, get_time(LO)); | |
1196 | rdmc.rx_dma[dma].pio_rd_RXDMA_CFIG1(rd_data64); | |
1197 | rd_data64[EN]=0; | |
1198 | rdmc.rx_dma[dma].pio_wr_RXDMA_CFIG1(rd_data64); | |
1199 | ||
1200 | delay(dma_off_time); | |
1201 | printf("rxTEST rand_disable dma=%0d enable time=%0d\n", dma, get_time(LO)); | |
1202 | rd_data64[EN]=1; | |
1203 | rdmc.rx_dma[dma].pio_wr_RXDMA_CFIG1(rd_data64); | |
1204 | } | |
1205 | } | |
1206 | ///////////////////////////////////////////////////////// | |
1207 | #define TCAM_READ 3'b001 | |
1208 | #define TCAM_WRITE 3'b000 | |
1209 | #define ASSO_READ 3'b101 | |
1210 | #define ASSO_WRITE 3'b100 | |
1211 | #define TCAM_COMP 3'b010 | |
1212 | #define STAT 17 | |
1213 | #define MATCH 16 | |
1214 | #define LOC 9:0 | |
1215 | ||
1216 | task rx_rand_test::tcam_compare() { | |
1217 | bit[63:0] data64; | |
1218 | bit[9:0] tcam_index; | |
1219 | bit[199:0] key, mask; | |
1220 | bit status=0; | |
1221 | integer ii; | |
1222 | ||
1223 | status=0; | |
1224 | while(status==0) { | |
1225 | gen_pio_drv.pio_rd(fullFFLP_CAM_CONTROL, data64); | |
1226 | status=data64[STAT]; | |
1227 | } | |
1228 | tcam_index=random()%(num_tcam_entries-1); | |
1229 | printf("rxTEST reg_access tcam_compare index=%0d\n", tcam_index); | |
1230 | key=pktC.get_tcam_shadow(tcam_index); | |
1231 | mask=pktC.get_tcam_mask(tcam_index); | |
1232 | ||
1233 | //search and compare for lowest entry - use mask&key | |
1234 | for(ii=0; ii<num_tcam_entries; ii++) { | |
1235 | //printf("rxTEST reg_access %0d skey=0x%0h smask=0x%0h\n",ii, pktC.get_tcam_shadow(ii), pktC.get_tcam_mask(ii)); | |
1236 | //printf("rxTEST reg_access %0d ikey=0x%0h imask=0x%0h\n",ii, key, mask); | |
1237 | if( pktC.get_tcam_shadow(ii)==key && pktC.get_tcam_mask(ii)==mask ) { | |
1238 | tcam_index=ii; | |
1239 | break; | |
1240 | } | |
1241 | } | |
1242 | printf("rxTEST reg_access tcam_compare index=%0d key=0x%h mask=0x%h\n", tcam_index, key, mask); | |
1243 | ||
1244 | gen_pio_drv.pio_wr(fullFFLP_CAM_KEY_REG0, key[199:192]); | |
1245 | gen_pio_drv.pio_wr(fullFFLP_CAM_KEY_REG1, key[191:128]); | |
1246 | gen_pio_drv.pio_wr(fullFFLP_CAM_KEY_REG2, key[127:64]); | |
1247 | gen_pio_drv.pio_wr(fullFFLP_CAM_KEY_REG3, key[63:0]); | |
1248 | gen_pio_drv.pio_wr(fullFFLP_CAM_MASK_REG0, mask[199:192]); | |
1249 | gen_pio_drv.pio_wr(fullFFLP_CAM_MASK_REG1, mask[191:128]); | |
1250 | gen_pio_drv.pio_wr(fullFFLP_CAM_MASK_REG2, mask[127:64]); | |
1251 | gen_pio_drv.pio_wr(fullFFLP_CAM_MASK_REG3, mask[63:0]); | |
1252 | ||
1253 | data64={43'h0, TCAM_COMP, 8'h0, tcam_index}; | |
1254 | gen_pio_drv.pio_wr(fullFFLP_CAM_CONTROL, data64); | |
1255 | status=0; | |
1256 | while(status==0) { | |
1257 | gen_pio_drv.pio_rd(fullFFLP_CAM_CONTROL, data64); | |
1258 | status=data64[STAT]; | |
1259 | } | |
1260 | if(data64[MATCH]!==1) printf("rxTEST reg_access tcam compare match=0 ERROR time=%0d\n", get_time(LO)); | |
1261 | if(data64[LOC]!==tcam_index) printf("rxTEST reg_access tcam compare loc=%0d exp=%0d ERROR time=%0d\n", data64[LOC], tcam_index, get_time(LO)); | |
1262 | } | |
1263 | //////////////////////////////////////// | |
1264 | task rx_rand_test::reg_access() { | |
1265 | bit[39:0] address; | |
1266 | bit[63:0] data64; | |
1267 | bit[9:0] tcam_index; | |
1268 | bit[199:0] key, mask; | |
1269 | integer misc_drop_index=0, wred_drop_index=0, cfig1_index=0, status_index=0; | |
1270 | #define EN 31 | |
1271 | ||
1272 | while(sending_pkts) { | |
1273 | ||
1274 | tcam_compare(); | |
1275 | ||
1276 | tcam_index=random()%num_tcam_entries; | |
1277 | key=fflp_util.pio_rd_tcam_key(tcam_index, mask); | |
1278 | printf("rxTEST reg_access tcam_read index=%0d key=0x%0h mask=0x%0h time=%0d\n", | |
1279 | tcam_index, key, mask, get_time(LO)); | |
1280 | ||
1281 | printf("rxTEST reg_access tcam_write index=%0d key=0x%0h mask=0x%0h time=%0d\n", | |
1282 | tcam_index, key, mask, get_time(LO)); | |
1283 | fflp_util.pio_wr_tcam_key(tcam_index, key, mask); | |
1284 | ||
1285 | ||
1286 | tcam_index=random()%num_tcam_entries; | |
1287 | data64=fflp_util.pio_rd_tcam_asdata(tcam_index); | |
1288 | printf("rxTEST reg_access tcam_read_asdata=0x%0h index=%0d time=%0d\n", data64, tcam_index, get_time(LO)); | |
1289 | ||
1290 | printf("rxTEST reg_access tcam_read_asdata=0x%0h index=%0d time=%0d\n", data64, tcam_index, get_time(LO)); | |
1291 | fflp_util.pio_wr_tcam_asdata(tcam_index, data64); | |
1292 | ||
1293 | //misc drop counters | |
1294 | rdmc.rx_dma[misc_drop_index].pio_rd_RX_MISC_DROP(data64); | |
1295 | printf("rxTEST reg_access read addr=0x%0h dma%0d_misc_drop data=%0d time=%0d\n", RX_MISC_START + RXDMA_STEP*misc_drop_index, misc_drop_index, data64, get_time(LO)); | |
1296 | if(data64!==0) | |
1297 | printf("rxTEST reg_access read WARNING dma%0d MISC DROP=%0d time=%0d\n", misc_drop_index, data64, get_time(LO)); | |
1298 | if(misc_drop_index==15) misc_drop_index=0; | |
1299 | else misc_drop_index++; | |
1300 | ||
1301 | ||
1302 | //wred drop counters | |
1303 | if(do_wred) { | |
1304 | rdmc.rx_dma[wred_drop_index].pio_rd_RED_DISC(data64); | |
1305 | printf("rxTEST read addr=0x%0h dma%0d_wred_drop data=%0d time=%0d\n", RED_DIS_CNT_START+RED_DIS_CNT_STEP*wred_drop_index, wred_drop_index, data64, get_time(LO)); | |
1306 | if(wred_drop_index==15) wred_drop_index=0; | |
1307 | else wred_drop_index++; | |
1308 | } | |
1309 | ||
1310 | ||
1311 | //check if dma gets disabled | |
1312 | rdmc.rx_dma[cfig1_index].pio_rd_RXDMA_CFIG1(data64); | |
1313 | printf("rxTEST reg_access read addr=0x%0h dma%0d_cfigA data=%0d time=%0d\n", RXDMA_CFIG1+RXDMA_STEP*cfig1_index, cfig1_index, data64, get_time(LO)); | |
1314 | if(data64[EN]==0 && do_rand_dis_dma==0) | |
1315 | printf("rxTEST reg_access read FATAL ERROR dma%0d disabled time=%0d\n", cfig1_index, get_time(LO)); | |
1316 | if(cfig1_index==15) cfig1_index=0; | |
1317 | else cfig1_index++; | |
1318 | ||
1319 | ||
1320 | //status regs | |
1321 | gen_pio_drv.pio_rd(RX_DMA_CTL_STAT_START + RXDMA_STEP*status_index, data64); | |
1322 | printf("rxTEST reg_access read addr=0x%0h dma%0d status data=0x%h_%h time=%0d\n", RX_MISC_START + RXDMA_STEP*status_index, status_index, data64[63:32], data64[31:0], get_time(LO)); | |
1323 | if(data64[32]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_CFIGLOGPAGE=1 time=%0d\n", status_index, get_time(LO)); | |
1324 | if(data64[33]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RBRLOGPAGE=1 time=%0d\n", status_index, get_time(LO)); | |
1325 | if(data64[34]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RBRFULL=1 time=%0d\n", status_index, get_time(LO)); | |
1326 | //if(data64[35]==1) printf("rxTEST reg_access ERROR dma%0d STATUS_RBR_EMPTY=1 time=%0d\n", status_index, get_time(LO)); | |
1327 | if(data64[36]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RCRFULL=1 time=%0d\n", status_index, get_time(LO)); | |
1328 | if(data64[37]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RCRINCON=1 time=%0d\n", status_index, get_time(LO)); | |
1329 | if(data64[38]==1) printf("rxTEST reg_access ERROR dma%0d STATUS_CONFIG_ERR=1 time=%0d\n", status_index, get_time(LO)); | |
1330 | if(data64[39]==1) printf("rxTEST reg_access WARN dma%0d STATUS_RCR_SHADOW_FULL=1 time=%0d\n", status_index, get_time(LO)); | |
1331 | if(data64[40]==1) printf("rxTEST reg_access WARNING dma%0d STATUS_RBR_PRE_EMTY=1 time=%0d\n", status_index, get_time(LO)); | |
1332 | if(data64[43]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RBR_PRE_PAR=1 time=%0d\n", status_index, get_time(LO)); | |
1333 | if(data64[44]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_CR_SHA_PAR=1 time=%0d\n", status_index, get_time(LO)); | |
1334 | if(data64[49]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RCR_ACK_ERR=1 time=%0d\n", status_index, get_time(LO)); | |
1335 | if(data64[50]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RSP_DAT_ERR=1 time=%0d\n", status_index, get_time(LO)); | |
1336 | if(data64[51]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_BYTE_EN_BUS=1 time=%0d\n", status_index, get_time(LO)); | |
1337 | if(data64[52]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RSP_CNT_ERR=1 time=%0d\n", status_index, get_time(LO)); | |
1338 | if(data64[53]==1) printf("rxTEST reg_access FATAL ERROR dma%0d STATUS_RBR_TMOUT=1 time=%0d\n", status_index, get_time(LO)); | |
1339 | if(status_index==15) status_index=0; | |
1340 | else status_index++; | |
1341 | ||
1342 | ||
1343 | gen_pio_drv.pio_rd(fullFFLP_TCAM_ERR, data64); | |
1344 | printf("rxTEST read addr=0x%0h FFLP_TCAM_ERR data=0x%h time=%0d\n", FFLP_TCAM_ERR, data64, get_time(LO)); | |
1345 | if(data64[31]==1) printf("rxTEST reg_access FFLP_TCAM ERR time=%0d\n", get_time(LO)); | |
1346 | if(data64[30]==1) printf("rxTEST reg_access FFLP_TCAM P_ECC time=%0d\n", get_time(LO)); | |
1347 | if(data64[29]==1) printf("rxTEST reg_access FFLP_TCAM MULT time=%0d\n", get_time(LO)); | |
1348 | } | |
1349 | } | |
1350 | //////////////////////////////////////// | |
1351 | task rx_rand_test::rx_dma_config(integer dma_ch) { | |
1352 | bit[63:0] rbr_config_B_data=0, rd_data64; | |
1353 | integer blk_size, buf_siz0, buf_siz1, buf_siz2, vld0=1, vld1=1, vld2=1; | |
1354 | bit tr_addr; | |
1355 | bit[5:0] tmp; | |
1356 | bit[15:0] rcr_len; | |
1357 | ||
1358 | void=rand_dma_parameters.randomize(); | |
1359 | ||
1360 | if(do_rand_vld) { | |
1361 | tmp=random(); | |
1362 | vld0=tmp[0]||tmp[3]; vld1=tmp[1]||tmp[4]; vld2=tmp[2]||tmp[5]; | |
1363 | if({vld0,vld1,vld2}==3'b000) vld2=1; //not all zero | |
1364 | } | |
1365 | ||
1366 | printf("rxTEST initalizing dma channel=%0d =====================\n", dma_ch); | |
1367 | buf_siz0 = rand_dma_parameters.buf_siz0; | |
1368 | buf_siz1 = rand_dma_parameters.buf_siz1; | |
1369 | buf_siz2 = rand_dma_parameters.buf_siz2; | |
1370 | blk_size = rand_dma_parameters.blk_size; | |
1371 | ||
1372 | case(blk_size) { | |
1373 | 4: rbr_config_B_data[25:24] = 2'b00; | |
1374 | 8: rbr_config_B_data[25:24] = 2'b01; | |
1375 | 16: rbr_config_B_data[25:24] = 2'b10; | |
1376 | 32: rbr_config_B_data[25:24] = 2'b11; | |
1377 | } | |
1378 | rbr_config_B_data[23] = vld2; | |
1379 | rbr_config_B_data[17:16] = 2'b00; | |
1380 | case(buf_siz2) { | |
1381 | 2048: rbr_config_B_data[17:16] = 2'b00; | |
1382 | 4096: rbr_config_B_data[17:16] = 2'b01; | |
1383 | 8192: rbr_config_B_data[17:16] = 2'b10; | |
1384 | 16384: rbr_config_B_data[17:16] = 2'b11; | |
1385 | } | |
1386 | rbr_config_B_data[15] = vld1; | |
1387 | rbr_config_B_data[9:8] = 2'b00; | |
1388 | case(buf_siz1) { | |
1389 | 1024: rbr_config_B_data[9:8] = 2'b00; | |
1390 | 2048: rbr_config_B_data[9:8] = 2'b01; | |
1391 | 4096: rbr_config_B_data[9:8] = 2'b10; | |
1392 | 8192: rbr_config_B_data[9:8] = 2'b11; | |
1393 | } | |
1394 | rbr_config_B_data[7]= vld0; | |
1395 | case(buf_siz0) { | |
1396 | 256: rbr_config_B_data[1:0] = 2'b00; | |
1397 | 512: rbr_config_B_data[1:0] = 2'b01; | |
1398 | 1024: rbr_config_B_data[1:0] = 2'b10; | |
1399 | 2048: rbr_config_B_data[1:0] = 2'b11; | |
1400 | } | |
1401 | printf("rxTEST dma=%0d Rx Block size=%0d\n", dma_ch, blk_size); | |
1402 | printf("rxTEST dma=%0d Rx Buf Siz0=%0d Siz1=%0d Siz2=%0d\n", dma_ch, buf_siz0, buf_siz1, buf_siz2); | |
1403 | printf("rxTEST dma=%0d Rx Buf vld0=%0d vld1=%0d vld2=%0d\n", dma_ch, vld0, vld1, vld2); | |
1404 | ||
1405 | dring_len[dma_ch]=rand_dma_parameters.desc_ring_length; | |
1406 | if(kick_mul16) initial_kick[dma_ch] = (rand_dma_parameters.initial_kick/16)*16; | |
1407 | else initial_kick[dma_ch] = rand_dma_parameters.initial_kick; | |
1408 | printf("rxTEST dma=%0d dring_length=0x%0h initial_kick=0x%0h\n", dma_ch, dring_len[dma_ch], initial_kick[dma_ch]); | |
1409 | ||
1410 | cring_len[dma_ch] = rand_dma_parameters.comp_ring_length; | |
1411 | printf("rxTEST dma=%0d cring_len=0x%0h\n", dma_ch, cring_len[dma_ch]); | |
1412 | //tail_ptr[dma_ch] = initial_kick[dma_ch]; | |
1413 | ||
1414 | tr_addr=1; | |
1415 | rdmc.rx_dma[dma_ch].random_page_alloc=1; | |
1416 | ||
1417 | if(get_plus_arg(CHECK, "ALL_DESCRIPTORS_IN_ONE_PAGE")) | |
1418 | rdmc.rx_dma[dma_ch].pkts_in_alternate_pages=0; | |
1419 | else | |
1420 | rdmc.rx_dma[dma_ch].pkts_in_alternate_pages=1; | |
1421 | ||
1422 | if(hdr_18B_en) { | |
1423 | tmp=random(); | |
1424 | if(tmp[0]) { rdmc.rx_dma[dma_ch].ctrl_hdr_len = 18; | |
1425 | printf("rxTEST dma=%0d using 18B hdr\n", dma_ch); | |
1426 | } | |
1427 | } | |
1428 | ||
1429 | //rdmc.InitRXDMA(dma_ch, dring_len[dma_ch], cring_len[dma_ch], rbr_config_B_data, initial_kick[dma_ch], tr_addr, 0); //0=no holes, 200=random holes | |
1430 | ||
1431 | rdmc.InitRXDMA(dma_ch, dring_len[dma_ch], cring_len[dma_ch], rbr_config_B_data, initial_kick[dma_ch], tr_addr); | |
1432 | ||
1433 | if(get_plus_arg(CHECK, "DONT_WAIT_FOR_DESCR_LOAD")) {} | |
1434 | else if(initial_kick[dma_ch]!==0) { | |
1435 | //RBR_STAT reg is first loaded with initial_kick value, as descriptors are read, it decrements | |
1436 | rbr_config_B_data=(initial_kick[dma_ch]); //use rbr_config_B_data as dummy 64 bit reg | |
1437 | //printf("rxTEST read rbr_kick until initial kick loaded kick=%0h reg=%0h\n", initial_kick[dma_ch], rbr_config_B_data[15:0]); | |
1438 | while( !(rbr_config_B_data[15:0]<initial_kick[dma_ch]) ) { | |
1439 | gen_pio_drv.pio_rd(RBR_STAT + dma_ch*RXDMA_STEP, rbr_config_B_data); | |
1440 | //printf("rxTEST read rbr_kick until initial kick loaded kick=%0h reg=%0h\n", initial_kick[dma_ch], rbr_config_B_data[15:0]); | |
1441 | repeat(20) {@(CLOCK);} | |
1442 | } | |
1443 | } | |
1444 | ||
1445 | #define RCR_LEN 63:48 | |
1446 | #define THRE_SYN 31:20 | |
1447 | #define WIN_SYN 19:16 | |
1448 | #define THRE 15:4 | |
1449 | #define WIN 3:0 | |
1450 | if(do_wred) { | |
1451 | gen_pio_drv.pio_rd(RCR_CFIG_A + dma_ch*RXDMA_STEP, rbr_config_B_data); | |
1452 | rcr_len=rbr_config_B_data[RCR_LEN]; | |
1453 | rbr_config_B_data=0; | |
1454 | if(wred_thre>0) { | |
1455 | rbr_config_B_data[THRE_SYN]=wred_thre; | |
1456 | rbr_config_B_data[THRE]=wred_thre; | |
1457 | } | |
1458 | else { | |
1459 | rbr_config_B_data[THRE_SYN]=rcr_len-33; | |
1460 | rbr_config_B_data[THRE]=rcr_len-33; | |
1461 | } | |
1462 | rbr_config_B_data[WIN_SYN]=0; | |
1463 | rbr_config_B_data[WIN]=0; | |
1464 | printf("rxTEST dma=%0d setup wred thr=0x%0h win=0 (rcr_len=0x%h) time=%0d\n", dma_ch, rbr_config_B_data[THRE], rcr_len, get_time(LO)); | |
1465 | gen_pio_drv.pio_wr(RDC_RED_PARA_START + dma_ch*RDC_RED_PARA_STEP, rbr_config_B_data); | |
1466 | } | |
1467 | ||
1468 | #define PTHRES 31:16 | |
1469 | #define ENTOUT 15 | |
1470 | #define TIMEOUT 5:0 | |
1471 | #define CK_DIV 15:0 | |
1472 | if(thr_timer_int_en[dma_ch]) { | |
1473 | rd_data64 = 21'h1fffff; | |
1474 | rd_data64[RX_DMA_ENT_MSK_RCRTHRES] = 0; | |
1475 | rd_data64[RX_DMA_ENT_MSK_RCRTO] = 0; | |
1476 | printf("rxTEST dma=%0d programming int mask=0x%0h time=%0d\n", dma_ch, rd_data64, get_time(LO)); | |
1477 | rdmc.rx_dma[dma_ch].pio_wr_RX_DMA_ENT_MSK_START(rd_data64); | |
1478 | ||
1479 | rdmc.rx_dma[dma_ch].pio_rd_RCR_CFIG_B_START(rd_data64); | |
1480 | rd_data64[PTHRES] = rcr_pkt_threshold; | |
1481 | rd_data64[TIMEOUT] = rcr_timer_value%64; | |
1482 | rd_data64[ENTOUT]=1; | |
1483 | printf("rxTEST dma=%0d write pkt_threshold=0x%h timer=0x%h 0x%h\n", dma_ch, rd_data64[PTHRES], rd_data64[TIMEOUT], rd_data64); | |
1484 | rdmc.rx_dma[dma_ch].pio_wr_RCR_CFIG_B_START(rd_data64); | |
1485 | ||
1486 | // program the CLK DIV register also | |
1487 | rd_data64 = 0; | |
1488 | rd_data64[CK_DIV] = rcr_timer_value/ 64; | |
1489 | if (rd_data64[CK_DIV] > 0) | |
1490 | gen_pio_drv.pio_wr(rdmc.rx_dma[dma_ch].getPIOAddress(RX_DMA_CK_DIV, rdmc.rx_dma[dma_ch].dis_pio_virt), rd_data64); | |
1491 | printf("rxTEST CLK_DIV = 0x%h\n ", rd_data64[CK_DIV]); | |
1492 | ||
1493 | printf("rxTEST dma=%0d programming mex bit time=%0d\n", dma_ch, get_time(LO)); | |
1494 | rdmc.rx_dma[dma_ch].pio_rd_RX_DMA_CTL_STAT_START(rd_data64); | |
1495 | rd_data64[47]=1; | |
1496 | rdmc.rx_dma[dma_ch].pio_wr_RX_DMA_CTL_STAT_START(rd_data64); | |
1497 | ||
1498 | // determine where the current RCR pointer is | |
1499 | rdmc.rx_dma[dma_ch].SetCurrentPtrs(); | |
1500 | ||
1501 | printf("rxTEST dma=%0d Done interrupt setup time=%0d\n", dma_ch, get_time(LO)); | |
1502 | } | |
1503 | else { | |
1504 | fork | |
1505 | rdmc.rx_dma[dma_ch].pollCRPtr(poll_interval); //if not doing interrupts | |
1506 | join none | |
1507 | } | |
1508 | fork | |
1509 | rdmc.rx_dma[dma_ch].UpdateRCRStat(); //always do | |
1510 | join none | |
1511 | } | |
1512 | ////////////////////////////////////////////// | |
1513 | //basic test setup parameters | |
1514 | task rx_rand_test::rx_control() { | |
1515 | ||
1516 | if(rtl_mac[0]) { | |
1517 | if(get_plus_arg(CHECK, "RATE_P0")) port_rate[0]=get_plus_arg (NUM, "RATE_P0"); | |
1518 | else port_rate[0]=10; | |
1519 | if(get_plus_arg (CHECK, "RX_PKTCNT_P0")) num_pkts_port[0] = (get_plus_arg (NUM, "RX_PKTCNT_P0")); | |
1520 | else num_pkts_port[0]=20; | |
1521 | printf("rxTEST port0 num_pkts=%0d rate=%0d\n", num_pkts_port[0], port_rate[0]); | |
1522 | ||
1523 | if(get_plus_arg(CHECK, "PKT_LEN_PARAM_P0")) pkt_len_param[0]=get_plus_arg (NUM, "PKT_LEN_PARAM_P0"); | |
1524 | else pkt_len_param[0]=0; | |
1525 | printf("rxTEST port0 pkt_len_param=%0d (%s)\n", pkt_len_param[0], (pkt_len_param[0]==0)?"random":(pkt_len_param[0]==1)?"byte sweep":"constant=min"); | |
1526 | ||
1527 | if(get_plus_arg(CHECK, "PKT_MAX_LEN_P0")) pkt_max_len[0]=get_plus_arg (NUM, "PKT_MAX_LEN_P0"); | |
1528 | else pkt_max_len[0]=1518; | |
1529 | if(get_plus_arg(CHECK, "PKT_MIN_LEN_P0")) pkt_min_len[0]=get_plus_arg (NUM, "PKT_MIN_LEN_P0"); | |
1530 | else pkt_min_len[0]=64; | |
1531 | printf("rxTEST port0 pkt_min_len=%0d pkt_max_len=%0d\n", pkt_min_len[0], pkt_max_len[0]); | |
1532 | ||
1533 | if(get_plus_arg(CHECK, "CS_CRC_ERR_P0")) cs_crc_err[0]=get_plus_arg (NUM, "CS_CRC_ERR_P0"); | |
1534 | else cs_crc_err[0]=0; | |
1535 | printf("rxTEST port0 cs_crc_err=%0d (percent)\n", cs_crc_err[0]); | |
1536 | } | |
1537 | if(rtl_mac[1]) { | |
1538 | if(get_plus_arg(CHECK, "RATE_P1")) port_rate[1]=get_plus_arg (NUM, "RATE_P1"); | |
1539 | else port_rate[1]=10; | |
1540 | if(get_plus_arg(CHECK, "RX_PKTCNT_P1")) num_pkts_port[1] = (get_plus_arg (NUM, "RX_PKTCNT_P1")); | |
1541 | else num_pkts_port[1]=20; | |
1542 | printf("rxTEST port1 num_pkts=%0d rate=%0d\n", num_pkts_port[1], port_rate[1]); | |
1543 | ||
1544 | if(get_plus_arg(CHECK, "PKT_LEN_PARAM_P1")) pkt_len_param[1]=get_plus_arg (NUM, "PKT_LEN_PARAM_P1"); | |
1545 | else pkt_len_param[1]=0; | |
1546 | printf("rxTEST port1 pkt_len_param=%0d (%s)\n", pkt_len_param[1], (pkt_len_param[1]==0)?"random":(pkt_len_param[1]==1)?"byte sweep":"constant=min"); | |
1547 | ||
1548 | if(get_plus_arg(CHECK, "PKT_MAX_LEN_P1")) pkt_max_len[1]=get_plus_arg (NUM, "PKT_MAX_LEN_P1"); | |
1549 | else pkt_max_len[1]=1518; | |
1550 | if(get_plus_arg(CHECK, "PKT_MIN_LEN_P1")) pkt_min_len[1]=get_plus_arg (NUM, "PKT_MIN_LEN_P1"); | |
1551 | else pkt_min_len[1]=64; | |
1552 | printf("rxTEST port1 pkt_min_len=%0d pkt_max_len=%0d\n", pkt_min_len[1], pkt_max_len[1]); | |
1553 | ||
1554 | if(get_plus_arg(CHECK, "CS_CRC_ERR_P1")) cs_crc_err[1]=get_plus_arg (NUM, "CS_CRC_ERR_P1"); | |
1555 | else cs_crc_err[1]=0; | |
1556 | printf("rxTEST port1 cs_crc_err=%0d (percent)\n", cs_crc_err[1]); | |
1557 | } | |
1558 | if(rtl_mac[2]) { | |
1559 | if(get_plus_arg(CHECK, "RATE_P2")) port_rate[2]=get_plus_arg (NUM, "RATE_P2"); | |
1560 | else port_rate[2]=1; | |
1561 | if(get_plus_arg(CHECK, "RX_PKTCNT_P2")) num_pkts_port[2] = (get_plus_arg (NUM, "RX_PKTCNT_P2")); | |
1562 | else num_pkts_port[2]=2; | |
1563 | printf("rxTEST port2 num_pkts=%0d rate=%0d\n", num_pkts_port[2], port_rate[2]); | |
1564 | ||
1565 | if(get_plus_arg(CHECK, "PKT_LEN_PARAM_P2")) pkt_len_param[2]=get_plus_arg (NUM, "PKT_LEN_PARAM_P2"); | |
1566 | else pkt_len_param[2]=0; | |
1567 | printf("rxTEST port2 pkt_len_param=%0d (%s)\n", pkt_len_param[2], (pkt_len_param[2]==0)?"random":(pkt_len_param[2]==1)?"byte sweep":"constant=min"); | |
1568 | ||
1569 | if(get_plus_arg(CHECK, "PKT_MAX_LEN_P2")) pkt_max_len[2]=get_plus_arg (NUM, "PKT_MAX_LEN_P2"); | |
1570 | else pkt_max_len[2]=1518; | |
1571 | if(get_plus_arg(CHECK, "PKT_MIN_LEN_P2")) pkt_min_len[2]=get_plus_arg (NUM, "PKT_MIN_LEN_P2"); | |
1572 | else pkt_min_len[2]=64; | |
1573 | printf("rxTEST port2 pkt_min_len=%0d pkt_max_len=%0d\n", pkt_min_len[2], pkt_max_len[2]); | |
1574 | ||
1575 | if(get_plus_arg(CHECK, "CS_CRC_ERR_P2")) cs_crc_err[2]=get_plus_arg (NUM, "CS_CRC_ERR_P2"); | |
1576 | else cs_crc_err[2]=0; | |
1577 | printf("rxTEST port2 cs_crc_err=%0d (percent)\n", cs_crc_err[2]); | |
1578 | } | |
1579 | if(rtl_mac[3]) { | |
1580 | if(get_plus_arg(CHECK, "RATE_P3")) port_rate[3]=get_plus_arg (NUM, "RATE_P3"); | |
1581 | else port_rate[3]=1; | |
1582 | if(get_plus_arg(CHECK, "RX_PKTCNT_P3")) num_pkts_port[3] = (get_plus_arg (NUM, "RX_PKTCNT_P3")); | |
1583 | else num_pkts_port[3]=2; | |
1584 | printf("rxTEST port3 num_pkts=%0d rate=%0d\n", num_pkts_port[3], port_rate[3]); | |
1585 | ||
1586 | if(get_plus_arg(CHECK, "PKT_LEN_PARAM_P3")) pkt_len_param[3]=get_plus_arg (NUM, "PKT_LEN_PARAM_P3"); | |
1587 | else pkt_len_param[3]=0; | |
1588 | printf("rxTEST port3 pkt_len_param=%0d (%s)\n", pkt_len_param[3], (pkt_len_param[3]==0)?"random":(pkt_len_param[3]==1)?"byte sweep":"constant=min"); | |
1589 | ||
1590 | if(get_plus_arg(CHECK, "PKT_MAX_LEN_P3")) pkt_max_len[3]=get_plus_arg (NUM, "PKT_MAX_LEN_P3"); | |
1591 | else pkt_max_len[3]=1518; | |
1592 | if(get_plus_arg(CHECK, "PKT_MIN_LEN_P3")) pkt_min_len[3]=get_plus_arg (NUM, "PKT_MIN_LEN_P3"); | |
1593 | else pkt_min_len[3]=64; | |
1594 | printf("rxTEST port3 pkt_min_len=%0d pkt_max_len=%0d\n", pkt_min_len[3], pkt_max_len[3]); | |
1595 | ||
1596 | if(get_plus_arg(CHECK, "CS_CRC_ERR_P3")) cs_crc_err[3]=get_plus_arg (NUM, "CS_CRC_ERR_P3"); | |
1597 | else cs_crc_err[3]=0; | |
1598 | printf("rxTEST port3 cs_crc_err=%0d (percent)\n", cs_crc_err[3]); | |
1599 | } | |
1600 | ||
1601 | if(DO_INTERNAL_RAND_KICKS) { | |
1602 | if(get_plus_arg(CHECK, "KICK_MORE_MAX")) kick_more_max=get_plus_arg (NUM, "KICK_MORE_MAX"); | |
1603 | else kick_more_max=256; | |
1604 | if(get_plus_arg(CHECK, "KICK_MORE_MIN")) kick_more_min=get_plus_arg (NUM, "KICK_MORE_MIN"); | |
1605 | else kick_more_min=128; | |
1606 | printf("rxTEST kick_more_min=%0d kick_more_max=%0d\n", kick_more_min, kick_more_max); | |
1607 | } | |
1608 | else { | |
1609 | if(!get_plus_arg(CHECK, "RX_PERIODIC_KICK_AUTO")) { | |
1610 | printf("rxTEST ERROR must add +RX_PERIODIC_KICK_AUTO=x\n"); | |
1611 | exit(1); | |
1612 | } | |
1613 | else printf("rxTEST RX_PERIODIC_KICK_AUTO=%0d\n", get_plus_arg(NUM,"RX_PERIODIC_KICK_AUTO")); | |
1614 | if(get_plus_arg(CHECK, "RX_PERIODIC_KICK_NUM_DESC")) | |
1615 | printf("rxTEST RX_PERIODIC_KICK_NUM_DESC=%0d\n", get_plus_arg(NUM,"RX_PERIODIC_KICK_NUM_DESCR")); | |
1616 | if(get_plus_arg(CHECK, "RX_PERIODIC_KICK_THRESHOLD")) | |
1617 | printf("rxTEST RX_PERIODIC_KICK_THRESHOLD=%0d\n", get_plus_arg(NUM,"RX_PERIODIC_KICK_THRESHOLD")); | |
1618 | if(get_plus_arg(CHECK, "RX_PERIODIC_KICK_INTERVAL")) | |
1619 | printf("rxTEST RX_PERIODIC_KICK_INTERVAL=%0d\n", get_plus_arg(NUM,"RX_PERIODIC_KICK_INTERVAL")); | |
1620 | } | |
1621 | ||
1622 | if(get_plus_arg(CHECK, "DRING_MARGIN")) DringMargin=get_plus_arg (NUM, "DRING_MARGIN"); | |
1623 | else DringMargin=128; | |
1624 | printf("rxTEST DringMargin=%0d\n", DringMargin); | |
1625 | ||
1626 | if(get_plus_arg(CHECK, "NUM_TCAM_ENTRIES")) num_tcam_entries=get_plus_arg (NUM, "NUM_TCAM_ENTRIES"); | |
1627 | else num_tcam_entries=128; | |
1628 | printf("rxTEST num_tcam_entries=%0d\n", num_tcam_entries); | |
1629 | frag_id=num_tcam_entries-1; //last one | |
1630 | frag_id_tcp=num_tcam_entries-2; //second to last one | |
1631 | ||
1632 | if(get_plus_arg(CHECK, "NUM_TCAM_REPEATS")) num_tcam_repeats=get_plus_arg (NUM, "NUM_TCAM_REPEATS"); | |
1633 | else num_tcam_repeats=0; | |
1634 | printf("rxTEST num_tcam_repeats=%0d\n", num_tcam_repeats); | |
1635 | ||
1636 | if(get_plus_arg(CHECK, "HDR_18B_EN")) hdr_18B_en=1; | |
1637 | else hdr_18B_en=0; | |
1638 | printf("rxTEST hdr_18B_en=%0d\n", hdr_18B_en); | |
1639 | ||
1640 | if(get_plus_arg(CHECK, "NOT_KICK_MUL16")) kick_mul16=0; | |
1641 | else kick_mul16=1; | |
1642 | printf("rxTEST kick_mul16=%0d\n", kick_mul16); | |
1643 | ||
1644 | if(pkt_len_param[0]==1 | pkt_len_param[1]==1 | pkt_len_param[2]==1 | pkt_len_param[3]==1) { | |
1645 | if(get_plus_arg(CHECK, "BYTE_SWEEP")) byte_sweep=get_plus_arg (NUM, "BYTE_SWEEP"); | |
1646 | else byte_sweep=1; | |
1647 | printf("rxTEST byte_sweep=%0d\n", byte_sweep); | |
1648 | } | |
1649 | ||
1650 | if(get_plus_arg(CHECK, "DO_FRAG")) do_frag=1; | |
1651 | else do_frag=0; | |
1652 | printf("rxTEST do_frag=%0d\n", do_frag); | |
1653 | ||
1654 | if(get_plus_arg(CHECK, "DO_FLUSH")) do_flush=get_plus_arg (NUM, "DO_FLUSH"); | |
1655 | else do_flush=0; | |
1656 | printf("rxTEST do_flush=%0d\n", do_flush); | |
1657 | ||
1658 | if(get_plus_arg(CHECK, "DO_RAND_DEF_DMA")) do_rand_def_dma=1; | |
1659 | else do_rand_def_dma=0; | |
1660 | printf("rxTEST do_rand_def_dma=%0d\n", do_rand_def_dma); | |
1661 | ||
1662 | if(get_plus_arg(CHECK, "DO_RAND_VLD")) do_rand_vld=1; | |
1663 | else do_rand_vld=0; | |
1664 | printf("rxTEST do_rand_vld=%0d\n", do_rand_vld); | |
1665 | ||
1666 | if(get_plus_arg(CHECK, "DO_RAND_DIS_DMA")) do_rand_dis_dma=get_plus_arg (NUM, "DO_RAND_DIS_DMA"); | |
1667 | else do_rand_dis_dma=0; | |
1668 | printf("rxTEST do_rand_dis_dma=%0d\n", do_rand_dis_dma); | |
1669 | ||
1670 | if(do_rand_dis_dma>0) { | |
1671 | if(get_plus_arg(CHECK, "DMA_OFF_TIME")) dma_off_time=get_plus_arg (NUM, "DMA_OFF_TIME"); | |
1672 | else dma_off_time=200; | |
1673 | printf("rxTEST dma_off_time=%0d\n", dma_off_time); | |
1674 | } | |
1675 | ||
1676 | if(get_plus_arg(CHECK, "DO_WRED")) do_wred=1; | |
1677 | else do_wred=0; | |
1678 | printf("rxTEST do_wred=%0d\n", do_wred); | |
1679 | ||
1680 | if(do_wred) { | |
1681 | if(get_plus_arg(CHECK, "WRED_THRE")) { | |
1682 | wred_thre=get_plus_arg (NUM, "WRED_THRE"); | |
1683 | printf("rxTEST wred_thre=%0d Caution should be less than rcr_length\n", wred_thre); | |
1684 | } | |
1685 | else { | |
1686 | wred_thre=0; | |
1687 | printf("rxTEST wred_thre=rce_len-32\n"); | |
1688 | } | |
1689 | } | |
1690 | ||
1691 | if(get_plus_arg(CHECK, "POLL_INTERVAL")) poll_interval=get_plus_arg (NUM, "POLL_INTERVAL"); | |
1692 | else poll_interval=1000; | |
1693 | printf("rxTEST poll_interval=%0d\n", poll_interval); | |
1694 | ||
1695 | if(get_plus_arg(CHECK, "TCAM_FRONTDOOR")) do_rand_mask=1; | |
1696 | else do_rand_mask=0; | |
1697 | printf("rxTEST do_rand_mask=%0d (tcam_frontdoor)\n", do_rand_mask); | |
1698 | ||
1699 | if(get_plus_arg (CHECK,"RX_THR_TIMER_INT_HEX=")) | |
1700 | thr_timer_int_en = get_plus_arg(HNUM,"RX_THR_TIMER_INT_HEX="); | |
1701 | else thr_timer_int_en = 16'h0000; | |
1702 | printf("rxTEST thr_timer_int_en=0x%h\n", thr_timer_int_en); | |
1703 | ||
1704 | if(thr_timer_int_en!==0) { | |
1705 | if(get_plus_arg(CHECK, "RCR_PKT_THRESHOLD")) | |
1706 | rcr_pkt_threshold = get_plus_arg(NUM, "RCR_PKT_THRESHOLD"); | |
1707 | else rcr_pkt_threshold = 1; | |
1708 | printf("rxTEST rcr_pkt_threshold=0x%h\n", rcr_pkt_threshold); | |
1709 | ||
1710 | if(get_plus_arg(CHECK, "RCR_TIMER_VALUE")) | |
1711 | rcr_timer_value = get_plus_arg(NUM, "RCR_TIMER_VALUE"); | |
1712 | else rcr_timer_value = 63; | |
1713 | printf("rxTEST rcr_timer_value=0x%h\n", rcr_timer_value); | |
1714 | } | |
1715 | ||
1716 | if(get_plus_arg(CHECK, "DO_RAND_KEY_DISC")) do_rand_key_disc=1; | |
1717 | else do_rand_key_disc=0; | |
1718 | printf("rxTEST do_rand_key_disc=%0d\n", do_rand_key_disc); | |
1719 | ||
1720 | if(get_plus_arg(CHECK, "DO_RAND_AD_DISC")) do_rand_ad_disc=1; | |
1721 | else do_rand_ad_disc=0; | |
1722 | printf("rxTEST do_rand_ad_disc=%0d\n", do_rand_ad_disc); | |
1723 | ||
1724 | if(get_plus_arg(CHECK, "DO_RAND_HASH_MASK")) do_rand_hash_mask=1; | |
1725 | else do_rand_hash_mask=0; | |
1726 | printf("rxTEST do_rand_hash_mask=%0d\n", do_rand_hash_mask); | |
1727 | ||
1728 | if(get_plus_arg(CHECK, "SEND_RUNTS")) send_runts=get_plus_arg(NUM, "SEND_RUNTS"); | |
1729 | else send_runts=0; | |
1730 | printf("rxTEST send_runts=%0d (percent)\n", send_runts); | |
1731 | ||
1732 | if(get_plus_arg(CHECK, "BASE_WEIGHT01_HEX")) base_weight01=get_plus_arg(HNUM, "BASE_WEIGHT01_HEX"); | |
1733 | else base_weight01='h400; | |
1734 | printf("rxTEST base_weight01=0x%0h\n", base_weight01 ); | |
1735 | ||
1736 | if(get_plus_arg(CHECK, "WEIGHT_MARGIN")) weight_margin=get_plus_arg(NUM, "WEIGHT_MARGIN"); | |
1737 | else weight_margin=5; | |
1738 | printf("rxTEST weight_margin=%0d (percent)\n", weight_margin ); | |
1739 | ||
1740 | if(get_plus_arg(CHECK, "SET_ERRCHKDISABLE")) set_errchkdisable=1; | |
1741 | else set_errchkdisable=0; | |
1742 | if(send_runts>0) set_errchkdisable=0; | |
1743 | printf("rxTEST set_errchkdisable=%0d (not set if sending runts)\n", set_errchkdisable); | |
1744 | ||
1745 | if(get_plus_arg(CHECK, "CORRUPT_VLAN_PARITY")) corrupt_vlan_parity=1; | |
1746 | else corrupt_vlan_parity=0; | |
1747 | printf("rxTEST corrupt_vlan_parity=%0d\n", corrupt_vlan_parity); | |
1748 | ||
1749 | if(get_plus_arg(CHECK, "PROMIS")) promis=1; | |
1750 | else promis=0; | |
1751 | printf("rxTEST promis=%0d\n", promis); | |
1752 | ||
1753 | if(get_plus_arg(CHECK, "DA_MISMATCH")) da_mismatch=1; | |
1754 | else da_mismatch=0; | |
1755 | printf("rxTEST da_mismatch=%0d\n", da_mismatch); | |
1756 | ||
1757 | if(get_plus_arg(CHECK, "NO_PAD")) no_pad=1; | |
1758 | else no_pad=0; | |
1759 | printf("rxTEST no_pad=%0d\n", no_pad); | |
1760 | ||
1761 | if(get_plus_arg(CHECK, "L4_PROTO_ERR")) l4_proto_err=get_plus_arg(NUM, "L4_PROTO_ERR"); | |
1762 | else l4_proto_err=0; | |
1763 | printf("rxTEST l4_proto_err=%0d\n", l4_proto_err); | |
1764 | ||
1765 | if(get_plus_arg(CHECK, "SEND_PAUSE")) send_pause=get_plus_arg(NUM, "SEND_PAUSE"); | |
1766 | else send_pause=0; | |
1767 | printf("rxTEST send_pause=%0d\n", send_pause); | |
1768 | ||
1769 | } | |
1770 | ///////////////////////////////////////// | |
1771 | //note: rate must be a whole number - no fractional part | |
1772 | function integer rx_rand_test::ipg_in_ns(integer rate_in_Mhz, integer pkt_len, integer header_len) { | |
1773 | ||
1774 | ipg_in_ns = ( (((pkt_len + header_len)*80)/rate_in_Mhz) - ((pkt_len + header_len) * 8) )/10; | |
1775 | //ipg_in_ns = (((pkt_len + header_len)*8)/rate_in_Mhz) - ((pkt_len + header_len) * 0.8); | |
1776 | printf("rxTEST ipg_in_ns=%0d\n", ipg_in_ns); | |
1777 | } | |
1778 | //////////////////////////////////////// | |
1779 | function bit[47:0] rx_rand_test::get_l2dest_from_Trdc(bit[2:0] Trdc, integer mac_id) { | |
1780 | #define MAC_L2_DEST_ADDR 47:0 | |
1781 | #define MAC_L2_RDC 50:48 | |
1782 | #define MAC_PRI 51 | |
1783 | ||
1784 | integer ii; | |
1785 | bit[3:0] rnum; | |
1786 | bit[51:0] mac_entry; | |
1787 | ||
1788 | if(mac_id==2 || mac_id==3) rnum=random()%8; | |
1789 | else rnum=random()%16; | |
1790 | ||
1791 | case(mac_id) { | |
1792 | 0: mac_entry=pktC.FFLP_Model.mac_da_table0[rnum]; | |
1793 | 1: mac_entry=pktC.FFLP_Model.mac_da_table1[rnum]; | |
1794 | 2: mac_entry=pktC.FFLP_Model.mac_da_table2[rnum]; | |
1795 | 3: mac_entry=pktC.FFLP_Model.mac_da_table3[rnum]; | |
1796 | } | |
1797 | //printf("rxTEST p%0d %0d mac rdc=%0d\n", mac_id, rnum, mac_entry[MAC_L2_RDC]); | |
1798 | while(mac_entry[MAC_L2_RDC]!==Trdc) { | |
1799 | if(mac_id==2 || mac_id==3) { | |
1800 | if(rnum==7) rnum=0; | |
1801 | else rnum++; | |
1802 | } | |
1803 | else { | |
1804 | if(rnum==15) rnum=0; | |
1805 | else rnum++; | |
1806 | } | |
1807 | case(mac_id) { | |
1808 | 0: mac_entry=pktC.FFLP_Model.mac_da_table0[rnum]; | |
1809 | 1: mac_entry=pktC.FFLP_Model.mac_da_table1[rnum]; | |
1810 | 2: mac_entry=pktC.FFLP_Model.mac_da_table2[rnum]; | |
1811 | 3: mac_entry=pktC.FFLP_Model.mac_da_table3[rnum]; | |
1812 | } | |
1813 | //printf("rxTEST p%0d %0d mac rdc=%0d\n", mac_id, rnum, mac_entry[MAC_L2_RDC]); | |
1814 | } | |
1815 | ||
1816 | get_l2dest_from_Trdc=mac_entry[MAC_L2_DEST_ADDR]; | |
1817 | } | |
1818 | /////////////////////////// | |
1819 | function bit[11:0] rx_rand_test::get_vlan_from_Trdc(bit[2:0] Trdc, integer mac_id) { | |
1820 | //pick random number 0<= rnum <4096 | |
1821 | //check if Vrdc=Trdc, if yes, return vlan | |
1822 | // if no, inc rnum and redo check | |
1823 | bit[11:0] rnum; | |
1824 | bit[2:0] Vrdc; | |
1825 | bit[17:0] vlan_entry; | |
1826 | ||
1827 | rnum=random()%4096; | |
1828 | ||
1829 | while(Vrdc!==Trdc) { | |
1830 | rnum++; //since bitwise, will rollover | |
1831 | ||
1832 | vlan_entry = pktC.FFLP_Model.vlan_table[rnum]; | |
1833 | case(mac_id) { | |
1834 | 0: Vrdc = vlan_entry[2:0]; | |
1835 | 1: Vrdc = vlan_entry[6:4]; | |
1836 | 2: Vrdc = vlan_entry[10:8]; | |
1837 | 3: Vrdc = vlan_entry[14:12]; | |
1838 | } | |
1839 | //printf("rxTEST rnum=%0d Trdc=%0d Vrdc=%0d\n", rnum, Trdc, Vrdc); | |
1840 | } | |
1841 | get_vlan_from_Trdc=rnum; | |
1842 | } | |
1843 | ////////////////////////////// |