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