mirror of https://gitee.com/openkylin/linux.git
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 <vasundhara-v.volam@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2a51644443
commit
0ca12be996
|
@ -31,6 +31,7 @@
|
|||
#include <asm/page.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/if_bridge.h>
|
||||
|
@ -8621,24 +8622,88 @@ static int bnxt_close(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_port_phy_read(struct bnxt *bp, u16 phy_addr, u16 reg,
|
||||
u16 *val)
|
||||
{
|
||||
struct hwrm_port_phy_mdio_read_output *resp = bp->hwrm_cmd_resp_addr;
|
||||
struct hwrm_port_phy_mdio_read_input req = {0};
|
||||
int rc;
|
||||
|
||||
if (bp->hwrm_spec_code < 0x10a00)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_READ, -1, -1);
|
||||
req.port_id = cpu_to_le16(bp->pf.port_id);
|
||||
req.phy_addr = phy_addr;
|
||||
req.reg_addr = cpu_to_le16(reg & 0x1f);
|
||||
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
|
||||
req.cl45_mdio = 1;
|
||||
req.phy_addr = mdio_phy_id_prtad(phy_addr);
|
||||
req.dev_addr = mdio_phy_id_devad(phy_addr);
|
||||
req.reg_addr = cpu_to_le16(reg);
|
||||
}
|
||||
|
||||
mutex_lock(&bp->hwrm_cmd_lock);
|
||||
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
if (!rc)
|
||||
*val = le16_to_cpu(resp->reg_data);
|
||||
mutex_unlock(&bp->hwrm_cmd_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_port_phy_write(struct bnxt *bp, u16 phy_addr, u16 reg,
|
||||
u16 val)
|
||||
{
|
||||
struct hwrm_port_phy_mdio_write_input req = {0};
|
||||
|
||||
if (bp->hwrm_spec_code < 0x10a00)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_MDIO_WRITE, -1, -1);
|
||||
req.port_id = cpu_to_le16(bp->pf.port_id);
|
||||
req.phy_addr = phy_addr;
|
||||
req.reg_addr = cpu_to_le16(reg & 0x1f);
|
||||
if (bp->link_info.support_speeds & BNXT_LINK_SPEED_MSK_10GB) {
|
||||
req.cl45_mdio = 1;
|
||||
req.phy_addr = mdio_phy_id_prtad(phy_addr);
|
||||
req.dev_addr = mdio_phy_id_devad(phy_addr);
|
||||
req.reg_addr = cpu_to_le16(reg);
|
||||
}
|
||||
req.reg_data = cpu_to_le16(val);
|
||||
|
||||
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
/* rtnl_lock held */
|
||||
static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct mii_ioctl_data *mdio = if_mii(ifr);
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
int rc;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGMIIPHY:
|
||||
mdio->phy_id = bp->link_info.phy_addr;
|
||||
|
||||
/* fallthru */
|
||||
case SIOCGMIIREG: {
|
||||
u16 mii_regval = 0;
|
||||
|
||||
if (!netif_running(dev))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
rc = bnxt_hwrm_port_phy_read(bp, mdio->phy_id, mdio->reg_num,
|
||||
&mii_regval);
|
||||
mdio->val_out = mii_regval;
|
||||
return rc;
|
||||
}
|
||||
|
||||
case SIOCSMIIREG:
|
||||
if (!netif_running(dev))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
return bnxt_hwrm_port_phy_write(bp, mdio->phy_id, mdio->reg_num,
|
||||
mdio->val_in);
|
||||
|
||||
default:
|
||||
/* do nothing */
|
||||
|
|
Loading…
Reference in New Issue