Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / niu / txc_sat / vera / niu_txhost_pktgen.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_txhost_pktgen.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include <vera_defines.vrh>
36#include <ListMacros.vrh>
37#include "niu_mem.vrh"
38#include "dmc_memory_map.vri"
39#include "txc_memory_map.vri"
40// #include "tx_host_err_defines.vri"
41#include "niu_error_dfn.vri"
42
43#include "niu_dma.vrh"
44#include "pcg_token.vrh"
45#include "niu_txtoken.vrh"
46#include "niu_txcntrl_wd.vrh"
47#include "niu_tx_pktconfig.vrh"
48#include "niu_tx_descp.vrh"
49#include "cMesg.vrh"
50#include "pgIdgen.vrh"
51
52
53
54extern CSparseMem SparseMem;
55extern mbox_class mbox_id;
56extern Mesg be_msg;
57
58extern niu_gen_pio gen_pio_drv;
59
60function byte_array DMAChannel::generate_packets(TxPacketGenConfig PktGenConfig,CTxToken TxToken ) {
61
62
63 byte_array packets;
64 integer mac_id;
65 integer d;
66 integer token;
67 integer port_id;
68 integer i;
69 CpgToken pgToken;
70 integer LLC_HACK = 1;
71 bit [15:0] llc_length;
72 integer status;
73
74
75
76
77 if(PktGenConfig.error_info.hosterrors.dma_errors == NACK_PREF_ERROR) {
78 is_nack_pref_err = 1;
79 nack_pref_err_addr = TxToken.xlate_desc_addr;
80 nack_pref_err_pcaddr = TxToken.xlate_desc_addr - 64'h40;
81 }
82
83 status = SetTxError.set_up_errors(PktGenConfig,TxToken);
84 if(status) do_not_check_packet = 1;
85
86 mac_id = PktGenConfig.mac_id ;
87 packets = new();
88
89
90 printf(" Generating Packets for DMA id %d , data_length = %d \n",id,PktGenConfig.data_length);
91 if (get_plus_arg (CHECK, "RX_DROP_PKT_CHECK")) {
92 printf("RX_DROP_PKT_CHECK is specified. MAC-SA before replacing 0x%h\n", PktGenConfig.flow.src_node.l2_addr);
93 // modify src address for the drop checker
94 // This is to be used only for loopback cases
95 PktGenConfig.flow.src_node.l2_addr = pgIdgen.getMacSA(PktGenConfig.loop_back_rxdma_num,mac_id);
96 printf("RX_DROP_PKT_CHECK is specified. MAC-SA after replacing 0x%h\n", PktGenConfig.flow.src_node.l2_addr);
97 } else
98 PktGenConfig.flow.src_node.l2_addr = pgIdgen.getMacSA(id,mac_id);
99
100 // Need some config info which indicates the type of packets to generate
101 pack_gen[mac_id + 8].pkt_gen( PktGenConfig.flow,PktGenConfig.data_length, 3, pgToken, O_WAIT_SEND_FAKE | O_FAKE_OUT );
102 printf(" data_len - %d \n",pgToken.pack_db.data_length);
103 printf(" header len - %d \n",pgToken.pack_db.header_len[0]);
104 token = pgToken.gId;
105
106 // Copy header to out_header in pack_db
107 pgToken.pack_db.out_header[mac_id ] = new;
108 pgToken.pack_db.out_header[mac_id ].use_header = 0;
109 pgToken.pack_db.out_header[mac_id ].header[0] = new;
110 pgToken.pack_db.out_header[mac_id ].header_len[0] = pgToken.pack_db.header_len[ pgToken.pack_db.use_hdr ];
111
112
113
114 for( i = 0; i < pgToken.pack_db.out_header[mac_id ].header_len[0]; i++ )
115 pgToken.pack_db.out_header[mac_id].header[0].val[i] =
116 pgToken.pack_db.header[ pgToken.pack_db.use_hdr ].val[i];
117
118// NEW PACKET
119#ifdef MAC_SAT
120#else
121 packets = new pgToken.buf;
122#endif
123 TxToken.pgToken = new pgToken;
124 TxToken.pgToken.exp_err = PktGenConfig.err_pkt;
125
126 if(PktGenConfig.ecc_2biterr_line1)
127 TxToken.pgToken.do_not_check = do_not_check_packet || PktGenConfig.err_pkt;
128 else
129 TxToken.pgToken.do_not_check = do_not_check_packet;
130
131 TxToken.pgToken.tx_dma_id = id;
132 printf("Err DEBUG ID - %d Flag - %d \n",TxToken.pgToken.gId,do_not_check_packet);
133 printf("Err DEBUG ID - %d Flag - %d \n",TxToken.pgToken.gId,TxToken.pgToken.do_not_check);
134
135 printf("gen_pkts : value of exp_err %0d\n",TxToken.pgToken.exp_err);
136
137
138
139
140 printf("################## BEFORE HOSTPKT DISPLAY\n");
141
142 if (get_plus_arg(CHECK,"TX_VERBOSE")) {
143 pack_gen[mac_id + 8].display_buf(packets,PktGenConfig.data_length);
144 }
145
146
147 if(tx_port_num == -1) {
148 printf("ERROR- TxPort Not Bound for DMA Channel Id -%d \n",id);
149 } else {
150 port_id = tx_port_num;
151 // Only for MAC loop back
152 TxToken.loop_back_rxdma_num = PktGenConfig.loop_back_rxdma_num;
153 TxToken.loop_back_rx_lastpacket = PktGenConfig.loop_back_rx_lastpacket;
154 generate_tokens(port_id,token,TxToken);
155 }
156
157 generate_packets = packets;
158
159}
160
161
162
163task DMAChannel::gen_txpacket(integer ii,TxPacketGenConfig PktGenConfig) {
164
165/*
166
167 ip_packets = generate_packet(config);
168
169 noofdescs = check_how_many_descriptors_for_this_packet;
170 for(i=0;i<noofdescs;i++) {
171 get_address();
172 write_packet_into_memory;
173 create_descriptors;
174 add_descriptors(r);
175 }
176 generate_tokens;
177
178*/
179
180
181 TxPacketControlWord control_word;
182 CTxdescriptor desc;
183 bit[43:0] address;
184 integer noofdescs;
185 bit [13:0] pkt_length;
186 integer rem_pkt_length;
187 integer i;
188 byte_array packets;
189 bit [127:0] w;
190 byte_array ip_packets;
191 integer pkt_ptr;
192 integer last_pkt_ptr;
193 integer buf_sz;
194 bit [3:0] num_ptr;
195 bit [95:0] debug_mac_hdr_bits;
196 bit [39:0] phy_addr;
197 bit [39:0] desc_phy_addr;
198 bit [39:0] desc_v_addr;
199 bit [39:0] mbox_phy_addr;
200
201 integer pad;
202 integer mac_id;
203
204 integer pkt_page_id;
205 integer pageid = -1; // default to give random page_id
206 integer chksum_enb;
207 bit [15:0] partial_chk_sum;
208 bit[43:0] st_addr_4ka;
209 bit[43:0] end_addr_4ka;
210 integer done = 0;
211 integer offset16B = 0;
212
213 CTxToken TxToken;
214
215 TxToken = new(); // Uninitialized
216
217 TxToken.dma_num = id;
218 TxToken.port_num = tx_port_num;
219
220 pad = PktGenConfig.pad;
221 mac_id = PktGenConfig.mac_id;
222 pkt_length = PktGenConfig.data_length + PktGenConfig.flow.frame.l2_pad_length - 4;
223
224 TxToken.pkt_length = pkt_length + 2*pad;
225
226 // get the buffsize from command line
227
228 if (get_plus_arg (CHECK,"TX_BUFFSZ"))
229 buf_sz = get_plus_arg(NUM,"TX_BUFFSZ");
230 else
231 buf_sz = 128;
232
233 // plus arg for a particular page_id
234
235 if (get_plus_arg (CHECK,"PAGE_ID"))
236 pageid = get_plus_arg(NUM,"PAGE_ID");
237
238 if (get_plus_arg (CHECK,"CHKSUM_ENB"))
239 chksum_enb = get_plus_arg(NUM,"CHKSUM_ENB");
240 else
241 chksum_enb = 0;
242
243 if(pageid == 0)
244 pkt_page_id = page0_id;
245 else if(pageid == 1)
246 pkt_page_id = page1_id;
247 else {
248 // randomize the pageid
249 pkt_page_id = random()%2 ? page1_id : page0_id;
250 }
251
252
253 // based on the gather mode do the following
254
255 // hack untill clean up happens to code below
256
257 if((PktGenConfig.gConfig_mode!=0) ) {
258 gen_txGatherPackets( PktGenConfig,pkt_page_id );
259 } else {
260
261
262 if(gather_mode || PktGenConfig.g_mode) {
263 noofdescs = (pkt_length + 16)%buf_sz ?
264 (pkt_length +16)/buf_sz + 1 :
265 (pkt_length + 16)/buf_sz;
266 } else noofdescs = 1;
267
268 printf("Num of desc used %d\n",noofdescs);
269
270 num_ptr = noofdescs;
271 TxToken.NoofGathers = noofdescs;
272
273 for(i=0;i<noofdescs;i++) {
274
275 done = 0;
276
277 if (get_plus_arg (CHECK, "USE_RANDOM_ADDRESS")) {
278 if(i==0) {
279 address = SparseMem.get_address(1,pkt_page_id,16);//10Blocks -- 10*block_size = 5120B
280 } else {
281 address = SparseMem.get_address(1,pkt_page_id,64);//10Blocks -- 10*block_size = 5120B
282 }
283 // address = address + 9'h1ff - address[8:0] + 1;
284 // To make this address 64byte aligned
285 } else {
286 address = 44'h0_03456000 + ii*2048 + id*32'h10_0000 + i*buf_sz;
287 }
288 TxToken.xlate_gather_address[i] = SparseMem.xlate_addr( address[39:0], pkt_page_id );
289
290
291 if(i==0) {
292 if( get_plus_arg (CHECK,"ENABLE_MAC_HDR_DEBUG") ) {
293 debug_mac_hdr_bits = gen_debug_header( address, desc_ring.ring_current_addr, pkt_length /*MORE FIELDS TO BE ADDED*/ );
294 printf(" DEBUG - MAC_ HEADER - %x \n",debug_mac_hdr_bits);
295
296 PktGenConfig.flow.src_node.l2_addr = debug_mac_hdr_bits[47:0];
297 PktGenConfig.flow.dst_node.l2_addr = debug_mac_hdr_bits[95:48];
298 }
299
300 // get the descriptor virtual & phy address
301 desc_v_addr = desc_ring.ring_start_addr + desc_ring.ring_current_addr;
302 desc_phy_addr = SparseMem.xlate_addr(desc_v_addr,desc_ring.ring_page_id,0);
303
304 // get ohy address of the mailbox addr
305 mbox_phy_addr = SparseMem.xlate_addr(mailbox_addr,desc_ring.ring_page_id,0);
306
307 // code to induce pkt_part_err (this is translation erro for pkt_address)
308 // if(PktGenConfig.error_info.hosterrors.packet_errors == PKT_PART_ERROR)
309 if(PktGenConfig.err_code == PKT_PART_ERROR) {
310 address = address ^ 44'hfff_ffff_ffff;
311 do_not_check_packet = 1;
312 TxToken.pgToken.do_not_check = do_not_check_packet;
313 printf("Inducing PKT_PART_ERR\n");
314 }
315
316
317 TxToken.packet_start_address = address;
318 TxToken.descriptor_address = desc_ring.ring_current_addr;
319 TxToken.xlate_desc_addr = desc_phy_addr;
320 TxToken.xlate_mb_addr = mbox_phy_addr;
321
322 if(noofdescs == 1)
323 TxToken.last_descriptor_address = desc_ring.ring_current_addr;
324
325 TxToken.print();
326
327 ip_packets = generate_packets(PktGenConfig,TxToken);
328
329 // Check if TCP pkt
330 if((PktGenConfig.flow.frame.frame_class == CL_TCP) || (PktGenConfig.flow.frame.frame_class == CL_TCP_IP_V6) || (PktGenConfig.flow.frame.frame_class == CL_UDP) || (PktGenConfig.flow.frame.frame_class == CL_UDP_IP_V6)) {
331 stuff_psu_hdr_chksum(ip_packets,PktGenConfig);
332 }
333
334 // display the pseudo hdr stuffed buffer
335
336 // pack_gen[mac_id + 8].display_buf(ip_packets,PktGenConfig.data_length);
337 }
338
339 if(i==0) {
340 if(gather_mode || PktGenConfig.g_mode) {
341
342 control_word = new(i);
343
344 if(PktGenConfig.set_wrong_ctlwd)
345 w = 128'h0;
346 else
347 w = control_word.format_ctrl_word(PktGenConfig);
348
349 control_word.set_control_word(w);
350
351 pkt_ptr = 0;
352 if((pkt_length + 16) <= buf_sz) {
353 if(PktGenConfig.mark_bit)
354 create_descriptor(desc,pkt_length + 16 + 2*pad ,address,num_ptr,1,1,pkt_page_id);
355 else
356 create_descriptor(desc,pkt_length + 16 + 2*pad ,address,num_ptr,1,0,pkt_page_id);
357
358 TxToken.gather_pkt_length[i] = desc.tr_len;
359 WriteTxControlWord(address,control_word,pkt_page_id);
360 address = address + 16 + pad*2; // 128 bits of internal packet_header
361 WritePackets(ip_packets,address,pkt_length,pkt_ptr,last_pkt_ptr,pkt_page_id);
362 } else {
363 if(PktGenConfig.mark_bit)
364 create_descriptor(desc,buf_sz,address,num_ptr,1,1,pkt_page_id);
365 else
366 create_descriptor(desc,buf_sz,address,num_ptr,1,0,pkt_page_id);
367 TxToken.gather_pkt_length[i] = desc.tr_len;
368 WriteTxControlWord(address,control_word,pkt_page_id);
369 address = address + 16 + pad*2; // 128 bits of internal packet_header
370 WritePackets(ip_packets,address,(buf_sz-16),pkt_ptr,last_pkt_ptr,pkt_page_id);
371 rem_pkt_length = (pkt_length +16) - buf_sz;
372 }
373 desc_ring.add_descriptor(desc);
374 pkt_ptr = last_pkt_ptr;
375 } else {
376 control_word = new(i);
377 pkt_ptr = 0;
378 w = control_word.format_ctrl_word(PktGenConfig);
379 control_word.set_control_word(w);
380 if(PktGenConfig.mark_bit)
381 create_descriptor(desc,pkt_length + 16 + 2*pad ,address,num_ptr,1,1,pkt_page_id);
382 else
383 create_descriptor(desc,pkt_length + 16 + 2*pad ,address,num_ptr,1,0,pkt_page_id);
384 TxToken.gather_pkt_length[i] = desc.tr_len;
385 WriteTxControlWord(address,control_word,pkt_page_id);
386 address = address + 16 + pad*2;
387 WritePackets(ip_packets,address,pkt_length,pkt_ptr,last_pkt_ptr,pkt_page_id);
388 desc_ring.add_descriptor(desc);
389 pkt_ptr = last_pkt_ptr;
390 rem_pkt_length = 0;
391 }
392 } else {
393 if(rem_pkt_length <= buf_sz) {
394 create_descriptor(desc,rem_pkt_length,address,num_ptr,0,0,pkt_page_id);
395 TxToken.gather_pkt_length[i] = desc.tr_len;
396 WritePackets(ip_packets,address,rem_pkt_length,pkt_ptr,last_pkt_ptr,pkt_page_id);
397 rem_pkt_length = rem_pkt_length - buf_sz;
398 // update the last descriptor address of the pkt
399 TxToken.last_descriptor_address = desc_ring.ring_current_addr;
400 printf("last_desc of token %d is %h\n",TxToken.id,TxToken.last_descriptor_address);
401 desc_ring.add_descriptor(desc);
402 PktGenConfig.g_mode = 0;
403 } else {
404 create_descriptor(desc,buf_sz,address,num_ptr,0,0,pkt_page_id);
405 TxToken.gather_pkt_length[i] = desc.tr_len;
406 WritePackets(ip_packets,address,buf_sz,pkt_ptr,last_pkt_ptr,pkt_page_id);
407 rem_pkt_length = rem_pkt_length - buf_sz;
408 desc_ring.add_descriptor(desc);
409 }
410 // printf("Remainder_pkt_len %d\n",rem_pkt_length);
411 pkt_ptr=last_pkt_ptr;
412 }
413 printf("Remainder_pkt_len %d\n",rem_pkt_length);
414
415 }
416
417 }// else for hack code
418}
419
420// New code for gather packet generation
421
422task DMAChannel::gen_txGatherPackets(TxPacketGenConfig PktGenConfig, (integer pkt_page_id=0)) {
423
424
425
426 TxPacketControlWord control_word;
427 CTxdescriptor desc;
428 bit[43:0] address;
429 integer noofdescs;
430 bit [13:0] pkt_length;
431 integer rem_pkt_length;
432 integer i;
433 byte_array packets;
434 bit [127:0] w;
435 byte_array ip_packets;
436 integer pkt_ptr;
437 integer last_pkt_ptr;
438 integer buf_sz;
439 bit [3:0] num_ptr;
440 bit [3:0] offset;
441 bit [95:0] debug_mac_hdr_bits;
442 integer pad;
443 bit[43:0] st_addr_4ka;
444
445
446 CTxToken TxToken;
447
448 TxToken = new(); // Uninitialized
449
450 TxToken.dma_num = id;
451 TxToken.port_num = tx_port_num;
452
453 pad = PktGenConfig.pad;
454 pkt_length = PktGenConfig.data_length + PktGenConfig.flow.frame.l2_pad_length - 4;
455
456 TxToken.pkt_length = pkt_length + 2*pad;
457
458
459 if(PktGenConfig.gConfig_mode == -1) {
460 PktGenConfig.SetGatherFields();
461 PktGenConfig.printGatherFields();
462 }
463 noofdescs = PktGenConfig.gConfig_noOfDesc;
464
465 printf("DMAChannel::gen_txGatherPackets Num of desc to beused %d\n",noofdescs);
466
467 // ifset in random mode, populate gConfig_length and gConfig_alignment fields
468
469
470 num_ptr = noofdescs;
471 TxToken.NoofGathers = noofdescs;
472 for(i=0;i<noofdescs;i++) {
473
474 if (get_plus_arg (CHECK, "USE_RANDOM_ADDRESS")) {
475 if(i==0)
476 address = SparseMem.get_address(1,pkt_page_id,PktGenConfig.gConfig_alignment[i]);//10Blocks -- 10*block_size = 5120B
477 else {
478 if(PktGenConfig.gConfig_specific_alignment) {
479 st_addr_4ka = SparseMem.get_address(2,pkt_page_id,4096);
480 address = st_addr_4ka + PktGenConfig.gConfig_specific_line*16 +PktGenConfig.gConfig_alignment[i];
481 } else {
482
483 address = SparseMem.get_address(1,pkt_page_id,PktGenConfig.gConfig_alignment[i]);//10Blocks -- 10*block_size = 5120B
484 offset = address[3:0];
485 be_msg.print(e_mesg_info,"niu_tx_descp","gather_waddr_offset","BYTE_ADDR_OFFSET %0h\n",offset);
486 }
487 }
488
489 // address = address + 9'h1ff - address[8:0] + 1;
490 // To make this address 64byte aligned
491 }
492
493 TxToken.xlate_gather_address[i] = SparseMem.xlate_addr( address[39:0], pkt_page_id );
494
495
496 if(i==0) {
497 if( get_plus_arg (CHECK,"ENABLE_MAC_HDR_DEBUG") ) {
498 debug_mac_hdr_bits = gen_debug_header( address, desc_ring.ring_current_addr, pkt_length /*MORE FIELDS TO BE ADDED*/ );
499 printf(" DEBUG - MAC_ HEADER - %x \n",debug_mac_hdr_bits);
500
501 PktGenConfig.flow.src_node.l2_addr = debug_mac_hdr_bits[47:0];
502 PktGenConfig.flow.dst_node.l2_addr = debug_mac_hdr_bits[95:48];
503 }
504
505 TxToken.packet_start_address = address;
506 TxToken.descriptor_address = desc_ring.ring_current_addr;
507 TxToken.print();
508 ip_packets = generate_packets(PktGenConfig,TxToken);
509
510 if(noofdescs == 1)
511 TxToken.last_descriptor_address = desc_ring.ring_current_addr;
512
513
514 // Check if TCP pkt
515 if((PktGenConfig.flow.frame.frame_class == CL_TCP) || (PktGenConfig.flow.frame.frame_class == CL_TCP_IP_V6) || (PktGenConfig.flow.frame.frame_class == CL_UDP) || (PktGenConfig.flow.frame.frame_class == CL_UDP_IP_V6)) {
516 stuff_psu_hdr_chksum(ip_packets,PktGenConfig);
517 }
518
519 }
520
521 if(i==0) {
522 pkt_ptr = 0;
523 control_word = new(i);
524 w = control_word.format_ctrl_word(PktGenConfig);
525 control_word.set_control_word(w);
526 if(PktGenConfig.mark_bit)
527 create_descriptor(desc,PktGenConfig.gConfig_length[i] + 16 + 2*pad,address,num_ptr,1,1,pkt_page_id);
528 else
529 create_descriptor(desc,PktGenConfig.gConfig_length[i] + 16 + 2*pad,address,num_ptr,1,0,pkt_page_id);
530 TxToken.gather_pkt_length[i] = desc.tr_len;
531 WriteTxControlWord(address,control_word,pkt_page_id);
532 address = address + 16 + 2*pad; // 128 bits of internal packet_header
533 WritePackets(ip_packets,address,PktGenConfig.gConfig_length[i],pkt_ptr,last_pkt_ptr,pkt_page_id);
534 desc_ring.add_descriptor(desc);
535 pkt_ptr = last_pkt_ptr;
536
537 } else {
538 create_descriptor(desc,PktGenConfig.gConfig_length[i],address,num_ptr,0,0,pkt_page_id);
539 TxToken.gather_pkt_length[i] = desc.tr_len;
540 WritePackets(ip_packets,address,PktGenConfig.gConfig_length[i],pkt_ptr,last_pkt_ptr,pkt_page_id);
541 TxToken.last_descriptor_address = desc_ring.ring_current_addr;
542 printf("last_desc of token %d is %h\n",TxToken.id,TxToken.last_descriptor_address);
543 desc_ring.add_descriptor(desc);
544 PktGenConfig.g_mode = 0;
545 pkt_ptr=last_pkt_ptr;
546 }
547
548 }
549
550}
551
552
553//-- task to calulate partial checksum with zeros in the stuff field
554
555function bit[15:0] DMAChannel:: partial_cksum(byte_array ip_packets, TxPacketGenConfig PktGenConfig, integer
556index) {
557
558 integer i,j;
559 bit [16:0] chksum_tmp = 16'h0;
560 integer len;
561 integer l4_start;
562 bit [15:0] tmp_pchksum;
563 integer fclass;
564
565 fclass = PktGenConfig.flow.frame.frame_class;
566
567 if((fclass == CL_TCP) || (fclass == CL_TCP_IP_V6))
568 l4_start = index - 16; // this is because index points to the chksum bytes
569 else if((fclass == CL_UDP) || (fclass == CL_UDP_IP_V6))
570 l4_start = index - 6; // this is because index points to the chksum bytes
571
572 len = PktGenConfig.data_length + PktGenConfig.flow.frame.l2_pad_length - 4;
573
574 ip_packets.val[index] = 8'h0;
575 ip_packets.val[index+1] = 8'h0;
576
577 printf("partial_cksum : index %0d\n",index);
578 printf("partial_cksum : l4_start %0d\n",l4_start);
579 printf("partial_cksum : len %0d\n",len);
580
581 for(i = l4_start; i < len ; i=i+2)
582 {
583 if(i == len - 1) {
584 chksum_tmp = chksum_tmp + {ip_packets.val[i],8'h0};
585 chksum_tmp = chksum_tmp + chksum_tmp[16];
586 chksum_tmp[16] = 1'b0;
587 } else {
588 chksum_tmp = chksum_tmp + {ip_packets.val[i],ip_packets.val[i+1]};
589 chksum_tmp = chksum_tmp + chksum_tmp[16];
590 chksum_tmp[16] = 1'b0;
591 }
592 }
593
594 tmp_pchksum = chksum_tmp[15:0];
595
596 partial_cksum = ~({tmp_pchksum[7:0],tmp_pchksum[15:8]});
597
598}
599
600
601
602//-- task to stuff psuedo header checksum
603
604task DMAChannel:: stuff_psu_hdr_chksum(byte_array ip_packets, TxPacketGenConfig PktGenConfig)
605{
606
607 integer hdr_len = PktGenConfig.flow.frame.header_length;
608 integer index;
609 integer index_base;
610 bit ipver;
611 bit [15:0] full_chksum;
612 bit [15:0] tmp;
613
614 bit [15:0] partial_chksum;
615 bit [15:0] psd_hdr_chksum;
616 bit [15:0] inv_psd_hdr_chksum;
617
618 ipver = PktGenConfig.flow.frame.frame_type[3];
619 index_base = get_index_base(PktGenConfig);
620
621 if(ipver == 1'b0) {
622 index = index_base + (hdr_len - 5)*4;
623 } else {
624 index = index_base;
625 }
626
627 full_chksum = {ip_packets.val[index+1],ip_packets.val[index]};
628
629 printf("stuff : full_cksum : value of full_chksum %0h\n",full_chksum);
630
631 partial_chksum = partial_cksum(ip_packets,PktGenConfig,index);
632
633 printf("stuff : partial_cksum : value of partial_chksum %0h\n",partial_chksum);
634
635 if(full_chksum > partial_chksum)
636 psd_hdr_chksum = full_chksum - partial_chksum;
637 else {
638 tmp = full_chksum - 1;
639 psd_hdr_chksum = {1'b1,tmp} - partial_chksum;
640 }
641
642
643 printf("stuff : partial_cksum : value of psd_hdr_chksum %0h\n",psd_hdr_chksum);
644
645 inv_psd_hdr_chksum = ~psd_hdr_chksum;
646
647 printf("stuff : partial_cksum : value of inv_psd_hdr_chksum %0h\n",inv_psd_hdr_chksum);
648
649 ip_packets.val[index] = inv_psd_hdr_chksum[7:0];
650 ip_packets.val[index+1] = inv_psd_hdr_chksum[15:8];
651
652}
653
654//--- function to calculate the index base value
655
656function integer DMAChannel:: get_index_base(TxPacketGenConfig PktGenConfig)
657{
658 integer base;
659 integer fclass;
660 bit vlan;
661 bit llc;
662 bit ipver;
663
664 ipver = PktGenConfig.flow.frame.frame_type[3];
665 vlan = PktGenConfig.flow.frame.frame_type[2];
666 llc = PktGenConfig.flow.frame.frame_type[0];
667 fclass = PktGenConfig.flow.frame.frame_class;
668
669 if(ipver == 1'b0) {
670 if(fclass == CL_TCP) {
671 case({llc,vlan}) {
672 2'b00 : base = 50;
673 2'b01 : base = 54;
674 2'b10 : base = 58;
675 2'b11 : base = 62;
676 }
677 } else if(fclass == CL_UDP) {
678 case({llc,vlan}) {
679 2'b00 : base = 40;
680 2'b01 : base = 44;
681 2'b10 : base = 48;
682 2'b11 : base = 52;
683 }
684 }
685 } else {
686 if(fclass == CL_TCP_IP_V6) {
687 case({llc,vlan}) {
688 2'b00 : base = 70;
689 2'b01 : base = 74;
690 2'b10 : base = 78;
691 2'b11 : base = 82;
692 }
693 } else if(fclass == CL_UDP_IP_V6) {
694 case({llc,vlan}) {
695 2'b00 : base = 60;
696 2'b01 : base = 64;
697 2'b10 : base = 68;
698 2'b11 : base = 72;
699 }
700 }
701 }
702
703 get_index_base = base;
704}