Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  QLogic FCoE Offload Driver
0004  *  Copyright (c) 2016-2018 Cavium Inc.
0005  */
0006 #include "qedf.h"
0007 
0008 inline bool qedf_is_vport(struct qedf_ctx *qedf)
0009 {
0010     return qedf->lport->vport != NULL;
0011 }
0012 
0013 /* Get base qedf for physical port from vport */
0014 static struct qedf_ctx *qedf_get_base_qedf(struct qedf_ctx *qedf)
0015 {
0016     struct fc_lport *lport;
0017     struct fc_lport *base_lport;
0018 
0019     if (!(qedf_is_vport(qedf)))
0020         return NULL;
0021 
0022     lport = qedf->lport;
0023     base_lport = shost_priv(vport_to_shost(lport->vport));
0024     return lport_priv(base_lport);
0025 }
0026 
0027 static ssize_t fcoe_mac_show(struct device *dev,
0028                  struct device_attribute *attr, char *buf)
0029 {
0030     struct fc_lport *lport = shost_priv(class_to_shost(dev));
0031     u32 port_id;
0032     u8 lport_src_id[3];
0033     u8 fcoe_mac[6];
0034 
0035     port_id = fc_host_port_id(lport->host);
0036     lport_src_id[2] = (port_id & 0x000000FF);
0037     lport_src_id[1] = (port_id & 0x0000FF00) >> 8;
0038     lport_src_id[0] = (port_id & 0x00FF0000) >> 16;
0039     fc_fcoe_set_mac(fcoe_mac, lport_src_id);
0040 
0041     return scnprintf(buf, PAGE_SIZE, "%pM\n", fcoe_mac);
0042 }
0043 
0044 static ssize_t fka_period_show(struct device *dev,
0045                    struct device_attribute *attr, char *buf)
0046 {
0047     struct fc_lport *lport = shost_priv(class_to_shost(dev));
0048     struct qedf_ctx *qedf = lport_priv(lport);
0049     int fka_period = -1;
0050 
0051     if (qedf_is_vport(qedf))
0052         qedf = qedf_get_base_qedf(qedf);
0053 
0054     if (qedf->ctlr.sel_fcf)
0055         fka_period = qedf->ctlr.sel_fcf->fka_period;
0056 
0057     return scnprintf(buf, PAGE_SIZE, "%d\n", fka_period);
0058 }
0059 
0060 static DEVICE_ATTR_RO(fcoe_mac);
0061 static DEVICE_ATTR_RO(fka_period);
0062 
0063 static struct attribute *qedf_host_attrs[] = {
0064     &dev_attr_fcoe_mac.attr,
0065     &dev_attr_fka_period.attr,
0066     NULL,
0067 };
0068 
0069 static const struct attribute_group qedf_host_attr_group = {
0070     .attrs = qedf_host_attrs
0071 };
0072 
0073 const struct attribute_group *qedf_host_groups[] = {
0074     &qedf_host_attr_group,
0075     NULL
0076 };
0077 
0078 extern const struct qed_fcoe_ops *qed_ops;
0079 
0080 void qedf_capture_grc_dump(struct qedf_ctx *qedf)
0081 {
0082     struct qedf_ctx *base_qedf;
0083 
0084     /* Make sure we use the base qedf to take the GRC dump */
0085     if (qedf_is_vport(qedf))
0086         base_qedf = qedf_get_base_qedf(qedf);
0087     else
0088         base_qedf = qedf;
0089 
0090     if (test_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags)) {
0091         QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_INFO,
0092             "GRC Dump already captured.\n");
0093         return;
0094     }
0095 
0096 
0097     qedf_get_grc_dump(base_qedf->cdev, qed_ops->common,
0098         &base_qedf->grcdump, &base_qedf->grcdump_size);
0099     QEDF_ERR(&(base_qedf->dbg_ctx), "GRC Dump captured.\n");
0100     set_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags);
0101     qedf_uevent_emit(base_qedf->lport->host, QEDF_UEVENT_CODE_GRCDUMP,
0102         NULL);
0103 }
0104 
0105 static ssize_t
0106 qedf_sysfs_read_grcdump(struct file *filep, struct kobject *kobj,
0107             struct bin_attribute *ba, char *buf, loff_t off,
0108             size_t count)
0109 {
0110     ssize_t ret = 0;
0111     struct fc_lport *lport = shost_priv(dev_to_shost(container_of(kobj,
0112                             struct device, kobj)));
0113     struct qedf_ctx *qedf = lport_priv(lport);
0114 
0115     if (test_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags)) {
0116         ret = memory_read_from_buffer(buf, count, &off,
0117             qedf->grcdump, qedf->grcdump_size);
0118     } else {
0119         QEDF_ERR(&(qedf->dbg_ctx), "GRC Dump not captured!\n");
0120     }
0121 
0122     return ret;
0123 }
0124 
0125 static ssize_t
0126 qedf_sysfs_write_grcdump(struct file *filep, struct kobject *kobj,
0127             struct bin_attribute *ba, char *buf, loff_t off,
0128             size_t count)
0129 {
0130     struct fc_lport *lport = NULL;
0131     struct qedf_ctx *qedf = NULL;
0132     long reading;
0133     int ret = 0;
0134 
0135     if (off != 0)
0136         return ret;
0137 
0138 
0139     lport = shost_priv(dev_to_shost(container_of(kobj,
0140         struct device, kobj)));
0141     qedf = lport_priv(lport);
0142 
0143     buf[1] = 0;
0144     ret = kstrtol(buf, 10, &reading);
0145     if (ret) {
0146         QEDF_ERR(&(qedf->dbg_ctx), "Invalid input, err(%d)\n", ret);
0147         return ret;
0148     }
0149 
0150     switch (reading) {
0151     case 0:
0152         memset(qedf->grcdump, 0, qedf->grcdump_size);
0153         clear_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags);
0154         break;
0155     case 1:
0156         qedf_capture_grc_dump(qedf);
0157         break;
0158     }
0159 
0160     return count;
0161 }
0162 
0163 static struct bin_attribute sysfs_grcdump_attr = {
0164     .attr = {
0165         .name = "grcdump",
0166         .mode = S_IRUSR | S_IWUSR,
0167     },
0168     .size = 0,
0169     .read = qedf_sysfs_read_grcdump,
0170     .write = qedf_sysfs_write_grcdump,
0171 };
0172 
0173 static struct sysfs_bin_attrs bin_file_entries[] = {
0174     {"grcdump", &sysfs_grcdump_attr},
0175     {NULL},
0176 };
0177 
0178 void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf)
0179 {
0180     qedf_create_sysfs_attr(qedf->lport->host, bin_file_entries);
0181 }
0182 
0183 void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf)
0184 {
0185     qedf_remove_sysfs_attr(qedf->lport->host, bin_file_entries);
0186 }