qlcnic: remove netdev->trans_start updates within the driver
[linux-2.6-block.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]);
547 break;
548 case QLCNIC_ADD_VLAN:
549 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
550 break;
551 case QLCNIC_DEL_VLAN:
552 esw_cfg[i].vlan_id = 0;
553 qlcnic_set_vlan_config(adapter, &esw_cfg[i]);
554 break;
555 }
556 }
557
79788450 558 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
ec079a07
SC
559 goto out;
560
561 for (i = 0; i < count; i++) {
562 pci_func = esw_cfg[i].pci_func;
319ecf12
SC
563 index = qlcnic_is_valid_nic_func(adapter, pci_func);
564 npar = &adapter->npars[index];
ec079a07
SC
565 switch (esw_cfg[i].op_mode) {
566 case QLCNIC_PORT_DEFAULTS:
567 npar->promisc_mode = esw_cfg[i].promisc_mode;
568 npar->mac_override = esw_cfg[i].mac_override;
569 npar->offload_flags = esw_cfg[i].offload_flags;
570 npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof;
571 npar->discard_tagged = esw_cfg[i].discard_tagged;
572 break;
573 case QLCNIC_ADD_VLAN:
574 npar->pvid = esw_cfg[i].vlan_id;
575 break;
576 case QLCNIC_DEL_VLAN:
577 npar->pvid = 0;
578 break;
579 }
580 }
581out:
582 return size;
583}
584
b66e29c9
SC
585static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
586 struct kobject *kobj,
587 struct bin_attribute *attr,
588 char *buf, loff_t offset,
589 size_t size)
ec079a07
SC
590{
591 struct device *dev = container_of(kobj, struct device, kobj);
592 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
593 struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC];
319ecf12 594 u8 i, pci_func;
ec079a07
SC
595
596 if (size != sizeof(esw_cfg))
597 return QL_STATUS_INVALID_PARAM;
598
319ecf12
SC
599 memset(&esw_cfg, 0,
600 sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC);
601
602 for (i = 0; i < adapter->ahw->act_pci_func; i++) {
603 pci_func = adapter->npars[i].pci_func;
604 esw_cfg[pci_func].pci_func = pci_func;
605 if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func]))
ec079a07
SC
606 return QL_STATUS_INVALID_PARAM;
607 }
319ecf12 608
ec079a07
SC
609 memcpy(buf, &esw_cfg, size);
610
611 return size;
612}
613
b66e29c9
SC
614static int validate_npar_config(struct qlcnic_adapter *adapter,
615 struct qlcnic_npar_func_cfg *np_cfg,
616 int count)
ec079a07
SC
617{
618 u8 pci_func, i;
619
620 for (i = 0; i < count; i++) {
621 pci_func = np_cfg[i].pci_func;
319ecf12 622 if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0)
ec079a07
SC
623 return QL_STATUS_INVALID_PARAM;
624
625 if (!IS_VALID_BW(np_cfg[i].min_bw) ||
626 !IS_VALID_BW(np_cfg[i].max_bw))
627 return QL_STATUS_INVALID_PARAM;
628 }
629 return 0;
630}
631
b66e29c9
SC
632static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
633 struct kobject *kobj,
634 struct bin_attribute *attr,
635 char *buf, loff_t offset,
636 size_t size)
ec079a07
SC
637{
638 struct device *dev = container_of(kobj, struct device, kobj);
639 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
640 struct qlcnic_info nic_info;
641 struct qlcnic_npar_func_cfg *np_cfg;
319ecf12 642 int i, count, rem, ret, index;
ec079a07
SC
643 u8 pci_func;
644
645 count = size / sizeof(struct qlcnic_npar_func_cfg);
646 rem = size % sizeof(struct qlcnic_npar_func_cfg);
647 if (rem)
648 return QL_STATUS_INVALID_PARAM;
649
b66e29c9 650 np_cfg = (struct qlcnic_npar_func_cfg *)buf;
ec079a07
SC
651 ret = validate_npar_config(adapter, np_cfg, count);
652 if (ret)
653 return ret;
654
319ecf12 655 for (i = 0; i < count; i++) {
ec079a07 656 pci_func = np_cfg[i].pci_func;
319ecf12
SC
657
658 memset(&nic_info, 0, sizeof(struct qlcnic_info));
ec079a07
SC
659 ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func);
660 if (ret)
661 return ret;
662 nic_info.pci_func = pci_func;
663 nic_info.min_tx_bw = np_cfg[i].min_bw;
664 nic_info.max_tx_bw = np_cfg[i].max_bw;
665 ret = qlcnic_set_nic_info(adapter, &nic_info);
666 if (ret)
667 return ret;
319ecf12
SC
668 index = qlcnic_is_valid_nic_func(adapter, pci_func);
669 adapter->npars[index].min_bw = nic_info.min_tx_bw;
670 adapter->npars[index].max_bw = nic_info.max_tx_bw;
ec079a07
SC
671 }
672
673 return size;
ec079a07 674}
b66e29c9
SC
675
676static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
677 struct kobject *kobj,
678 struct bin_attribute *attr,
679 char *buf, loff_t offset,
680 size_t size)
ec079a07
SC
681{
682 struct device *dev = container_of(kobj, struct device, kobj);
683 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
684 struct qlcnic_info nic_info;
685 struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC];
686 int i, ret;
687
688 if (size != sizeof(np_cfg))
689 return QL_STATUS_INVALID_PARAM;
690
319ecf12
SC
691 memset(&nic_info, 0, sizeof(struct qlcnic_info));
692 memset(&np_cfg, 0,
693 sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC);
694
b66e29c9 695 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
319ecf12 696 if (qlcnic_is_valid_nic_func(adapter, i) < 0)
ec079a07
SC
697 continue;
698 ret = qlcnic_get_nic_info(adapter, &nic_info, i);
699 if (ret)
700 return ret;
701
702 np_cfg[i].pci_func = i;
703 np_cfg[i].op_mode = (u8)nic_info.op_mode;
704 np_cfg[i].port_num = nic_info.phys_port;
705 np_cfg[i].fw_capab = nic_info.capabilities;
b66e29c9 706 np_cfg[i].min_bw = nic_info.min_tx_bw;
ec079a07
SC
707 np_cfg[i].max_bw = nic_info.max_tx_bw;
708 np_cfg[i].max_tx_queues = nic_info.max_tx_ques;
709 np_cfg[i].max_rx_queues = nic_info.max_rx_ques;
710 }
319ecf12 711
ec079a07
SC
712 memcpy(buf, &np_cfg, size);
713 return size;
714}
715
b66e29c9
SC
716static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
717 struct kobject *kobj,
718 struct bin_attribute *attr,
719 char *buf, loff_t offset,
720 size_t size)
ec079a07
SC
721{
722 struct device *dev = container_of(kobj, struct device, kobj);
723 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
724 struct qlcnic_esw_statistics port_stats;
725 int ret;
726
319ecf12
SC
727 if (qlcnic_83xx_check(adapter))
728 return QLC_STATUS_UNSUPPORTED_CMD;
729
ec079a07
SC
730 if (size != sizeof(struct qlcnic_esw_statistics))
731 return QL_STATUS_INVALID_PARAM;
732
733 if (offset >= QLCNIC_MAX_PCI_FUNC)
734 return QL_STATUS_INVALID_PARAM;
735
736 memset(&port_stats, 0, size);
737 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
b66e29c9 738 &port_stats.rx);
ec079a07
SC
739 if (ret)
740 return ret;
741
742 ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
b66e29c9 743 &port_stats.tx);
ec079a07
SC
744 if (ret)
745 return ret;
746
747 memcpy(buf, &port_stats, size);
748 return size;
749}
750
b66e29c9
SC
751static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
752 struct kobject *kobj,
753 struct bin_attribute *attr,
754 char *buf, loff_t offset,
755 size_t size)
ec079a07
SC
756{
757 struct device *dev = container_of(kobj, struct device, kobj);
758 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
759 struct qlcnic_esw_statistics esw_stats;
760 int ret;
761
319ecf12
SC
762 if (qlcnic_83xx_check(adapter))
763 return QLC_STATUS_UNSUPPORTED_CMD;
764
ec079a07
SC
765 if (size != sizeof(struct qlcnic_esw_statistics))
766 return QL_STATUS_INVALID_PARAM;
767
768 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
769 return QL_STATUS_INVALID_PARAM;
770
771 memset(&esw_stats, 0, size);
772 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
b66e29c9 773 &esw_stats.rx);
ec079a07
SC
774 if (ret)
775 return ret;
776
777 ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
b66e29c9 778 &esw_stats.tx);
ec079a07
SC
779 if (ret)
780 return ret;
781
782 memcpy(buf, &esw_stats, size);
783 return size;
784}
785
b66e29c9
SC
786static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
787 struct kobject *kobj,
788 struct bin_attribute *attr,
789 char *buf, loff_t offset,
790 size_t size)
ec079a07
SC
791{
792 struct device *dev = container_of(kobj, struct device, kobj);
793 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
794 int ret;
795
319ecf12
SC
796 if (qlcnic_83xx_check(adapter))
797 return QLC_STATUS_UNSUPPORTED_CMD;
798
ec079a07
SC
799 if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
800 return QL_STATUS_INVALID_PARAM;
801
802 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
b66e29c9 803 QLCNIC_QUERY_RX_COUNTER);
ec079a07
SC
804 if (ret)
805 return ret;
806
807 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
b66e29c9 808 QLCNIC_QUERY_TX_COUNTER);
ec079a07
SC
809 if (ret)
810 return ret;
811
812 return size;
813}
814
b66e29c9
SC
815static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
816 struct kobject *kobj,
817 struct bin_attribute *attr,
818 char *buf, loff_t offset,
819 size_t size)
ec079a07 820{
319ecf12 821
ec079a07
SC
822 struct device *dev = container_of(kobj, struct device, kobj);
823 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
824 int ret;
825
319ecf12
SC
826 if (qlcnic_83xx_check(adapter))
827 return QLC_STATUS_UNSUPPORTED_CMD;
828
ec079a07
SC
829 if (offset >= QLCNIC_MAX_PCI_FUNC)
830 return QL_STATUS_INVALID_PARAM;
831
832 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
b66e29c9 833 QLCNIC_QUERY_RX_COUNTER);
ec079a07
SC
834 if (ret)
835 return ret;
836
837 ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
b66e29c9 838 QLCNIC_QUERY_TX_COUNTER);
ec079a07
SC
839 if (ret)
840 return ret;
841
842 return size;
843}
844
b66e29c9
SC
845static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
846 struct kobject *kobj,
847 struct bin_attribute *attr,
848 char *buf, loff_t offset,
849 size_t size)
ec079a07
SC
850{
851 struct device *dev = container_of(kobj, struct device, kobj);
852 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
853 struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC];
854 struct qlcnic_pci_info *pci_info;
855 int i, ret;
856
857 if (size != sizeof(pci_cfg))
858 return QL_STATUS_INVALID_PARAM;
859
860 pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL);
861 if (!pci_info)
862 return -ENOMEM;
863
864 ret = qlcnic_get_pci_info(adapter, pci_info);
865 if (ret) {
866 kfree(pci_info);
867 return ret;
868 }
869
319ecf12
SC
870 memset(&pci_cfg, 0,
871 sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC);
872
873 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
ec079a07
SC
874 pci_cfg[i].pci_func = pci_info[i].id;
875 pci_cfg[i].func_type = pci_info[i].type;
876 pci_cfg[i].port_num = pci_info[i].default_port;
877 pci_cfg[i].min_bw = pci_info[i].tx_min_bw;
878 pci_cfg[i].max_bw = pci_info[i].tx_max_bw;
879 memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN);
880 }
319ecf12 881
ec079a07
SC
882 memcpy(buf, &pci_cfg, size);
883 kfree(pci_info);
884 return size;
885}
886
a520030e
HM
887static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
888 struct kobject *kobj,
889 struct bin_attribute *attr,
890 char *buf, loff_t offset,
891 size_t size)
892{
893 unsigned char *p_read_buf;
894 int ret, count;
895 struct device *dev = container_of(kobj, struct device, kobj);
896 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
897
898 if (!size)
899 return QL_STATUS_INVALID_PARAM;
900 if (!buf)
901 return QL_STATUS_INVALID_PARAM;
902
903 count = size / sizeof(u32);
904
905 if (size % sizeof(u32))
906 count++;
907
908 p_read_buf = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
909 if (!p_read_buf)
910 return -ENOMEM;
911 if (qlcnic_83xx_lock_flash(adapter) != 0) {
912 kfree(p_read_buf);
913 return -EIO;
914 }
915
916 ret = qlcnic_83xx_lockless_flash_read32(adapter, offset, p_read_buf,
917 count);
918
919 if (ret) {
920 qlcnic_83xx_unlock_flash(adapter);
921 kfree(p_read_buf);
922 return ret;
923 }
924
925 qlcnic_83xx_unlock_flash(adapter);
926 memcpy(buf, p_read_buf, size);
927 kfree(p_read_buf);
928
929 return size;
930}
931
932static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter *adapter,
933 char *buf, loff_t offset,
934 size_t size)
935{
936 int i, ret, count;
937 unsigned char *p_cache, *p_src;
938
939 p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
940 if (!p_cache)
941 return -ENOMEM;
942
943 memcpy(p_cache, buf, size);
944 p_src = p_cache;
945 count = size / sizeof(u32);
946
947 if (qlcnic_83xx_lock_flash(adapter) != 0) {
948 kfree(p_cache);
949 return -EIO;
950 }
951
952 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
953 ret = qlcnic_83xx_enable_flash_write(adapter);
954 if (ret) {
955 kfree(p_cache);
956 qlcnic_83xx_unlock_flash(adapter);
957 return -EIO;
958 }
959 }
960
961 for (i = 0; i < count / QLC_83XX_FLASH_WRITE_MAX; i++) {
962 ret = qlcnic_83xx_flash_bulk_write(adapter, offset,
963 (u32 *)p_src,
964 QLC_83XX_FLASH_WRITE_MAX);
965
966 if (ret) {
967 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
968 ret = qlcnic_83xx_disable_flash_write(adapter);
969 if (ret) {
970 kfree(p_cache);
971 qlcnic_83xx_unlock_flash(adapter);
972 return -EIO;
973 }
974 }
975
976 kfree(p_cache);
977 qlcnic_83xx_unlock_flash(adapter);
978 return -EIO;
979 }
980
981 p_src = p_src + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
982 offset = offset + sizeof(u32)*QLC_83XX_FLASH_WRITE_MAX;
983 }
984
985 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
986 ret = qlcnic_83xx_disable_flash_write(adapter);
987 if (ret) {
988 kfree(p_cache);
989 qlcnic_83xx_unlock_flash(adapter);
990 return -EIO;
991 }
992 }
993
994 kfree(p_cache);
995 qlcnic_83xx_unlock_flash(adapter);
996
997 return 0;
998}
999
1000static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter *adapter,
1001 char *buf, loff_t offset, size_t size)
1002{
1003 int i, ret, count;
1004 unsigned char *p_cache, *p_src;
1005
1006 p_cache = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
1007 if (!p_cache)
1008 return -ENOMEM;
1009
1010 memcpy(p_cache, buf, size);
1011 p_src = p_cache;
1012 count = size / sizeof(u32);
1013
1014 if (qlcnic_83xx_lock_flash(adapter) != 0) {
1015 kfree(p_cache);
1016 return -EIO;
1017 }
1018
1019 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1020 ret = qlcnic_83xx_enable_flash_write(adapter);
1021 if (ret) {
1022 kfree(p_cache);
1023 qlcnic_83xx_unlock_flash(adapter);
1024 return -EIO;
1025 }
1026 }
1027
1028 for (i = 0; i < count; i++) {
1029 ret = qlcnic_83xx_flash_write32(adapter, offset, (u32 *)p_src);
1030 if (ret) {
1031 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1032 ret = qlcnic_83xx_disable_flash_write(adapter);
1033 if (ret) {
1034 kfree(p_cache);
1035 qlcnic_83xx_unlock_flash(adapter);
1036 return -EIO;
1037 }
1038 }
1039 kfree(p_cache);
1040 qlcnic_83xx_unlock_flash(adapter);
1041 return -EIO;
1042 }
1043
1044 p_src = p_src + sizeof(u32);
1045 offset = offset + sizeof(u32);
1046 }
1047
1048 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
1049 ret = qlcnic_83xx_disable_flash_write(adapter);
1050 if (ret) {
1051 kfree(p_cache);
1052 qlcnic_83xx_unlock_flash(adapter);
1053 return -EIO;
1054 }
1055 }
1056
1057 kfree(p_cache);
1058 qlcnic_83xx_unlock_flash(adapter);
1059
1060 return 0;
1061}
1062
1063static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
1064 struct kobject *kobj,
1065 struct bin_attribute *attr,
1066 char *buf, loff_t offset,
1067 size_t size)
1068{
1069 int ret;
1070 static int flash_mode;
1071 unsigned long data;
1072 struct device *dev = container_of(kobj, struct device, kobj);
1073 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
1074
1075 if (!buf)
1076 return QL_STATUS_INVALID_PARAM;
1077
1078 ret = kstrtoul(buf, 16, &data);
1079
1080 switch (data) {
1081 case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
1082 flash_mode = QLC_83XX_ERASE_MODE;
1083 ret = qlcnic_83xx_erase_flash_sector(adapter, offset);
1084 if (ret) {
1085 dev_err(&adapter->pdev->dev,
1086 "%s failed at %d\n", __func__, __LINE__);
1087 return -EIO;
1088 }
1089 break;
1090
1091 case QLC_83XX_FLASH_BULK_WRITE_CMD:
1092 flash_mode = QLC_83XX_BULK_WRITE_MODE;
1093 break;
1094
1095 case QLC_83XX_FLASH_WRITE_CMD:
1096 flash_mode = QLC_83XX_WRITE_MODE;
1097 break;
1098 default:
1099 if (flash_mode == QLC_83XX_BULK_WRITE_MODE) {
1100 ret = qlcnic_83xx_sysfs_flash_bulk_write(adapter, buf,
1101 offset, size);
1102 if (ret) {
1103 dev_err(&adapter->pdev->dev,
1104 "%s failed at %d\n",
1105 __func__, __LINE__);
1106 return -EIO;
1107 }
1108 }
1109
1110 if (flash_mode == QLC_83XX_WRITE_MODE) {
1111 ret = qlcnic_83xx_sysfs_flash_write(adapter, buf,
1112 offset, size);
1113 if (ret) {
1114 dev_err(&adapter->pdev->dev,
1115 "%s failed at %d\n", __func__,
1116 __LINE__);
1117 return -EIO;
1118 }
1119 }
1120 }
1121
1122 return size;
1123}
1124
ec079a07
SC
1125static struct device_attribute dev_attr_bridged_mode = {
1126 .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
1127 .show = qlcnic_show_bridged_mode,
1128 .store = qlcnic_store_bridged_mode,
1129};
1130
1131static struct device_attribute dev_attr_diag_mode = {
1132 .attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
1133 .show = qlcnic_show_diag_mode,
1134 .store = qlcnic_store_diag_mode,
1135};
1136
1137static struct device_attribute dev_attr_beacon = {
1138 .attr = {.name = "beacon", .mode = (S_IRUGO | S_IWUSR)},
1139 .show = qlcnic_show_beacon,
1140 .store = qlcnic_store_beacon,
1141};
1142
1143static struct bin_attribute bin_attr_crb = {
1144 .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
1145 .size = 0,
1146 .read = qlcnic_sysfs_read_crb,
1147 .write = qlcnic_sysfs_write_crb,
1148};
1149
1150static struct bin_attribute bin_attr_mem = {
1151 .attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
1152 .size = 0,
1153 .read = qlcnic_sysfs_read_mem,
1154 .write = qlcnic_sysfs_write_mem,
1155};
1156
1157static struct bin_attribute bin_attr_npar_config = {
1158 .attr = {.name = "npar_config", .mode = (S_IRUGO | S_IWUSR)},
1159 .size = 0,
1160 .read = qlcnic_sysfs_read_npar_config,
1161 .write = qlcnic_sysfs_write_npar_config,
1162};
1163
1164static struct bin_attribute bin_attr_pci_config = {
1165 .attr = {.name = "pci_config", .mode = (S_IRUGO | S_IWUSR)},
1166 .size = 0,
1167 .read = qlcnic_sysfs_read_pci_config,
1168 .write = NULL,
1169};
1170
1171static struct bin_attribute bin_attr_port_stats = {
1172 .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
1173 .size = 0,
1174 .read = qlcnic_sysfs_get_port_stats,
1175 .write = qlcnic_sysfs_clear_port_stats,
1176};
1177
1178static struct bin_attribute bin_attr_esw_stats = {
1179 .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
1180 .size = 0,
1181 .read = qlcnic_sysfs_get_esw_stats,
1182 .write = qlcnic_sysfs_clear_esw_stats,
1183};
1184
1185static struct bin_attribute bin_attr_esw_config = {
1186 .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
1187 .size = 0,
1188 .read = qlcnic_sysfs_read_esw_config,
1189 .write = qlcnic_sysfs_write_esw_config,
1190};
1191
1192static struct bin_attribute bin_attr_pm_config = {
1193 .attr = {.name = "pm_config", .mode = (S_IRUGO | S_IWUSR)},
1194 .size = 0,
1195 .read = qlcnic_sysfs_read_pm_config,
1196 .write = qlcnic_sysfs_write_pm_config,
1197};
1198
a520030e
HM
1199static struct bin_attribute bin_attr_flash = {
1200 .attr = {.name = "flash", .mode = (S_IRUGO | S_IWUSR)},
1201 .size = 0,
1202 .read = qlcnic_83xx_sysfs_flash_read_handler,
1203 .write = qlcnic_83xx_sysfs_flash_write_handler,
1204};
1205
ec079a07
SC
1206void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
1207{
1208 struct device *dev = &adapter->pdev->dev;
1209
79788450 1210 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
ec079a07
SC
1211 if (device_create_file(dev, &dev_attr_bridged_mode))
1212 dev_warn(dev,
b66e29c9 1213 "failed to create bridged_mode sysfs entry\n");
ec079a07
SC
1214}
1215
1216void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter)
1217{
1218 struct device *dev = &adapter->pdev->dev;
1219
79788450 1220 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_BDG)
ec079a07
SC
1221 device_remove_file(dev, &dev_attr_bridged_mode);
1222}
1223
1224void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
1225{
1226 struct device *dev = &adapter->pdev->dev;
ec079a07
SC
1227
1228 if (device_create_bin_file(dev, &bin_attr_port_stats))
1229 dev_info(dev, "failed to create port stats sysfs entry");
1230
79788450 1231 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
ec079a07
SC
1232 return;
1233 if (device_create_file(dev, &dev_attr_diag_mode))
1234 dev_info(dev, "failed to create diag_mode sysfs entry\n");
1235 if (device_create_bin_file(dev, &bin_attr_crb))
1236 dev_info(dev, "failed to create crb sysfs entry\n");
1237 if (device_create_bin_file(dev, &bin_attr_mem))
1238 dev_info(dev, "failed to create mem sysfs entry\n");
1239
ec079a07
SC
1240 if (device_create_bin_file(dev, &bin_attr_pci_config))
1241 dev_info(dev, "failed to create pci config sysfs entry");
1242 if (device_create_file(dev, &dev_attr_beacon))
1243 dev_info(dev, "failed to create beacon sysfs entry");
1244
1245 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1246 return;
1247 if (device_create_bin_file(dev, &bin_attr_esw_config))
1248 dev_info(dev, "failed to create esw config sysfs entry");
79788450 1249 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
ec079a07
SC
1250 return;
1251 if (device_create_bin_file(dev, &bin_attr_npar_config))
1252 dev_info(dev, "failed to create npar config sysfs entry");
1253 if (device_create_bin_file(dev, &bin_attr_pm_config))
1254 dev_info(dev, "failed to create pm config sysfs entry");
1255 if (device_create_bin_file(dev, &bin_attr_esw_stats))
1256 dev_info(dev, "failed to create eswitch stats sysfs entry");
1257}
1258
1259void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
1260{
1261 struct device *dev = &adapter->pdev->dev;
ec079a07
SC
1262
1263 device_remove_bin_file(dev, &bin_attr_port_stats);
1264
79788450 1265 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC)
ec079a07
SC
1266 return;
1267 device_remove_file(dev, &dev_attr_diag_mode);
1268 device_remove_bin_file(dev, &bin_attr_crb);
1269 device_remove_bin_file(dev, &bin_attr_mem);
ec079a07
SC
1270 device_remove_bin_file(dev, &bin_attr_pci_config);
1271 device_remove_file(dev, &dev_attr_beacon);
1272 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
1273 return;
1274 device_remove_bin_file(dev, &bin_attr_esw_config);
79788450 1275 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
ec079a07
SC
1276 return;
1277 device_remove_bin_file(dev, &bin_attr_npar_config);
1278 device_remove_bin_file(dev, &bin_attr_pm_config);
1279 device_remove_bin_file(dev, &bin_attr_esw_stats);
1280}
7e2cf4fe
SC
1281
1282void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter)
1283{
1284 qlcnic_create_diag_entries(adapter);
1285}
1286
1287void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter)
1288{
1289 qlcnic_remove_diag_entries(adapter);
1290}
319ecf12
SC
1291
1292void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter)
1293{
a520030e
HM
1294 struct device *dev = &adapter->pdev->dev;
1295
319ecf12 1296 qlcnic_create_diag_entries(adapter);
a520030e
HM
1297
1298 if (sysfs_create_bin_file(&dev->kobj, &bin_attr_flash))
1299 dev_info(dev, "failed to create flash sysfs entry\n");
319ecf12
SC
1300}
1301
1302void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter)
1303{
a520030e
HM
1304 struct device *dev = &adapter->pdev->dev;
1305
319ecf12 1306 qlcnic_remove_diag_entries(adapter);
a520030e 1307 sysfs_remove_bin_file(&dev->kobj, &bin_attr_flash);
319ecf12 1308}