| 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 | ////////////////////////////// |