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