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);