162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * QLogic qlcnic NIC Driver
462306a36Sopenharmony_ci * Copyright (c) 2009-2013 QLogic Corporation
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/slab.h>
862306a36Sopenharmony_ci#include <linux/interrupt.h>
962306a36Sopenharmony_ci#include <linux/swab.h>
1062306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1162306a36Sopenharmony_ci#include <net/ip.h>
1262306a36Sopenharmony_ci#include <linux/ipv6.h>
1362306a36Sopenharmony_ci#include <linux/inetdevice.h>
1462306a36Sopenharmony_ci#include <linux/sysfs.h>
1562306a36Sopenharmony_ci#include <linux/log2.h>
1662306a36Sopenharmony_ci#ifdef CONFIG_QLCNIC_HWMON
1762306a36Sopenharmony_ci#include <linux/hwmon.h>
1862306a36Sopenharmony_ci#include <linux/hwmon-sysfs.h>
1962306a36Sopenharmony_ci#endif
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include "qlcnic.h"
2262306a36Sopenharmony_ci#include "qlcnic_hw.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciint qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	return -EOPNOTSUPP;
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciint qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	return -EOPNOTSUPP;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic ssize_t qlcnic_store_bridged_mode(struct device *dev,
3562306a36Sopenharmony_ci					 struct device_attribute *attr,
3662306a36Sopenharmony_ci					 const char *buf, size_t len)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
3962306a36Sopenharmony_ci	unsigned long new;
4062306a36Sopenharmony_ci	int ret = -EINVAL;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
4362306a36Sopenharmony_ci		goto err_out;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
4662306a36Sopenharmony_ci		goto err_out;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	if (kstrtoul(buf, 2, &new))
4962306a36Sopenharmony_ci		goto err_out;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	if (!qlcnic_config_bridged_mode(adapter, !!new))
5262306a36Sopenharmony_ci		ret = len;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cierr_out:
5562306a36Sopenharmony_ci	return ret;
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic ssize_t qlcnic_show_bridged_mode(struct device *dev,
5962306a36Sopenharmony_ci					struct device_attribute *attr,
6062306a36Sopenharmony_ci					char *buf)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
6362306a36Sopenharmony_ci	int bridged_mode = 0;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
6662306a36Sopenharmony_ci		bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	return sprintf(buf, "%d\n", bridged_mode);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic ssize_t qlcnic_store_diag_mode(struct device *dev,
7262306a36Sopenharmony_ci				      struct device_attribute *attr,
7362306a36Sopenharmony_ci				      const char *buf, size_t len)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
7662306a36Sopenharmony_ci	unsigned long new;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (kstrtoul(buf, 2, &new))
7962306a36Sopenharmony_ci		return -EINVAL;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
8262306a36Sopenharmony_ci		adapter->flags ^= QLCNIC_DIAG_ENABLED;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	return len;
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic ssize_t qlcnic_show_diag_mode(struct device *dev,
8862306a36Sopenharmony_ci				     struct device_attribute *attr, char *buf)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
9162306a36Sopenharmony_ci	return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistatic int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
9562306a36Sopenharmony_ci				  u8 *state, u8 *rate)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	*rate = LSB(beacon);
9862306a36Sopenharmony_ci	*state = MSB(beacon);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	if (!*state) {
10362306a36Sopenharmony_ci		*rate = __QLCNIC_MAX_LED_RATE;
10462306a36Sopenharmony_ci		return 0;
10562306a36Sopenharmony_ci	} else if (*state > __QLCNIC_MAX_LED_STATE) {
10662306a36Sopenharmony_ci		return -EINVAL;
10762306a36Sopenharmony_ci	}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
11062306a36Sopenharmony_ci		return -EINVAL;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	return 0;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter,
11662306a36Sopenharmony_ci				    const char *buf, size_t len)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	struct qlcnic_hardware_context *ahw = adapter->ahw;
11962306a36Sopenharmony_ci	unsigned long h_beacon;
12062306a36Sopenharmony_ci	int err;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
12362306a36Sopenharmony_ci		return -EIO;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	if (kstrtoul(buf, 2, &h_beacon))
12662306a36Sopenharmony_ci		return -EINVAL;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	qlcnic_get_beacon_state(adapter);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	if (ahw->beacon_state == h_beacon)
13162306a36Sopenharmony_ci		return len;
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	rtnl_lock();
13462306a36Sopenharmony_ci	if (!ahw->beacon_state) {
13562306a36Sopenharmony_ci		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
13662306a36Sopenharmony_ci			rtnl_unlock();
13762306a36Sopenharmony_ci			return -EBUSY;
13862306a36Sopenharmony_ci		}
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	if (h_beacon)
14262306a36Sopenharmony_ci		err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
14362306a36Sopenharmony_ci	else
14462306a36Sopenharmony_ci		err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
14562306a36Sopenharmony_ci	if (!err)
14662306a36Sopenharmony_ci		ahw->beacon_state = h_beacon;
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	if (!ahw->beacon_state)
14962306a36Sopenharmony_ci		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	rtnl_unlock();
15262306a36Sopenharmony_ci	return len;
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
15662306a36Sopenharmony_ci				    const char *buf, size_t len)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	struct qlcnic_hardware_context *ahw = adapter->ahw;
15962306a36Sopenharmony_ci	int err, drv_sds_rings = adapter->drv_sds_rings;
16062306a36Sopenharmony_ci	u16 beacon;
16162306a36Sopenharmony_ci	u8 b_state, b_rate;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	if (len != sizeof(u16))
16462306a36Sopenharmony_ci		return -EINVAL;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	memcpy(&beacon, buf, sizeof(u16));
16762306a36Sopenharmony_ci	err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
16862306a36Sopenharmony_ci	if (err)
16962306a36Sopenharmony_ci		return err;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	qlcnic_get_beacon_state(adapter);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	if (ahw->beacon_state == b_state)
17462306a36Sopenharmony_ci		return len;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	rtnl_lock();
17762306a36Sopenharmony_ci	if (!ahw->beacon_state) {
17862306a36Sopenharmony_ci		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
17962306a36Sopenharmony_ci			rtnl_unlock();
18062306a36Sopenharmony_ci			return -EBUSY;
18162306a36Sopenharmony_ci		}
18262306a36Sopenharmony_ci	}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
18562306a36Sopenharmony_ci		err = -EIO;
18662306a36Sopenharmony_ci		goto out;
18762306a36Sopenharmony_ci	}
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
19062306a36Sopenharmony_ci		err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
19162306a36Sopenharmony_ci		if (err)
19262306a36Sopenharmony_ci			goto out;
19362306a36Sopenharmony_ci		set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	err = qlcnic_config_led(adapter, b_state, b_rate);
19762306a36Sopenharmony_ci	if (!err) {
19862306a36Sopenharmony_ci		err = len;
19962306a36Sopenharmony_ci		ahw->beacon_state = b_state;
20062306a36Sopenharmony_ci	}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
20362306a36Sopenharmony_ci		qlcnic_diag_free_res(adapter->netdev, drv_sds_rings);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciout:
20662306a36Sopenharmony_ci	if (!ahw->beacon_state)
20762306a36Sopenharmony_ci		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
20862306a36Sopenharmony_ci	rtnl_unlock();
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	return err;
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic ssize_t qlcnic_store_beacon(struct device *dev,
21462306a36Sopenharmony_ci				   struct device_attribute *attr,
21562306a36Sopenharmony_ci				   const char *buf, size_t len)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
21862306a36Sopenharmony_ci	int err = 0;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
22162306a36Sopenharmony_ci		dev_warn(dev,
22262306a36Sopenharmony_ci			 "LED test not supported in non privileged mode\n");
22362306a36Sopenharmony_ci		return -EOPNOTSUPP;
22462306a36Sopenharmony_ci	}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	if (qlcnic_82xx_check(adapter))
22762306a36Sopenharmony_ci		err = qlcnic_82xx_store_beacon(adapter, buf, len);
22862306a36Sopenharmony_ci	else if (qlcnic_83xx_check(adapter))
22962306a36Sopenharmony_ci		err = qlcnic_83xx_store_beacon(adapter, buf, len);
23062306a36Sopenharmony_ci	else
23162306a36Sopenharmony_ci		return -EIO;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	return err;
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic ssize_t qlcnic_show_beacon(struct device *dev,
23762306a36Sopenharmony_ci				  struct device_attribute *attr, char *buf)
23862306a36Sopenharmony_ci{
23962306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci	return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
24262306a36Sopenharmony_ci}
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistatic int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
24562306a36Sopenharmony_ci				     loff_t offset, size_t size)
24662306a36Sopenharmony_ci{
24762306a36Sopenharmony_ci	size_t crb_size = 4;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
25062306a36Sopenharmony_ci		return -EIO;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	if (offset < QLCNIC_PCI_CRBSPACE) {
25362306a36Sopenharmony_ci		if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
25462306a36Sopenharmony_ci				  QLCNIC_PCI_CAMQM_END))
25562306a36Sopenharmony_ci			crb_size = 8;
25662306a36Sopenharmony_ci		else
25762306a36Sopenharmony_ci			return -EINVAL;
25862306a36Sopenharmony_ci	}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	if ((size != crb_size) || (offset & (crb_size-1)))
26162306a36Sopenharmony_ci		return  -EINVAL;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	return 0;
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
26762306a36Sopenharmony_ci				     struct bin_attribute *attr, char *buf,
26862306a36Sopenharmony_ci				     loff_t offset, size_t size)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
27162306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
27262306a36Sopenharmony_ci	int ret;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
27562306a36Sopenharmony_ci	if (ret != 0)
27662306a36Sopenharmony_ci		return ret;
27762306a36Sopenharmony_ci	qlcnic_read_crb(adapter, buf, offset, size);
27862306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	return size;
28162306a36Sopenharmony_ci}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
28462306a36Sopenharmony_ci				      struct bin_attribute *attr, char *buf,
28562306a36Sopenharmony_ci				      loff_t offset, size_t size)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
28862306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
28962306a36Sopenharmony_ci	int ret;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
29262306a36Sopenharmony_ci	if (ret != 0)
29362306a36Sopenharmony_ci		return ret;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
29662306a36Sopenharmony_ci	qlcnic_write_crb(adapter, buf, offset, size);
29762306a36Sopenharmony_ci	return size;
29862306a36Sopenharmony_ci}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
30162306a36Sopenharmony_ci				     loff_t offset, size_t size)
30262306a36Sopenharmony_ci{
30362306a36Sopenharmony_ci	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
30462306a36Sopenharmony_ci		return -EIO;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	if ((size != 8) || (offset & 0x7))
30762306a36Sopenharmony_ci		return  -EIO;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	return 0;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
31362306a36Sopenharmony_ci				     struct bin_attribute *attr, char *buf,
31462306a36Sopenharmony_ci				     loff_t offset, size_t size)
31562306a36Sopenharmony_ci{
31662306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
31762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
31862306a36Sopenharmony_ci	u64 data;
31962306a36Sopenharmony_ci	int ret;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
32262306a36Sopenharmony_ci	if (ret != 0)
32362306a36Sopenharmony_ci		return ret;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
32662306a36Sopenharmony_ci		return -EIO;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	memcpy(buf, &data, size);
32962306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	return size;
33262306a36Sopenharmony_ci}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
33562306a36Sopenharmony_ci				      struct bin_attribute *attr, char *buf,
33662306a36Sopenharmony_ci				      loff_t offset, size_t size)
33762306a36Sopenharmony_ci{
33862306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
33962306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
34062306a36Sopenharmony_ci	u64 data;
34162306a36Sopenharmony_ci	int ret;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
34462306a36Sopenharmony_ci	if (ret != 0)
34562306a36Sopenharmony_ci		return ret;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
34862306a36Sopenharmony_ci	memcpy(&data, buf, size);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	if (qlcnic_pci_mem_write_2M(adapter, offset, data))
35162306a36Sopenharmony_ci		return -EIO;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	return size;
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ciint qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	int i;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
36162306a36Sopenharmony_ci		if (adapter->npars[i].pci_func == pci_func)
36262306a36Sopenharmony_ci			return i;
36362306a36Sopenharmony_ci	}
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__);
36662306a36Sopenharmony_ci	return -EINVAL;
36762306a36Sopenharmony_ci}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_cistatic int validate_pm_config(struct qlcnic_adapter *adapter,
37062306a36Sopenharmony_ci			      struct qlcnic_pm_func_cfg *pm_cfg, int count)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	u8 src_pci_func, s_esw_id, d_esw_id;
37362306a36Sopenharmony_ci	u8 dest_pci_func;
37462306a36Sopenharmony_ci	int i, src_index, dest_index;
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
37762306a36Sopenharmony_ci		src_pci_func = pm_cfg[i].pci_func;
37862306a36Sopenharmony_ci		dest_pci_func = pm_cfg[i].dest_npar;
37962306a36Sopenharmony_ci		src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
38062306a36Sopenharmony_ci		if (src_index < 0)
38162306a36Sopenharmony_ci			return -EINVAL;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci		dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
38462306a36Sopenharmony_ci		if (dest_index < 0)
38562306a36Sopenharmony_ci			return -EINVAL;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci		s_esw_id = adapter->npars[src_index].phy_port;
38862306a36Sopenharmony_ci		d_esw_id = adapter->npars[dest_index].phy_port;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci		if (s_esw_id != d_esw_id)
39162306a36Sopenharmony_ci			return -EINVAL;
39262306a36Sopenharmony_ci	}
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	return 0;
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
39862306a36Sopenharmony_ci					    struct kobject *kobj,
39962306a36Sopenharmony_ci					    struct bin_attribute *attr,
40062306a36Sopenharmony_ci					    char *buf, loff_t offset,
40162306a36Sopenharmony_ci					    size_t size)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
40462306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
40562306a36Sopenharmony_ci	struct qlcnic_pm_func_cfg *pm_cfg;
40662306a36Sopenharmony_ci	u32 id, action, pci_func;
40762306a36Sopenharmony_ci	int count, rem, i, ret, index;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	count	= size / sizeof(struct qlcnic_pm_func_cfg);
41062306a36Sopenharmony_ci	rem	= size % sizeof(struct qlcnic_pm_func_cfg);
41162306a36Sopenharmony_ci	if (rem)
41262306a36Sopenharmony_ci		return -EINVAL;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
41562306a36Sopenharmony_ci	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
41662306a36Sopenharmony_ci	ret = validate_pm_config(adapter, pm_cfg, count);
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	if (ret)
41962306a36Sopenharmony_ci		return ret;
42062306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
42162306a36Sopenharmony_ci		pci_func = pm_cfg[i].pci_func;
42262306a36Sopenharmony_ci		action = !!pm_cfg[i].action;
42362306a36Sopenharmony_ci		index = qlcnic_is_valid_nic_func(adapter, pci_func);
42462306a36Sopenharmony_ci		if (index < 0)
42562306a36Sopenharmony_ci			return -EINVAL;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci		id = adapter->npars[index].phy_port;
42862306a36Sopenharmony_ci		ret = qlcnic_config_port_mirroring(adapter, id,
42962306a36Sopenharmony_ci						   action, pci_func);
43062306a36Sopenharmony_ci		if (ret)
43162306a36Sopenharmony_ci			return ret;
43262306a36Sopenharmony_ci	}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
43562306a36Sopenharmony_ci		pci_func = pm_cfg[i].pci_func;
43662306a36Sopenharmony_ci		index = qlcnic_is_valid_nic_func(adapter, pci_func);
43762306a36Sopenharmony_ci		if (index < 0)
43862306a36Sopenharmony_ci			return -EINVAL;
43962306a36Sopenharmony_ci		id = adapter->npars[index].phy_port;
44062306a36Sopenharmony_ci		adapter->npars[index].enable_pm = !!pm_cfg[i].action;
44162306a36Sopenharmony_ci		adapter->npars[index].dest_npar = id;
44262306a36Sopenharmony_ci	}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	return size;
44562306a36Sopenharmony_ci}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
44862306a36Sopenharmony_ci					   struct kobject *kobj,
44962306a36Sopenharmony_ci					   struct bin_attribute *attr,
45062306a36Sopenharmony_ci					   char *buf, loff_t offset,
45162306a36Sopenharmony_ci					   size_t size)
45262306a36Sopenharmony_ci{
45362306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
45462306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
45562306a36Sopenharmony_ci	struct qlcnic_pm_func_cfg *pm_cfg;
45662306a36Sopenharmony_ci	u8 pci_func;
45762306a36Sopenharmony_ci	u32 count;
45862306a36Sopenharmony_ci	int i;
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	memset(buf, 0, size);
46162306a36Sopenharmony_ci	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
46262306a36Sopenharmony_ci	count = size / sizeof(struct qlcnic_pm_func_cfg);
46362306a36Sopenharmony_ci	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
46462306a36Sopenharmony_ci		pci_func = adapter->npars[i].pci_func;
46562306a36Sopenharmony_ci		if (pci_func >= count) {
46662306a36Sopenharmony_ci			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
46762306a36Sopenharmony_ci				__func__, adapter->ahw->total_nic_func, count);
46862306a36Sopenharmony_ci			continue;
46962306a36Sopenharmony_ci		}
47062306a36Sopenharmony_ci		if (!adapter->npars[i].eswitch_status)
47162306a36Sopenharmony_ci			continue;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci		pm_cfg[pci_func].action = adapter->npars[i].enable_pm;
47462306a36Sopenharmony_ci		pm_cfg[pci_func].dest_npar = 0;
47562306a36Sopenharmony_ci		pm_cfg[pci_func].pci_func = i;
47662306a36Sopenharmony_ci	}
47762306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
47862306a36Sopenharmony_ci	return size;
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_cistatic int validate_esw_config(struct qlcnic_adapter *adapter,
48262306a36Sopenharmony_ci			       struct qlcnic_esw_func_cfg *esw_cfg, int count)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	struct qlcnic_hardware_context *ahw = adapter->ahw;
48562306a36Sopenharmony_ci	int i, ret;
48662306a36Sopenharmony_ci	u32 op_mode;
48762306a36Sopenharmony_ci	u8 pci_func;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	if (qlcnic_82xx_check(adapter))
49062306a36Sopenharmony_ci		op_mode = readl(ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
49162306a36Sopenharmony_ci	else
49262306a36Sopenharmony_ci		op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE);
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
49562306a36Sopenharmony_ci		pci_func = esw_cfg[i].pci_func;
49662306a36Sopenharmony_ci		if (pci_func >= ahw->max_vnic_func)
49762306a36Sopenharmony_ci			return -EINVAL;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
50062306a36Sopenharmony_ci			if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
50162306a36Sopenharmony_ci				return -EINVAL;
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci		switch (esw_cfg[i].op_mode) {
50462306a36Sopenharmony_ci		case QLCNIC_PORT_DEFAULTS:
50562306a36Sopenharmony_ci			if (qlcnic_82xx_check(adapter)) {
50662306a36Sopenharmony_ci				ret = QLC_DEV_GET_DRV(op_mode, pci_func);
50762306a36Sopenharmony_ci			} else {
50862306a36Sopenharmony_ci				ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
50962306a36Sopenharmony_ci								  pci_func);
51062306a36Sopenharmony_ci				esw_cfg[i].offload_flags = 0;
51162306a36Sopenharmony_ci			}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci			if (ret != QLCNIC_NON_PRIV_FUNC) {
51462306a36Sopenharmony_ci				if (esw_cfg[i].mac_anti_spoof != 0)
51562306a36Sopenharmony_ci					return -EINVAL;
51662306a36Sopenharmony_ci				if (esw_cfg[i].mac_override != 1)
51762306a36Sopenharmony_ci					return -EINVAL;
51862306a36Sopenharmony_ci				if (esw_cfg[i].promisc_mode != 1)
51962306a36Sopenharmony_ci					return -EINVAL;
52062306a36Sopenharmony_ci			}
52162306a36Sopenharmony_ci			break;
52262306a36Sopenharmony_ci		case QLCNIC_ADD_VLAN:
52362306a36Sopenharmony_ci			if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
52462306a36Sopenharmony_ci				return -EINVAL;
52562306a36Sopenharmony_ci			if (!esw_cfg[i].op_type)
52662306a36Sopenharmony_ci				return -EINVAL;
52762306a36Sopenharmony_ci			break;
52862306a36Sopenharmony_ci		case QLCNIC_DEL_VLAN:
52962306a36Sopenharmony_ci			if (!esw_cfg[i].op_type)
53062306a36Sopenharmony_ci				return -EINVAL;
53162306a36Sopenharmony_ci			break;
53262306a36Sopenharmony_ci		default:
53362306a36Sopenharmony_ci			return -EINVAL;
53462306a36Sopenharmony_ci		}
53562306a36Sopenharmony_ci	}
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	return 0;
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
54162306a36Sopenharmony_ci					     struct kobject *kobj,
54262306a36Sopenharmony_ci					     struct bin_attribute *attr,
54362306a36Sopenharmony_ci					     char *buf, loff_t offset,
54462306a36Sopenharmony_ci					     size_t size)
54562306a36Sopenharmony_ci{
54662306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
54762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
54862306a36Sopenharmony_ci	struct qlcnic_esw_func_cfg *esw_cfg;
54962306a36Sopenharmony_ci	struct qlcnic_npar_info *npar;
55062306a36Sopenharmony_ci	int count, rem, i, ret;
55162306a36Sopenharmony_ci	int index;
55262306a36Sopenharmony_ci	u8 op_mode = 0, pci_func;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	count	= size / sizeof(struct qlcnic_esw_func_cfg);
55562306a36Sopenharmony_ci	rem	= size % sizeof(struct qlcnic_esw_func_cfg);
55662306a36Sopenharmony_ci	if (rem)
55762306a36Sopenharmony_ci		return -EINVAL;
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
56062306a36Sopenharmony_ci	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
56162306a36Sopenharmony_ci	ret = validate_esw_config(adapter, esw_cfg, count);
56262306a36Sopenharmony_ci	if (ret)
56362306a36Sopenharmony_ci		return ret;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
56662306a36Sopenharmony_ci		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
56762306a36Sopenharmony_ci			if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
56862306a36Sopenharmony_ci				return -EINVAL;
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci		if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
57162306a36Sopenharmony_ci			continue;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci		op_mode = esw_cfg[i].op_mode;
57462306a36Sopenharmony_ci		qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
57562306a36Sopenharmony_ci		esw_cfg[i].op_mode = op_mode;
57662306a36Sopenharmony_ci		esw_cfg[i].pci_func = adapter->ahw->pci_func;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci		switch (esw_cfg[i].op_mode) {
57962306a36Sopenharmony_ci		case QLCNIC_PORT_DEFAULTS:
58062306a36Sopenharmony_ci			qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
58162306a36Sopenharmony_ci			rtnl_lock();
58262306a36Sopenharmony_ci			qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
58362306a36Sopenharmony_ci			rtnl_unlock();
58462306a36Sopenharmony_ci			break;
58562306a36Sopenharmony_ci		case QLCNIC_ADD_VLAN:
58662306a36Sopenharmony_ci			qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
58762306a36Sopenharmony_ci			break;
58862306a36Sopenharmony_ci		case QLCNIC_DEL_VLAN:
58962306a36Sopenharmony_ci			esw_cfg[i].vlan_id = 0;
59062306a36Sopenharmony_ci			qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
59162306a36Sopenharmony_ci			break;
59262306a36Sopenharmony_ci		}
59362306a36Sopenharmony_ci	}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
59662306a36Sopenharmony_ci		goto out;
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
59962306a36Sopenharmony_ci		pci_func = esw_cfg[i].pci_func;
60062306a36Sopenharmony_ci		index = qlcnic_is_valid_nic_func(adapter, pci_func);
60162306a36Sopenharmony_ci		if (index < 0)
60262306a36Sopenharmony_ci			return -EINVAL;
60362306a36Sopenharmony_ci		npar = &adapter->npars[index];
60462306a36Sopenharmony_ci		switch (esw_cfg[i].op_mode) {
60562306a36Sopenharmony_ci		case QLCNIC_PORT_DEFAULTS:
60662306a36Sopenharmony_ci			npar->promisc_mode = esw_cfg[i].promisc_mode;
60762306a36Sopenharmony_ci			npar->mac_override = esw_cfg[i].mac_override;
60862306a36Sopenharmony_ci			npar->offload_flags = esw_cfg[i].offload_flags;
60962306a36Sopenharmony_ci			npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
61062306a36Sopenharmony_ci			npar->discard_tagged = esw_cfg[i].discard_tagged;
61162306a36Sopenharmony_ci			break;
61262306a36Sopenharmony_ci		case QLCNIC_ADD_VLAN:
61362306a36Sopenharmony_ci			npar->pvid = esw_cfg[i].vlan_id;
61462306a36Sopenharmony_ci			break;
61562306a36Sopenharmony_ci		case QLCNIC_DEL_VLAN:
61662306a36Sopenharmony_ci			npar->pvid = 0;
61762306a36Sopenharmony_ci			break;
61862306a36Sopenharmony_ci		}
61962306a36Sopenharmony_ci	}
62062306a36Sopenharmony_ciout:
62162306a36Sopenharmony_ci	return size;
62262306a36Sopenharmony_ci}
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
62562306a36Sopenharmony_ci					    struct kobject *kobj,
62662306a36Sopenharmony_ci					    struct bin_attribute *attr,
62762306a36Sopenharmony_ci					    char *buf, loff_t offset,
62862306a36Sopenharmony_ci					    size_t size)
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
63162306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
63262306a36Sopenharmony_ci	struct qlcnic_esw_func_cfg *esw_cfg;
63362306a36Sopenharmony_ci	u8 pci_func;
63462306a36Sopenharmony_ci	u32 count;
63562306a36Sopenharmony_ci	int i;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	memset(buf, 0, size);
63862306a36Sopenharmony_ci	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
63962306a36Sopenharmony_ci	count = size / sizeof(struct qlcnic_esw_func_cfg);
64062306a36Sopenharmony_ci	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
64162306a36Sopenharmony_ci		pci_func = adapter->npars[i].pci_func;
64262306a36Sopenharmony_ci		if (pci_func >= count) {
64362306a36Sopenharmony_ci			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
64462306a36Sopenharmony_ci				__func__, adapter->ahw->total_nic_func, count);
64562306a36Sopenharmony_ci			continue;
64662306a36Sopenharmony_ci		}
64762306a36Sopenharmony_ci		if (!adapter->npars[i].eswitch_status)
64862306a36Sopenharmony_ci			continue;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci		esw_cfg[pci_func].pci_func = pci_func;
65162306a36Sopenharmony_ci		if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
65262306a36Sopenharmony_ci			return -EINVAL;
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
65562306a36Sopenharmony_ci	return size;
65662306a36Sopenharmony_ci}
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_cistatic int validate_npar_config(struct qlcnic_adapter *adapter,
65962306a36Sopenharmony_ci				struct qlcnic_npar_func_cfg *np_cfg,
66062306a36Sopenharmony_ci				int count)
66162306a36Sopenharmony_ci{
66262306a36Sopenharmony_ci	u8 pci_func, i;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
66562306a36Sopenharmony_ci		pci_func = np_cfg[i].pci_func;
66662306a36Sopenharmony_ci		if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
66762306a36Sopenharmony_ci			return -EINVAL;
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci		if (!IS_VALID_BW(np_cfg[i].min_bw) ||
67062306a36Sopenharmony_ci		    !IS_VALID_BW(np_cfg[i].max_bw))
67162306a36Sopenharmony_ci			return -EINVAL;
67262306a36Sopenharmony_ci	}
67362306a36Sopenharmony_ci	return 0;
67462306a36Sopenharmony_ci}
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
67762306a36Sopenharmony_ci					      struct kobject *kobj,
67862306a36Sopenharmony_ci					      struct bin_attribute *attr,
67962306a36Sopenharmony_ci					      char *buf, loff_t offset,
68062306a36Sopenharmony_ci					      size_t size)
68162306a36Sopenharmony_ci{
68262306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
68362306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
68462306a36Sopenharmony_ci	struct qlcnic_info nic_info;
68562306a36Sopenharmony_ci	struct qlcnic_npar_func_cfg *np_cfg;
68662306a36Sopenharmony_ci	int i, count, rem, ret, index;
68762306a36Sopenharmony_ci	u8 pci_func;
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci	count	= size / sizeof(struct qlcnic_npar_func_cfg);
69062306a36Sopenharmony_ci	rem	= size % sizeof(struct qlcnic_npar_func_cfg);
69162306a36Sopenharmony_ci	if (rem)
69262306a36Sopenharmony_ci		return -EINVAL;
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
69562306a36Sopenharmony_ci	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
69662306a36Sopenharmony_ci	ret = validate_npar_config(adapter, np_cfg, count);
69762306a36Sopenharmony_ci	if (ret)
69862306a36Sopenharmony_ci		return ret;
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
70162306a36Sopenharmony_ci		pci_func = np_cfg[i].pci_func;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci		memset(&nic_info, 0, sizeof(struct qlcnic_info));
70462306a36Sopenharmony_ci		ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
70562306a36Sopenharmony_ci		if (ret)
70662306a36Sopenharmony_ci			return ret;
70762306a36Sopenharmony_ci		nic_info.pci_func = pci_func;
70862306a36Sopenharmony_ci		nic_info.min_tx_bw = np_cfg[i].min_bw;
70962306a36Sopenharmony_ci		nic_info.max_tx_bw = np_cfg[i].max_bw;
71062306a36Sopenharmony_ci		ret = qlcnic_set_nic_info(adapter, &nic_info);
71162306a36Sopenharmony_ci		if (ret)
71262306a36Sopenharmony_ci			return ret;
71362306a36Sopenharmony_ci		index = qlcnic_is_valid_nic_func(adapter, pci_func);
71462306a36Sopenharmony_ci		if (index < 0)
71562306a36Sopenharmony_ci			return -EINVAL;
71662306a36Sopenharmony_ci		adapter->npars[index].min_bw = nic_info.min_tx_bw;
71762306a36Sopenharmony_ci		adapter->npars[index].max_bw = nic_info.max_tx_bw;
71862306a36Sopenharmony_ci	}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	return size;
72162306a36Sopenharmony_ci}
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
72462306a36Sopenharmony_ci					     struct kobject *kobj,
72562306a36Sopenharmony_ci					     struct bin_attribute *attr,
72662306a36Sopenharmony_ci					     char *buf, loff_t offset,
72762306a36Sopenharmony_ci					     size_t size)
72862306a36Sopenharmony_ci{
72962306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
73062306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
73162306a36Sopenharmony_ci	struct qlcnic_npar_func_cfg *np_cfg;
73262306a36Sopenharmony_ci	struct qlcnic_info nic_info;
73362306a36Sopenharmony_ci	u8 pci_func;
73462306a36Sopenharmony_ci	int i, ret;
73562306a36Sopenharmony_ci	u32 count;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	memset(&nic_info, 0, sizeof(struct qlcnic_info));
73862306a36Sopenharmony_ci	memset(buf, 0, size);
73962306a36Sopenharmony_ci	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci	count = size / sizeof(struct qlcnic_npar_func_cfg);
74262306a36Sopenharmony_ci	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
74362306a36Sopenharmony_ci		if (adapter->npars[i].pci_func >= count) {
74462306a36Sopenharmony_ci			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
74562306a36Sopenharmony_ci				__func__, adapter->ahw->total_nic_func, count);
74662306a36Sopenharmony_ci			continue;
74762306a36Sopenharmony_ci		}
74862306a36Sopenharmony_ci		if (!adapter->npars[i].eswitch_status)
74962306a36Sopenharmony_ci			continue;
75062306a36Sopenharmony_ci		pci_func = adapter->npars[i].pci_func;
75162306a36Sopenharmony_ci		if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
75262306a36Sopenharmony_ci			continue;
75362306a36Sopenharmony_ci		ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
75462306a36Sopenharmony_ci		if (ret)
75562306a36Sopenharmony_ci			return ret;
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci		np_cfg[pci_func].pci_func = pci_func;
75862306a36Sopenharmony_ci		np_cfg[pci_func].op_mode = (u8)nic_info.op_mode;
75962306a36Sopenharmony_ci		np_cfg[pci_func].port_num = nic_info.phys_port;
76062306a36Sopenharmony_ci		np_cfg[pci_func].fw_capab = nic_info.capabilities;
76162306a36Sopenharmony_ci		np_cfg[pci_func].min_bw = nic_info.min_tx_bw;
76262306a36Sopenharmony_ci		np_cfg[pci_func].max_bw = nic_info.max_tx_bw;
76362306a36Sopenharmony_ci		np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
76462306a36Sopenharmony_ci		np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
76562306a36Sopenharmony_ci	}
76662306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
76762306a36Sopenharmony_ci	return size;
76862306a36Sopenharmony_ci}
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
77162306a36Sopenharmony_ci					   struct kobject *kobj,
77262306a36Sopenharmony_ci					   struct bin_attribute *attr,
77362306a36Sopenharmony_ci					   char *buf, loff_t offset,
77462306a36Sopenharmony_ci					   size_t size)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
77762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
77862306a36Sopenharmony_ci	struct qlcnic_esw_statistics port_stats;
77962306a36Sopenharmony_ci	int ret;
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	if (qlcnic_83xx_check(adapter))
78262306a36Sopenharmony_ci		return -EOPNOTSUPP;
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci	if (size != sizeof(struct qlcnic_esw_statistics))
78562306a36Sopenharmony_ci		return -EINVAL;
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci	if (offset >= adapter->ahw->max_vnic_func)
78862306a36Sopenharmony_ci		return -EINVAL;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	memset(&port_stats, 0, size);
79162306a36Sopenharmony_ci	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
79262306a36Sopenharmony_ci				    &port_stats.rx);
79362306a36Sopenharmony_ci	if (ret)
79462306a36Sopenharmony_ci		return ret;
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
79762306a36Sopenharmony_ci				    &port_stats.tx);
79862306a36Sopenharmony_ci	if (ret)
79962306a36Sopenharmony_ci		return ret;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	memcpy(buf, &port_stats, size);
80262306a36Sopenharmony_ci	return size;
80362306a36Sopenharmony_ci}
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
80662306a36Sopenharmony_ci					  struct kobject *kobj,
80762306a36Sopenharmony_ci					  struct bin_attribute *attr,
80862306a36Sopenharmony_ci					  char *buf, loff_t offset,
80962306a36Sopenharmony_ci					  size_t size)
81062306a36Sopenharmony_ci{
81162306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
81262306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
81362306a36Sopenharmony_ci	struct qlcnic_esw_statistics esw_stats;
81462306a36Sopenharmony_ci	int ret;
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	if (qlcnic_83xx_check(adapter))
81762306a36Sopenharmony_ci		return -EOPNOTSUPP;
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci	if (size != sizeof(struct qlcnic_esw_statistics))
82062306a36Sopenharmony_ci		return -EINVAL;
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
82362306a36Sopenharmony_ci		return -EINVAL;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	memset(&esw_stats, 0, size);
82662306a36Sopenharmony_ci	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
82762306a36Sopenharmony_ci				       &esw_stats.rx);
82862306a36Sopenharmony_ci	if (ret)
82962306a36Sopenharmony_ci		return ret;
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
83262306a36Sopenharmony_ci				       &esw_stats.tx);
83362306a36Sopenharmony_ci	if (ret)
83462306a36Sopenharmony_ci		return ret;
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	memcpy(buf, &esw_stats, size);
83762306a36Sopenharmony_ci	return size;
83862306a36Sopenharmony_ci}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
84162306a36Sopenharmony_ci					    struct kobject *kobj,
84262306a36Sopenharmony_ci					    struct bin_attribute *attr,
84362306a36Sopenharmony_ci					    char *buf, loff_t offset,
84462306a36Sopenharmony_ci					    size_t size)
84562306a36Sopenharmony_ci{
84662306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
84762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
84862306a36Sopenharmony_ci	int ret;
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci	if (qlcnic_83xx_check(adapter))
85162306a36Sopenharmony_ci		return -EOPNOTSUPP;
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
85462306a36Sopenharmony_ci		return -EINVAL;
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
85762306a36Sopenharmony_ci				     QLCNIC_QUERY_RX_COUNTER);
85862306a36Sopenharmony_ci	if (ret)
85962306a36Sopenharmony_ci		return ret;
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
86262306a36Sopenharmony_ci				     QLCNIC_QUERY_TX_COUNTER);
86362306a36Sopenharmony_ci	if (ret)
86462306a36Sopenharmony_ci		return ret;
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci	return size;
86762306a36Sopenharmony_ci}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
87062306a36Sopenharmony_ci					     struct kobject *kobj,
87162306a36Sopenharmony_ci					     struct bin_attribute *attr,
87262306a36Sopenharmony_ci					     char *buf, loff_t offset,
87362306a36Sopenharmony_ci					     size_t size)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
87762306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
87862306a36Sopenharmony_ci	int ret;
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci	if (qlcnic_83xx_check(adapter))
88162306a36Sopenharmony_ci		return -EOPNOTSUPP;
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	if (offset >= adapter->ahw->max_vnic_func)
88462306a36Sopenharmony_ci		return -EINVAL;
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
88762306a36Sopenharmony_ci				     QLCNIC_QUERY_RX_COUNTER);
88862306a36Sopenharmony_ci	if (ret)
88962306a36Sopenharmony_ci		return ret;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
89262306a36Sopenharmony_ci				     QLCNIC_QUERY_TX_COUNTER);
89362306a36Sopenharmony_ci	if (ret)
89462306a36Sopenharmony_ci		return ret;
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci	return size;
89762306a36Sopenharmony_ci}
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_cistatic ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
90062306a36Sopenharmony_ci					    struct kobject *kobj,
90162306a36Sopenharmony_ci					    struct bin_attribute *attr,
90262306a36Sopenharmony_ci					    char *buf, loff_t offset,
90362306a36Sopenharmony_ci					    size_t size)
90462306a36Sopenharmony_ci{
90562306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
90662306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
90762306a36Sopenharmony_ci	struct qlcnic_pci_func_cfg *pci_cfg;
90862306a36Sopenharmony_ci	struct qlcnic_pci_info *pci_info;
90962306a36Sopenharmony_ci	int i, ret;
91062306a36Sopenharmony_ci	u32 count;
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	pci_info = kcalloc(size, sizeof(*pci_info), GFP_KERNEL);
91362306a36Sopenharmony_ci	if (!pci_info)
91462306a36Sopenharmony_ci		return -ENOMEM;
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci	ret = qlcnic_get_pci_info(adapter, pci_info);
91762306a36Sopenharmony_ci	if (ret) {
91862306a36Sopenharmony_ci		kfree(pci_info);
91962306a36Sopenharmony_ci		return ret;
92062306a36Sopenharmony_ci	}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
92362306a36Sopenharmony_ci	count = size / sizeof(struct qlcnic_pci_func_cfg);
92462306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32));
92562306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
92662306a36Sopenharmony_ci		pci_cfg[i].pci_func = pci_info[i].id;
92762306a36Sopenharmony_ci		pci_cfg[i].func_type = pci_info[i].type;
92862306a36Sopenharmony_ci		pci_cfg[i].func_state = 0;
92962306a36Sopenharmony_ci		pci_cfg[i].port_num = pci_info[i].default_port;
93062306a36Sopenharmony_ci		pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
93162306a36Sopenharmony_ci		pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
93262306a36Sopenharmony_ci		memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	kfree(pci_info);
93662306a36Sopenharmony_ci	return size;
93762306a36Sopenharmony_ci}
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_cistatic ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
94062306a36Sopenharmony_ci						    struct kobject *kobj,
94162306a36Sopenharmony_ci						    struct bin_attribute *attr,
94262306a36Sopenharmony_ci						    char *buf, loff_t offset,
94362306a36Sopenharmony_ci						    size_t size)
94462306a36Sopenharmony_ci{
94562306a36Sopenharmony_ci	unsigned char *p_read_buf;
94662306a36Sopenharmony_ci	int  ret, count;
94762306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
94862306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	if (!size)
95162306a36Sopenharmony_ci		return -EINVAL;
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	count = size / sizeof(u32);
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci	if (size % sizeof(u32))
95662306a36Sopenharmony_ci		count++;
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci	p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
95962306a36Sopenharmony_ci	if (!p_read_buf)
96062306a36Sopenharmony_ci		return -ENOMEM;
96162306a36Sopenharmony_ci	if (qlcnic_83xx_lock_flash(adapter) != 0) {
96262306a36Sopenharmony_ci		kfree(p_read_buf);
96362306a36Sopenharmony_ci		return -EIO;
96462306a36Sopenharmony_ci	}
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf,
96762306a36Sopenharmony_ci						count);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	if (ret) {
97062306a36Sopenharmony_ci		qlcnic_83xx_unlock_flash(adapter);
97162306a36Sopenharmony_ci		kfree(p_read_buf);
97262306a36Sopenharmony_ci		return ret;
97362306a36Sopenharmony_ci	}
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	qlcnic_83xx_unlock_flash(adapter);
97662306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)p_read_buf, count);
97762306a36Sopenharmony_ci	memcpy(buf, p_read_buf, size);
97862306a36Sopenharmony_ci	kfree(p_read_buf);
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	return size;
98162306a36Sopenharmony_ci}
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_cistatic int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
98462306a36Sopenharmony_ci					      char *buf, loff_t offset,
98562306a36Sopenharmony_ci					      size_t size)
98662306a36Sopenharmony_ci{
98762306a36Sopenharmony_ci	int  i, ret, count;
98862306a36Sopenharmony_ci	unsigned char *p_cache, *p_src;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
99162306a36Sopenharmony_ci	if (!p_cache)
99262306a36Sopenharmony_ci		return -ENOMEM;
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	count = size / sizeof(u32);
99562306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, count);
99662306a36Sopenharmony_ci	memcpy(p_cache, buf, size);
99762306a36Sopenharmony_ci	p_src = p_cache;
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	if (qlcnic_83xx_lock_flash(adapter) != 0) {
100062306a36Sopenharmony_ci		kfree(p_cache);
100162306a36Sopenharmony_ci		return -EIO;
100262306a36Sopenharmony_ci	}
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
100562306a36Sopenharmony_ci		ret = qlcnic_83xx_enable_flash_write(adapter);
100662306a36Sopenharmony_ci		if (ret) {
100762306a36Sopenharmony_ci			kfree(p_cache);
100862306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
100962306a36Sopenharmony_ci			return -EIO;
101062306a36Sopenharmony_ci		}
101162306a36Sopenharmony_ci	}
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) {
101462306a36Sopenharmony_ci		ret = qlcnic_83xx_flash_bulk_write(adapter, offset,
101562306a36Sopenharmony_ci						   (u32 *)p_src,
101662306a36Sopenharmony_ci						   QLC_83XX_FLASH_WRITE_MAX);
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci		if (ret) {
101962306a36Sopenharmony_ci			if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
102062306a36Sopenharmony_ci				ret = qlcnic_83xx_disable_flash_write(adapter);
102162306a36Sopenharmony_ci				if (ret) {
102262306a36Sopenharmony_ci					kfree(p_cache);
102362306a36Sopenharmony_ci					qlcnic_83xx_unlock_flash(adapter);
102462306a36Sopenharmony_ci					return -EIO;
102562306a36Sopenharmony_ci				}
102662306a36Sopenharmony_ci			}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci			kfree(p_cache);
102962306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
103062306a36Sopenharmony_ci			return -EIO;
103162306a36Sopenharmony_ci		}
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci		p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
103462306a36Sopenharmony_ci		offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
103562306a36Sopenharmony_ci	}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
103862306a36Sopenharmony_ci		ret = qlcnic_83xx_disable_flash_write(adapter);
103962306a36Sopenharmony_ci		if (ret) {
104062306a36Sopenharmony_ci			kfree(p_cache);
104162306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
104262306a36Sopenharmony_ci			return -EIO;
104362306a36Sopenharmony_ci		}
104462306a36Sopenharmony_ci	}
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci	kfree(p_cache);
104762306a36Sopenharmony_ci	qlcnic_83xx_unlock_flash(adapter);
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	return 0;
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_cistatic int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
105362306a36Sopenharmony_ci					 char *buf, loff_t offset, size_t size)
105462306a36Sopenharmony_ci{
105562306a36Sopenharmony_ci	int  i, ret, count;
105662306a36Sopenharmony_ci	unsigned char *p_cache, *p_src;
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci	p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
105962306a36Sopenharmony_ci	if (!p_cache)
106062306a36Sopenharmony_ci		return -ENOMEM;
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_ci	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
106362306a36Sopenharmony_ci	memcpy(p_cache, buf, size);
106462306a36Sopenharmony_ci	p_src = p_cache;
106562306a36Sopenharmony_ci	count = size / sizeof(u32);
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_ci	if (qlcnic_83xx_lock_flash(adapter) != 0) {
106862306a36Sopenharmony_ci		kfree(p_cache);
106962306a36Sopenharmony_ci		return -EIO;
107062306a36Sopenharmony_ci	}
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
107362306a36Sopenharmony_ci		ret = qlcnic_83xx_enable_flash_write(adapter);
107462306a36Sopenharmony_ci		if (ret) {
107562306a36Sopenharmony_ci			kfree(p_cache);
107662306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
107762306a36Sopenharmony_ci			return -EIO;
107862306a36Sopenharmony_ci		}
107962306a36Sopenharmony_ci	}
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci	for (i = 0; i < count; i++) {
108262306a36Sopenharmony_ci		ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src);
108362306a36Sopenharmony_ci		if (ret) {
108462306a36Sopenharmony_ci			if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
108562306a36Sopenharmony_ci				ret = qlcnic_83xx_disable_flash_write(adapter);
108662306a36Sopenharmony_ci				if (ret) {
108762306a36Sopenharmony_ci					kfree(p_cache);
108862306a36Sopenharmony_ci					qlcnic_83xx_unlock_flash(adapter);
108962306a36Sopenharmony_ci					return -EIO;
109062306a36Sopenharmony_ci				}
109162306a36Sopenharmony_ci			}
109262306a36Sopenharmony_ci			kfree(p_cache);
109362306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
109462306a36Sopenharmony_ci			return -EIO;
109562306a36Sopenharmony_ci		}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci		p_src = p_src + sizeof(u32);
109862306a36Sopenharmony_ci		offset = offset + sizeof(u32);
109962306a36Sopenharmony_ci	}
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
110262306a36Sopenharmony_ci		ret = qlcnic_83xx_disable_flash_write(adapter);
110362306a36Sopenharmony_ci		if (ret) {
110462306a36Sopenharmony_ci			kfree(p_cache);
110562306a36Sopenharmony_ci			qlcnic_83xx_unlock_flash(adapter);
110662306a36Sopenharmony_ci			return -EIO;
110762306a36Sopenharmony_ci		}
110862306a36Sopenharmony_ci	}
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	kfree(p_cache);
111162306a36Sopenharmony_ci	qlcnic_83xx_unlock_flash(adapter);
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	return 0;
111462306a36Sopenharmony_ci}
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_cistatic ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
111762306a36Sopenharmony_ci						     struct kobject *kobj,
111862306a36Sopenharmony_ci						     struct bin_attribute *attr,
111962306a36Sopenharmony_ci						     char *buf, loff_t offset,
112062306a36Sopenharmony_ci						     size_t size)
112162306a36Sopenharmony_ci{
112262306a36Sopenharmony_ci	int  ret;
112362306a36Sopenharmony_ci	static int flash_mode;
112462306a36Sopenharmony_ci	unsigned long data;
112562306a36Sopenharmony_ci	struct device *dev = kobj_to_dev(kobj);
112662306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	ret = kstrtoul(buf, 16, &data);
112962306a36Sopenharmony_ci	if (ret)
113062306a36Sopenharmony_ci		return ret;
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci	switch (data) {
113362306a36Sopenharmony_ci	case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
113462306a36Sopenharmony_ci		flash_mode = QLC_83XX_ERASE_MODE;
113562306a36Sopenharmony_ci		ret = qlcnic_83xx_erase_flash_sector(adapter, offset);
113662306a36Sopenharmony_ci		if (ret) {
113762306a36Sopenharmony_ci			dev_err(&adapter->pdev->dev,
113862306a36Sopenharmony_ci				"%s failed at %d\n", __func__, __LINE__);
113962306a36Sopenharmony_ci			return -EIO;
114062306a36Sopenharmony_ci		}
114162306a36Sopenharmony_ci		break;
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	case QLC_83XX_FLASH_BULK_WRITE_CMD:
114462306a36Sopenharmony_ci		flash_mode = QLC_83XX_BULK_WRITE_MODE;
114562306a36Sopenharmony_ci		break;
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci	case QLC_83XX_FLASH_WRITE_CMD:
114862306a36Sopenharmony_ci		flash_mode = QLC_83XX_WRITE_MODE;
114962306a36Sopenharmony_ci		break;
115062306a36Sopenharmony_ci	default:
115162306a36Sopenharmony_ci		if (flash_mode == QLC_83XX_BULK_WRITE_MODE) {
115262306a36Sopenharmony_ci			ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf,
115362306a36Sopenharmony_ci								 offset, size);
115462306a36Sopenharmony_ci			if (ret) {
115562306a36Sopenharmony_ci				dev_err(&adapter->pdev->dev,
115662306a36Sopenharmony_ci					"%s failed at %d\n",
115762306a36Sopenharmony_ci					__func__, __LINE__);
115862306a36Sopenharmony_ci				return -EIO;
115962306a36Sopenharmony_ci			}
116062306a36Sopenharmony_ci		}
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci		if (flash_mode == QLC_83XX_WRITE_MODE) {
116362306a36Sopenharmony_ci			ret = qlcnic_83xx_sysfs_flash_write(adapter, buf,
116462306a36Sopenharmony_ci							    offset, size);
116562306a36Sopenharmony_ci			if (ret) {
116662306a36Sopenharmony_ci				dev_err(&adapter->pdev->dev,
116762306a36Sopenharmony_ci					"%s failed at %d\n", __func__,
116862306a36Sopenharmony_ci					__LINE__);
116962306a36Sopenharmony_ci				return -EIO;
117062306a36Sopenharmony_ci			}
117162306a36Sopenharmony_ci		}
117262306a36Sopenharmony_ci	}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	return size;
117562306a36Sopenharmony_ci}
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_cistatic const struct device_attribute dev_attr_bridged_mode = {
117862306a36Sopenharmony_ci	.attr = { .name = "bridged_mode", .mode = 0644 },
117962306a36Sopenharmony_ci	.show = qlcnic_show_bridged_mode,
118062306a36Sopenharmony_ci	.store = qlcnic_store_bridged_mode,
118162306a36Sopenharmony_ci};
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_cistatic const struct device_attribute dev_attr_diag_mode = {
118462306a36Sopenharmony_ci	.attr = { .name = "diag_mode", .mode = 0644 },
118562306a36Sopenharmony_ci	.show = qlcnic_show_diag_mode,
118662306a36Sopenharmony_ci	.store = qlcnic_store_diag_mode,
118762306a36Sopenharmony_ci};
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_cistatic const struct device_attribute dev_attr_beacon = {
119062306a36Sopenharmony_ci	.attr = { .name = "beacon", .mode = 0644 },
119162306a36Sopenharmony_ci	.show = qlcnic_show_beacon,
119262306a36Sopenharmony_ci	.store = qlcnic_store_beacon,
119362306a36Sopenharmony_ci};
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_crb = {
119662306a36Sopenharmony_ci	.attr = { .name = "crb", .mode = 0644 },
119762306a36Sopenharmony_ci	.size = 0,
119862306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_crb,
119962306a36Sopenharmony_ci	.write = qlcnic_sysfs_write_crb,
120062306a36Sopenharmony_ci};
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_mem = {
120362306a36Sopenharmony_ci	.attr = { .name = "mem", .mode = 0644 },
120462306a36Sopenharmony_ci	.size = 0,
120562306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_mem,
120662306a36Sopenharmony_ci	.write = qlcnic_sysfs_write_mem,
120762306a36Sopenharmony_ci};
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_npar_config = {
121062306a36Sopenharmony_ci	.attr = { .name = "npar_config", .mode = 0644 },
121162306a36Sopenharmony_ci	.size = 0,
121262306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_npar_config,
121362306a36Sopenharmony_ci	.write = qlcnic_sysfs_write_npar_config,
121462306a36Sopenharmony_ci};
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_pci_config = {
121762306a36Sopenharmony_ci	.attr = { .name = "pci_config", .mode = 0644 },
121862306a36Sopenharmony_ci	.size = 0,
121962306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_pci_config,
122062306a36Sopenharmony_ci	.write = NULL,
122162306a36Sopenharmony_ci};
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_port_stats = {
122462306a36Sopenharmony_ci	.attr = { .name = "port_stats", .mode = 0644 },
122562306a36Sopenharmony_ci	.size = 0,
122662306a36Sopenharmony_ci	.read = qlcnic_sysfs_get_port_stats,
122762306a36Sopenharmony_ci	.write = qlcnic_sysfs_clear_port_stats,
122862306a36Sopenharmony_ci};
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_esw_stats = {
123162306a36Sopenharmony_ci	.attr = { .name = "esw_stats", .mode = 0644 },
123262306a36Sopenharmony_ci	.size = 0,
123362306a36Sopenharmony_ci	.read = qlcnic_sysfs_get_esw_stats,
123462306a36Sopenharmony_ci	.write = qlcnic_sysfs_clear_esw_stats,
123562306a36Sopenharmony_ci};
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_esw_config = {
123862306a36Sopenharmony_ci	.attr = { .name = "esw_config", .mode = 0644 },
123962306a36Sopenharmony_ci	.size = 0,
124062306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_esw_config,
124162306a36Sopenharmony_ci	.write = qlcnic_sysfs_write_esw_config,
124262306a36Sopenharmony_ci};
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_pm_config = {
124562306a36Sopenharmony_ci	.attr = { .name = "pm_config", .mode = 0644 },
124662306a36Sopenharmony_ci	.size = 0,
124762306a36Sopenharmony_ci	.read = qlcnic_sysfs_read_pm_config,
124862306a36Sopenharmony_ci	.write = qlcnic_sysfs_write_pm_config,
124962306a36Sopenharmony_ci};
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_cistatic const struct bin_attribute bin_attr_flash = {
125262306a36Sopenharmony_ci	.attr = { .name = "flash", .mode = 0644 },
125362306a36Sopenharmony_ci	.size = 0,
125462306a36Sopenharmony_ci	.read = qlcnic_83xx_sysfs_flash_read_handler,
125562306a36Sopenharmony_ci	.write = qlcnic_83xx_sysfs_flash_write_handler,
125662306a36Sopenharmony_ci};
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci#ifdef CONFIG_QLCNIC_HWMON
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_cistatic ssize_t qlcnic_hwmon_show_temp(struct device *dev,
126162306a36Sopenharmony_ci				      struct device_attribute *dev_attr,
126262306a36Sopenharmony_ci				      char *buf)
126362306a36Sopenharmony_ci{
126462306a36Sopenharmony_ci	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
126562306a36Sopenharmony_ci	unsigned int temperature = 0, value = 0;
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	if (qlcnic_83xx_check(adapter))
126862306a36Sopenharmony_ci		value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP);
126962306a36Sopenharmony_ci	else if (qlcnic_82xx_check(adapter))
127062306a36Sopenharmony_ci		value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP);
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ci	temperature = qlcnic_get_temp_val(value);
127362306a36Sopenharmony_ci	/* display millidegree celcius */
127462306a36Sopenharmony_ci	temperature *= 1000;
127562306a36Sopenharmony_ci	return sprintf(buf, "%u\n", temperature);
127662306a36Sopenharmony_ci}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci/* hwmon-sysfs attributes */
127962306a36Sopenharmony_cistatic SENSOR_DEVICE_ATTR(temp1_input, 0444,
128062306a36Sopenharmony_ci			  qlcnic_hwmon_show_temp, NULL, 1);
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_cistatic struct attribute *qlcnic_hwmon_attrs[] = {
128362306a36Sopenharmony_ci	&sensor_dev_attr_temp1_input.dev_attr.attr,
128462306a36Sopenharmony_ci	NULL
128562306a36Sopenharmony_ci};
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ciATTRIBUTE_GROUPS(qlcnic_hwmon);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_civoid qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
129062306a36Sopenharmony_ci{
129162306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
129262306a36Sopenharmony_ci	struct device *hwmon_dev;
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	/* Skip hwmon registration for a VF device */
129562306a36Sopenharmony_ci	if (qlcnic_sriov_vf_check(adapter)) {
129662306a36Sopenharmony_ci		adapter->ahw->hwmon_dev = NULL;
129762306a36Sopenharmony_ci		return;
129862306a36Sopenharmony_ci	}
129962306a36Sopenharmony_ci	hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name,
130062306a36Sopenharmony_ci						      adapter,
130162306a36Sopenharmony_ci						      qlcnic_hwmon_groups);
130262306a36Sopenharmony_ci	if (IS_ERR(hwmon_dev)) {
130362306a36Sopenharmony_ci		dev_err(dev, "Cannot register with hwmon, err=%ld\n",
130462306a36Sopenharmony_ci			PTR_ERR(hwmon_dev));
130562306a36Sopenharmony_ci		hwmon_dev = NULL;
130662306a36Sopenharmony_ci	}
130762306a36Sopenharmony_ci	adapter->ahw->hwmon_dev = hwmon_dev;
130862306a36Sopenharmony_ci}
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_civoid qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
131162306a36Sopenharmony_ci{
131262306a36Sopenharmony_ci	struct device *hwmon_dev = adapter->ahw->hwmon_dev;
131362306a36Sopenharmony_ci	if (hwmon_dev) {
131462306a36Sopenharmony_ci		hwmon_device_unregister(hwmon_dev);
131562306a36Sopenharmony_ci		adapter->ahw->hwmon_dev = NULL;
131662306a36Sopenharmony_ci	}
131762306a36Sopenharmony_ci}
131862306a36Sopenharmony_ci#endif
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_civoid qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
132162306a36Sopenharmony_ci{
132262306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
132562306a36Sopenharmony_ci		if (device_create_file(dev, &dev_attr_bridged_mode))
132662306a36Sopenharmony_ci			dev_warn(dev,
132762306a36Sopenharmony_ci				 "failed to create bridged_mode sysfs entry\n");
132862306a36Sopenharmony_ci}
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_civoid qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
133162306a36Sopenharmony_ci{
133262306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
133362306a36Sopenharmony_ci
133462306a36Sopenharmony_ci	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
133562306a36Sopenharmony_ci		device_remove_file(dev, &dev_attr_bridged_mode);
133662306a36Sopenharmony_ci}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_cistatic void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
133962306a36Sopenharmony_ci{
134062306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_port_stats))
134362306a36Sopenharmony_ci		dev_info(dev, "failed to create port stats sysfs entry");
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
134662306a36Sopenharmony_ci		return;
134762306a36Sopenharmony_ci	if (device_create_file(dev, &dev_attr_diag_mode))
134862306a36Sopenharmony_ci		dev_info(dev, "failed to create diag_mode sysfs entry\n");
134962306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_crb))
135062306a36Sopenharmony_ci		dev_info(dev, "failed to create crb sysfs entry\n");
135162306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_mem))
135262306a36Sopenharmony_ci		dev_info(dev, "failed to create mem sysfs entry\n");
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
135562306a36Sopenharmony_ci		return;
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_pci_config))
135862306a36Sopenharmony_ci		dev_info(dev, "failed to create pci config sysfs entry");
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	if (device_create_file(dev, &dev_attr_beacon))
136162306a36Sopenharmony_ci		dev_info(dev, "failed to create beacon sysfs entry");
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
136462306a36Sopenharmony_ci		return;
136562306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_esw_config))
136662306a36Sopenharmony_ci		dev_info(dev, "failed to create esw config sysfs entry");
136762306a36Sopenharmony_ci	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
136862306a36Sopenharmony_ci		return;
136962306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_npar_config))
137062306a36Sopenharmony_ci		dev_info(dev, "failed to create npar config sysfs entry");
137162306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_pm_config))
137262306a36Sopenharmony_ci		dev_info(dev, "failed to create pm config sysfs entry");
137362306a36Sopenharmony_ci	if (device_create_bin_file(dev, &bin_attr_esw_stats))
137462306a36Sopenharmony_ci		dev_info(dev, "failed to create eswitch stats sysfs entry");
137562306a36Sopenharmony_ci}
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_cistatic void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
137862306a36Sopenharmony_ci{
137962306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_port_stats);
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_ci	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
138462306a36Sopenharmony_ci		return;
138562306a36Sopenharmony_ci	device_remove_file(dev, &dev_attr_diag_mode);
138662306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_crb);
138762306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_mem);
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
139062306a36Sopenharmony_ci		return;
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_pci_config);
139362306a36Sopenharmony_ci	device_remove_file(dev, &dev_attr_beacon);
139462306a36Sopenharmony_ci	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
139562306a36Sopenharmony_ci		return;
139662306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_esw_config);
139762306a36Sopenharmony_ci	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
139862306a36Sopenharmony_ci		return;
139962306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_npar_config);
140062306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_pm_config);
140162306a36Sopenharmony_ci	device_remove_bin_file(dev, &bin_attr_esw_stats);
140262306a36Sopenharmony_ci}
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_civoid qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
140562306a36Sopenharmony_ci{
140662306a36Sopenharmony_ci	qlcnic_create_diag_entries(adapter);
140762306a36Sopenharmony_ci}
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_civoid qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
141062306a36Sopenharmony_ci{
141162306a36Sopenharmony_ci	qlcnic_remove_diag_entries(adapter);
141262306a36Sopenharmony_ci}
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_civoid qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
141562306a36Sopenharmony_ci{
141662306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_ci	qlcnic_create_diag_entries(adapter);
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash))
142162306a36Sopenharmony_ci		dev_info(dev, "failed to create flash sysfs entry\n");
142262306a36Sopenharmony_ci}
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_civoid qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
142562306a36Sopenharmony_ci{
142662306a36Sopenharmony_ci	struct device *dev = &adapter->pdev->dev;
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	qlcnic_remove_diag_entries(adapter);
142962306a36Sopenharmony_ci	sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash);
143062306a36Sopenharmony_ci}
1431