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