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 /** \file 24 * 25 * $RCSfile: ttdsmp.c,v $ 26 * 27 * Copyright 2006 PMC-Sierra, Inc. 28 * 29 * $Author: hasungwo $ 30 * $Revision: 112322 $ 31 * $Date: 2012-01-04 19:23:42 -0800 (Wed, 04 Jan 2012) $ 32 * 33 * This file contains initiator IO related functions in TD layer 34 * 35 */ 36 #include <osenv.h> 37 #include <ostypes.h> 38 #include <osdebug.h> 39 40 #include <sa.h> 41 #include <saapi.h> 42 #include <saosapi.h> 43 44 #include <titypes.h> 45 #include <ostiapi.h> 46 #include <tiapi.h> 47 #include <tiglobal.h> 48 49 #include <tdtypes.h> 50 #include <osstring.h> 51 #include <tdutil.h> 52 53 #ifdef INITIATOR_DRIVER 54 #include <itdtypes.h> 55 #include <itddefs.h> 56 #include <itdglobl.h> 57 #endif 58 59 #ifdef TARGET_DRIVER 60 #include "ttdglobl.h" 61 #include "ttdtxchg.h" 62 #include "ttdtypes.h" 63 #endif 64 65 #include <tdsatypes.h> 66 #include <tdproto.h> 67 68 osGLOBAL void 69 ttdsaSMPCompleted( 70 agsaRoot_t *agRoot, 71 agsaIORequest_t *agIORequest, 72 bit32 agIOStatus, 73 //agsaSMPFrameHeader_t *agFrameHeader, //(TP) 74 bit32 agIOInfoLen, 75 agsaFrameHandle_t agFrameHandle 76 ) 77 { 78 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 79 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 80 ttdsaXchg_t *ttdsaXchg = (ttdsaXchg_t *)agIORequest->osData; 81 82 /* cf) ttdsaIOCompleted */ 83 TI_DBG1(("ttdsaSMPCompleted: start\n")); 84 if (tiRoot == agNULL) 85 { 86 TI_DBG1(("ttdsaSMPCompleted: tiRoot is NULL, wrong\n")); 87 return; 88 } 89 90 if (ttdsaXchg == agNULL) 91 { 92 TI_DBG1(("ttdsaSMPCompleted: ttdsaXchg is NULL, wrong\n")); 93 return; 94 } 95 96 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg); 97 98 99 /* to-do: no callback to OS layer */ 100 return; 101 } 102 103 osGLOBAL void 104 ttdsaNotSupportRespSend( 105 agsaRoot_t *agRoot, 106 agsaDevHandle_t *agDevHandle, 107 ttdsaXchg_t *ttdsaXchg, 108 bit8 smpfn 109 ) 110 { 111 bit32 agRequestType; 112 agsaSASRequestBody_t *agSASRequestBody; 113 agsaSMPFrame_t *agSMPFrame; 114 agsaIORequest_t *agIORequest; 115 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/ 116 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/ 117 118 TI_DBG1(("ttdsaNotSupportSend:\n")); 119 agRequestType = AGSA_SMP_TGT_RESPONSE; 120 121 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest); 122 123 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody); 124 agSMPFrame = &(agSASRequestBody->smpFrame); 125 126 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/ 127 128 /* smp header */ /*(TP)*/ 129 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 130 tdSMPFrameHeader.smpFunction = smpfn; 131 tdSMPFrameHeader.smpFunctionResult = UNKNOWN_SMP_FUNCTION; /* unknown smp */ 132 tdSMPFrameHeader.smpReserved = 0; 133 134 /*old*/ 135 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 136 //agSMPFrame->frameHeader.smpFunction = smpfn; 137 //agSMPFrame->frameHeader.smpFunctionResult = UNKNOWN_SMP_FUNCTION; /* unknown smp */ 138 139 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*TP)*/ 140 141 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/ 142 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper; 143 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower; 144 agSMPFrame->outFrameLen = 0; /* no smp response payload */ 145 146 //agSMPFrame->phyId = ttdsaXchg->SMPphyId; 147 148 #ifdef RPM_SOC 149 /* not work yet because of high priority q */ 150 saSMPStart( 151 agRoot, 152 agIORequest, 153 agDevHandle, 154 agRequestType, 155 agSASRequestBody, 156 &ossaSMPCompleted 157 ); 158 #else 159 saSMPStart( 160 agRoot, 161 agIORequest, 162 0, /* queue number */ 163 agDevHandle, 164 agRequestType, 165 agSASRequestBody, 166 &ossaSMPCompleted 167 ); 168 #endif 169 return; 170 } 171 172 osGLOBAL void 173 ttdsaDiscoverRespSend( 174 agsaRoot_t *agRoot, 175 agsaDevHandle_t *agDevHandle, 176 ttdsaXchg_t *ttdsaXchg 177 ) 178 { 179 bit32 agRequestType; 180 agsaSASRequestBody_t *agSASRequestBody; 181 agsaSMPFrame_t *agSMPFrame; 182 smpRespDiscover_t *Resp; 183 smp_resp_t *SMPResp; 184 agsaIORequest_t *agIORequest; 185 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/ 186 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/ 187 188 TI_DBG1(("ttdsaDiscoverRespSend:\n")); 189 190 agRequestType = AGSA_SMP_TGT_RESPONSE; 191 192 SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr; 193 194 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest); 195 196 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody); 197 agSMPFrame = &(agSASRequestBody->smpFrame); 198 199 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/ 200 201 /* smp header */ /*(TP)*/ 202 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 203 tdSMPFrameHeader.smpFunction = SMP_DISCOVER; /* discover */ 204 tdSMPFrameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED; 205 tdSMPFrameHeader.smpReserved = 0; 206 207 /*old*/ 208 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 209 //agSMPFrame->frameHeader.smpFunction = SMP_DISCOVER; /* discover */ 210 //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED; 211 212 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*TP)*/ 213 214 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/ 215 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper; 216 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower; 217 agSMPFrame->outFrameLen = sizeof(smpRespDiscover_t); 218 219 //agSMPFrame->phyId = ttdsaXchg->SMPphyId; 220 221 /* smp response payload */ 222 Resp = (smpRespDiscover_t *)&(SMPResp->RespData); 223 osti_memset(Resp, 0, sizeof(smpRespDiscover_t)); 224 /* temp, hardcode smp discover response */ 225 /* needs to read contents from ID frame */ 226 /* assumption: for now, attached to edge expander */ 227 Resp->phyIdentifier = 0; 228 Resp->attachedDeviceType = SAS_EDGE_EXPANDER_DEVICE; 229 Resp->negotiatedPhyLinkRate = 0x9; /* enabled, 1.5G */ 230 Resp->attached_Ssp_Stp_Smp_Sata_Initiator = 0; 231 Resp->attached_SataPS_Ssp_Stp_Smp_Sata_Target = 0x2; /* SMP target */ 232 Resp->sasAddressHi[3] = 0x01; 233 Resp->sasAddressHi[2] = 0x02; 234 Resp->sasAddressHi[1] = 0x03; 235 Resp->sasAddressHi[0] = 0x04; 236 Resp->sasAddressLo[3] = 0x05; 237 Resp->sasAddressLo[2] = 0x06; 238 Resp->sasAddressLo[1] = 0x07; 239 Resp->sasAddressLo[0] = 0x08; 240 241 Resp->attachedSasAddressHi[3] = 0x01; 242 Resp->attachedSasAddressHi[2] = 0x01; 243 Resp->attachedSasAddressHi[1] = 0x01; 244 Resp->attachedSasAddressHi[0] = 0x01; 245 Resp->attachedSasAddressLo[3] = 0x02; 246 Resp->attachedSasAddressLo[2] = 0x02; 247 Resp->attachedSasAddressLo[1] = 0x02; 248 Resp->attachedSasAddressLo[0] = 0x02; 249 250 Resp->attachedPhyIdentifier = 0; 251 Resp->programmedAndHardware_MinPhyLinkRate = 0x8; /* not programmable and 1.5 G */ 252 Resp->programmedAndHardware_MaxPhyLinkRate = 0x8; /* not programmable and 1.5 G */ 253 Resp->phyChangeCount = 0; /* No broadcast(Change) received */ 254 Resp->virtualPhy_partialPathwayTimeout = 0x7; /* no virutal phy and see spec 10.4.3.5, p 404 rev 7 */ 255 Resp->routingAttribute = 0; 256 osti_memset(&Resp->reserved13, 0, 5); 257 osti_memset(&Resp->vendorSpecific, 0, 2); 258 259 #ifdef RPM_SOC 260 /* not work yet because of high priority q */ 261 saSMPStart( 262 agRoot, 263 agIORequest, 264 agDevHandle, 265 agRequestType, 266 agSASRequestBody, 267 &ossaSMPCompleted 268 ); 269 #else 270 saSMPStart( 271 agRoot, 272 agIORequest, 273 0, /* queue number */ 274 agDevHandle, 275 agRequestType, 276 agSASRequestBody, 277 &ossaSMPCompleted 278 ); 279 #endif 280 return; 281 } 282 283 osGLOBAL void 284 ttdsaReportGeneralRespSend( 285 agsaRoot_t *agRoot, 286 agsaDevHandle_t *agDevHandle, 287 ttdsaXchg_t *ttdsaXchg 288 ) 289 { 290 bit32 agRequestType; 291 agsaSASRequestBody_t *agSASRequestBody; 292 agsaSMPFrame_t *agSMPFrame; 293 smpRespReportGeneral_t *Resp; 294 smp_resp_t *SMPResp; 295 agsaIORequest_t *agIORequest; 296 bit8 SMPPayload[SMP_DIRECT_PAYLOAD_LIMIT]; /*(TP)*/ 297 tdssSMPFrameHeader_t tdSMPFrameHeader; /*(TP)*/ 298 299 TI_DBG1(("ttdsaReportGeneralRespSend:\n")); 300 301 agRequestType = AGSA_SMP_TGT_RESPONSE; 302 303 SMPResp = (smp_resp_t *)ttdsaXchg->smpresp.virtAddr; 304 305 agIORequest = &(ttdsaXchg->SMPRequestBody.agIORequest); 306 307 agSASRequestBody = &(ttdsaXchg->SMPRequestBody.agSASRequestBody); 308 agSMPFrame = &(agSASRequestBody->smpFrame); 309 310 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); /*(TP)*/ 311 312 tdSMPFrameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 313 tdSMPFrameHeader.smpFunction = SMP_REPORT_GENERAL; /* report general */ 314 tdSMPFrameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED; 315 tdSMPFrameHeader.smpReserved = 0; 316 317 /*old*/ 318 //agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP response */ 319 //agSMPFrame->frameHeader.smpFunction = SMP_REPORT_GENERAL; /* report general */ 320 //agSMPFrame->frameHeader.smpFunctionResult = SMP_FUNCTION_ACCEPTED; 321 322 osti_memcpy(SMPPayload, &tdSMPFrameHeader, 4); /*(TP)*/ 323 324 agSMPFrame->outFrameBuf = SMPPayload; /*(TP)*/ 325 agSMPFrame->outFrameAddrUpper32 = ttdsaXchg->smpresp.phyAddrUpper; 326 agSMPFrame->outFrameAddrLower32 = ttdsaXchg->smpresp.phyAddrLower; 327 agSMPFrame->outFrameLen = sizeof(smpRespReportGeneral_t); 328 329 //agSMPFrame->phyId = ttdsaXchg->SMPphyId; 330 331 /* smp response payload */ 332 Resp = (smpRespReportGeneral_t *)&(SMPResp->RespData); 333 osti_memset(Resp, 0, sizeof(smpRespReportGeneral_t)); 334 /* temp, hardcode smp general response */ 335 Resp->expanderChangeCount16[0] = 1; 336 Resp->expanderRouteIndexes16[0] = 2; 337 Resp->numOfPhys = 0x5; /* 0x1; */ 338 Resp->configuring_configurable = 0; 339 tdhexdump("smp general response", (bit8 *)Resp, sizeof(smpRespReportGeneral_t)); 340 341 #ifdef RPM_SOC 342 /* not work yet because of high priority q */ 343 saSMPStart( 344 agRoot, 345 agIORequest, 346 agDevHandle, 347 agRequestType, 348 agSASRequestBody, 349 &ossaSMPCompleted 350 ); 351 #else 352 saSMPStart( 353 agRoot, 354 agIORequest, 355 0, /* queue number */ 356 agDevHandle, 357 agRequestType, 358 agSASRequestBody, 359 &ossaSMPCompleted 360 ); 361 #endif 362 return; 363 } 364 365 366 osGLOBAL void 367 ttdsaSMPReqReceived( 368 agsaRoot_t *agRoot, 369 agsaDevHandle_t *agDevHandle, 370 agsaSMPFrameHeader_t *agFrameHeader, 371 agsaFrameHandle_t agFrameHandle, 372 bit32 agFrameLength, 373 bit32 phyId 374 ) 375 { 376 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 377 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 378 ttdsaXchg_t *ttdsaXchg; 379 tdsaDeviceData_t *oneDeviceData = agNULL; 380 381 382 TI_DBG1(("ttdsaSMPReqReceived: start\n")); 383 384 oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData; 385 386 if (oneDeviceData == agNULL) 387 { 388 TI_DBG1(("ttdsaSMPReqReceived: no device data\n")); 389 return; 390 } 391 392 ttdsaXchg = ttdsaXchgGetStruct(agRoot); 393 394 if (ttdsaXchg == agNULL) 395 { 396 TI_DBG1(("ttdsaSMPReqReceived: no free xchg structures\n")); 397 return; 398 } 399 400 401 oneDeviceData->agDevHandle = agDevHandle; 402 oneDeviceData->agRoot = agRoot; 403 404 /* saving the device */ 405 ttdsaXchg->DeviceData = oneDeviceData; 406 407 ttdsaXchg->agRoot = agRoot; 408 ttdsaXchg->tiRoot = tiRoot; 409 410 ttdsaXchg->SMPRequestBody.agIORequest.sdkData = agNULL; 411 412 ttdsaXchg->SMPphyId = phyId; 413 414 switch ( agFrameHeader->smpFunction ) 415 { 416 case SMP_REPORT_GENERAL: 417 { 418 /* must spec p392, rev7*/ 419 TI_DBG1(("ttdsaSMPReqReceived: REPORT_GENERAL\n")); 420 ttdsaReportGeneralRespSend(agRoot, agDevHandle, ttdsaXchg); 421 break; 422 } 423 case SMP_REPORT_MANUFACTURE_INFORMATION: 424 { 425 /* optional, spec p394, rev7*/ 426 TI_DBG1(("ttdsaSMPReqReceived: REPORT_MANUFACTURE_INFORMATION\n")); 427 ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, SMP_REPORT_MANUFACTURE_INFORMATION); 428 break; 429 } 430 case SMP_DISCOVER: 431 { 432 /* must, spec p398, rev7*/ 433 TI_DBG1(("ttdsaSMPReqReceived: DISCOVER\n")); 434 ttdsaDiscoverRespSend(agRoot, agDevHandle, ttdsaXchg); 435 break; 436 } 437 default: 438 { 439 TI_DBG1(("ttdsaSMPReqReceived: UKNOWN or not yet supported 0x%x\n", agFrameHeader->smpFunction)); 440 ttdsaNotSupportRespSend(agRoot, agDevHandle, ttdsaXchg, (bit8) agFrameHeader->smpFunction); 441 break; 442 } 443 } 444 445 return; 446 } 447