cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hinic_port.c (37706B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Huawei HiNIC PCI Express Linux driver
      4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
      5 */
      6
      7#include <linux/types.h>
      8#include <linux/netdevice.h>
      9#include <linux/etherdevice.h>
     10#include <linux/if_vlan.h>
     11#include <linux/pci.h>
     12#include <linux/device.h>
     13#include <linux/errno.h>
     14
     15#include "hinic_hw_if.h"
     16#include "hinic_hw_dev.h"
     17#include "hinic_port.h"
     18#include "hinic_dev.h"
     19
     20#define HINIC_MIN_MTU_SIZE              256
     21#define HINIC_MAX_JUMBO_FRAME_SIZE      15872
     22
     23enum mac_op {
     24	MAC_DEL,
     25	MAC_SET,
     26};
     27
     28/**
     29 * change_mac - change(add or delete) mac address
     30 * @nic_dev: nic device
     31 * @addr: mac address
     32 * @vlan_id: vlan number to set with the mac
     33 * @op: add or delete the mac
     34 *
     35 * Return 0 - Success, negative - Failure
     36 **/
     37static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
     38		      u16 vlan_id, enum mac_op op)
     39{
     40	struct hinic_hwdev *hwdev = nic_dev->hwdev;
     41	struct hinic_port_mac_cmd port_mac_cmd;
     42	struct hinic_hwif *hwif = hwdev->hwif;
     43	u16 out_size = sizeof(port_mac_cmd);
     44	struct pci_dev *pdev = hwif->pdev;
     45	enum hinic_port_cmd cmd;
     46	int err;
     47
     48	if (op == MAC_SET)
     49		cmd = HINIC_PORT_CMD_SET_MAC;
     50	else
     51		cmd = HINIC_PORT_CMD_DEL_MAC;
     52
     53	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
     54	port_mac_cmd.vlan_id = vlan_id;
     55	memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
     56
     57	err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
     58				 sizeof(port_mac_cmd),
     59				 &port_mac_cmd, &out_size);
     60	if (err || out_size != sizeof(port_mac_cmd) ||
     61	    (port_mac_cmd.status &&
     62	     (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
     63	     port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
     64		dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
     65			err, port_mac_cmd.status, out_size);
     66		return -EFAULT;
     67	}
     68
     69	if (port_mac_cmd.status == HINIC_PF_SET_VF_ALREADY) {
     70		dev_warn(&pdev->dev, "PF has already set VF mac, ignore %s operation\n",
     71			 (op == MAC_SET) ? "set" : "del");
     72		return HINIC_PF_SET_VF_ALREADY;
     73	}
     74
     75	if (cmd == HINIC_PORT_CMD_SET_MAC && port_mac_cmd.status ==
     76	    HINIC_MGMT_STATUS_EXIST)
     77		dev_warn(&pdev->dev, "MAC is repeated, ignore set operation\n");
     78
     79	return 0;
     80}
     81
     82/**
     83 * hinic_port_add_mac - add mac address
     84 * @nic_dev: nic device
     85 * @addr: mac address
     86 * @vlan_id: vlan number to set with the mac
     87 *
     88 * Return 0 - Success, negative - Failure
     89 **/
     90int hinic_port_add_mac(struct hinic_dev *nic_dev,
     91		       const u8 *addr, u16 vlan_id)
     92{
     93	return change_mac(nic_dev, addr, vlan_id, MAC_SET);
     94}
     95
     96/**
     97 * hinic_port_del_mac - remove mac address
     98 * @nic_dev: nic device
     99 * @addr: mac address
    100 * @vlan_id: vlan number that is connected to the mac
    101 *
    102 * Return 0 - Success, negative - Failure
    103 **/
    104int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
    105		       u16 vlan_id)
    106{
    107	return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
    108}
    109
    110/**
    111 * hinic_port_get_mac - get the mac address of the nic device
    112 * @nic_dev: nic device
    113 * @addr: returned mac address
    114 *
    115 * Return 0 - Success, negative - Failure
    116 **/
    117int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
    118{
    119	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    120	struct hinic_port_mac_cmd port_mac_cmd;
    121	struct hinic_hwif *hwif = hwdev->hwif;
    122	u16 out_size = sizeof(port_mac_cmd);
    123	struct pci_dev *pdev = hwif->pdev;
    124	int err;
    125
    126	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
    127
    128	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
    129				 &port_mac_cmd, sizeof(port_mac_cmd),
    130				 &port_mac_cmd, &out_size);
    131	if (err || out_size != sizeof(port_mac_cmd) || port_mac_cmd.status) {
    132		dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
    133			err, port_mac_cmd.status, out_size);
    134		return -EFAULT;
    135	}
    136
    137	memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
    138	return 0;
    139}
    140
    141/**
    142 * hinic_port_set_mtu - set mtu
    143 * @nic_dev: nic device
    144 * @new_mtu: new mtu
    145 *
    146 * Return 0 - Success, negative - Failure
    147 **/
    148int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
    149{
    150	struct net_device *netdev = nic_dev->netdev;
    151	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    152	struct hinic_port_mtu_cmd port_mtu_cmd;
    153	struct hinic_hwif *hwif = hwdev->hwif;
    154	u16 out_size = sizeof(port_mtu_cmd);
    155	struct pci_dev *pdev = hwif->pdev;
    156	int err, max_frame;
    157
    158	if (new_mtu < HINIC_MIN_MTU_SIZE) {
    159		netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
    160		return -EINVAL;
    161	}
    162
    163	max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
    164	if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) {
    165		netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size");
    166		return -EINVAL;
    167	}
    168
    169	port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
    170	port_mtu_cmd.mtu = new_mtu;
    171
    172	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
    173				 &port_mtu_cmd, sizeof(port_mtu_cmd),
    174				 &port_mtu_cmd, &out_size);
    175	if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
    176		dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
    177			err, port_mtu_cmd.status, out_size);
    178		return -EFAULT;
    179	}
    180
    181	return 0;
    182}
    183
    184/**
    185 * hinic_port_add_vlan - add vlan to the nic device
    186 * @nic_dev: nic device
    187 * @vlan_id: the vlan number to add
    188 *
    189 * Return 0 - Success, negative - Failure
    190 **/
    191int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
    192{
    193	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    194	struct hinic_port_vlan_cmd port_vlan_cmd;
    195
    196	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
    197	port_vlan_cmd.vlan_id = vlan_id;
    198
    199	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
    200				  &port_vlan_cmd, sizeof(port_vlan_cmd),
    201				  NULL, NULL);
    202}
    203
    204/**
    205 * hinic_port_del_vlan - delete vlan from the nic device
    206 * @nic_dev: nic device
    207 * @vlan_id: the vlan number to delete
    208 *
    209 * Return 0 - Success, negative - Failure
    210 **/
    211int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
    212{
    213	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    214	struct hinic_port_vlan_cmd port_vlan_cmd;
    215
    216	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
    217	port_vlan_cmd.vlan_id = vlan_id;
    218
    219	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
    220				 &port_vlan_cmd, sizeof(port_vlan_cmd),
    221				 NULL, NULL);
    222}
    223
    224/**
    225 * hinic_port_set_rx_mode - set rx mode in the nic device
    226 * @nic_dev: nic device
    227 * @rx_mode: the rx mode to set
    228 *
    229 * Return 0 - Success, negative - Failure
    230 **/
    231int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
    232{
    233	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    234	struct hinic_port_rx_mode_cmd rx_mode_cmd;
    235
    236	rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
    237	rx_mode_cmd.rx_mode = rx_mode;
    238
    239	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
    240				  &rx_mode_cmd, sizeof(rx_mode_cmd),
    241				  NULL, NULL);
    242}
    243
    244/**
    245 * hinic_port_link_state - get the link state
    246 * @nic_dev: nic device
    247 * @link_state: the returned link state
    248 *
    249 * Return 0 - Success, negative - Failure
    250 **/
    251int hinic_port_link_state(struct hinic_dev *nic_dev,
    252			  enum hinic_port_link_state *link_state)
    253{
    254	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    255	struct hinic_hwif *hwif = hwdev->hwif;
    256	struct hinic_port_link_cmd link_cmd;
    257	struct pci_dev *pdev = hwif->pdev;
    258	u16 out_size = sizeof(link_cmd);
    259	int err;
    260
    261	link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
    262
    263	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
    264				 &link_cmd, sizeof(link_cmd),
    265				 &link_cmd, &out_size);
    266	if (err || out_size != sizeof(link_cmd) || link_cmd.status) {
    267		dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
    268			err, link_cmd.status, out_size);
    269		return -EINVAL;
    270	}
    271
    272	*link_state = link_cmd.state;
    273	return 0;
    274}
    275
    276/**
    277 * hinic_port_set_state - set port state
    278 * @nic_dev: nic device
    279 * @state: the state to set
    280 *
    281 * Return 0 - Success, negative - Failure
    282 **/
    283int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
    284{
    285	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    286	struct hinic_port_state_cmd port_state;
    287	struct hinic_hwif *hwif = hwdev->hwif;
    288	struct pci_dev *pdev = hwif->pdev;
    289	u16 out_size = sizeof(port_state);
    290	int err;
    291
    292	if (HINIC_IS_VF(hwdev->hwif))
    293		return 0;
    294
    295	port_state.state = state;
    296
    297	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE,
    298				 &port_state, sizeof(port_state),
    299				 &port_state, &out_size);
    300	if (err || out_size != sizeof(port_state) || port_state.status) {
    301		dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
    302			err, port_state.status, out_size);
    303		return -EFAULT;
    304	}
    305
    306	return 0;
    307}
    308
    309/**
    310 * hinic_port_set_func_state- set func device state
    311 * @nic_dev: nic device
    312 * @state: the state to set
    313 *
    314 * Return 0 - Success, negative - Failure
    315 **/
    316int hinic_port_set_func_state(struct hinic_dev *nic_dev,
    317			      enum hinic_func_port_state state)
    318{
    319	struct hinic_port_func_state_cmd func_state;
    320	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    321	struct hinic_hwif *hwif = hwdev->hwif;
    322	struct pci_dev *pdev = hwif->pdev;
    323	u16 out_size = sizeof(func_state);
    324	int err;
    325
    326	func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
    327	func_state.state = state;
    328
    329	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE,
    330				 &func_state, sizeof(func_state),
    331				 &func_state, &out_size);
    332	if (err || out_size != sizeof(func_state) || func_state.status) {
    333		dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
    334			err, func_state.status, out_size);
    335		return -EFAULT;
    336	}
    337
    338	return 0;
    339}
    340
    341/**
    342 * hinic_port_get_cap - get port capabilities
    343 * @nic_dev: nic device
    344 * @port_cap: returned port capabilities
    345 *
    346 * Return 0 - Success, negative - Failure
    347 **/
    348int hinic_port_get_cap(struct hinic_dev *nic_dev,
    349		       struct hinic_port_cap *port_cap)
    350{
    351	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    352	struct hinic_hwif *hwif = hwdev->hwif;
    353	struct pci_dev *pdev = hwif->pdev;
    354	u16 out_size = sizeof(*port_cap);
    355	int err;
    356
    357	port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);
    358
    359	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP,
    360				 port_cap, sizeof(*port_cap),
    361				 port_cap, &out_size);
    362	if (err || out_size != sizeof(*port_cap) || port_cap->status) {
    363		dev_err(&pdev->dev,
    364			"Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
    365			err, port_cap->status, out_size);
    366		return -EIO;
    367	}
    368
    369	return 0;
    370}
    371
    372/**
    373 * hinic_port_set_tso - set port tso configuration
    374 * @nic_dev: nic device
    375 * @state: the tso state to set
    376 *
    377 * Return 0 - Success, negative - Failure
    378 **/
    379int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
    380{
    381	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    382	struct hinic_hwif *hwif = hwdev->hwif;
    383	struct hinic_tso_config tso_cfg = {0};
    384	struct pci_dev *pdev = hwif->pdev;
    385	u16 out_size = sizeof(tso_cfg);
    386	int err;
    387
    388	tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    389	tso_cfg.tso_en = state;
    390
    391	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO,
    392				 &tso_cfg, sizeof(tso_cfg),
    393				 &tso_cfg, &out_size);
    394	if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
    395		dev_err(&pdev->dev,
    396			"Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
    397			err, tso_cfg.status, out_size);
    398		return -EIO;
    399	}
    400
    401	return 0;
    402}
    403
    404int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
    405{
    406	struct hinic_checksum_offload rx_csum_cfg = {0};
    407	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    408	u16 out_size = sizeof(rx_csum_cfg);
    409	struct hinic_hwif *hwif;
    410	struct pci_dev *pdev;
    411	int err;
    412
    413	if (!hwdev)
    414		return -EINVAL;
    415
    416	hwif = hwdev->hwif;
    417	pdev = hwif->pdev;
    418	rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    419	rx_csum_cfg.rx_csum_offload = en;
    420
    421	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
    422				 &rx_csum_cfg, sizeof(rx_csum_cfg),
    423				 &rx_csum_cfg, &out_size);
    424	if (err || !out_size || rx_csum_cfg.status) {
    425		dev_err(&pdev->dev,
    426			"Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
    427			err, rx_csum_cfg.status, out_size);
    428		return -EIO;
    429	}
    430
    431	return 0;
    432}
    433
    434int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
    435{
    436	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    437	struct hinic_vlan_cfg vlan_cfg;
    438	struct hinic_hwif *hwif;
    439	struct pci_dev *pdev;
    440	u16 out_size;
    441	int err;
    442
    443	if (!hwdev)
    444		return -EINVAL;
    445
    446	out_size = sizeof(vlan_cfg);
    447	hwif = hwdev->hwif;
    448	pdev = hwif->pdev;
    449	vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    450	vlan_cfg.vlan_rx_offload = en;
    451
    452	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
    453				 &vlan_cfg, sizeof(vlan_cfg),
    454				 &vlan_cfg, &out_size);
    455	if (err || !out_size || vlan_cfg.status) {
    456		dev_err(&pdev->dev,
    457			"Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
    458			err, vlan_cfg.status, out_size);
    459		return -EINVAL;
    460	}
    461
    462	return 0;
    463}
    464
    465int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
    466{
    467	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    468	struct hinic_hwif *hwif = hwdev->hwif;
    469	struct hinic_rq_num rq_num = { 0 };
    470	struct pci_dev *pdev = hwif->pdev;
    471	u16 out_size = sizeof(rq_num);
    472	int err;
    473
    474	rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    475	rq_num.num_rqs = num_rqs;
    476	rq_num.rq_depth = ilog2(nic_dev->rq_depth);
    477
    478	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
    479				 &rq_num, sizeof(rq_num),
    480				 &rq_num, &out_size);
    481	if (err || !out_size || rq_num.status) {
    482		dev_err(&pdev->dev,
    483			"Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
    484			err, rq_num.status, out_size);
    485		return -EIO;
    486	}
    487
    488	return 0;
    489}
    490
    491static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
    492			    u8 max_wqe_num)
    493{
    494	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    495	struct hinic_lro_config lro_cfg = { 0 };
    496	struct hinic_hwif *hwif = hwdev->hwif;
    497	struct pci_dev *pdev = hwif->pdev;
    498	u16 out_size = sizeof(lro_cfg);
    499	int err;
    500
    501	lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    502	lro_cfg.lro_ipv4_en = ipv4_en;
    503	lro_cfg.lro_ipv6_en = ipv6_en;
    504	lro_cfg.lro_max_wqe_num = max_wqe_num;
    505
    506	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
    507				 &lro_cfg, sizeof(lro_cfg),
    508				 &lro_cfg, &out_size);
    509	if (err || !out_size || lro_cfg.status) {
    510		dev_err(&pdev->dev,
    511			"Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
    512			err, lro_cfg.status, out_size);
    513		return -EIO;
    514	}
    515
    516	return 0;
    517}
    518
    519static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
    520{
    521	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    522	struct hinic_lro_timer lro_timer = { 0 };
    523	struct hinic_hwif *hwif = hwdev->hwif;
    524	struct pci_dev *pdev = hwif->pdev;
    525	u16 out_size = sizeof(lro_timer);
    526	int err;
    527
    528	lro_timer.status = 0;
    529	lro_timer.type = 0;
    530	lro_timer.enable = 1;
    531	lro_timer.timer = timer_value;
    532
    533	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
    534				 &lro_timer, sizeof(lro_timer),
    535				 &lro_timer, &out_size);
    536	if (lro_timer.status == 0xFF) {
    537		/* For this case, we think status (0xFF) is OK */
    538		lro_timer.status = 0;
    539		dev_dbg(&pdev->dev,
    540			"Set lro timer not supported by the current FW version, it will be 1ms default\n");
    541	}
    542
    543	if (err || !out_size || lro_timer.status) {
    544		dev_err(&pdev->dev,
    545			"Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
    546			err, lro_timer.status, out_size);
    547
    548		return -EIO;
    549	}
    550
    551	return 0;
    552}
    553
    554int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
    555			   u32 lro_timer, u32 wqe_num)
    556{
    557	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    558	u8 ipv4_en;
    559	u8 ipv6_en;
    560	int err;
    561
    562	if (!hwdev)
    563		return -EINVAL;
    564
    565	ipv4_en = lro_en ? 1 : 0;
    566	ipv6_en = lro_en ? 1 : 0;
    567
    568	err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
    569	if (err)
    570		return err;
    571
    572	if (HINIC_IS_VF(nic_dev->hwdev->hwif))
    573		return 0;
    574
    575	err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
    576	if (err)
    577		return err;
    578
    579	return 0;
    580}
    581
    582int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
    583			    const u32 *indir_table)
    584{
    585	struct hinic_rss_indirect_tbl *indir_tbl;
    586	struct hinic_func_to_io *func_to_io;
    587	struct hinic_cmdq_buf cmd_buf;
    588	struct hinic_hwdev *hwdev;
    589	struct hinic_hwif *hwif;
    590	struct pci_dev *pdev;
    591	u32 indir_size;
    592	u64 out_param;
    593	int err, i;
    594	u32 *temp;
    595
    596	hwdev = nic_dev->hwdev;
    597	func_to_io = &hwdev->func_to_io;
    598	hwif = hwdev->hwif;
    599	pdev = hwif->pdev;
    600
    601	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
    602	if (err) {
    603		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
    604		return err;
    605	}
    606
    607	cmd_buf.size = sizeof(*indir_tbl);
    608
    609	indir_tbl = cmd_buf.buf;
    610	indir_tbl->group_index = cpu_to_be32(tmpl_idx);
    611
    612	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
    613		indir_tbl->entry[i] = indir_table[i];
    614
    615		if (0x3 == (i & 0x3)) {
    616			temp = (u32 *)&indir_tbl->entry[i - 3];
    617			*temp = cpu_to_be32(*temp);
    618		}
    619	}
    620
    621	/* cfg the rss indirect table by command queue */
    622	indir_size = HINIC_RSS_INDIR_SIZE / 2;
    623	indir_tbl->offset = 0;
    624	indir_tbl->size = cpu_to_be32(indir_size);
    625
    626	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
    627				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
    628				     &cmd_buf, &out_param);
    629	if (err || out_param != 0) {
    630		dev_err(&pdev->dev, "Failed to set rss indir table\n");
    631		err = -EFAULT;
    632		goto free_buf;
    633	}
    634
    635	indir_tbl->offset = cpu_to_be32(indir_size);
    636	indir_tbl->size = cpu_to_be32(indir_size);
    637	memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
    638
    639	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
    640				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
    641				     &cmd_buf, &out_param);
    642	if (err || out_param != 0) {
    643		dev_err(&pdev->dev, "Failed to set rss indir table\n");
    644		err = -EFAULT;
    645	}
    646
    647free_buf:
    648	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
    649
    650	return err;
    651}
    652
    653int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
    654			    u32 *indir_table)
    655{
    656	struct hinic_rss_indir_table rss_cfg = { 0 };
    657	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    658	struct hinic_hwif *hwif = hwdev->hwif;
    659	struct pci_dev *pdev = hwif->pdev;
    660	u16 out_size = sizeof(rss_cfg);
    661	int err = 0, i;
    662
    663	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    664	rss_cfg.template_id = tmpl_idx;
    665
    666	err = hinic_port_msg_cmd(hwdev,
    667				 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
    668				 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
    669				 &out_size);
    670	if (err || !out_size || rss_cfg.status) {
    671		dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
    672			err, rss_cfg.status, out_size);
    673		return -EINVAL;
    674	}
    675
    676	hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
    677	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
    678		indir_table[i] = rss_cfg.indir[i];
    679
    680	return 0;
    681}
    682
    683int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
    684		       struct hinic_rss_type rss_type)
    685{
    686	struct hinic_rss_context_tbl *ctx_tbl;
    687	struct hinic_func_to_io *func_to_io;
    688	struct hinic_cmdq_buf cmd_buf;
    689	struct hinic_hwdev *hwdev;
    690	struct hinic_hwif *hwif;
    691	struct pci_dev *pdev;
    692	u64 out_param;
    693	u32 ctx = 0;
    694	int err;
    695
    696	hwdev = nic_dev->hwdev;
    697	func_to_io = &hwdev->func_to_io;
    698	hwif = hwdev->hwif;
    699	pdev = hwif->pdev;
    700
    701	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
    702	if (err) {
    703		dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
    704		return -ENOMEM;
    705	}
    706
    707	ctx |=  HINIC_RSS_TYPE_SET(1, VALID) |
    708		HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
    709		HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
    710		HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
    711		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
    712		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
    713		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
    714		HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
    715		HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
    716
    717	cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
    718
    719	ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
    720	ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
    721	ctx_tbl->offset = 0;
    722	ctx_tbl->size = sizeof(u32);
    723	ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
    724	ctx_tbl->rsvd = 0;
    725	ctx_tbl->ctx = cpu_to_be32(ctx);
    726
    727	/* cfg the rss context table by command queue */
    728	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
    729				     HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
    730				     &cmd_buf, &out_param);
    731
    732	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
    733
    734	if (err || out_param != 0) {
    735		dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
    736			err);
    737		return -EFAULT;
    738	}
    739
    740	return 0;
    741}
    742
    743int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
    744		       struct hinic_rss_type *rss_type)
    745{
    746	struct hinic_rss_context_table ctx_tbl = { 0 };
    747	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    748	u16 out_size = sizeof(ctx_tbl);
    749	struct hinic_hwif *hwif;
    750	struct pci_dev *pdev;
    751	int err;
    752
    753	if (!hwdev || !rss_type)
    754		return -EINVAL;
    755
    756	hwif = hwdev->hwif;
    757	pdev = hwif->pdev;
    758
    759	ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    760	ctx_tbl.template_id = tmpl_idx;
    761
    762	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
    763				 &ctx_tbl, sizeof(ctx_tbl),
    764				 &ctx_tbl, &out_size);
    765	if (err || !out_size || ctx_tbl.status) {
    766		dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
    767			err, ctx_tbl.status, out_size);
    768		return -EINVAL;
    769	}
    770
    771	rss_type->ipv4          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
    772	rss_type->ipv6          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
    773	rss_type->ipv6_ext      = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
    774	rss_type->tcp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
    775	rss_type->tcp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
    776	rss_type->tcp_ipv6_ext  = HINIC_RSS_TYPE_GET(ctx_tbl.context,
    777						     TCP_IPV6_EXT);
    778	rss_type->udp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
    779	rss_type->udp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
    780
    781	return 0;
    782}
    783
    784int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
    785			       const u8 *temp)
    786{
    787	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    788	struct hinic_hwif *hwif = hwdev->hwif;
    789	struct hinic_rss_key rss_key = { 0 };
    790	struct pci_dev *pdev = hwif->pdev;
    791	u16 out_size = sizeof(rss_key);
    792	int err;
    793
    794	rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    795	rss_key.template_id = template_id;
    796	memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
    797
    798	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
    799				 &rss_key, sizeof(rss_key),
    800				 &rss_key, &out_size);
    801	if (err || !out_size || rss_key.status) {
    802		dev_err(&pdev->dev,
    803			"Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
    804			err, rss_key.status, out_size);
    805		return -EINVAL;
    806	}
    807
    808	return 0;
    809}
    810
    811int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
    812			       u8 *temp)
    813{
    814	struct hinic_rss_template_key temp_key = { 0 };
    815	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    816	u16 out_size = sizeof(temp_key);
    817	struct hinic_hwif *hwif;
    818	struct pci_dev *pdev;
    819	int err;
    820
    821	if (!hwdev || !temp)
    822		return -EINVAL;
    823
    824	hwif = hwdev->hwif;
    825	pdev = hwif->pdev;
    826
    827	temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    828	temp_key.template_id = tmpl_idx;
    829
    830	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
    831				 &temp_key, sizeof(temp_key),
    832				 &temp_key, &out_size);
    833	if (err || !out_size || temp_key.status) {
    834		dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
    835			err, temp_key.status, out_size);
    836		return -EINVAL;
    837	}
    838
    839	memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
    840
    841	return 0;
    842}
    843
    844int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
    845			      u8 type)
    846{
    847	struct hinic_rss_engine_type rss_engine = { 0 };
    848	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    849	struct hinic_hwif *hwif = hwdev->hwif;
    850	struct pci_dev *pdev = hwif->pdev;
    851	u16 out_size = sizeof(rss_engine);
    852	int err;
    853
    854	rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    855	rss_engine.hash_engine = type;
    856	rss_engine.template_id = template_id;
    857
    858	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
    859				 &rss_engine, sizeof(rss_engine),
    860				 &rss_engine, &out_size);
    861	if (err || !out_size || rss_engine.status) {
    862		dev_err(&pdev->dev,
    863			"Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
    864			err, rss_engine.status, out_size);
    865		return -EINVAL;
    866	}
    867
    868	return 0;
    869}
    870
    871int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
    872{
    873	struct hinic_rss_engine_type hash_type = { 0 };
    874	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    875	u16 out_size = sizeof(hash_type);
    876	struct hinic_hwif *hwif;
    877	struct pci_dev *pdev;
    878	int err;
    879
    880	if (!hwdev || !type)
    881		return -EINVAL;
    882
    883	hwif = hwdev->hwif;
    884	pdev = hwif->pdev;
    885
    886	hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    887	hash_type.template_id = tmpl_idx;
    888
    889	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
    890				 &hash_type, sizeof(hash_type),
    891				 &hash_type, &out_size);
    892	if (err || !out_size || hash_type.status) {
    893		dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
    894			err, hash_type.status, out_size);
    895		return -EINVAL;
    896	}
    897
    898	*type = hash_type.hash_engine;
    899	return 0;
    900}
    901
    902int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
    903{
    904	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    905	struct hinic_rss_config rss_cfg = { 0 };
    906	struct hinic_hwif *hwif = hwdev->hwif;
    907	struct pci_dev *pdev = hwif->pdev;
    908	u16 out_size = sizeof(rss_cfg);
    909	int err;
    910
    911	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    912	rss_cfg.rss_en = rss_en;
    913	rss_cfg.template_id = template_id;
    914	rss_cfg.rq_priority_number = 0;
    915
    916	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
    917				 &rss_cfg, sizeof(rss_cfg),
    918				 &rss_cfg, &out_size);
    919	if (err || !out_size || rss_cfg.status) {
    920		dev_err(&pdev->dev,
    921			"Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
    922			err, rss_cfg.status, out_size);
    923		return -EINVAL;
    924	}
    925
    926	return 0;
    927}
    928
    929int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
    930{
    931	struct hinic_rss_template_mgmt template_mgmt = { 0 };
    932	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    933	struct hinic_hwif *hwif = hwdev->hwif;
    934	u16 out_size = sizeof(template_mgmt);
    935	struct pci_dev *pdev = hwif->pdev;
    936	int err;
    937
    938	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    939	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
    940
    941	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
    942				 &template_mgmt, sizeof(template_mgmt),
    943				 &template_mgmt, &out_size);
    944	if (err || !out_size || template_mgmt.status) {
    945		dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
    946			err, template_mgmt.status, out_size);
    947		return -EINVAL;
    948	}
    949
    950	*tmpl_idx = template_mgmt.template_id;
    951
    952	return 0;
    953}
    954
    955int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
    956{
    957	struct hinic_rss_template_mgmt template_mgmt = { 0 };
    958	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    959	struct hinic_hwif *hwif = hwdev->hwif;
    960	u16 out_size = sizeof(template_mgmt);
    961	struct pci_dev *pdev = hwif->pdev;
    962	int err;
    963
    964	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    965	template_mgmt.template_id = tmpl_idx;
    966	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
    967
    968	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
    969				 &template_mgmt, sizeof(template_mgmt),
    970				 &template_mgmt, &out_size);
    971	if (err || !out_size || template_mgmt.status) {
    972		dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
    973			err, template_mgmt.status, out_size);
    974		return -EINVAL;
    975	}
    976
    977	return 0;
    978}
    979
    980int hinic_get_vport_stats(struct hinic_dev *nic_dev,
    981			  struct hinic_vport_stats *stats)
    982{
    983	struct hinic_cmd_vport_stats vport_stats = { 0 };
    984	struct hinic_port_stats_info stats_info = { 0 };
    985	struct hinic_hwdev *hwdev = nic_dev->hwdev;
    986	struct hinic_hwif *hwif = hwdev->hwif;
    987	u16 out_size = sizeof(vport_stats);
    988	struct pci_dev *pdev = hwif->pdev;
    989	int err;
    990
    991	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
    992	stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
    993	stats_info.stats_size = sizeof(vport_stats);
    994
    995	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
    996				 &stats_info, sizeof(stats_info),
    997				 &vport_stats, &out_size);
    998	if (err || !out_size || vport_stats.status) {
    999		dev_err(&pdev->dev,
   1000			"Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
   1001			err, vport_stats.status, out_size);
   1002		return -EFAULT;
   1003	}
   1004
   1005	memcpy(stats, &vport_stats.stats, sizeof(*stats));
   1006	return 0;
   1007}
   1008
   1009int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
   1010			     struct hinic_phy_port_stats *stats)
   1011{
   1012	struct hinic_port_stats_info stats_info = { 0 };
   1013	struct hinic_hwdev *hwdev = nic_dev->hwdev;
   1014	struct hinic_hwif *hwif = hwdev->hwif;
   1015	struct hinic_port_stats *port_stats;
   1016	u16 out_size = sizeof(*port_stats);
   1017	struct pci_dev *pdev = hwif->pdev;
   1018	int err;
   1019
   1020	port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
   1021	if (!port_stats)
   1022		return -ENOMEM;
   1023
   1024	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
   1025	stats_info.stats_size = sizeof(*port_stats);
   1026
   1027	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
   1028				 &stats_info, sizeof(stats_info),
   1029				 port_stats, &out_size);
   1030	if (err || !out_size || port_stats->status) {
   1031		dev_err(&pdev->dev,
   1032			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
   1033			err, port_stats->status, out_size);
   1034		err = -EINVAL;
   1035		goto out;
   1036	}
   1037
   1038	memcpy(stats, &port_stats->stats, sizeof(*stats));
   1039
   1040out:
   1041	kfree(port_stats);
   1042
   1043	return err;
   1044}
   1045
   1046int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
   1047{
   1048	struct hinic_hwdev *hwdev = nic_dev->hwdev;
   1049	struct hinic_version_info up_ver = {0};
   1050	u16 out_size = sizeof(up_ver);
   1051	struct hinic_hwif *hwif;
   1052	struct pci_dev *pdev;
   1053	int err;
   1054
   1055	if (!hwdev)
   1056		return -EINVAL;
   1057
   1058	hwif = hwdev->hwif;
   1059	pdev = hwif->pdev;
   1060
   1061	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
   1062				 &up_ver, sizeof(up_ver), &up_ver,
   1063				 &out_size);
   1064	if (err || !out_size || up_ver.status) {
   1065		dev_err(&pdev->dev,
   1066			"Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
   1067			err, up_ver.status, out_size);
   1068		return -EINVAL;
   1069	}
   1070
   1071	snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
   1072
   1073	return 0;
   1074}
   1075
   1076int hinic_get_link_mode(struct hinic_hwdev *hwdev,
   1077			struct hinic_link_mode_cmd *link_mode)
   1078{
   1079	u16 out_size;
   1080	int err;
   1081
   1082	if (!hwdev || !link_mode)
   1083		return -EINVAL;
   1084
   1085	link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1086	out_size = sizeof(*link_mode);
   1087
   1088	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
   1089				 link_mode, sizeof(*link_mode),
   1090				 link_mode, &out_size);
   1091	if (err || !out_size || link_mode->status) {
   1092		dev_err(&hwdev->hwif->pdev->dev,
   1093			"Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n",
   1094			err, link_mode->status, out_size);
   1095		return -EIO;
   1096	}
   1097
   1098	return 0;
   1099}
   1100
   1101int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable)
   1102{
   1103	struct hinic_set_autoneg_cmd autoneg = {0};
   1104	u16 out_size = sizeof(autoneg);
   1105	int err;
   1106
   1107	if (!hwdev)
   1108		return -EINVAL;
   1109
   1110	autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1111	autoneg.enable = enable;
   1112
   1113	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG,
   1114				 &autoneg, sizeof(autoneg),
   1115				 &autoneg, &out_size);
   1116	if (err || !out_size || autoneg.status) {
   1117		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n",
   1118			enable ? "enable" : "disable", err, autoneg.status,
   1119			out_size);
   1120		return -EIO;
   1121	}
   1122
   1123	return 0;
   1124}
   1125
   1126int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed)
   1127{
   1128	struct hinic_speed_cmd speed_info = {0};
   1129	u16 out_size = sizeof(speed_info);
   1130	int err;
   1131
   1132	if (!hwdev)
   1133		return -EINVAL;
   1134
   1135	speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1136	speed_info.speed = speed;
   1137
   1138	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_SPEED,
   1139				 &speed_info, sizeof(speed_info),
   1140				 &speed_info, &out_size);
   1141	if (err || !out_size || speed_info.status) {
   1142		dev_err(&hwdev->hwif->pdev->dev,
   1143			"Failed to set speed, err: %d, status: 0x%x, out size: 0x%x\n",
   1144			err, speed_info.status, out_size);
   1145		return -EIO;
   1146	}
   1147
   1148	return 0;
   1149}
   1150
   1151int hinic_set_link_settings(struct hinic_hwdev *hwdev,
   1152			    struct hinic_link_ksettings_info *info)
   1153{
   1154	u16 out_size = sizeof(*info);
   1155	int err;
   1156
   1157	err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS,
   1158				   info, sizeof(*info), info, &out_size);
   1159	if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED &&
   1160	     info->status) || err || !out_size) {
   1161		dev_err(&hwdev->hwif->pdev->dev,
   1162			"Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
   1163			err, info->status, out_size);
   1164		return -EFAULT;
   1165	}
   1166
   1167	return info->status;
   1168}
   1169
   1170int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
   1171			    struct hinic_pause_config *pause_info)
   1172{
   1173	u16 out_size = sizeof(*pause_info);
   1174	int err;
   1175
   1176	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1177
   1178	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
   1179				 pause_info, sizeof(*pause_info),
   1180				 pause_info, &out_size);
   1181	if (err || !out_size || pause_info->status) {
   1182		dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
   1183			err, pause_info->status, out_size);
   1184		return -EIO;
   1185	}
   1186
   1187	return 0;
   1188}
   1189
   1190int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
   1191			    struct hinic_pause_config *pause_info)
   1192{
   1193	u16 out_size = sizeof(*pause_info);
   1194	int err;
   1195
   1196	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1197
   1198	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
   1199				 pause_info, sizeof(*pause_info),
   1200				 pause_info, &out_size);
   1201	if (err || !out_size || pause_info->status) {
   1202		dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n",
   1203			err, pause_info->status, out_size);
   1204		return -EIO;
   1205	}
   1206
   1207	return 0;
   1208}
   1209
   1210int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
   1211{
   1212	struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg;
   1213	struct hinic_set_pfc pfc = {0};
   1214	u16 out_size = sizeof(pfc);
   1215	int err;
   1216
   1217	if (HINIC_IS_VF(hwdev->hwif))
   1218		return 0;
   1219
   1220	mutex_lock(&nic_cfg->cfg_mutex);
   1221
   1222	pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
   1223	pfc.pfc_bitmap = pfc_bitmap;
   1224	pfc.pfc_en = pfc_en;
   1225
   1226	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC,
   1227				 &pfc, sizeof(pfc), &pfc, &out_size);
   1228	if (err || pfc.status || !out_size) {
   1229		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n",
   1230			pfc_en ? "enable" : "disable", err, pfc.status,
   1231			out_size);
   1232		mutex_unlock(&nic_cfg->cfg_mutex);
   1233		return -EIO;
   1234	}
   1235
   1236	/* pause settings is opposite from pfc */
   1237	nic_cfg->rx_pause = pfc_en ? 0 : 1;
   1238	nic_cfg->tx_pause = pfc_en ? 0 : 1;
   1239
   1240	mutex_unlock(&nic_cfg->cfg_mutex);
   1241
   1242	return 0;
   1243}
   1244
   1245int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
   1246{
   1247	struct hinic_port_loopback lb = {0};
   1248	u16 out_size = sizeof(lb);
   1249	int err;
   1250
   1251	lb.mode = mode;
   1252	lb.en = enable;
   1253
   1254	if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
   1255		dev_err(&hwdev->hwif->pdev->dev,
   1256			"Invalid loopback mode %d to set\n", mode);
   1257		return -EINVAL;
   1258	}
   1259
   1260	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE,
   1261				 &lb, sizeof(lb), &lb, &out_size);
   1262	if (err || !out_size || lb.status) {
   1263		dev_err(&hwdev->hwif->pdev->dev,
   1264			"Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n",
   1265			mode, enable, err, lb.status, out_size);
   1266		return -EIO;
   1267	}
   1268
   1269	return 0;
   1270}
   1271
   1272static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
   1273			   enum hinic_led_type type,
   1274			   enum hinic_led_mode mode, u8 reset)
   1275{
   1276	struct hinic_led_info led_info = {0};
   1277	u16 out_size = sizeof(led_info);
   1278	struct hinic_pfhwdev *pfhwdev;
   1279	int err;
   1280
   1281	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
   1282
   1283	led_info.port = port;
   1284	led_info.reset = reset;
   1285
   1286	led_info.type = type;
   1287	led_info.mode = mode;
   1288
   1289	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
   1290				HINIC_COMM_CMD_SET_LED_STATUS,
   1291				&led_info, sizeof(led_info),
   1292				&led_info, &out_size, HINIC_MGMT_MSG_SYNC);
   1293	if (err || led_info.status || !out_size) {
   1294		dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
   1295			err, led_info.status, out_size);
   1296		return -EIO;
   1297	}
   1298
   1299	return 0;
   1300}
   1301
   1302int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
   1303			 enum hinic_led_type type, enum hinic_led_mode mode)
   1304{
   1305	if (!hwdev)
   1306		return -EINVAL;
   1307
   1308	return _set_led_status(hwdev, port, type, mode, 0);
   1309}
   1310
   1311int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
   1312{
   1313	int err;
   1314
   1315	if (!hwdev)
   1316		return -EINVAL;
   1317
   1318	err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
   1319			      HINIC_LED_MODE_INVALID, 1);
   1320	if (err)
   1321		dev_err(&hwdev->hwif->pdev->dev,
   1322			"Failed to reset led status\n");
   1323
   1324	return err;
   1325}
   1326
   1327static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
   1328{
   1329	struct hinic_cmd_get_light_module_abs sfp_abs = {0};
   1330	u16 out_size = sizeof(sfp_abs);
   1331	u8 port_id = hwdev->port_id;
   1332	int err;
   1333
   1334	sfp_abs.port_id = port_id;
   1335	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
   1336				 &sfp_abs, sizeof(sfp_abs), &sfp_abs,
   1337				 &out_size);
   1338	if (sfp_abs.status || err || !out_size) {
   1339		dev_err(&hwdev->hwif->pdev->dev,
   1340			"Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
   1341			port_id, err, sfp_abs.status, out_size);
   1342		return true;
   1343	}
   1344
   1345	return ((sfp_abs.abs_status == 0) ? false : true);
   1346}
   1347
   1348int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
   1349{
   1350	struct hinic_cmd_get_std_sfp_info sfp_info = {0};
   1351	u16 out_size = sizeof(sfp_info);
   1352	u8 port_id;
   1353	int err;
   1354
   1355	if (!hwdev || !data || !len)
   1356		return -EINVAL;
   1357
   1358	port_id = hwdev->port_id;
   1359
   1360	if (hinic_if_sfp_absent(hwdev))
   1361		return -ENXIO;
   1362
   1363	sfp_info.port_id = port_id;
   1364	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
   1365				 &sfp_info, sizeof(sfp_info), &sfp_info,
   1366				 &out_size);
   1367	if (sfp_info.status || err || !out_size) {
   1368		dev_err(&hwdev->hwif->pdev->dev,
   1369			"Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
   1370			port_id, err, sfp_info.status, out_size);
   1371		return -EIO;
   1372	}
   1373
   1374	*len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
   1375	memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);
   1376
   1377	return 0;
   1378}
   1379
   1380int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
   1381{
   1382	u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
   1383	u16 len;
   1384	int err;
   1385
   1386	if (hinic_if_sfp_absent(hwdev))
   1387		return -ENXIO;
   1388
   1389	err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
   1390	if (err)
   1391		return err;
   1392
   1393	*data0 = sfp_data[0];
   1394	*data1 = sfp_data[1];
   1395
   1396	return 0;
   1397}