xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * QLogic qlcnic NIC Driver
4*4882a593Smuzhiyun  * Copyright (c) 2009-2013 QLogic Corporation
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/interrupt.h>
9*4882a593Smuzhiyun #include <linux/swab.h>
10*4882a593Smuzhiyun #include <linux/dma-mapping.h>
11*4882a593Smuzhiyun #include <net/ip.h>
12*4882a593Smuzhiyun #include <linux/ipv6.h>
13*4882a593Smuzhiyun #include <linux/inetdevice.h>
14*4882a593Smuzhiyun #include <linux/sysfs.h>
15*4882a593Smuzhiyun #include <linux/aer.h>
16*4882a593Smuzhiyun #include <linux/log2.h>
17*4882a593Smuzhiyun #ifdef CONFIG_QLCNIC_HWMON
18*4882a593Smuzhiyun #include <linux/hwmon.h>
19*4882a593Smuzhiyun #include <linux/hwmon-sysfs.h>
20*4882a593Smuzhiyun #endif
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include "qlcnic.h"
23*4882a593Smuzhiyun #include "qlcnic_hw.h"
24*4882a593Smuzhiyun 
qlcnicvf_config_bridged_mode(struct qlcnic_adapter * adapter,u32 enable)25*4882a593Smuzhiyun int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	return -EOPNOTSUPP;
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
qlcnicvf_config_led(struct qlcnic_adapter * adapter,u32 state,u32 rate)30*4882a593Smuzhiyun int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	return -EOPNOTSUPP;
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun 
qlcnic_store_bridged_mode(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)35*4882a593Smuzhiyun static ssize_t qlcnic_store_bridged_mode(struct device *dev,
36*4882a593Smuzhiyun 					 struct device_attribute *attr,
37*4882a593Smuzhiyun 					 const char *buf, size_t len)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
40*4882a593Smuzhiyun 	unsigned long new;
41*4882a593Smuzhiyun 	int ret = -EINVAL;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
44*4882a593Smuzhiyun 		goto err_out;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
47*4882a593Smuzhiyun 		goto err_out;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	if (kstrtoul(buf, 2, &new))
50*4882a593Smuzhiyun 		goto err_out;
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	if (!qlcnic_config_bridged_mode(adapter, !!new))
53*4882a593Smuzhiyun 		ret = len;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun err_out:
56*4882a593Smuzhiyun 	return ret;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
qlcnic_show_bridged_mode(struct device * dev,struct device_attribute * attr,char * buf)59*4882a593Smuzhiyun static ssize_t qlcnic_show_bridged_mode(struct device *dev,
60*4882a593Smuzhiyun 					struct device_attribute *attr,
61*4882a593Smuzhiyun 					char *buf)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
64*4882a593Smuzhiyun 	int bridged_mode = 0;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
67*4882a593Smuzhiyun 		bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", bridged_mode);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
qlcnic_store_diag_mode(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)72*4882a593Smuzhiyun static ssize_t qlcnic_store_diag_mode(struct device *dev,
73*4882a593Smuzhiyun 				      struct device_attribute *attr,
74*4882a593Smuzhiyun 				      const char *buf, size_t len)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
77*4882a593Smuzhiyun 	unsigned long new;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	if (kstrtoul(buf, 2, &new))
80*4882a593Smuzhiyun 		return -EINVAL;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
83*4882a593Smuzhiyun 		adapter->flags ^= QLCNIC_DIAG_ENABLED;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	return len;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
qlcnic_show_diag_mode(struct device * dev,struct device_attribute * attr,char * buf)88*4882a593Smuzhiyun static ssize_t qlcnic_show_diag_mode(struct device *dev,
89*4882a593Smuzhiyun 				     struct device_attribute *attr, char *buf)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
92*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
qlcnic_validate_beacon(struct qlcnic_adapter * adapter,u16 beacon,u8 * state,u8 * rate)95*4882a593Smuzhiyun static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
96*4882a593Smuzhiyun 				  u8 *state, u8 *rate)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	*rate = LSB(beacon);
99*4882a593Smuzhiyun 	*state = MSB(beacon);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	if (!*state) {
104*4882a593Smuzhiyun 		*rate = __QLCNIC_MAX_LED_RATE;
105*4882a593Smuzhiyun 		return 0;
106*4882a593Smuzhiyun 	} else if (*state > __QLCNIC_MAX_LED_STATE) {
107*4882a593Smuzhiyun 		return -EINVAL;
108*4882a593Smuzhiyun 	}
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
111*4882a593Smuzhiyun 		return -EINVAL;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	return 0;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
qlcnic_83xx_store_beacon(struct qlcnic_adapter * adapter,const char * buf,size_t len)116*4882a593Smuzhiyun static int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter,
117*4882a593Smuzhiyun 				    const char *buf, size_t len)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	struct qlcnic_hardware_context *ahw = adapter->ahw;
120*4882a593Smuzhiyun 	unsigned long h_beacon;
121*4882a593Smuzhiyun 	int err;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
124*4882a593Smuzhiyun 		return -EIO;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	if (kstrtoul(buf, 2, &h_beacon))
127*4882a593Smuzhiyun 		return -EINVAL;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	qlcnic_get_beacon_state(adapter);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	if (ahw->beacon_state == h_beacon)
132*4882a593Smuzhiyun 		return len;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	rtnl_lock();
135*4882a593Smuzhiyun 	if (!ahw->beacon_state) {
136*4882a593Smuzhiyun 		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
137*4882a593Smuzhiyun 			rtnl_unlock();
138*4882a593Smuzhiyun 			return -EBUSY;
139*4882a593Smuzhiyun 		}
140*4882a593Smuzhiyun 	}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	if (h_beacon)
143*4882a593Smuzhiyun 		err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
144*4882a593Smuzhiyun 	else
145*4882a593Smuzhiyun 		err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
146*4882a593Smuzhiyun 	if (!err)
147*4882a593Smuzhiyun 		ahw->beacon_state = h_beacon;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	if (!ahw->beacon_state)
150*4882a593Smuzhiyun 		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	rtnl_unlock();
153*4882a593Smuzhiyun 	return len;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
qlcnic_82xx_store_beacon(struct qlcnic_adapter * adapter,const char * buf,size_t len)156*4882a593Smuzhiyun static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
157*4882a593Smuzhiyun 				    const char *buf, size_t len)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	struct qlcnic_hardware_context *ahw = adapter->ahw;
160*4882a593Smuzhiyun 	int err, drv_sds_rings = adapter->drv_sds_rings;
161*4882a593Smuzhiyun 	u16 beacon;
162*4882a593Smuzhiyun 	u8 b_state, b_rate;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	if (len != sizeof(u16))
165*4882a593Smuzhiyun 		return -EINVAL;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	memcpy(&beacon, buf, sizeof(u16));
168*4882a593Smuzhiyun 	err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
169*4882a593Smuzhiyun 	if (err)
170*4882a593Smuzhiyun 		return err;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	qlcnic_get_beacon_state(adapter);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	if (ahw->beacon_state == b_state)
175*4882a593Smuzhiyun 		return len;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	rtnl_lock();
178*4882a593Smuzhiyun 	if (!ahw->beacon_state) {
179*4882a593Smuzhiyun 		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
180*4882a593Smuzhiyun 			rtnl_unlock();
181*4882a593Smuzhiyun 			return -EBUSY;
182*4882a593Smuzhiyun 		}
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
186*4882a593Smuzhiyun 		err = -EIO;
187*4882a593Smuzhiyun 		goto out;
188*4882a593Smuzhiyun 	}
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
191*4882a593Smuzhiyun 		err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
192*4882a593Smuzhiyun 		if (err)
193*4882a593Smuzhiyun 			goto out;
194*4882a593Smuzhiyun 		set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	err = qlcnic_config_led(adapter, b_state, b_rate);
198*4882a593Smuzhiyun 	if (!err) {
199*4882a593Smuzhiyun 		err = len;
200*4882a593Smuzhiyun 		ahw->beacon_state = b_state;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
204*4882a593Smuzhiyun 		qlcnic_diag_free_res(adapter->netdev, drv_sds_rings);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun out:
207*4882a593Smuzhiyun 	if (!ahw->beacon_state)
208*4882a593Smuzhiyun 		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
209*4882a593Smuzhiyun 	rtnl_unlock();
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	return err;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
qlcnic_store_beacon(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)214*4882a593Smuzhiyun static ssize_t qlcnic_store_beacon(struct device *dev,
215*4882a593Smuzhiyun 				   struct device_attribute *attr,
216*4882a593Smuzhiyun 				   const char *buf, size_t len)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
219*4882a593Smuzhiyun 	int err = 0;
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
222*4882a593Smuzhiyun 		dev_warn(dev,
223*4882a593Smuzhiyun 			 "LED test not supported in non privileged mode\n");
224*4882a593Smuzhiyun 		return -EOPNOTSUPP;
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	if (qlcnic_82xx_check(adapter))
228*4882a593Smuzhiyun 		err = qlcnic_82xx_store_beacon(adapter, buf, len);
229*4882a593Smuzhiyun 	else if (qlcnic_83xx_check(adapter))
230*4882a593Smuzhiyun 		err = qlcnic_83xx_store_beacon(adapter, buf, len);
231*4882a593Smuzhiyun 	else
232*4882a593Smuzhiyun 		return -EIO;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	return err;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun 
qlcnic_show_beacon(struct device * dev,struct device_attribute * attr,char * buf)237*4882a593Smuzhiyun static ssize_t qlcnic_show_beacon(struct device *dev,
238*4882a593Smuzhiyun 				  struct device_attribute *attr, char *buf)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
qlcnic_sysfs_validate_crb(struct qlcnic_adapter * adapter,loff_t offset,size_t size)245*4882a593Smuzhiyun static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
246*4882a593Smuzhiyun 				     loff_t offset, size_t size)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	size_t crb_size = 4;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
251*4882a593Smuzhiyun 		return -EIO;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (offset < QLCNIC_PCI_CRBSPACE) {
254*4882a593Smuzhiyun 		if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
255*4882a593Smuzhiyun 				  QLCNIC_PCI_CAMQM_END))
256*4882a593Smuzhiyun 			crb_size = 8;
257*4882a593Smuzhiyun 		else
258*4882a593Smuzhiyun 			return -EINVAL;
259*4882a593Smuzhiyun 	}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	if ((size != crb_size) || (offset & (crb_size-1)))
262*4882a593Smuzhiyun 		return  -EINVAL;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	return 0;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
qlcnic_sysfs_read_crb(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)267*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
268*4882a593Smuzhiyun 				     struct bin_attribute *attr, char *buf,
269*4882a593Smuzhiyun 				     loff_t offset, size_t size)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
272*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
273*4882a593Smuzhiyun 	int ret;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
276*4882a593Smuzhiyun 	if (ret != 0)
277*4882a593Smuzhiyun 		return ret;
278*4882a593Smuzhiyun 	qlcnic_read_crb(adapter, buf, offset, size);
279*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	return size;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
qlcnic_sysfs_write_crb(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)284*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
285*4882a593Smuzhiyun 				      struct bin_attribute *attr, char *buf,
286*4882a593Smuzhiyun 				      loff_t offset, size_t size)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
289*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
290*4882a593Smuzhiyun 	int ret;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
293*4882a593Smuzhiyun 	if (ret != 0)
294*4882a593Smuzhiyun 		return ret;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
297*4882a593Smuzhiyun 	qlcnic_write_crb(adapter, buf, offset, size);
298*4882a593Smuzhiyun 	return size;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
qlcnic_sysfs_validate_mem(struct qlcnic_adapter * adapter,loff_t offset,size_t size)301*4882a593Smuzhiyun static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
302*4882a593Smuzhiyun 				     loff_t offset, size_t size)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
305*4882a593Smuzhiyun 		return -EIO;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	if ((size != 8) || (offset & 0x7))
308*4882a593Smuzhiyun 		return  -EIO;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	return 0;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
qlcnic_sysfs_read_mem(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)313*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
314*4882a593Smuzhiyun 				     struct bin_attribute *attr, char *buf,
315*4882a593Smuzhiyun 				     loff_t offset, size_t size)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
318*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
319*4882a593Smuzhiyun 	u64 data;
320*4882a593Smuzhiyun 	int ret;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
323*4882a593Smuzhiyun 	if (ret != 0)
324*4882a593Smuzhiyun 		return ret;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
327*4882a593Smuzhiyun 		return -EIO;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	memcpy(buf, &data, size);
330*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	return size;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
qlcnic_sysfs_write_mem(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)335*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
336*4882a593Smuzhiyun 				      struct bin_attribute *attr, char *buf,
337*4882a593Smuzhiyun 				      loff_t offset, size_t size)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
340*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
341*4882a593Smuzhiyun 	u64 data;
342*4882a593Smuzhiyun 	int ret;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
345*4882a593Smuzhiyun 	if (ret != 0)
346*4882a593Smuzhiyun 		return ret;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
349*4882a593Smuzhiyun 	memcpy(&data, buf, size);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	if (qlcnic_pci_mem_write_2M(adapter, offset, data))
352*4882a593Smuzhiyun 		return -EIO;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	return size;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun 
qlcnic_is_valid_nic_func(struct qlcnic_adapter * adapter,u8 pci_func)357*4882a593Smuzhiyun int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
358*4882a593Smuzhiyun {
359*4882a593Smuzhiyun 	int i;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
362*4882a593Smuzhiyun 		if (adapter->npars[i].pci_func == pci_func)
363*4882a593Smuzhiyun 			return i;
364*4882a593Smuzhiyun 	}
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__);
367*4882a593Smuzhiyun 	return -EINVAL;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
validate_pm_config(struct qlcnic_adapter * adapter,struct qlcnic_pm_func_cfg * pm_cfg,int count)370*4882a593Smuzhiyun static int validate_pm_config(struct qlcnic_adapter *adapter,
371*4882a593Smuzhiyun 			      struct qlcnic_pm_func_cfg *pm_cfg, int count)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	u8 src_pci_func, s_esw_id, d_esw_id;
374*4882a593Smuzhiyun 	u8 dest_pci_func;
375*4882a593Smuzhiyun 	int i, src_index, dest_index;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
378*4882a593Smuzhiyun 		src_pci_func = pm_cfg[i].pci_func;
379*4882a593Smuzhiyun 		dest_pci_func = pm_cfg[i].dest_npar;
380*4882a593Smuzhiyun 		src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
381*4882a593Smuzhiyun 		if (src_index < 0)
382*4882a593Smuzhiyun 			return -EINVAL;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
385*4882a593Smuzhiyun 		if (dest_index < 0)
386*4882a593Smuzhiyun 			return -EINVAL;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 		s_esw_id = adapter->npars[src_index].phy_port;
389*4882a593Smuzhiyun 		d_esw_id = adapter->npars[dest_index].phy_port;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		if (s_esw_id != d_esw_id)
392*4882a593Smuzhiyun 			return -EINVAL;
393*4882a593Smuzhiyun 	}
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
qlcnic_sysfs_write_pm_config(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)398*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
399*4882a593Smuzhiyun 					    struct kobject *kobj,
400*4882a593Smuzhiyun 					    struct bin_attribute *attr,
401*4882a593Smuzhiyun 					    char *buf, loff_t offset,
402*4882a593Smuzhiyun 					    size_t size)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
405*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
406*4882a593Smuzhiyun 	struct qlcnic_pm_func_cfg *pm_cfg;
407*4882a593Smuzhiyun 	u32 id, action, pci_func;
408*4882a593Smuzhiyun 	int count, rem, i, ret, index;
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	count	= size / sizeof(struct qlcnic_pm_func_cfg);
411*4882a593Smuzhiyun 	rem	= size % sizeof(struct qlcnic_pm_func_cfg);
412*4882a593Smuzhiyun 	if (rem)
413*4882a593Smuzhiyun 		return -EINVAL;
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
416*4882a593Smuzhiyun 	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
417*4882a593Smuzhiyun 	ret = validate_pm_config(adapter, pm_cfg, count);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	if (ret)
420*4882a593Smuzhiyun 		return ret;
421*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
422*4882a593Smuzhiyun 		pci_func = pm_cfg[i].pci_func;
423*4882a593Smuzhiyun 		action = !!pm_cfg[i].action;
424*4882a593Smuzhiyun 		index = qlcnic_is_valid_nic_func(adapter, pci_func);
425*4882a593Smuzhiyun 		if (index < 0)
426*4882a593Smuzhiyun 			return -EINVAL;
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 		id = adapter->npars[index].phy_port;
429*4882a593Smuzhiyun 		ret = qlcnic_config_port_mirroring(adapter, id,
430*4882a593Smuzhiyun 						   action, pci_func);
431*4882a593Smuzhiyun 		if (ret)
432*4882a593Smuzhiyun 			return ret;
433*4882a593Smuzhiyun 	}
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
436*4882a593Smuzhiyun 		pci_func = pm_cfg[i].pci_func;
437*4882a593Smuzhiyun 		index = qlcnic_is_valid_nic_func(adapter, pci_func);
438*4882a593Smuzhiyun 		if (index < 0)
439*4882a593Smuzhiyun 			return -EINVAL;
440*4882a593Smuzhiyun 		id = adapter->npars[index].phy_port;
441*4882a593Smuzhiyun 		adapter->npars[index].enable_pm = !!pm_cfg[i].action;
442*4882a593Smuzhiyun 		adapter->npars[index].dest_npar = id;
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	return size;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun 
qlcnic_sysfs_read_pm_config(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)448*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
449*4882a593Smuzhiyun 					   struct kobject *kobj,
450*4882a593Smuzhiyun 					   struct bin_attribute *attr,
451*4882a593Smuzhiyun 					   char *buf, loff_t offset,
452*4882a593Smuzhiyun 					   size_t size)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
455*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
456*4882a593Smuzhiyun 	struct qlcnic_pm_func_cfg *pm_cfg;
457*4882a593Smuzhiyun 	u8 pci_func;
458*4882a593Smuzhiyun 	u32 count;
459*4882a593Smuzhiyun 	int i;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	memset(buf, 0, size);
462*4882a593Smuzhiyun 	pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
463*4882a593Smuzhiyun 	count = size / sizeof(struct qlcnic_pm_func_cfg);
464*4882a593Smuzhiyun 	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
465*4882a593Smuzhiyun 		pci_func = adapter->npars[i].pci_func;
466*4882a593Smuzhiyun 		if (pci_func >= count) {
467*4882a593Smuzhiyun 			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
468*4882a593Smuzhiyun 				__func__, adapter->ahw->total_nic_func, count);
469*4882a593Smuzhiyun 			continue;
470*4882a593Smuzhiyun 		}
471*4882a593Smuzhiyun 		if (!adapter->npars[i].eswitch_status)
472*4882a593Smuzhiyun 			continue;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 		pm_cfg[pci_func].action = adapter->npars[i].enable_pm;
475*4882a593Smuzhiyun 		pm_cfg[pci_func].dest_npar = 0;
476*4882a593Smuzhiyun 		pm_cfg[pci_func].pci_func = i;
477*4882a593Smuzhiyun 	}
478*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
479*4882a593Smuzhiyun 	return size;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun 
validate_esw_config(struct qlcnic_adapter * adapter,struct qlcnic_esw_func_cfg * esw_cfg,int count)482*4882a593Smuzhiyun static int validate_esw_config(struct qlcnic_adapter *adapter,
483*4882a593Smuzhiyun 			       struct qlcnic_esw_func_cfg *esw_cfg, int count)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun 	struct qlcnic_hardware_context *ahw = adapter->ahw;
486*4882a593Smuzhiyun 	int i, ret;
487*4882a593Smuzhiyun 	u32 op_mode;
488*4882a593Smuzhiyun 	u8 pci_func;
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	if (qlcnic_82xx_check(adapter))
491*4882a593Smuzhiyun 		op_mode = readl(ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
492*4882a593Smuzhiyun 	else
493*4882a593Smuzhiyun 		op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
496*4882a593Smuzhiyun 		pci_func = esw_cfg[i].pci_func;
497*4882a593Smuzhiyun 		if (pci_func >= ahw->max_vnic_func)
498*4882a593Smuzhiyun 			return -EINVAL;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
501*4882a593Smuzhiyun 			if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
502*4882a593Smuzhiyun 				return -EINVAL;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 		switch (esw_cfg[i].op_mode) {
505*4882a593Smuzhiyun 		case QLCNIC_PORT_DEFAULTS:
506*4882a593Smuzhiyun 			if (qlcnic_82xx_check(adapter)) {
507*4882a593Smuzhiyun 				ret = QLC_DEV_GET_DRV(op_mode, pci_func);
508*4882a593Smuzhiyun 			} else {
509*4882a593Smuzhiyun 				ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
510*4882a593Smuzhiyun 								  pci_func);
511*4882a593Smuzhiyun 				esw_cfg[i].offload_flags = 0;
512*4882a593Smuzhiyun 			}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 			if (ret != QLCNIC_NON_PRIV_FUNC) {
515*4882a593Smuzhiyun 				if (esw_cfg[i].mac_anti_spoof != 0)
516*4882a593Smuzhiyun 					return -EINVAL;
517*4882a593Smuzhiyun 				if (esw_cfg[i].mac_override != 1)
518*4882a593Smuzhiyun 					return -EINVAL;
519*4882a593Smuzhiyun 				if (esw_cfg[i].promisc_mode != 1)
520*4882a593Smuzhiyun 					return -EINVAL;
521*4882a593Smuzhiyun 			}
522*4882a593Smuzhiyun 			break;
523*4882a593Smuzhiyun 		case QLCNIC_ADD_VLAN:
524*4882a593Smuzhiyun 			if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
525*4882a593Smuzhiyun 				return -EINVAL;
526*4882a593Smuzhiyun 			if (!esw_cfg[i].op_type)
527*4882a593Smuzhiyun 				return -EINVAL;
528*4882a593Smuzhiyun 			break;
529*4882a593Smuzhiyun 		case QLCNIC_DEL_VLAN:
530*4882a593Smuzhiyun 			if (!esw_cfg[i].op_type)
531*4882a593Smuzhiyun 				return -EINVAL;
532*4882a593Smuzhiyun 			break;
533*4882a593Smuzhiyun 		default:
534*4882a593Smuzhiyun 			return -EINVAL;
535*4882a593Smuzhiyun 		}
536*4882a593Smuzhiyun 	}
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	return 0;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun 
qlcnic_sysfs_write_esw_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)541*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
542*4882a593Smuzhiyun 					     struct kobject *kobj,
543*4882a593Smuzhiyun 					     struct bin_attribute *attr,
544*4882a593Smuzhiyun 					     char *buf, loff_t offset,
545*4882a593Smuzhiyun 					     size_t size)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
548*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
549*4882a593Smuzhiyun 	struct qlcnic_esw_func_cfg *esw_cfg;
550*4882a593Smuzhiyun 	struct qlcnic_npar_info *npar;
551*4882a593Smuzhiyun 	int count, rem, i, ret;
552*4882a593Smuzhiyun 	int index;
553*4882a593Smuzhiyun 	u8 op_mode = 0, pci_func;
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	count	= size / sizeof(struct qlcnic_esw_func_cfg);
556*4882a593Smuzhiyun 	rem	= size % sizeof(struct qlcnic_esw_func_cfg);
557*4882a593Smuzhiyun 	if (rem)
558*4882a593Smuzhiyun 		return -EINVAL;
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
561*4882a593Smuzhiyun 	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
562*4882a593Smuzhiyun 	ret = validate_esw_config(adapter, esw_cfg, count);
563*4882a593Smuzhiyun 	if (ret)
564*4882a593Smuzhiyun 		return ret;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
567*4882a593Smuzhiyun 		if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
568*4882a593Smuzhiyun 			if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
569*4882a593Smuzhiyun 				return -EINVAL;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 		if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
572*4882a593Smuzhiyun 			continue;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 		op_mode = esw_cfg[i].op_mode;
575*4882a593Smuzhiyun 		qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
576*4882a593Smuzhiyun 		esw_cfg[i].op_mode = op_mode;
577*4882a593Smuzhiyun 		esw_cfg[i].pci_func = adapter->ahw->pci_func;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 		switch (esw_cfg[i].op_mode) {
580*4882a593Smuzhiyun 		case QLCNIC_PORT_DEFAULTS:
581*4882a593Smuzhiyun 			qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
582*4882a593Smuzhiyun 			rtnl_lock();
583*4882a593Smuzhiyun 			qlcnic_set_netdev_features(adapter, &esw_cfg[i]);
584*4882a593Smuzhiyun 			rtnl_unlock();
585*4882a593Smuzhiyun 			break;
586*4882a593Smuzhiyun 		case QLCNIC_ADD_VLAN:
587*4882a593Smuzhiyun 			qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
588*4882a593Smuzhiyun 			break;
589*4882a593Smuzhiyun 		case QLCNIC_DEL_VLAN:
590*4882a593Smuzhiyun 			esw_cfg[i].vlan_id = 0;
591*4882a593Smuzhiyun 			qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
592*4882a593Smuzhiyun 			break;
593*4882a593Smuzhiyun 		}
594*4882a593Smuzhiyun 	}
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
597*4882a593Smuzhiyun 		goto out;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
600*4882a593Smuzhiyun 		pci_func = esw_cfg[i].pci_func;
601*4882a593Smuzhiyun 		index = qlcnic_is_valid_nic_func(adapter, pci_func);
602*4882a593Smuzhiyun 		if (index < 0)
603*4882a593Smuzhiyun 			return -EINVAL;
604*4882a593Smuzhiyun 		npar = &adapter->npars[index];
605*4882a593Smuzhiyun 		switch (esw_cfg[i].op_mode) {
606*4882a593Smuzhiyun 		case QLCNIC_PORT_DEFAULTS:
607*4882a593Smuzhiyun 			npar->promisc_mode = esw_cfg[i].promisc_mode;
608*4882a593Smuzhiyun 			npar->mac_override = esw_cfg[i].mac_override;
609*4882a593Smuzhiyun 			npar->offload_flags = esw_cfg[i].offload_flags;
610*4882a593Smuzhiyun 			npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
611*4882a593Smuzhiyun 			npar->discard_tagged = esw_cfg[i].discard_tagged;
612*4882a593Smuzhiyun 			break;
613*4882a593Smuzhiyun 		case QLCNIC_ADD_VLAN:
614*4882a593Smuzhiyun 			npar->pvid = esw_cfg[i].vlan_id;
615*4882a593Smuzhiyun 			break;
616*4882a593Smuzhiyun 		case QLCNIC_DEL_VLAN:
617*4882a593Smuzhiyun 			npar->pvid = 0;
618*4882a593Smuzhiyun 			break;
619*4882a593Smuzhiyun 		}
620*4882a593Smuzhiyun 	}
621*4882a593Smuzhiyun out:
622*4882a593Smuzhiyun 	return size;
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun 
qlcnic_sysfs_read_esw_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)625*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
626*4882a593Smuzhiyun 					    struct kobject *kobj,
627*4882a593Smuzhiyun 					    struct bin_attribute *attr,
628*4882a593Smuzhiyun 					    char *buf, loff_t offset,
629*4882a593Smuzhiyun 					    size_t size)
630*4882a593Smuzhiyun {
631*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
632*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
633*4882a593Smuzhiyun 	struct qlcnic_esw_func_cfg *esw_cfg;
634*4882a593Smuzhiyun 	u8 pci_func;
635*4882a593Smuzhiyun 	u32 count;
636*4882a593Smuzhiyun 	int i;
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	memset(buf, 0, size);
639*4882a593Smuzhiyun 	esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
640*4882a593Smuzhiyun 	count = size / sizeof(struct qlcnic_esw_func_cfg);
641*4882a593Smuzhiyun 	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
642*4882a593Smuzhiyun 		pci_func = adapter->npars[i].pci_func;
643*4882a593Smuzhiyun 		if (pci_func >= count) {
644*4882a593Smuzhiyun 			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
645*4882a593Smuzhiyun 				__func__, adapter->ahw->total_nic_func, count);
646*4882a593Smuzhiyun 			continue;
647*4882a593Smuzhiyun 		}
648*4882a593Smuzhiyun 		if (!adapter->npars[i].eswitch_status)
649*4882a593Smuzhiyun 			continue;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 		esw_cfg[pci_func].pci_func = pci_func;
652*4882a593Smuzhiyun 		if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
653*4882a593Smuzhiyun 			return -EINVAL;
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
656*4882a593Smuzhiyun 	return size;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun 
validate_npar_config(struct qlcnic_adapter * adapter,struct qlcnic_npar_func_cfg * np_cfg,int count)659*4882a593Smuzhiyun static int validate_npar_config(struct qlcnic_adapter *adapter,
660*4882a593Smuzhiyun 				struct qlcnic_npar_func_cfg *np_cfg,
661*4882a593Smuzhiyun 				int count)
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun 	u8 pci_func, i;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
666*4882a593Smuzhiyun 		pci_func = np_cfg[i].pci_func;
667*4882a593Smuzhiyun 		if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
668*4882a593Smuzhiyun 			return -EINVAL;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 		if (!IS_VALID_BW(np_cfg[i].min_bw) ||
671*4882a593Smuzhiyun 		    !IS_VALID_BW(np_cfg[i].max_bw))
672*4882a593Smuzhiyun 			return -EINVAL;
673*4882a593Smuzhiyun 	}
674*4882a593Smuzhiyun 	return 0;
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
qlcnic_sysfs_write_npar_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)677*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
678*4882a593Smuzhiyun 					      struct kobject *kobj,
679*4882a593Smuzhiyun 					      struct bin_attribute *attr,
680*4882a593Smuzhiyun 					      char *buf, loff_t offset,
681*4882a593Smuzhiyun 					      size_t size)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
684*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
685*4882a593Smuzhiyun 	struct qlcnic_info nic_info;
686*4882a593Smuzhiyun 	struct qlcnic_npar_func_cfg *np_cfg;
687*4882a593Smuzhiyun 	int i, count, rem, ret, index;
688*4882a593Smuzhiyun 	u8 pci_func;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	count	= size / sizeof(struct qlcnic_npar_func_cfg);
691*4882a593Smuzhiyun 	rem	= size % sizeof(struct qlcnic_npar_func_cfg);
692*4882a593Smuzhiyun 	if (rem)
693*4882a593Smuzhiyun 		return -EINVAL;
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
696*4882a593Smuzhiyun 	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
697*4882a593Smuzhiyun 	ret = validate_npar_config(adapter, np_cfg, count);
698*4882a593Smuzhiyun 	if (ret)
699*4882a593Smuzhiyun 		return ret;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
702*4882a593Smuzhiyun 		pci_func = np_cfg[i].pci_func;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 		memset(&nic_info, 0, sizeof(struct qlcnic_info));
705*4882a593Smuzhiyun 		ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
706*4882a593Smuzhiyun 		if (ret)
707*4882a593Smuzhiyun 			return ret;
708*4882a593Smuzhiyun 		nic_info.pci_func = pci_func;
709*4882a593Smuzhiyun 		nic_info.min_tx_bw = np_cfg[i].min_bw;
710*4882a593Smuzhiyun 		nic_info.max_tx_bw = np_cfg[i].max_bw;
711*4882a593Smuzhiyun 		ret = qlcnic_set_nic_info(adapter, &nic_info);
712*4882a593Smuzhiyun 		if (ret)
713*4882a593Smuzhiyun 			return ret;
714*4882a593Smuzhiyun 		index = qlcnic_is_valid_nic_func(adapter, pci_func);
715*4882a593Smuzhiyun 		if (index < 0)
716*4882a593Smuzhiyun 			return -EINVAL;
717*4882a593Smuzhiyun 		adapter->npars[index].min_bw = nic_info.min_tx_bw;
718*4882a593Smuzhiyun 		adapter->npars[index].max_bw = nic_info.max_tx_bw;
719*4882a593Smuzhiyun 	}
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	return size;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun 
qlcnic_sysfs_read_npar_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)724*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
725*4882a593Smuzhiyun 					     struct kobject *kobj,
726*4882a593Smuzhiyun 					     struct bin_attribute *attr,
727*4882a593Smuzhiyun 					     char *buf, loff_t offset,
728*4882a593Smuzhiyun 					     size_t size)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
731*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
732*4882a593Smuzhiyun 	struct qlcnic_npar_func_cfg *np_cfg;
733*4882a593Smuzhiyun 	struct qlcnic_info nic_info;
734*4882a593Smuzhiyun 	u8 pci_func;
735*4882a593Smuzhiyun 	int i, ret;
736*4882a593Smuzhiyun 	u32 count;
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun 	memset(&nic_info, 0, sizeof(struct qlcnic_info));
739*4882a593Smuzhiyun 	memset(buf, 0, size);
740*4882a593Smuzhiyun 	np_cfg = (struct qlcnic_npar_func_cfg *)buf;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	count = size / sizeof(struct qlcnic_npar_func_cfg);
743*4882a593Smuzhiyun 	for (i = 0; i < adapter->ahw->total_nic_func; i++) {
744*4882a593Smuzhiyun 		if (adapter->npars[i].pci_func >= count) {
745*4882a593Smuzhiyun 			dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n",
746*4882a593Smuzhiyun 				__func__, adapter->ahw->total_nic_func, count);
747*4882a593Smuzhiyun 			continue;
748*4882a593Smuzhiyun 		}
749*4882a593Smuzhiyun 		if (!adapter->npars[i].eswitch_status)
750*4882a593Smuzhiyun 			continue;
751*4882a593Smuzhiyun 		pci_func = adapter->npars[i].pci_func;
752*4882a593Smuzhiyun 		if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
753*4882a593Smuzhiyun 			continue;
754*4882a593Smuzhiyun 		ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
755*4882a593Smuzhiyun 		if (ret)
756*4882a593Smuzhiyun 			return ret;
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 		np_cfg[pci_func].pci_func = pci_func;
759*4882a593Smuzhiyun 		np_cfg[pci_func].op_mode = (u8)nic_info.op_mode;
760*4882a593Smuzhiyun 		np_cfg[pci_func].port_num = nic_info.phys_port;
761*4882a593Smuzhiyun 		np_cfg[pci_func].fw_capab = nic_info.capabilities;
762*4882a593Smuzhiyun 		np_cfg[pci_func].min_bw = nic_info.min_tx_bw;
763*4882a593Smuzhiyun 		np_cfg[pci_func].max_bw = nic_info.max_tx_bw;
764*4882a593Smuzhiyun 		np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques;
765*4882a593Smuzhiyun 		np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques;
766*4882a593Smuzhiyun 	}
767*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
768*4882a593Smuzhiyun 	return size;
769*4882a593Smuzhiyun }
770*4882a593Smuzhiyun 
qlcnic_sysfs_get_port_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)771*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
772*4882a593Smuzhiyun 					   struct kobject *kobj,
773*4882a593Smuzhiyun 					   struct bin_attribute *attr,
774*4882a593Smuzhiyun 					   char *buf, loff_t offset,
775*4882a593Smuzhiyun 					   size_t size)
776*4882a593Smuzhiyun {
777*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
778*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
779*4882a593Smuzhiyun 	struct qlcnic_esw_statistics port_stats;
780*4882a593Smuzhiyun 	int ret;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	if (qlcnic_83xx_check(adapter))
783*4882a593Smuzhiyun 		return -EOPNOTSUPP;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	if (size != sizeof(struct qlcnic_esw_statistics))
786*4882a593Smuzhiyun 		return -EINVAL;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun 	if (offset >= adapter->ahw->max_vnic_func)
789*4882a593Smuzhiyun 		return -EINVAL;
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 	memset(&port_stats, 0, size);
792*4882a593Smuzhiyun 	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
793*4882a593Smuzhiyun 				    &port_stats.rx);
794*4882a593Smuzhiyun 	if (ret)
795*4882a593Smuzhiyun 		return ret;
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
798*4882a593Smuzhiyun 				    &port_stats.tx);
799*4882a593Smuzhiyun 	if (ret)
800*4882a593Smuzhiyun 		return ret;
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	memcpy(buf, &port_stats, size);
803*4882a593Smuzhiyun 	return size;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun 
qlcnic_sysfs_get_esw_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)806*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
807*4882a593Smuzhiyun 					  struct kobject *kobj,
808*4882a593Smuzhiyun 					  struct bin_attribute *attr,
809*4882a593Smuzhiyun 					  char *buf, loff_t offset,
810*4882a593Smuzhiyun 					  size_t size)
811*4882a593Smuzhiyun {
812*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
813*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
814*4882a593Smuzhiyun 	struct qlcnic_esw_statistics esw_stats;
815*4882a593Smuzhiyun 	int ret;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	if (qlcnic_83xx_check(adapter))
818*4882a593Smuzhiyun 		return -EOPNOTSUPP;
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun 	if (size != sizeof(struct qlcnic_esw_statistics))
821*4882a593Smuzhiyun 		return -EINVAL;
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
824*4882a593Smuzhiyun 		return -EINVAL;
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun 	memset(&esw_stats, 0, size);
827*4882a593Smuzhiyun 	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
828*4882a593Smuzhiyun 				       &esw_stats.rx);
829*4882a593Smuzhiyun 	if (ret)
830*4882a593Smuzhiyun 		return ret;
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
833*4882a593Smuzhiyun 				       &esw_stats.tx);
834*4882a593Smuzhiyun 	if (ret)
835*4882a593Smuzhiyun 		return ret;
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun 	memcpy(buf, &esw_stats, size);
838*4882a593Smuzhiyun 	return size;
839*4882a593Smuzhiyun }
840*4882a593Smuzhiyun 
qlcnic_sysfs_clear_esw_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)841*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
842*4882a593Smuzhiyun 					    struct kobject *kobj,
843*4882a593Smuzhiyun 					    struct bin_attribute *attr,
844*4882a593Smuzhiyun 					    char *buf, loff_t offset,
845*4882a593Smuzhiyun 					    size_t size)
846*4882a593Smuzhiyun {
847*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
848*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
849*4882a593Smuzhiyun 	int ret;
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	if (qlcnic_83xx_check(adapter))
852*4882a593Smuzhiyun 		return -EOPNOTSUPP;
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
855*4882a593Smuzhiyun 		return -EINVAL;
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
858*4882a593Smuzhiyun 				     QLCNIC_QUERY_RX_COUNTER);
859*4882a593Smuzhiyun 	if (ret)
860*4882a593Smuzhiyun 		return ret;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
863*4882a593Smuzhiyun 				     QLCNIC_QUERY_TX_COUNTER);
864*4882a593Smuzhiyun 	if (ret)
865*4882a593Smuzhiyun 		return ret;
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	return size;
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun 
qlcnic_sysfs_clear_port_stats(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)870*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
871*4882a593Smuzhiyun 					     struct kobject *kobj,
872*4882a593Smuzhiyun 					     struct bin_attribute *attr,
873*4882a593Smuzhiyun 					     char *buf, loff_t offset,
874*4882a593Smuzhiyun 					     size_t size)
875*4882a593Smuzhiyun {
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
878*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
879*4882a593Smuzhiyun 	int ret;
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	if (qlcnic_83xx_check(adapter))
882*4882a593Smuzhiyun 		return -EOPNOTSUPP;
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun 	if (offset >= adapter->ahw->max_vnic_func)
885*4882a593Smuzhiyun 		return -EINVAL;
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun 	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
888*4882a593Smuzhiyun 				     QLCNIC_QUERY_RX_COUNTER);
889*4882a593Smuzhiyun 	if (ret)
890*4882a593Smuzhiyun 		return ret;
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun 	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
893*4882a593Smuzhiyun 				     QLCNIC_QUERY_TX_COUNTER);
894*4882a593Smuzhiyun 	if (ret)
895*4882a593Smuzhiyun 		return ret;
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	return size;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun 
qlcnic_sysfs_read_pci_config(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)900*4882a593Smuzhiyun static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
901*4882a593Smuzhiyun 					    struct kobject *kobj,
902*4882a593Smuzhiyun 					    struct bin_attribute *attr,
903*4882a593Smuzhiyun 					    char *buf, loff_t offset,
904*4882a593Smuzhiyun 					    size_t size)
905*4882a593Smuzhiyun {
906*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
907*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
908*4882a593Smuzhiyun 	struct qlcnic_pci_func_cfg *pci_cfg;
909*4882a593Smuzhiyun 	struct qlcnic_pci_info *pci_info;
910*4882a593Smuzhiyun 	int i, ret;
911*4882a593Smuzhiyun 	u32 count;
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	pci_info = kcalloc(size, sizeof(*pci_info), GFP_KERNEL);
914*4882a593Smuzhiyun 	if (!pci_info)
915*4882a593Smuzhiyun 		return -ENOMEM;
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun 	ret = qlcnic_get_pci_info(adapter, pci_info);
918*4882a593Smuzhiyun 	if (ret) {
919*4882a593Smuzhiyun 		kfree(pci_info);
920*4882a593Smuzhiyun 		return ret;
921*4882a593Smuzhiyun 	}
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun 	pci_cfg = (struct qlcnic_pci_func_cfg *)buf;
924*4882a593Smuzhiyun 	count = size / sizeof(struct qlcnic_pci_func_cfg);
925*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)pci_info, size / sizeof(u32));
926*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
927*4882a593Smuzhiyun 		pci_cfg[i].pci_func = pci_info[i].id;
928*4882a593Smuzhiyun 		pci_cfg[i].func_type = pci_info[i].type;
929*4882a593Smuzhiyun 		pci_cfg[i].func_state = 0;
930*4882a593Smuzhiyun 		pci_cfg[i].port_num = pci_info[i].default_port;
931*4882a593Smuzhiyun 		pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
932*4882a593Smuzhiyun 		pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
933*4882a593Smuzhiyun 		memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
934*4882a593Smuzhiyun 	}
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	kfree(pci_info);
937*4882a593Smuzhiyun 	return size;
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun 
qlcnic_83xx_sysfs_flash_read_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)940*4882a593Smuzhiyun static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
941*4882a593Smuzhiyun 						    struct kobject *kobj,
942*4882a593Smuzhiyun 						    struct bin_attribute *attr,
943*4882a593Smuzhiyun 						    char *buf, loff_t offset,
944*4882a593Smuzhiyun 						    size_t size)
945*4882a593Smuzhiyun {
946*4882a593Smuzhiyun 	unsigned char *p_read_buf;
947*4882a593Smuzhiyun 	int  ret, count;
948*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
949*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	if (!size)
952*4882a593Smuzhiyun 		return -EINVAL;
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	count = size / sizeof(u32);
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	if (size % sizeof(u32))
957*4882a593Smuzhiyun 		count++;
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun 	p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
960*4882a593Smuzhiyun 	if (!p_read_buf)
961*4882a593Smuzhiyun 		return -ENOMEM;
962*4882a593Smuzhiyun 	if (qlcnic_83xx_lock_flash(adapter) != 0) {
963*4882a593Smuzhiyun 		kfree(p_read_buf);
964*4882a593Smuzhiyun 		return -EIO;
965*4882a593Smuzhiyun 	}
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf,
968*4882a593Smuzhiyun 						count);
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 	if (ret) {
971*4882a593Smuzhiyun 		qlcnic_83xx_unlock_flash(adapter);
972*4882a593Smuzhiyun 		kfree(p_read_buf);
973*4882a593Smuzhiyun 		return ret;
974*4882a593Smuzhiyun 	}
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun 	qlcnic_83xx_unlock_flash(adapter);
977*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)p_read_buf, count);
978*4882a593Smuzhiyun 	memcpy(buf, p_read_buf, size);
979*4882a593Smuzhiyun 	kfree(p_read_buf);
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun 	return size;
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun 
qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter * adapter,char * buf,loff_t offset,size_t size)984*4882a593Smuzhiyun static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
985*4882a593Smuzhiyun 					      char *buf, loff_t offset,
986*4882a593Smuzhiyun 					      size_t size)
987*4882a593Smuzhiyun {
988*4882a593Smuzhiyun 	int  i, ret, count;
989*4882a593Smuzhiyun 	unsigned char *p_cache, *p_src;
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
992*4882a593Smuzhiyun 	if (!p_cache)
993*4882a593Smuzhiyun 		return -ENOMEM;
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	count = size / sizeof(u32);
996*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, count);
997*4882a593Smuzhiyun 	memcpy(p_cache, buf, size);
998*4882a593Smuzhiyun 	p_src = p_cache;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	if (qlcnic_83xx_lock_flash(adapter) != 0) {
1001*4882a593Smuzhiyun 		kfree(p_cache);
1002*4882a593Smuzhiyun 		return -EIO;
1003*4882a593Smuzhiyun 	}
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun 	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1006*4882a593Smuzhiyun 		ret = qlcnic_83xx_enable_flash_write(adapter);
1007*4882a593Smuzhiyun 		if (ret) {
1008*4882a593Smuzhiyun 			kfree(p_cache);
1009*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1010*4882a593Smuzhiyun 			return -EIO;
1011*4882a593Smuzhiyun 		}
1012*4882a593Smuzhiyun 	}
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) {
1015*4882a593Smuzhiyun 		ret = qlcnic_83xx_flash_bulk_write(adapter, offset,
1016*4882a593Smuzhiyun 						   (u32 *)p_src,
1017*4882a593Smuzhiyun 						   QLC_83XX_FLASH_WRITE_MAX);
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 		if (ret) {
1020*4882a593Smuzhiyun 			if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1021*4882a593Smuzhiyun 				ret = qlcnic_83xx_disable_flash_write(adapter);
1022*4882a593Smuzhiyun 				if (ret) {
1023*4882a593Smuzhiyun 					kfree(p_cache);
1024*4882a593Smuzhiyun 					qlcnic_83xx_unlock_flash(adapter);
1025*4882a593Smuzhiyun 					return -EIO;
1026*4882a593Smuzhiyun 				}
1027*4882a593Smuzhiyun 			}
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 			kfree(p_cache);
1030*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1031*4882a593Smuzhiyun 			return -EIO;
1032*4882a593Smuzhiyun 		}
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 		p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
1035*4882a593Smuzhiyun 		offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
1036*4882a593Smuzhiyun 	}
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1039*4882a593Smuzhiyun 		ret = qlcnic_83xx_disable_flash_write(adapter);
1040*4882a593Smuzhiyun 		if (ret) {
1041*4882a593Smuzhiyun 			kfree(p_cache);
1042*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1043*4882a593Smuzhiyun 			return -EIO;
1044*4882a593Smuzhiyun 		}
1045*4882a593Smuzhiyun 	}
1046*4882a593Smuzhiyun 
1047*4882a593Smuzhiyun 	kfree(p_cache);
1048*4882a593Smuzhiyun 	qlcnic_83xx_unlock_flash(adapter);
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun 	return 0;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun 
qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter * adapter,char * buf,loff_t offset,size_t size)1053*4882a593Smuzhiyun static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
1054*4882a593Smuzhiyun 					 char *buf, loff_t offset, size_t size)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun 	int  i, ret, count;
1057*4882a593Smuzhiyun 	unsigned char *p_cache, *p_src;
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
1060*4882a593Smuzhiyun 	if (!p_cache)
1061*4882a593Smuzhiyun 		return -ENOMEM;
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	qlcnic_swap32_buffer((u32 *)buf, size / sizeof(u32));
1064*4882a593Smuzhiyun 	memcpy(p_cache, buf, size);
1065*4882a593Smuzhiyun 	p_src = p_cache;
1066*4882a593Smuzhiyun 	count = size / sizeof(u32);
1067*4882a593Smuzhiyun 
1068*4882a593Smuzhiyun 	if (qlcnic_83xx_lock_flash(adapter) != 0) {
1069*4882a593Smuzhiyun 		kfree(p_cache);
1070*4882a593Smuzhiyun 		return -EIO;
1071*4882a593Smuzhiyun 	}
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1074*4882a593Smuzhiyun 		ret = qlcnic_83xx_enable_flash_write(adapter);
1075*4882a593Smuzhiyun 		if (ret) {
1076*4882a593Smuzhiyun 			kfree(p_cache);
1077*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1078*4882a593Smuzhiyun 			return -EIO;
1079*4882a593Smuzhiyun 		}
1080*4882a593Smuzhiyun 	}
1081*4882a593Smuzhiyun 
1082*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
1083*4882a593Smuzhiyun 		ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src);
1084*4882a593Smuzhiyun 		if (ret) {
1085*4882a593Smuzhiyun 			if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1086*4882a593Smuzhiyun 				ret = qlcnic_83xx_disable_flash_write(adapter);
1087*4882a593Smuzhiyun 				if (ret) {
1088*4882a593Smuzhiyun 					kfree(p_cache);
1089*4882a593Smuzhiyun 					qlcnic_83xx_unlock_flash(adapter);
1090*4882a593Smuzhiyun 					return -EIO;
1091*4882a593Smuzhiyun 				}
1092*4882a593Smuzhiyun 			}
1093*4882a593Smuzhiyun 			kfree(p_cache);
1094*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1095*4882a593Smuzhiyun 			return -EIO;
1096*4882a593Smuzhiyun 		}
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 		p_src = p_src + sizeof(u32);
1099*4882a593Smuzhiyun 		offset = offset + sizeof(u32);
1100*4882a593Smuzhiyun 	}
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun 	if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1103*4882a593Smuzhiyun 		ret = qlcnic_83xx_disable_flash_write(adapter);
1104*4882a593Smuzhiyun 		if (ret) {
1105*4882a593Smuzhiyun 			kfree(p_cache);
1106*4882a593Smuzhiyun 			qlcnic_83xx_unlock_flash(adapter);
1107*4882a593Smuzhiyun 			return -EIO;
1108*4882a593Smuzhiyun 		}
1109*4882a593Smuzhiyun 	}
1110*4882a593Smuzhiyun 
1111*4882a593Smuzhiyun 	kfree(p_cache);
1112*4882a593Smuzhiyun 	qlcnic_83xx_unlock_flash(adapter);
1113*4882a593Smuzhiyun 
1114*4882a593Smuzhiyun 	return 0;
1115*4882a593Smuzhiyun }
1116*4882a593Smuzhiyun 
qlcnic_83xx_sysfs_flash_write_handler(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t offset,size_t size)1117*4882a593Smuzhiyun static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
1118*4882a593Smuzhiyun 						     struct kobject *kobj,
1119*4882a593Smuzhiyun 						     struct bin_attribute *attr,
1120*4882a593Smuzhiyun 						     char *buf, loff_t offset,
1121*4882a593Smuzhiyun 						     size_t size)
1122*4882a593Smuzhiyun {
1123*4882a593Smuzhiyun 	int  ret;
1124*4882a593Smuzhiyun 	static int flash_mode;
1125*4882a593Smuzhiyun 	unsigned long data;
1126*4882a593Smuzhiyun 	struct device *dev = kobj_to_dev(kobj);
1127*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	ret = kstrtoul(buf, 16, &data);
1130*4882a593Smuzhiyun 	if (ret)
1131*4882a593Smuzhiyun 		return ret;
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	switch (data) {
1134*4882a593Smuzhiyun 	case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
1135*4882a593Smuzhiyun 		flash_mode = QLC_83XX_ERASE_MODE;
1136*4882a593Smuzhiyun 		ret = qlcnic_83xx_erase_flash_sector(adapter, offset);
1137*4882a593Smuzhiyun 		if (ret) {
1138*4882a593Smuzhiyun 			dev_err(&adapter->pdev->dev,
1139*4882a593Smuzhiyun 				"%s failed at %d\n", __func__, __LINE__);
1140*4882a593Smuzhiyun 			return -EIO;
1141*4882a593Smuzhiyun 		}
1142*4882a593Smuzhiyun 		break;
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun 	case QLC_83XX_FLASH_BULK_WRITE_CMD:
1145*4882a593Smuzhiyun 		flash_mode = QLC_83XX_BULK_WRITE_MODE;
1146*4882a593Smuzhiyun 		break;
1147*4882a593Smuzhiyun 
1148*4882a593Smuzhiyun 	case QLC_83XX_FLASH_WRITE_CMD:
1149*4882a593Smuzhiyun 		flash_mode = QLC_83XX_WRITE_MODE;
1150*4882a593Smuzhiyun 		break;
1151*4882a593Smuzhiyun 	default:
1152*4882a593Smuzhiyun 		if (flash_mode == QLC_83XX_BULK_WRITE_MODE) {
1153*4882a593Smuzhiyun 			ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf,
1154*4882a593Smuzhiyun 								 offset, size);
1155*4882a593Smuzhiyun 			if (ret) {
1156*4882a593Smuzhiyun 				dev_err(&adapter->pdev->dev,
1157*4882a593Smuzhiyun 					"%s failed at %d\n",
1158*4882a593Smuzhiyun 					__func__, __LINE__);
1159*4882a593Smuzhiyun 				return -EIO;
1160*4882a593Smuzhiyun 			}
1161*4882a593Smuzhiyun 		}
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 		if (flash_mode == QLC_83XX_WRITE_MODE) {
1164*4882a593Smuzhiyun 			ret = qlcnic_83xx_sysfs_flash_write(adapter, buf,
1165*4882a593Smuzhiyun 							    offset, size);
1166*4882a593Smuzhiyun 			if (ret) {
1167*4882a593Smuzhiyun 				dev_err(&adapter->pdev->dev,
1168*4882a593Smuzhiyun 					"%s failed at %d\n", __func__,
1169*4882a593Smuzhiyun 					__LINE__);
1170*4882a593Smuzhiyun 				return -EIO;
1171*4882a593Smuzhiyun 			}
1172*4882a593Smuzhiyun 		}
1173*4882a593Smuzhiyun 	}
1174*4882a593Smuzhiyun 
1175*4882a593Smuzhiyun 	return size;
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun static const struct device_attribute dev_attr_bridged_mode = {
1179*4882a593Smuzhiyun 	.attr = { .name = "bridged_mode", .mode = 0644 },
1180*4882a593Smuzhiyun 	.show = qlcnic_show_bridged_mode,
1181*4882a593Smuzhiyun 	.store = qlcnic_store_bridged_mode,
1182*4882a593Smuzhiyun };
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun static const struct device_attribute dev_attr_diag_mode = {
1185*4882a593Smuzhiyun 	.attr = { .name = "diag_mode", .mode = 0644 },
1186*4882a593Smuzhiyun 	.show = qlcnic_show_diag_mode,
1187*4882a593Smuzhiyun 	.store = qlcnic_store_diag_mode,
1188*4882a593Smuzhiyun };
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun static const struct device_attribute dev_attr_beacon = {
1191*4882a593Smuzhiyun 	.attr = { .name = "beacon", .mode = 0644 },
1192*4882a593Smuzhiyun 	.show = qlcnic_show_beacon,
1193*4882a593Smuzhiyun 	.store = qlcnic_store_beacon,
1194*4882a593Smuzhiyun };
1195*4882a593Smuzhiyun 
1196*4882a593Smuzhiyun static const struct bin_attribute bin_attr_crb = {
1197*4882a593Smuzhiyun 	.attr = { .name = "crb", .mode = 0644 },
1198*4882a593Smuzhiyun 	.size = 0,
1199*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_crb,
1200*4882a593Smuzhiyun 	.write = qlcnic_sysfs_write_crb,
1201*4882a593Smuzhiyun };
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun static const struct bin_attribute bin_attr_mem = {
1204*4882a593Smuzhiyun 	.attr = { .name = "mem", .mode = 0644 },
1205*4882a593Smuzhiyun 	.size = 0,
1206*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_mem,
1207*4882a593Smuzhiyun 	.write = qlcnic_sysfs_write_mem,
1208*4882a593Smuzhiyun };
1209*4882a593Smuzhiyun 
1210*4882a593Smuzhiyun static const struct bin_attribute bin_attr_npar_config = {
1211*4882a593Smuzhiyun 	.attr = { .name = "npar_config", .mode = 0644 },
1212*4882a593Smuzhiyun 	.size = 0,
1213*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_npar_config,
1214*4882a593Smuzhiyun 	.write = qlcnic_sysfs_write_npar_config,
1215*4882a593Smuzhiyun };
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun static const struct bin_attribute bin_attr_pci_config = {
1218*4882a593Smuzhiyun 	.attr = { .name = "pci_config", .mode = 0644 },
1219*4882a593Smuzhiyun 	.size = 0,
1220*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_pci_config,
1221*4882a593Smuzhiyun 	.write = NULL,
1222*4882a593Smuzhiyun };
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun static const struct bin_attribute bin_attr_port_stats = {
1225*4882a593Smuzhiyun 	.attr = { .name = "port_stats", .mode = 0644 },
1226*4882a593Smuzhiyun 	.size = 0,
1227*4882a593Smuzhiyun 	.read = qlcnic_sysfs_get_port_stats,
1228*4882a593Smuzhiyun 	.write = qlcnic_sysfs_clear_port_stats,
1229*4882a593Smuzhiyun };
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun static const struct bin_attribute bin_attr_esw_stats = {
1232*4882a593Smuzhiyun 	.attr = { .name = "esw_stats", .mode = 0644 },
1233*4882a593Smuzhiyun 	.size = 0,
1234*4882a593Smuzhiyun 	.read = qlcnic_sysfs_get_esw_stats,
1235*4882a593Smuzhiyun 	.write = qlcnic_sysfs_clear_esw_stats,
1236*4882a593Smuzhiyun };
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun static const struct bin_attribute bin_attr_esw_config = {
1239*4882a593Smuzhiyun 	.attr = { .name = "esw_config", .mode = 0644 },
1240*4882a593Smuzhiyun 	.size = 0,
1241*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_esw_config,
1242*4882a593Smuzhiyun 	.write = qlcnic_sysfs_write_esw_config,
1243*4882a593Smuzhiyun };
1244*4882a593Smuzhiyun 
1245*4882a593Smuzhiyun static const struct bin_attribute bin_attr_pm_config = {
1246*4882a593Smuzhiyun 	.attr = { .name = "pm_config", .mode = 0644 },
1247*4882a593Smuzhiyun 	.size = 0,
1248*4882a593Smuzhiyun 	.read = qlcnic_sysfs_read_pm_config,
1249*4882a593Smuzhiyun 	.write = qlcnic_sysfs_write_pm_config,
1250*4882a593Smuzhiyun };
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun static const struct bin_attribute bin_attr_flash = {
1253*4882a593Smuzhiyun 	.attr = { .name = "flash", .mode = 0644 },
1254*4882a593Smuzhiyun 	.size = 0,
1255*4882a593Smuzhiyun 	.read = qlcnic_83xx_sysfs_flash_read_handler,
1256*4882a593Smuzhiyun 	.write = qlcnic_83xx_sysfs_flash_write_handler,
1257*4882a593Smuzhiyun };
1258*4882a593Smuzhiyun 
1259*4882a593Smuzhiyun #ifdef CONFIG_QLCNIC_HWMON
1260*4882a593Smuzhiyun 
qlcnic_hwmon_show_temp(struct device * dev,struct device_attribute * dev_attr,char * buf)1261*4882a593Smuzhiyun static ssize_t qlcnic_hwmon_show_temp(struct device *dev,
1262*4882a593Smuzhiyun 				      struct device_attribute *dev_attr,
1263*4882a593Smuzhiyun 				      char *buf)
1264*4882a593Smuzhiyun {
1265*4882a593Smuzhiyun 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
1266*4882a593Smuzhiyun 	unsigned int temperature = 0, value = 0;
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 	if (qlcnic_83xx_check(adapter))
1269*4882a593Smuzhiyun 		value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP);
1270*4882a593Smuzhiyun 	else if (qlcnic_82xx_check(adapter))
1271*4882a593Smuzhiyun 		value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP);
1272*4882a593Smuzhiyun 
1273*4882a593Smuzhiyun 	temperature = qlcnic_get_temp_val(value);
1274*4882a593Smuzhiyun 	/* display millidegree celcius */
1275*4882a593Smuzhiyun 	temperature *= 1000;
1276*4882a593Smuzhiyun 	return sprintf(buf, "%u\n", temperature);
1277*4882a593Smuzhiyun }
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun /* hwmon-sysfs attributes */
1280*4882a593Smuzhiyun static SENSOR_DEVICE_ATTR(temp1_input, 0444,
1281*4882a593Smuzhiyun 			  qlcnic_hwmon_show_temp, NULL, 1);
1282*4882a593Smuzhiyun 
1283*4882a593Smuzhiyun static struct attribute *qlcnic_hwmon_attrs[] = {
1284*4882a593Smuzhiyun 	&sensor_dev_attr_temp1_input.dev_attr.attr,
1285*4882a593Smuzhiyun 	NULL
1286*4882a593Smuzhiyun };
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun ATTRIBUTE_GROUPS(qlcnic_hwmon);
1289*4882a593Smuzhiyun 
qlcnic_register_hwmon_dev(struct qlcnic_adapter * adapter)1290*4882a593Smuzhiyun void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
1291*4882a593Smuzhiyun {
1292*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1293*4882a593Smuzhiyun 	struct device *hwmon_dev;
1294*4882a593Smuzhiyun 
1295*4882a593Smuzhiyun 	/* Skip hwmon registration for a VF device */
1296*4882a593Smuzhiyun 	if (qlcnic_sriov_vf_check(adapter)) {
1297*4882a593Smuzhiyun 		adapter->ahw->hwmon_dev = NULL;
1298*4882a593Smuzhiyun 		return;
1299*4882a593Smuzhiyun 	}
1300*4882a593Smuzhiyun 	hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name,
1301*4882a593Smuzhiyun 						      adapter,
1302*4882a593Smuzhiyun 						      qlcnic_hwmon_groups);
1303*4882a593Smuzhiyun 	if (IS_ERR(hwmon_dev)) {
1304*4882a593Smuzhiyun 		dev_err(dev, "Cannot register with hwmon, err=%ld\n",
1305*4882a593Smuzhiyun 			PTR_ERR(hwmon_dev));
1306*4882a593Smuzhiyun 		hwmon_dev = NULL;
1307*4882a593Smuzhiyun 	}
1308*4882a593Smuzhiyun 	adapter->ahw->hwmon_dev = hwmon_dev;
1309*4882a593Smuzhiyun }
1310*4882a593Smuzhiyun 
qlcnic_unregister_hwmon_dev(struct qlcnic_adapter * adapter)1311*4882a593Smuzhiyun void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
1312*4882a593Smuzhiyun {
1313*4882a593Smuzhiyun 	struct device *hwmon_dev = adapter->ahw->hwmon_dev;
1314*4882a593Smuzhiyun 	if (hwmon_dev) {
1315*4882a593Smuzhiyun 		hwmon_device_unregister(hwmon_dev);
1316*4882a593Smuzhiyun 		adapter->ahw->hwmon_dev = NULL;
1317*4882a593Smuzhiyun 	}
1318*4882a593Smuzhiyun }
1319*4882a593Smuzhiyun #endif
1320*4882a593Smuzhiyun 
qlcnic_create_sysfs_entries(struct qlcnic_adapter * adapter)1321*4882a593Smuzhiyun void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
1322*4882a593Smuzhiyun {
1323*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun 	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
1326*4882a593Smuzhiyun 		if (device_create_file(dev, &dev_attr_bridged_mode))
1327*4882a593Smuzhiyun 			dev_warn(dev,
1328*4882a593Smuzhiyun 				 "failed to create bridged_mode sysfs entry\n");
1329*4882a593Smuzhiyun }
1330*4882a593Smuzhiyun 
qlcnic_remove_sysfs_entries(struct qlcnic_adapter * adapter)1331*4882a593Smuzhiyun void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
1332*4882a593Smuzhiyun {
1333*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1334*4882a593Smuzhiyun 
1335*4882a593Smuzhiyun 	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
1336*4882a593Smuzhiyun 		device_remove_file(dev, &dev_attr_bridged_mode);
1337*4882a593Smuzhiyun }
1338*4882a593Smuzhiyun 
qlcnic_create_diag_entries(struct qlcnic_adapter * adapter)1339*4882a593Smuzhiyun static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
1340*4882a593Smuzhiyun {
1341*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1342*4882a593Smuzhiyun 
1343*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_port_stats))
1344*4882a593Smuzhiyun 		dev_info(dev, "failed to create port stats sysfs entry");
1345*4882a593Smuzhiyun 
1346*4882a593Smuzhiyun 	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
1347*4882a593Smuzhiyun 		return;
1348*4882a593Smuzhiyun 	if (device_create_file(dev, &dev_attr_diag_mode))
1349*4882a593Smuzhiyun 		dev_info(dev, "failed to create diag_mode sysfs entry\n");
1350*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_crb))
1351*4882a593Smuzhiyun 		dev_info(dev, "failed to create crb sysfs entry\n");
1352*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_mem))
1353*4882a593Smuzhiyun 		dev_info(dev, "failed to create mem sysfs entry\n");
1354*4882a593Smuzhiyun 
1355*4882a593Smuzhiyun 	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1356*4882a593Smuzhiyun 		return;
1357*4882a593Smuzhiyun 
1358*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_pci_config))
1359*4882a593Smuzhiyun 		dev_info(dev, "failed to create pci config sysfs entry");
1360*4882a593Smuzhiyun 
1361*4882a593Smuzhiyun 	if (device_create_file(dev, &dev_attr_beacon))
1362*4882a593Smuzhiyun 		dev_info(dev, "failed to create beacon sysfs entry");
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1365*4882a593Smuzhiyun 		return;
1366*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_esw_config))
1367*4882a593Smuzhiyun 		dev_info(dev, "failed to create esw config sysfs entry");
1368*4882a593Smuzhiyun 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
1369*4882a593Smuzhiyun 		return;
1370*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_npar_config))
1371*4882a593Smuzhiyun 		dev_info(dev, "failed to create npar config sysfs entry");
1372*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_pm_config))
1373*4882a593Smuzhiyun 		dev_info(dev, "failed to create pm config sysfs entry");
1374*4882a593Smuzhiyun 	if (device_create_bin_file(dev, &bin_attr_esw_stats))
1375*4882a593Smuzhiyun 		dev_info(dev, "failed to create eswitch stats sysfs entry");
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun 
qlcnic_remove_diag_entries(struct qlcnic_adapter * adapter)1378*4882a593Smuzhiyun static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
1379*4882a593Smuzhiyun {
1380*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_port_stats);
1383*4882a593Smuzhiyun 
1384*4882a593Smuzhiyun 	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
1385*4882a593Smuzhiyun 		return;
1386*4882a593Smuzhiyun 	device_remove_file(dev, &dev_attr_diag_mode);
1387*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_crb);
1388*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_mem);
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	if (test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state))
1391*4882a593Smuzhiyun 		return;
1392*4882a593Smuzhiyun 
1393*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_pci_config);
1394*4882a593Smuzhiyun 	device_remove_file(dev, &dev_attr_beacon);
1395*4882a593Smuzhiyun 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1396*4882a593Smuzhiyun 		return;
1397*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_esw_config);
1398*4882a593Smuzhiyun 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
1399*4882a593Smuzhiyun 		return;
1400*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_npar_config);
1401*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_pm_config);
1402*4882a593Smuzhiyun 	device_remove_bin_file(dev, &bin_attr_esw_stats);
1403*4882a593Smuzhiyun }
1404*4882a593Smuzhiyun 
qlcnic_82xx_add_sysfs(struct qlcnic_adapter * adapter)1405*4882a593Smuzhiyun void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
1406*4882a593Smuzhiyun {
1407*4882a593Smuzhiyun 	qlcnic_create_diag_entries(adapter);
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun 
qlcnic_82xx_remove_sysfs(struct qlcnic_adapter * adapter)1410*4882a593Smuzhiyun void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
1411*4882a593Smuzhiyun {
1412*4882a593Smuzhiyun 	qlcnic_remove_diag_entries(adapter);
1413*4882a593Smuzhiyun }
1414*4882a593Smuzhiyun 
qlcnic_83xx_add_sysfs(struct qlcnic_adapter * adapter)1415*4882a593Smuzhiyun void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun 	qlcnic_create_diag_entries(adapter);
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun 	if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash))
1422*4882a593Smuzhiyun 		dev_info(dev, "failed to create flash sysfs entry\n");
1423*4882a593Smuzhiyun }
1424*4882a593Smuzhiyun 
qlcnic_83xx_remove_sysfs(struct qlcnic_adapter * adapter)1425*4882a593Smuzhiyun void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
1426*4882a593Smuzhiyun {
1427*4882a593Smuzhiyun 	struct device *dev = &adapter->pdev->dev;
1428*4882a593Smuzhiyun 
1429*4882a593Smuzhiyun 	qlcnic_remove_diag_entries(adapter);
1430*4882a593Smuzhiyun 	sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash);
1431*4882a593Smuzhiyun }
1432