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