linux/drivers/scsi/qedf/qedf_attr.c
<<
>>
Prefs
   1/*
   2 *  QLogic FCoE Offload Driver
   3 *  Copyright (c) 2016-2017 Cavium Inc.
   4 *
   5 *  This software is available under the terms of the GNU General Public License
   6 *  (GPL) Version 2, available from the file COPYING in the main directory of
   7 *  this source tree.
   8 */
   9#include "qedf.h"
  10
  11inline bool qedf_is_vport(struct qedf_ctx *qedf)
  12{
  13        return qedf->lport->vport != NULL;
  14}
  15
  16/* Get base qedf for physical port from vport */
  17static struct qedf_ctx *qedf_get_base_qedf(struct qedf_ctx *qedf)
  18{
  19        struct fc_lport *lport;
  20        struct fc_lport *base_lport;
  21
  22        if (!(qedf_is_vport(qedf)))
  23                return NULL;
  24
  25        lport = qedf->lport;
  26        base_lport = shost_priv(vport_to_shost(lport->vport));
  27        return lport_priv(base_lport);
  28}
  29
  30static ssize_t
  31qedf_fcoe_mac_show(struct device *dev,
  32        struct device_attribute *attr, char *buf)
  33{
  34        struct fc_lport *lport = shost_priv(class_to_shost(dev));
  35        u32 port_id;
  36        u8 lport_src_id[3];
  37        u8 fcoe_mac[6];
  38
  39        port_id = fc_host_port_id(lport->host);
  40        lport_src_id[2] = (port_id & 0x000000FF);
  41        lport_src_id[1] = (port_id & 0x0000FF00) >> 8;
  42        lport_src_id[0] = (port_id & 0x00FF0000) >> 16;
  43        fc_fcoe_set_mac(fcoe_mac, lport_src_id);
  44
  45        return scnprintf(buf, PAGE_SIZE, "%pM\n", fcoe_mac);
  46}
  47
  48static ssize_t
  49qedf_fka_period_show(struct device *dev,
  50        struct device_attribute *attr, char *buf)
  51{
  52        struct fc_lport *lport = shost_priv(class_to_shost(dev));
  53        struct qedf_ctx *qedf = lport_priv(lport);
  54        int fka_period = -1;
  55
  56        if (qedf_is_vport(qedf))
  57                qedf = qedf_get_base_qedf(qedf);
  58
  59        if (qedf->ctlr.sel_fcf)
  60                fka_period = qedf->ctlr.sel_fcf->fka_period;
  61
  62        return scnprintf(buf, PAGE_SIZE, "%d\n", fka_period);
  63}
  64
  65static DEVICE_ATTR(fcoe_mac, S_IRUGO, qedf_fcoe_mac_show, NULL);
  66static DEVICE_ATTR(fka_period, S_IRUGO, qedf_fka_period_show, NULL);
  67
  68struct device_attribute *qedf_host_attrs[] = {
  69        &dev_attr_fcoe_mac,
  70        &dev_attr_fka_period,
  71        NULL,
  72};
  73
  74extern const struct qed_fcoe_ops *qed_ops;
  75
  76void qedf_capture_grc_dump(struct qedf_ctx *qedf)
  77{
  78        struct qedf_ctx *base_qedf;
  79
  80        /* Make sure we use the base qedf to take the GRC dump */
  81        if (qedf_is_vport(qedf))
  82                base_qedf = qedf_get_base_qedf(qedf);
  83        else
  84                base_qedf = qedf;
  85
  86        if (test_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags)) {
  87                QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_INFO,
  88                    "GRC Dump already captured.\n");
  89                return;
  90        }
  91
  92
  93        qedf_get_grc_dump(base_qedf->cdev, qed_ops->common,
  94            &base_qedf->grcdump, &base_qedf->grcdump_size);
  95        QEDF_ERR(&(base_qedf->dbg_ctx), "GRC Dump captured.\n");
  96        set_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags);
  97        qedf_uevent_emit(base_qedf->lport->host, QEDF_UEVENT_CODE_GRCDUMP,
  98            NULL);
  99}
 100
 101static ssize_t
 102qedf_sysfs_read_grcdump(struct file *filep, struct kobject *kobj,
 103                        struct bin_attribute *ba, char *buf, loff_t off,
 104                        size_t count)
 105{
 106        ssize_t ret = 0;
 107        struct fc_lport *lport = shost_priv(dev_to_shost(container_of(kobj,
 108                                                        struct device, kobj)));
 109        struct qedf_ctx *qedf = lport_priv(lport);
 110
 111        if (test_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags)) {
 112                ret = memory_read_from_buffer(buf, count, &off,
 113                    qedf->grcdump, qedf->grcdump_size);
 114        } else {
 115                QEDF_ERR(&(qedf->dbg_ctx), "GRC Dump not captured!\n");
 116        }
 117
 118        return ret;
 119}
 120
 121static ssize_t
 122qedf_sysfs_write_grcdump(struct file *filep, struct kobject *kobj,
 123                        struct bin_attribute *ba, char *buf, loff_t off,
 124                        size_t count)
 125{
 126        struct fc_lport *lport = NULL;
 127        struct qedf_ctx *qedf = NULL;
 128        long reading;
 129        int ret = 0;
 130        char msg[40];
 131
 132        if (off != 0)
 133                return ret;
 134
 135
 136        lport = shost_priv(dev_to_shost(container_of(kobj,
 137            struct device, kobj)));
 138        qedf = lport_priv(lport);
 139
 140        buf[1] = 0;
 141        ret = kstrtol(buf, 10, &reading);
 142        if (ret) {
 143                QEDF_ERR(&(qedf->dbg_ctx), "Invalid input, err(%d)\n", ret);
 144                return ret;
 145        }
 146
 147        memset(msg, 0, sizeof(msg));
 148        switch (reading) {
 149        case 0:
 150                memset(qedf->grcdump, 0, qedf->grcdump_size);
 151                clear_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags);
 152                break;
 153        case 1:
 154                qedf_capture_grc_dump(qedf);
 155                break;
 156        }
 157
 158        return count;
 159}
 160
 161static struct bin_attribute sysfs_grcdump_attr = {
 162        .attr = {
 163                .name = "grcdump",
 164                .mode = S_IRUSR | S_IWUSR,
 165        },
 166        .size = 0,
 167        .read = qedf_sysfs_read_grcdump,
 168        .write = qedf_sysfs_write_grcdump,
 169};
 170
 171static struct sysfs_bin_attrs bin_file_entries[] = {
 172        {"grcdump", &sysfs_grcdump_attr},
 173        {NULL},
 174};
 175
 176void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf)
 177{
 178        qedf_create_sysfs_attr(qedf->lport->host, bin_file_entries);
 179}
 180
 181void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf)
 182{
 183        qedf_remove_sysfs_attr(qedf->lport->host, bin_file_entries);
 184}
 185