|
31 | 31 | #include <asm/page.h>
|
32 | 32 | #include <linux/time.h>
|
33 | 33 | #include <linux/mii.h>
|
| 34 | +#include <linux/mdio.h> |
34 | 35 | #include <linux/if.h>
|
35 | 36 | #include <linux/if_vlan.h>
|
36 | 37 | #include <linux/if_bridge.h>
|
@@ -8621,24 +8622,88 @@ static int bnxt_close(struct net_device *dev)
|
8621 | 8622 | return 0;
|
8622 | 8623 | }
|
8623 | 8624 |
|
| 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 | + |
8624 | 8677 | /* rtnl_lock held */
|
8625 | 8678 | static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
8626 | 8679 | {
|
| 8680 | + struct mii_ioctl_data *mdio = if_mii(ifr); |
| 8681 | + struct bnxt *bp = netdev_priv(dev); |
| 8682 | + int rc; |
| 8683 | + |
8627 | 8684 | switch (cmd) {
|
8628 | 8685 | case SIOCGMIIPHY:
|
| 8686 | + mdio->phy_id = bp->link_info.phy_addr; |
| 8687 | + |
8629 | 8688 | /* fallthru */
|
8630 | 8689 | case SIOCGMIIREG: {
|
| 8690 | + u16 mii_regval = 0; |
| 8691 | + |
8631 | 8692 | if (!netif_running(dev))
|
8632 | 8693 | return -EAGAIN;
|
8633 | 8694 |
|
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; |
8635 | 8699 | }
|
8636 | 8700 |
|
8637 | 8701 | case SIOCSMIIREG:
|
8638 | 8702 | if (!netif_running(dev))
|
8639 | 8703 | return -EAGAIN;
|
8640 | 8704 |
|
8641 |
| - return 0; |
| 8705 | + return bnxt_hwrm_port_phy_write(bp, mdio->phy_id, mdio->reg_num, |
| 8706 | + mdio->val_in); |
8642 | 8707 |
|
8643 | 8708 | default:
|
8644 | 8709 | /* do nothing */
|
|
0 commit comments