aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c40
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c8
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c30
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h1
5 files changed, 76 insertions, 4 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 597e4724a474..4645c44e7c15 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -122,6 +122,7 @@ static const u16 bnxt_async_events_arr[] = {
122 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE, 122 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE,
123 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD, 123 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD,
124 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED, 124 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED,
125 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE,
125}; 126};
126 127
127static bool bnxt_vf_pciid(enum board_idx idx) 128static bool bnxt_vf_pciid(enum board_idx idx)
@@ -1257,6 +1258,21 @@ static int bnxt_async_event_process(struct bnxt *bp,
1257 1258
1258 /* TODO CHIMP_FW: Define event id's for link change, error etc */ 1259 /* TODO CHIMP_FW: Define event id's for link change, error etc */
1259 switch (event_id) { 1260 switch (event_id) {
1261 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE: {
1262 u32 data1 = le32_to_cpu(cmpl->event_data1);
1263 struct bnxt_link_info *link_info = &bp->link_info;
1264
1265 if (BNXT_VF(bp))
1266 goto async_event_process_exit;
1267 if (data1 & 0x20000) {
1268 u16 fw_speed = link_info->force_link_speed;
1269 u32 speed = bnxt_fw_to_ethtool_speed(fw_speed);
1270
1271 netdev_warn(bp->dev, "Link speed %d no longer supported\n",
1272 speed);
1273 }
1274 /* fall thru */
1275 }
1260 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: 1276 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
1261 set_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event); 1277 set_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event);
1262 break; 1278 break;
@@ -4611,6 +4627,7 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
4611 link_info->phy_ver[1] = resp->phy_min; 4627 link_info->phy_ver[1] = resp->phy_min;
4612 link_info->phy_ver[2] = resp->phy_bld; 4628 link_info->phy_ver[2] = resp->phy_bld;
4613 link_info->media_type = resp->media_type; 4629 link_info->media_type = resp->media_type;
4630 link_info->phy_type = resp->phy_type;
4614 link_info->transceiver = resp->xcvr_pkg_type; 4631 link_info->transceiver = resp->xcvr_pkg_type;
4615 link_info->phy_addr = resp->eee_config_phy_addr & 4632 link_info->phy_addr = resp->eee_config_phy_addr &
4616 PORT_PHY_QCFG_RESP_PHY_ADDR_MASK; 4633 PORT_PHY_QCFG_RESP_PHY_ADDR_MASK;
@@ -4789,6 +4806,21 @@ int bnxt_hwrm_set_link_setting(struct bnxt *bp, bool set_pause, bool set_eee)
4789 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 4806 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
4790} 4807}
4791 4808
4809static int bnxt_hwrm_shutdown_link(struct bnxt *bp)
4810{
4811 struct hwrm_port_phy_cfg_input req = {0};
4812
4813 if (BNXT_VF(bp))
4814 return 0;
4815
4816 if (pci_num_vf(bp->pdev))
4817 return 0;
4818
4819 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_CFG, -1, -1);
4820 req.flags = cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DOWN);
4821 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
4822}
4823
4792static bool bnxt_eee_config_ok(struct bnxt *bp) 4824static bool bnxt_eee_config_ok(struct bnxt *bp)
4793{ 4825{
4794 struct ethtool_eee *eee = &bp->eee; 4826 struct ethtool_eee *eee = &bp->eee;
@@ -5043,6 +5075,7 @@ static int bnxt_close(struct net_device *dev)
5043 struct bnxt *bp = netdev_priv(dev); 5075 struct bnxt *bp = netdev_priv(dev);
5044 5076
5045 bnxt_close_nic(bp, true, true); 5077 bnxt_close_nic(bp, true, true);
5078 bnxt_hwrm_shutdown_link(bp);
5046 return 0; 5079 return 0;
5047} 5080}
5048 5081
@@ -5679,10 +5712,9 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
5679 if (!is_valid_ether_addr(addr->sa_data)) 5712 if (!is_valid_ether_addr(addr->sa_data))
5680 return -EADDRNOTAVAIL; 5713 return -EADDRNOTAVAIL;
5681 5714
5682#ifdef CONFIG_BNXT_SRIOV 5715 rc = bnxt_approve_mac(bp, addr->sa_data);
5683 if (BNXT_VF(bp) && is_valid_ether_addr(bp->vf.mac_addr)) 5716 if (rc)
5684 return -EADDRNOTAVAIL; 5717 return rc;
5685#endif
5686 5718
5687 if (ether_addr_equal(addr->sa_data, dev->dev_addr)) 5719 if (ether_addr_equal(addr->sa_data, dev->dev_addr))
5688 return 0; 5720 return 0;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index cc8e38a9f684..26dac2f3c63c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -759,6 +759,7 @@ struct bnxt_ntuple_filter {
759}; 759};
760 760
761struct bnxt_link_info { 761struct bnxt_link_info {
762 u8 phy_type;
762 u8 media_type; 763 u8 media_type;
763 u8 transceiver; 764 u8 transceiver;
764 u8 phy_addr; 765 u8 phy_addr;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index a2e93241b06b..d6e41f237f2c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -850,7 +850,15 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
850 set_pause = true; 850 set_pause = true;
851 } else { 851 } else {
852 u16 fw_speed; 852 u16 fw_speed;
853 u8 phy_type = link_info->phy_type;
853 854
855 if (phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASET ||
856 phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASETE ||
857 link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
858 netdev_err(dev, "10GBase-T devices must autoneg\n");
859 rc = -EINVAL;
860 goto set_setting_exit;
861 }
854 /* TODO: currently don't support half duplex */ 862 /* TODO: currently don't support half duplex */
855 if (cmd->duplex == DUPLEX_HALF) { 863 if (cmd->duplex == DUPLEX_HALF) {
856 netdev_err(dev, "HALF DUPLEX is not supported!\n"); 864 netdev_err(dev, "HALF DUPLEX is not supported!\n");
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 8457850b0bdd..363884dd9e8a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -865,6 +865,31 @@ update_vf_mac_exit:
865 mutex_unlock(&bp->hwrm_cmd_lock); 865 mutex_unlock(&bp->hwrm_cmd_lock);
866} 866}
867 867
868int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
869{
870 struct hwrm_func_vf_cfg_input req = {0};
871 int rc = 0;
872
873 if (!BNXT_VF(bp))
874 return 0;
875
876 if (bp->hwrm_spec_code < 0x10202) {
877 if (is_valid_ether_addr(bp->vf.mac_addr))
878 rc = -EADDRNOTAVAIL;
879 goto mac_done;
880 }
881 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
882 req.enables = cpu_to_le32(FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR);
883 memcpy(req.dflt_mac_addr, mac, ETH_ALEN);
884 rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
885mac_done:
886 if (rc) {
887 rc = -EADDRNOTAVAIL;
888 netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n",
889 mac);
890 }
891 return rc;
892}
868#else 893#else
869 894
870void bnxt_sriov_disable(struct bnxt *bp) 895void bnxt_sriov_disable(struct bnxt *bp)
@@ -879,4 +904,9 @@ void bnxt_hwrm_exec_fwd_req(struct bnxt *bp)
879void bnxt_update_vf_mac(struct bnxt *bp) 904void bnxt_update_vf_mac(struct bnxt *bp)
880{ 905{
881} 906}
907
908int bnxt_approve_mac(struct bnxt *bp, u8 *mac)
909{
910 return 0;
911}
882#endif 912#endif
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
index 3f08354a247e..0392670ab49c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
@@ -20,4 +20,5 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
20void bnxt_sriov_disable(struct bnxt *); 20void bnxt_sriov_disable(struct bnxt *);
21void bnxt_hwrm_exec_fwd_req(struct bnxt *); 21void bnxt_hwrm_exec_fwd_req(struct bnxt *);
22void bnxt_update_vf_mac(struct bnxt *); 22void bnxt_update_vf_mac(struct bnxt *);
23int bnxt_approve_mac(struct bnxt *, u8 *);
23#endif 24#endif