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/interrupt.h>
12 #include "qlcnic_hw.h"
14 #include <linux/swab.h>
15 #include <linux/dma-mapping.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>
23 #define QLC_STATUS_UNSUPPORTED_CMD -2
25 int qlcnicvf_config_bridged_mode(struct qlcnic_adapter
*adapter
, u32 enable
)
30 int qlcnicvf_config_led(struct qlcnic_adapter
*adapter
, u32 state
, u32 rate
)
35 static ssize_t
qlcnic_store_bridged_mode(struct device
*dev
,
36 struct device_attribute
*attr
,
37 const char *buf
, size_t len
)
39 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
43 if (!(adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
))
46 if (!test_bit(__QLCNIC_DEV_UP
, &adapter
->state
))
49 if (kstrtoul(buf
, 2, &new))
52 if (!qlcnic_config_bridged_mode(adapter
, !!new))
59 static ssize_t
qlcnic_show_bridged_mode(struct device
*dev
,
60 struct device_attribute
*attr
,
63 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
66 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
67 bridged_mode
= !!(adapter
->flags
& QLCNIC_BRIDGE_ENABLED
);
69 return sprintf(buf
, "%d\n", bridged_mode
);
72 static ssize_t
qlcnic_store_diag_mode(struct device
*dev
,
73 struct device_attribute
*attr
,
74 const char *buf
, size_t len
)
76 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
79 if (kstrtoul(buf
, 2, &new))
82 if (!!new != !!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
83 adapter
->flags
^= QLCNIC_DIAG_ENABLED
;
88 static ssize_t
qlcnic_show_diag_mode(struct device
*dev
,
89 struct device_attribute
*attr
, char *buf
)
91 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
92 return sprintf(buf
, "%d\n", !!(adapter
->flags
& QLCNIC_DIAG_ENABLED
));
95 static int qlcnic_validate_beacon(struct qlcnic_adapter
*adapter
, u16 beacon
,
101 QLCDB(adapter
, DRV
, "rate %x state %x\n", *rate
, *state
);
104 *rate
= __QLCNIC_MAX_LED_RATE
;
106 } else if (*state
> __QLCNIC_MAX_LED_STATE
) {
110 if ((!*rate
) || (*rate
> __QLCNIC_MAX_LED_RATE
))
116 static int qlcnic_83xx_store_beacon(struct qlcnic_adapter
*adapter
,
117 const char *buf
, size_t len
)
119 struct qlcnic_hardware_context
*ahw
= adapter
->ahw
;
120 unsigned long h_beacon
;
123 if (test_bit(__QLCNIC_RESETTING
, &adapter
->state
))
126 if (kstrtoul(buf
, 2, &h_beacon
))
129 qlcnic_get_beacon_state(adapter
);
131 if (ahw
->beacon_state
== h_beacon
)
135 if (!ahw
->beacon_state
) {
136 if (test_and_set_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
)) {
143 err
= qlcnic_83xx_config_led(adapter
, 1, h_beacon
);
145 err
= qlcnic_83xx_config_led(adapter
, 0, !h_beacon
);
147 ahw
->beacon_state
= h_beacon
;
149 if (!ahw
->beacon_state
)
150 clear_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
);
156 static int qlcnic_82xx_store_beacon(struct qlcnic_adapter
*adapter
,
157 const char *buf
, size_t len
)
159 struct qlcnic_hardware_context
*ahw
= adapter
->ahw
;
160 int err
, drv_sds_rings
= adapter
->drv_sds_rings
;
164 if (len
!= sizeof(u16
))
165 return QL_STATUS_INVALID_PARAM
;
167 memcpy(&beacon
, buf
, sizeof(u16
));
168 err
= qlcnic_validate_beacon(adapter
, beacon
, &b_state
, &b_rate
);
172 qlcnic_get_beacon_state(adapter
);
174 if (ahw
->beacon_state
== b_state
)
178 if (!ahw
->beacon_state
) {
179 if (test_and_set_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
)) {
185 if (test_bit(__QLCNIC_RESETTING
, &adapter
->state
)) {
190 if (!test_bit(__QLCNIC_DEV_UP
, &adapter
->state
)) {
191 err
= qlcnic_diag_alloc_res(adapter
->netdev
, QLCNIC_LED_TEST
);
194 set_bit(__QLCNIC_DIAG_RES_ALLOC
, &adapter
->state
);
197 err
= qlcnic_config_led(adapter
, b_state
, b_rate
);
200 ahw
->beacon_state
= b_state
;
203 if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC
, &adapter
->state
))
204 qlcnic_diag_free_res(adapter
->netdev
, drv_sds_rings
);
207 if (!ahw
->beacon_state
)
208 clear_bit(__QLCNIC_LED_ENABLE
, &adapter
->state
);
214 static ssize_t
qlcnic_store_beacon(struct device
*dev
,
215 struct device_attribute
*attr
,
216 const char *buf
, size_t len
)
218 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
221 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
) {
223 "LED test not supported in non privileged mode\n");
227 if (qlcnic_82xx_check(adapter
))
228 err
= qlcnic_82xx_store_beacon(adapter
, buf
, len
);
229 else if (qlcnic_83xx_check(adapter
))
230 err
= qlcnic_83xx_store_beacon(adapter
, buf
, len
);
237 static ssize_t
qlcnic_show_beacon(struct device
*dev
,
238 struct device_attribute
*attr
, char *buf
)
240 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
242 return sprintf(buf
, "%d\n", adapter
->ahw
->beacon_state
);
245 static int qlcnic_sysfs_validate_crb(struct qlcnic_adapter
*adapter
,
246 loff_t offset
, size_t size
)
250 if (!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
253 if (offset
< QLCNIC_PCI_CRBSPACE
) {
254 if (ADDR_IN_RANGE(offset
, QLCNIC_PCI_CAMQM
,
255 QLCNIC_PCI_CAMQM_END
))
261 if ((size
!= crb_size
) || (offset
& (crb_size
-1)))
267 static ssize_t
qlcnic_sysfs_read_crb(struct file
*filp
, struct kobject
*kobj
,
268 struct bin_attribute
*attr
, char *buf
,
269 loff_t offset
, size_t size
)
271 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
272 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
275 ret
= qlcnic_sysfs_validate_crb(adapter
, offset
, size
);
278 qlcnic_read_crb(adapter
, buf
, offset
, size
);
283 static ssize_t
qlcnic_sysfs_write_crb(struct file
*filp
, struct kobject
*kobj
,
284 struct bin_attribute
*attr
, char *buf
,
285 loff_t offset
, size_t size
)
287 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
288 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
291 ret
= qlcnic_sysfs_validate_crb(adapter
, offset
, size
);
295 qlcnic_write_crb(adapter
, buf
, offset
, size
);
299 static int qlcnic_sysfs_validate_mem(struct qlcnic_adapter
*adapter
,
300 loff_t offset
, size_t size
)
302 if (!(adapter
->flags
& QLCNIC_DIAG_ENABLED
))
305 if ((size
!= 8) || (offset
& 0x7))
311 static ssize_t
qlcnic_sysfs_read_mem(struct file
*filp
, struct kobject
*kobj
,
312 struct bin_attribute
*attr
, char *buf
,
313 loff_t offset
, size_t size
)
315 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
316 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
320 ret
= qlcnic_sysfs_validate_mem(adapter
, offset
, size
);
324 if (qlcnic_pci_mem_read_2M(adapter
, offset
, &data
))
327 memcpy(buf
, &data
, size
);
332 static ssize_t
qlcnic_sysfs_write_mem(struct file
*filp
, struct kobject
*kobj
,
333 struct bin_attribute
*attr
, char *buf
,
334 loff_t offset
, size_t size
)
336 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
337 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
341 ret
= qlcnic_sysfs_validate_mem(adapter
, offset
, size
);
345 memcpy(&data
, buf
, size
);
347 if (qlcnic_pci_mem_write_2M(adapter
, offset
, data
))
353 static u32
qlcnic_get_pci_func_count(struct qlcnic_adapter
*adapter
)
355 struct qlcnic_hardware_context
*ahw
= adapter
->ahw
;
358 if (!(adapter
->flags
& QLCNIC_ESWITCH_ENABLED
))
359 return ahw
->total_nic_func
;
361 if (ahw
->total_pci_func
<= QLC_DEFAULT_VNIC_COUNT
)
362 count
= QLC_DEFAULT_VNIC_COUNT
;
364 count
= ahw
->max_vnic_func
;
369 int qlcnic_is_valid_nic_func(struct qlcnic_adapter
*adapter
, u8 pci_func
)
371 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
374 for (i
= 0; i
< pci_func_count
; i
++) {
375 if (adapter
->npars
[i
].pci_func
== pci_func
)
382 static int validate_pm_config(struct qlcnic_adapter
*adapter
,
383 struct qlcnic_pm_func_cfg
*pm_cfg
, int count
)
385 u8 src_pci_func
, s_esw_id
, d_esw_id
;
387 int i
, src_index
, dest_index
;
389 for (i
= 0; i
< count
; i
++) {
390 src_pci_func
= pm_cfg
[i
].pci_func
;
391 dest_pci_func
= pm_cfg
[i
].dest_npar
;
392 src_index
= qlcnic_is_valid_nic_func(adapter
, src_pci_func
);
394 return QL_STATUS_INVALID_PARAM
;
396 dest_index
= qlcnic_is_valid_nic_func(adapter
, dest_pci_func
);
398 return QL_STATUS_INVALID_PARAM
;
400 s_esw_id
= adapter
->npars
[src_index
].phy_port
;
401 d_esw_id
= adapter
->npars
[dest_index
].phy_port
;
403 if (s_esw_id
!= d_esw_id
)
404 return QL_STATUS_INVALID_PARAM
;
410 static ssize_t
qlcnic_sysfs_write_pm_config(struct file
*filp
,
411 struct kobject
*kobj
,
412 struct bin_attribute
*attr
,
413 char *buf
, loff_t offset
,
416 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
417 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
418 struct qlcnic_pm_func_cfg
*pm_cfg
;
419 u32 id
, action
, pci_func
;
420 int count
, rem
, i
, ret
, index
;
422 count
= size
/ sizeof(struct qlcnic_pm_func_cfg
);
423 rem
= size
% sizeof(struct qlcnic_pm_func_cfg
);
425 return QL_STATUS_INVALID_PARAM
;
427 pm_cfg
= (struct qlcnic_pm_func_cfg
*)buf
;
428 ret
= validate_pm_config(adapter
, pm_cfg
, count
);
432 for (i
= 0; i
< count
; i
++) {
433 pci_func
= pm_cfg
[i
].pci_func
;
434 action
= !!pm_cfg
[i
].action
;
435 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
437 return QL_STATUS_INVALID_PARAM
;
439 id
= adapter
->npars
[index
].phy_port
;
440 ret
= qlcnic_config_port_mirroring(adapter
, id
,
446 for (i
= 0; i
< count
; i
++) {
447 pci_func
= pm_cfg
[i
].pci_func
;
448 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
450 return QL_STATUS_INVALID_PARAM
;
451 id
= adapter
->npars
[index
].phy_port
;
452 adapter
->npars
[index
].enable_pm
= !!pm_cfg
[i
].action
;
453 adapter
->npars
[index
].dest_npar
= id
;
459 static ssize_t
qlcnic_sysfs_read_pm_config(struct file
*filp
,
460 struct kobject
*kobj
,
461 struct bin_attribute
*attr
,
462 char *buf
, loff_t offset
,
465 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
466 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
467 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
468 struct qlcnic_pm_func_cfg
*pm_cfg
;
472 pm_cfg_size
= pci_func_count
* sizeof(*pm_cfg
);
473 if (size
!= pm_cfg_size
)
474 return QL_STATUS_INVALID_PARAM
;
476 memset(buf
, 0, pm_cfg_size
);
477 pm_cfg
= (struct qlcnic_pm_func_cfg
*)buf
;
479 for (i
= 0; i
< pci_func_count
; i
++) {
480 pci_func
= adapter
->npars
[i
].pci_func
;
481 if (!adapter
->npars
[i
].active
)
484 if (!adapter
->npars
[i
].eswitch_status
)
487 pm_cfg
[pci_func
].action
= adapter
->npars
[i
].enable_pm
;
488 pm_cfg
[pci_func
].dest_npar
= 0;
489 pm_cfg
[pci_func
].pci_func
= i
;
494 static int validate_esw_config(struct qlcnic_adapter
*adapter
,
495 struct qlcnic_esw_func_cfg
*esw_cfg
, int count
)
497 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
498 struct qlcnic_hardware_context
*ahw
= adapter
->ahw
;
503 if (qlcnic_82xx_check(adapter
))
504 op_mode
= readl(ahw
->pci_base0
+ QLCNIC_DRV_OP_MODE
);
506 op_mode
= QLCRDX(ahw
, QLC_83XX_DRV_OP_MODE
);
508 for (i
= 0; i
< count
; i
++) {
509 pci_func
= esw_cfg
[i
].pci_func
;
510 if (pci_func
>= pci_func_count
)
511 return QL_STATUS_INVALID_PARAM
;
513 if (adapter
->ahw
->op_mode
== QLCNIC_MGMT_FUNC
)
514 if (qlcnic_is_valid_nic_func(adapter
, pci_func
) < 0)
515 return QL_STATUS_INVALID_PARAM
;
517 switch (esw_cfg
[i
].op_mode
) {
518 case QLCNIC_PORT_DEFAULTS
:
519 if (qlcnic_82xx_check(adapter
)) {
520 ret
= QLC_DEV_GET_DRV(op_mode
, pci_func
);
522 ret
= QLC_83XX_GET_FUNC_PRIVILEGE(op_mode
,
524 esw_cfg
[i
].offload_flags
= 0;
527 if (ret
!= QLCNIC_NON_PRIV_FUNC
) {
528 if (esw_cfg
[i
].mac_anti_spoof
!= 0)
529 return QL_STATUS_INVALID_PARAM
;
530 if (esw_cfg
[i
].mac_override
!= 1)
531 return QL_STATUS_INVALID_PARAM
;
532 if (esw_cfg
[i
].promisc_mode
!= 1)
533 return QL_STATUS_INVALID_PARAM
;
536 case QLCNIC_ADD_VLAN
:
537 if (!IS_VALID_VLAN(esw_cfg
[i
].vlan_id
))
538 return QL_STATUS_INVALID_PARAM
;
539 if (!esw_cfg
[i
].op_type
)
540 return QL_STATUS_INVALID_PARAM
;
542 case QLCNIC_DEL_VLAN
:
543 if (!esw_cfg
[i
].op_type
)
544 return QL_STATUS_INVALID_PARAM
;
547 return QL_STATUS_INVALID_PARAM
;
554 static ssize_t
qlcnic_sysfs_write_esw_config(struct file
*file
,
555 struct kobject
*kobj
,
556 struct bin_attribute
*attr
,
557 char *buf
, loff_t offset
,
560 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
561 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
562 struct qlcnic_esw_func_cfg
*esw_cfg
;
563 struct qlcnic_npar_info
*npar
;
564 int count
, rem
, i
, ret
;
566 u8 op_mode
= 0, pci_func
;
568 count
= size
/ sizeof(struct qlcnic_esw_func_cfg
);
569 rem
= size
% sizeof(struct qlcnic_esw_func_cfg
);
571 return QL_STATUS_INVALID_PARAM
;
573 esw_cfg
= (struct qlcnic_esw_func_cfg
*)buf
;
574 ret
= validate_esw_config(adapter
, esw_cfg
, count
);
578 for (i
= 0; i
< count
; i
++) {
579 if (adapter
->ahw
->op_mode
== QLCNIC_MGMT_FUNC
)
580 if (qlcnic_config_switch_port(adapter
, &esw_cfg
[i
]))
581 return QL_STATUS_INVALID_PARAM
;
583 if (adapter
->ahw
->pci_func
!= esw_cfg
[i
].pci_func
)
586 op_mode
= esw_cfg
[i
].op_mode
;
587 qlcnic_get_eswitch_port_config(adapter
, &esw_cfg
[i
]);
588 esw_cfg
[i
].op_mode
= op_mode
;
589 esw_cfg
[i
].pci_func
= adapter
->ahw
->pci_func
;
591 switch (esw_cfg
[i
].op_mode
) {
592 case QLCNIC_PORT_DEFAULTS
:
593 qlcnic_set_eswitch_port_features(adapter
, &esw_cfg
[i
]);
595 qlcnic_set_netdev_features(adapter
, &esw_cfg
[i
]);
598 case QLCNIC_ADD_VLAN
:
599 qlcnic_set_vlan_config(adapter
, &esw_cfg
[i
]);
601 case QLCNIC_DEL_VLAN
:
602 esw_cfg
[i
].vlan_id
= 0;
603 qlcnic_set_vlan_config(adapter
, &esw_cfg
[i
]);
608 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
611 for (i
= 0; i
< count
; i
++) {
612 pci_func
= esw_cfg
[i
].pci_func
;
613 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
615 return QL_STATUS_INVALID_PARAM
;
616 npar
= &adapter
->npars
[index
];
617 switch (esw_cfg
[i
].op_mode
) {
618 case QLCNIC_PORT_DEFAULTS
:
619 npar
->promisc_mode
= esw_cfg
[i
].promisc_mode
;
620 npar
->mac_override
= esw_cfg
[i
].mac_override
;
621 npar
->offload_flags
= esw_cfg
[i
].offload_flags
;
622 npar
->mac_anti_spoof
= esw_cfg
[i
].mac_anti_spoof
;
623 npar
->discard_tagged
= esw_cfg
[i
].discard_tagged
;
625 case QLCNIC_ADD_VLAN
:
626 npar
->pvid
= esw_cfg
[i
].vlan_id
;
628 case QLCNIC_DEL_VLAN
:
637 static ssize_t
qlcnic_sysfs_read_esw_config(struct file
*file
,
638 struct kobject
*kobj
,
639 struct bin_attribute
*attr
,
640 char *buf
, loff_t offset
,
643 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
644 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
645 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
646 struct qlcnic_esw_func_cfg
*esw_cfg
;
650 esw_cfg_size
= pci_func_count
* sizeof(*esw_cfg
);
651 if (size
!= esw_cfg_size
)
652 return QL_STATUS_INVALID_PARAM
;
654 memset(buf
, 0, esw_cfg_size
);
655 esw_cfg
= (struct qlcnic_esw_func_cfg
*)buf
;
657 for (i
= 0; i
< pci_func_count
; i
++) {
658 pci_func
= adapter
->npars
[i
].pci_func
;
659 if (!adapter
->npars
[i
].active
)
662 if (!adapter
->npars
[i
].eswitch_status
)
665 esw_cfg
[pci_func
].pci_func
= pci_func
;
666 if (qlcnic_get_eswitch_port_config(adapter
, &esw_cfg
[pci_func
]))
667 return QL_STATUS_INVALID_PARAM
;
672 static int validate_npar_config(struct qlcnic_adapter
*adapter
,
673 struct qlcnic_npar_func_cfg
*np_cfg
,
678 for (i
= 0; i
< count
; i
++) {
679 pci_func
= np_cfg
[i
].pci_func
;
680 if (qlcnic_is_valid_nic_func(adapter
, pci_func
) < 0)
681 return QL_STATUS_INVALID_PARAM
;
683 if (!IS_VALID_BW(np_cfg
[i
].min_bw
) ||
684 !IS_VALID_BW(np_cfg
[i
].max_bw
))
685 return QL_STATUS_INVALID_PARAM
;
690 static ssize_t
qlcnic_sysfs_write_npar_config(struct file
*file
,
691 struct kobject
*kobj
,
692 struct bin_attribute
*attr
,
693 char *buf
, loff_t offset
,
696 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
697 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
698 struct qlcnic_info nic_info
;
699 struct qlcnic_npar_func_cfg
*np_cfg
;
700 int i
, count
, rem
, ret
, index
;
703 count
= size
/ sizeof(struct qlcnic_npar_func_cfg
);
704 rem
= size
% sizeof(struct qlcnic_npar_func_cfg
);
706 return QL_STATUS_INVALID_PARAM
;
708 np_cfg
= (struct qlcnic_npar_func_cfg
*)buf
;
709 ret
= validate_npar_config(adapter
, np_cfg
, count
);
713 for (i
= 0; i
< count
; i
++) {
714 pci_func
= np_cfg
[i
].pci_func
;
716 memset(&nic_info
, 0, sizeof(struct qlcnic_info
));
717 ret
= qlcnic_get_nic_info(adapter
, &nic_info
, pci_func
);
720 nic_info
.pci_func
= pci_func
;
721 nic_info
.min_tx_bw
= np_cfg
[i
].min_bw
;
722 nic_info
.max_tx_bw
= np_cfg
[i
].max_bw
;
723 ret
= qlcnic_set_nic_info(adapter
, &nic_info
);
726 index
= qlcnic_is_valid_nic_func(adapter
, pci_func
);
728 return QL_STATUS_INVALID_PARAM
;
729 adapter
->npars
[index
].min_bw
= nic_info
.min_tx_bw
;
730 adapter
->npars
[index
].max_bw
= nic_info
.max_tx_bw
;
736 static ssize_t
qlcnic_sysfs_read_npar_config(struct file
*file
,
737 struct kobject
*kobj
,
738 struct bin_attribute
*attr
,
739 char *buf
, loff_t offset
,
742 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
743 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
744 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
745 struct qlcnic_npar_func_cfg
*np_cfg
;
746 struct qlcnic_info nic_info
;
750 np_cfg_size
= pci_func_count
* sizeof(*np_cfg
);
751 if (size
!= np_cfg_size
)
752 return QL_STATUS_INVALID_PARAM
;
754 memset(&nic_info
, 0, sizeof(struct qlcnic_info
));
755 memset(buf
, 0, np_cfg_size
);
756 np_cfg
= (struct qlcnic_npar_func_cfg
*)buf
;
758 for (i
= 0; i
< pci_func_count
; i
++) {
759 if (qlcnic_is_valid_nic_func(adapter
, i
) < 0)
761 ret
= qlcnic_get_nic_info(adapter
, &nic_info
, i
);
764 if (!adapter
->npars
[i
].eswitch_status
)
766 np_cfg
[i
].pci_func
= i
;
767 np_cfg
[i
].op_mode
= (u8
)nic_info
.op_mode
;
768 np_cfg
[i
].port_num
= nic_info
.phys_port
;
769 np_cfg
[i
].fw_capab
= nic_info
.capabilities
;
770 np_cfg
[i
].min_bw
= nic_info
.min_tx_bw
;
771 np_cfg
[i
].max_bw
= nic_info
.max_tx_bw
;
772 np_cfg
[i
].max_tx_queues
= nic_info
.max_tx_ques
;
773 np_cfg
[i
].max_rx_queues
= nic_info
.max_rx_ques
;
778 static ssize_t
qlcnic_sysfs_get_port_stats(struct file
*file
,
779 struct kobject
*kobj
,
780 struct bin_attribute
*attr
,
781 char *buf
, loff_t offset
,
784 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
785 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
786 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
787 struct qlcnic_esw_statistics port_stats
;
790 if (qlcnic_83xx_check(adapter
))
791 return QLC_STATUS_UNSUPPORTED_CMD
;
793 if (size
!= sizeof(struct qlcnic_esw_statistics
))
794 return QL_STATUS_INVALID_PARAM
;
796 if (offset
>= pci_func_count
)
797 return QL_STATUS_INVALID_PARAM
;
799 memset(&port_stats
, 0, size
);
800 ret
= qlcnic_get_port_stats(adapter
, offset
, QLCNIC_QUERY_RX_COUNTER
,
805 ret
= qlcnic_get_port_stats(adapter
, offset
, QLCNIC_QUERY_TX_COUNTER
,
810 memcpy(buf
, &port_stats
, size
);
814 static ssize_t
qlcnic_sysfs_get_esw_stats(struct file
*file
,
815 struct kobject
*kobj
,
816 struct bin_attribute
*attr
,
817 char *buf
, loff_t offset
,
820 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
821 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
822 struct qlcnic_esw_statistics esw_stats
;
825 if (qlcnic_83xx_check(adapter
))
826 return QLC_STATUS_UNSUPPORTED_CMD
;
828 if (size
!= sizeof(struct qlcnic_esw_statistics
))
829 return QL_STATUS_INVALID_PARAM
;
831 if (offset
>= QLCNIC_NIU_MAX_XG_PORTS
)
832 return QL_STATUS_INVALID_PARAM
;
834 memset(&esw_stats
, 0, size
);
835 ret
= qlcnic_get_eswitch_stats(adapter
, offset
, QLCNIC_QUERY_RX_COUNTER
,
840 ret
= qlcnic_get_eswitch_stats(adapter
, offset
, QLCNIC_QUERY_TX_COUNTER
,
845 memcpy(buf
, &esw_stats
, size
);
849 static ssize_t
qlcnic_sysfs_clear_esw_stats(struct file
*file
,
850 struct kobject
*kobj
,
851 struct bin_attribute
*attr
,
852 char *buf
, loff_t offset
,
855 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
856 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
859 if (qlcnic_83xx_check(adapter
))
860 return QLC_STATUS_UNSUPPORTED_CMD
;
862 if (offset
>= QLCNIC_NIU_MAX_XG_PORTS
)
863 return QL_STATUS_INVALID_PARAM
;
865 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_ESWITCH
, offset
,
866 QLCNIC_QUERY_RX_COUNTER
);
870 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_ESWITCH
, offset
,
871 QLCNIC_QUERY_TX_COUNTER
);
878 static ssize_t
qlcnic_sysfs_clear_port_stats(struct file
*file
,
879 struct kobject
*kobj
,
880 struct bin_attribute
*attr
,
881 char *buf
, loff_t offset
,
885 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
886 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
887 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
890 if (qlcnic_83xx_check(adapter
))
891 return QLC_STATUS_UNSUPPORTED_CMD
;
893 if (offset
>= pci_func_count
)
894 return QL_STATUS_INVALID_PARAM
;
896 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_PORT
, offset
,
897 QLCNIC_QUERY_RX_COUNTER
);
901 ret
= qlcnic_clear_esw_stats(adapter
, QLCNIC_STATS_PORT
, offset
,
902 QLCNIC_QUERY_TX_COUNTER
);
909 static ssize_t
qlcnic_sysfs_read_pci_config(struct file
*file
,
910 struct kobject
*kobj
,
911 struct bin_attribute
*attr
,
912 char *buf
, loff_t offset
,
915 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
916 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
917 u32 pci_func_count
= qlcnic_get_pci_func_count(adapter
);
918 struct qlcnic_pci_func_cfg
*pci_cfg
;
919 struct qlcnic_pci_info
*pci_info
;
923 pci_cfg_sz
= pci_func_count
* sizeof(*pci_cfg
);
924 if (size
!= pci_cfg_sz
)
925 return QL_STATUS_INVALID_PARAM
;
927 pci_info
= kcalloc(pci_func_count
, sizeof(*pci_info
), GFP_KERNEL
);
931 ret
= qlcnic_get_pci_info(adapter
, pci_info
);
937 pci_cfg
= (struct qlcnic_pci_func_cfg
*)buf
;
938 for (i
= 0; i
< pci_func_count
; i
++) {
939 pci_cfg
[i
].pci_func
= pci_info
[i
].id
;
940 pci_cfg
[i
].func_type
= pci_info
[i
].type
;
941 pci_cfg
[i
].func_state
= 0;
942 pci_cfg
[i
].port_num
= pci_info
[i
].default_port
;
943 pci_cfg
[i
].min_bw
= pci_info
[i
].tx_min_bw
;
944 pci_cfg
[i
].max_bw
= pci_info
[i
].tx_max_bw
;
945 memcpy(&pci_cfg
[i
].def_mac_addr
, &pci_info
[i
].mac
, ETH_ALEN
);
952 static ssize_t
qlcnic_83xx_sysfs_flash_read_handler(struct file
*filp
,
953 struct kobject
*kobj
,
954 struct bin_attribute
*attr
,
955 char *buf
, loff_t offset
,
958 unsigned char *p_read_buf
;
960 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
961 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
964 return QL_STATUS_INVALID_PARAM
;
966 return QL_STATUS_INVALID_PARAM
;
968 count
= size
/ sizeof(u32
);
970 if (size
% sizeof(u32
))
973 p_read_buf
= kcalloc(size
, sizeof(unsigned char), GFP_KERNEL
);
976 if (qlcnic_83xx_lock_flash(adapter
) != 0) {
981 ret
= qlcnic_83xx_lockless_flash_read32(adapter
, offset
, p_read_buf
,
985 qlcnic_83xx_unlock_flash(adapter
);
990 qlcnic_83xx_unlock_flash(adapter
);
991 memcpy(buf
, p_read_buf
, size
);
997 static int qlcnic_83xx_sysfs_flash_bulk_write(struct qlcnic_adapter
*adapter
,
998 char *buf
, loff_t offset
,
1002 unsigned char *p_cache
, *p_src
;
1004 p_cache
= kcalloc(size
, sizeof(unsigned char), GFP_KERNEL
);
1008 memcpy(p_cache
, buf
, size
);
1010 count
= size
/ sizeof(u32
);
1012 if (qlcnic_83xx_lock_flash(adapter
) != 0) {
1017 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1018 ret
= qlcnic_83xx_enable_flash_write(adapter
);
1021 qlcnic_83xx_unlock_flash(adapter
);
1026 for (i
= 0; i
< count
/ QLC_83XX_FLASH_WRITE_MAX
; i
++) {
1027 ret
= qlcnic_83xx_flash_bulk_write(adapter
, offset
,
1029 QLC_83XX_FLASH_WRITE_MAX
);
1032 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1033 ret
= qlcnic_83xx_disable_flash_write(adapter
);
1036 qlcnic_83xx_unlock_flash(adapter
);
1042 qlcnic_83xx_unlock_flash(adapter
);
1046 p_src
= p_src
+ sizeof(u32
)*QLC_83XX_FLASH_WRITE_MAX
;
1047 offset
= offset
+ sizeof(u32
)*QLC_83XX_FLASH_WRITE_MAX
;
1050 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1051 ret
= qlcnic_83xx_disable_flash_write(adapter
);
1054 qlcnic_83xx_unlock_flash(adapter
);
1060 qlcnic_83xx_unlock_flash(adapter
);
1065 static int qlcnic_83xx_sysfs_flash_write(struct qlcnic_adapter
*adapter
,
1066 char *buf
, loff_t offset
, size_t size
)
1069 unsigned char *p_cache
, *p_src
;
1071 p_cache
= kcalloc(size
, sizeof(unsigned char), GFP_KERNEL
);
1075 memcpy(p_cache
, buf
, size
);
1077 count
= size
/ sizeof(u32
);
1079 if (qlcnic_83xx_lock_flash(adapter
) != 0) {
1084 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1085 ret
= qlcnic_83xx_enable_flash_write(adapter
);
1088 qlcnic_83xx_unlock_flash(adapter
);
1093 for (i
= 0; i
< count
; i
++) {
1094 ret
= qlcnic_83xx_flash_write32(adapter
, offset
, (u32
*)p_src
);
1096 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1097 ret
= qlcnic_83xx_disable_flash_write(adapter
);
1100 qlcnic_83xx_unlock_flash(adapter
);
1105 qlcnic_83xx_unlock_flash(adapter
);
1109 p_src
= p_src
+ sizeof(u32
);
1110 offset
= offset
+ sizeof(u32
);
1113 if (adapter
->ahw
->fdt
.mfg_id
== adapter
->flash_mfg_id
) {
1114 ret
= qlcnic_83xx_disable_flash_write(adapter
);
1117 qlcnic_83xx_unlock_flash(adapter
);
1123 qlcnic_83xx_unlock_flash(adapter
);
1128 static ssize_t
qlcnic_83xx_sysfs_flash_write_handler(struct file
*filp
,
1129 struct kobject
*kobj
,
1130 struct bin_attribute
*attr
,
1131 char *buf
, loff_t offset
,
1135 static int flash_mode
;
1137 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
1138 struct qlcnic_adapter
*adapter
= dev_get_drvdata(dev
);
1141 return QL_STATUS_INVALID_PARAM
;
1143 ret
= kstrtoul(buf
, 16, &data
);
1146 case QLC_83XX_FLASH_SECTOR_ERASE_CMD
:
1147 flash_mode
= QLC_83XX_ERASE_MODE
;
1148 ret
= qlcnic_83xx_erase_flash_sector(adapter
, offset
);
1150 dev_err(&adapter
->pdev
->dev
,
1151 "%s failed at %d\n", __func__
, __LINE__
);
1156 case QLC_83XX_FLASH_BULK_WRITE_CMD
:
1157 flash_mode
= QLC_83XX_BULK_WRITE_MODE
;
1160 case QLC_83XX_FLASH_WRITE_CMD
:
1161 flash_mode
= QLC_83XX_WRITE_MODE
;
1164 if (flash_mode
== QLC_83XX_BULK_WRITE_MODE
) {
1165 ret
= qlcnic_83xx_sysfs_flash_bulk_write(adapter
, buf
,
1168 dev_err(&adapter
->pdev
->dev
,
1169 "%s failed at %d\n",
1170 __func__
, __LINE__
);
1175 if (flash_mode
== QLC_83XX_WRITE_MODE
) {
1176 ret
= qlcnic_83xx_sysfs_flash_write(adapter
, buf
,
1179 dev_err(&adapter
->pdev
->dev
,
1180 "%s failed at %d\n", __func__
,
1190 static struct device_attribute dev_attr_bridged_mode
= {
1191 .attr
= {.name
= "bridged_mode", .mode
= (S_IRUGO
| S_IWUSR
)},
1192 .show
= qlcnic_show_bridged_mode
,
1193 .store
= qlcnic_store_bridged_mode
,
1196 static struct device_attribute dev_attr_diag_mode
= {
1197 .attr
= {.name
= "diag_mode", .mode
= (S_IRUGO
| S_IWUSR
)},
1198 .show
= qlcnic_show_diag_mode
,
1199 .store
= qlcnic_store_diag_mode
,
1202 static struct device_attribute dev_attr_beacon
= {
1203 .attr
= {.name
= "beacon", .mode
= (S_IRUGO
| S_IWUSR
)},
1204 .show
= qlcnic_show_beacon
,
1205 .store
= qlcnic_store_beacon
,
1208 static struct bin_attribute bin_attr_crb
= {
1209 .attr
= {.name
= "crb", .mode
= (S_IRUGO
| S_IWUSR
)},
1211 .read
= qlcnic_sysfs_read_crb
,
1212 .write
= qlcnic_sysfs_write_crb
,
1215 static struct bin_attribute bin_attr_mem
= {
1216 .attr
= {.name
= "mem", .mode
= (S_IRUGO
| S_IWUSR
)},
1218 .read
= qlcnic_sysfs_read_mem
,
1219 .write
= qlcnic_sysfs_write_mem
,
1222 static struct bin_attribute bin_attr_npar_config
= {
1223 .attr
= {.name
= "npar_config", .mode
= (S_IRUGO
| S_IWUSR
)},
1225 .read
= qlcnic_sysfs_read_npar_config
,
1226 .write
= qlcnic_sysfs_write_npar_config
,
1229 static struct bin_attribute bin_attr_pci_config
= {
1230 .attr
= {.name
= "pci_config", .mode
= (S_IRUGO
| S_IWUSR
)},
1232 .read
= qlcnic_sysfs_read_pci_config
,
1236 static struct bin_attribute bin_attr_port_stats
= {
1237 .attr
= {.name
= "port_stats", .mode
= (S_IRUGO
| S_IWUSR
)},
1239 .read
= qlcnic_sysfs_get_port_stats
,
1240 .write
= qlcnic_sysfs_clear_port_stats
,
1243 static struct bin_attribute bin_attr_esw_stats
= {
1244 .attr
= {.name
= "esw_stats", .mode
= (S_IRUGO
| S_IWUSR
)},
1246 .read
= qlcnic_sysfs_get_esw_stats
,
1247 .write
= qlcnic_sysfs_clear_esw_stats
,
1250 static struct bin_attribute bin_attr_esw_config
= {
1251 .attr
= {.name
= "esw_config", .mode
= (S_IRUGO
| S_IWUSR
)},
1253 .read
= qlcnic_sysfs_read_esw_config
,
1254 .write
= qlcnic_sysfs_write_esw_config
,
1257 static struct bin_attribute bin_attr_pm_config
= {
1258 .attr
= {.name
= "pm_config", .mode
= (S_IRUGO
| S_IWUSR
)},
1260 .read
= qlcnic_sysfs_read_pm_config
,
1261 .write
= qlcnic_sysfs_write_pm_config
,
1264 static struct bin_attribute bin_attr_flash
= {
1265 .attr
= {.name
= "flash", .mode
= (S_IRUGO
| S_IWUSR
)},
1267 .read
= qlcnic_83xx_sysfs_flash_read_handler
,
1268 .write
= qlcnic_83xx_sysfs_flash_write_handler
,
1271 void qlcnic_create_sysfs_entries(struct qlcnic_adapter
*adapter
)
1273 struct device
*dev
= &adapter
->pdev
->dev
;
1275 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
1276 if (device_create_file(dev
, &dev_attr_bridged_mode
))
1278 "failed to create bridged_mode sysfs entry\n");
1281 void qlcnic_remove_sysfs_entries(struct qlcnic_adapter
*adapter
)
1283 struct device
*dev
= &adapter
->pdev
->dev
;
1285 if (adapter
->ahw
->capabilities
& QLCNIC_FW_CAPABILITY_BDG
)
1286 device_remove_file(dev
, &dev_attr_bridged_mode
);
1289 static void qlcnic_create_diag_entries(struct qlcnic_adapter
*adapter
)
1291 struct device
*dev
= &adapter
->pdev
->dev
;
1293 if (device_create_bin_file(dev
, &bin_attr_port_stats
))
1294 dev_info(dev
, "failed to create port stats sysfs entry");
1296 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
)
1298 if (device_create_file(dev
, &dev_attr_diag_mode
))
1299 dev_info(dev
, "failed to create diag_mode sysfs entry\n");
1300 if (device_create_bin_file(dev
, &bin_attr_crb
))
1301 dev_info(dev
, "failed to create crb sysfs entry\n");
1302 if (device_create_bin_file(dev
, &bin_attr_mem
))
1303 dev_info(dev
, "failed to create mem sysfs entry\n");
1305 if (test_bit(__QLCNIC_MAINTENANCE_MODE
, &adapter
->state
))
1308 if (device_create_bin_file(dev
, &bin_attr_pci_config
))
1309 dev_info(dev
, "failed to create pci config sysfs entry");
1311 if (device_create_file(dev
, &dev_attr_beacon
))
1312 dev_info(dev
, "failed to create beacon sysfs entry");
1314 if (!(adapter
->flags
& QLCNIC_ESWITCH_ENABLED
))
1316 if (device_create_bin_file(dev
, &bin_attr_esw_config
))
1317 dev_info(dev
, "failed to create esw config sysfs entry");
1318 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
1320 if (device_create_bin_file(dev
, &bin_attr_npar_config
))
1321 dev_info(dev
, "failed to create npar config sysfs entry");
1322 if (device_create_bin_file(dev
, &bin_attr_pm_config
))
1323 dev_info(dev
, "failed to create pm config sysfs entry");
1324 if (device_create_bin_file(dev
, &bin_attr_esw_stats
))
1325 dev_info(dev
, "failed to create eswitch stats sysfs entry");
1328 static void qlcnic_remove_diag_entries(struct qlcnic_adapter
*adapter
)
1330 struct device
*dev
= &adapter
->pdev
->dev
;
1332 device_remove_bin_file(dev
, &bin_attr_port_stats
);
1334 if (adapter
->ahw
->op_mode
== QLCNIC_NON_PRIV_FUNC
)
1336 device_remove_file(dev
, &dev_attr_diag_mode
);
1337 device_remove_bin_file(dev
, &bin_attr_crb
);
1338 device_remove_bin_file(dev
, &bin_attr_mem
);
1340 if (test_bit(__QLCNIC_MAINTENANCE_MODE
, &adapter
->state
))
1343 device_remove_bin_file(dev
, &bin_attr_pci_config
);
1344 device_remove_file(dev
, &dev_attr_beacon
);
1345 if (!(adapter
->flags
& QLCNIC_ESWITCH_ENABLED
))
1347 device_remove_bin_file(dev
, &bin_attr_esw_config
);
1348 if (adapter
->ahw
->op_mode
!= QLCNIC_MGMT_FUNC
)
1350 device_remove_bin_file(dev
, &bin_attr_npar_config
);
1351 device_remove_bin_file(dev
, &bin_attr_pm_config
);
1352 device_remove_bin_file(dev
, &bin_attr_esw_stats
);
1355 void qlcnic_82xx_add_sysfs(struct qlcnic_adapter
*adapter
)
1357 qlcnic_create_diag_entries(adapter
);
1360 void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter
*adapter
)
1362 qlcnic_remove_diag_entries(adapter
);
1365 void qlcnic_83xx_add_sysfs(struct qlcnic_adapter
*adapter
)
1367 struct device
*dev
= &adapter
->pdev
->dev
;
1369 qlcnic_create_diag_entries(adapter
);
1371 if (sysfs_create_bin_file(&dev
->kobj
, &bin_attr_flash
))
1372 dev_info(dev
, "failed to create flash sysfs entry\n");
1375 void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter
*adapter
)
1377 struct device
*dev
= &adapter
->pdev
->dev
;
1379 qlcnic_remove_diag_entries(adapter
);
1380 sysfs_remove_bin_file(&dev
->kobj
, &bin_attr_flash
);