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 8 inline 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 */ 14 static 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 27 static 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 44 static 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 60 static DEVICE_ATTR_RO(fcoe_mac); 61 static DEVICE_ATTR_RO(fka_period); 62 63 static struct attribute *qedf_host_attrs[] = { 64 &dev_attr_fcoe_mac.attr, 65 &dev_attr_fka_period.attr, 66 NULL, 67 }; 68 69 static const struct attribute_group qedf_host_attr_group = { 70 .attrs = qedf_host_attrs 71 }; 72 73 const struct attribute_group *qedf_host_groups[] = { 74 &qedf_host_attr_group, 75 NULL 76 }; 77 78 extern const struct qed_fcoe_ops *qed_ops; 79 80 void 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 105 static ssize_t 106 qedf_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 125 static ssize_t 126 qedf_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 163 static 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 173 static struct sysfs_bin_attrs bin_file_entries[] = { 174 {"grcdump", &sysfs_grcdump_attr}, 175 {NULL}, 176 }; 177 178 void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf) 179 { 180 qedf_create_sysfs_attr(qedf->lport->host, bin_file_entries); 181 } 182 183 void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf) 184 { 185 qedf_remove_sysfs_attr(qedf->lport->host, bin_file_entries); 186 } 187