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