Commit 9b18e5199ec42f9dc62c0da7f4fe7554e199980d

Authored by Shengzhou Liu
Committed by York Sun
1 parent 84baed2a2b

net/phy: Add support for CS4315/CS4340 PHY

Add support for Cortina CS4315/CS4340 10G PHY.
- This driver loads CS43xx firmware from NOR/NAND/SPI/SD device
  to initialize Cortina PHY.
- Cortina PHY has non-standard offset of PHY ID registers, thus
  we define own get_phy_id() to override default get_phy_id().
- To define macro CONFIG_PHY_CORTINA will enable this driver.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 5 changed files with 414 additions and 0 deletions Side-by-side Diff

drivers/net/phy/Makefile
... ... @@ -13,6 +13,7 @@
13 13 obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
14 14 obj-$(CONFIG_PHY_ATHEROS) += atheros.o
15 15 obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
  16 +obj-$(CONFIG_PHY_CORTINA) += cortina.o
16 17 obj-$(CONFIG_PHY_DAVICOM) += davicom.o
17 18 obj-$(CONFIG_PHY_ET1011C) += et1011c.o
18 19 obj-$(CONFIG_PHY_LXT) += lxt.o
drivers/net/phy/cortina.c
  1 +/*
  2 + * Cortina CS4315/CS4340 10G PHY drivers
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + *
  6 + * Copyright 2014 Freescale Semiconductor, Inc.
  7 + *
  8 + */
  9 +
  10 +#include <config.h>
  11 +#include <common.h>
  12 +#include <malloc.h>
  13 +#include <linux/ctype.h>
  14 +#include <linux/string.h>
  15 +#include <linux/err.h>
  16 +#include <phy.h>
  17 +#include <cortina.h>
  18 +#ifdef CONFIG_SYS_CORTINA_FW_IN_NAND
  19 +#include <nand.h>
  20 +#elif defined(CONFIG_SYS_CORTINA_FW_IN_SPIFLASH)
  21 +#include <spi_flash.h>
  22 +#elif defined(CONFIG_SYS_CORTINA_FW_IN_MMC)
  23 +#include <mmc.h>
  24 +#endif
  25 +
  26 +#ifndef CONFIG_PHYLIB_10G
  27 +#error The Cortina PHY needs 10G support
  28 +#endif
  29 +
  30 +struct cortina_reg_config cortina_reg_cfg[] = {
  31 + /* CS4315_enable_sr_mode */
  32 + {VILLA_GLOBAL_MSEQCLKCTRL, 0x8004},
  33 + {VILLA_MSEQ_OPTIONS, 0xf},
  34 + {VILLA_MSEQ_PC, 0x0},
  35 + {VILLA_MSEQ_BANKSELECT, 0x4},
  36 + {VILLA_LINE_SDS_COMMON_SRX0_RX_CPA, 0x55},
  37 + {VILLA_LINE_SDS_COMMON_SRX0_RX_LOOP_FILTER, 0x30},
  38 + {VILLA_DSP_SDS_SERDES_SRX_DFE0_SELECT, 0x1},
  39 + {VILLA_DSP_SDS_DSP_COEF_DFE0_SELECT, 0x2},
  40 + {VILLA_LINE_SDS_COMMON_SRX0_RX_CPB, 0x2003},
  41 + {VILLA_DSP_SDS_SERDES_SRX_FFE_DELAY_CTRL, 0xF047},
  42 + {VILLA_MSEQ_ENABLE_MSB, 0x0000},
  43 + {VILLA_MSEQ_SPARE21_LSB, 0x6},
  44 + {VILLA_MSEQ_RESET_COUNT_LSB, 0x0},
  45 + {VILLA_MSEQ_SPARE12_MSB, 0x0000},
  46 + /*
  47 + * to invert the receiver path, uncomment the next line
  48 + * write (VILLA_MSEQ_SPARE12_MSB, 0x4000)
  49 + *
  50 + * SPARE2_LSB is used to configure the device while in sr mode to
  51 + * enable power savings and to use the optical module LOS signal.
  52 + * in power savings mode, the internal prbs checker can not be used.
  53 + * if the optical module LOS signal is used as an input to the micro
  54 + * code, then the micro code will wait until the optical module
  55 + * LOS = 0 before turning on the adaptive equalizer.
  56 + * Setting SPARE2_LSB bit 0 to 1 places the devie in power savings mode
  57 + * while setting bit 0 to 0 disables power savings mode.
  58 + * Setting SPARE2_LSB bit 2 to 0 configures the device to use the
  59 + * optical module LOS signal while setting bit 2 to 1 configures the
  60 + * device so that it will ignore the optical module LOS SPARE2_LSB = 0
  61 + */
  62 +
  63 + /* enable power savings, ignore optical module LOS */
  64 + {VILLA_MSEQ_SPARE2_LSB, 0x5},
  65 +
  66 + {VILLA_MSEQ_SPARE7_LSB, 0x1e},
  67 + {VILLA_MSEQ_BANKSELECT, 0x4},
  68 + {VILLA_MSEQ_SPARE9_LSB, 0x2},
  69 + {VILLA_MSEQ_SPARE3_LSB, 0x0F53},
  70 + {VILLA_MSEQ_SPARE3_MSB, 0x2006},
  71 + {VILLA_MSEQ_SPARE8_LSB, 0x3FF7},
  72 + {VILLA_MSEQ_SPARE8_MSB, 0x0A46},
  73 + {VILLA_MSEQ_COEF8_FFE0_LSB, 0xD500},
  74 + {VILLA_MSEQ_COEF8_FFE1_LSB, 0x0200},
  75 + {VILLA_MSEQ_COEF8_FFE2_LSB, 0xBA00},
  76 + {VILLA_MSEQ_COEF8_FFE3_LSB, 0x0100},
  77 + {VILLA_MSEQ_COEF8_FFE4_LSB, 0x0300},
  78 + {VILLA_MSEQ_COEF8_FFE5_LSB, 0x0300},
  79 + {VILLA_MSEQ_COEF8_DFE0_LSB, 0x0700},
  80 + {VILLA_MSEQ_COEF8_DFE0N_LSB, 0x0E00},
  81 + {VILLA_MSEQ_COEF8_DFE1_LSB, 0x0B00},
  82 + {VILLA_DSP_SDS_DSP_COEF_LARGE_LEAK, 0x2},
  83 + {VILLA_DSP_SDS_SERDES_SRX_DAC_ENABLEB_LSB, 0xD000},
  84 + {VILLA_MSEQ_POWER_DOWN_LSB, 0xFFFF},
  85 + {VILLA_MSEQ_POWER_DOWN_MSB, 0x0},
  86 + {VILLA_MSEQ_CAL_RX_SLICER, 0x80},
  87 + {VILLA_DSP_SDS_SERDES_SRX_DAC_BIAS_SELECT1_MSB, 0x3f},
  88 + {VILLA_GLOBAL_MSEQCLKCTRL, 0x4},
  89 + {VILLA_MSEQ_OPTIONS, 0x7},
  90 +
  91 + /* set up min value for ffe1 */
  92 + {VILLA_MSEQ_COEF_INIT_SEL, 0x2},
  93 + {VILLA_DSP_SDS_DSP_PRECODEDINITFFE21, 0x41},
  94 +
  95 + /* CS4315_sr_rx_pre_eq_set_4in */
  96 + {VILLA_GLOBAL_MSEQCLKCTRL, 0x8004},
  97 + {VILLA_MSEQ_OPTIONS, 0xf},
  98 + {VILLA_MSEQ_BANKSELECT, 0x4},
  99 + {VILLA_MSEQ_PC, 0x0},
  100 +
  101 + /* for lengths from 3.5 to 4.5inches */
  102 + {VILLA_MSEQ_SERDES_PARAM_LSB, 0x0306},
  103 + {VILLA_MSEQ_SPARE25_LSB, 0x0306},
  104 + {VILLA_MSEQ_SPARE21_LSB, 0x2},
  105 + {VILLA_MSEQ_SPARE23_LSB, 0x2},
  106 + {VILLA_MSEQ_CAL_RX_DFE_EQ, 0x0},
  107 +
  108 + {VILLA_GLOBAL_MSEQCLKCTRL, 0x4},
  109 + {VILLA_MSEQ_OPTIONS, 0x7},
  110 +
  111 + /* CS4315_rx_drive_4inch */
  112 + /* for length 4inches */
  113 + {VILLA_GLOBAL_VILLA2_COMPATIBLE, 0x0000},
  114 + {VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLA, 0x3023},
  115 + {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB, 0xc01E},
  116 +
  117 + /* CS4315_tx_drive_4inch */
  118 + /* for length 4inches */
  119 + {VILLA_GLOBAL_VILLA2_COMPATIBLE, 0x0000},
  120 + {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLA, 0x3023},
  121 + {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB, 0xc01E},
  122 +};
  123 +
  124 +void cs4340_upload_firmware(struct phy_device *phydev)
  125 +{
  126 + char line_temp[0x50] = {0};
  127 + char reg_addr[0x50] = {0};
  128 + char reg_data[0x50] = {0};
  129 + int i, line_cnt = 0, column_cnt = 0;
  130 + struct cortina_reg_config fw_temp;
  131 + char *addr = NULL;
  132 +
  133 +#if defined(CONFIG_SYS_CORTINA_FW_IN_NOR) || \
  134 + defined(CONFIG_SYS_CORTINA_FW_IN_REMOTE)
  135 +
  136 + addr = (char *)CONFIG_CORTINA_FW_ADDR;
  137 +#elif defined(CONFIG_SYS_CORTINA_FW_IN_NAND)
  138 + int ret;
  139 + size_t fw_length = CONFIG_CORTINA_FW_LENGTH;
  140 +
  141 + addr = malloc(CONFIG_CORTINA_FW_LENGTH);
  142 + ret = nand_read(&nand_info[0], (loff_t)CONFIG_CORTINA_FW_ADDR,
  143 + &fw_length, (u_char *)addr);
  144 + if (ret == -EUCLEAN) {
  145 + printf("NAND read of Cortina firmware at 0x%x failed %d\n",
  146 + CONFIG_CORTINA_FW_ADDR, ret);
  147 + }
  148 +#elif defined(CONFIG_SYS_CORTINA_FW_IN_SPIFLASH)
  149 + int ret;
  150 + struct spi_flash *ucode_flash;
  151 +
  152 + addr = malloc(CONFIG_CORTINA_FW_LENGTH);
  153 + ucode_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
  154 + CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
  155 + if (!ucode_flash) {
  156 + puts("SF: probe for Cortina ucode failed\n");
  157 + } else {
  158 + ret = spi_flash_read(ucode_flash, CONFIG_CORTINA_FW_ADDR,
  159 + CONFIG_CORTINA_FW_LENGTH, addr);
  160 + if (ret)
  161 + puts("SF: read for Cortina ucode failed\n");
  162 + spi_flash_free(ucode_flash);
  163 + }
  164 +#elif defined(CONFIG_SYS_CORTINA_FW_IN_MMC)
  165 + int dev = CONFIG_SYS_MMC_ENV_DEV;
  166 + u32 cnt = CONFIG_CORTINA_FW_LENGTH / 512;
  167 + u32 blk = CONFIG_CORTINA_FW_ADDR / 512;
  168 + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
  169 +
  170 + if (!mmc) {
  171 + puts("Failed to find MMC device for Cortina ucode\n");
  172 + } else {
  173 + addr = malloc(CONFIG_CORTINA_FW_LENGTH);
  174 + printf("MMC read: dev # %u, block # %u, count %u ...\n",
  175 + dev, blk, cnt);
  176 + mmc_init(mmc);
  177 + (void)mmc->block_dev.block_read(dev, blk, cnt, addr);
  178 + /* flush cache after read */
  179 + flush_cache((ulong)addr, cnt * 512);
  180 + }
  181 +#endif
  182 +
  183 + while (*addr != 'Q') {
  184 + i = 0;
  185 +
  186 + while (*addr != 0x0a) {
  187 + line_temp[i++] = *addr++;
  188 + if (0x50 < i) {
  189 + printf("Not found Cortina PHY ucode at 0x%x\n",
  190 + CONFIG_CORTINA_FW_ADDR);
  191 + return;
  192 + }
  193 + }
  194 +
  195 + addr++; /* skip '\n' */
  196 + line_cnt++;
  197 + column_cnt = i;
  198 + line_temp[column_cnt] = '\0';
  199 +
  200 + if (CONFIG_CORTINA_FW_LENGTH < line_cnt)
  201 + return;
  202 +
  203 + for (i = 0; i < column_cnt; i++) {
  204 + if (isspace(line_temp[i++]))
  205 + break;
  206 + }
  207 +
  208 + memcpy(reg_addr, line_temp, i);
  209 + memcpy(reg_data, &line_temp[i], column_cnt - i);
  210 + strim(reg_addr);
  211 + strim(reg_data);
  212 + fw_temp.reg_addr = (simple_strtoul(reg_addr, NULL, 0)) & 0xffff;
  213 + fw_temp.reg_value = (simple_strtoul(reg_data, NULL, 0)) &
  214 + 0xffff;
  215 + phy_write(phydev, 0x00, fw_temp.reg_addr, fw_temp.reg_value);
  216 + }
  217 +}
  218 +
  219 +int cs4340_phy_init(struct phy_device *phydev)
  220 +{
  221 + int timeout = 100; /* 100ms */
  222 + int reg_value;
  223 +
  224 + /* step1: BIST test */
  225 + phy_write(phydev, 0x00, VILLA_GLOBAL_MSEQCLKCTRL, 0x0004);
  226 + phy_write(phydev, 0x00, VILLA_GLOBAL_LINE_SOFT_RESET, 0x0000);
  227 + phy_write(phydev, 0x00, VILLA_GLOBAL_BIST_CONTROL, 0x0001);
  228 + while (--timeout) {
  229 + reg_value = phy_read(phydev, 0x00, VILLA_GLOBAL_BIST_STATUS);
  230 + if (reg_value & mseq_edc_bist_done) {
  231 + if (0 == (reg_value & mseq_edc_bist_fail))
  232 + break;
  233 + }
  234 + udelay(1000);
  235 + }
  236 +
  237 + if (!timeout) {
  238 + printf("%s BIST mseq_edc_bist_done timeout!\n", __func__);
  239 + return -1;
  240 + }
  241 +
  242 + /* setp2: upload ucode */
  243 + cs4340_upload_firmware(phydev);
  244 + reg_value = phy_read(phydev, 0x00, VILLA_GLOBAL_DWNLD_CHECKSUM_STATUS);
  245 + if (reg_value) {
  246 + debug("%s checksum status failed.\n", __func__);
  247 + return -1;
  248 + }
  249 +
  250 + return 0;
  251 +}
  252 +
  253 +int cs4340_config(struct phy_device *phydev)
  254 +{
  255 + cs4340_phy_init(phydev);
  256 + return 0;
  257 +}
  258 +
  259 +int cs4340_startup(struct phy_device *phydev)
  260 +{
  261 + phydev->link = 1;
  262 +
  263 + /* For now just lie and say it's 10G all the time */
  264 + phydev->speed = SPEED_10000;
  265 + phydev->duplex = DUPLEX_FULL;
  266 + return 0;
  267 +}
  268 +
  269 +struct phy_driver cs4340_driver = {
  270 + .name = "Cortina CS4315/CS4340",
  271 + .uid = PHY_UID_CS4340,
  272 + .mask = 0xfffffff0,
  273 + .features = PHY_10G_FEATURES,
  274 + .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
  275 + MDIO_DEVS_PHYXS | MDIO_DEVS_AN |
  276 + MDIO_DEVS_VEND1 | MDIO_DEVS_VEND2),
  277 + .config = &cs4340_config,
  278 + .startup = &cs4340_startup,
  279 + .shutdown = &gen10g_shutdown,
  280 +};
  281 +
  282 +int phy_cortina_init(void)
  283 +{
  284 + phy_register(&cs4340_driver);
  285 + return 0;
  286 +}
  287 +
  288 +int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
  289 +{
  290 + int phy_reg;
  291 + bool is_cortina_phy = false;
  292 +
  293 + switch (addr) {
  294 +#ifdef CORTINA_PHY_ADDR1
  295 + case CORTINA_PHY_ADDR1:
  296 +#endif
  297 +#ifdef CORTINA_PHY_ADDR2
  298 + case CORTINA_PHY_ADDR2:
  299 +#endif
  300 +#ifdef CORTINA_PHY_ADDR3
  301 + case CORTINA_PHY_ADDR3:
  302 +#endif
  303 +#ifdef CORTINA_PHY_ADDR4
  304 + case CORTINA_PHY_ADDR4:
  305 +#endif
  306 + is_cortina_phy = true;
  307 + break;
  308 + default:
  309 + break;
  310 + }
  311 +
  312 + /* Cortina PHY has non-standard offset of PHY ID registers */
  313 + if (is_cortina_phy)
  314 + phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_LSB);
  315 + else
  316 + phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
  317 +
  318 + if (phy_reg < 0)
  319 + return -EIO;
  320 +
  321 + *phy_id = (phy_reg & 0xffff) << 16;
  322 + if (is_cortina_phy)
  323 + phy_reg = bus->read(bus, addr, 0, VILLA_GLOBAL_CHIP_ID_MSB);
  324 + else
  325 + phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
  326 +
  327 + if (phy_reg < 0)
  328 + return -EIO;
  329 +
  330 + *phy_id |= (phy_reg & 0xffff);
  331 +
  332 + return 0;
  333 +}
drivers/net/phy/phy.c
... ... @@ -448,6 +448,9 @@
448 448 #ifdef CONFIG_PHY_BROADCOM
449 449 phy_broadcom_init();
450 450 #endif
  451 +#ifdef CONFIG_PHY_CORTINA
  452 + phy_cortina_init();
  453 +#endif
451 454 #ifdef CONFIG_PHY_DAVICOM
452 455 phy_davicom_init();
453 456 #endif
  1 +/*
  2 + * Cortina PHY drivers
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + *
  6 + * Copyright 2014 Freescale Semiconductor, Inc.
  7 + */
  8 +
  9 +#ifndef _CORTINA_H_
  10 +#define _CORTINA_H_
  11 +
  12 +#define VILLA_GLOBAL_CHIP_ID_LSB 0x000
  13 +#define VILLA_GLOBAL_CHIP_ID_MSB 0x001
  14 +#define VILLA_GLOBAL_BIST_CONTROL 0x002
  15 +#define VILLA_GLOBAL_BIST_STATUS 0x003
  16 +#define VILLA_GLOBAL_LINE_SOFT_RESET 0x007
  17 +#define VILLA_GLOBAL_HOST_SOFT_RESET 0x008
  18 +#define VILLA_GLOBAL_DWNLD_CHECKSUM_CTRL 0x00A
  19 +#define VILLA_GLOBAL_DWNLD_CHECKSUM_STATUS 0x00B
  20 +#define VILLA_GLOBAL_MSEQCLKCTRL 0x00E
  21 +#define VILLA_MSEQ_OPTIONS 0x1D0
  22 +#define VILLA_MSEQ_PC 0x1D3
  23 +#define VILLA_MSEQ_BANKSELECT 0x1DF
  24 +#define VILLA_DSP_SDS_DSP_COEF_DFE0_SELECT 0x2DB
  25 +#define VILLA_DSP_SDS_SERDES_SRX_DFE0_SELECT 0x36E
  26 +#define VILLA_LINE_SDS_COMMON_SRX0_RX_LOOP_FILTER 0x403
  27 +#define VILLA_LINE_SDS_COMMON_SRX0_RX_CPA 0x404
  28 +#define VILLA_LINE_SDS_COMMON_SRX0_RX_CPB 0x405
  29 +#define VILLA_DSP_SDS_SERDES_SRX_FFE_DELAY_CTRL 0x369
  30 +#define VILLA_MSEQ_ENABLE_MSB 0x194
  31 +#define VILLA_MSEQ_SPARE21_LSB 0x226
  32 +#define VILLA_MSEQ_RESET_COUNT_LSB 0x1E0
  33 +#define VILLA_MSEQ_SPARE12_MSB 0x215
  34 +#define VILLA_MSEQ_SPARE2_LSB 0x200
  35 +#define VILLA_MSEQ_SPARE7_LSB 0x20A
  36 +#define VILLA_MSEQ_SPARE9_LSB 0x20E
  37 +#define VILLA_MSEQ_SPARE3_LSB 0x202
  38 +#define VILLA_MSEQ_SPARE3_MSB 0x203
  39 +#define VILLA_MSEQ_SPARE8_LSB 0x20C
  40 +#define VILLA_MSEQ_SPARE8_MSB 0x20D
  41 +#define VILLA_MSEQ_COEF8_FFE0_LSB 0x1E2
  42 +#define VILLA_MSEQ_COEF8_FFE1_LSB 0x1E4
  43 +#define VILLA_MSEQ_COEF8_FFE2_LSB 0x1E6
  44 +#define VILLA_MSEQ_COEF8_FFE3_LSB 0x1E8
  45 +#define VILLA_MSEQ_COEF8_FFE4_LSB 0x1EA
  46 +#define VILLA_MSEQ_COEF8_FFE5_LSB 0x1EC
  47 +#define VILLA_MSEQ_COEF8_DFE0_LSB 0x1F0
  48 +#define VILLA_MSEQ_COEF8_DFE0N_LSB 0x1EE
  49 +#define VILLA_MSEQ_COEF8_DFE1_LSB 0x1F2
  50 +#define VILLA_DSP_SDS_DSP_COEF_LARGE_LEAK 0x2E2
  51 +#define VILLA_DSP_SDS_SERDES_SRX_DAC_ENABLEB_LSB 0x360
  52 +#define VILLA_MSEQ_POWER_DOWN_LSB 0x198
  53 +#define VILLA_MSEQ_POWER_DOWN_MSB 0x199
  54 +#define VILLA_MSEQ_CAL_RX_SLICER 0x1B8
  55 +#define VILLA_DSP_SDS_SERDES_SRX_DAC_BIAS_SELECT1_MSB 0x365
  56 +#define VILLA_MSEQ_COEF_INIT_SEL 0x1AE
  57 +#define VILLA_DSP_SDS_DSP_PRECODEDINITFFE21 0x26A
  58 +#define VILLA_MSEQ_SERDES_PARAM_LSB 0x195
  59 +#define VILLA_MSEQ_SPARE25_LSB 0x22E
  60 +#define VILLA_MSEQ_SPARE23_LSB 0x22A
  61 +#define VILLA_MSEQ_CAL_RX_DFE_EQ 0x1BA
  62 +#define VILLA_GLOBAL_VILLA2_COMPATIBLE 0x030
  63 +#define VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLA 0x812
  64 +#define VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLB 0x813
  65 +#define VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLA 0x427
  66 +#define VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB 0x428
  67 +
  68 +#define mseq_edc_bist_done (0x1<<0)
  69 +#define mseq_edc_bist_fail (0x1<<8)
  70 +
  71 +struct cortina_reg_config {
  72 + unsigned short reg_addr;
  73 + unsigned short reg_value;
  74 +};
  75 +#endif
... ... @@ -227,6 +227,7 @@
227 227  
228 228 int phy_atheros_init(void);
229 229 int phy_broadcom_init(void);
  230 +int phy_cortina_init(void);
230 231 int phy_davicom_init(void);
231 232 int phy_et1011c_init(void);
232 233 int phy_lxt_init(void);
... ... @@ -241,6 +242,7 @@
241 242 int board_phy_config(struct phy_device *phydev);
242 243  
243 244 /* PHY UIDs for various PHYs that are referenced in external code */
  245 +#define PHY_UID_CS4340 0x13e51002
244 246 #define PHY_UID_TN2020 0x00a19410
245 247  
246 248 #endif