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