Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_rxdmc.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 "niu_rx_descp.vrh" | |
39 | #include "niu_rxtoken.vrh" | |
40 | #include "mbox_class.vrh" | |
41 | #include "get_mbox_id.vrh" | |
42 | extern mbox_class mbox_id; | |
43 | extern niu_gen_pio gen_pio_drv; | |
44 | extern CSparseMem SparseMem; | |
45 | ||
46 | /* These classes/file is to embedd the DMA classes, DRR, and other stuff related to RDMC | |
47 | the inputs into this class would be the mbox from pktgen and output would be the stream going | |
48 | into the memory checker | |
49 | ||
50 | ||
51 | */ | |
52 | ||
53 | ||
54 | class CRdmcToken { | |
55 | CRxToken RxToken; // This comes from pktgen | |
56 | ||
57 | // To add more fields | |
58 | } | |
59 | MakeVeraList(CRdmcToken) // list of descriptors | |
60 | ||
61 | class CRxPortDRRInterface { | |
62 | bit [3:0] ports_active; // No of active ports | |
63 | integer NoOfPorts; // No of Ports attached | |
64 | integer started ; | |
65 | integer enable_sb =0; | |
66 | ||
67 | local integer PortDRRWeight[4]; | |
68 | local integer PortDRRDeficit[4]; | |
69 | ||
70 | VeraList_CRdmcToken DrrTokenList[4]; | |
71 | VeraList_CRdmcToken DrrResultList; | |
72 | ||
73 | task new( bit [3:0] ports) { | |
74 | integer i; | |
75 | ports_active = ports ; | |
76 | NoOfPorts = 2;// to be derived at the config time | |
77 | started = 0; | |
78 | for(i=0;i<NoOfPorts; i ++) { | |
79 | DrrTokenList[i] = new(); | |
80 | PortDRRWeight[i] = 16'h400*16; | |
81 | } | |
82 | DrrResultList = new(); | |
83 | ||
84 | fork { | |
85 | getRxToken(); | |
86 | PortDRR(); | |
87 | } join none | |
88 | ||
89 | started = 1; | |
90 | ||
91 | if (get_plus_arg (CHECK, "RX_DROP_PKT_CHECK")) | |
92 | enable_sb = 1; | |
93 | else | |
94 | enable_sb = 0; | |
95 | ||
96 | } | |
97 | ||
98 | // local function integer getTokenHead( var CRdmcToken RdmcToken, integer id); | |
99 | task SetPortsActive(integer num); | |
100 | task ProgramDRRWeight(integer port_num, integer weight); | |
101 | local task getRxToken(); | |
102 | local task addToken( CRdmcToken RdmcToken, integer i); | |
103 | local task getToken(integer i); | |
104 | local task PortDRR(); | |
105 | local function integer check_active(integer id,integer port_id); | |
106 | local function integer update_deficit(integer id, integer length); | |
107 | local function bit[3:0] getActiveList(); | |
108 | ||
109 | local task add_drr_credits(integer i); | |
110 | ||
111 | function integer getDRRResult( var CRdmcToken RdmcToken ); | |
112 | task SetPortDrrWeight(integer w, integer id) { | |
113 | PortDRRWeight[id] = w*16; | |
114 | } | |
115 | ||
116 | } | |
117 | ||
118 | function integer CRxPortDRRInterface::check_active ( integer j, integer activeList) { | |
119 | // returns 1 if jth bit in the ActiveList is set else returns 0 | |
120 | integer tmp; | |
121 | tmp = 1 <<j; | |
122 | if(activeList & tmp) check_active = (1); | |
123 | else check_active = (0); | |
124 | ||
125 | } | |
126 | function integer CRxPortDRRInterface::update_deficit(integer id, integer length) { | |
127 | PortDRRDeficit[id] = PortDRRDeficit[id] - length; | |
128 | printf(" RxDRR DEBUG Credits Spent for PORT %d New Credits = %d \n",id,PortDRRDeficit[id]); | |
129 | if(PortDRRDeficit[id] <=0) update_deficit = 0; | |
130 | else update_deficit = 1; | |
131 | } | |
132 | task CRxPortDRRInterface::add_drr_credits(integer i) { | |
133 | if(PortDRRWeight[i] == -1) { | |
134 | printf("ERROR-- DRR Weights Not programmed for PORT %d \n",i); | |
135 | } | |
136 | PortDRRDeficit[i] = PortDRRDeficit[i] + PortDRRWeight[i] ; | |
137 | // printf(" RxDRR DEBUG Added Credits to PORT %d New Credits = %d \n",i,PortDRRDeficit[i]); | |
138 | } | |
139 | ||
140 | function bit[3:0] CRxPortDRRInterface::getActiveList() { | |
141 | ||
142 | integer i; | |
143 | bit[3:0] active_list; | |
144 | active_list = 0; | |
145 | ||
146 | for(i =0;i<NoOfPorts;i++) { | |
147 | active_list[i] = ( DrrTokenList[i].empty()!=1) ; | |
148 | } | |
149 | getActiveList = active_list; | |
150 | //printf("CRxPortDRRInterface::getActiveList - %x \n",getActiveList); | |
151 | ||
152 | } | |
153 | ||
154 | function integer CRxPortDRRInterface::getDRRResult( var CRdmcToken RdmcToken) { | |
155 | ||
156 | integer status; | |
157 | if(DrrResultList.empty() ) { | |
158 | status = 0; | |
159 | RdmcToken = null; | |
160 | } else { | |
161 | RdmcToken = DrrResultList.front(); | |
162 | DrrResultList.pop_front(); | |
163 | printf(" RxDRR POP from port# -Token - id - %d Size - %d \n",RdmcToken.RxToken.id,DrrResultList.size()); | |
164 | ||
165 | status = 1; | |
166 | } | |
167 | getDRRResult = status; | |
168 | ||
169 | // Need to expand this | |
170 | ||
171 | ||
172 | ||
173 | } | |
174 | ||
175 | ||
176 | task CRxPortDRRInterface::getRxToken() { | |
177 | ||
178 | // Read from mbox from pkt gen and add it to DrrTokenList | |
179 | ||
180 | /* | |
181 | ||
182 | while(1) { | |
183 | for(each port_id) { | |
184 | fork { | |
185 | RxToken = mailbox_get(); | |
186 | // do any misc checking if needed | |
187 | DrrTokenList[port_id].push_back(); | |
188 | } join none | |
189 | } | |
190 | } | |
191 | ||
192 | */ | |
193 | ||
194 | shadow integer i; | |
195 | ||
196 | for(i = 0;i < NoOfPorts; i ++) { | |
197 | if(ports_active[i]) { | |
198 | fork { | |
199 | getToken(i); | |
200 | } join none | |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | task CRxPortDRRInterface::addToken( CRdmcToken RdmcToken, integer i) { | |
206 | ||
207 | DrrTokenList[i].push_back(RdmcToken); | |
208 | printf(" Current Size of DrrTokenList - %d for Port %d \n",DrrTokenList[i].size(),i); | |
209 | ||
210 | } | |
211 | ||
212 | ||
213 | task CRxPortDRRInterface::getToken(integer i) { | |
214 | ||
215 | CRxToken RxToken; | |
216 | CRxToken RxToken_sb; | |
217 | CRdmcToken RdmcToken; | |
218 | integer no_of_tkns; | |
219 | ||
220 | printf(" Start getToken in RDMC for Port %d \n",i); | |
221 | ||
222 | while(1) { | |
223 | no_of_tkns = mailbox_get(WAIT,mbox_id.niu_rxpath_mb[i], RxToken); | |
224 | printf(" No of Tokens left for port %d = %d \n",i, no_of_tkns); | |
225 | ||
226 | if(RxToken == null) { | |
227 | printf("ERROR CRxPortDRRInterface::getToken -Failed for port id %d\n",i); | |
228 | return; | |
229 | } | |
230 | ||
231 | if(enable_sb) { | |
232 | RxToken_sb = RxToken.object_copy(); | |
233 | mailbox_put(mbox_id.niu_rxpath_sb[i],RxToken_sb); | |
234 | ||
235 | } else { | |
236 | RdmcToken = new(); | |
237 | RdmcToken.RxToken = new RxToken; | |
238 | addToken(RdmcToken,i); | |
239 | } | |
240 | ||
241 | } | |
242 | ||
243 | ||
244 | } | |
245 | task CRxPortDRRInterface::PortDRR() { | |
246 | ||
247 | /* | |
248 | ||
249 | for each port { | |
250 | status = RxDrrIntf.getTokenHead( head, port_id) ; | |
251 | weight associated with the port is in PortDRRWeight[id] | |
252 | if(status== VALID) { | |
253 | //Arbitrate---- This is implementaion dependent | |
254 | ||
255 | } | |
256 | SendOutput to DrrResultList | |
257 | } | |
258 | */ | |
259 | CRdmcToken RdmcToken ; | |
260 | integer port_id; | |
261 | bit[3:0] active_list = 0; | |
262 | integer arb_id,old_arb_id; | |
263 | integer i,match_found; | |
264 | integer iter; | |
265 | integer status; | |
266 | integer maintain_active_state; | |
267 | integer length; | |
268 | ||
269 | ||
270 | // In the absence of DRR | |
271 | old_arb_id = 0; | |
272 | for(i =0;i<NoOfPorts;i++) { | |
273 | PortDRRDeficit[i] = 0; | |
274 | } | |
275 | ||
276 | while(1) { | |
277 | ||
278 | // active_list = wait_for_active(); | |
279 | active_list = getActiveList(); | |
280 | while(active_list == 4'h0 ) { // Wait here if none of these had any packet | |
281 | @(posedge CLOCK); | |
282 | active_list = getActiveList(); | |
283 | } | |
284 | ||
285 | ports_active = 0; | |
286 | for(i = 0; i < NoOfPorts; i ++) { | |
287 | if(active_list[i]) { | |
288 | ports_active = ( ports_active | ( 1<< i )); | |
289 | if(PortDRRDeficit[i]<=0) { | |
290 | add_drr_credits(i); | |
291 | } | |
292 | } else { | |
293 | // printf("Rx TokenList Empty\n"); | |
294 | } | |
295 | } | |
296 | ||
297 | while(ports_active) { | |
298 | arb_id = old_arb_id ; | |
299 | port_id = -1; | |
300 | match_found =0; | |
301 | iter =0; | |
302 | ||
303 | printf("RxDRR DEBUG:Before While Arb id - %d iter - %d ports_active - %x \n",arb_id,iter,ports_active); | |
304 | while( (iter <NoOfPorts /*MAX_NO_OF_PORTS*/) & ( !match_found)) { | |
305 | if(check_active(arb_id,ports_active)) { | |
306 | port_id = arb_id; | |
307 | match_found = 1; | |
308 | ||
309 | } | |
310 | arb_id = (arb_id + 1)%NoOfPorts; | |
311 | iter++; | |
312 | //printf("RxDRR DEBUG: Arb id - %d iter - %d ports_active - %x \n",arb_id,iter,ports_active); | |
313 | } // At the end of this there should be at least one port_id selected | |
314 | ||
315 | if( (port_id == -1) ) { | |
316 | ||
317 | exit(0); | |
318 | return; | |
319 | } | |
320 | ||
321 | if(DrrTokenList[port_id].empty() ) { | |
322 | status = 0; | |
323 | ports_active = 0; | |
324 | }else { | |
325 | RdmcToken = DrrTokenList[port_id].front(); | |
326 | status = 1; // Status will be set to -1, if any errors are to be detected | |
327 | // and the ports is set to inactive | |
328 | } | |
329 | ||
330 | maintain_active_state = 1; | |
331 | if(status == -1) { | |
332 | maintain_active_state = 0; | |
333 | } else if(status ==1 ){ | |
334 | if(PortDRRDeficit[port_id] > 0) { | |
335 | length = RdmcToken.RxToken.pkt_length; | |
336 | maintain_active_state = update_deficit(port_id,length); // | |
337 | printf(" RxDRR Received Token - id - %d dma_num - %d \n",RdmcToken.RxToken.id,RdmcToken.RxToken.dma_num); | |
338 | DrrTokenList[port_id].pop_front(); | |
339 | DrrResultList.push_back(RdmcToken); | |
340 | printf(" RxDRR Sent from port# - %d Token - id - %d Size - %d \n",port_id,RdmcToken.RxToken.id,DrrResultList.size()); | |
341 | } else { | |
342 | maintain_active_state = 0; | |
343 | printf("RxDRR DEBUG PORT# %d In deficit Need more credit \n",port_id); | |
344 | } | |
345 | } | |
346 | ||
347 | if(maintain_active_state==0) { | |
348 | // printf(" RxDRR DEBUG - Before deleting ports_active = %x \n",ports_active); | |
349 | ports_active = ports_active ^ ( 1 << port_id ); | |
350 | // printf(" RxDRR DEBUG - After deleting ports_active = %x \n",ports_active); | |
351 | old_arb_id = (port_id + 1) %NoOfPorts ; | |
352 | } | |
353 | } | |
354 | @(posedge CLOCK); | |
355 | // old_arb_id = 0; | |
356 | ||
357 | } | |
358 | } | |
359 | ||
360 | task CRxPortDRRInterface::ProgramDRRWeight(integer port_num, integer weight) { | |
361 | ||
362 | case(port_num) { | |
363 | 0: { gen_pio_drv.pio_wr(PT_DRR_WT0,weight); | |
364 | PortDRRWeight[port_num] = 16*weight; | |
365 | } | |
366 | 1: { gen_pio_drv.pio_wr(PT_DRR_WT1,weight); | |
367 | PortDRRWeight[port_num] = 16*weight; | |
368 | } | |
369 | 2: { gen_pio_drv.pio_wr(PT_DRR_WT2,weight); | |
370 | PortDRRWeight[port_num] = 16*weight; | |
371 | } | |
372 | 3: { gen_pio_drv.pio_wr(PT_DRR_WT3,weight); | |
373 | PortDRRWeight[port_num] = 16*weight; | |
374 | } | |
375 | default: { } | |
376 | } | |
377 | } | |
378 | ||
379 | class CRDMC { | |
380 | bit [3:0] active_ports; | |
381 | bit [3:0] PortDefDma[4]; // 4 Registers present in RDMC | |
382 | bit [3:0] L2DefDma[4]; // 4 Registers present in ZCP | |
383 | RxDMAChannel rx_dma[32]; | |
384 | CRxPortDRRInterface RxDrrIntf; | |
385 | local VeraList_CRdmcToken RdmcTokens; | |
386 | local task ProcessDRROutput(); | |
387 | local task SendTokenForCheck(CRxToken RxToken); | |
388 | ||
389 | task SetPortsActive(integer num); | |
390 | task new(); | |
391 | task start(bit [3:0] port_list); | |
392 | task InitRXDMA(integer dma_ch_num, integer desc_ring_length, integer compl_ring_len, bit [63:0] rbr_config_B_data, bit [15:0] initial_kick, (integer xlation = 1)); | |
393 | task SetPage0Registers (integer dma_chnl, bit [31:0] mask,bit [31:0] value, bit [31:0] reloc); | |
394 | task BindDmaIntrDev( RxDMAChannel RxDma, integer i ); | |
395 | task ProgramPortDefDma(bit [1:0] port_id, bit [3:0] dma_num); | |
396 | task ProgramL2DefDma(bit [1:0] port_id, bit [3:0] dma_num); | |
397 | function bit [3:0] getPortDefDma(bit [1:0] port_id); | |
398 | function bit [3:0] getL2DefDma(bit [1:0] port_id); | |
399 | task resetDMA(integer dma_num); | |
400 | } | |
401 | ||
402 | task CRDMC::new() { | |
403 | ||
404 | integer i; | |
405 | string init_mac_ports,temp_port; | |
406 | bit[31:0] get_mac_port; | |
407 | bit [3:0] ports_active; | |
408 | ||
409 | for(i = 0 ; i < 32; i ++) { | |
410 | rx_dma[i]=new(i,"Rx"); // power up as inactive | |
411 | } | |
412 | ||
413 | if (get_plus_arg( CHECK, "CHKR_AUTO_UPDATE_RCR_HEAD")) { | |
414 | for(i = 0 ; i < 32; i ++) { | |
415 | if(mbox_id.niu_rxpath_rcr_update[i] == -1) { | |
416 | mbox_id.niu_rxpath_rcr_update[i] = alloc(MAILBOX,0,1); | |
417 | } | |
418 | } | |
419 | } | |
420 | ||
421 | RdmcTokens = new(); | |
422 | active_ports = 0; | |
423 | if( get_plus_arg( CHECK, "GET_MAC_PORTS=")) | |
424 | get_mac_port = get_plus_arg( STR, "GET_MAC_PORTS="); | |
425 | init_mac_ports.bittostr(get_mac_port); | |
426 | for (i=0; i<init_mac_ports.len();i++) { | |
427 | temp_port =init_mac_ports.substr(i,i); | |
428 | ports_active[i]=( temp_port.atoi()== i) ; | |
429 | } | |
430 | ||
431 | printf ("niu_rxdmc.vr: From +GET_MAC_PORTS, ports_active = %b\n", ports_active); | |
432 | active_ports = 4'b0011; | |
433 | for(i = 0 ; i < 4; i ++) { | |
434 | PortDefDma[i] = 0; | |
435 | L2DefDma[i] = 0; | |
436 | } | |
437 | printf ("niu_rxdmc.vr: final active_ports = %b\n", active_ports); | |
438 | RxDrrIntf = new(active_ports); | |
439 | fork { | |
440 | ProcessDRROutput (); | |
441 | } join none | |
442 | ||
443 | } | |
444 | ||
445 | task CRDMC::resetDMA(integer dma_num) { | |
446 | bit [39:0] address; | |
447 | bit [63:0] rd_data; | |
448 | bit rst_done = 0; | |
449 | integer ret; | |
450 | ||
451 | address = RXDMA_CFIG1 + dma_num*40'h200; | |
452 | rd_data = 64'h0; | |
453 | rd_data[30] = 1; // reset bit | |
454 | gen_pio_drv.pio_wr(address,rd_data); | |
455 | printf ("RxDMAChannel::resetRxDma() Time %0d, DMA - %0d was just reset\n", {get_time(HI),get_time(LO)}, dma_num); | |
456 | ||
457 | printf ("RxDMAChannel::resetRxDma() Time %0d, Polling on reset_done ... DMA - %0d\n", {get_time(HI),get_time(LO)}, dma_num); | |
458 | ||
459 | while(!rst_done) { | |
460 | repeat(100) @(posedge CLOCK); | |
461 | address = RXDMA_CFIG1 + dma_num*40'h200; | |
462 | gen_pio_drv.pio_rd(address,rd_data); | |
463 | rst_done = !rd_data[30]; | |
464 | } | |
465 | printf ("RxDMAChannel::resetRxDma() Time %0d, Reset_done! Flushing the Verif State for DMA - %0d\n", | |
466 | {get_time(HI),get_time(LO)}, dma_num); | |
467 | ||
468 | rx_dma[dma_num] = new(dma_num,"Rx"); | |
469 | ret = SparseMem.delete_page_contexts(64+(2*dma_num)); | |
470 | ret = SparseMem.delete_page_contexts(64+(2*dma_num+1)); | |
471 | ||
472 | } | |
473 | ||
474 | task CRDMC::ProgramPortDefDma(bit [1:0] port_id, bit [3:0] dma_num){ | |
475 | // Initiate the PIO Write to RTL, and update the shadow as well | |
476 | case(port_id){ | |
477 | 0: gen_pio_drv.pio_wr(DEF_PTO_RDC, {60'h0,dma_num}); | |
478 | 1: gen_pio_drv.pio_wr(DEF_PT1_RDC, {60'h0,dma_num}); | |
479 | default: printf ("WARNING: CRDMC::ProgramPortDefDma() Invalid port_id %0d\n", port_id); | |
480 | } | |
481 | // Update the shadow | |
482 | PortDefDma[port_id] = dma_num; | |
483 | } | |
484 | ||
485 | function bit [3:0] CRDMC::getPortDefDma(bit [1:0] port_id){ | |
486 | getPortDefDma = PortDefDma[port_id]; | |
487 | } | |
488 | ||
489 | task CRDMC::BindDmaIntrDev( RxDMAChannel RxDma, integer i ){ | |
490 | rx_dma[i]= RxDma; | |
491 | printf(" CRDMC::BindDmaIntrDev RxDMA Channel - %d Bound as Logical DeviceId - %d \n",i,rx_dma[i].dev_id); | |
492 | } | |
493 | task CRDMC::start(bit [3:0] port_list) { | |
494 | ||
495 | integer i; | |
496 | active_ports = port_list; | |
497 | /* DUMMY DO NOT USE*/ | |
498 | ||
499 | } | |
500 | ||
501 | ||
502 | task CRDMC::SendTokenForCheck(CRxToken RxToken) { | |
503 | mailbox_put(mbox_id.niu_rxpacket_memchk_mb,RxToken); | |
504 | } | |
505 | ||
506 | task CRDMC::ProcessDRROutput () { | |
507 | ||
508 | /* | |
509 | ||
510 | gets the tokens from DRR , based upon the dma number- checks with the DMA class about the | |
511 | its status | |
512 | The functions in the DMA class has to return the address and the status associated with this | |
513 | ||
514 | ||
515 | while(1) { | |
516 | ||
517 | while(DrrResultList == empty) { | |
518 | wait(); | |
519 | } | |
520 | ||
521 | DRRstatus = RxDrrIntf.getDRRResult(RxToken); | |
522 | if(DRRstatus == VALID) { | |
523 | ||
524 | dma_num = RxToken.dma_num; | |
525 | ||
526 | status = RxDma[dma_num].checkStatus(token); | |
527 | ||
528 | if(status == DMA_NOT_ENABLED) { | |
529 | //Take appropriate action -- such as choose default dma - ? | |
530 | ||
531 | SetTokenToDropPacket(); | |
532 | } else if( status == COMPLETION_FULL) { | |
533 | //Take appropriate action -- such as choose default dma - ? | |
534 | ||
535 | SetTokenToDropPacket(); | |
536 | ||
537 | } else if(status == VALID) { | |
538 | ||
539 | AddressStatus = RxDma[dma_num].GetPacketAddress(Token); | |
540 | // CheckStatus for caselike not more descriptor? | |
541 | // etc etc. | |
542 | ||
543 | SetAddress(Token); | |
544 | ForwardToken(Token); | |
545 | } | |
546 | } | |
547 | } | |
548 | ||
549 | ||
550 | */ | |
551 | ||
552 | ||
553 | CRdmcToken RdmcToken; | |
554 | integer DMAState; | |
555 | integer dma_num; | |
556 | ||
557 | integer address_status; | |
558 | ||
559 | bit [63:0] packet_start_address; | |
560 | bit [63:0] packet_end_address; | |
561 | integer status; | |
562 | ||
563 | while(RxDrrIntf.started == 0) { | |
564 | // wait | |
565 | @(posedge CLOCK); | |
566 | } | |
567 | ||
568 | while(1) { | |
569 | ||
570 | ||
571 | status = 0; | |
572 | while (status ==0) { | |
573 | status = RxDrrIntf.getDRRResult(RdmcToken); | |
574 | // if(status == 1) { | |
575 | // printf(" Status - 1 Token Received from DRR - id - %d - dma - %d \n",RdmcToken.RxToken.id,RdmcToken.RxToken.dma_num); | |
576 | // } | |
577 | @(posedge CLOCK); | |
578 | } | |
579 | printf(" Token Received from DRR - id - %d - dma - %d \n",RdmcToken.RxToken.id,RdmcToken.RxToken.dma_num); | |
580 | ||
581 | dma_num = RdmcToken.RxToken.dma_num; | |
582 | if(RdmcToken.RxToken.pkt_length<=56) { | |
583 | printf("<%0d> CRxPortDRRInterface::getToken: rtl will drop runt pkts len<=56B, pkt ID %0d, pkt length:%0d\n", | |
584 | get_time(LO),RdmcToken.RxToken.pgToken.gId, RdmcToken.RxToken.pkt_length); | |
585 | RdmcToken.RxToken.pkt_type = RUNT_DROP_RxPKT; | |
586 | DMAState = 0; | |
587 | } else { | |
588 | DMAState = rx_dma[dma_num].CheckDMAStatus(RdmcToken.RxToken); | |
589 | if(DMAState) { | |
590 | printf(" RDMC DEBUG - DMA %d is active - Packets to be forwarded Further - \n",dma_num); | |
591 | } else { | |
592 | printf(" RDMC DEBUG - DMA %d is not active - Packets to be dropped \n",dma_num); | |
593 | // Need more cases here | |
594 | } | |
595 | ||
596 | } | |
597 | ||
598 | if(DMAState) | |
599 | address_status = rx_dma[dma_num].getPacketAddress(RdmcToken.RxToken); | |
600 | ||
601 | // address_status here can be used as a status to indicate if DMC will be writing | |
602 | // packets.. ie to filter out any errors -- as a place holder | |
603 | ||
604 | // If the status is correct and everything is updated - send this token to the other | |
605 | // side and let the packet checker check this | |
606 | ||
607 | // This should be used only when packets are going to be checked without parsing the | |
608 | // completion ring. | |
609 | ||
610 | ||
611 | SendTokenForCheck(RdmcToken.RxToken); | |
612 | ||
613 | } | |
614 | ||
615 | } | |
616 | ||
617 | task CRDMC::SetPage0Registers(integer dma_chnl, bit [31:0] mask,bit [31:0] value, bit [31:0] reloc) { | |
618 | bit [39:0] address; | |
619 | ||
620 | address = RX_LOG_PAGE_MASK1 + dma_chnl*8'h40; | |
621 | gen_pio_drv.pio_wr(address,{32'h0,mask}); | |
622 | ||
623 | address = RX_LOG_PAGE_VALUE1 + dma_chnl*8'h40; | |
624 | gen_pio_drv.pio_wr(address,{32'h0,value}); | |
625 | ||
626 | address = RX_LOG_PAGE_RELO1 + dma_chnl*8'h40; | |
627 | gen_pio_drv.pio_wr(address,{32'h0,reloc}); | |
628 | ||
629 | } | |
630 | ||
631 | task CRDMC::InitRXDMA(integer dma_chnl, integer desc_ring_length, integer compl_ring_len, bit [63:0] rbr_config_B_data, bit [15:0] initial_kick, (integer xlation = 1)) { | |
632 | // Activate the Ports 0, 1, 2 and/or 3. | |
633 | // start(3); | |
634 | // Call the init function for the particular DMA channel | |
635 | rx_dma[dma_chnl].InitDMAChan(dma_chnl, desc_ring_length, compl_ring_len, rbr_config_B_data, initial_kick, xlation); | |
636 | } | |
637 | ||
638 |