diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h | 1 |
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 | ||
127 | static bool bnxt_vf_pciid(enum board_idx idx) | 128 | static 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 | ||
4809 | static 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 | |||
4792 | static bool bnxt_eee_config_ok(struct bnxt *bp) | 4824 | static 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 | ||
761 | struct bnxt_link_info { | 761 | struct 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 | ||
868 | int 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); | ||
885 | mac_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 | ||
870 | void bnxt_sriov_disable(struct bnxt *bp) | 895 | void bnxt_sriov_disable(struct bnxt *bp) |
@@ -879,4 +904,9 @@ void bnxt_hwrm_exec_fwd_req(struct bnxt *bp) | |||
879 | void bnxt_update_vf_mac(struct bnxt *bp) | 904 | void bnxt_update_vf_mac(struct bnxt *bp) |
880 | { | 905 | { |
881 | } | 906 | } |
907 | |||
908 | int 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); | |||
20 | void bnxt_sriov_disable(struct bnxt *); | 20 | void bnxt_sriov_disable(struct bnxt *); |
21 | void bnxt_hwrm_exec_fwd_req(struct bnxt *); | 21 | void bnxt_hwrm_exec_fwd_req(struct bnxt *); |
22 | void bnxt_update_vf_mac(struct bnxt *); | 22 | void bnxt_update_vf_mac(struct bnxt *); |
23 | int bnxt_approve_mac(struct bnxt *, u8 *); | ||
23 | #endif | 24 | #endif |