phy8806x.c (57631B)
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 * File: phy8806x.c 8 */ 9 10 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_util.h> 13 #include "phy8806x_xmod_api.h" 14 #define PHY8806X_DEBUG 0 15 16 #ifdef PHYMOD_PHY8806X_SUPPORT 17 18 /* ! Byte swap unsigned short */ 19 uint16_t swap_uint16( uint16_t val ) 20 { 21 return (val << 8) | (val >> 8 ); 22 } 23 /* ! Byte swap unsigned int32 */ 24 uint32_t swap_uint32( uint32_t val ) 25 { 26 val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); 27 return (val << 16) | (val >> 16); 28 } 29 30 #ifdef BE_HOST 31 #define HOST2LE32(_x) (swap_uint32((_x))) 32 #define LE2HOST32(_x) (swap_uint32((_x))) 33 #define HOST2LE16(_x) (swap_uint16((_x))) 34 #define LE2HOST16(_x) (swap_uint16((_x))) 35 #else 36 #define HOST2LE32(_x) (_x) 37 #define LE2HOST32(_x) (_x) 38 #define HOST2LE16(_x) (_x) 39 #define LE2HOST16(_x) (_x) 40 #endif 41 42 static int 43 _phy_8806x_xmod_command(const phymod_access_t* access, int mode_opcode, uint32_t xmodtxbuff[], int xmodtxlen, uint32_t xmodrxbuff[], int xmodrxlen) 44 { 45 xmod_buf_desc bd; 46 47 if (PHYMOD_ACC_EXT_ACC(access)) { 48 bd.pa = access; 49 bd.mode_opcode = mode_opcode; 50 bd.xmodtxbuff = xmodtxbuff; 51 bd.xmodtxlen = xmodtxlen; 52 bd.xmodrxbuff = xmodrxbuff; 53 bd.xmodrxlen = xmodrxlen; 54 55 return (*PHYMOD_ACC_EXT_ACC(access))(&bd); 56 } 57 58 return PHYMOD_E_UNAVAIL; 59 } 60 61 int phy8806x_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 62 { 63 return PHYMOD_E_NONE; 64 } 65 66 67 int phy8806x_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 68 { 69 return PHYMOD_E_NONE; 70 } 71 72 73 int phy8806x_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 74 { 75 return PHYMOD_E_NONE; 76 } 77 78 79 int phy8806x_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 80 { 81 return PHYMOD_E_NONE; 82 } 83 84 85 int phy8806x_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 86 { 87 return PHYMOD_E_NONE; 88 } 89 90 91 int phy8806x_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 92 { 93 return PHYMOD_E_UNAVAIL; 94 } 95 96 97 int phy8806x_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 98 { 99 return PHYMOD_E_NONE; 100 } 101 102 103 int phy8806x_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 104 { 105 return PHYMOD_E_NONE; 106 } 107 108 109 int phy8806x_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 110 { 111 return PHYMOD_E_NONE; 112 } 113 114 115 int phy8806x_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 116 { 117 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 118 uint8_t *buftxptr; 119 int xmodtxlen, rv=PHYMOD_E_NONE; 120 xmod_firmware_lane_config_t x_fw_config; 121 122 x_fw_config.SystemSide = (phy->port_loc == phymodPortLocSys) ? 1 : 0; 123 124 x_fw_config.LaneConfigFromPCS = HOST2LE32(fw_config.LaneConfigFromPCS); 125 x_fw_config.AnEnabled = HOST2LE32(fw_config.AnEnabled); 126 x_fw_config.DfeOn = HOST2LE32(fw_config.DfeOn); 127 x_fw_config.ForceBrDfe = HOST2LE32(fw_config.ForceBrDfe); 128 x_fw_config.LpDfeOn = HOST2LE32(fw_config.LpDfeOn); 129 x_fw_config.MediaType = HOST2LE32(fw_config.MediaType); 130 x_fw_config.UnreliableLos = HOST2LE32(fw_config.UnreliableLos); 131 x_fw_config.ScramblingDisable = HOST2LE32(fw_config.ScramblingDisable); 132 x_fw_config.Cl72AutoPolEn = HOST2LE32(fw_config.Cl72AutoPolEn); 133 x_fw_config.Cl72RestTO = HOST2LE32(fw_config.Cl72RestTO); 134 x_fw_config.ForceExtenedReach = HOST2LE32(fw_config.ForceExtenedReach); 135 x_fw_config.ForceNormalReach = HOST2LE32(fw_config.ForceNormalReach); 136 x_fw_config.LpPrecoderEnabled = HOST2LE32(fw_config.LpPrecoderEnabled); 137 x_fw_config.ForcePAM4Mode = HOST2LE32(fw_config.ForcePAM4Mode); 138 x_fw_config.ForceNRZMode = HOST2LE32(fw_config.ForceNRZMode); 139 x_fw_config.SystemSide = HOST2LE32(x_fw_config.SystemSide); 140 141 /* write args to xmod buffer */ 142 buftxptr = (uint8_t *) xmodtxbuff; 143 WRITE_XMOD_ARG_BUFF(buftxptr, &x_fw_config, sizeof(xmod_firmware_lane_config_t)); 144 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FW_LANE_CFG_SET); 145 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 146 147 /* call xmod */ 148 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FW_LANE_CFG_SET), 149 xmodtxbuff, xmodtxlen, NULL, 0); 150 151 return rv; 152 } 153 154 155 int phy8806x_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 156 { 157 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 158 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 159 uint8_t *bufrxptr; 160 uint8_t *buftxptr; 161 int xmodrxlen, rv; 162 int xmodtxlen; 163 xmod_firmware_lane_config_t x_fw_config; 164 uint32_t sys_side; 165 166 sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; 167 168 sys_side = HOST2LE32(sys_side); 169 170 buftxptr = (uint8_t *)xmodtxbuff; 171 WRITE_XMOD_ARG_BUFF(buftxptr, &sys_side, sizeof(uint32_t)); 172 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FW_LANE_CFG_GET); 173 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 174 175 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_FW_LANE_CFG_GET); 176 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 177 178 /* call xmod */ 179 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FW_LANE_CFG_GET), 180 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 181 182 /* retrieve the argument from the xmod rx buffer */ 183 bufrxptr = (uint8_t *)xmodrxbuff; 184 READ_XMOD_ARG_BUFF(bufrxptr, &x_fw_config, sizeof(xmod_firmware_lane_config_t)); 185 186 fw_config->LaneConfigFromPCS = HOST2LE32(x_fw_config.LaneConfigFromPCS); 187 fw_config->AnEnabled = HOST2LE32(x_fw_config.AnEnabled); 188 fw_config->DfeOn = HOST2LE32(x_fw_config.DfeOn); 189 fw_config->ForceBrDfe = HOST2LE32(x_fw_config.ForceBrDfe); 190 fw_config->LpDfeOn = HOST2LE32(x_fw_config.LpDfeOn); 191 fw_config->MediaType = HOST2LE32(x_fw_config.MediaType); 192 fw_config->UnreliableLos = HOST2LE32(x_fw_config.UnreliableLos); 193 fw_config->ScramblingDisable = HOST2LE32(x_fw_config.ScramblingDisable); 194 fw_config->Cl72AutoPolEn = HOST2LE32(x_fw_config.Cl72AutoPolEn); 195 fw_config->Cl72RestTO = HOST2LE32(x_fw_config.Cl72RestTO); 196 fw_config->ForceExtenedReach = HOST2LE32(x_fw_config.ForceExtenedReach); 197 fw_config->ForceNormalReach = HOST2LE32(x_fw_config.ForceNormalReach); 198 fw_config->LpPrecoderEnabled = HOST2LE32(x_fw_config.LpPrecoderEnabled); 199 fw_config->ForcePAM4Mode = HOST2LE32(x_fw_config.ForcePAM4Mode); 200 fw_config->ForceNRZMode = HOST2LE32(x_fw_config.ForceNRZMode); 201 202 return rv; 203 } 204 205 206 /* reset pll sequencer 207 * flags - unused parameter 208 */ 209 int phy8806x_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 210 { 211 return PHYMOD_E_UNAVAIL; 212 } 213 214 215 int phy8806x_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 216 { 217 return PHYMOD_E_NONE; 218 } 219 220 221 int phy8806x_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* pll_multiplier) 222 { 223 return PHYMOD_E_NONE; 224 } 225 226 227 /* reset rx sequencer 228 * flags - unused parameter 229 */ 230 int phy8806x_phy_rx_restart(const phymod_phy_access_t* phy) 231 { 232 return PHYMOD_E_NONE; 233 } 234 235 236 int phy8806x_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 237 { 238 return PHYMOD_E_NONE; 239 } 240 241 242 int phy8806x_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 243 { 244 return PHYMOD_E_NONE; 245 } 246 247 248 int phy8806x_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 249 { 250 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 251 uint8_t *buftxptr; 252 int xmodtxlen, rv; 253 xmod_tx_t xmod_tx; 254 255 xmod_tx.sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; /* int8_t, no swap */ 256 257 xmod_tx.pre = (int8_t)tx->pre; /* int8_t, no swap */ 258 xmod_tx.main = (int8_t)tx->main; /* int8_t, no swap */ 259 xmod_tx.post = (int8_t)tx->post; /* int8_t, no swap */ 260 xmod_tx.post2 = (int8_t)tx->post2; /* int8_t, no swap */ 261 xmod_tx.post3 = (int8_t)tx->post3; /* int8_t, no swap */ 262 xmod_tx.amp = (int8_t)tx->amp; /* int8_t, no swap */ 263 264 /* write args to xmod buffer */ 265 buftxptr = (uint8_t *)xmodtxbuff; 266 WRITE_XMOD_ARG_BUFF(buftxptr, &xmod_tx, sizeof(xmod_tx_t)); 267 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_TX_SET); 268 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 269 270 /* call xmod */ 271 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_TX_SET), 272 xmodtxbuff, xmodtxlen, NULL, 0); 273 274 return rv; 275 } 276 277 278 int phy8806x_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 279 { 280 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 281 uint8_t *buftxptr; 282 int xmodtxlen, rv; 283 xmod_tx_t xmod_tx; 284 285 PHYMOD_MEMSET(&xmod_tx, 0, sizeof(xmod_tx)); 286 xmod_tx.sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; /* int8_t, no swap */ 287 288 /* write args to xmod buffer */ 289 buftxptr = (uint8_t *)xmodtxbuff; 290 WRITE_XMOD_ARG_BUFF(buftxptr, &xmod_tx, sizeof(xmod_tx_t)); 291 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_TX_GET); /* Same as GET_XMOD_ETHERNET_CMD_OUT_LEN. */ 292 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 293 294 /* call xmod */ 295 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_TX_GET), 296 xmodtxbuff, xmodtxlen, xmodtxbuff, xmodtxlen); 297 298 /* retrieve the argument from the xmod rx buffer */ 299 buftxptr = (uint8_t *)xmodtxbuff; 300 READ_XMOD_ARG_BUFF(buftxptr, &xmod_tx, sizeof(xmod_tx_t)); 301 302 tx->pre = xmod_tx.pre; /* int8_t, no swap */ 303 tx->main = xmod_tx.main; /* int8_t, no swap */ 304 tx->post = xmod_tx.post; /* int8_t, no swap */ 305 tx->post2 = xmod_tx.post2; /* int8_t, no swap */ 306 tx->post3 = xmod_tx.post3; /* int8_t, no swap */ 307 tx->amp = xmod_tx.amp; /* int8_t, no swap */ 308 309 return rv; 310 } 311 312 313 int phy8806x_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 314 { 315 return PHYMOD_E_NONE; 316 } 317 318 319 int phy8806x_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 320 { 321 return PHYMOD_E_NONE; 322 } 323 324 325 int phy8806x_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 326 { 327 return PHYMOD_E_NONE; 328 } 329 330 331 int phy8806x_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 332 { 333 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 334 uint8_t *buftxptr; 335 int xmodtxlen, rv, i; 336 xmod_rx_t xmod_rx; 337 338 xmod_rx.sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; /* int8_t, no swap */ 339 340 xmod_rx.vga.enable = HOST2LE32(rx->vga.enable); 341 xmod_rx.vga.value = HOST2LE32(rx->vga.value); 342 343 xmod_rx.num_of_dfe_taps = HOST2LE32(rx->num_of_dfe_taps); /* number of elements in DFE array */ 344 345 for (i = 0; i < XMOD_NUM_DFE_TAPS; i++) { 346 xmod_rx.dfe[i].enable = HOST2LE32(rx->dfe[i].enable); 347 xmod_rx.dfe[i].value = HOST2LE32(rx->dfe[i].value); 348 } 349 350 xmod_rx.peaking_filter.enable = HOST2LE32(rx->peaking_filter.enable); 351 xmod_rx.peaking_filter.value = HOST2LE32(rx->peaking_filter.value); 352 353 xmod_rx.low_freq_peaking_filter.enable = HOST2LE32(rx->low_freq_peaking_filter.enable); 354 xmod_rx.low_freq_peaking_filter.value = HOST2LE32(rx->low_freq_peaking_filter.value); 355 356 xmod_rx.rx_adaptation_on = HOST2LE32(rx->rx_adaptation_on); 357 358 /* write args to xmod buffer */ 359 buftxptr = (uint8_t *)xmodtxbuff; 360 WRITE_XMOD_ARG_BUFF(buftxptr, &xmod_rx, sizeof(xmod_rx_t)); 361 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_RX_SET); 362 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 363 364 /* call xmod */ 365 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_RX_SET), 366 xmodtxbuff, xmodtxlen, NULL, 0); 367 368 return rv; 369 } 370 371 372 int phy8806x_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 373 { 374 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 375 uint8_t *bufrxptr; 376 int xmodrxlen, rv, i; 377 xmod_rx_t xmod_rx; 378 379 PHYMOD_MEMSET(&xmod_rx, 0, sizeof(xmod_rx)); 380 xmod_rx.sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; /* int8_t, no swap */ 381 382 /* write args to xmod buffer */ 383 bufrxptr = (uint8_t *)xmodrxbuff; 384 WRITE_XMOD_ARG_BUFF(bufrxptr, &xmod_rx, sizeof(xmod_rx_t)); 385 xmodrxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_RX_GET); /* Same as GET_XMOD_ETHERNET_CMD_OUT_LEN. */ 386 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 387 388 /* call xmod */ 389 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_RX_GET), 390 xmodrxbuff, xmodrxlen, xmodrxbuff, xmodrxlen); 391 392 /* retrieve the argument from the xmod rx buffer */ 393 bufrxptr = (uint8_t *)xmodrxbuff; 394 READ_XMOD_ARG_BUFF(bufrxptr, &xmod_rx, sizeof(xmod_rx_t)); 395 396 rx->vga.enable = LE2HOST32(xmod_rx.vga.enable); 397 rx->vga.value = LE2HOST32(xmod_rx.vga.value); 398 399 rx->num_of_dfe_taps = LE2HOST32(xmod_rx.num_of_dfe_taps); /* number of elements in DFE array */ 400 401 for (i = 0; i < XMOD_NUM_DFE_TAPS; i++) { 402 rx->dfe[i].enable = LE2HOST32(xmod_rx.dfe[i].enable); 403 rx->dfe[i].value = LE2HOST32(xmod_rx.dfe[i].value); 404 } 405 406 rx->peaking_filter.enable = LE2HOST32(xmod_rx.peaking_filter.enable); 407 rx->peaking_filter.value = LE2HOST32(xmod_rx.peaking_filter.value); 408 409 rx->low_freq_peaking_filter.enable = LE2HOST32(xmod_rx.low_freq_peaking_filter.enable); 410 rx->low_freq_peaking_filter.value = LE2HOST32(xmod_rx.low_freq_peaking_filter.value); 411 412 rx->rx_adaptation_on = LE2HOST32(xmod_rx.rx_adaptation_on); 413 414 return rv; 415 } 416 417 418 int phy8806x_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 419 { 420 return PHYMOD_E_NONE; 421 } 422 423 424 int phy8806x_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 425 { 426 return PHYMOD_E_NONE; 427 } 428 429 430 int phy8806x_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 431 { 432 return PHYMOD_E_NONE; 433 } 434 435 int phy8806x_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 436 { 437 return PHYMOD_E_NONE; 438 } 439 440 441 int phy8806x_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 442 { 443 return PHYMOD_E_NONE; 444 } 445 446 447 int phy8806x_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 448 { 449 return PHYMOD_E_NONE; 450 } 451 452 453 int phy8806x_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 454 { 455 return PHYMOD_E_NONE; 456 } 457 458 459 int phy8806x_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 460 { 461 return PHYMOD_E_NONE; 462 } 463 464 465 int phy8806x_phy_tx_disable_set(const phymod_phy_access_t* phy, uint32_t tx_disable) 466 { 467 return PHYMOD_E_NONE; 468 } 469 470 471 int phy8806x_phy_tx_disable_get(const phymod_phy_access_t* phy, uint32_t* tx_disable) 472 { 473 return PHYMOD_E_NONE; 474 } 475 476 int phy8806x_reset_interface(const phymod_phy_access_t* phy) 477 { 478 #ifdef INCLUDE_PHY_8806X 479 int rv; 480 481 /* call xmod */ 482 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_RESET_INTF), 483 0, 0, NULL, 0); 484 485 return rv; 486 #else 487 return PHYMOD_E_NONE; 488 #endif 489 } 490 491 int phy8806x_port_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 492 { 493 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 494 uint8_t *buftxptr; 495 int xmodtxlen, rv=PHYMOD_E_NONE; 496 xmod_port_enable_control_t x_port_en_ctrl; 497 498 enable = HOST2LE32(enable); 499 x_port_en_ctrl.enable = enable; 500 501 /* write args to xmod buffer */ 502 buftxptr = (uint8_t *) xmodtxbuff; 503 WRITE_XMOD_ARG_BUFF(buftxptr, &x_port_en_ctrl, sizeof(xmod_port_enable_control_t)); 504 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PORT_ENABLE_SET); 505 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 506 507 /* call xmod */ 508 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PORT_ENABLE_SET), 509 xmodtxbuff, xmodtxlen, NULL, 0); 510 511 return rv; 512 } 513 514 515 int phy8806x_port_enable_get(const phymod_phy_access_t* phy, uint32_t *enable) 516 { 517 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 518 uint8_t *bufrxptr; 519 int xmodrxlen, rv; 520 xmod_port_enable_control_t x_port_en_ctrl; 521 522 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PORT_ENABLE_GET); 523 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 524 525 /* call xmod */ 526 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PORT_ENABLE_GET), 527 NULL, 0, xmodrxbuff, xmodrxlen); 528 529 /* retrieve the argument from the xmod rx buffer */ 530 bufrxptr = (uint8_t *)xmodrxbuff; 531 READ_XMOD_ARG_BUFF(bufrxptr, &x_port_en_ctrl, sizeof(x_port_en_ctrl)); 532 533 *enable = HOST2LE32(x_port_en_ctrl.enable); 534 535 return rv; 536 } 537 538 539 540 int phy8806x_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t fec_en) 541 { 542 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 543 uint8_t *buftxptr; 544 int xmodtxlen, rv; 545 xmod_fec_t fec_st; 546 547 /* write args to xmod buffer */ 548 buftxptr = (uint8_t *)xmodtxbuff; 549 550 fec_st.enable = fec_en & 0xFF; 551 fec_st.sys_side = 0; 552 if (fec_en & PORT_SYS_SIDE_CTRL) 553 fec_st.sys_side = 1; 554 555 WRITE_XMOD_ARG_BUFF(buftxptr, &fec_st, sizeof(xmod_fec_t)); 556 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FEC_ENABLE_SET); 557 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 558 559 /* call xmod */ 560 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FEC_ENABLE_SET), 561 xmodtxbuff, xmodtxlen, NULL, 0); 562 563 return rv; 564 } 565 566 567 int phy8806x_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* fec_en) 568 { 569 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 570 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 571 uint8_t *buftxptr; 572 int xmodtxlen; 573 uint8_t *bufrxptr; 574 int xmodrxlen, rv; 575 uint32_t sys_side = 0; 576 577 if (*fec_en & PORT_SYS_SIDE_CTRL) { 578 sys_side = 1; 579 } 580 581 *fec_en = 0; 582 sys_side = HOST2LE32(sys_side); 583 584 /* write args to xmod buffer */ 585 buftxptr = (uint8_t *)xmodtxbuff; 586 WRITE_XMOD_ARG_BUFF(buftxptr, &sys_side, sizeof(uint32_t)); 587 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FEC_ENABLE_GET); 588 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 589 590 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_FEC_ENABLE_GET); 591 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 592 593 /* call xmod */ 594 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FEC_ENABLE_GET), 595 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 596 597 /* retrieve the argument from the xmod rx buffer */ 598 bufrxptr = (uint8_t *)xmodrxbuff; 599 READ_XMOD_ARG_BUFF(bufrxptr, fec_en, sizeof(uint32_t)); 600 601 *fec_en = LE2HOST32(*fec_en); 602 603 return rv; 604 } 605 606 607 int phy8806x_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 608 { 609 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 610 uint8_t *buftxptr; 611 uint8_t x_flags; 612 xmod_phy_inf_config_t x_config; 613 int xmodtxlen, rv; 614 uint16_t port_flags = 0; 615 616 /* setting up xmod xmod_phy_interface_config_set: */ 617 /* int xmod_phy_interface_config_set( IN uint8_t flags, IN xmod_phy_inf_config_t* config ) */ 618 if (phy->port_loc == phymodPortLocSys) { 619 port_flags = (XMOD_SYS_FLAG << XMOD_FLAGS_SHIFT); 620 } else if (phy->port_loc == phymodPortLocLine) { 621 port_flags = (XMOD_LINE_FLAG << XMOD_FLAGS_SHIFT); 622 } 623 624 /* write args to xmod buffer */ 625 x_flags = flags; 626 buftxptr = (uint8_t *)xmodtxbuff; 627 WRITE_XMOD_ARG_BUFF(buftxptr, &x_flags, sizeof(uint8_t)); 628 x_config.interface_type = config->interface_type; 629 x_config.device_aux_modes = config->device_aux_modes; 630 x_config.ref_clock = config->ref_clock; 631 x_config.data_rate = HOST2LE32(config->data_rate); 632 x_config.interface_modes = HOST2LE32(config->interface_modes); 633 x_config.pll_divider_req = HOST2LE16(config->pll_divider_req); 634 635 WRITE_XMOD_ARG_BUFF(buftxptr, &x_config, sizeof(xmod_phy_inf_config_t)); 636 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_INTERFACE_CONFIG_SET); 637 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 638 639 /* call xmod */ 640 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_INTERFACE_CONFIG_SET) | port_flags, 641 xmodtxbuff, xmodtxlen, NULL, 0); 642 643 return rv; 644 } 645 646 647 /*flags- unused parameter*/ 648 int phy8806x_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config) 649 { 650 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 651 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 652 uint8_t *buftxptr, *bufrxptr; 653 uint8_t x_flags; 654 xmod_phy_inf_config_t x_config; 655 int xmodtxlen, xmodrxlen, rv; 656 uint16_t port_flags = 0; 657 658 /* setting up xmod xmod_phy_interface_config_get: */ 659 /* int xmod_phy_interface_config_get( IN uint8_t flags, OUT xmod_phy_inf_config_t* config ) */ 660 if (phy->port_loc == phymodPortLocSys) { 661 port_flags = (XMOD_SYS_FLAG << XMOD_FLAGS_SHIFT); /* sys interface */ 662 } else if (phy->port_loc == phymodPortLocLine) { 663 port_flags = (XMOD_LINE_FLAG << XMOD_FLAGS_SHIFT); /* line interface */ 664 } 665 666 /* write args to xmod buffer */ 667 x_flags = flags; 668 buftxptr = (uint8_t *)xmodtxbuff; 669 WRITE_XMOD_ARG_BUFF(buftxptr, &x_flags, sizeof(uint8_t)); 670 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_INTERFACE_CONFIG_GET); 671 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 672 673 /* call xmod */ 674 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_INTERFACE_CONFIG_GET); 675 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 676 677 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_INTERFACE_CONFIG_GET) | port_flags, 678 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 679 680 /* retrieve the argument from the xmod rx buffer */ 681 bufrxptr = (uint8_t *)xmodrxbuff; 682 READ_XMOD_ARG_BUFF(bufrxptr, &x_config, sizeof(xmod_phy_inf_config_t)); 683 config->interface_type = x_config.interface_type; 684 config->device_aux_modes = x_config.device_aux_modes; 685 config->ref_clock = x_config.ref_clock; 686 config->data_rate = LE2HOST32(x_config.data_rate); 687 config->interface_modes = LE2HOST32(x_config.interface_modes); 688 config->pll_divider_req = LE2HOST16(x_config.pll_divider_req); 689 690 return rv; 691 } 692 693 694 int phy8806x_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 695 { 696 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 697 uint8_t *buftxptr; 698 int xmodtxlen, rv; 699 xmod_cl72_t cl72_st; 700 701 /* write args to xmod buffer */ 702 buftxptr = (uint8_t *)xmodtxbuff; 703 704 cl72_st.enable = cl72_en & 0xFF; 705 cl72_st.sys_side = 0; 706 if (cl72_en & PORT_SYS_SIDE_CTRL) 707 cl72_st.sys_side = 1; 708 WRITE_XMOD_ARG_BUFF(buftxptr, &cl72_st, sizeof(xmod_cl72_t)); 709 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_CL72_SET); 710 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 711 712 /* call xmod */ 713 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_CL72_SET), 714 xmodtxbuff, xmodtxlen, NULL, 0); 715 716 return rv; 717 } 718 719 720 int phy8806x_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 721 { 722 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 723 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 724 uint8_t *buftxptr; 725 int xmodtxlen; 726 uint8_t *bufrxptr; 727 int xmodrxlen, rv; 728 uint32_t sys_side = 0; 729 730 if (*cl72_en & PORT_SYS_SIDE_CTRL) { 731 sys_side = 1; 732 } 733 734 *cl72_en = 0; 735 sys_side = HOST2LE32(sys_side); 736 737 /* write args to xmod buffer */ 738 buftxptr = (uint8_t *)xmodtxbuff; 739 WRITE_XMOD_ARG_BUFF(buftxptr, &sys_side, sizeof(uint32_t)); 740 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_CL72_GET); 741 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 742 743 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_CL72_GET); 744 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 745 746 /* call xmod */ 747 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_CL72_GET), 748 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 749 750 /* retrieve the argument from the xmod rx buffer */ 751 bufrxptr = (uint8_t *)xmodrxbuff; 752 READ_XMOD_ARG_BUFF(bufrxptr, cl72_en, sizeof(uint32_t)); 753 754 *cl72_en = LE2HOST32(*cl72_en); 755 756 return rv; 757 } 758 759 760 int phy8806x_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 761 { 762 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 763 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 764 uint8_t *buftxptr; 765 int xmodtxlen; 766 uint8_t *bufrxptr; 767 int xmodrxlen, rv; 768 uint32_t sys_side = 0; 769 xmod_cl72_status_t cl72_st; 770 771 sys_side = (phy->port_loc == phymodPortLocSys) ? 1 : 0; 772 773 sys_side = HOST2LE32(sys_side); 774 775 /* write args to xmod buffer */ 776 buftxptr = (uint8_t *)xmodtxbuff; 777 WRITE_XMOD_ARG_BUFF(buftxptr, &sys_side, sizeof(uint32_t)); 778 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_CL72_STATUS_GET); 779 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 780 781 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_CL72_STATUS_GET); 782 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 783 784 /* call xmod */ 785 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_CL72_STATUS_GET), 786 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 787 788 /* retrieve the argument from the xmod rx buffer */ 789 bufrxptr = (uint8_t *)xmodrxbuff; 790 READ_XMOD_ARG_BUFF(bufrxptr, &cl72_st, sizeof(xmod_cl72_status_t)); 791 792 status->enabled = LE2HOST32(cl72_st.enabled); 793 status->locked = LE2HOST32(cl72_st.locked); 794 795 return rv; 796 797 } 798 799 800 int phy8806x_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 801 { 802 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 803 uint8_t *buftxptr; 804 xmod_autoneg_ability_t x_an_ability; 805 int xmodtxlen, rv; 806 807 /* write args to xmod buffer */ 808 buftxptr = (uint8_t *)xmodtxbuff; 809 x_an_ability.sgmii_speed = an_ability->sgmii_speed; 810 811 x_an_ability.an_cap = HOST2LE32(an_ability->an_cap); 812 x_an_ability.cl73bam_cap = HOST2LE32(an_ability->cl73bam_cap); 813 x_an_ability.cl37bam_cap = HOST2LE32(an_ability->cl37bam_cap); 814 x_an_ability.an_fec = HOST2LE32(an_ability->an_fec); 815 x_an_ability.an_cl72 = HOST2LE32(an_ability->an_cl72); 816 x_an_ability.an_hg2 = HOST2LE32(an_ability->an_hg2); 817 x_an_ability.capabilities = HOST2LE32(an_ability->capabilities); 818 819 WRITE_XMOD_ARG_BUFF(buftxptr, &x_an_ability, sizeof(xmod_autoneg_ability_t)); 820 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AUTONEG_ABILITY_SET); 821 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 822 823 /* call xmod */ 824 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_ABILITY_SET), 825 xmodtxbuff, xmodtxlen, NULL, 0); 826 827 return rv; 828 } 829 830 831 int phy8806x_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability) 832 { 833 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 834 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 835 uint8_t *bufrxptr; 836 xmod_autoneg_ability_t x_an_ability; 837 int xmodtxlen, xmodrxlen, rv; 838 839 /* write args to xmod buffer */ 840 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AUTONEG_ABILITY_GET); 841 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 842 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AUTONEG_ABILITY_GET); 843 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 844 845 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_ABILITY_GET), 846 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 847 848 bufrxptr = (uint8_t *)xmodrxbuff; 849 READ_XMOD_ARG_BUFF(bufrxptr, &x_an_ability, sizeof(xmod_autoneg_ability_t)); 850 851 an_ability->sgmii_speed = x_an_ability.sgmii_speed; 852 an_ability->an_cap = LE2HOST32(x_an_ability.an_cap); 853 an_ability->cl73bam_cap = LE2HOST32(x_an_ability.cl73bam_cap); 854 an_ability->cl37bam_cap = LE2HOST32(x_an_ability.cl37bam_cap); 855 an_ability->an_fec = LE2HOST32(x_an_ability.an_fec); 856 an_ability->an_cl72 = LE2HOST32(x_an_ability.an_cl72); 857 an_ability->an_hg2 = LE2HOST32(x_an_ability.an_hg2); 858 an_ability->capabilities = LE2HOST32(x_an_ability.capabilities); 859 860 return rv; 861 } 862 863 864 int phy8806x_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability) 865 { 866 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 867 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 868 uint8_t *bufrxptr; 869 xmod_autoneg_ability_t x_an_ability; 870 int xmodtxlen, xmodrxlen, rv; 871 872 /* write args to xmod buffer */ 873 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AUTONEG_REMOTE_ABILITY_GET); 874 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 875 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AUTONEG_REMOTE_ABILITY_GET); 876 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 877 878 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_REMOTE_ABILITY_GET), 879 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 880 881 bufrxptr = (uint8_t *)xmodrxbuff; 882 READ_XMOD_ARG_BUFF(bufrxptr, &x_an_ability, sizeof(xmod_autoneg_ability_t)); 883 884 an_ability->sgmii_speed = x_an_ability.sgmii_speed; 885 an_ability->an_cap = LE2HOST32(x_an_ability.an_cap); 886 an_ability->cl73bam_cap = LE2HOST32(x_an_ability.cl73bam_cap); 887 an_ability->cl37bam_cap = LE2HOST32(x_an_ability.cl37bam_cap); 888 an_ability->an_fec = LE2HOST32(x_an_ability.an_fec); 889 an_ability->an_cl72 = LE2HOST32(x_an_ability.an_cl72); 890 an_ability->an_hg2 = LE2HOST32(x_an_ability.an_hg2); 891 an_ability->capabilities = LE2HOST32(x_an_ability.capabilities); 892 893 return rv; 894 } 895 896 897 int phy8806x_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 898 { 899 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 900 uint8_t *buftxptr; 901 int xmodtxlen, rv=PHYMOD_E_NONE; 902 xmod_autoneg_control_t x_an_ctrl; 903 904 x_an_ctrl.an_mode = an->an_mode; 905 x_an_ctrl.an_done = 0; 906 x_an_ctrl.num_lane_adv = HOST2LE32(an->num_lane_adv); 907 x_an_ctrl.flags = HOST2LE32(an->flags); 908 x_an_ctrl.enable = HOST2LE32(an->enable); 909 910 if (!(an->enable)) { 911 /* write args to xmod buffer */ 912 buftxptr = (uint8_t *) xmodtxbuff; 913 WRITE_XMOD_ARG_BUFF(buftxptr, &x_an_ctrl, sizeof(x_an_ctrl)); 914 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AUTONEG_SET); 915 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 916 917 /* call xmod */ 918 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_SET), 919 xmodtxbuff, xmodtxlen, NULL, 0); 920 } 921 922 return rv; 923 } 924 925 926 int phy8806x_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 927 { 928 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 929 uint8_t *bufrxptr; 930 int xmodrxlen, rv; 931 xmod_autoneg_control_t x_an_ctrl; 932 933 /* write args to xmod buffer */ 934 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AUTONEG_GET); 935 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 936 937 /* call xmod */ 938 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_GET), 939 NULL, 0, xmodrxbuff, xmodrxlen); 940 941 /* retrieve the argument from the xmod rx buffer */ 942 bufrxptr = (uint8_t *)xmodrxbuff; 943 READ_XMOD_ARG_BUFF(bufrxptr, &x_an_ctrl, sizeof(xmod_autoneg_control_t)); 944 945 an->an_mode = x_an_ctrl.an_mode; 946 an->num_lane_adv = LE2HOST32(x_an_ctrl.num_lane_adv); 947 an->flags = LE2HOST32(x_an_ctrl.flags); 948 an->enable = LE2HOST32(x_an_ctrl.enable); 949 950 *an_done = x_an_ctrl.an_done; 951 952 return rv; 953 } 954 955 956 int phy8806x_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 957 { 958 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 959 uint8_t *bufrxptr; 960 int xmodrxlen, rv; 961 xmod_autoneg_status_t x_an_status; 962 963 /* write args to xmod buffer */ 964 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AUTONEG_STATUS_GET); 965 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 966 967 /* call xmod */ 968 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_STATUS_GET), 969 NULL, 0, xmodrxbuff, xmodrxlen); 970 971 /* retrieve the argument from the xmod rx buffer */ 972 bufrxptr = (uint8_t *)xmodrxbuff; 973 READ_XMOD_ARG_BUFF(bufrxptr, &x_an_status, sizeof(xmod_autoneg_status_t)); 974 975 status->enabled = LE2HOST32(x_an_status.enabled); 976 status->locked = LE2HOST32(x_an_status.locked); 977 status->data_rate = LE2HOST32(x_an_status.data_rate); 978 status->interface = LE2HOST32(x_an_status.interface); 979 980 return rv; 981 } 982 983 984 int phy8806x_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 985 { 986 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 987 uint8_t *buftxptr; 988 int xmodtxlen; 989 xmod_core_init_config_t x_core_init; 990 int idx, rv; 991 992 /* setting up xmod xmod_core_init: */ 993 /* int xmod_core_init( IN xmod_core_init_config_t* init_config ) */ 994 995 /* Initialize the xmod_core_init_config_t structure */ 996 x_core_init.num_of_lanes = HOST2LE32(init_config->lane_map.num_of_lanes); 997 x_core_init.ref_clock = HOST2LE32(xmodRefClk156Mhz); 998 x_core_init.tx_polarity = HOST2LE32(init_config->polarity_map.tx_polarity); 999 x_core_init.rx_polarity = HOST2LE32(init_config->polarity_map.rx_polarity); 1000 1001 for (idx=0; idx<XMOD_MAX_LANES_PER_CORE; idx++) { 1002 x_core_init.lane_map_rx[idx] = HOST2LE32(init_config->lane_map.lane_map_rx[idx]); 1003 x_core_init.lane_map_tx[idx] = HOST2LE32(init_config->lane_map.lane_map_tx[idx]); 1004 } 1005 x_core_init.core_mode = init_config->core_mode; 1006 x_core_init.trcvr_host_managed = init_config->trcvr_host_managed; 1007 1008 /* write args to xmod buffer */ 1009 buftxptr = (uint8_t *)xmodtxbuff; 1010 WRITE_XMOD_ARG_BUFF(buftxptr, &x_core_init, sizeof(xmod_core_init_config_t)); 1011 xmodtxlen = GET_XMOD_CORE_CMD_IN_LEN(XMOD_CORE_INIT); 1012 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1013 1014 /* call xmod */ 1015 rv = _phy_8806x_xmod_command(&core->access, XMOD_CORE_INIT, xmodtxbuff, xmodtxlen, NULL, 0); 1016 1017 return rv; 1018 } 1019 1020 1021 int phy8806x_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 1022 { 1023 return PHYMOD_E_NONE; 1024 } 1025 1026 1027 int phy8806x_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 1028 { 1029 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1030 uint8_t *buftxptr; 1031 uint8_t x_loopback; 1032 uint8_t x_enable; 1033 int xmodtxlen, rv; 1034 1035 /* setting up xmod xmod_phy_loopback_set: */ 1036 /* int xmod_phy_loopback_set( IN xmod_loopback_mode_t loopback_type, IN uint8_t enable ) */ 1037 1038 /* Initialize the xmod args */ 1039 x_loopback = loopback; 1040 x_enable = enable; 1041 1042 /* write args to xmod buffer */ 1043 buftxptr = (uint8_t *) xmodtxbuff; 1044 WRITE_XMOD_ARG_BUFF(buftxptr, &x_loopback, sizeof(x_loopback)); 1045 WRITE_XMOD_ARG_BUFF(buftxptr, &x_enable, sizeof(x_enable)); 1046 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_LOOPBACK_SET); 1047 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1048 1049 /* call xmod */ 1050 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_LOOPBACK_SET), 1051 xmodtxbuff, xmodtxlen, NULL, 0); 1052 1053 return rv; 1054 } 1055 1056 1057 int phy8806x_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 1058 { 1059 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1060 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1061 uint8_t *buftxptr, *bufrxptr; 1062 int xmodtxlen, xmodrxlen, rv; 1063 xmod_loopback_mode_t x_loopback; 1064 uint8_t x_enable; 1065 1066 /* setting up xmod xmod_phy_loopback_get: */ 1067 /* int xmod_phy_loopback_get( IN xmod_loopback_mode_t loopback_type, OUT uint8_t enable ) */ 1068 1069 /* Initialize the xmod args */ 1070 x_loopback = loopback; 1071 /* write args to xmod buffer */ 1072 buftxptr = (uint8_t *)xmodtxbuff; 1073 WRITE_XMOD_ARG_BUFF(buftxptr, &x_loopback, sizeof(x_loopback)); 1074 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_LOOPBACK_GET); 1075 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1076 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_LOOPBACK_GET); 1077 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1078 1079 /* call xmod */ 1080 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_LOOPBACK_GET), 1081 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1082 1083 /* retrieve the argument from the xmod rx buffer */ 1084 bufrxptr = (uint8_t *)xmodrxbuff; 1085 READ_XMOD_ARG_BUFF(bufrxptr, &x_enable, sizeof(uint8_t)); 1086 *enable = x_enable; 1087 1088 return rv; 1089 } 1090 1091 1092 int phy8806x_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done) 1093 { 1094 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1095 uint8_t *bufrxptr; 1096 int xmodrxlen, rv; 1097 int8_t lock_st = -1; 1098 1099 /* write args to xmod buffer */ 1100 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_RX_PMD_LOCKED_GET); 1101 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1102 1103 /* call xmod */ 1104 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_RX_PMD_LOCKED_GET), 1105 NULL, 0, xmodrxbuff, xmodrxlen); 1106 1107 1108 /* retrieve the argument from the xmod rx buffer */ 1109 bufrxptr = (uint8_t *)xmodrxbuff; 1110 READ_XMOD_ARG_BUFF(bufrxptr, &lock_st, sizeof(lock_st)); 1111 1112 if (lock_st != 1) 1113 *rx_seq_done = 0; 1114 else 1115 *rx_seq_done = 1; 1116 1117 return rv; 1118 } 1119 1120 1121 int phy8806x_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 1122 { 1123 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1124 uint8_t *bufrxptr; 1125 int xmodrxlen, rv; 1126 int8_t link_st = -1; 1127 1128 /* write args to xmod buffer */ 1129 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_LINK_STATUS_GET); 1130 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1131 1132 /* call xmod */ 1133 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_LINK_STATUS_GET), 1134 NULL, 0, xmodrxbuff, xmodrxlen); 1135 1136 1137 /* retrieve the argument from the xmod rx buffer */ 1138 bufrxptr = (uint8_t *)xmodrxbuff; 1139 READ_XMOD_ARG_BUFF(bufrxptr, &link_st, sizeof(link_st)); 1140 1141 if (link_st != 1) 1142 *link_status = 0; 1143 else 1144 *link_status = 1; 1145 1146 return rv; 1147 } 1148 1149 1150 int phy8806x_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config) 1151 { 1152 return PHYMOD_E_UNAVAIL; 1153 } 1154 1155 1156 int phy8806x_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config) 1157 { 1158 return PHYMOD_E_UNAVAIL; 1159 } 1160 1161 1162 int phy8806x_phy_status_dump(const phymod_phy_access_t* phy) 1163 { 1164 return PHYMOD_E_NONE; 1165 } 1166 1167 1168 int phy8806x_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t *val) 1169 { 1170 return PHYMOD_E_NONE; 1171 } 1172 1173 1174 int phy8806x_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 1175 { 1176 return PHYMOD_E_NONE; 1177 } 1178 1179 1180 int phy8806x_phy_private_read(const phymod_phy_access_t* phy, uint32_t addr, uint32_t *val) 1181 { 1182 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1183 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1184 uint8_t *buftxptr, *bufrxptr; 1185 int xmodtxlen, xmodrxlen, rv; 1186 uint32_t x_addr; 1187 1188 x_addr = addr; 1189 x_addr = HOST2LE32(x_addr); 1190 1191 buftxptr = (uint8_t *)xmodtxbuff; 1192 WRITE_XMOD_ARG_BUFF(buftxptr, &x_addr, sizeof(uint32_t)); 1193 xmodtxlen = GET_XMOD_CORE_CMD_IN_LEN(XMOD_DEV_REG_GET); 1194 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1195 1196 bufrxptr = (uint8_t *)xmodrxbuff; 1197 xmodrxlen = GET_XMOD_CORE_CMD_OUT_LEN(XMOD_DEV_REG_GET); 1198 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1199 1200 /* call xmod */ 1201 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_CORE(XMOD_DEV_REG_GET), 1202 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1203 1204 /* retrieve the data from the xmod rx buffer */ 1205 bufrxptr = (uint8_t *)xmodrxbuff; 1206 READ_XMOD_ARG_BUFF(bufrxptr, val, sizeof(uint32_t)); 1207 *val = LE2HOST32(*val); 1208 1209 return rv; 1210 } 1211 1212 1213 int phy8806x_phy_private_write(const phymod_phy_access_t* phy, uint32_t addr, uint32_t val) 1214 { 1215 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1216 uint8_t *buftxptr; 1217 int xmodtxlen, rv; 1218 uint32_t x_addr, x_data; 1219 1220 x_addr = addr; 1221 x_data = val; 1222 x_addr = HOST2LE32(x_addr); 1223 x_data = HOST2LE32(x_data); 1224 1225 buftxptr = (uint8_t *)xmodtxbuff; 1226 WRITE_XMOD_ARG_BUFF(buftxptr, &x_addr, sizeof(uint32_t)); 1227 WRITE_XMOD_ARG_BUFF(buftxptr, &x_data, sizeof(uint32_t)); 1228 xmodtxlen = GET_XMOD_CORE_CMD_IN_LEN(XMOD_DEV_REG_SET); 1229 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1230 1231 /* call xmod */ 1232 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_CORE(XMOD_DEV_REG_SET), 1233 xmodtxbuff, xmodtxlen, NULL, 0); 1234 1235 return rv; 1236 } 1237 1238 1239 int phy8806x_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data) 1240 { 1241 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1242 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1243 uint8_t *buftxptr, *bufrxptr; 1244 int xmodtxlen, xmodrxlen, rv; 1245 xmod_core_i2c_t xmod_core_i2c; 1246 uint32_t smstat; 1247 1248 xmod_core_i2c.dev_addr = (uint8_t) (addr & 0xff); 1249 xmod_core_i2c.offset = (uint8_t) (offset & 0xff); 1250 xmod_core_i2c.size = (uint8_t) (size & 0xff); 1251 buftxptr = (uint8_t *)xmodtxbuff; 1252 WRITE_XMOD_ARG_BUFF(buftxptr, &xmod_core_i2c, sizeof(xmod_core_i2c_t)); 1253 xmodtxlen = GET_XMOD_CORE_CMD_IN_LEN(XMOD_DEV_I2C_GET); 1254 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1255 1256 bufrxptr = (uint8_t *)xmodrxbuff; 1257 /* This is the max size of xmod rx buffer */ 1258 xmodrxlen = GET_XMOD_CORE_CMD_OUT_LEN(XMOD_DEV_I2C_GET); 1259 if (xmod_core_i2c.size > (xmodrxlen - sizeof(uint32_t))) { 1260 return PHYMOD_E_PARAM; 1261 } 1262 /* For optimization, we will use the actual size of 1263 xmod rx buffer as below. This is run time size as 1264 opposed to the compile time size coming from 1265 xmod_core_cmds_arg_len_tbl. 1266 */ 1267 xmodrxlen = sizeof(uint32_t) + xmod_core_i2c.size; 1268 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1269 1270 /* call xmod */ 1271 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_CORE(XMOD_DEV_I2C_GET), 1272 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1273 1274 /* retrieve the SMBUS Status and the read data from the xmod rx buffer */ 1275 READ_XMOD_ARG_BUFF(bufrxptr, &smstat, sizeof(uint32_t)); 1276 smstat = LE2HOST32(smstat); 1277 READ_XMOD_ARG_BUFF(bufrxptr, data, xmod_core_i2c.size); 1278 if (smstat != 0) { 1279 PHYMOD_DEBUG_ERROR(("I2C / SMBUS Error %d\n", smstat)); 1280 return PHYMOD_E_FAIL; 1281 } 1282 1283 return rv; 1284 } 1285 1286 1287 int phy8806x_phy_i2c_write(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, const uint8_t* data) 1288 { 1289 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1290 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1291 uint8_t *buftxptr, *bufrxptr; 1292 int xmodtxlen, xmodrxlen, rv; 1293 xmod_core_i2c_t xmod_core_i2c; 1294 uint32_t smstat, data32; 1295 1296 xmod_core_i2c.dev_addr = (uint8_t) (addr & 0xff); 1297 xmod_core_i2c.offset = (uint8_t) (offset & 0xff); 1298 xmod_core_i2c.size = (uint8_t) (size & 0xff); 1299 PHYMOD_MEMCPY((void*)&data32, (void*)data, sizeof(uint32_t)); 1300 data32 = HOST2LE32(data32); 1301 1302 buftxptr = (uint8_t *)xmodtxbuff; 1303 WRITE_XMOD_ARG_BUFF(buftxptr, &xmod_core_i2c, sizeof(xmod_core_i2c_t)); 1304 WRITE_XMOD_ARG_BUFF(buftxptr, &data32, sizeof(uint32_t)); 1305 xmodtxlen = GET_XMOD_CORE_CMD_IN_LEN(XMOD_DEV_I2C_SET); 1306 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1307 1308 bufrxptr = (uint8_t *)xmodrxbuff; 1309 xmodrxlen = GET_XMOD_CORE_CMD_OUT_LEN(XMOD_DEV_I2C_SET); 1310 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1311 1312 /* call xmod */ 1313 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_CORE(XMOD_DEV_I2C_SET), 1314 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1315 1316 /* retrieve the SMBUS Status from the xmod rx buffer */ 1317 READ_XMOD_ARG_BUFF(bufrxptr, &smstat, sizeof(uint32_t)); 1318 smstat = LE2HOST32(smstat); 1319 1320 if (smstat != 0) { 1321 PHYMOD_DEBUG_ERROR(("I2C / SMBUS Error %d\n", smstat)); 1322 return PHYMOD_E_FAIL; 1323 } 1324 1325 return rv; 1326 } 1327 1328 1329 int phy8806x_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable) 1330 { 1331 return PHYMOD_E_NONE; 1332 } 1333 1334 1335 int phy8806x_phy_eee_get(const phymod_phy_access_t* phy, uint32_t *enable) 1336 { 1337 return PHYMOD_E_NONE; 1338 } 1339 1340 1341 int phy8806x_port_init(const phymod_phy_access_t* phy, phymod_port_config_t *port_config) 1342 { 1343 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1344 uint8_t *buftxptr; 1345 xmod_port_config_t x_port_config; 1346 int xmodtxlen, rv; 1347 1348 /* setting up xmod xmod_port_init: */ 1349 /* int int xmod_port_init( IN xmod_port_config_t port_config ) */ 1350 1351 x_port_config.speed = HOST2LE32(port_config->speed); 1352 x_port_config.interface = port_config->interface; 1353 x_port_config.sys_lane_count = port_config->sys_lane_count; 1354 x_port_config.ln_lane_count = port_config->ln_lane_count; 1355 x_port_config.an_mode = port_config->an_mode; 1356 x_port_config.an_cl72 = port_config->an_cl72; 1357 x_port_config.fs_cl72 = port_config->fs_cl72; 1358 x_port_config.fs_cl72_sys = port_config->fs_cl72_sys; 1359 x_port_config.an_fec = port_config->an_fec; 1360 x_port_config.port_is_higig = port_config->port_is_higig; 1361 x_port_config.fiber_pref = port_config->fiber_pref; 1362 x_port_config.fiber_pref_sys = port_config->fiber_pref_sys; 1363 x_port_config.port_mode = port_config->port_mode; 1364 x_port_config.is_bootmaster = port_config->is_bootmaster; 1365 x_port_config.fs_fec = port_config->fs_fec; 1366 x_port_config.fs_fec_sys = port_config->fs_fec_sys; 1367 x_port_config.is_flex = port_config->is_flex; 1368 x_port_config.is_strip_crc = 0; 1369 x_port_config.quad_mode = port_config->quad_mode; 1370 1371 /* write args to xmod buffer */ 1372 buftxptr = (uint8_t *)xmodtxbuff; 1373 WRITE_XMOD_ARG_BUFF(buftxptr, &x_port_config, sizeof(xmod_port_config_t)); 1374 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PORT_INIT); 1375 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1376 1377 /* call xmod */ 1378 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PORT_INIT), 1379 xmodtxbuff, xmodtxlen, NULL, 0); 1380 1381 /* to remove warning */ 1382 xmodtxlen = GET_XMOD_FC_CMD_IN_LEN(0); 1383 1384 return rv; 1385 } 1386 1387 1388 int phy8806x_phy_autoneg_try_enable(const phymod_phy_access_t* phy, const phymod_an_try_enable_control_t* an, 1389 phymod_phy_an_status_t* an_status) 1390 { 1391 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1392 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1393 int xmodtxlen, xmodrxlen, rv; 1394 uint8_t *buftxptr, *bufrxptr; 1395 xmod_an_status_t x_an_status; 1396 xmod_an_try_enable_control_t x_an_ctrl; 1397 1398 /* write args to xmod buffer */ 1399 x_an_ctrl.an_mode = an->an_mode; 1400 x_an_ctrl.num_lane_adv = HOST2LE32(an->num_lane_adv); 1401 x_an_ctrl.flags = HOST2LE32(an->flags); 1402 x_an_ctrl.enable = HOST2LE32(an->enable); 1403 x_an_ctrl.speed = HOST2LE32(an->speed); 1404 1405 buftxptr = (uint8_t *)xmodtxbuff; 1406 WRITE_XMOD_ARG_BUFF(buftxptr, &x_an_ctrl, sizeof(x_an_ctrl)); 1407 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AN_TRY_ENABLE); 1408 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1409 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AN_TRY_ENABLE); 1410 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1411 1412 /* call xmod */ 1413 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AN_TRY_ENABLE), 1414 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1415 1416 /* retrieve the argument from the xmod rx buffer */ 1417 bufrxptr = (uint8_t *)xmodrxbuff; 1418 READ_XMOD_ARG_BUFF(bufrxptr, &x_an_status, sizeof(xmod_an_status_t)); 1419 an_status->result = x_an_status.result; 1420 an_status->hcd_speed = LE2HOST32(x_an_status.hcd_speed); 1421 1422 return rv; 1423 } 1424 1425 int phy8806x_phy_pfc_use_ip_cos_get(const phymod_phy_access_t* phy, uint32_t* enable) 1426 { 1427 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1428 uint8_t *bufrxptr; 1429 int xmodrxlen, rv; 1430 1431 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_PSM_COS_BMP_GET); 1432 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1433 1434 /* call xmod */ 1435 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_PSM_COS_BMP_GET), 1436 NULL, 0, xmodrxbuff, xmodrxlen); 1437 1438 /* retrieve the argument from the xmod rx buffer */ 1439 bufrxptr = (uint8_t *)xmodrxbuff; 1440 READ_XMOD_ARG_BUFF(bufrxptr, enable, sizeof(uint32_t)); 1441 1442 *enable = LE2HOST32(*enable); 1443 *enable = (*enable) >> XMOD_USE_IP_COS_SHIFT; 1444 1445 return rv; 1446 } 1447 1448 int phy8806x_phy_pfc_use_ip_cos_set(const phymod_phy_access_t* phy, uint32_t enable) 1449 { 1450 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1451 uint8_t *buftxptr; 1452 int xmodtxlen, rv; 1453 1454 /* write args to xmod buffer */ 1455 buftxptr = (uint8_t *)xmodtxbuff; 1456 1457 enable |= (XMOD_USE_IP_COS_CMD << XMOD_USE_IP_COS_SHIFT); 1458 enable = HOST2LE32(enable); 1459 WRITE_XMOD_ARG_BUFF(buftxptr, &enable, sizeof(uint32_t)); 1460 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_PSM_COS_BMP_SET); 1461 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1462 1463 /* call xmod */ 1464 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_PSM_COS_BMP_SET), 1465 xmodtxbuff, xmodtxlen, NULL, 0); 1466 1467 return rv; 1468 } 1469 1470 int phy8806x_phy_psm_cos_bmp_get(const phymod_phy_access_t* phy, uint32_t* cos_bmp) 1471 { 1472 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1473 uint8_t *bufrxptr; 1474 int xmodrxlen, rv; 1475 1476 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_PSM_COS_BMP_GET); 1477 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1478 1479 /* call xmod */ 1480 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_PSM_COS_BMP_GET), 1481 NULL, 0, xmodrxbuff, xmodrxlen); 1482 1483 /* retrieve the argument from the xmod rx buffer */ 1484 bufrxptr = (uint8_t *)xmodrxbuff; 1485 READ_XMOD_ARG_BUFF(bufrxptr, cos_bmp, sizeof(uint32_t)); 1486 1487 *cos_bmp = LE2HOST32(*cos_bmp); 1488 *cos_bmp &= (1 << XMOD_USE_IP_COS_SHIFT)-1; 1489 1490 return rv; 1491 } 1492 1493 int phy8806x_phy_psm_cos_bmp_set(const phymod_phy_access_t* phy, uint32_t cos_bmp) 1494 { 1495 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1496 uint8_t *buftxptr; 1497 int xmodtxlen, rv; 1498 1499 /* write args to xmod buffer */ 1500 buftxptr = (uint8_t *)xmodtxbuff; 1501 1502 cos_bmp = HOST2LE32(cos_bmp); 1503 WRITE_XMOD_ARG_BUFF(buftxptr, &cos_bmp, sizeof(uint32_t)); 1504 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_PSM_COS_BMP_SET); 1505 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1506 1507 /* call xmod */ 1508 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_PSM_COS_BMP_SET), 1509 xmodtxbuff, xmodtxlen, NULL, 0); 1510 1511 return rv; 1512 1513 } 1514 1515 int phy8806x_phy_flow_control_mode_get(const phymod_phy_access_t* phy, uint32_t ingress, uint32_t* mode) 1516 { 1517 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1518 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1519 uint8_t *buftxptr; 1520 int xmodtxlen; 1521 uint8_t *bufrxptr; 1522 int xmodrxlen, rv; 1523 1524 ingress = HOST2LE32(ingress); 1525 1526 /* write args to xmod buffer */ 1527 buftxptr = (uint8_t *)xmodtxbuff; 1528 WRITE_XMOD_ARG_BUFF(buftxptr, &ingress, sizeof(uint32_t)); 1529 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FLOW_CONTROL_MODE_GET); 1530 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1531 1532 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_FLOW_CONTROL_MODE_GET); 1533 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1534 1535 /* call xmod */ 1536 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FLOW_CONTROL_MODE_GET), 1537 xmodtxbuff, xmodtxlen, xmodrxbuff, xmodrxlen); 1538 1539 /* retrieve the argument from the xmod rx buffer */ 1540 bufrxptr = (uint8_t *)xmodrxbuff; 1541 READ_XMOD_ARG_BUFF(bufrxptr, mode, sizeof(uint32_t)); 1542 1543 *mode = LE2HOST32(*mode); 1544 1545 return rv; 1546 } 1547 1548 int phy8806x_phy_flow_control_mode_set(const phymod_phy_access_t* phy, uint32_t mode, uint32_t ingress) 1549 { 1550 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1551 uint8_t *buftxptr; 1552 int xmodtxlen, rv; 1553 xmod_flow_ctrl_t flow_ctrl; 1554 1555 /* write args to xmod buffer */ 1556 buftxptr = (uint8_t *)xmodtxbuff; 1557 1558 flow_ctrl.mode = mode; 1559 flow_ctrl.ingress = ingress; 1560 1561 WRITE_XMOD_ARG_BUFF(buftxptr, &flow_ctrl, sizeof(xmod_flow_ctrl_t)); 1562 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FLOW_CONTROL_MODE_SET); 1563 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1564 1565 /* call xmod */ 1566 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FLOW_CONTROL_MODE_SET), 1567 xmodtxbuff, xmodtxlen, NULL, 0); 1568 1569 return rv; 1570 } 1571 1572 int phy8806x_phy_forced_speed_line_side_get(const phymod_phy_access_t* phy, uint32_t* speed) 1573 { 1574 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1575 uint8_t *bufrxptr; 1576 int xmodrxlen, rv; 1577 1578 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_FORCED_SPEED_LINE_SIDE_GET); 1579 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1580 1581 /* call xmod */ 1582 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FORCED_SPEED_LINE_SIDE_GET), 1583 NULL, 0, xmodrxbuff, xmodrxlen); 1584 1585 /* retrieve the argument from the xmod rx buffer */ 1586 bufrxptr = (uint8_t *)xmodrxbuff; 1587 READ_XMOD_ARG_BUFF(bufrxptr, speed, sizeof(uint32_t)); 1588 1589 *speed = LE2HOST32(*speed); 1590 1591 return rv; 1592 } 1593 1594 int phy8806x_phy_forced_speed_line_side_set(const phymod_phy_access_t* phy, uint32_t speed) 1595 { 1596 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1597 uint8_t *buftxptr; 1598 int xmodtxlen, rv; 1599 1600 /* write args to xmod buffer */ 1601 buftxptr = (uint8_t *)xmodtxbuff; 1602 1603 speed = HOST2LE32(speed); 1604 1605 WRITE_XMOD_ARG_BUFF(buftxptr, &speed, sizeof(uint32_t)); 1606 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_FORCED_SPEED_LINE_SIDE_SET); 1607 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1608 1609 /* call xmod */ 1610 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_FORCED_SPEED_LINE_SIDE_SET), 1611 xmodtxbuff, xmodtxlen, NULL, 0); 1612 1613 return rv; 1614 1615 } 1616 1617 int phy8806x_phy_autoneg_line_side_get(const phymod_phy_access_t* phy, uint32_t* enable) 1618 { 1619 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1620 uint8_t *bufrxptr; 1621 int xmodrxlen, rv; 1622 1623 xmodrxlen = GET_XMOD_ETHERNET_CMD_OUT_LEN(XMOD_PHY_AUTONEG_LINE_SIDE_GET); 1624 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1625 1626 /* call xmod */ 1627 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_LINE_SIDE_GET), 1628 NULL, 0, xmodrxbuff, xmodrxlen); 1629 1630 /* retrieve the argument from the xmod rx buffer */ 1631 bufrxptr = (uint8_t *)xmodrxbuff; 1632 READ_XMOD_ARG_BUFF(bufrxptr, enable, sizeof(uint32_t)); 1633 1634 *enable = LE2HOST32(*enable); 1635 1636 return rv; 1637 } 1638 1639 int phy8806x_phy_autoneg_line_side_set(const phymod_phy_access_t* phy, uint32_t enable) 1640 { 1641 uint32_t xmodtxbuff[XMOD_BUFFER_MAX_LEN/4]; 1642 uint8_t *buftxptr; 1643 int xmodtxlen, rv; 1644 1645 /* write args to xmod buffer */ 1646 buftxptr = (uint8_t *)xmodtxbuff; 1647 1648 enable = HOST2LE32(enable); 1649 WRITE_XMOD_ARG_BUFF(buftxptr, &enable, sizeof(uint32_t)); 1650 xmodtxlen = GET_XMOD_ETHERNET_CMD_IN_LEN(XMOD_PHY_AUTONEG_LINE_SIDE_SET); 1651 xmodtxlen = GET_XMOD_BUF_WORD_LEN(xmodtxlen); 1652 1653 /* call xmod */ 1654 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_ETH(XMOD_PHY_AUTONEG_LINE_SIDE_SET), 1655 xmodtxbuff, xmodtxlen, NULL, 0); 1656 1657 return rv; 1658 1659 } 1660 1661 int phy8806x_debug_ether(const phymod_phy_access_t* phy) 1662 { 1663 uint32_t xmodrxbuff[XMOD_BUFFER_MAX_LEN/4]; 1664 uint8_t *bufrxptr; 1665 int xmodrxlen, rv; 1666 xmod_debug_ether_t x_debug_ether; 1667 1668 xmodrxlen = GET_XMOD_CORE_CMD_OUT_LEN(XMOD_DEV_DEBUG_ETHER_CMD); 1669 xmodrxlen = GET_XMOD_BUF_WORD_LEN(xmodrxlen); 1670 1671 /* call xmod */ 1672 rv = _phy_8806x_xmod_command(&phy->access, XMOD_CMD_MODE_CORE(XMOD_DEV_DEBUG_ETHER_CMD), 1673 NULL, 0, xmodrxbuff, xmodrxlen); 1674 1675 /* retrieve the argument from the xmod rx buffer */ 1676 bufrxptr = (uint8_t *)xmodrxbuff; 1677 READ_XMOD_ARG_BUFF(bufrxptr, &x_debug_ether, sizeof(x_debug_ether)); 1678 1679 PHYMOD_DIAG_OUT(("Line side Link status: %d \n", x_debug_ether.link_state_ln_side)); 1680 PHYMOD_DIAG_OUT(("System side Link status: %d \n", x_debug_ether.link_state_sys_side)); 1681 1682 PHYMOD_DIAG_OUT(("System side Speed: %d \n", LE2HOST32(x_debug_ether.link_speed_sys_side))); 1683 PHYMOD_DIAG_OUT(("Line side Speed: %d \n", LE2HOST32(x_debug_ether.link_speed_ln_side))); 1684 1685 PHYMOD_DIAG_OUT(("Line side CL72 status: %d \n", x_debug_ether.link_cl72_ln_side)); 1686 PHYMOD_DIAG_OUT(("System side CL72 status: %d \n", x_debug_ether.link_cl72_sys_side)); 1687 1688 PHYMOD_DIAG_OUT(("Line side FEC status: %d \n", x_debug_ether.link_fec_ln_side)); 1689 PHYMOD_DIAG_OUT(("System side FEC status: %d \n", x_debug_ether.link_fec_sys_side)); 1690 1691 return rv; 1692 } 1693 1694 int phy8806x_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode) 1695 { 1696 return PHYMOD_E_UNAVAIL; 1697 } 1698 1699 #endif /* PHYMOD_PHY8806X_SUPPORT */