Skip to content

Commit 0ca12be

Browse files
Vasundhara Volamdavem330
authored andcommitted
bnxt_en: Add support for mdio read/write to external PHY
Add support for SIOCGMIIREG and SIOCSMIIREG ioctls to mdio read/write to external PHY. Signed-off-by: Vasundhara Volam <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2a51644 commit 0ca12be

File tree

1 file changed

+67
-2
lines changed
  • drivers/net/ethernet/broadcom/bnxt

1 file changed

+67
-2
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <asm/page.h>
3232
#include <linux/time.h>
3333
#include <linux/mii.h>
34+
#include <linux/mdio.h>
3435
#include <linux/if.h>
3536
#include <linux/if_vlan.h>
3637
#include <linux/if_bridge.h>
@@ -8621,24 +8622,88 @@ static int bnxt_close(struct net_device *dev)
86218622
return 0;
86228623
}
86238624

8625+
static int bnxt_hwrm_port_phy_read(struct bnxt *bp, u16 phy_addr, u16 reg,
8626+
u16 *val)
8627+
{
8628+
struct hwrm_port_phy_mdio_read_output *resp = bp->hwrm_cmd_resp_addr;
8629+
struct hwrm_port_phy_mdio_read_input req = {0};
8630+
int rc;
8631+
8632+
if (bp->hwrm_spec_code < 0x10a00)
8633+
return -EOPNOTSUPP;
8634+
8635+
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_READ, -1, -1);
8636+
req.port_id = cpu_to_le16(bp->pf.port_id);
8637+
req.phy_addr = phy_addr;
8638+
req.reg_addr = cpu_to_le16(reg & 0x1f);
8639+
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
8640+
req.cl45_mdio = 1;
8641+
req.phy_addr = mdio_phy_id_prtad(phy_addr);
8642+
req.dev_addr = mdio_phy_id_devad(phy_addr);
8643+
req.reg_addr = cpu_to_le16(reg);
8644+
}
8645+
8646+
mutex_lock(&bp->hwrm_cmd_lock);
8647+
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
8648+
if (!rc)
8649+
*val = le16_to_cpu(resp->reg_data);
8650+
mutex_unlock(&bp->hwrm_cmd_lock);
8651+
return rc;
8652+
}
8653+
8654+
static int bnxt_hwrm_port_phy_write(struct bnxt *bp, u16 phy_addr, u16 reg,
8655+
u16 val)
8656+
{
8657+
struct hwrm_port_phy_mdio_write_input req = {0};
8658+
8659+
if (bp->hwrm_spec_code < 0x10a00)
8660+
return -EOPNOTSUPP;
8661+
8662+
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_WRITE, -1, -1);
8663+
req.port_id = cpu_to_le16(bp->pf.port_id);
8664+
req.phy_addr = phy_addr;
8665+
req.reg_addr = cpu_to_le16(reg & 0x1f);
8666+
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
8667+
req.cl45_mdio = 1;
8668+
req.phy_addr = mdio_phy_id_prtad(phy_addr);
8669+
req.dev_addr = mdio_phy_id_devad(phy_addr);
8670+
req.reg_addr = cpu_to_le16(reg);
8671+
}
8672+
req.reg_data = cpu_to_le16(val);
8673+
8674+
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
8675+
}
8676+
86248677
/* rtnl_lock held */
86258678
static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
86268679
{
8680+
struct mii_ioctl_data *mdio = if_mii(ifr);
8681+
struct bnxt *bp = netdev_priv(dev);
8682+
int rc;
8683+
86278684
switch (cmd) {
86288685
case SIOCGMIIPHY:
8686+
mdio->phy_id = bp->link_info.phy_addr;
8687+
86298688
/* fallthru */
86308689
case SIOCGMIIREG: {
8690+
u16 mii_regval = 0;
8691+
86318692
if (!netif_running(dev))
86328693
return -EAGAIN;
86338694

8634-
return 0;
8695+
rc = bnxt_hwrm_port_phy_read(bp, mdio->phy_id, mdio->reg_num,
8696+
&mii_regval);
8697+
mdio->val_out = mii_regval;
8698+
return rc;
86358699
}
86368700

86378701
case SIOCSMIIREG:
86388702
if (!netif_running(dev))
86398703
return -EAGAIN;
86408704

8641-
return 0;
8705+
return bnxt_hwrm_port_phy_write(bp, mdio->phy_id, mdio->reg_num,
8706+
mdio->val_in);
86428707

86438708
default:
86448709
/* do nothing */

0 commit comments

Comments
 (0)