|
1 | 1 | /* Broadcom NetXtreme-C/E network driver.
|
2 | 2 | *
|
3 | 3 | * Copyright (c) 2014-2016 Broadcom Corporation
|
4 |
| - * Copyright (c) 2016-2018 Broadcom Limited |
| 4 | + * Copyright (c) 2016-2019 Broadcom Limited |
5 | 5 | *
|
6 | 6 | * This program is free software; you can redistribute it and/or modify
|
7 | 7 | * it under the terms of the GNU General Public License as published by
|
|
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>
|
@@ -112,6 +113,7 @@ enum board_idx {
|
112 | 113 | BCM57454,
|
113 | 114 | BCM5745x_NPAR,
|
114 | 115 | BCM57508,
|
| 116 | + BCM57504, |
115 | 117 | BCM58802,
|
116 | 118 | BCM58804,
|
117 | 119 | BCM58808,
|
@@ -155,6 +157,7 @@ static const struct {
|
155 | 157 | [BCM57454] = { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
|
156 | 158 | [BCM5745x_NPAR] = { "Broadcom BCM5745x NetXtreme-E Ethernet Partition" },
|
157 | 159 | [BCM57508] = { "Broadcom BCM57508 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" },
|
| 160 | + [BCM57504] = { "Broadcom BCM57504 NetXtreme-E 10Gb/25Gb/50Gb/100Gb/200Gb Ethernet" }, |
158 | 161 | [BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
159 | 162 | [BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
|
160 | 163 | [BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
|
@@ -201,6 +204,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
|
201 | 204 | { PCI_VDEVICE(BROADCOM, 0x16f0), .driver_data = BCM58808 },
|
202 | 205 | { PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
|
203 | 206 | { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
|
| 207 | + { PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 }, |
204 | 208 | { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
|
205 | 209 | { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
|
206 | 210 | #ifdef CONFIG_BNXT_SRIOV
|
@@ -6680,6 +6684,10 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
6680 | 6684 | VER_GET_RESP_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED)
|
6681 | 6685 | bp->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE;
|
6682 | 6686 |
|
| 6687 | + if (dev_caps_cfg & |
| 6688 | + VER_GET_RESP_DEV_CAPS_CFG_TRUSTED_VF_SUPPORTED) |
| 6689 | + bp->fw_cap |= BNXT_FW_CAP_TRUSTED_VF; |
| 6690 | + |
6683 | 6691 | hwrm_ver_get_exit:
|
6684 | 6692 | mutex_unlock(&bp->hwrm_cmd_lock);
|
6685 | 6693 | return rc;
|
@@ -8614,24 +8622,88 @@ static int bnxt_close(struct net_device *dev)
|
8614 | 8622 | return 0;
|
8615 | 8623 | }
|
8616 | 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 | + |
8617 | 8677 | /* rtnl_lock held */
|
8618 | 8678 | static int bnxt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
8619 | 8679 | {
|
| 8680 | + struct mii_ioctl_data *mdio = if_mii(ifr); |
| 8681 | + struct bnxt *bp = netdev_priv(dev); |
| 8682 | + int rc; |
| 8683 | + |
8620 | 8684 | switch (cmd) {
|
8621 | 8685 | case SIOCGMIIPHY:
|
| 8686 | + mdio->phy_id = bp->link_info.phy_addr; |
| 8687 | + |
8622 | 8688 | /* fallthru */
|
8623 | 8689 | case SIOCGMIIREG: {
|
| 8690 | + u16 mii_regval = 0; |
| 8691 | + |
8624 | 8692 | if (!netif_running(dev))
|
8625 | 8693 | return -EAGAIN;
|
8626 | 8694 |
|
8627 |
| - 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; |
8628 | 8699 | }
|
8629 | 8700 |
|
8630 | 8701 | case SIOCSMIIREG:
|
8631 | 8702 | if (!netif_running(dev))
|
8632 | 8703 | return -EAGAIN;
|
8633 | 8704 |
|
8634 |
| - return 0; |
| 8705 | + return bnxt_hwrm_port_phy_write(bp, mdio->phy_id, mdio->reg_num, |
| 8706 | + mdio->val_in); |
8635 | 8707 |
|
8636 | 8708 | default:
|
8637 | 8709 | /* do nothing */
|
|
0 commit comments