提交 9bfc5a8c 编写于 作者: C Chiqijun 提交者: Yang Yingliang

Added ethtool_ops interface to query optical module information

driver inclusion
category: feature
bugzilla: 4472

-----------------------------------------------------------------------

Obtaining optical module information is time-consuming. If the user
frequently acquires, it will affect the firmware to process other
commands. To prevent such events, the firmware will actively report
the optical module information to the driver when it is idle. Obtained
from the driver cache information. When the user obtains through the
command, directly obtain from the information saved by the driver.
Signed-off-by: NChiqijun <chiqijun@huawei.com>
Reviewed-by: NLuoshaokai <luoshaokai@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 d38bc42e
......@@ -2039,6 +2039,74 @@ static void hinic_diag_test(struct net_device *netdev,
hinic_lp_test(netdev, eth_test, data, 0);
}
#ifdef ETHTOOL_GMODULEEEPROM
static int hinic_get_module_info(struct net_device *netdev,
struct ethtool_modinfo *modinfo)
{
struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
u8 sfp_type;
u8 sfp_type_ext;
int err;
err = hinic_get_sfp_type(nic_dev->hwdev, &sfp_type, &sfp_type_ext);
if (err)
return err;
switch (sfp_type) {
case MODULE_TYPE_SFP:
modinfo->type = ETH_MODULE_SFF_8472;
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
break;
case MODULE_TYPE_QSFP:
modinfo->type = ETH_MODULE_SFF_8436;
modinfo->eeprom_len = STD_SFP_INFO_MAX_SIZE;
break;
case MODULE_TYPE_QSFP_PLUS:
if (sfp_type_ext >= 0x3) {
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = STD_SFP_INFO_MAX_SIZE;
} else {
modinfo->type = ETH_MODULE_SFF_8436;
modinfo->eeprom_len = STD_SFP_INFO_MAX_SIZE;
}
break;
case MODULE_TYPE_QSFP28:
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = STD_SFP_INFO_MAX_SIZE;
break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
return -EINVAL;
}
return 0;
}
static int hinic_get_module_eeprom(struct net_device *netdev,
struct ethtool_eeprom *ee, u8 *data)
{
struct hinic_nic_dev *nic_dev = netdev_priv(netdev);
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
u16 len;
int err;
if (!ee->len || ((ee->len + ee->offset) > STD_SFP_INFO_MAX_SIZE))
return -EINVAL;
memset(data, 0, ee->len);
err = hinic_get_sfp_eeprom(nic_dev->hwdev, sfp_data, &len);
if (err)
return err;
memcpy(data, sfp_data + ee->offset, ee->len);
return 0;
}
#endif /* ETHTOOL_GMODULEEEPROM */
static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd,
struct nic_rss_type *rss_type)
{
......@@ -2532,6 +2600,10 @@ static const struct ethtool_ops hinic_ethtool_ops = {
#ifndef HAVE_RHEL6_ETHTOOL_OPS_EXT_STRUCT
.get_channels = hinic_get_channels,
.set_channels = hinic_set_channels,
#ifdef ETHTOOL_GMODULEEEPROM
.get_module_info = hinic_get_module_info,
.get_module_eeprom = hinic_get_module_eeprom,
#endif
#ifndef NOT_HAVE_GET_RXFH_INDIR_SIZE
.get_rxfh_indir_size = hinic_get_rxfh_indir_size,
#endif
......@@ -2552,6 +2624,11 @@ static const struct ethtool_ops_ext hinic_ethtool_ops_ext = {
.set_phys_id = hinic_set_phys_id,
.get_channels = hinic_get_channels,
.set_channels = hinic_set_channels,
#ifdef ETHTOOL_GMODULEEEPROM
.get_module_info = hinic_get_module_info,
.get_module_eeprom = hinic_get_module_eeprom,
#endif
#ifndef NOT_HAVE_GET_RXFH_INDIR_SIZE
.get_rxfh_indir_size = hinic_get_rxfh_indir_size,
#endif
......
......@@ -264,6 +264,56 @@ struct hinic_init_para {
#define INIT_SUCCESS 1
#define MAX_DRV_BUF_SIZE 4096
struct hinic_cmd_get_light_module_abs {
u8 status;
u8 version;
u8 rsvd0[6];
u8 port_id;
u8 abs_status; /* 0:present, 1:absent */
u8 rsv[2];
};
#define MODULE_TYPE_SFP 0x3
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
#define SFP_INFO_MAX_SIZE 512
struct hinic_cmd_get_sfp_qsfp_info {
u8 status;
u8 version;
u8 rsvd0[6];
u8 port_id;
u8 wire_type;
u16 out_len;
u8 sfp_qsfp_info[SFP_INFO_MAX_SIZE];
};
#define STD_SFP_INFO_MAX_SIZE 640
struct hinic_cmd_get_std_sfp_info {
u8 status;
u8 version;
u8 rsvd0[6];
u8 port_id;
u8 wire_type;
u16 eeprom_len;
u32 rsvd;
u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
};
#define HINIC_MAX_PORT_ID 4
struct hinic_port_routine_cmd {
int up_send_sfp_info;
int up_send_sfp_abs;
struct hinic_cmd_get_sfp_qsfp_info sfp_info;
struct hinic_cmd_get_light_module_abs abs;
};
struct card_node {
struct list_head node;
struct list_head func_list;
......@@ -282,6 +332,10 @@ struct card_node {
bool disable_vf_load[HINIC_MAX_PF_NUM];
u32 vf_mbx_old_rand_id[MAX_FUNCTION_NUM];
u32 vf_mbx_rand_id[MAX_FUNCTION_NUM];
struct hinic_port_routine_cmd rt_cmd[HINIC_MAX_PORT_ID];
/* mutex used for copy sfp info */
struct mutex sfp_mutex;
};
enum hinic_hwdev_init_state {
......
......@@ -59,6 +59,8 @@
#define HINIC_OK_FLAG_FAILED 1
#define HINIC_GET_SFP_INFO_REAL_TIME 0x1
#define HINIC_GLB_SO_RO_CFG_SHIFT 0x0
#define HINIC_GLB_SO_RO_CFG_MASK 0x1
#define HINIC_DISABLE_ORDER 0
......@@ -913,6 +915,80 @@ int hinic_pf_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
return err;
}
static bool is_sfp_info_cmd_cached(struct hinic_hwdev *hwdev,
enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct hinic_cmd_get_sfp_qsfp_info *sfp_info = NULL;
struct hinic_port_routine_cmd *rt_cmd = NULL;
struct card_node *chip_node = hwdev->chip_node;
sfp_info = buf_in;
if (sfp_info->port_id >= HINIC_MAX_PORT_ID ||
*out_size < sizeof(*sfp_info))
return false;
if (sfp_info->version == HINIC_GET_SFP_INFO_REAL_TIME)
return false;
rt_cmd = &chip_node->rt_cmd[sfp_info->port_id];
mutex_lock(&chip_node->sfp_mutex);
memcpy(buf_out, &rt_cmd->sfp_info, sizeof(*sfp_info));
mutex_unlock(&chip_node->sfp_mutex);
return true;
}
static bool is_sfp_abs_cmd_cached(struct hinic_hwdev *hwdev,
enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct hinic_cmd_get_light_module_abs *abs = NULL;
struct hinic_port_routine_cmd *rt_cmd = NULL;
struct card_node *chip_node = hwdev->chip_node;
abs = buf_in;
if (abs->port_id >= HINIC_MAX_PORT_ID ||
*out_size < sizeof(*abs))
return false;
if (abs->version == HINIC_GET_SFP_INFO_REAL_TIME)
return false;
rt_cmd = &chip_node->rt_cmd[abs->port_id];
mutex_lock(&chip_node->sfp_mutex);
memcpy(buf_out, &rt_cmd->abs, sizeof(*abs));
mutex_unlock(&chip_node->sfp_mutex);
return true;
}
static bool driver_processed_cmd(struct hinic_hwdev *hwdev,
enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct card_node *chip_node = hwdev->chip_node;
if (mod == HINIC_MOD_L2NIC) {
if (cmd == HINIC_PORT_CMD_GET_SFP_INFO &&
chip_node->rt_cmd->up_send_sfp_info) {
return is_sfp_info_cmd_cached(hwdev, mod, cmd, buf_in,
in_size, buf_out,
out_size);
} else if (cmd == HINIC_PORT_CMD_GET_SFP_ABS &&
chip_node->rt_cmd->up_send_sfp_abs) {
return is_sfp_abs_cmd_cached(hwdev, mod, cmd, buf_in,
in_size, buf_out,
out_size);
}
}
return false;
}
int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
void *buf_in, u16 in_size,
void *buf_out, u16 *out_size, u32 timeout)
......@@ -949,6 +1025,10 @@ int hinic_msg_to_mgmt_sync(void *hwdev, enum hinic_mod_type mod, u8 cmd,
err = __func_send_mbox(hwdev, mod, cmd, buf_in, in_size,
buf_out, out_size, timeout);
} else {
if (driver_processed_cmd(hwdev, mod, cmd, buf_in, in_size,
buf_out, out_size))
return 0;
do {
if (!hinic_get_mgmt_channel_status(hwdev) ||
!hinic_get_chip_present_flag(hwdev))
......@@ -3202,6 +3282,8 @@ enum hinic_event_cmd {
HINIC_EVENT_MGMT_PCIE_DFX,
HINIC_EVENT_MCTP_HOST_INFO,
HINIC_EVENT_MGMT_HEARTBEAT_EHD,
HINIC_EVENT_SFP_INFO_REPORT,
HINIC_EVENT_SFP_ABS_REPORT,
HINIC_EVENT_MAX_TYPE,
};
......@@ -3284,6 +3366,16 @@ static struct hinic_event_convert __event_convert[] = {
.cmd = HINIC_MGMT_CMD_HEARTBEAT_EVENT,
.event = HINIC_EVENT_MGMT_HEARTBEAT_EHD,
},
{
.mod = HINIC_MOD_L2NIC,
.cmd = HINIC_PORT_CMD_GET_SFP_INFO,
.event = HINIC_EVENT_SFP_INFO_REPORT,
},
{
.mod = HINIC_MOD_L2NIC,
.cmd = HINIC_PORT_CMD_GET_SFP_ABS,
.event = HINIC_EVENT_SFP_ABS_REPORT,
},
};
static enum hinic_event_cmd __get_event_type(u8 mod, u8 cmd)
......@@ -3587,12 +3679,22 @@ static void module_status_event(struct hinic_hwdev *hwdev,
struct hinic_cable_plug_event *plug_event;
struct hinic_link_err_event *link_err;
struct hinic_event_info event_info = {0};
struct hinic_port_routine_cmd *rt_cmd;
struct card_node *chip_node = hwdev->chip_node;
event_info.type = HINIC_EVENT_PORT_MODULE_EVENT;
if (cmd == HINIC_EVENT_CABLE_PLUG) {
plug_event = buf_in;
if (plug_event->port_id < HINIC_MAX_PORT_ID) {
rt_cmd = &chip_node->rt_cmd[plug_event->port_id];
mutex_lock(&chip_node->sfp_mutex);
rt_cmd->up_send_sfp_abs = false;
rt_cmd->up_send_sfp_info = false;
mutex_unlock(&chip_node->sfp_mutex);
}
event_info.module_event.type = plug_event->plugged ?
HINIC_PORT_MODULE_CABLE_PLUGGED :
HINIC_PORT_MODULE_CABLE_UNPLUGGED;
......@@ -3733,6 +3835,64 @@ static void mgmt_watchdog_timeout_event_handler(struct hinic_hwdev *hwdev,
queue_work(hwdev->workq, &hwdev->fault_work);
}
static void port_sfp_info_event(struct hinic_hwdev *hwdev, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size)
{
struct hinic_cmd_get_sfp_qsfp_info *sfp_info = buf_in;
struct hinic_port_routine_cmd *rt_cmd;
struct card_node *chip_node = hwdev->chip_node;
if (in_size != sizeof(*sfp_info)) {
sdk_err(hwdev->dev_hdl, "Invalid sfp info cmd, length: %d, should be %ld\n",
in_size, sizeof(*sfp_info));
return;
}
if (sfp_info->port_id >= HINIC_MAX_PORT_ID) {
sdk_err(hwdev->dev_hdl, "Invalid sfp port id: %d, max port is %d\n",
sfp_info->port_id, HINIC_MAX_PORT_ID - 1);
return;
}
if (!chip_node->rt_cmd)
return;
rt_cmd = &chip_node->rt_cmd[sfp_info->port_id];
mutex_lock(&chip_node->sfp_mutex);
memcpy(&rt_cmd->sfp_info, sfp_info, sizeof(rt_cmd->sfp_info));
rt_cmd->up_send_sfp_info = true;
mutex_unlock(&chip_node->sfp_mutex);
}
static void port_sfp_abs_event(struct hinic_hwdev *hwdev, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size)
{
struct hinic_cmd_get_light_module_abs *sfp_abs = buf_in;
struct hinic_port_routine_cmd *rt_cmd;
struct card_node *chip_node = hwdev->chip_node;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(hwdev->dev_hdl, "Invalid sfp absent cmd, length: %d, should be %ld\n",
in_size, sizeof(*sfp_abs));
return;
}
if (sfp_abs->port_id >= HINIC_MAX_PORT_ID) {
sdk_err(hwdev->dev_hdl, "Invalid sfp port id: %d, max port is %d\n",
sfp_abs->port_id, HINIC_MAX_PORT_ID - 1);
return;
}
if (!chip_node->rt_cmd)
return;
rt_cmd = &chip_node->rt_cmd[sfp_abs->port_id];
mutex_lock(&chip_node->sfp_mutex);
memcpy(&rt_cmd->abs, sfp_abs, sizeof(rt_cmd->abs));
rt_cmd->up_send_sfp_abs = true;
mutex_unlock(&chip_node->sfp_mutex);
}
static void mgmt_reset_event_handler(struct hinic_hwdev *hwdev)
{
sdk_info(hwdev->dev_hdl, "Mgmt is reset\n");
......@@ -4241,6 +4401,14 @@ static void _event_handler(struct hinic_hwdev *hwdev, enum hinic_event_cmd cmd,
buf_out, out_size);
break;
case HINIC_EVENT_SFP_INFO_REPORT:
port_sfp_info_event(hwdev, buf_in, in_size, buf_out, out_size);
break;
case HINIC_EVENT_SFP_ABS_REPORT:
port_sfp_abs_event(hwdev, buf_in, in_size, buf_out, out_size);
break;
default:
sdk_warn(hwdev->dev_hdl, "Unsupported event %d to process\n",
cmd);
......
......@@ -1990,6 +1990,8 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter)
INIT_LIST_HEAD(&chip_node->func_list);
pci_adapter->chip_node = chip_node;
mutex_init(&chip_node->sfp_mutex);
return 0;
alloc_dbgtool_attr_file_err:
......
......@@ -680,6 +680,16 @@ struct hinic_capture_info {
u32 data_vlan;
};
struct hinic_port_rt_cmd {
u8 status;
u8 version;
u8 rsvd0[6];
u8 pf_id;
u8 enable;
u8 rsvd1[6];
};
struct hinic_vf_dcb_state {
u8 status;
u8 version;
......@@ -737,6 +747,8 @@ void hinic_vf_func_free(struct hinic_hwdev *hwdev);
void hinic_unregister_vf_msg_handler(void *hwdev, u16 vf_id);
int hinic_set_port_routine_cmd_report(void *hwdev, bool enable);
int hinic_refresh_nic_cfg(void *hwdev, struct nic_port_info *port_info);
int hinic_save_dcb_state(struct hinic_hwdev *hwdev,
......
......@@ -35,7 +35,6 @@
#include "hinic_nic.h"
#include "hinic_mgmt_interface.h"
#include "hinic_hwif.h"
#include "hinic_eqs.h"
static unsigned char set_vf_link_state;
module_param(set_vf_link_state, byte, 0444);
......@@ -3571,6 +3570,35 @@ int hinic_set_super_cqe_state(void *hwdev, bool enable)
return 0;
}
int hinic_set_port_routine_cmd_report(void *hwdev, bool enable)
{
struct hinic_port_rt_cmd rt_cmd = { 0 };
struct hinic_hwdev *dev = hwdev;
u16 out_size = sizeof(rt_cmd);
int err;
if (!hwdev)
return -EINVAL;
rt_cmd.pf_id = (u8)hinic_global_func_id(hwdev);
rt_cmd.enable = enable;
err = l2nic_msg_to_mgmt_sync(hwdev,
HINIC_PORT_CMD_SET_PORT_REPORT,
&rt_cmd, sizeof(rt_cmd), &rt_cmd,
&out_size);
if (rt_cmd.status == HINIC_MGMT_CMD_UNSUPPORTED) {
nic_info(dev->dev_hdl, "Current firmware doesn't support to set port routine command report\n");
} else if (rt_cmd.status || err || !out_size) {
nic_err(dev->dev_hdl,
"Failed to set port routine command report, err: %d, status: 0x%x, out size: 0x%x\n",
err, rt_cmd.status, out_size);
return -EFAULT;
}
return 0;
}
int hinic_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
struct hinic_hwdev *dev = hwdev;
......@@ -3889,3 +3917,112 @@ int hinic_disable_tx_promisc(void *hwdev)
}
return 0;
}
static bool hinic_if_sfp_absent(void *hwdev)
{
struct card_node *chip_node = ((struct hinic_hwdev *)hwdev)->chip_node;
struct hinic_port_routine_cmd *rt_cmd;
struct hinic_cmd_get_light_module_abs sfp_abs = {0};
u8 port_id = hinic_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
bool sfp_abs_valid;
bool sfp_abs_status;
rt_cmd = &chip_node->rt_cmd[port_id];
mutex_lock(&chip_node->sfp_mutex);
sfp_abs_valid = rt_cmd->up_send_sfp_abs;
sfp_abs_status = (bool)rt_cmd->abs.abs_status;
if (sfp_abs_valid) {
mutex_unlock(&chip_node->sfp_mutex);
return sfp_abs_status;
}
mutex_unlock(&chip_node->sfp_mutex);
sfp_abs.port_id = port_id;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
&sfp_abs, sizeof(sfp_abs), &sfp_abs,
&out_size);
if (sfp_abs.status || err || !out_size) {
nic_err(((struct hinic_hwdev *)hwdev)->dev_hdl,
"Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
port_id, err, sfp_abs.status, out_size);
return true;
}
return ((sfp_abs.abs_status == 0) ? false : true);
}
int hinic_get_sfp_eeprom(void *hwdev, u8 *data, u16 *len)
{
struct hinic_cmd_get_std_sfp_info sfp_info = {0};
u8 port_id;
u16 out_size = sizeof(sfp_info);
int err;
if (!hwdev || !data || !len)
return -EINVAL;
port_id = hinic_physical_port_id(hwdev);
if (port_id >= HINIC_MAX_PORT_ID)
return -EINVAL;
if (hinic_if_sfp_absent(hwdev))
return -ENXIO;
sfp_info.port_id = port_id;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
&sfp_info, sizeof(sfp_info), &sfp_info,
&out_size);
if (sfp_info.status || err || !out_size) {
nic_err(((struct hinic_hwdev *)hwdev)->dev_hdl,
"Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
port_id, err, sfp_info.status, out_size);
return -EIO;
}
*len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);
return 0;
}
int hinic_get_sfp_type(void *hwdev, u8 *data0, u8 *data1)
{
struct card_node *chip_node = NULL;
struct hinic_port_routine_cmd *rt_cmd;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
u16 len;
u8 port_id;
int err;
if (!hwdev || !data0 || !data1)
return -EINVAL;
port_id = hinic_physical_port_id(hwdev);
if (port_id >= HINIC_MAX_PORT_ID)
return -EINVAL;
if (hinic_if_sfp_absent(hwdev))
return -ENXIO;
chip_node = ((struct hinic_hwdev *)hwdev)->chip_node;
rt_cmd = &chip_node->rt_cmd[port_id];
mutex_lock(&chip_node->sfp_mutex);
if (rt_cmd->up_send_sfp_info) {
*data0 = rt_cmd->sfp_info.sfp_qsfp_info[0];
*data1 = rt_cmd->sfp_info.sfp_qsfp_info[1];
mutex_unlock(&chip_node->sfp_mutex);
return 0;
}
mutex_unlock(&chip_node->sfp_mutex);
err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
if (err)
return err;
*data0 = sfp_data[0];
*data1 = sfp_data[1];
return 0;
}
......@@ -620,5 +620,7 @@ int hinic_add_hw_rqfilter(void *hwdev,
struct hinic_rq_filter_info *filter_info);
int hinic_del_hw_rqfilter(void *hwdev,
struct hinic_rq_filter_info *filter_info);
int hinic_get_sfp_eeprom(void *hwdev, u8 *data, u16 *len);
int hinic_get_sfp_type(void *hwdev, u8 *data0, u8 *data1);
#endif
......@@ -829,13 +829,20 @@ int hinic_init_nic_hwdev(void *hwdev, u16 rx_buff_len)
}
}
}
return 0;
/* VFs don't set port routine command report */
if (hinic_func_type(dev) != TYPE_VF)
/* Inform mgmt to send sfp's information to driver */
err = hinic_set_port_routine_cmd_report(hwdev, true);
return err;
}
EXPORT_SYMBOL(hinic_init_nic_hwdev);
void hinic_free_nic_hwdev(void *hwdev)
{
/* nothing to do for now */
if (hinic_func_type(hwdev) != TYPE_VF)
hinic_set_port_routine_cmd_report(hwdev, false);
}
EXPORT_SYMBOL(hinic_free_nic_hwdev);
......
......@@ -146,6 +146,8 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_SET_PORT_LINK_STATUS = 0x76,
HINIC_PORT_CMD_SET_CGE_PAUSE_TIME_CFG = 0x77,
HINIC_PORT_CMD_SET_PORT_REPORT = 0x7B,
HINIC_PORT_CMD_LINK_STATUS_REPORT = 0xa0,
HINIC_PORT_CMD_SET_LOSSLESS_ETH = 0xa3,
......@@ -200,6 +202,7 @@ enum hinic_port_cmd {
HINIC_PORT_CMD_SET_LINK_FOLLOW = 0xF8,
HINIC_PORT_CMD_SET_VF_MAX_MIN_RATE = 0xF9,
HINIC_PORT_CMD_SET_RXQ_LRO_ADPT = 0xFA,
HINIC_PORT_CMD_GET_SFP_ABS = 0xFB,
HINIC_PORT_CMD_Q_FILTER = 0xFC,
HINIC_PORT_CMD_TCAM_FILTER = 0xFE,
HINIC_PORT_CMD_SET_VLAN_FILTER = 0xFF,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册