blob: 504506349ac1cd1af3b8e5d4d6b5e7b8ac6fdb9a [file] [log] [blame]
Sony Chackoec079a02012-11-28 04:34:28 +00001#include <linux/slab.h>
2#include <linux/vmalloc.h>
3#include <linux/interrupt.h>
4
5#include "qlcnic.h"
Sony Chacko319ecf12013-01-01 03:20:22 +00006#include "qlcnic_hw.h"
Sony Chackoec079a02012-11-28 04:34:28 +00007
8#include <linux/swab.h>
9#include <linux/dma-mapping.h>
10#include <net/ip.h>
11#include <linux/ipv6.h>
12#include <linux/inetdevice.h>
13#include <linux/sysfs.h>
14#include <linux/aer.h>
15#include <linux/log2.h>
16
Sony Chacko319ecf12013-01-01 03:20:22 +000017#include <linux/sysfs.h>
18
19#define QLC_STATUS_UNSUPPORTED_CMD -2
20
Sony Chackoec079a02012-11-28 04:34:28 +000021int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable)
22{
23 return -EOPNOTSUPP;
24}
25
26int qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate)
27{
28 return -EOPNOTSUPP;
29}
30
Sony Chackob66e29c2012-11-28 04:34:29 +000031static ssize_t qlcnic_store_bridged_mode(struct device *dev,
32 struct device_attribute *attr,
33 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +000034{
35 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
36 unsigned long new;
37 int ret = -EINVAL;
38
Sony Chacko79788452012-12-04 03:33:53 +000039 if (!(adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG))
Sony Chackoec079a02012-11-28 04:34:28 +000040 goto err_out;
41
42 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
43 goto err_out;
44
45 if (strict_strtoul(buf, 2, &new))
46 goto err_out;
47
Sony Chacko319ecf12013-01-01 03:20:22 +000048 if (!qlcnic_config_bridged_mode(adapter, !!new))
Sony Chackoec079a02012-11-28 04:34:28 +000049 ret = len;
50
51err_out:
52 return ret;
53}
54
Sony Chackob66e29c2012-11-28 04:34:29 +000055static ssize_t qlcnic_show_bridged_mode(struct device *dev,
56 struct device_attribute *attr,
57 char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +000058{
59 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
60 int bridged_mode = 0;
61
Sony Chacko79788452012-12-04 03:33:53 +000062 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +000063 bridged_mode = !!(adapter->flags & QLCNIC_BRIDGE_ENABLED);
64
65 return sprintf(buf, "%d\n", bridged_mode);
66}
67
Sony Chackob66e29c2012-11-28 04:34:29 +000068static ssize_t qlcnic_store_diag_mode(struct device *dev,
69 struct device_attribute *attr,
70 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +000071{
72 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
73 unsigned long new;
74
75 if (strict_strtoul(buf, 2, &new))
76 return -EINVAL;
77
78 if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
79 adapter->flags ^= QLCNIC_DIAG_ENABLED;
80
81 return len;
82}
83
Sony Chackob66e29c2012-11-28 04:34:29 +000084static ssize_t qlcnic_show_diag_mode(struct device *dev,
85 struct device_attribute *attr, char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +000086{
87 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chacko319ecf12013-01-01 03:20:22 +000088 return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED));
Sony Chackoec079a02012-11-28 04:34:28 +000089}
90
Sony Chackob66e29c2012-11-28 04:34:29 +000091static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon,
92 u8 *state, u8 *rate)
Sony Chackoec079a02012-11-28 04:34:28 +000093{
94 *rate = LSB(beacon);
95 *state = MSB(beacon);
96
97 QLCDB(adapter, DRV, "rate %x state %x\n", *rate, *state);
98
99 if (!*state) {
100 *rate = __QLCNIC_MAX_LED_RATE;
101 return 0;
Sony Chackob66e29c2012-11-28 04:34:29 +0000102 } else if (*state > __QLCNIC_MAX_LED_STATE) {
Sony Chackoec079a02012-11-28 04:34:28 +0000103 return -EINVAL;
Sony Chackob66e29c2012-11-28 04:34:29 +0000104 }
Sony Chackoec079a02012-11-28 04:34:28 +0000105
106 if ((!*rate) || (*rate > __QLCNIC_MAX_LED_RATE))
107 return -EINVAL;
108
109 return 0;
110}
111
Sony Chackob66e29c2012-11-28 04:34:29 +0000112static ssize_t qlcnic_store_beacon(struct device *dev,
113 struct device_attribute *attr,
114 const char *buf, size_t len)
Sony Chackoec079a02012-11-28 04:34:28 +0000115{
116 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chacko319ecf12013-01-01 03:20:22 +0000117 struct qlcnic_hardware_context *ahw = adapter->ahw;
118 int err, max_sds_rings = adapter->max_sds_rings;
Sony Chackoec079a02012-11-28 04:34:28 +0000119 u16 beacon;
120 u8 b_state, b_rate;
Sony Chacko319ecf12013-01-01 03:20:22 +0000121 unsigned long h_beacon;
Sony Chackoec079a02012-11-28 04:34:28 +0000122
Sony Chacko79788452012-12-04 03:33:53 +0000123 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
Sony Chackob66e29c2012-11-28 04:34:29 +0000124 dev_warn(dev,
125 "LED test not supported in non privileged mode\n");
Sony Chackoec079a02012-11-28 04:34:28 +0000126 return -EOPNOTSUPP;
127 }
128
Sony Chacko319ecf12013-01-01 03:20:22 +0000129 if (qlcnic_83xx_check(adapter) &&
130 !test_bit(__QLCNIC_RESETTING, &adapter->state)) {
131 if (kstrtoul(buf, 2, &h_beacon))
132 return -EINVAL;
133
134 if (ahw->beacon_state == h_beacon)
135 return len;
136
137 rtnl_lock();
138 if (!ahw->beacon_state) {
139 if (test_and_set_bit(__QLCNIC_LED_ENABLE,
140 &adapter->state)) {
141 rtnl_unlock();
142 return -EBUSY;
143 }
144 }
145 if (h_beacon) {
146 err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
147 if (err)
148 goto beacon_err;
149 } else {
150 err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
151 if (err)
152 goto beacon_err;
153 }
154 /* set the current beacon state */
155 ahw->beacon_state = h_beacon;
156beacon_err:
157 if (!ahw->beacon_state)
158 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
159
160 rtnl_unlock();
161 return len;
162 }
163
Sony Chackoec079a02012-11-28 04:34:28 +0000164 if (len != sizeof(u16))
165 return QL_STATUS_INVALID_PARAM;
166
167 memcpy(&beacon, buf, sizeof(u16));
168 err = qlcnic_validate_beacon(adapter, beacon, &b_state, &b_rate);
169 if (err)
170 return err;
171
172 if (adapter->ahw->beacon_state == b_state)
173 return len;
174
175 rtnl_lock();
176
177 if (!adapter->ahw->beacon_state)
178 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
179 rtnl_unlock();
180 return -EBUSY;
181 }
182
183 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
184 err = -EIO;
185 goto out;
186 }
187
188 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
189 err = qlcnic_diag_alloc_res(adapter->netdev, QLCNIC_LED_TEST);
190 if (err)
191 goto out;
192 set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
193 }
194
195 err = qlcnic_config_led(adapter, b_state, b_rate);
Sony Chacko319ecf12013-01-01 03:20:22 +0000196 if (!err)
Sony Chackoec079a02012-11-28 04:34:28 +0000197 err = len;
Sony Chacko319ecf12013-01-01 03:20:22 +0000198 else
199 ahw->beacon_state = b_state;
Sony Chackoec079a02012-11-28 04:34:28 +0000200
201 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
202 qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
203
204 out:
205 if (!adapter->ahw->beacon_state)
206 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
207 rtnl_unlock();
208
209 return err;
210}
211
Sony Chackob66e29c2012-11-28 04:34:29 +0000212static ssize_t qlcnic_show_beacon(struct device *dev,
213 struct device_attribute *attr, char *buf)
Sony Chackoec079a02012-11-28 04:34:28 +0000214{
215 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
216
217 return sprintf(buf, "%d\n", adapter->ahw->beacon_state);
218}
219
Sony Chackob66e29c2012-11-28 04:34:29 +0000220static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
221 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000222{
223 size_t crb_size = 4;
224
225 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
226 return -EIO;
227
228 if (offset < QLCNIC_PCI_CRBSPACE) {
229 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
Sony Chackob66e29c2012-11-28 04:34:29 +0000230 QLCNIC_PCI_CAMQM_END))
Sony Chackoec079a02012-11-28 04:34:28 +0000231 crb_size = 8;
232 else
233 return -EINVAL;
234 }
235
236 if ((size != crb_size) || (offset & (crb_size-1)))
237 return -EINVAL;
238
239 return 0;
240}
241
Sony Chackob66e29c2012-11-28 04:34:29 +0000242static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
243 struct bin_attribute *attr, char *buf,
244 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000245{
246 struct device *dev = container_of(kobj, struct device, kobj);
247 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chackoec079a02012-11-28 04:34:28 +0000248 int ret;
249
250 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
251 if (ret != 0)
252 return ret;
Sony Chacko319ecf12013-01-01 03:20:22 +0000253 qlcnic_read_crb(adapter, buf, offset, size);
Sony Chackoec079a02012-11-28 04:34:28 +0000254
Sony Chackoec079a02012-11-28 04:34:28 +0000255 return size;
256}
257
Sony Chackob66e29c2012-11-28 04:34:29 +0000258static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
259 struct bin_attribute *attr, char *buf,
260 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000261{
262 struct device *dev = container_of(kobj, struct device, kobj);
263 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
Sony Chackoec079a02012-11-28 04:34:28 +0000264 int ret;
265
266 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
267 if (ret != 0)
268 return ret;
269
Sony Chacko319ecf12013-01-01 03:20:22 +0000270 qlcnic_write_crb(adapter, buf, offset, size);
Sony Chackoec079a02012-11-28 04:34:28 +0000271 return size;
272}
273
Sony Chackob66e29c2012-11-28 04:34:29 +0000274static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter,
275 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000276{
277 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
278 return -EIO;
279
280 if ((size != 8) || (offset & 0x7))
281 return -EIO;
282
283 return 0;
284}
285
Sony Chackob66e29c2012-11-28 04:34:29 +0000286static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
287 struct bin_attribute *attr, char *buf,
288 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000289{
290 struct device *dev = container_of(kobj, struct device, kobj);
291 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
292 u64 data;
293 int ret;
294
295 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
296 if (ret != 0)
297 return ret;
298
299 if (qlcnic_pci_mem_read_2M(adapter, offset, &data))
300 return -EIO;
301
302 memcpy(buf, &data, size);
303
304 return size;
305}
306
Sony Chackob66e29c2012-11-28 04:34:29 +0000307static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
308 struct bin_attribute *attr, char *buf,
309 loff_t offset, size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000310{
311 struct device *dev = container_of(kobj, struct device, kobj);
312 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
313 u64 data;
314 int ret;
315
316 ret = qlcnic_sysfs_validate_mem(adapter, offset, size);
317 if (ret != 0)
318 return ret;
319
320 memcpy(&data, buf, size);
321
322 if (qlcnic_pci_mem_write_2M(adapter, offset, data))
323 return -EIO;
324
325 return size;
326}
327
Sony Chacko319ecf12013-01-01 03:20:22 +0000328static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
329{
330 int i;
331 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
332 if (adapter->npars[i].pci_func == pci_func)
333 return i;
334 }
335
336 return -1;
337}
338
Sony Chackob66e29c2012-11-28 04:34:29 +0000339static int validate_pm_config(struct qlcnic_adapter *adapter,
340 struct qlcnic_pm_func_cfg *pm_cfg, int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000341{
Sony Chacko319ecf12013-01-01 03:20:22 +0000342 u8 src_pci_func, s_esw_id, d_esw_id;
343 u8 dest_pci_func;
344 int i, src_index, dest_index;
Sony Chackoec079a02012-11-28 04:34:28 +0000345
346 for (i = 0; i < count; i++) {
347 src_pci_func = pm_cfg[i].pci_func;
348 dest_pci_func = pm_cfg[i].dest_npar;
Sony Chacko319ecf12013-01-01 03:20:22 +0000349 src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func);
350
351 if (src_index < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000352 return QL_STATUS_INVALID_PARAM;
353
Sony Chacko319ecf12013-01-01 03:20:22 +0000354 dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func);
355 if (dest_index < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000356 return QL_STATUS_INVALID_PARAM;
357
Sony Chacko319ecf12013-01-01 03:20:22 +0000358 s_esw_id = adapter->npars[src_index].phy_port;
359 d_esw_id = adapter->npars[dest_index].phy_port;
Sony Chackoec079a02012-11-28 04:34:28 +0000360
361 if (s_esw_id != d_esw_id)
362 return QL_STATUS_INVALID_PARAM;
Sony Chackoec079a02012-11-28 04:34:28 +0000363 }
Sony Chackoec079a02012-11-28 04:34:28 +0000364
Sony Chacko319ecf12013-01-01 03:20:22 +0000365 return 0;
Sony Chackoec079a02012-11-28 04:34:28 +0000366}
367
Sony Chackob66e29c2012-11-28 04:34:29 +0000368static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
369 struct kobject *kobj,
370 struct bin_attribute *attr,
371 char *buf, loff_t offset,
372 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000373{
374 struct device *dev = container_of(kobj, struct device, kobj);
375 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
376 struct qlcnic_pm_func_cfg *pm_cfg;
377 u32 id, action, pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000378 int count, rem, i, ret, index;
Sony Chackoec079a02012-11-28 04:34:28 +0000379
380 count = size / sizeof(struct qlcnic_pm_func_cfg);
381 rem = size % sizeof(struct qlcnic_pm_func_cfg);
382 if (rem)
383 return QL_STATUS_INVALID_PARAM;
384
Sony Chackob66e29c2012-11-28 04:34:29 +0000385 pm_cfg = (struct qlcnic_pm_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000386 ret = validate_pm_config(adapter, pm_cfg, count);
Sony Chacko319ecf12013-01-01 03:20:22 +0000387
Sony Chackoec079a02012-11-28 04:34:28 +0000388 if (ret)
389 return ret;
390 for (i = 0; i < count; i++) {
391 pci_func = pm_cfg[i].pci_func;
392 action = !!pm_cfg[i].action;
Sony Chacko319ecf12013-01-01 03:20:22 +0000393 index = qlcnic_is_valid_nic_func(adapter, pci_func);
394 if (index < 0)
395 return QL_STATUS_INVALID_PARAM;
396
397 id = adapter->npars[index].phy_port;
398 ret = qlcnic_config_port_mirroring(adapter, id,
399 action, pci_func);
Sony Chackoec079a02012-11-28 04:34:28 +0000400 if (ret)
401 return ret;
402 }
403
404 for (i = 0; i < count; i++) {
405 pci_func = pm_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000406 index = qlcnic_is_valid_nic_func(adapter, pci_func);
407 id = adapter->npars[index].phy_port;
408 adapter->npars[index].enable_pm = !!pm_cfg[i].action;
409 adapter->npars[index].dest_npar = id;
Sony Chackoec079a02012-11-28 04:34:28 +0000410 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000411
Sony Chackoec079a02012-11-28 04:34:28 +0000412 return size;
413}
414
Sony Chackob66e29c2012-11-28 04:34:29 +0000415static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
416 struct kobject *kobj,
417 struct bin_attribute *attr,
418 char *buf, loff_t offset,
419 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000420{
421 struct device *dev = container_of(kobj, struct device, kobj);
422 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
423 struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC];
424 int i;
Sony Chacko319ecf12013-01-01 03:20:22 +0000425 u8 pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000426
427 if (size != sizeof(pm_cfg))
428 return QL_STATUS_INVALID_PARAM;
429
Sony Chacko319ecf12013-01-01 03:20:22 +0000430 memset(&pm_cfg, 0,
431 sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC);
432
433 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
434 pci_func = adapter->npars[i].pci_func;
435 pm_cfg[pci_func].action = adapter->npars[i].enable_pm;
436 pm_cfg[pci_func].dest_npar = 0;
437 pm_cfg[pci_func].pci_func = i;
Sony Chackoec079a02012-11-28 04:34:28 +0000438 }
439 memcpy(buf, &pm_cfg, size);
440
441 return size;
442}
443
Sony Chackob66e29c2012-11-28 04:34:29 +0000444static int validate_esw_config(struct qlcnic_adapter *adapter,
445 struct qlcnic_esw_func_cfg *esw_cfg, int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000446{
447 u32 op_mode;
448 u8 pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000449 int i, ret;
Sony Chackoec079a02012-11-28 04:34:28 +0000450
Sony Chacko319ecf12013-01-01 03:20:22 +0000451 if (qlcnic_82xx_check(adapter))
452 op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
453 else
454 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
Sony Chackoec079a02012-11-28 04:34:28 +0000455
456 for (i = 0; i < count; i++) {
457 pci_func = esw_cfg[i].pci_func;
458 if (pci_func >= QLCNIC_MAX_PCI_FUNC)
459 return QL_STATUS_INVALID_PARAM;
460
Sony Chacko319ecf12013-01-01 03:20:22 +0000461 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
462 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000463 return QL_STATUS_INVALID_PARAM;
464
465 switch (esw_cfg[i].op_mode) {
466 case QLCNIC_PORT_DEFAULTS:
Sony Chacko319ecf12013-01-01 03:20:22 +0000467 if (qlcnic_82xx_check(adapter)) {
468 ret = QLC_DEV_GET_DRV(op_mode, pci_func);
469 } else {
470 ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
471 pci_func);
472 esw_cfg[i].offload_flags = 0;
473 }
474
475 if (ret != QLCNIC_NON_PRIV_FUNC) {
Sony Chackoec079a02012-11-28 04:34:28 +0000476 if (esw_cfg[i].mac_anti_spoof != 0)
477 return QL_STATUS_INVALID_PARAM;
478 if (esw_cfg[i].mac_override != 1)
479 return QL_STATUS_INVALID_PARAM;
480 if (esw_cfg[i].promisc_mode != 1)
481 return QL_STATUS_INVALID_PARAM;
482 }
483 break;
484 case QLCNIC_ADD_VLAN:
485 if (!IS_VALID_VLAN(esw_cfg[i].vlan_id))
486 return QL_STATUS_INVALID_PARAM;
487 if (!esw_cfg[i].op_type)
488 return QL_STATUS_INVALID_PARAM;
489 break;
490 case QLCNIC_DEL_VLAN:
491 if (!esw_cfg[i].op_type)
492 return QL_STATUS_INVALID_PARAM;
493 break;
494 default:
495 return QL_STATUS_INVALID_PARAM;
496 }
497 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000498
Sony Chackoec079a02012-11-28 04:34:28 +0000499 return 0;
500}
501
Sony Chackob66e29c2012-11-28 04:34:29 +0000502static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
503 struct kobject *kobj,
504 struct bin_attribute *attr,
505 char *buf, loff_t offset,
506 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000507{
508 struct device *dev = container_of(kobj, struct device, kobj);
509 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
510 struct qlcnic_esw_func_cfg *esw_cfg;
511 struct qlcnic_npar_info *npar;
512 int count, rem, i, ret;
Sony Chacko319ecf12013-01-01 03:20:22 +0000513 int index;
514 u8 op_mode = 0, pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000515
516 count = size / sizeof(struct qlcnic_esw_func_cfg);
517 rem = size % sizeof(struct qlcnic_esw_func_cfg);
518 if (rem)
519 return QL_STATUS_INVALID_PARAM;
520
Sony Chackob66e29c2012-11-28 04:34:29 +0000521 esw_cfg = (struct qlcnic_esw_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000522 ret = validate_esw_config(adapter, esw_cfg, count);
523 if (ret)
524 return ret;
525
526 for (i = 0; i < count; i++) {
Sony Chacko319ecf12013-01-01 03:20:22 +0000527 if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000528 if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
529 return QL_STATUS_INVALID_PARAM;
530
531 if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
532 continue;
533
534 op_mode = esw_cfg[i].op_mode;
535 qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
536 esw_cfg[i].op_mode = op_mode;
537 esw_cfg[i].pci_func = adapter->ahw->pci_func;
538
539 switch (esw_cfg[i].op_mode) {
540 case QLCNIC_PORT_DEFAULTS:
541 qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]);
542 break;
543 case QLCNIC_ADD_VLAN:
544 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
545 break;
546 case QLCNIC_DEL_VLAN:
547 esw_cfg[i].vlan_id = 0;
548 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
549 break;
550 }
551 }
552
Sony Chacko79788452012-12-04 03:33:53 +0000553 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000554 goto out;
555
556 for (i = 0; i < count; i++) {
557 pci_func = esw_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000558 index = qlcnic_is_valid_nic_func(adapter, pci_func);
559 npar = &adapter->npars[index];
Sony Chackoec079a02012-11-28 04:34:28 +0000560 switch (esw_cfg[i].op_mode) {
561 case QLCNIC_PORT_DEFAULTS:
562 npar->promisc_mode = esw_cfg[i].promisc_mode;
563 npar->mac_override = esw_cfg[i].mac_override;
564 npar->offload_flags = esw_cfg[i].offload_flags;
565 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
566 npar->discard_tagged = esw_cfg[i].discard_tagged;
567 break;
568 case QLCNIC_ADD_VLAN:
569 npar->pvid = esw_cfg[i].vlan_id;
570 break;
571 case QLCNIC_DEL_VLAN:
572 npar->pvid = 0;
573 break;
574 }
575 }
576out:
577 return size;
578}
579
Sony Chackob66e29c2012-11-28 04:34:29 +0000580static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
581 struct kobject *kobj,
582 struct bin_attribute *attr,
583 char *buf, loff_t offset,
584 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000585{
586 struct device *dev = container_of(kobj, struct device, kobj);
587 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
588 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
Sony Chacko319ecf12013-01-01 03:20:22 +0000589 u8 i, pci_func;
Sony Chackoec079a02012-11-28 04:34:28 +0000590
591 if (size != sizeof(esw_cfg))
592 return QL_STATUS_INVALID_PARAM;
593
Sony Chacko319ecf12013-01-01 03:20:22 +0000594 memset(&esw_cfg, 0,
595 sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC);
596
597 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
598 pci_func = adapter->npars[i].pci_func;
599 esw_cfg[pci_func].pci_func = pci_func;
600 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
Sony Chackoec079a02012-11-28 04:34:28 +0000601 return QL_STATUS_INVALID_PARAM;
602 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000603
Sony Chackoec079a02012-11-28 04:34:28 +0000604 memcpy(buf, &esw_cfg, size);
605
606 return size;
607}
608
Sony Chackob66e29c2012-11-28 04:34:29 +0000609static int validate_npar_config(struct qlcnic_adapter *adapter,
610 struct qlcnic_npar_func_cfg *np_cfg,
611 int count)
Sony Chackoec079a02012-11-28 04:34:28 +0000612{
613 u8 pci_func, i;
614
615 for (i = 0; i < count; i++) {
616 pci_func = np_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000617 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000618 return QL_STATUS_INVALID_PARAM;
619
620 if (!IS_VALID_BW(np_cfg[i].min_bw) ||
621 !IS_VALID_BW(np_cfg[i].max_bw))
622 return QL_STATUS_INVALID_PARAM;
623 }
624 return 0;
625}
626
Sony Chackob66e29c2012-11-28 04:34:29 +0000627static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
628 struct kobject *kobj,
629 struct bin_attribute *attr,
630 char *buf, loff_t offset,
631 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000632{
633 struct device *dev = container_of(kobj, struct device, kobj);
634 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
635 struct qlcnic_info nic_info;
636 struct qlcnic_npar_func_cfg *np_cfg;
Sony Chacko319ecf12013-01-01 03:20:22 +0000637 int i, count, rem, ret, index;
Sony Chackoec079a02012-11-28 04:34:28 +0000638 u8 pci_func;
639
640 count = size / sizeof(struct qlcnic_npar_func_cfg);
641 rem = size % sizeof(struct qlcnic_npar_func_cfg);
642 if (rem)
643 return QL_STATUS_INVALID_PARAM;
644
Sony Chackob66e29c2012-11-28 04:34:29 +0000645 np_cfg = (struct qlcnic_npar_func_cfg *)buf;
Sony Chackoec079a02012-11-28 04:34:28 +0000646 ret = validate_npar_config(adapter, np_cfg, count);
647 if (ret)
648 return ret;
649
Sony Chacko319ecf12013-01-01 03:20:22 +0000650 for (i = 0; i < count; i++) {
Sony Chackoec079a02012-11-28 04:34:28 +0000651 pci_func = np_cfg[i].pci_func;
Sony Chacko319ecf12013-01-01 03:20:22 +0000652
653 memset(&nic_info, 0, sizeof(struct qlcnic_info));
Sony Chackoec079a02012-11-28 04:34:28 +0000654 ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
655 if (ret)
656 return ret;
657 nic_info.pci_func = pci_func;
658 nic_info.min_tx_bw = np_cfg[i].min_bw;
659 nic_info.max_tx_bw = np_cfg[i].max_bw;
660 ret = qlcnic_set_nic_info(adapter, &nic_info);
661 if (ret)
662 return ret;
Sony Chacko319ecf12013-01-01 03:20:22 +0000663 index = qlcnic_is_valid_nic_func(adapter, pci_func);
664 adapter->npars[index].min_bw = nic_info.min_tx_bw;
665 adapter->npars[index].max_bw = nic_info.max_tx_bw;
Sony Chackoec079a02012-11-28 04:34:28 +0000666 }
667
668 return size;
Sony Chackoec079a02012-11-28 04:34:28 +0000669}
Sony Chackob66e29c2012-11-28 04:34:29 +0000670
671static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
672 struct kobject *kobj,
673 struct bin_attribute *attr,
674 char *buf, loff_t offset,
675 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000676{
677 struct device *dev = container_of(kobj, struct device, kobj);
678 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
679 struct qlcnic_info nic_info;
680 struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC];
681 int i, ret;
682
683 if (size != sizeof(np_cfg))
684 return QL_STATUS_INVALID_PARAM;
685
Sony Chacko319ecf12013-01-01 03:20:22 +0000686 memset(&nic_info, 0, sizeof(struct qlcnic_info));
687 memset(&np_cfg, 0,
688 sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC);
689
Sony Chackob66e29c2012-11-28 04:34:29 +0000690 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
Sony Chacko319ecf12013-01-01 03:20:22 +0000691 if (qlcnic_is_valid_nic_func(adapter, i) < 0)
Sony Chackoec079a02012-11-28 04:34:28 +0000692 continue;
693 ret = qlcnic_get_nic_info(adapter, &nic_info, i);
694 if (ret)
695 return ret;
696
697 np_cfg[i].pci_func = i;
698 np_cfg[i].op_mode = (u8)nic_info.op_mode;
699 np_cfg[i].port_num = nic_info.phys_port;
700 np_cfg[i].fw_capab = nic_info.capabilities;
Sony Chackob66e29c2012-11-28 04:34:29 +0000701 np_cfg[i].min_bw = nic_info.min_tx_bw;
Sony Chackoec079a02012-11-28 04:34:28 +0000702 np_cfg[i].max_bw = nic_info.max_tx_bw;
703 np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
704 np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
705 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000706
Sony Chackoec079a02012-11-28 04:34:28 +0000707 memcpy(buf, &np_cfg, size);
708 return size;
709}
710
Sony Chackob66e29c2012-11-28 04:34:29 +0000711static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
712 struct kobject *kobj,
713 struct bin_attribute *attr,
714 char *buf, loff_t offset,
715 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000716{
717 struct device *dev = container_of(kobj, struct device, kobj);
718 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
719 struct qlcnic_esw_statistics port_stats;
720 int ret;
721
Sony Chacko319ecf12013-01-01 03:20:22 +0000722 if (qlcnic_83xx_check(adapter))
723 return QLC_STATUS_UNSUPPORTED_CMD;
724
Sony Chackoec079a02012-11-28 04:34:28 +0000725 if (size != sizeof(struct qlcnic_esw_statistics))
726 return QL_STATUS_INVALID_PARAM;
727
728 if (offset >= QLCNIC_MAX_PCI_FUNC)
729 return QL_STATUS_INVALID_PARAM;
730
731 memset(&port_stats, 0, size);
732 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000733 &port_stats.rx);
Sony Chackoec079a02012-11-28 04:34:28 +0000734 if (ret)
735 return ret;
736
737 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000738 &port_stats.tx);
Sony Chackoec079a02012-11-28 04:34:28 +0000739 if (ret)
740 return ret;
741
742 memcpy(buf, &port_stats, size);
743 return size;
744}
745
Sony Chackob66e29c2012-11-28 04:34:29 +0000746static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
747 struct kobject *kobj,
748 struct bin_attribute *attr,
749 char *buf, loff_t offset,
750 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000751{
752 struct device *dev = container_of(kobj, struct device, kobj);
753 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
754 struct qlcnic_esw_statistics esw_stats;
755 int ret;
756
Sony Chacko319ecf12013-01-01 03:20:22 +0000757 if (qlcnic_83xx_check(adapter))
758 return QLC_STATUS_UNSUPPORTED_CMD;
759
Sony Chackoec079a02012-11-28 04:34:28 +0000760 if (size != sizeof(struct qlcnic_esw_statistics))
761 return QL_STATUS_INVALID_PARAM;
762
763 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
764 return QL_STATUS_INVALID_PARAM;
765
766 memset(&esw_stats, 0, size);
767 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000768 &esw_stats.rx);
Sony Chackoec079a02012-11-28 04:34:28 +0000769 if (ret)
770 return ret;
771
772 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
Sony Chackob66e29c2012-11-28 04:34:29 +0000773 &esw_stats.tx);
Sony Chackoec079a02012-11-28 04:34:28 +0000774 if (ret)
775 return ret;
776
777 memcpy(buf, &esw_stats, size);
778 return size;
779}
780
Sony Chackob66e29c2012-11-28 04:34:29 +0000781static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
782 struct kobject *kobj,
783 struct bin_attribute *attr,
784 char *buf, loff_t offset,
785 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000786{
787 struct device *dev = container_of(kobj, struct device, kobj);
788 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
789 int ret;
790
Sony Chacko319ecf12013-01-01 03:20:22 +0000791 if (qlcnic_83xx_check(adapter))
792 return QLC_STATUS_UNSUPPORTED_CMD;
793
Sony Chackoec079a02012-11-28 04:34:28 +0000794 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
795 return QL_STATUS_INVALID_PARAM;
796
797 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000798 QLCNIC_QUERY_RX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000799 if (ret)
800 return ret;
801
802 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000803 QLCNIC_QUERY_TX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000804 if (ret)
805 return ret;
806
807 return size;
808}
809
Sony Chackob66e29c2012-11-28 04:34:29 +0000810static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
811 struct kobject *kobj,
812 struct bin_attribute *attr,
813 char *buf, loff_t offset,
814 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000815{
Sony Chacko319ecf12013-01-01 03:20:22 +0000816
Sony Chackoec079a02012-11-28 04:34:28 +0000817 struct device *dev = container_of(kobj, struct device, kobj);
818 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
819 int ret;
820
Sony Chacko319ecf12013-01-01 03:20:22 +0000821 if (qlcnic_83xx_check(adapter))
822 return QLC_STATUS_UNSUPPORTED_CMD;
823
Sony Chackoec079a02012-11-28 04:34:28 +0000824 if (offset >= QLCNIC_MAX_PCI_FUNC)
825 return QL_STATUS_INVALID_PARAM;
826
827 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000828 QLCNIC_QUERY_RX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000829 if (ret)
830 return ret;
831
832 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
Sony Chackob66e29c2012-11-28 04:34:29 +0000833 QLCNIC_QUERY_TX_COUNTER);
Sony Chackoec079a02012-11-28 04:34:28 +0000834 if (ret)
835 return ret;
836
837 return size;
838}
839
Sony Chackob66e29c2012-11-28 04:34:29 +0000840static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
841 struct kobject *kobj,
842 struct bin_attribute *attr,
843 char *buf, loff_t offset,
844 size_t size)
Sony Chackoec079a02012-11-28 04:34:28 +0000845{
846 struct device *dev = container_of(kobj, struct device, kobj);
847 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
848 struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC];
849 struct qlcnic_pci_info *pci_info;
850 int i, ret;
851
852 if (size != sizeof(pci_cfg))
853 return QL_STATUS_INVALID_PARAM;
854
855 pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
856 if (!pci_info)
857 return -ENOMEM;
858
859 ret = qlcnic_get_pci_info(adapter, pci_info);
860 if (ret) {
861 kfree(pci_info);
862 return ret;
863 }
864
Sony Chacko319ecf12013-01-01 03:20:22 +0000865 memset(&pci_cfg, 0,
866 sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC);
867
868 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
Sony Chackoec079a02012-11-28 04:34:28 +0000869 pci_cfg[i].pci_func = pci_info[i].id;
870 pci_cfg[i].func_type = pci_info[i].type;
871 pci_cfg[i].port_num = pci_info[i].default_port;
872 pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
873 pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
874 memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
875 }
Sony Chacko319ecf12013-01-01 03:20:22 +0000876
Sony Chackoec079a02012-11-28 04:34:28 +0000877 memcpy(buf, &pci_cfg, size);
878 kfree(pci_info);
879 return size;
880}
881
882static struct device_attribute dev_attr_bridged_mode = {
883 .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
884 .show = qlcnic_show_bridged_mode,
885 .store = qlcnic_store_bridged_mode,
886};
887
888static struct device_attribute dev_attr_diag_mode = {
889 .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
890 .show = qlcnic_show_diag_mode,
891 .store = qlcnic_store_diag_mode,
892};
893
894static struct device_attribute dev_attr_beacon = {
895 .attr = {.name = "beacon", .mode = (S_IRUGO | S_IWUSR)},
896 .show = qlcnic_show_beacon,
897 .store = qlcnic_store_beacon,
898};
899
900static struct bin_attribute bin_attr_crb = {
901 .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
902 .size = 0,
903 .read = qlcnic_sysfs_read_crb,
904 .write = qlcnic_sysfs_write_crb,
905};
906
907static struct bin_attribute bin_attr_mem = {
908 .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
909 .size = 0,
910 .read = qlcnic_sysfs_read_mem,
911 .write = qlcnic_sysfs_write_mem,
912};
913
914static struct bin_attribute bin_attr_npar_config = {
915 .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
916 .size = 0,
917 .read = qlcnic_sysfs_read_npar_config,
918 .write = qlcnic_sysfs_write_npar_config,
919};
920
921static struct bin_attribute bin_attr_pci_config = {
922 .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
923 .size = 0,
924 .read = qlcnic_sysfs_read_pci_config,
925 .write = NULL,
926};
927
928static struct bin_attribute bin_attr_port_stats = {
929 .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
930 .size = 0,
931 .read = qlcnic_sysfs_get_port_stats,
932 .write = qlcnic_sysfs_clear_port_stats,
933};
934
935static struct bin_attribute bin_attr_esw_stats = {
936 .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
937 .size = 0,
938 .read = qlcnic_sysfs_get_esw_stats,
939 .write = qlcnic_sysfs_clear_esw_stats,
940};
941
942static struct bin_attribute bin_attr_esw_config = {
943 .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
944 .size = 0,
945 .read = qlcnic_sysfs_read_esw_config,
946 .write = qlcnic_sysfs_write_esw_config,
947};
948
949static struct bin_attribute bin_attr_pm_config = {
950 .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
951 .size = 0,
952 .read = qlcnic_sysfs_read_pm_config,
953 .write = qlcnic_sysfs_write_pm_config,
954};
955
956void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
957{
958 struct device *dev = &adapter->pdev->dev;
959
Sony Chacko79788452012-12-04 03:33:53 +0000960 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +0000961 if (device_create_file(dev, &dev_attr_bridged_mode))
962 dev_warn(dev,
Sony Chackob66e29c2012-11-28 04:34:29 +0000963 "failed to create bridged_mode sysfs entry\n");
Sony Chackoec079a02012-11-28 04:34:28 +0000964}
965
966void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
967{
968 struct device *dev = &adapter->pdev->dev;
969
Sony Chacko79788452012-12-04 03:33:53 +0000970 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
Sony Chackoec079a02012-11-28 04:34:28 +0000971 device_remove_file(dev, &dev_attr_bridged_mode);
972}
973
974void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
975{
976 struct device *dev = &adapter->pdev->dev;
Sony Chackoec079a02012-11-28 04:34:28 +0000977
978 if (device_create_bin_file(dev, &bin_attr_port_stats))
979 dev_info(dev, "failed to create port stats sysfs entry");
980
Sony Chacko79788452012-12-04 03:33:53 +0000981 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +0000982 return;
983 if (device_create_file(dev, &dev_attr_diag_mode))
984 dev_info(dev, "failed to create diag_mode sysfs entry\n");
985 if (device_create_bin_file(dev, &bin_attr_crb))
986 dev_info(dev, "failed to create crb sysfs entry\n");
987 if (device_create_bin_file(dev, &bin_attr_mem))
988 dev_info(dev, "failed to create mem sysfs entry\n");
989
Sony Chackoec079a02012-11-28 04:34:28 +0000990 if (device_create_bin_file(dev, &bin_attr_pci_config))
991 dev_info(dev, "failed to create pci config sysfs entry");
992 if (device_create_file(dev, &dev_attr_beacon))
993 dev_info(dev, "failed to create beacon sysfs entry");
994
995 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
996 return;
997 if (device_create_bin_file(dev, &bin_attr_esw_config))
998 dev_info(dev, "failed to create esw config sysfs entry");
Sony Chacko79788452012-12-04 03:33:53 +0000999 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001000 return;
1001 if (device_create_bin_file(dev, &bin_attr_npar_config))
1002 dev_info(dev, "failed to create npar config sysfs entry");
1003 if (device_create_bin_file(dev, &bin_attr_pm_config))
1004 dev_info(dev, "failed to create pm config sysfs entry");
1005 if (device_create_bin_file(dev, &bin_attr_esw_stats))
1006 dev_info(dev, "failed to create eswitch stats sysfs entry");
1007}
1008
1009void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
1010{
1011 struct device *dev = &adapter->pdev->dev;
Sony Chackoec079a02012-11-28 04:34:28 +00001012
1013 device_remove_bin_file(dev, &bin_attr_port_stats);
1014
Sony Chacko79788452012-12-04 03:33:53 +00001015 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001016 return;
1017 device_remove_file(dev, &dev_attr_diag_mode);
1018 device_remove_bin_file(dev, &bin_attr_crb);
1019 device_remove_bin_file(dev, &bin_attr_mem);
Sony Chackoec079a02012-11-28 04:34:28 +00001020 device_remove_bin_file(dev, &bin_attr_pci_config);
1021 device_remove_file(dev, &dev_attr_beacon);
1022 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1023 return;
1024 device_remove_bin_file(dev, &bin_attr_esw_config);
Sony Chacko79788452012-12-04 03:33:53 +00001025 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
Sony Chackoec079a02012-11-28 04:34:28 +00001026 return;
1027 device_remove_bin_file(dev, &bin_attr_npar_config);
1028 device_remove_bin_file(dev, &bin_attr_pm_config);
1029 device_remove_bin_file(dev, &bin_attr_esw_stats);
1030}
Sony Chacko7e2cf4f2013-01-01 03:20:17 +00001031
1032void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
1033{
1034 qlcnic_create_diag_entries(adapter);
1035}
1036
1037void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
1038{
1039 qlcnic_remove_diag_entries(adapter);
1040}
Sony Chacko319ecf12013-01-01 03:20:22 +00001041
1042void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
1043{
1044 qlcnic_create_diag_entries(adapter);
1045}
1046
1047void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
1048{
1049 qlcnic_remove_diag_entries(adapter);
1050}