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