1 /****************************************************************************** 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ******************************************************************************/ 22 /* $FreeBSD$ */ 23 /****************************************************************************** 24 This program is part of PMC-Sierra initiator/target device driver. 25 The functions here are commonly used by different type of drivers that support 26 PMC-Sierra storage network initiator hardware. 27 ******************************************************************************/ 28 29 30 MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc", 31 "allocated from agtiapi_MemAlloc as simple malloc case" ); 32 33 34 /***************************************************************************** 35 agtiapi_DelayMSec() 36 37 Purpose: 38 Busy wait for number of mili-seconds 39 Parameters: 40 U32 MiliSeconds (IN) Number of mili-seconds to delay 41 Return: 42 Note: 43 *****************************************************************************/ 44 STATIC void agtiapi_DelayMSec( U32 MiliSeconds ) 45 { 46 DELAY(MiliSeconds * 1000); // DELAY takes in usecs 47 } 48 49 /****************************************************************************** 50 agtiapi_typhAlloc() 51 Purpose: 52 Preallocation handling 53 Allocate DMA memory which will be divided among proper pointers in 54 agtiapi_MemAlloc() later 55 Parameters: 56 ag_card_info_t *thisCardInst (IN) 57 Return: 58 AGTIAPI_SUCCESS - success 59 AGTIAPI_FAIL - fail 60 ******************************************************************************/ 61 STATIC agBOOLEAN agtiapi_typhAlloc( ag_card_info_t *thisCardInst ) 62 { 63 struct agtiapi_softc *pmsc = thisCardInst->pCard; 64 int wait = 0; 65 66 if( bus_dma_tag_create( agNULL, // parent 67 32, // alignment 68 0, // boundary 69 BUS_SPACE_MAXADDR, // lowaddr 70 BUS_SPACE_MAXADDR, // highaddr 71 NULL, // filter 72 NULL, // filterarg 73 pmsc->typhn, // maxsize (size) 74 1, // number of segments 75 pmsc->typhn, // maxsegsize 76 0, // flags 77 NULL, // lockfunc 78 NULL, // lockarg 79 &pmsc->typh_dmat ) ) { 80 printf( "agtiapi_typhAlloc: Can't create no-cache mem tag\n" ); 81 return AGTIAPI_FAIL; 82 } 83 84 if( bus_dmamem_alloc( pmsc->typh_dmat, 85 &pmsc->typh_mem, 86 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, 87 &pmsc->typh_mapp ) ) { 88 printf( "agtiapi_typhAlloc: Cannot allocate cache mem %d\n", 89 pmsc->typhn ); 90 return AGTIAPI_FAIL; 91 } 92 93 if ( bus_dmamap_load( pmsc->typh_dmat, 94 pmsc->typh_mapp, 95 pmsc->typh_mem, 96 pmsc->typhn, 97 agtiapi_MemoryCB, // try reuse of CB for same goal 98 &pmsc->typh_busaddr, 99 0 ) || !pmsc->typh_busaddr ) { 100 for( ; wait < 20; wait++ ) { 101 if( pmsc->typh_busaddr ) break; 102 DELAY( 50000 ); 103 } 104 105 if( ! pmsc->typh_busaddr ) { 106 printf( "agtiapi_typhAlloc: cache mem won't load %d\n", 107 pmsc->typhn ); 108 return AGTIAPI_FAIL; 109 } 110 } 111 112 pmsc->typhIdx = 0; 113 pmsc->tyPhsIx = 0; 114 115 return AGTIAPI_SUCCESS; 116 } 117 118 119 /****************************************************************************** 120 agtiapi_InitResource() 121 Purpose: 122 Mapping PCI memory space 123 Allocate and initialize per card based resource 124 Parameters: 125 ag_card_info_t *pCardInfo (IN) 126 Return: 127 AGTIAPI_SUCCESS - success 128 AGTIAPI_FAIL - fail 129 Note: 130 ******************************************************************************/ 131 STATIC agBOOLEAN agtiapi_InitResource( ag_card_info_t *thisCardInst ) 132 { 133 struct agtiapi_softc *pmsc = thisCardInst->pCard; 134 device_t devx = thisCardInst->pPCIDev; 135 136 //AGTIAPI_PRINTK( "agtiapi_InitResource: begin; pointer values %p / %p \n", 137 // devx, thisCardInst ); 138 // no IO mapped card implementation, we'll implement memory mapping 139 140 if( agtiapi_typhAlloc( thisCardInst ) == AGTIAPI_FAIL ) { 141 printf( "agtiapi_InitResource: failed call to agtiapi_typhAlloc \n" ); 142 return AGTIAPI_FAIL; 143 } 144 145 AGTIAPI_PRINTK( "agtiapi_InitResource: dma alloc MemSpan %p -- %p\n", 146 (void*) pmsc->typh_busaddr, 147 (void*) ( (U32_64)pmsc->typh_busaddr + pmsc->typhn ) ); 148 149 // logical BARs for SPC: 150 // bar 0 and 1 - logical BAR0 151 // bar 2 and 3 - logical BAR1 152 // bar4 - logical BAR2 153 // bar5 - logical BAR3 154 // Skiping the assignments for bar 1 and bar 3 (making bar 0, 2 64-bit): 155 U32 bar; 156 U32 lBar = 0; // logicalBar 157 for (bar = 0; bar < PCI_NUMBER_BARS; bar++) { 158 if ((bar==1) || (bar==3)) 159 continue; 160 thisCardInst->pciMemBaseRIDSpc[lBar] = PCIR_BAR(bar); 161 thisCardInst->pciMemBaseRscSpc[lBar] = 162 bus_alloc_resource_any( devx, 163 SYS_RES_MEMORY, 164 &(thisCardInst->pciMemBaseRIDSpc[lBar]), 165 RF_ACTIVE ); 166 AGTIAPI_PRINTK( "agtiapi_InitResource: bus_alloc_resource_any rtn %p \n", 167 thisCardInst->pciMemBaseRscSpc[lBar] ); 168 if ( thisCardInst->pciMemBaseRscSpc[lBar] != NULL ) { 169 thisCardInst->pciMemVirtAddrSpc[lBar] = 170 (caddr_t)rman_get_virtual( 171 thisCardInst->pciMemBaseRscSpc[lBar] ); 172 thisCardInst->pciMemBaseSpc[lBar] = 173 bus_get_resource_start( devx, SYS_RES_MEMORY, 174 thisCardInst->pciMemBaseRIDSpc[lBar]); 175 thisCardInst->pciMemSizeSpc[lBar] = 176 bus_get_resource_count( devx, SYS_RES_MEMORY, 177 thisCardInst->pciMemBaseRIDSpc[lBar] ); 178 AGTIAPI_PRINTK( "agtiapi_InitResource: PCI: bar %d, lBar %d " 179 "VirtAddr=%lx, len=%d\n", bar, lBar, 180 (long unsigned int)thisCardInst->pciMemVirtAddrSpc[lBar], 181 thisCardInst->pciMemSizeSpc[lBar] ); 182 } 183 else { 184 thisCardInst->pciMemVirtAddrSpc[lBar] = 0; 185 thisCardInst->pciMemBaseSpc[lBar] = 0; 186 thisCardInst->pciMemSizeSpc[lBar] = 0; 187 } 188 lBar++; 189 } 190 thisCardInst->pciMemVirtAddr = thisCardInst->pciMemVirtAddrSpc[0]; 191 thisCardInst->pciMemSize = thisCardInst->pciMemSizeSpc[0]; 192 thisCardInst->pciMemBase = thisCardInst->pciMemBaseSpc[0]; 193 194 // Allocate all TI data structure required resources. 195 // tiLoLevelResource 196 U32 numVal; 197 ag_resource_info_t *pRscInfo; 198 pRscInfo = &thisCardInst->tiRscInfo; 199 pRscInfo->tiLoLevelResource.loLevelOption.pciFunctionNumber = 200 pci_get_function( devx ); 201 202 struct timeval tv; 203 tv.tv_sec = 1; 204 tv.tv_usec = 0; 205 int ticksPerSec; 206 ticksPerSec = tvtohz( &tv ); 207 int uSecPerTick = 1000000/USEC_PER_TICK; 208 209 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) { 210 //AGTIAPI_INIT("agtiapi_InitResource: loLevelMem count = %d\n", 211 // pRscInfo->tiLoLevelResource.loLevelMem.count); 212 213 // adjust tick value to meet Linux requirement 214 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick = uSecPerTick; 215 AGTIAPI_PRINTK( "agtiapi_InitResource: " 216 "pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick" 217 " 0x%x\n", 218 pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick ); 219 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count; 220 numVal++ ) { 221 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength == 222 0 ) { 223 AGTIAPI_PRINTK("agtiapi_InitResource: skip ZERO %d\n", numVal); 224 continue; 225 } 226 227 // check for 64 bit alignment 228 if ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment < 229 AGTIAPI_64BIT_ALIGN ) { 230 AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal); 231 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment = 232 AGTIAPI_64BIT_ALIGN; 233 } 234 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 235 & (BIT(0) | BIT(1))) == TI_DMA_MEM) || 236 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 237 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) { 238 if ( thisCardInst->dmaIndex >= 239 sizeof(thisCardInst->tiDmaMem) / 240 sizeof(thisCardInst->tiDmaMem[0]) ) { 241 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", 242 thisCardInst->dmaIndex ); 243 return AGTIAPI_FAIL; 244 } 245 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type = 246 #ifdef CACHED_DMA 247 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 248 & (BIT(0) | BIT(1)); 249 #else 250 TI_DMA_MEM; 251 #endif 252 if( agtiapi_MemAlloc( thisCardInst, 253 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr, 254 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaPhysAddr, 255 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr, 256 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal]. 257 physAddrUpper, 258 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal]. 259 physAddrLower, 260 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength, 261 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type, 262 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment) 263 != AGTIAPI_SUCCESS ) { 264 return AGTIAPI_FAIL; 265 } 266 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize = 267 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength; 268 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d dmaIndex=%d DMA virt" 269 // " %p, phys 0x%x, length %d align %d\n", 270 // numVal, pCardInfo->dmaIndex, 271 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr, 272 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].physAddrLower, 273 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength, 274 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment); 275 thisCardInst->dmaIndex++; 276 } 277 else if ( (pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type & 278 (BIT(0) | BIT(1))) == TI_CACHED_MEM) { 279 if (thisCardInst->cacheIndex >= 280 sizeof(thisCardInst->tiCachedMem) / 281 sizeof(thisCardInst->tiCachedMem[0])) { 282 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", 283 thisCardInst->cacheIndex ); 284 return AGTIAPI_FAIL; 285 } 286 if ( agtiapi_MemAlloc( thisCardInst, 287 &thisCardInst->tiCachedMem[thisCardInst->cacheIndex], 288 (vm_paddr_t *)agNULL, 289 &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr, 290 (U32 *)agNULL, 291 (U32 *)agNULL, 292 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength, 293 TI_CACHED_MEM, 294 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment) 295 != AGTIAPI_SUCCESS ) { 296 return AGTIAPI_FAIL; 297 } 298 299 //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d cacheIndex=%d CACHED " 300 // "vaddr %p / %p, length %d align %d\n", 301 // numVal, pCardInfo->cacheIndex, 302 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex], 303 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr, 304 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength, 305 // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment); 306 307 thisCardInst->cacheIndex++; 308 } 309 else if ( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 310 & (BIT(0) | BIT(1))) == TI_DMA_MEM_CHIP)) { 311 // not expecting this case, print warning that should get attention 312 printf( "RED ALARM: we need a BAR for TI_DMA_MEM_CHIP, ignoring!" ); 313 } 314 else { 315 printf( "agtiapi_InitResource: Unknown required memory type %d " 316 "ERROR!\n", 317 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type); 318 return AGTIAPI_FAIL; 319 } 320 } 321 } 322 // end: TI data structure resources ... 323 324 // begin: tiInitiatorResource 325 if ( pmsc->flags & AGTIAPI_INITIATOR ) { 326 if ( pRscInfo->tiInitiatorResource.initiatorMem.count != 0 ) { 327 //AGTIAPI_INIT("agtiapi_InitResource: initiatorMem count = %d\n", 328 // pRscInfo->tiInitiatorResource.initiatorMem.count); 329 numVal = 330 (U32)( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick 331 / uSecPerTick ); 332 if( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick 333 % uSecPerTick > 0 ) 334 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick = 335 (numVal + 1) * uSecPerTick; 336 else 337 pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick = 338 numVal * uSecPerTick; 339 for ( numVal = 0; 340 numVal < pRscInfo->tiInitiatorResource.initiatorMem.count; 341 numVal++ ) { 342 // check for 64 bit alignment 343 if( pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 344 alignment < AGTIAPI_64BIT_ALIGN ) { 345 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 346 alignment = AGTIAPI_64BIT_ALIGN; 347 } 348 if( thisCardInst->cacheIndex >= 349 sizeof( thisCardInst->tiCachedMem) / 350 sizeof( thisCardInst->tiCachedMem[0])) { 351 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", 352 thisCardInst->cacheIndex ); 353 return AGTIAPI_FAIL; 354 } 355 // initiator memory is cached, no check is needed 356 if( agtiapi_MemAlloc( thisCardInst, 357 (void *)&thisCardInst->tiCachedMem[thisCardInst->cacheIndex], 358 (vm_paddr_t *)agNULL, 359 &pRscInfo->tiInitiatorResource.initiatorMem. 360 tdCachedMem[numVal].virtPtr, 361 (U32 *)agNULL, 362 (U32 *)agNULL, 363 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 364 totalLength, 365 TI_CACHED_MEM, 366 pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 367 alignment) 368 != AGTIAPI_SUCCESS) { 369 return AGTIAPI_FAIL; 370 } 371 // AGTIAPI_INIT("agtiapi_InitResource: IniMem %d cacheIndex=%d CACHED " 372 // "vaddr %p / %p, length %d align 0x%x\n", 373 // numVal, 374 // pCardInfo->cacheIndex, 375 // pCardInfo->tiCachedMem[pCardInfo->cacheIndex], 376 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 377 // virtPtr, 378 //pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 379 // totalLength, 380 // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal]. 381 // alignment); 382 thisCardInst->cacheIndex++; 383 } 384 } 385 } 386 // end: tiInitiatorResource 387 388 // begin: tiTdSharedMem 389 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) { 390 // check for 64 bit alignment 391 if( pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment < 392 AGTIAPI_64BIT_ALIGN ) { 393 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment = AGTIAPI_64BIT_ALIGN; 394 } 395 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1))) 396 == TI_DMA_MEM ) { 397 if( thisCardInst->dmaIndex >= 398 sizeof(thisCardInst->tiDmaMem) / sizeof(thisCardInst->tiDmaMem[0]) ) { 399 AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", thisCardInst->dmaIndex); 400 return AGTIAPI_FAIL; 401 } 402 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst-> 403 tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr, 404 &thisCardInst->tiDmaMem[thisCardInst->dmaIndex]. 405 dmaPhysAddr, 406 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 407 &pRscInfo->tiSharedMem.tdSharedCachedMem1. 408 physAddrUpper, 409 &pRscInfo->tiSharedMem.tdSharedCachedMem1. 410 physAddrLower, 411 pRscInfo->tiSharedMem.tdSharedCachedMem1. 412 totalLength, 413 TI_DMA_MEM, 414 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment) 415 != AGTIAPI_SUCCESS ) 416 return AGTIAPI_FAIL; 417 418 thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize = 419 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength + 420 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment; 421 // printf( "agtiapi_InitResource: SharedMem DmaIndex=%d DMA " 422 // "virt %p / %p, phys 0x%x, align %d\n", 423 // thisCardInst->dmaIndex, 424 // thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr, 425 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 426 // pRscInfo->tiSharedMem.tdSharedCachedMem1.physAddrLower, 427 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment); 428 thisCardInst->dmaIndex++; 429 } 430 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & 431 (BIT(0) | BIT(1))) 432 == TI_CACHED_MEM ) { 433 if( thisCardInst->cacheIndex >= 434 sizeof(thisCardInst->tiCachedMem) / 435 sizeof(thisCardInst->tiCachedMem[0]) ) { 436 AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", thisCardInst->cacheIndex); 437 return AGTIAPI_FAIL; 438 } 439 if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst-> 440 tiCachedMem[thisCardInst->cacheIndex], 441 (vm_paddr_t *)agNULL, 442 &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 443 (U32 *)agNULL, 444 (U32 *)agNULL, 445 pRscInfo-> 446 tiSharedMem.tdSharedCachedMem1.totalLength, 447 TI_CACHED_MEM, 448 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment) 449 != AGTIAPI_SUCCESS ) 450 return AGTIAPI_FAIL; 451 // printf( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED " 452 // "vaddr %p / %p, length %d align 0x%x\n", 453 // thisCardInst->cacheIndex, 454 // thisCardInst->tiCachedMem[thisCardInst->cacheIndex], 455 // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 456 // pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength, 457 // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment); 458 AGTIAPI_PRINTK( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED " 459 "vaddr %p / %p, length %d align 0x%x\n", 460 thisCardInst->cacheIndex, 461 thisCardInst->tiCachedMem[thisCardInst->cacheIndex], 462 pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr, 463 pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength, 464 pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment ); 465 thisCardInst->cacheIndex++; 466 } 467 else { 468 AGTIAPI_PRINTK( "agtiapi_InitResource: " 469 "Unknown required memory type ERROR!\n" ); 470 return AGTIAPI_FAIL; 471 } 472 } 473 // end: tiTdSharedMem 474 DELAY( 200000 ); // or use AGTIAPI_INIT_MDELAY(200); 475 return AGTIAPI_SUCCESS; 476 } // agtiapi_InitResource() ends here 477 478 /****************************************************************************** 479 agtiapi_ScopeDMARes() 480 Purpose: 481 Determine the amount of DMA (non-cache) memory resources which will be 482 required for a card ( and necessarily allocated in agtiapi_InitResource() ) 483 Parameters: 484 ag_card_info_t *thisCardInst (IN) 485 Return: 486 size of DMA memory which call to agtiapi_InitResource() will consume 487 Note: 488 this funcion mirrors the flow of agtiapi_InitResource() 489 results are stored in agtiapi_softc fields 490 ******************************************************************************/ 491 STATIC int agtiapi_ScopeDMARes( ag_card_info_t *thisCardInst ) 492 { 493 struct agtiapi_softc *pmsc = thisCardInst->pCard; 494 U32 lAllMem = 0; // total memory count; typhn 495 U32 lTmpAlign, lTmpType, lTmpLen; 496 497 // tiLoLevelResource 498 U32 numVal; 499 ag_resource_info_t *pRscInfo; 500 pRscInfo = &thisCardInst->tiRscInfo; 501 502 if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) { 503 for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count; 504 numVal++ ) { 505 if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength == 506 0 ) { 507 printf( "agtiapi_ScopeDMARes: skip ZERO %d\n", numVal ); 508 continue; 509 } 510 // check for 64 bit alignment 511 lTmpAlign = pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment; 512 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) { 513 AGTIAPI_PRINTK("agtiapi_ScopeDMARes: set ALIGN %d\n", numVal); 514 //pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment = 515 lTmpAlign = AGTIAPI_64BIT_ALIGN; 516 } 517 if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 518 & (BIT(0) | BIT(1))) == TI_DMA_MEM) || 519 ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 520 & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) { 521 //thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type = 522 lTmpType = 523 #ifdef CACHED_DMA 524 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type 525 & (BIT(0) | BIT(1)); 526 #else 527 TI_DMA_MEM; 528 #endif 529 if( lTmpType == TI_DMA_MEM ) { 530 lTmpLen = 531 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength; 532 lAllMem += lTmpLen + lTmpAlign; 533 } 534 //printf( "agtiapi_ScopeDMARes: call 1 0x%x\n", lAllMem ); 535 } 536 else if ( ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type & 537 (BIT(0) | BIT(1)) ) == TI_CACHED_MEM ) { 538 // these are not the droids we're looking for 539 if( thisCardInst->cacheIndex >= 540 sizeof(thisCardInst->tiCachedMem) / 541 sizeof(thisCardInst->tiCachedMem[0]) ) { 542 AGTIAPI_PRINTK( "agtiapi_ScopeDMARes: Invalid cacheIndex %d ERROR\n", 543 thisCardInst->cacheIndex ); 544 return lAllMem; 545 } 546 } 547 else { 548 printf( "agtiapi_ScopeDMARes: Unknown required memory type %d " 549 "ERROR!\n", 550 pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type ); 551 return lAllMem; 552 } 553 } 554 } 555 // end: TI data structure resources ... 556 557 // nothing for tiInitiatorResource 558 559 // begin: tiTdSharedMem 560 if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) { 561 // check for 64 bit alignment 562 lTmpAlign = pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment; 563 if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) { 564 //pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment=AGTIAPI_64BIT_ALIGN; 565 lTmpAlign = AGTIAPI_64BIT_ALIGN; 566 } 567 if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1))) 568 == TI_DMA_MEM ) { 569 lTmpLen = pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength; 570 lAllMem += lTmpLen + lTmpAlign; 571 // printf( "agtiapi_ScopeDMARes: call 4D 0x%x\n", lAllMem ); 572 } 573 else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & 574 (BIT(0) | BIT(1))) 575 != TI_CACHED_MEM ) { 576 printf( "agtiapi_ScopeDMARes: Unknown required memory type ERROR!\n" ); 577 } 578 } 579 // end: tiTdSharedMem 580 581 pmsc->typhn = lAllMem; 582 return lAllMem; 583 584 } // agtiapi_ScopeDMARes() ends here 585 586 587 STATIC void agtiapi_ReleasePCIMem( ag_card_info_t *pCardInfo ) { 588 U32 bar = 0; 589 int tmpRid = 0; 590 struct resource *tmpRsc = NULL; 591 device_t dev; 592 dev = pCardInfo->pPCIDev; 593 594 for (bar=0; bar < PCI_NUMBER_BARS; bar++) { // clean up PCI resource 595 tmpRid = pCardInfo->pciMemBaseRIDSpc[bar]; 596 tmpRsc = pCardInfo->pciMemBaseRscSpc[bar]; 597 if (tmpRsc != NULL) { // Release PCI resources 598 bus_release_resource( dev, SYS_RES_MEMORY, tmpRid, tmpRsc ); 599 } 600 } 601 return; 602 } 603 604 605 /****************************************************************************** 606 agtiapi_MemAlloc() 607 Purpose: 608 Handle various memory allocation requests. 609 Parameters: 610 ag_card_info_t *pCardInfo (IN) Pointer to card info structure 611 void **VirtAlloc (OUT) Allocated memory virtual address 612 dma_addr_t *pDmaAddr (OUT) Allocated dma memory physical address 613 void **VirtAddr (OUT) Aligned memory virtual address 614 U32 *pPhysAddrUp (OUT) Allocated memory physical upper 32 bits 615 U32 *pPhysAddrLow (OUT) Allocated memory physical lower 32 bits 616 U32 MemSize (IN) Allocated memory size 617 U32 Type (IN) Type of memory required 618 U32 Align (IN) Required memory alignment 619 Return: 620 AGTIAPI_SUCCESS - success 621 AGTIAPI_FAIL - fail 622 ******************************************************************************/ 623 STATIC agBOOLEAN agtiapi_MemAlloc( ag_card_info_t *thisCardInst, 624 void **VirtAlloc, 625 vm_paddr_t *pDmaAddr, 626 void **VirtAddr, 627 U32 *pPhysAddrUp, 628 U32 *pPhysAddrLow, 629 U32 MemSize, 630 U32 Type, 631 U32 Align ) 632 { 633 U32_64 alignOffset = 0; 634 if( Align ) 635 alignOffset = Align - 1; 636 637 // printf( "agtiapi_MemAlloc: debug find mem TYPE, %d vs. CACHE %d, DMA %d \n", 638 // ( Type & ( BIT(0) | BIT(1) ) ), TI_CACHED_MEM, TI_DMA_MEM ); 639 640 if ((Type & (BIT(0) | BIT(1))) == TI_CACHED_MEM) { 641 *VirtAlloc = malloc( MemSize + Align, M_PMC_MMAL, M_ZERO | M_NOWAIT ); 642 *VirtAddr = (void *)(((U32_64)*VirtAlloc + alignOffset) & ~alignOffset); 643 } 644 else { 645 struct agtiapi_softc *pmsc = thisCardInst->pCard; // get card reference 646 U32 residAlign = 0; 647 // find virt index value 648 *VirtAlloc = (void*)( (U64)pmsc->typh_mem + pmsc->typhIdx ); 649 *VirtAddr = (void *)( ( (U32_64)*VirtAlloc + alignOffset) & ~alignOffset ); 650 if( *VirtAddr != *VirtAlloc ) 651 residAlign = (U64)*VirtAddr - (U64)*VirtAlloc; // find alignment needed 652 pmsc->typhIdx += residAlign + MemSize; // update index 653 residAlign = 0; // reset variable for reuse 654 // find phys index val 655 pDmaAddr = (vm_paddr_t*)( (U64)pmsc->typh_busaddr + pmsc->tyPhsIx ); 656 vm_paddr_t *lPhysAligned = 657 (vm_paddr_t*)( ( (U64)pDmaAddr + alignOffset ) & ~alignOffset ); 658 if( lPhysAligned != pDmaAddr ) 659 residAlign = (U64)lPhysAligned - (U64)pDmaAddr; // find alignment needed 660 pmsc->tyPhsIx += residAlign + MemSize; // update index 661 *pPhysAddrUp = HIGH_32_BITS( (U64)lPhysAligned ); 662 *pPhysAddrLow = LOW_32_BITS( (U64)lPhysAligned ); 663 //printf( "agtiapi_MemAlloc: physIx 0x%x size 0x%x resid:0x%x " 664 // "addr:0x%p addrAligned:0x%p Align:0x%x\n", 665 // pmsc->tyPhsIx, MemSize, residAlign, pDmaAddr, lPhysAligned, 666 // Align ); 667 } 668 if ( !*VirtAlloc ) { 669 AGTIAPI_PRINTK( "agtiapi_MemAlloc memory allocation ERROR x%x\n", 670 Type & (U32)(BIT(0) | BIT(1))); 671 return AGTIAPI_FAIL; 672 } 673 return AGTIAPI_SUCCESS; 674 } 675 676 677 /****************************************************************************** 678 agtiapi_MemFree() 679 680 Purpose: 681 Free agtiapi_MemAlloc() allocated memory 682 Parameters: 683 ag_card_info_t *pCardInfo (IN) Pointer to card info structure 684 Return: none 685 ******************************************************************************/ 686 STATIC void agtiapi_MemFree( ag_card_info_t *pCardInfo ) 687 { 688 U32 idx; 689 690 // release memory vs. alloc in agtiapi_MemAlloc; cached case 691 for( idx = 0; idx < pCardInfo->cacheIndex; idx++ ) { 692 if( pCardInfo->tiCachedMem[idx] ) { 693 free( pCardInfo->tiCachedMem[idx], M_PMC_MMAL ); 694 AGTIAPI_PRINTK( "agtiapi_MemFree: TI_CACHED_MEM Mem[%d] %p\n", 695 idx, pCardInfo->tiCachedMem[idx] ); 696 } 697 } 698 699 // release memory vs. alloc in agtiapi_typhAlloc; used in agtiapi_MemAlloc 700 struct agtiapi_softc *pmsc = pCardInfo->pCard; // get card reference 701 if( pmsc->typh_busaddr != 0 ) { 702 bus_dmamap_unload( pmsc->typh_dmat, pmsc->typh_mapp ); 703 } 704 if( pmsc->typh_mem != NULL ) { 705 bus_dmamem_free( pmsc->typh_dmat, pmsc->typh_mem, pmsc->typh_mapp ); 706 } 707 if( pmsc->typh_dmat != NULL ) { 708 bus_dma_tag_destroy( pmsc->typh_dmat ); 709 } 710 //reference values: 711 // pCardInfo->dmaIndex 712 // pCardInfo->tiDmaMem[idx].dmaVirtAddr 713 // pCardInfo->tiDmaMem[idx].memSize 714 // pCardInfo->tiDmaMem[idx].type == TI_CACHED_DMA_MEM 715 // pCardInfo->tiDmaMem[idx].type == TI_DMA_MEM 716 717 /* This code is redundant. Commenting out for now to maintain a placekeeper. 718 Free actually takes place in agtiapi_ReleaseHBA as calls on osti_dmat. dm 719 // release possible lower layer dynamic memory 720 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) { 721 if( pCardInfo->dynamicMem[idx].dmaVirtAddr != NULL ) { 722 printf( "agtiapi_MemFree: dynMem[%d] virtAddr" 723 " %p / %lx size: %d\n", 724 idx, pCardInfo->dynamicMem[idx].dmaVirtAddr, 725 (long unsigned int)pCardInfo->dynamicMem[idx].dmaPhysAddr, 726 pCardInfo->dynamicMem[idx].memSize ); 727 if( pCardInfo->dynamicMem[idx].dmaPhysAddr ) 728 some form of free call would go here ( 729 pCardInfo->dynamicMem[idx].dmaVirtAddr, 730 pCardInfo->dynamicMem[idx].memSize, ... ); 731 else 732 free case for cacheable memory would go here 733 } 734 } 735 */ 736 return; 737 } 738 739 /****************************************************************************** 740 agtiapi_ProbeCard() 741 Purpose: 742 sets thisCardInst->cardIdIndex to structure variant consistent with card. 743 ag_card_type[idx].vendorId we already determined is PCI_VENDOR_ID_PMC_SIERRA. 744 Parameters: 745 device_t dev, 746 ag_card_info_t *thisCardInst, 747 int thisCard 748 Return: 749 0 - success 750 other values are not as good 751 Note: 752 This implementation is tailored to FreeBSD in alignment with the probe 753 functionality of the FreeBSD environment. 754 ******************************************************************************/ 755 STATIC int agtiapi_ProbeCard( device_t dev, 756 ag_card_info_t *thisCardInst, 757 int thisCard ) 758 { 759 int idx; 760 u_int16_t agtiapi_vendor; // PCI vendor ID 761 u_int16_t agtiapi_dev; // PCI device ID 762 AGTIAPI_PRINTK("agtiapi_ProbeCard: start\n"); 763 764 agtiapi_vendor = pci_get_vendor( dev ); // get PCI vendor ID 765 agtiapi_dev = pci_get_device( dev ); // get PCI device ID 766 for( idx = 0; idx < COUNT(ag_card_type); idx++ ) 767 { 768 if ( ag_card_type[idx].deviceId == agtiapi_dev && 769 ag_card_type[idx].vendorId == agtiapi_vendor) 770 { // device ID match 771 memset( (void *)&agCardInfoList[ thisCard ], 0, 772 sizeof(ag_card_info_t) ); 773 thisCardInst->cardIdIndex = idx; 774 thisCardInst->pPCIDev = dev; 775 thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex; 776 thisCardInst->cardID = 777 pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr 778 AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n", 779 thisCardInst->pPCIDev, thisCardInst ); 780 device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] ); 781 return 0; 782 } 783 } 784 return 1; 785 } 786 787