2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
5 * See LICENSE.qlcnic for copyright and licensing details.
8 #include <linux/slab.h>
9 #include <linux/vmalloc.h>
10 #include <linux/interrupt.h>
13 #include "qlcnic_hw.h"
15 #include <linux/swab.h>
16 #include <linux/dma-mapping.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>
24 #include <linux/sysfs.h>
26 #define QLC_STATUS_UNSUPPORTED_CMD -2
28 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter
*adapter
, u32 enable
)
33 int qlcnicvf_config_led(struct qlcnic_adapter
*adapter
, u32 state
, u32 rate
)
38 static ssize_t
qlcnic_store_bridged_mode(struct device
*dev
,
39 struct device_attribute
*attr
,
40 const char *buf
, size_t len
)
42 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
46 if (!(adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
))
49 if (!test_bit(__QLCNIC_DEV_UP
, &adapter
->state
))
52 if (strict_strtoul(buf
, 2, &new))
55 if (!qlcnic_config_bridged_mode(adapter
, !!new))
62 static ssize_t
qlcnic_show_bridged_mode(struct device
*dev
,
63 struct device_attribute
*attr
,
66 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
69 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
70 bridged_mode
= !!(adapter
->flags
& QLCNIC_BRIDGE_ENABLED
);
72 return sprintf(buf
, "%d\n", bridged_mode
);
75 static ssize_t
qlcnic_store_diag_mode(struct device
*dev
,
76 struct device_attribute
*attr
,
77 const char *buf
, size_t len
)
79 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
82 if (strict_strtoul(buf
, 2, &new))
85 if (!!new != !!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
86 adapter
->flags
^= QLCNIC_DIAG_ENABLED
;
91 static ssize_t
qlcnic_show_diag_mode(struct device
*dev
,
92 struct device_attribute
*attr
, char *buf
)
94 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
95 return sprintf(buf
, "%d\n", !!(adapter
->flags
& QLCNIC_DIAG_ENABLED
));
98 static int qlcnic_validate_beacon(struct qlcnic_adapter
*adapter
, u16 beacon
,
102 *state
= MSB(beacon
);
104 QLCDB(adapter
, DRV
, "rate %x state %x\n", *rate
, *state
);
107 *rate
= __QLCNIC_MAX_LED_RATE
;
109 } else if (*state
> __QLCNIC_MAX_LED_STATE
) {
113 if ((!*rate
) || (*rate
> __QLCNIC_MAX_LED_RATE
))
119 static ssize_t
qlcnic_store_beacon(struct device
*dev
,
120 struct device_attribute
*attr
,
121 const char *buf
, size_t len
)
123 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
124 struct qlcnic_hardware_context
*ahw
= adapter
->ahw
;
125 int err
, max_sds_rings
= adapter
->max_sds_rings
;
128 unsigned long h_beacon
;
130 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
) {
132 "LED test not supported in non privileged mode\n");
136 if (qlcnic_83xx_check(adapter
) &&
137 !test_bit(__QLCNIC_RESETTING
, &adapter
->state
)) {
138 if (kstrtoul(buf
, 2, &h_beacon
))
141 if (ahw
->beacon_state
== h_beacon
)
145 if (!ahw
->beacon_state
) {
146 if (test_and_set_bit(__QLCNIC_LED_ENABLE
,
153 err
= qlcnic_83xx_config_led(adapter
, 1, h_beacon
);
157 err
= qlcnic_83xx_config_led(adapter
, 0, !h_beacon
);
161 /* set the current beacon state */
162 ahw
->beacon_state
= h_beacon
;
164 if (!ahw
->beacon_state
)
165 clear_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
);
171 if (len
!= sizeof(u16
))
172 return QL_STATUS_INVALID_PARAM
;
174 memcpy(&beacon
, buf
, sizeof(u16
));
175 err
= qlcnic_validate_beacon(adapter
, beacon
, &b_state
, &b_rate
);
179 if (adapter
->ahw
->beacon_state
== b_state
)
184 if (!adapter
->ahw
->beacon_state
)
185 if (test_and_set_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
)) {
190 if (test_bit(__QLCNIC_RESETTING
, &adapter
->state
)) {
195 if (!test_bit(__QLCNIC_DEV_UP
, &adapter
->state
)) {
196 err
= qlcnic_diag_alloc_res(adapter
->netdev
, QLCNIC_LED_TEST
);
199 set_bit(__QLCNIC_DIAG_RES_ALLOC
, &adapter
->state
);
202 err
= qlcnic_config_led(adapter
, b_state
, b_rate
);
206 ahw
->beacon_state
= b_state
;
208 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC
, &adapter
->state
))
209 qlcnic_diag_free_res(adapter
->netdev
, max_sds_rings
);
212 if (!adapter
->ahw
->beacon_state
)
213 clear_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
);
219 static ssize_t
qlcnic_show_beacon(struct device
*dev
,
220 struct device_attribute
*attr
, char *buf
)
222 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
224 return sprintf(buf
, "%d\n", adapter
->ahw
->beacon_state
);
227 static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter
*adapter
,
228 loff_t offset
, size_t size
)
232 if (!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
235 if (offset
< QLCNIC_PCI_CRBSPACE
) {
236 if (ADDR_IN_RANGE(offset
, QLCNIC_PCI_CAMQM
,
237 QLCNIC_PCI_CAMQM_END
))
243 if ((size
!= crb_size
) || (offset
& (crb_size
-1)))
249 static ssize_t
qlcnic_sysfs_read_crb(struct file
*filp
, struct kobject
*kobj
,
250 struct bin_attribute
*attr
, char *buf
,
251 loff_t offset
, size_t size
)
253 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
254 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
257 ret
= qlcnic_sysfs_validate_crb(adapter
, offset
, size
);
260 qlcnic_read_crb(adapter
, buf
, offset
, size
);
265 static ssize_t
qlcnic_sysfs_write_crb(struct file
*filp
, struct kobject
*kobj
,
266 struct bin_attribute
*attr
, char *buf
,
267 loff_t offset
, size_t size
)
269 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
270 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
273 ret
= qlcnic_sysfs_validate_crb(adapter
, offset
, size
);
277 qlcnic_write_crb(adapter
, buf
, offset
, size
);
281 static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter
*adapter
,
282 loff_t offset
, size_t size
)
284 if (!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
287 if ((size
!= 8) || (offset
& 0x7))
293 static ssize_t
qlcnic_sysfs_read_mem(struct file
*filp
, struct kobject
*kobj
,
294 struct bin_attribute
*attr
, char *buf
,
295 loff_t offset
, size_t size
)
297 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
298 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
302 ret
= qlcnic_sysfs_validate_mem(adapter
, offset
, size
);
306 if (qlcnic_pci_mem_read_2M(adapter
, offset
, &data
))
309 memcpy(buf
, &data
, size
);
314 static ssize_t
qlcnic_sysfs_write_mem(struct file
*filp
, struct kobject
*kobj
,
315 struct bin_attribute
*attr
, char *buf
,
316 loff_t offset
, size_t size
)
318 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
319 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
323 ret
= qlcnic_sysfs_validate_mem(adapter
, offset
, size
);
327 memcpy(&data
, buf
, size
);
329 if (qlcnic_pci_mem_write_2M(adapter
, offset
, data
))
335 static int qlcnic_is_valid_nic_func(struct qlcnic_adapter
*adapter
, u8 pci_func
)
338 for (i
= 0; i
< adapter
->ahw
->act_pci_func
; i
++) {
339 if (adapter
->npars
[i
].pci_func
== pci_func
)
346 static int validate_pm_config(struct qlcnic_adapter
*adapter
,
347 struct qlcnic_pm_func_cfg
*pm_cfg
, int count
)
349 u8 src_pci_func
, s_esw_id
, d_esw_id
;
351 int i
, src_index
, dest_index
;
353 for (i
= 0; i
< count
; i
++) {
354 src_pci_func
= pm_cfg
[i
].pci_func
;
355 dest_pci_func
= pm_cfg
[i
].dest_npar
;
356 src_index
= qlcnic_is_valid_nic_func(adapter
, src_pci_func
);
359 return QL_STATUS_INVALID_PARAM
;
361 dest_index
= qlcnic_is_valid_nic_func(adapter
, dest_pci_func
);
363 return QL_STATUS_INVALID_PARAM
;
365 s_esw_id
= adapter
->npars
[src_index
].phy_port
;
366 d_esw_id
= adapter
->npars
[dest_index
].phy_port
;
368 if (s_esw_id
!= d_esw_id
)
369 return QL_STATUS_INVALID_PARAM
;
375 static ssize_t
qlcnic_sysfs_write_pm_config(struct file
*filp
,
376 struct kobject
*kobj
,
377 struct bin_attribute
*attr
,
378 char *buf
, loff_t offset
,
381 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
382 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
383 struct qlcnic_pm_func_cfg
*pm_cfg
;
384 u32 id
, action
, pci_func
;
385 int count
, rem
, i
, ret
, index
;
387 count
= size
/ sizeof(struct qlcnic_pm_func_cfg
);
388 rem
= size
% sizeof(struct qlcnic_pm_func_cfg
);
390 return QL_STATUS_INVALID_PARAM
;
392 pm_cfg
= (struct qlcnic_pm_func_cfg
*)buf
;
393 ret
= validate_pm_config(adapter
, pm_cfg
, count
);
397 for (i
= 0; i
< count
; i
++) {
398 pci_func
= pm_cfg
[i
].pci_func
;
399 action
= !!pm_cfg
[i
].action
;
400 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
402 return QL_STATUS_INVALID_PARAM
;
404 id
= adapter
->npars
[index
].phy_port
;
405 ret
= qlcnic_config_port_mirroring(adapter
, id
,
411 for (i
= 0; i
< count
; i
++) {
412 pci_func
= pm_cfg
[i
].pci_func
;
413 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
414 id
= adapter
->npars
[index
].phy_port
;
415 adapter
->npars
[index
].enable_pm
= !!pm_cfg
[i
].action
;
416 adapter
->npars
[index
].dest_npar
= id
;
422 static ssize_t
qlcnic_sysfs_read_pm_config(struct file
*filp
,
423 struct kobject
*kobj
,
424 struct bin_attribute
*attr
,
425 char *buf
, loff_t offset
,
428 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
429 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
430 struct qlcnic_pm_func_cfg pm_cfg
[QLCNIC_MAX_PCI_FUNC
];
434 if (size
!= sizeof(pm_cfg
))
435 return QL_STATUS_INVALID_PARAM
;
438 sizeof(struct qlcnic_pm_func_cfg
) * QLCNIC_MAX_PCI_FUNC
);
440 for (i
= 0; i
< adapter
->ahw
->act_pci_func
; i
++) {
441 pci_func
= adapter
->npars
[i
].pci_func
;
442 pm_cfg
[pci_func
].action
= adapter
->npars
[i
].enable_pm
;
443 pm_cfg
[pci_func
].dest_npar
= 0;
444 pm_cfg
[pci_func
].pci_func
= i
;
446 memcpy(buf
, &pm_cfg
, size
);
451 static int validate_esw_config(struct qlcnic_adapter
*adapter
,
452 struct qlcnic_esw_func_cfg
*esw_cfg
, int count
)
458 if (qlcnic_82xx_check(adapter
))
459 op_mode
= readl(adapter
->ahw
->pci_base0
+ QLCNIC_DRV_OP_MODE
);
461 op_mode
= QLCRDX(adapter
->ahw
, QLC_83XX_DRV_OP_MODE
);
463 for (i
= 0; i
< count
; i
++) {
464 pci_func
= esw_cfg
[i
].pci_func
;
465 if (pci_func
>= QLCNIC_MAX_PCI_FUNC
)
466 return QL_STATUS_INVALID_PARAM
;
468 if (adapter
->ahw
->op_mode
== QLCNIC_MGMT_FUNC
)
469 if (qlcnic_is_valid_nic_func(adapter
, pci_func
) < 0)
470 return QL_STATUS_INVALID_PARAM
;
472 switch (esw_cfg
[i
].op_mode
) {
473 case QLCNIC_PORT_DEFAULTS
:
474 if (qlcnic_82xx_check(adapter
)) {
475 ret
= QLC_DEV_GET_DRV(op_mode
, pci_func
);
477 ret
= QLC_83XX_GET_FUNC_PRIVILEGE(op_mode
,
479 esw_cfg
[i
].offload_flags
= 0;
482 if (ret
!= QLCNIC_NON_PRIV_FUNC
) {
483 if (esw_cfg
[i
].mac_anti_spoof
!= 0)
484 return QL_STATUS_INVALID_PARAM
;
485 if (esw_cfg
[i
].mac_override
!= 1)
486 return QL_STATUS_INVALID_PARAM
;
487 if (esw_cfg
[i
].promisc_mode
!= 1)
488 return QL_STATUS_INVALID_PARAM
;
491 case QLCNIC_ADD_VLAN
:
492 if (!IS_VALID_VLAN(esw_cfg
[i
].vlan_id
))
493 return QL_STATUS_INVALID_PARAM
;
494 if (!esw_cfg
[i
].op_type
)
495 return QL_STATUS_INVALID_PARAM
;
497 case QLCNIC_DEL_VLAN
:
498 if (!esw_cfg
[i
].op_type
)
499 return QL_STATUS_INVALID_PARAM
;
502 return QL_STATUS_INVALID_PARAM
;
509 static ssize_t
qlcnic_sysfs_write_esw_config(struct file
*file
,
510 struct kobject
*kobj
,
511 struct bin_attribute
*attr
,
512 char *buf
, loff_t offset
,
515 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
516 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
517 struct qlcnic_esw_func_cfg
*esw_cfg
;
518 struct qlcnic_npar_info
*npar
;
519 int count
, rem
, i
, ret
;
521 u8 op_mode
= 0, pci_func
;
523 count
= size
/ sizeof(struct qlcnic_esw_func_cfg
);
524 rem
= size
% sizeof(struct qlcnic_esw_func_cfg
);
526 return QL_STATUS_INVALID_PARAM
;
528 esw_cfg
= (struct qlcnic_esw_func_cfg
*)buf
;
529 ret
= validate_esw_config(adapter
, esw_cfg
, count
);
533 for (i
= 0; i
< count
; i
++) {
534 if (adapter
->ahw
->op_mode
== QLCNIC_MGMT_FUNC
)
535 if (qlcnic_config_switch_port(adapter
, &esw_cfg
[i
]))
536 return QL_STATUS_INVALID_PARAM
;
538 if (adapter
->ahw
->pci_func
!= esw_cfg
[i
].pci_func
)
541 op_mode
= esw_cfg
[i
].op_mode
;
542 qlcnic_get_eswitch_port_config(adapter
, &esw_cfg
[i
]);
543 esw_cfg
[i
].op_mode
= op_mode
;
544 esw_cfg
[i
].pci_func
= adapter
->ahw
->pci_func
;
546 switch (esw_cfg
[i
].op_mode
) {
547 case QLCNIC_PORT_DEFAULTS
:
548 qlcnic_set_eswitch_port_features(adapter
, &esw_cfg
[i
]);
550 case QLCNIC_ADD_VLAN
:
551 qlcnic_set_vlan_config(adapter
, &esw_cfg
[i
]);
553 case QLCNIC_DEL_VLAN
:
554 esw_cfg
[i
].vlan_id
= 0;
555 qlcnic_set_vlan_config(adapter
, &esw_cfg
[i
]);
560 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
563 for (i
= 0; i
< count
; i
++) {
564 pci_func
= esw_cfg
[i
].pci_func
;
565 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
566 npar
= &adapter
->npars
[index
];
567 switch (esw_cfg
[i
].op_mode
) {
568 case QLCNIC_PORT_DEFAULTS
:
569 npar
->promisc_mode
= esw_cfg
[i
].promisc_mode
;
570 npar
->mac_override
= esw_cfg
[i
].mac_override
;
571 npar
->offload_flags
= esw_cfg
[i
].offload_flags
;
572 npar
->mac_anti_spoof
= esw_cfg
[i
].mac_anti_spoof
;
573 npar
->discard_tagged
= esw_cfg
[i
].discard_tagged
;
575 case QLCNIC_ADD_VLAN
:
576 npar
->pvid
= esw_cfg
[i
].vlan_id
;
578 case QLCNIC_DEL_VLAN
:
587 static ssize_t
qlcnic_sysfs_read_esw_config(struct file
*file
,
588 struct kobject
*kobj
,
589 struct bin_attribute
*attr
,
590 char *buf
, loff_t offset
,
593 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
594 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
595 struct qlcnic_esw_func_cfg esw_cfg
[QLCNIC_MAX_PCI_FUNC
];
598 if (size
!= sizeof(esw_cfg
))
599 return QL_STATUS_INVALID_PARAM
;
602 sizeof(struct qlcnic_esw_func_cfg
) * QLCNIC_MAX_PCI_FUNC
);
604 for (i
= 0; i
< adapter
->ahw
->act_pci_func
; i
++) {
605 pci_func
= adapter
->npars
[i
].pci_func
;
606 esw_cfg
[pci_func
].pci_func
= pci_func
;
607 if (qlcnic_get_eswitch_port_config(adapter
, &esw_cfg
[pci_func
]))
608 return QL_STATUS_INVALID_PARAM
;
611 memcpy(buf
, &esw_cfg
, size
);
616 static int validate_npar_config(struct qlcnic_adapter
*adapter
,
617 struct qlcnic_npar_func_cfg
*np_cfg
,
622 for (i
= 0; i
< count
; i
++) {
623 pci_func
= np_cfg
[i
].pci_func
;
624 if (qlcnic_is_valid_nic_func(adapter
, pci_func
) < 0)
625 return QL_STATUS_INVALID_PARAM
;
627 if (!IS_VALID_BW(np_cfg
[i
].min_bw
) ||
628 !IS_VALID_BW(np_cfg
[i
].max_bw
))
629 return QL_STATUS_INVALID_PARAM
;
634 static ssize_t
qlcnic_sysfs_write_npar_config(struct file
*file
,
635 struct kobject
*kobj
,
636 struct bin_attribute
*attr
,
637 char *buf
, loff_t offset
,
640 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
641 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
642 struct qlcnic_info nic_info
;
643 struct qlcnic_npar_func_cfg
*np_cfg
;
644 int i
, count
, rem
, ret
, index
;
647 count
= size
/ sizeof(struct qlcnic_npar_func_cfg
);
648 rem
= size
% sizeof(struct qlcnic_npar_func_cfg
);
650 return QL_STATUS_INVALID_PARAM
;
652 np_cfg
= (struct qlcnic_npar_func_cfg
*)buf
;
653 ret
= validate_npar_config(adapter
, np_cfg
, count
);
657 for (i
= 0; i
< count
; i
++) {
658 pci_func
= np_cfg
[i
].pci_func
;
660 memset(&nic_info
, 0, sizeof(struct qlcnic_info
));
661 ret
= qlcnic_get_nic_info(adapter
, &nic_info
, pci_func
);
664 nic_info
.pci_func
= pci_func
;
665 nic_info
.min_tx_bw
= np_cfg
[i
].min_bw
;
666 nic_info
.max_tx_bw
= np_cfg
[i
].max_bw
;
667 ret
= qlcnic_set_nic_info(adapter
, &nic_info
);
670 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
671 adapter
->npars
[index
].min_bw
= nic_info
.min_tx_bw
;
672 adapter
->npars
[index
].max_bw
= nic_info
.max_tx_bw
;
678 static ssize_t
qlcnic_sysfs_read_npar_config(struct file
*file
,
679 struct kobject
*kobj
,
680 struct bin_attribute
*attr
,
681 char *buf
, loff_t offset
,
684 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
685 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
686 struct qlcnic_info nic_info
;
687 struct qlcnic_npar_func_cfg np_cfg
[QLCNIC_MAX_PCI_FUNC
];
690 if (size
!= sizeof(np_cfg
))
691 return QL_STATUS_INVALID_PARAM
;
693 memset(&nic_info
, 0, sizeof(struct qlcnic_info
));
695 sizeof(struct qlcnic_npar_func_cfg
) * QLCNIC_MAX_PCI_FUNC
);
697 for (i
= 0; i
< QLCNIC_MAX_PCI_FUNC
; i
++) {
698 if (qlcnic_is_valid_nic_func(adapter
, i
) < 0)
700 ret
= qlcnic_get_nic_info(adapter
, &nic_info
, i
);
704 np_cfg
[i
].pci_func
= i
;
705 np_cfg
[i
].op_mode
= (u8
)nic_info
.op_mode
;
706 np_cfg
[i
].port_num
= nic_info
.phys_port
;
707 np_cfg
[i
].fw_capab
= nic_info
.capabilities
;
708 np_cfg
[i
].min_bw
= nic_info
.min_tx_bw
;
709 np_cfg
[i
].max_bw
= nic_info
.max_tx_bw
;
710 np_cfg
[i
].max_tx_queues
= nic_info
.max_tx_ques
;
711 np_cfg
[i
].max_rx_queues
= nic_info
.max_rx_ques
;
714 memcpy(buf
, &np_cfg
, size
);
718 static ssize_t
qlcnic_sysfs_get_port_stats(struct file
*file
,
719 struct kobject
*kobj
,
720 struct bin_attribute
*attr
,
721 char *buf
, loff_t offset
,
724 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
725 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
726 struct qlcnic_esw_statistics port_stats
;
729 if (qlcnic_83xx_check(adapter
))
730 return QLC_STATUS_UNSUPPORTED_CMD
;
732 if (size
!= sizeof(struct qlcnic_esw_statistics
))
733 return QL_STATUS_INVALID_PARAM
;
735 if (offset
>= QLCNIC_MAX_PCI_FUNC
)
736 return QL_STATUS_INVALID_PARAM
;
738 memset(&port_stats
, 0, size
);
739 ret
= qlcnic_get_port_stats(adapter
, offset
, QLCNIC_QUERY_RX_COUNTER
,
744 ret
= qlcnic_get_port_stats(adapter
, offset
, QLCNIC_QUERY_TX_COUNTER
,
749 memcpy(buf
, &port_stats
, size
);
753 static ssize_t
qlcnic_sysfs_get_esw_stats(struct file
*file
,
754 struct kobject
*kobj
,
755 struct bin_attribute
*attr
,
756 char *buf
, loff_t offset
,
759 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
760 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
761 struct qlcnic_esw_statistics esw_stats
;
764 if (qlcnic_83xx_check(adapter
))
765 return QLC_STATUS_UNSUPPORTED_CMD
;
767 if (size
!= sizeof(struct qlcnic_esw_statistics
))
768 return QL_STATUS_INVALID_PARAM
;
770 if (offset
>= QLCNIC_NIU_MAX_XG_PORTS
)
771 return QL_STATUS_INVALID_PARAM
;
773 memset(&esw_stats
, 0, size
);
774 ret
= qlcnic_get_eswitch_stats(adapter
, offset
, QLCNIC_QUERY_RX_COUNTER
,
779 ret
= qlcnic_get_eswitch_stats(adapter
, offset
, QLCNIC_QUERY_TX_COUNTER
,
784 memcpy(buf
, &esw_stats
, size
);
788 static ssize_t
qlcnic_sysfs_clear_esw_stats(struct file
*file
,
789 struct kobject
*kobj
,
790 struct bin_attribute
*attr
,
791 char *buf
, loff_t offset
,
794 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
795 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
798 if (qlcnic_83xx_check(adapter
))
799 return QLC_STATUS_UNSUPPORTED_CMD
;
801 if (offset
>= QLCNIC_NIU_MAX_XG_PORTS
)
802 return QL_STATUS_INVALID_PARAM
;
804 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_ESWITCH
, offset
,
805 QLCNIC_QUERY_RX_COUNTER
);
809 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_ESWITCH
, offset
,
810 QLCNIC_QUERY_TX_COUNTER
);
817 static ssize_t
qlcnic_sysfs_clear_port_stats(struct file
*file
,
818 struct kobject
*kobj
,
819 struct bin_attribute
*attr
,
820 char *buf
, loff_t offset
,
824 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
825 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
828 if (qlcnic_83xx_check(adapter
))
829 return QLC_STATUS_UNSUPPORTED_CMD
;
831 if (offset
>= QLCNIC_MAX_PCI_FUNC
)
832 return QL_STATUS_INVALID_PARAM
;
834 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_PORT
, offset
,
835 QLCNIC_QUERY_RX_COUNTER
);
839 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_PORT
, offset
,
840 QLCNIC_QUERY_TX_COUNTER
);
847 static ssize_t
qlcnic_sysfs_read_pci_config(struct file
*file
,
848 struct kobject
*kobj
,
849 struct bin_attribute
*attr
,
850 char *buf
, loff_t offset
,
853 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
854 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
855 struct qlcnic_pci_func_cfg pci_cfg
[QLCNIC_MAX_PCI_FUNC
];
856 struct qlcnic_pci_info
*pci_info
;
859 if (size
!= sizeof(pci_cfg
))
860 return QL_STATUS_INVALID_PARAM
;
862 pci_info
= kcalloc(QLCNIC_MAX_PCI_FUNC
, sizeof(*pci_info
), GFP_KERNEL
);
866 ret
= qlcnic_get_pci_info(adapter
, pci_info
);
873 sizeof(struct qlcnic_pci_func_cfg
) * QLCNIC_MAX_PCI_FUNC
);
875 for (i
= 0; i
< QLCNIC_MAX_PCI_FUNC
; i
++) {
876 pci_cfg
[i
].pci_func
= pci_info
[i
].id
;
877 pci_cfg
[i
].func_type
= pci_info
[i
].type
;
878 pci_cfg
[i
].port_num
= pci_info
[i
].default_port
;
879 pci_cfg
[i
].min_bw
= pci_info
[i
].tx_min_bw
;
880 pci_cfg
[i
].max_bw
= pci_info
[i
].tx_max_bw
;
881 memcpy(&pci_cfg
[i
].def_mac_addr
, &pci_info
[i
].mac
, ETH_ALEN
);
884 memcpy(buf
, &pci_cfg
, size
);
889 static struct device_attribute dev_attr_bridged_mode
= {
890 .attr
= {.name
= "bridged_mode", .mode
= (S_IRUGO
| S_IWUSR
)},
891 .show
= qlcnic_show_bridged_mode
,
892 .store
= qlcnic_store_bridged_mode
,
895 static struct device_attribute dev_attr_diag_mode
= {
896 .attr
= {.name
= "diag_mode", .mode
= (S_IRUGO
| S_IWUSR
)},
897 .show
= qlcnic_show_diag_mode
,
898 .store
= qlcnic_store_diag_mode
,
901 static struct device_attribute dev_attr_beacon
= {
902 .attr
= {.name
= "beacon", .mode
= (S_IRUGO
| S_IWUSR
)},
903 .show
= qlcnic_show_beacon
,
904 .store
= qlcnic_store_beacon
,
907 static struct bin_attribute bin_attr_crb
= {
908 .attr
= {.name
= "crb", .mode
= (S_IRUGO
| S_IWUSR
)},
910 .read
= qlcnic_sysfs_read_crb
,
911 .write
= qlcnic_sysfs_write_crb
,
914 static struct bin_attribute bin_attr_mem
= {
915 .attr
= {.name
= "mem", .mode
= (S_IRUGO
| S_IWUSR
)},
917 .read
= qlcnic_sysfs_read_mem
,
918 .write
= qlcnic_sysfs_write_mem
,
921 static struct bin_attribute bin_attr_npar_config
= {
922 .attr
= {.name
= "npar_config", .mode
= (S_IRUGO
| S_IWUSR
)},
924 .read
= qlcnic_sysfs_read_npar_config
,
925 .write
= qlcnic_sysfs_write_npar_config
,
928 static struct bin_attribute bin_attr_pci_config
= {
929 .attr
= {.name
= "pci_config", .mode
= (S_IRUGO
| S_IWUSR
)},
931 .read
= qlcnic_sysfs_read_pci_config
,
935 static struct bin_attribute bin_attr_port_stats
= {
936 .attr
= {.name
= "port_stats", .mode
= (S_IRUGO
| S_IWUSR
)},
938 .read
= qlcnic_sysfs_get_port_stats
,
939 .write
= qlcnic_sysfs_clear_port_stats
,
942 static struct bin_attribute bin_attr_esw_stats
= {
943 .attr
= {.name
= "esw_stats", .mode
= (S_IRUGO
| S_IWUSR
)},
945 .read
= qlcnic_sysfs_get_esw_stats
,
946 .write
= qlcnic_sysfs_clear_esw_stats
,
949 static struct bin_attribute bin_attr_esw_config
= {
950 .attr
= {.name
= "esw_config", .mode
= (S_IRUGO
| S_IWUSR
)},
952 .read
= qlcnic_sysfs_read_esw_config
,
953 .write
= qlcnic_sysfs_write_esw_config
,
956 static struct bin_attribute bin_attr_pm_config
= {
957 .attr
= {.name
= "pm_config", .mode
= (S_IRUGO
| S_IWUSR
)},
959 .read
= qlcnic_sysfs_read_pm_config
,
960 .write
= qlcnic_sysfs_write_pm_config
,
963 void qlcnic_create_sysfs_entries(struct qlcnic_adapter
*adapter
)
965 struct device
*dev
= &adapter
->pdev
->dev
;
967 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
968 if (device_create_file(dev
, &dev_attr_bridged_mode
))
970 "failed to create bridged_mode sysfs entry\n");
973 void qlcnic_remove_sysfs_entries(struct qlcnic_adapter
*adapter
)
975 struct device
*dev
= &adapter
->pdev
->dev
;
977 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
978 device_remove_file(dev
, &dev_attr_bridged_mode
);
981 void qlcnic_create_diag_entries(struct qlcnic_adapter
*adapter
)
983 struct device
*dev
= &adapter
->pdev
->dev
;
985 if (device_create_bin_file(dev
, &bin_attr_port_stats
))
986 dev_info(dev
, "failed to create port stats sysfs entry");
988 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
)
990 if (device_create_file(dev
, &dev_attr_diag_mode
))
991 dev_info(dev
, "failed to create diag_mode sysfs entry\n");
992 if (device_create_bin_file(dev
, &bin_attr_crb
))
993 dev_info(dev
, "failed to create crb sysfs entry\n");
994 if (device_create_bin_file(dev
, &bin_attr_mem
))
995 dev_info(dev
, "failed to create mem sysfs entry\n");
997 if (device_create_bin_file(dev
, &bin_attr_pci_config
))
998 dev_info(dev
, "failed to create pci config sysfs entry");
999 if (device_create_file(dev
, &dev_attr_beacon
))
1000 dev_info(dev
, "failed to create beacon sysfs entry");
1002 if (!(adapter
->flags
& QLCNIC_ESWITCH_ENABLED
))
1004 if (device_create_bin_file(dev
, &bin_attr_esw_config
))
1005 dev_info(dev
, "failed to create esw config sysfs entry");
1006 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
1008 if (device_create_bin_file(dev
, &bin_attr_npar_config
))
1009 dev_info(dev
, "failed to create npar config sysfs entry");
1010 if (device_create_bin_file(dev
, &bin_attr_pm_config
))
1011 dev_info(dev
, "failed to create pm config sysfs entry");
1012 if (device_create_bin_file(dev
, &bin_attr_esw_stats
))
1013 dev_info(dev
, "failed to create eswitch stats sysfs entry");
1016 void qlcnic_remove_diag_entries(struct qlcnic_adapter
*adapter
)
1018 struct device
*dev
= &adapter
->pdev
->dev
;
1020 device_remove_bin_file(dev
, &bin_attr_port_stats
);
1022 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
)
1024 device_remove_file(dev
, &dev_attr_diag_mode
);
1025 device_remove_bin_file(dev
, &bin_attr_crb
);
1026 device_remove_bin_file(dev
, &bin_attr_mem
);
1027 device_remove_bin_file(dev
, &bin_attr_pci_config
);
1028 device_remove_file(dev
, &dev_attr_beacon
);
1029 if (!(adapter
->flags
& QLCNIC_ESWITCH_ENABLED
))
1031 device_remove_bin_file(dev
, &bin_attr_esw_config
);
1032 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
1034 device_remove_bin_file(dev
, &bin_attr_npar_config
);
1035 device_remove_bin_file(dev
, &bin_attr_pm_config
);
1036 device_remove_bin_file(dev
, &bin_attr_esw_stats
);
1039 void qlcnic_82xx_add_sysfs(struct qlcnic_adapter
*adapter
)
1041 qlcnic_create_diag_entries(adapter
);
1044 void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter
*adapter
)
1046 qlcnic_remove_diag_entries(adapter
);
1049 void qlcnic_83xx_add_sysfs(struct qlcnic_adapter
*adapter
)
1051 qlcnic_create_diag_entries(adapter
);
1054 void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter
*adapter
)
1056 qlcnic_remove_diag_entries(adapter
);