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 struct device_attribute *qedf_host_attrs[] = { 64 &dev_attr_fcoe_mac, 65 &dev_attr_fka_period, 66 NULL, 67 }; 68 69 extern const struct qed_fcoe_ops *qed_ops; 70 71 void qedf_capture_grc_dump(struct qedf_ctx *qedf) 72 { 73 struct qedf_ctx *base_qedf; 74 75 /* Make sure we use the base qedf to take the GRC dump */ 76 if (qedf_is_vport(qedf)) 77 base_qedf = qedf_get_base_qedf(qedf); 78 else 79 base_qedf = qedf; 80 81 if (test_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags)) { 82 QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_INFO, 83 "GRC Dump already captured.\n"); 84 return; 85 } 86 87 88 qedf_get_grc_dump(base_qedf->cdev, qed_ops->common, 89 &base_qedf->grcdump, &base_qedf->grcdump_size); 90 QEDF_ERR(&(base_qedf->dbg_ctx), "GRC Dump captured.\n"); 91 set_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags); 92 qedf_uevent_emit(base_qedf->lport->host, QEDF_UEVENT_CODE_GRCDUMP, 93 NULL); 94 } 95 96 static ssize_t 97 qedf_sysfs_read_grcdump(struct file *filep, struct kobject *kobj, 98 struct bin_attribute *ba, char *buf, loff_t off, 99 size_t count) 100 { 101 ssize_t ret = 0; 102 struct fc_lport *lport = shost_priv(dev_to_shost(container_of(kobj, 103 struct device, kobj))); 104 struct qedf_ctx *qedf = lport_priv(lport); 105 106 if (test_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags)) { 107 ret = memory_read_from_buffer(buf, count, &off, 108 qedf->grcdump, qedf->grcdump_size); 109 } else { 110 QEDF_ERR(&(qedf->dbg_ctx), "GRC Dump not captured!\n"); 111 } 112 113 return ret; 114 } 115 116 static ssize_t 117 qedf_sysfs_write_grcdump(struct file *filep, struct kobject *kobj, 118 struct bin_attribute *ba, char *buf, loff_t off, 119 size_t count) 120 { 121 struct fc_lport *lport = NULL; 122 struct qedf_ctx *qedf = NULL; 123 long reading; 124 int ret = 0; 125 char msg[40]; 126 127 if (off != 0) 128 return ret; 129 130 131 lport = shost_priv(dev_to_shost(container_of(kobj, 132 struct device, kobj))); 133 qedf = lport_priv(lport); 134 135 buf[1] = 0; 136 ret = kstrtol(buf, 10, &reading); 137 if (ret) { 138 QEDF_ERR(&(qedf->dbg_ctx), "Invalid input, err(%d)\n", ret); 139 return ret; 140 } 141 142 memset(msg, 0, sizeof(msg)); 143 switch (reading) { 144 case 0: 145 memset(qedf->grcdump, 0, qedf->grcdump_size); 146 clear_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags); 147 break; 148 case 1: 149 qedf_capture_grc_dump(qedf); 150 break; 151 } 152 153 return count; 154 } 155 156 static struct bin_attribute sysfs_grcdump_attr = { 157 .attr = { 158 .name = "grcdump", 159 .mode = S_IRUSR | S_IWUSR, 160 }, 161 .size = 0, 162 .read = qedf_sysfs_read_grcdump, 163 .write = qedf_sysfs_write_grcdump, 164 }; 165 166 static struct sysfs_bin_attrs bin_file_entries[] = { 167 {"grcdump", &sysfs_grcdump_attr}, 168 {NULL}, 169 }; 170 171 void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf) 172 { 173 qedf_create_sysfs_attr(qedf->lport->host, bin_file_entries); 174 } 175 176 void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf) 177 { 178 qedf_remove_sysfs_attr(qedf->lport->host, bin_file_entries); 179 } 180