| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: niu_rx_descp_sch.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_rxtoken.vrh" |
| 39 | #include "niu_dmc_descr_ring.vrh" |
| 40 | |
| 41 | extern CSparseMem SparseMem; |
| 42 | |
| 43 | #define DESCR_DONE 1 |
| 44 | #define DESCR_NOT_DONE 0 |
| 45 | |
| 46 | class CRxDescSch extends CRxdescriptor { |
| 47 | |
| 48 | // This is the place holder for the descriptor before scheduling one |
| 49 | integer id; |
| 50 | bit [63:0]address;// Address of this descriptor |
| 51 | bit [63:0] virtaddress;// Address of this descriptor |
| 52 | integer valid; |
| 53 | integer blk_size; |
| 54 | integer buf_size; |
| 55 | integer bytes_allocated; |
| 56 | integer index; |
| 57 | |
| 58 | |
| 59 | task new( ( integer i =0)) { |
| 60 | id = 0; |
| 61 | valid = 0; |
| 62 | bytes_allocated = 0; |
| 63 | index = 0; |
| 64 | } |
| 65 | |
| 66 | function bit[63:0] getAddress ( integer length, var bit[63:0] vaddr ) { |
| 67 | getAddress = address + bytes_allocated; |
| 68 | vaddr = virtaddress + bytes_allocated; |
| 69 | bytes_allocated = bytes_allocated + buf_size; |
| 70 | printf(" RDMC DEBUG - buf_size- %d bytes_allocated - %d Address - %x\n",buf_size,bytes_allocated,getAddress); |
| 71 | if(bytes_allocated >blk_size) { |
| 72 | printf(" ERROR Potential Programming error or Testbench ERROR -- \n"); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | function integer checkState () { |
| 77 | if(bytes_allocated == blk_size) { |
| 78 | checkState = DESCR_DONE; |
| 79 | printf(" RDMC DEBUG - DONE WITH THIS DESCRIPTOR \n"); |
| 80 | } else { checkState = DESCR_NOT_DONE; |
| 81 | } |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | |
| 86 | MakeVeraList(CRxDescSch) // list of descriptors |
| 87 | |
| 88 | class CRxDescrSchRing extends CDescrRing { |
| 89 | |
| 90 | VeraList_CRxDescSch desc_ring; |
| 91 | integer index; |
| 92 | task new(integer i = 0) { |
| 93 | id = i; |
| 94 | index =0; |
| 95 | desc_ring = new(); |
| 96 | } |
| 97 | function CRxDescSch front() { |
| 98 | front = desc_ring.front(); |
| 99 | } |
| 100 | task pop_front(){ |
| 101 | desc_ring.pop_front(); |
| 102 | } |
| 103 | task push_back( CRxDescSch desc ) { |
| 104 | desc.index = index++; |
| 105 | desc_ring.push_back(desc); |
| 106 | //printf(" in CRxDescSch: Size - - %d \n",desc_ring.size()); |
| 107 | } |
| 108 | function CRxDescSch back() { |
| 109 | back = desc_ring.back(); |
| 110 | printf(" in CRxDescSch: address - %x \n",back.blk_addr); |
| 111 | } |
| 112 | function integer get_ring_size() { |
| 113 | get_ring_size = desc_ring.size(); |
| 114 | } |
| 115 | |
| 116 | // Something fishy here--- |
| 117 | function integer isRingEmpty() { |
| 118 | if(get_ring_size()) isRingEmpty = 0; |
| 119 | else isRingEmpty = 1; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | class CRxdescpScheduler { |
| 124 | |
| 125 | integer valid; |
| 126 | integer id; |
| 127 | // Variables needed for carving logic to work |
| 128 | bit vld0,vld1,vld2; |
| 129 | integer blk_size; |
| 130 | integer bufsz0,bufsz1,bufsz2; |
| 131 | |
| 132 | CRxDescrSchRing desc_ring; |
| 133 | |
| 134 | CRxDescSch RxDescSchSMALL; |
| 135 | CRxDescSch RxDescSchMEDIUM; |
| 136 | CRxDescSch RxDescSchLARGE; |
| 137 | static bit [2:0] RxDescState[32]; // indicates which ones are popped out and are valid |
| 138 | integer reclaim_index; |
| 139 | integer last_reclaim_index; |
| 140 | |
| 141 | |
| 142 | |
| 143 | task new(integer i) { |
| 144 | id = i; |
| 145 | vld0 = 0; |
| 146 | vld1 = 0; |
| 147 | vld2 = 0; |
| 148 | reclaim_index = 0; |
| 149 | last_reclaim_index = 0; |
| 150 | desc_ring = new(); |
| 151 | RxDescState[i] = 0; |
| 152 | // printf(" CRxdescpScheduler- Newd\n"); |
| 153 | } |
| 154 | |
| 155 | task set_blk_size(bit [1:0] s) ; |
| 156 | task set_bufsz0(bit [1:0] s,integer v) ; |
| 157 | task set_bufsz1(bit [1:0] s,integer v) ; |
| 158 | task set_bufsz2(bit [1:0] s,integer v) ; |
| 159 | task print() { |
| 160 | printf("CRxdescpScheduler DMA-%d - bufsz0 - %d bufz1 - %d bufz2 - %d vld0 - %d vld1 - %d vld2 - %d \n",id,bufsz0,bufsz1,bufsz2, vld0,vld1,vld2 ); |
| 161 | } |
| 162 | |
| 163 | |
| 164 | |
| 165 | function integer get_reclaim_index ( ) { get_reclaim_index = reclaim_index; } |
| 166 | task pushDescForSch( bit [31:0] address, (integer pkt_page_id = 0) ) ; |
| 167 | local function integer getNextDesc( var CRxDescSch RxDescSch, var integer type); |
| 168 | local function integer popDescrs(); |
| 169 | local task allocJumboPackets ( CRxToken RxToken, integer NoOfDescrNeeded ); |
| 170 | local task SetIndexForReclaim(); |
| 171 | function integer getAddress ( CRxToken RxToken ); |
| 172 | local task setDescType( CRxDescSch RxDescSch, integer type) { |
| 173 | if(type == 2) { |
| 174 | RxDescSchLARGE = new RxDescSch; |
| 175 | } else if( type ==1) { |
| 176 | RxDescSchMEDIUM = new RxDescSch; |
| 177 | } else if( type ==0) { |
| 178 | RxDescSchSMALL = new RxDescSch; |
| 179 | } else { |
| 180 | printf(" ERROR in setDescType \n"); |
| 181 | } |
| 182 | |
| 183 | } |
| 184 | |
| 185 | } |
| 186 | task CRxdescpScheduler::set_blk_size(bit [1:0] s) { |
| 187 | case(s) { |
| 188 | 2'b00 : blk_size = 4096; |
| 189 | 2'b01 : blk_size = 8192; |
| 190 | 2'b10 : blk_size = 16384; |
| 191 | 2'b11 : blk_size = 32768; |
| 192 | } |
| 193 | } |
| 194 | task CRxdescpScheduler::set_bufsz0(bit [1:0] s, integer v) { |
| 195 | bufsz0 = 256 * ( 1<<s ) ; |
| 196 | vld0 = v; |
| 197 | } |
| 198 | task CRxdescpScheduler::set_bufsz1(bit [1:0] s, integer v) { |
| 199 | bufsz1 = 1024 * ( 1<<s ) ; |
| 200 | vld1 = v; |
| 201 | } |
| 202 | task CRxdescpScheduler::set_bufsz2(bit [1:0] s, integer v) { |
| 203 | bufsz2 = 2048 * (1<< s) ; |
| 204 | vld2 = v; |
| 205 | } |
| 206 | |
| 207 | task CRxdescpScheduler::pushDescForSch( bit [31:0] address, (integer pkt_page_id = 0) ) { |
| 208 | |
| 209 | CRxDescSch RxDescSch; |
| 210 | bit [39:0] xlate_address; |
| 211 | bit [31:0] xlate_address_page; |
| 212 | xlate_address = SparseMem.xlate_addr({address,12'h0},pkt_page_id); |
| 213 | xlate_address_page = xlate_address[39:12]; |
| 214 | RxDescSch = new(); |
| 215 | // printf(" Pushing descriptor for DMA%d Descriptor - orig %x xlate - %x \n",id,address,xlate_address[39:12]); |
| 216 | |
| 217 | case(blk_size) { |
| 218 | 4096 : RxDescSch.address = {20'h0,xlate_address_page[31:0],12'h0}; |
| 219 | 8192 : RxDescSch.address = {20'h0,xlate_address_page[31:1],13'h0}; |
| 220 | 16384 : RxDescSch.address = {20'h0,xlate_address_page[31:2],14'h0}; |
| 221 | 32768 : RxDescSch.address = {20'h0,xlate_address_page[31:3],15'h0}; |
| 222 | } |
| 223 | |
| 224 | case(blk_size) { |
| 225 | 4096 : RxDescSch.virtaddress = {20'h0,address[31:0],12'h0}; |
| 226 | 8192 : RxDescSch.virtaddress = {20'h0,address[31:1],13'h0}; |
| 227 | 16384 : RxDescSch.virtaddress = {20'h0,address[31:2],14'h0}; |
| 228 | 32768 : RxDescSch.virtaddress = {20'h0,address[31:3],15'h0}; |
| 229 | } |
| 230 | // replace this with page handle |
| 231 | |
| 232 | desc_ring.push_back(RxDescSch); |
| 233 | |
| 234 | } |
| 235 | |
| 236 | task CRxdescpScheduler::SetIndexForReclaim() { |
| 237 | |
| 238 | // first check the state |
| 239 | // for each of the pop'd descriptor get the index |
| 240 | // compute min of all of these and compare against the last accessed index |
| 241 | |
| 242 | integer index_small; |
| 243 | integer index_medium; |
| 244 | integer index_large; |
| 245 | integer index_min; |
| 246 | bit[2:0] State; |
| 247 | // start with a large value |
| 248 | index_small = 32'hffffff; |
| 249 | index_medium = 32'hffffff; |
| 250 | index_large = 32'hffffff; |
| 251 | |
| 252 | State = RxDescState[id]; |
| 253 | |
| 254 | index_small = (State[0])? RxDescSchSMALL.index: index_small; |
| 255 | index_medium = (State[1])? RxDescSchMEDIUM.index: index_medium; |
| 256 | index_large = (State[2])? RxDescSchLARGE.index: index_large; |
| 257 | |
| 258 | // min value |
| 259 | index_min = (index_small<index_medium) ? index_small: index_medium; |
| 260 | index_min = (index_min<index_large) ? index_min : index_large; |
| 261 | |
| 262 | reclaim_index = (last_reclaim_index > index_min ) ? index_min : last_reclaim_index; |
| 263 | |
| 264 | } |
| 265 | |
| 266 | |
| 267 | |
| 268 | function integer CRxdescpScheduler::getNextDesc( var CRxDescSch RxDescSch, var integer type) { |
| 269 | |
| 270 | integer size; |
| 271 | bit [2:0] State; |
| 272 | |
| 273 | size = desc_ring.get_ring_size(); |
| 274 | printf(" CRxdescpScheduler::getNextDesc: DMA- %d ring size - %d isRingEmpty - %d \n",id,size,desc_ring.isRingEmpty()); |
| 275 | if(desc_ring.isRingEmpty() ) { |
| 276 | getNextDesc = -1; // Ring is empty - packet to be dropped |
| 277 | type = -1; |
| 278 | return; |
| 279 | |
| 280 | } else { |
| 281 | RxDescSch = desc_ring.front(); |
| 282 | printf(" CRxdescpScheduler::getNextDesc DMA- %d Address - %x Index - %d\n", id,RxDescSch.address,RxDescSch.index); |
| 283 | getNextDesc = size; |
| 284 | desc_ring.pop_front(); |
| 285 | } |
| 286 | |
| 287 | // Mark this descriptor as either of S,M,L |
| 288 | |
| 289 | // check various enables - |
| 290 | State = RxDescState[id]; |
| 291 | |
| 292 | if(vld2 & ~State[2] ) { |
| 293 | // Mark this as large |
| 294 | RxDescSch.buf_size = bufsz2; |
| 295 | RxDescSch.blk_size = blk_size; |
| 296 | RxDescSch.valid = 1; |
| 297 | State[2] = 1; |
| 298 | type = 2; |
| 299 | } else if(vld1 & ~State[1] ) { |
| 300 | RxDescSch.buf_size = bufsz1; |
| 301 | RxDescSch.blk_size = blk_size; |
| 302 | RxDescSch.valid = 1; |
| 303 | State[1] = 1; |
| 304 | type = 1; |
| 305 | } else if(vld0 & ~State[0] ) { |
| 306 | RxDescSch.buf_size = bufsz0; |
| 307 | RxDescSch.blk_size = blk_size; |
| 308 | RxDescSch.valid = 1; |
| 309 | State[0] = 1; |
| 310 | type = 0; |
| 311 | } else { |
| 312 | printf(" ERROR--- MOST Likely testbench ERROR -- FIX IT \n"); |
| 313 | getNextDesc = -1; |
| 314 | } |
| 315 | |
| 316 | RxDescState[id] = State; |
| 317 | printf(" CRxdescpScheduler::getNextDesc DMA- %d State - %b\n",id,State); |
| 318 | |
| 319 | } |
| 320 | |
| 321 | function integer CRxdescpScheduler::popDescrs() { |
| 322 | |
| 323 | // This function always keeps various descriptors blocks available |
| 324 | |
| 325 | integer done; |
| 326 | CRxDescSch RxDescSch; |
| 327 | integer status,type; |
| 328 | bit[2:0] State; |
| 329 | State = RxDescState[id]; |
| 330 | |
| 331 | if (vld2|vld1|vld0) |
| 332 | done = (State == {vld2,vld1,vld0}); |
| 333 | else { |
| 334 | popDescrs = -1; |
| 335 | return; |
| 336 | } |
| 337 | printf( "CRxdescpScheduler::popDescrs DMA %d State- %b Valid - %b\n",id,State,{vld2,vld1,vld0} ); |
| 338 | while(!done) { |
| 339 | printf( "CRxdescpScheduler::popDescrs DMA %d State- %b done - %d Valid - %b\n",id,State, done, {vld2,vld1,vld0}); |
| 340 | |
| 341 | status = getNextDesc(RxDescSch,type); |
| 342 | if(status == -1) { |
| 343 | popDescrs = -1; // None available |
| 344 | return; |
| 345 | } |
| 346 | setDescType( RxDescSch,type); |
| 347 | State = RxDescState[id]; |
| 348 | if (vld2|vld1|vld0) |
| 349 | done = (State == {vld2,vld1,vld0}); |
| 350 | else { |
| 351 | popDescrs = -1; |
| 352 | return; |
| 353 | } |
| 354 | printf( "CRxdescpScheduler::popDescrs DMA %d State- %b done - %d Valid - %b \n",id,State, done,{vld2,vld1,vld0} ); |
| 355 | } |
| 356 | popDescrs = done; |
| 357 | |
| 358 | } |
| 359 | |
| 360 | |
| 361 | task CRxdescpScheduler::allocJumboPackets ( CRxToken RxToken, integer NoOfDescrNeeded ) { |
| 362 | |
| 363 | integer i; |
| 364 | CRxDescSch RxDescSch,RxDescSchUseForFirstBuf; |
| 365 | integer bytes_remaining; |
| 366 | bit [63:0] packet_end_address; |
| 367 | bit [63:0] address; |
| 368 | bit [63:0] vaddr; |
| 369 | |
| 370 | |
| 371 | bytes_remaining = RxToken.pkt_length + RxToken.header_length; |
| 372 | |
| 373 | |
| 374 | for(i = 0; i < NoOfDescrNeeded; i ++ ) { |
| 375 | RxDescSch = desc_ring.front(); |
| 376 | desc_ring.pop_front(); |
| 377 | address = RxDescSch.getAddress( blk_size, vaddr ); |
| 378 | RxToken.packet_start_address[i] = address; |
| 379 | RxToken.packet_virtaddress[i] = vaddr; |
| 380 | packet_end_address = (bytes_remaining>blk_size) ? (address + blk_size) : ( address + bytes_remaining); |
| 381 | if (bytes_remaining >8) |
| 382 | packet_end_address = packet_end_address -8 ; |
| 383 | RxToken.bytesperchunk[i] = (bytes_remaining>blk_size) ? blk_size : bytes_remaining; |
| 384 | RxToken.packet_end_address[i] = {packet_end_address[63:3],3'h0}; |
| 385 | printf("CRxdescpScheduler::allocJumboPackets: RDMC DEBUG DMA - %d - SCHEDULER ALLOC ADDRESS - %x FOR JUMBO Scatter# - %d, PktType Set to %d Bytes- %d \n",id,RxToken.packet_start_address[i],i,RxToken.pkt_type,RxToken.bytesperchunk[i]); |
| 386 | |
| 387 | bytes_remaining = bytes_remaining - blk_size; |
| 388 | } |
| 389 | RxToken.NoOfScatter = NoOfDescrNeeded; |
| 390 | printf("CRxdescpScheduler::allocJumboPackets: RDMC DEBUG DMA - %d - SCHEDULER ALLOC ADDRESS - %x FOR JUMB NoOfDescrNeeded # - %d, PktType Set to %d Bytes- %d \n",id,RxToken.packet_start_address[NoOfDescrNeeded -1],NoOfDescrNeeded,RxToken.pkt_type,RxToken.bytesperchunk[NoOfDescrNeeded -1]); |
| 391 | |
| 392 | |
| 393 | } |
| 394 | |
| 395 | function integer CRxdescpScheduler::getAddress ( CRxToken RxToken ) { |
| 396 | |
| 397 | |
| 398 | |
| 399 | |
| 400 | |
| 401 | /* |
| 402 | |
| 403 | 1. Check if enough descriptors are available- else get more descriptors |
| 404 | 2. Check the packet size and see which descriptor can be chosen ( among S, M, L ) |
| 405 | 3. Once the descriptor is choosen, look at the bytes allocated to see space is available |
| 406 | else get more. Iterate untill this is done |
| 407 | |
| 408 | |
| 409 | |
| 410 | */ |
| 411 | |
| 412 | integer size; |
| 413 | integer length; |
| 414 | integer type; |
| 415 | integer descp_state; |
| 416 | integer status; |
| 417 | CRxDescSch RxDescSch; |
| 418 | bit [63:0] address,vaddr; |
| 419 | integer offset; |
| 420 | integer largest_available_pkt_buf; |
| 421 | integer jumbo_packet; |
| 422 | integer NoOfDescrNeeded; |
| 423 | integer i; |
| 424 | bit [2:0] State; |
| 425 | |
| 426 | integer done; |
| 427 | |
| 428 | length = RxToken.pkt_length + RxToken.header_length; |
| 429 | printf("RDMC DEBUG In Dma id - %d CRxdescpScheduler::getAddress Length - %d \n", RxToken.dma_num,length); |
| 430 | printf( "RDMC DEBUG In Dma id - %d CRxdescpScheduler::getAddress Current Descriptors poped out - %b \n",id,RxDescState[id]); |
| 431 | |
| 432 | |
| 433 | done = 0; |
| 434 | status = popDescrs(); |
| 435 | printf( "RDMC DEBUG In Dma id - %d CRxdescpScheduler::getAddress Descriptors poped out %b \n",id,RxDescState[id]); |
| 436 | if(status == -1) { |
| 437 | getAddress = -1; // None available -- packet to be dropped |
| 438 | |
| 439 | if(!(vld0|vld1|vld2)) { |
| 440 | RxToken.pkt_type = VALID_DISABLED_DROP_RxPKT; |
| 441 | printf("RDMC DEBUG - Packet to be dropped - All 3 buf_size_valids are disabled\n"); |
| 442 | } |
| 443 | else { |
| 444 | RxToken.pkt_type = RNGFULL_DROP_RxPKT; |
| 445 | printf("RDMC DEBUG - Packet to be dropped - Either Ring is FULL or EMPTY- \n"); |
| 446 | } |
| 447 | |
| 448 | done = 1; |
| 449 | return; |
| 450 | } |
| 451 | |
| 452 | RxToken.pkt_type = GOOD_RxPKT; |
| 453 | RxToken.bufsz = 3; |
| 454 | |
| 455 | // determine if this packet is a jumbo packet |
| 456 | |
| 457 | |
| 458 | largest_available_pkt_buf = vld2 ? bufsz2 : ( |
| 459 | vld1 ? bufsz1: ( |
| 460 | vld0 ? bufsz0: 0) ); |
| 461 | |
| 462 | |
| 463 | if(length > largest_available_pkt_buf ) { |
| 464 | jumbo_packet = 1; |
| 465 | } else jumbo_packet = 0; |
| 466 | |
| 467 | // check if this packet really qualifies as a jumbo packet ie |
| 468 | // how many buffer will this occupy |
| 469 | |
| 470 | if(!done & ( length > 3 * blk_size )) { |
| 471 | // this packet needs to be dropped |
| 472 | // mark this packet bad and exit |
| 473 | RxToken.pkt_type = BUFFSIZE_EXCEEDED_DROP_RxPKT; |
| 474 | RxToken.jumbo_pkt = 1; |
| 475 | done = 1; |
| 476 | getAddress = 0; // None available |
| 477 | return; |
| 478 | } else { |
| 479 | // this is the section to see how the descriptors are to be used |
| 480 | if(jumbo_packet) { |
| 481 | // Find out how many descriptors are needed for this length. It has to be <= 3 |
| 482 | NoOfDescrNeeded = ( length/blk_size ) + ((length%blk_size) ? 1 :0); |
| 483 | if(NoOfDescrNeeded == 0) { |
| 484 | // should not happen -- |
| 485 | printf(" TESTBENCH ERROR -- FIX IT\n"); |
| 486 | } |
| 487 | // Check if at least these many descriptors are available in the ring |
| 488 | // if not drop the packet |
| 489 | if(desc_ring.get_ring_size() >= NoOfDescrNeeded) { |
| 490 | // Now split the packets and start writing into the memory |
| 491 | |
| 492 | // Keep poping the descriptor and allocating into the address untill |
| 493 | // all the bytes are written |
| 494 | |
| 495 | |
| 496 | allocJumboPackets( RxToken , NoOfDescrNeeded); |
| 497 | |
| 498 | // for(i=0;i<RxToken.NoOfScatter;i++) { |
| 499 | // printf(" After allocJumboPackets- endaddress - %x i - %d\n",RxToken.packet_end_address[i],i); |
| 500 | // } |
| 501 | RxToken.pkt_type = GOOD_RxPKT; |
| 502 | RxToken.jumbo_pkt = 1; |
| 503 | getAddress = 1; |
| 504 | done = 1; |
| 505 | return; |
| 506 | |
| 507 | } else { |
| 508 | // packet to be dropped !!!! |
| 509 | RxToken.pkt_type = BUFFSIZE_EXCEEDED_DROP_RxPKT; |
| 510 | RxToken.jumbo_pkt = 1; |
| 511 | getAddress = 0; // None available |
| 512 | done = 1; |
| 513 | return; |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | } |
| 518 | // for(i=0;i<RxToken.NoOfScatter;i++) { |
| 519 | // printf(" in getaddress after allocJumboPackets- endaddress - %x i - %d\n",RxToken.packet_end_address[i],i); |
| 520 | // } |
| 521 | // Here the packet is not a jumbo packet and is within the limits of the pkt_buffer |
| 522 | // scan through available descriptors and choose the address |
| 523 | |
| 524 | if(!done) { |
| 525 | |
| 526 | State = RxDescState[id]; |
| 527 | // printf(" I am here== before small\n"); |
| 528 | if ( (length <= bufsz0) & vld0) { |
| 529 | // check if small descriptor is available |
| 530 | if ( State[0] ) { |
| 531 | address = RxDescSchSMALL.getAddress(length,vaddr); |
| 532 | descp_state = RxDescSchSMALL.checkState(); // Is this descriptor done? |
| 533 | if(descp_state == DESCR_DONE) { |
| 534 | // keep the next descriptor ready |
| 535 | |
| 536 | SetIndexForReclaim(); |
| 537 | RxDescSchSMALL = null; |
| 538 | State[0] = 0; |
| 539 | // status = popDescrs(); |
| 540 | if(status == -1 ) { |
| 541 | printf("CRxdescpScheduler::getAddress:RDMC DEBUG DMA - %d - DONE With SMALL descriptors!! \n",id); |
| 542 | } |
| 543 | } |
| 544 | RxToken.bufsz = 0; |
| 545 | } else { |
| 546 | // Drop this packet |
| 547 | RxToken.pkt_type = RNGFULL_DROP_RxPKT; |
| 548 | } |
| 549 | } else if ( (length <= bufsz1) & vld1) { |
| 550 | // check if Medium descriptor is available |
| 551 | // printf(" I am here== before medium\n"); |
| 552 | if ( State[1] ) { |
| 553 | address = RxDescSchMEDIUM.getAddress(length,vaddr); |
| 554 | descp_state = RxDescSchMEDIUM.checkState(); // Is this descriptor done? |
| 555 | if(descp_state == DESCR_DONE) { |
| 556 | // keep the next descriptor ready |
| 557 | |
| 558 | SetIndexForReclaim(); |
| 559 | RxDescSchMEDIUM = null; |
| 560 | State[1] = 0; |
| 561 | // status = popDescrs(); |
| 562 | if(status != -1) { |
| 563 | printf("CRxdescpScheduler::getAddress:RDMC DEBUG DMA - %d - DONE With MEDIUM the descriptors!! \n",id); |
| 564 | } |
| 565 | } |
| 566 | RxToken.bufsz = 1; |
| 567 | } else { |
| 568 | // Drop this packet |
| 569 | RxToken.pkt_type = RNGFULL_DROP_RxPKT; |
| 570 | } |
| 571 | } else if( (length <= bufsz2) & vld2) { |
| 572 | // check if small descriptor is available |
| 573 | // printf(" I am here== before large\n"); |
| 574 | if ( State[2] ) { |
| 575 | address = RxDescSchLARGE.getAddress(length,vaddr); |
| 576 | descp_state = RxDescSchLARGE.checkState(); // Is this descriptor done? |
| 577 | if(descp_state == DESCR_DONE) { |
| 578 | // keep the next descriptor ready |
| 579 | |
| 580 | SetIndexForReclaim(); |
| 581 | RxDescSchLARGE = null; |
| 582 | State[2] = 0; |
| 583 | // status = popDescrs(); |
| 584 | if(status != -1) { |
| 585 | printf("CRxdescpScheduler::getAddress:RDMC DEBUG DMA - %d - DONE With LARGE the descriptors!! \n"); |
| 586 | } |
| 587 | } |
| 588 | RxToken.bufsz = 2; |
| 589 | } else { |
| 590 | // Drop this packet |
| 591 | RxToken.pkt_type = RNGFULL_DROP_RxPKT; |
| 592 | } |
| 593 | } else { |
| 594 | // This is what none of the descriptors are available |
| 595 | // Set packet to be dropped |
| 596 | getAddress = -1; // None available |
| 597 | done = 1; |
| 598 | RxToken.pkt_type = RNGFULL_DROP_RxPKT; |
| 599 | } |
| 600 | |
| 601 | RxToken.packet_start_address[0] = address; |
| 602 | RxToken.packet_virtaddress[0] = vaddr; |
| 603 | address = address + length -8 ; // this needs to be 64 bit aligned for SIU Model's memory? |
| 604 | RxToken.packet_end_address[0] = {address[63:3],3'h0} ; |
| 605 | printf("CRxdescpScheduler::getAddress DMA - %d DEBUG in getaddress before exit- endaddress - %x \n",id,address); |
| 606 | RxToken.NoOfScatter = 1; |
| 607 | RxToken.bytesperchunk[0] = length; |
| 608 | RxDescState[id] = State; |
| 609 | } |
| 610 | |
| 611 | // for(i=0;i<RxToken.NoOfScatter;i++) { |
| 612 | // printf(" in getaddress before exit- endaddress - %x i - %d\n",RxToken.packet_end_address[i],i); |
| 613 | // } |
| 614 | |
| 615 | } |