Commit 88d10bd6 authored by Jian Shen's avatar Jian Shen Committed by David S. Miller

net: hns3: add support for multiple media type

Previously, we can only identify copper and fiber type, the
supported link modes of port information are always showing
SR type. This patch adds support for multiple media types,
include SR, LR CR, KR. Driver needs to query the media type
from firmware periodicly, and updates the port information.

The new port information looks like this:
Settings for eth0:
        Supported ports: [ FIBRE ]
        Supported link modes:   25000baseCR/Full
                                25000baseSR/Full
                                1000baseX/Full
                                10000baseCR/Full
                                10000baseSR/Full
                                10000baseLR/Full
        Supported pause frame use: Symmetric
        Supports auto-negotiation: No
        Supported FEC modes: None BaseR
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 10000Mb/s
        Duplex: Full
        Port: FIBRE
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        Current message level: 0x00000036 (54)
                               probe link ifdown ifup
        Link detected: yes

In order to be compatible with old firmware which only support
sfp speed, we remained using the same query command, and kept
the former logic.
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e28441e2
...@@ -120,6 +120,18 @@ enum hnae3_media_type { ...@@ -120,6 +120,18 @@ enum hnae3_media_type {
HNAE3_MEDIA_TYPE_NONE, HNAE3_MEDIA_TYPE_NONE,
}; };
/* must be consistent with definition in firmware */
enum hnae3_module_type {
HNAE3_MODULE_TYPE_UNKNOWN = 0x00,
HNAE3_MODULE_TYPE_FIBRE_LR = 0x01,
HNAE3_MODULE_TYPE_FIBRE_SR = 0x02,
HNAE3_MODULE_TYPE_AOC = 0x03,
HNAE3_MODULE_TYPE_CR = 0x04,
HNAE3_MODULE_TYPE_KR = 0x05,
HNAE3_MODULE_TYPE_TP = 0x06,
};
enum hnae3_reset_notify_type { enum hnae3_reset_notify_type {
HNAE3_UP_CLIENT, HNAE3_UP_CLIENT,
HNAE3_DOWN_CLIENT, HNAE3_DOWN_CLIENT,
...@@ -230,8 +242,6 @@ struct hnae3_ae_dev { ...@@ -230,8 +242,6 @@ struct hnae3_ae_dev {
* non-ok * non-ok
* get_ksettings_an_result() * get_ksettings_an_result()
* Get negotiation status,speed and duplex * Get negotiation status,speed and duplex
* update_speed_duplex_h()
* Update hardware speed and duplex
* get_media_type() * get_media_type()
* Get media type of MAC * Get media type of MAC
* adjust_link() * adjust_link()
...@@ -340,11 +350,11 @@ struct hnae3_ae_ops { ...@@ -340,11 +350,11 @@ struct hnae3_ae_ops {
void (*get_ksettings_an_result)(struct hnae3_handle *handle, void (*get_ksettings_an_result)(struct hnae3_handle *handle,
u8 *auto_neg, u32 *speed, u8 *duplex); u8 *auto_neg, u32 *speed, u8 *duplex);
int (*update_speed_duplex_h)(struct hnae3_handle *handle);
int (*cfg_mac_speed_dup_h)(struct hnae3_handle *handle, int speed, int (*cfg_mac_speed_dup_h)(struct hnae3_handle *handle, int speed,
u8 duplex); u8 duplex);
void (*get_media_type)(struct hnae3_handle *handle, u8 *media_type); void (*get_media_type)(struct hnae3_handle *handle, u8 *media_type,
u8 *module_type);
void (*adjust_link)(struct hnae3_handle *handle, int speed, int duplex); void (*adjust_link)(struct hnae3_handle *handle, int speed, int duplex);
int (*set_loopback)(struct hnae3_handle *handle, int (*set_loopback)(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en); enum hnae3_loop loop_mode, bool en);
......
...@@ -604,6 +604,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev, ...@@ -604,6 +604,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
{ {
struct hnae3_handle *h = hns3_get_handle(netdev); struct hnae3_handle *h = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops; const struct hnae3_ae_ops *ops;
u8 module_type;
u8 media_type; u8 media_type;
u8 link_stat; u8 link_stat;
...@@ -612,7 +613,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev, ...@@ -612,7 +613,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
ops = h->ae_algo->ops; ops = h->ae_algo->ops;
if (ops->get_media_type) if (ops->get_media_type)
ops->get_media_type(h, &media_type); ops->get_media_type(h, &media_type, &module_type);
else else
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -622,7 +623,15 @@ static int hns3_get_link_ksettings(struct net_device *netdev, ...@@ -622,7 +623,15 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
hns3_get_ksettings(h, cmd); hns3_get_ksettings(h, cmd);
break; break;
case HNAE3_MEDIA_TYPE_FIBER: case HNAE3_MEDIA_TYPE_FIBER:
cmd->base.port = PORT_FIBRE; if (module_type == HNAE3_MODULE_TYPE_CR)
cmd->base.port = PORT_DA;
else
cmd->base.port = PORT_FIBRE;
hns3_get_ksettings(h, cmd);
break;
case HNAE3_MEDIA_TYPE_BACKPLANE:
cmd->base.port = PORT_NONE;
hns3_get_ksettings(h, cmd); hns3_get_ksettings(h, cmd);
break; break;
case HNAE3_MEDIA_TYPE_COPPER: case HNAE3_MEDIA_TYPE_COPPER:
......
...@@ -244,7 +244,7 @@ enum hclge_opcode_type { ...@@ -244,7 +244,7 @@ enum hclge_opcode_type {
HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011, HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011,
/* SFP command */ /* SFP command */
HCLGE_OPC_SFP_GET_SPEED = 0x7104, HCLGE_OPC_GET_SFP_INFO = 0x7104,
/* Error INT commands */ /* Error INT commands */
HCLGE_MAC_COMMON_INT_EN = 0x030E, HCLGE_MAC_COMMON_INT_EN = 0x030E,
...@@ -599,9 +599,15 @@ struct hclge_config_auto_neg_cmd { ...@@ -599,9 +599,15 @@ struct hclge_config_auto_neg_cmd {
u8 rsv[20]; u8 rsv[20];
}; };
struct hclge_sfp_speed_cmd { struct hclge_sfp_info_cmd {
__le32 sfp_speed; __le32 speed;
u32 rsv[5]; u8 query_type; /* 0: sfp speed, 1: active speed */
u8 active_fec;
u8 autoneg; /* autoneg state */
u8 autoneg_ability; /* whether support autoneg */
__le32 speed_ability; /* speed ability for current media */
__le32 module_type;
u8 rsv[8];
}; };
#define HCLGE_MAC_UPLINK_PORT 0x100 #define HCLGE_MAC_UPLINK_PORT 0x100
......
...@@ -189,6 +189,8 @@ enum HLCGE_PORT_TYPE { ...@@ -189,6 +189,8 @@ enum HLCGE_PORT_TYPE {
#define HCLGE_SUPPORT_25G_BIT BIT(2) #define HCLGE_SUPPORT_25G_BIT BIT(2)
#define HCLGE_SUPPORT_50G_BIT BIT(3) #define HCLGE_SUPPORT_50G_BIT BIT(3)
#define HCLGE_SUPPORT_100G_BIT BIT(4) #define HCLGE_SUPPORT_100G_BIT BIT(4)
/* to be compatible with exsit board */
#define HCLGE_SUPPORT_40G_BIT BIT(5)
#define HCLGE_SUPPORT_100M_BIT BIT(6) #define HCLGE_SUPPORT_100M_BIT BIT(6)
#define HCLGE_SUPPORT_10M_BIT BIT(7) #define HCLGE_SUPPORT_10M_BIT BIT(7)
#define HCLGE_SUPPORT_GE \ #define HCLGE_SUPPORT_GE \
...@@ -236,14 +238,21 @@ enum HCLGE_MAC_DUPLEX { ...@@ -236,14 +238,21 @@ enum HCLGE_MAC_DUPLEX {
HCLGE_MAC_FULL HCLGE_MAC_FULL
}; };
#define QUERY_SFP_SPEED 0
#define QUERY_ACTIVE_SPEED 1
struct hclge_mac { struct hclge_mac {
u8 phy_addr; u8 phy_addr;
u8 flag; u8 flag;
u8 media_type; u8 media_type; /* port media type, e.g. fibre/copper/backplane */
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
u8 autoneg; u8 autoneg;
u8 duplex; u8 duplex;
u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */
u32 speed; u32 speed;
u32 speed_ability; /* speed ability supported by current media */
u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
int link; /* store the link status of mac & phy (if phy exit)*/ int link; /* store the link status of mac & phy (if phy exit)*/
struct phy_device *phydev; struct phy_device *phydev;
struct mii_bus *mdio_bus; struct mii_bus *mdio_bus;
......
...@@ -412,10 +412,11 @@ static int hclge_get_vf_media_type(struct hclge_vport *vport, ...@@ -412,10 +412,11 @@ static int hclge_get_vf_media_type(struct hclge_vport *vport,
struct hclge_mbx_vf_to_pf_cmd *mbx_req) struct hclge_mbx_vf_to_pf_cmd *mbx_req)
{ {
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
u8 resp_data; u8 resp_data[2];
resp_data = hdev->hw.mac.media_type; resp_data[0] = hdev->hw.mac.media_type;
return hclge_gen_resp_to_vf(vport, mbx_req, 0, &resp_data, resp_data[1] = hdev->hw.mac.module_type;
return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data,
sizeof(resp_data)); sizeof(resp_data));
} }
......
...@@ -330,11 +330,11 @@ static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id) ...@@ -330,11 +330,11 @@ static u16 hclgevf_get_qid_global(struct hnae3_handle *handle, u16 queue_id)
static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev) static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev)
{ {
u8 resp_msg; u8 resp_msg[2];
int ret; int ret;
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MEDIA_TYPE, 0, NULL, 0, ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MEDIA_TYPE, 0, NULL, 0,
true, &resp_msg, sizeof(resp_msg)); true, resp_msg, sizeof(resp_msg));
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"VF request to get the pf port media type failed %d", "VF request to get the pf port media type failed %d",
...@@ -342,7 +342,8 @@ static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev) ...@@ -342,7 +342,8 @@ static int hclgevf_get_pf_media_type(struct hclgevf_dev *hdev)
return ret; return ret;
} }
hdev->hw.mac.media_type = resp_msg; hdev->hw.mac.media_type = resp_msg[0];
hdev->hw.mac.module_type = resp_msg[1];
return 0; return 0;
} }
...@@ -2747,12 +2748,16 @@ static int hclgevf_gro_en(struct hnae3_handle *handle, bool enable) ...@@ -2747,12 +2748,16 @@ static int hclgevf_gro_en(struct hnae3_handle *handle, bool enable)
return hclgevf_config_gro(hdev, enable); return hclgevf_config_gro(hdev, enable);
} }
static void hclgevf_get_media_type(struct hnae3_handle *handle, static void hclgevf_get_media_type(struct hnae3_handle *handle, u8 *media_type,
u8 *media_type) u8 *module_type)
{ {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
if (media_type) if (media_type)
*media_type = hdev->hw.mac.media_type; *media_type = hdev->hw.mac.media_type;
if (module_type)
*module_type = hdev->hw.mac.module_type;
} }
static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle) static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle)
......
...@@ -143,6 +143,7 @@ enum hclgevf_states { ...@@ -143,6 +143,7 @@ enum hclgevf_states {
struct hclgevf_mac { struct hclgevf_mac {
u8 media_type; u8 media_type;
u8 module_type;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
int link; int link;
u8 duplex; u8 duplex;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment