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