cxp.c (15087B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * I2C Driver for CXP/QSFP device 8 * Derived from XFP driver, more ioctls supported 9 * Limited to page 0 10 */ 11 #include <shared/bsl.h> 12 13 #include <sal/types.h> 14 #include <soc/drv.h> 15 #include <soc/error.h> 16 #include <soc/debug.h> 17 #include <soc/i2c.h> 18 #include <shared/bsl.h> 19 20 #define CXP_PAGE_SIZE 1 /* Bytes per page */ 21 #define CXP_DEVICE_SIZE (256*CXP_PAGE_SIZE) /* 256 bytes */ 22 #define CXP_ACK_RETRY_COUNT 1000 /* Number of retry polls */ 23 24 #define CXP_TX_LOWER_PAGE 0 25 #define CXP_TX_UPPER_PAGE_0 1 26 #define CXP_TX_UPPER_PAGE_1 2 27 #define CXP_RX_LOWER_PAGE 3 28 #define CXP_RX_UPPER_PAGE_0 4 29 #define CXP_RX_UPPER_PAGE_1 5 30 31 #define CXP_RX_PAGE_MASK 0x40 32 #define CXP_UPPER_PAGE_CTRL 0x80 33 34 /* 35 * Function: cxp_ack_poll 36 * 37 * Purpose: Poll the device to determine if it is ready for IO. 38 * When the chip writes data, it will become unresponsive 39 * for a period of Time Tw (Internal Write Delay). We could 40 * either wait the maximum amount of time for the device to 41 * finish it's write-cycle (10ms), or we can poll the device 42 * for a specified operation (r/w) until it responds with an 43 * ACK. This routine polls the device until it is responsive. 44 * 45 * Parameters: 46 * unit - StrataSwitch device number or I2C bus number 47 * bus_addr - chip IO (I2C) slave bus address byte(s) 48 * 49 * Returns: 50 * Number of Poll operations required to contact device, or 51 * CXP_ACK_RETRY_COUNT if the device is not online or responding. 52 * 53 * 54 * Notes: 55 * See also: soc_i2c_ack_poll 56 */ 57 STATIC INLINE int 58 cxp_ack_poll(int unit, i2c_bus_addr_t bus_addr) 59 { 60 return soc_i2c_ack_poll(unit, bus_addr, CXP_ACK_RETRY_COUNT); 61 } 62 63 STATIC int 64 _cxp_read(int unit, uint8 saddr, 65 uint16 addr, uint8* data, uint32 *len) 66 { 67 int rv = SOC_E_NONE; 68 uint8 saddr_r; 69 uint32 nbytes = 0; 70 uint8 saddr_w, a0; 71 72 /* Valid address, memory and size must be provided */ 73 if ( ! len || ! data ) 74 return SOC_E_PARAM; 75 76 I2C_LOCK(unit); 77 78 saddr_r = SOC_I2C_RX_ADDR(saddr); 79 saddr_w = SOC_I2C_TX_ADDR(saddr); 80 81 a0 = (uint8) (addr & 0x00ff); 82 83 LOG_INFO(BSL_LS_SOC_I2C, 84 (BSL_META_U(unit, 85 "cxp_read: addr=0x%x (a0=0x%x) len=%d\n"), 86 addr, a0, (int)*len)); 87 88 /* First, we put out the address which we would like to 89 * read at using the SOC_I2C_TX_ADDR (saddr_w) 90 */ 91 if ( (rv = soc_i2c_start(unit, saddr_w)) < 0) { 92 LOG_INFO(BSL_LS_SOC_I2C, 93 (BSL_META_U(unit, 94 "cxp_read(%d,%x,%x,%p,%d): " 95 "failed to generate start.\n"), 96 unit, saddr_w, addr, (void *)data, *len)); 97 I2C_UNLOCK(unit); 98 return rv; 99 } 100 101 if( (rv = soc_i2c_write_one_byte(unit, a0)) < 0) { 102 LOG_INFO(BSL_LS_SOC_I2C, 103 (BSL_META_U(unit, 104 "cxp_read(%d,%x,%x,%p,%d): " 105 "failed to send a0 byte.\n"), 106 unit, saddr_w, addr, (void *)data, *len)); 107 108 goto error; 109 } 110 /* Now, we have sent the first and second word addresses, 111 * we then issue a repeated start condition, followed by 112 * the device's read address (note: saddr_r) 113 */ 114 if( (rv = soc_i2c_rep_start(unit, saddr_r)) < 0) { 115 LOG_INFO(BSL_LS_SOC_I2C, 116 (BSL_META_U(unit, 117 "cxp_read(%d,%x,%x,%p,%d): " 118 "failed to generate rep start.\n"), 119 unit, saddr_r, addr, (void *)data, *len)); 120 goto error; 121 } 122 nbytes = *len; 123 if ( (rv = soc_i2c_read_bytes(unit, data, (int *)&nbytes, 0) ) < 0 ) { 124 goto error; 125 } 126 *len = nbytes; 127 128 error: 129 130 soc_i2c_stop(unit); 131 132 I2C_UNLOCK(unit); 133 return rv ; 134 } 135 136 137 /* 138 * Function: cxp_read 139 * 140 * Purpose: Read len bytes of data into buffer, update len with total 141 * amount read. 142 * 143 * Parameters: 144 * unit - StrataSwitch device number or I2C bus number 145 * devno - chip device id 146 * addr - CXP memory address to read from 147 * data - address of data buffer to read into 148 * len - address containing number of bytes read into data buffer (updated 149 * with number of bytes read on completion). 150 * 151 * Returns: data bufffer filled in with data from address, number of 152 * bytes read is updated in len field. Status code: 153 * 154 * SOC_E_NONE -- no error encounter 155 * SOC_E_TIMEOUT - chip timeout or data error 156 * 157 * Notes: 158 * Currently uses random address byte read to initiate the read; if 159 * more than one byte of data is requested at the current address, a 160 * sequential read operation is performed. 161 */ 162 STATIC int 163 cxp_read(int unit, int devno, 164 uint16 addr, uint8* data, uint32 *len) 165 { 166 int rv; 167 uint8 saddr; 168 169 saddr = soc_i2c_addr(unit, devno); 170 171 rv = _cxp_read(unit, saddr, addr, data, len); 172 if (SOC_SUCCESS(rv)) { 173 soc_i2c_device(unit, devno)->rbyte += *len; 174 } 175 return rv; 176 } 177 178 /* 179 * Function: cxp_write 180 * Purpose: Write len bytes of data, return the number of bytes written. 181 * Uses PAGE mode to write up to 32 bytes at a time between address 182 * stages for maximum performance. 183 * 184 * Parameters: 185 * unit - StrataSwitch device number or I2C bus number 186 * devno - chip device id 187 * addr - CXP memory address to write to 188 * data - address of data buffer to write from 189 * len - number of bytes to write 190 * 191 * Returns: 192 * SOC_E_NONE -- no error encountered 193 * SOC_E_TIMEOUT - chip timeout or data error 194 * 195 * 196 * Notes: 197 * Uses page mode to write in 32-byte chunks, when an address 198 * which does not begin on a page boundary is provided, the write 199 * operation handles unaligned accesses by breaking up the write 200 * into one write which is not page aligned, and the remainder as 201 * page aligned accesses. 202 */ 203 STATIC int 204 _cxp_write(int unit, uint8 saddr , uint16 addr, uint8* data, uint32 len) 205 { 206 int rv = SOC_E_NONE; 207 i2c_bus_addr_t bus_addr; 208 uint32 b, numpages, cpage, nbytes, caddr; 209 uint8 *ptr, a0; 210 211 /* User must have data to write */ 212 if ( ! data || len <= 0 ) 213 return SOC_E_PARAM; 214 215 I2C_LOCK(unit); 216 217 /* Use PAGE mode */ 218 caddr = addr; 219 numpages = len / CXP_PAGE_SIZE + (len % CXP_PAGE_SIZE > 0); 220 ptr = data; 221 222 bus_addr = SOC_I2C_TX_ADDR(saddr); 223 224 LOG_INFO(BSL_LS_SOC_I2C, 225 (BSL_META_U(unit, 226 "cxp_write: addr=0x%x data=%p len=%d npages=%d\n"), 227 caddr, (void *)data, (int)len, numpages)); 228 229 /* Loop over every page in buffer .. */ 230 for(cpage = 0; cpage < numpages; cpage++){ 231 /* Address not page aligned, D'Oh, can't write a full page. */ 232 if( (caddr % CXP_PAGE_SIZE) != 0){ 233 /* coverity[dead_error_begin] */ 234 nbytes = CXP_PAGE_SIZE - (caddr % CXP_PAGE_SIZE); 235 len -= nbytes; 236 } else { 237 /* Address is page aligned, calculate bytes to write */ 238 if ( len <= CXP_PAGE_SIZE ) { 239 /* Less than a page to write */ 240 nbytes = len; 241 } else { 242 /* Wammo, full page write */ 243 nbytes = CXP_PAGE_SIZE; 244 len -= nbytes; 245 } 246 } 247 248 /* Construct device address bytes */ 249 a0 = (uint8) (caddr & 0x00ff); 250 251 LOG_INFO(BSL_LS_SOC_I2C, 252 (BSL_META_U(unit, 253 "cxp_write: unit=%d cpage=%d START on page_addr=0x%x" 254 " nbytes=%d\n"), unit, cpage, caddr, nbytes)); 255 256 /* Generate Start, for Write address */ 257 if( (rv = soc_i2c_start(unit, bus_addr)) < 0){ 258 LOG_INFO(BSL_LS_SOC_I2C, 259 (BSL_META_U(unit, 260 "cxp_write(%d,%x,%x,%d,%d): " 261 "failed to gen start\n"), 262 unit, bus_addr, caddr, *data, len)); 263 I2C_UNLOCK(unit); 264 return rv; 265 } 266 267 /* Send LSB (a0), wait for ACK */ 268 if( (rv = soc_i2c_write_one_byte(unit, a0)) < 0){ 269 LOG_INFO(BSL_LS_SOC_I2C, 270 (BSL_META_U(unit, 271 "cxp_write(%d,%x,%x,%d,%d): " 272 "failed to send a0 byte\n"), 273 unit, bus_addr, caddr, *data, len)); 274 goto error; 275 } 276 /* Send up to PAGE_SIZE data bytes, wait for ACK */ 277 for ( b = 0; b < nbytes; b++, ptr++, caddr++ ) { 278 if ( (rv = soc_i2c_write_one_byte(unit, *ptr)) < 0){ 279 LOG_INFO(BSL_LS_SOC_I2C, 280 (BSL_META_U(unit, 281 "cxp_write(%d,%x,%d,%d,%d): " 282 "tx data byte error\n"), 283 unit, bus_addr, caddr, (uint32)*ptr, b)); 284 goto error; 285 } 286 LOG_VERBOSE(BSL_LS_SOC_I2C, 287 (BSL_META_U(unit, 288 "cxp_write(u=%d,addr=%x,page=%d " 289 "caddr=%d,data=0x%x,idx=%d)\n"), 290 unit, bus_addr, cpage, caddr, (uint8)*ptr, b)); 291 292 } 293 294 /* Send STOP, also what we do on an error to free bus.. */ 295 error: 296 297 soc_i2c_stop(unit); 298 299 /* Acknowledge polling: When the chip enters it's 300 * own internal write-cycle, it falls off the I2C bus 301 * and does not ACK a start/address phase; hence, we 302 * attempt addressing the chip until it responds, at 303 * which point the internal write cycle has finished. 304 */ 305 rv = cxp_ack_poll(unit, bus_addr); 306 LOG_INFO(BSL_LS_SOC_I2C, 307 (BSL_META_U(unit, 308 "cxp_ack_poll: " 309 "%d address cycles for wr latency.\n"), rv)); 310 rv = (rv > 0 ? SOC_E_NONE: SOC_E_TIMEOUT); 311 312 } 313 314 I2C_UNLOCK(unit); 315 return (rv); 316 } 317 318 STATIC int 319 cxp_write(int unit, int devno, 320 uint16 addr, uint8* data, uint32 len) 321 { 322 uint8 saddr; 323 int rv; 324 325 saddr = soc_i2c_addr(unit, devno); 326 327 rv = _cxp_write(unit, saddr, addr, data, len); 328 if (SOC_SUCCESS(rv)) { 329 soc_i2c_device(unit, devno)->tbyte += len; 330 } 331 return rv; 332 } 333 334 335 /* 336 * Function: cxp_ioctl: does miscellaenous tasks. 337 * Purpose: Support miscellaneous chip options. 338 * 339 * Parameters: 340 * unit - StrataSwitch device number or I2C bus number 341 * devno - chip device id 342 * command - IO control operation 343 * data - address of user data 344 * len - size of test data 345 * 346 * Notes: 347 * Placeholder for write Protect, EEPROM Chip reset - NYI 348 */ 349 STATIC int 350 cxp_ioctl(int unit, int devno, 351 int command, void* data, int wlen) 352 { 353 int offset = 0, page = 0; 354 uint32 len = 1; 355 int op = 0; /* read */ 356 uint8 saddr; 357 uint8 cxp_dev = 1; 358 359 saddr = soc_i2c_addr(unit, devno); 360 361 _cxp_read(unit, saddr, 128, (uint8*)&cxp_dev, &len); 362 switch ( command ) { 363 case I2C_CXP_VENDOR_NAME: 364 page = 0; 365 if (cxp_dev == 0xc) { offset = 148; } 366 else if (cxp_dev < 0xc) { offset = 20; } 367 else { offset = 152; page = CXP_TX_UPPER_PAGE_0;} 368 len = 16; 369 break; 370 case I2C_CXP_VENDOR_OUI: 371 offset = 168; 372 page = CXP_TX_UPPER_PAGE_0; 373 len = 3; 374 break; 375 case I2C_CXP_VENDOR_PART_NUM: 376 page = 0; 377 if (cxp_dev == 0xc) { offset = 162; } 378 else if (cxp_dev < 0xc) { offset = 40; } 379 else { offset = 171; page = CXP_TX_UPPER_PAGE_0;} 380 len = 16; 381 break; 382 case I2C_CXP_VENDOR_REV_ID: 383 offset = 187; 384 page = CXP_TX_UPPER_PAGE_0; 385 len = 2; 386 break; 387 case I2C_CXP_VENDOR_SERIAL: 388 offset = 189; 389 page = CXP_TX_UPPER_PAGE_0; 390 len = 16; 391 break; 392 case I2C_CXP_VENDOR_DATE: 393 offset = 205; 394 page = CXP_TX_UPPER_PAGE_0; 395 len = 8; 396 break; 397 case I2C_CXP_VENDOR_LOT: 398 offset = 213; 399 page = CXP_TX_UPPER_PAGE_0; 400 len = 10; 401 break; 402 case I2C_CXP_TX_CAPABILITY: 403 offset = 142; 404 page = CXP_TX_UPPER_PAGE_0; 405 len = 2; 406 break; 407 case I2C_CXP_RX_CAPABILITY: 408 offset = 144 ; 409 page = CXP_RX_UPPER_PAGE_0; 410 len = 2; 411 break; 412 case I2C_CXP_RX_STATUS: 413 page = CXP_RX_LOWER_PAGE; 414 offset = 6; 415 len = 1; 416 break; 417 case I2C_CXP_RX_LOS_STATUS: 418 /* returns both LOS and FAULT */ 419 page = CXP_RX_LOWER_PAGE; 420 offset = 7; 421 len = 4; 422 break; 423 case I2C_CXP_RX_CHANNEL_CTRL: 424 page = CXP_RX_LOWER_PAGE; 425 offset = 52; 426 len = 2; 427 break; 428 case I2C_CXP_RX_OUTPUT_CTRL: 429 page = CXP_RX_LOWER_PAGE; 430 offset = 54; 431 len = 2; 432 op = 1; 433 break; 434 case I2C_CXP_RX_OUTPUT_STATUS: 435 page = CXP_RX_LOWER_PAGE; 436 offset = 54; 437 len = 2; 438 break; 439 case I2C_CXP_RX_LOS_MASK: 440 page = CXP_RX_LOWER_PAGE; 441 offset = 95; 442 len = 2; 443 break; 444 445 case I2C_CXP_TX_STATUS: 446 page = CXP_TX_LOWER_PAGE; 447 offset = 6; 448 len = 1; 449 break; 450 case I2C_CXP_TX_LOS_STATUS: 451 /* returns both LOS and FAULT */ 452 page = CXP_TX_LOWER_PAGE; 453 offset = 7; 454 len = 4; 455 break; 456 case I2C_CXP_TX_CHANNEL_CTRL: 457 page = CXP_TX_LOWER_PAGE; 458 offset = 52; 459 len = 2; 460 break; 461 case I2C_CXP_TX_OUTPUT_CTRL: 462 page = CXP_TX_LOWER_PAGE; 463 offset = 54; 464 len = 2; 465 op = 1; 466 break; 467 case I2C_CXP_TX_OUTPUT_STATUS: 468 page = CXP_TX_LOWER_PAGE; 469 offset = 54; 470 len = 2; 471 break; 472 case I2C_CXP_TX_LOS_MASK: 473 page = CXP_TX_LOWER_PAGE; 474 offset = 95; 475 len = 2; 476 break; 477 default: 478 break; 479 } 480 saddr = soc_i2c_addr(unit, devno); 481 if (page >= CXP_RX_LOWER_PAGE) { 482 saddr |= CXP_RX_PAGE_MASK; 483 } 484 if (op) { 485 _cxp_write(unit, saddr, offset, (uint8*)data, len); 486 } else { 487 _cxp_read(unit, saddr, offset, (uint8*)data, &len); 488 } 489 return SOC_E_NONE; 490 } 491 492 /* 493 * Function: cxp_init 494 * 495 * Purpose: initialize the CXP I2C interface. 496 * 497 * Parameters: 498 * unit - StrataSwitch device number or I2C bus number 499 * devno - chip device id 500 * data - address of test data 501 * len - size of test data 502 */ 503 STATIC int 504 cxp_init(int unit, int devno, void* data, int len) 505 { 506 uint8 buffer[256]; 507 sal_memset(buffer, 0, 256); 508 cxp_ioctl(unit, devno, I2C_CXP_VENDOR_NAME, buffer, 256); 509 LOG_VERBOSE(BSL_LS_SOC_I2C, 510 (BSL_META_U(unit, 511 "\nCXP device: Vendor name: %s"), buffer)); 512 sal_memset(buffer, 0, 256); 513 cxp_ioctl(unit, devno, I2C_CXP_VENDOR_PART_NUM, buffer, 256); 514 LOG_VERBOSE(BSL_LS_SOC_I2C, 515 (BSL_META_U(unit, 516 "Part: %s detected \n"), buffer)); 517 518 soc_i2c_devdesc_set(unit, devno, "Cxp/Sfp/Qsfp Driver"); 519 520 return SOC_E_NONE; 521 } 522 523 524 /* CXP Driver callout */ 525 i2c_driver_t _soc_i2c_cxp_driver = { 526 0x0,0x0, /* System assigned bytes */ 527 CXP_DEVICE_TYPE, 528 cxp_read, 529 cxp_write, 530 cxp_ioctl, 531 cxp_init, 532 NULL, 533 };