1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3 * Driver for Solarflare network controllers and boards
4 * Copyright 2009-2013 Solarflare Communications Inc.
8 * Driver for PHY related operations via MCDI.
11 #include <linux/slab.h>
13 #include "mcdi_port.h"
15 #include "mcdi_pcol.h"
18 #include "mcdi_port_common.h"
20 static int efx_mcdi_mdio_read(struct net_device
*net_dev
,
21 int prtad
, int devad
, u16 addr
)
23 struct efx_nic
*efx
= efx_netdev_priv(net_dev
);
24 MCDI_DECLARE_BUF(inbuf
, MC_CMD_MDIO_READ_IN_LEN
);
25 MCDI_DECLARE_BUF(outbuf
, MC_CMD_MDIO_READ_OUT_LEN
);
29 MCDI_SET_DWORD(inbuf
, MDIO_READ_IN_BUS
, efx
->mdio_bus
);
30 MCDI_SET_DWORD(inbuf
, MDIO_READ_IN_PRTAD
, prtad
);
31 MCDI_SET_DWORD(inbuf
, MDIO_READ_IN_DEVAD
, devad
);
32 MCDI_SET_DWORD(inbuf
, MDIO_READ_IN_ADDR
, addr
);
34 rc
= efx_mcdi_rpc(efx
, MC_CMD_MDIO_READ
, inbuf
, sizeof(inbuf
),
35 outbuf
, sizeof(outbuf
), &outlen
);
39 if (MCDI_DWORD(outbuf
, MDIO_READ_OUT_STATUS
) !=
40 MC_CMD_MDIO_STATUS_GOOD
)
43 return (u16
)MCDI_DWORD(outbuf
, MDIO_READ_OUT_VALUE
);
46 static int efx_mcdi_mdio_write(struct net_device
*net_dev
,
47 int prtad
, int devad
, u16 addr
, u16 value
)
49 struct efx_nic
*efx
= efx_netdev_priv(net_dev
);
50 MCDI_DECLARE_BUF(inbuf
, MC_CMD_MDIO_WRITE_IN_LEN
);
51 MCDI_DECLARE_BUF(outbuf
, MC_CMD_MDIO_WRITE_OUT_LEN
);
55 MCDI_SET_DWORD(inbuf
, MDIO_WRITE_IN_BUS
, efx
->mdio_bus
);
56 MCDI_SET_DWORD(inbuf
, MDIO_WRITE_IN_PRTAD
, prtad
);
57 MCDI_SET_DWORD(inbuf
, MDIO_WRITE_IN_DEVAD
, devad
);
58 MCDI_SET_DWORD(inbuf
, MDIO_WRITE_IN_ADDR
, addr
);
59 MCDI_SET_DWORD(inbuf
, MDIO_WRITE_IN_VALUE
, value
);
61 rc
= efx_mcdi_rpc(efx
, MC_CMD_MDIO_WRITE
, inbuf
, sizeof(inbuf
),
62 outbuf
, sizeof(outbuf
), &outlen
);
66 if (MCDI_DWORD(outbuf
, MDIO_WRITE_OUT_STATUS
) !=
67 MC_CMD_MDIO_STATUS_GOOD
)
73 u32
efx_mcdi_phy_get_caps(struct efx_nic
*efx
)
75 struct efx_mcdi_phy_data
*phy_data
= efx
->phy_data
;
77 return phy_data
->supported_cap
;
80 bool efx_mcdi_mac_check_fault(struct efx_nic
*efx
)
82 MCDI_DECLARE_BUF(outbuf
, MC_CMD_GET_LINK_OUT_LEN
);
86 BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN
!= 0);
88 rc
= efx_mcdi_rpc(efx
, MC_CMD_GET_LINK
, NULL
, 0,
89 outbuf
, sizeof(outbuf
), &outlength
);
93 return MCDI_DWORD(outbuf
, GET_LINK_OUT_MAC_FAULT
) != 0;
96 int efx_mcdi_port_probe(struct efx_nic
*efx
)
100 /* Set up MDIO structure for PHY */
101 efx
->mdio
.mode_support
= MDIO_SUPPORTS_C45
| MDIO_EMULATE_C22
;
102 efx
->mdio
.mdio_read
= efx_mcdi_mdio_read
;
103 efx
->mdio
.mdio_write
= efx_mcdi_mdio_write
;
105 /* Fill out MDIO structure, loopback modes, and initial link state */
106 rc
= efx_mcdi_phy_probe(efx
);
110 return efx_mcdi_mac_init_stats(efx
);
113 void efx_mcdi_port_remove(struct efx_nic
*efx
)
115 efx_mcdi_phy_remove(efx
);
116 efx_mcdi_mac_fini_stats(efx
);