1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright IBM Corp. 2013 4 * Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com> 5 */ 6 7 #include <linux/slab.h> 8 #include <asm/ebcdic.h> 9 #include "qeth_core.h" 10 #include "qeth_l2.h" 11 12 static ssize_t qeth_bridge_port_role_state_show(struct device *dev, 13 struct device_attribute *attr, char *buf, 14 int show_state) 15 { 16 struct qeth_card *card = dev_get_drvdata(dev); 17 enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE; 18 bool os_mismatch = false; 19 int rc = 0; 20 char *word; 21 22 if (!qeth_bridgeport_allowed(card)) 23 return sysfs_emit(buf, "n/a (VNIC characteristics)\n"); 24 25 mutex_lock(&card->sbp_lock); 26 if (qeth_card_hw_is_reachable(card) && 27 card->options.sbp.supported_funcs) 28 rc = qeth_bridgeport_query_ports(card, 29 &card->options.sbp.role, &state, &os_mismatch); 30 if (!rc) { 31 if (show_state) 32 switch (state) { 33 case QETH_SBP_STATE_INACTIVE: 34 word = "inactive"; break; 35 case QETH_SBP_STATE_STANDBY: 36 word = "standby"; break; 37 case QETH_SBP_STATE_ACTIVE: 38 word = "active"; break; 39 default: 40 rc = -EIO; 41 } 42 else 43 switch (card->options.sbp.role) { 44 case QETH_SBP_ROLE_NONE: 45 word = "none"; break; 46 case QETH_SBP_ROLE_PRIMARY: 47 word = "primary"; break; 48 case QETH_SBP_ROLE_SECONDARY: 49 word = "secondary"; break; 50 default: 51 rc = -EIO; 52 } 53 if (rc) 54 QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x", 55 card->options.sbp.role, state); 56 else if (!show_state && 57 card->options.sbp.role == QETH_SBP_ROLE_NONE && 58 os_mismatch) 59 rc = sysfs_emit(buf, "%s (OS family mismatch)\n", word); 60 else 61 rc = sysfs_emit(buf, "%s\n", word); 62 } 63 mutex_unlock(&card->sbp_lock); 64 65 return rc; 66 } 67 68 static ssize_t qeth_bridge_port_role_show(struct device *dev, 69 struct device_attribute *attr, char *buf) 70 { 71 struct qeth_card *card = dev_get_drvdata(dev); 72 73 if (!qeth_bridgeport_allowed(card)) 74 return sysfs_emit(buf, "n/a (VNIC characteristics)\n"); 75 76 return qeth_bridge_port_role_state_show(dev, attr, buf, 0); 77 } 78 79 static ssize_t qeth_bridge_port_role_store(struct device *dev, 80 struct device_attribute *attr, const char *buf, size_t count) 81 { 82 struct qeth_card *card = dev_get_drvdata(dev); 83 int rc = 0; 84 enum qeth_sbp_roles role; 85 86 if (sysfs_streq(buf, "primary")) 87 role = QETH_SBP_ROLE_PRIMARY; 88 else if (sysfs_streq(buf, "secondary")) 89 role = QETH_SBP_ROLE_SECONDARY; 90 else if (sysfs_streq(buf, "none")) 91 role = QETH_SBP_ROLE_NONE; 92 else 93 return -EINVAL; 94 95 mutex_lock(&card->conf_mutex); 96 mutex_lock(&card->sbp_lock); 97 98 if (!qeth_bridgeport_allowed(card)) 99 rc = -EBUSY; 100 else if (card->options.sbp.reflect_promisc) 101 /* Forbid direct manipulation */ 102 rc = -EPERM; 103 else if (qeth_card_hw_is_reachable(card)) { 104 rc = qeth_bridgeport_setrole(card, role); 105 if (!rc) 106 card->options.sbp.role = role; 107 } else 108 card->options.sbp.role = role; 109 110 mutex_unlock(&card->sbp_lock); 111 mutex_unlock(&card->conf_mutex); 112 113 return rc ? rc : count; 114 } 115 116 static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show, 117 qeth_bridge_port_role_store); 118 119 static ssize_t qeth_bridge_port_state_show(struct device *dev, 120 struct device_attribute *attr, char *buf) 121 { 122 struct qeth_card *card = dev_get_drvdata(dev); 123 124 if (!qeth_bridgeport_allowed(card)) 125 return sysfs_emit(buf, "n/a (VNIC characteristics)\n"); 126 127 return qeth_bridge_port_role_state_show(dev, attr, buf, 1); 128 } 129 130 static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show, 131 NULL); 132 133 static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev, 134 struct device_attribute *attr, char *buf) 135 { 136 struct qeth_card *card = dev_get_drvdata(dev); 137 int enabled; 138 139 if (!qeth_bridgeport_allowed(card)) 140 return sysfs_emit(buf, "n/a (VNIC characteristics)\n"); 141 142 enabled = card->options.sbp.hostnotification; 143 144 return sysfs_emit(buf, "%d\n", enabled); 145 } 146 147 static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev, 148 struct device_attribute *attr, const char *buf, size_t count) 149 { 150 struct qeth_card *card = dev_get_drvdata(dev); 151 bool enable; 152 int rc; 153 154 rc = kstrtobool(buf, &enable); 155 if (rc) 156 return rc; 157 158 mutex_lock(&card->conf_mutex); 159 mutex_lock(&card->sbp_lock); 160 161 if (!qeth_bridgeport_allowed(card)) 162 rc = -EBUSY; 163 else if (qeth_card_hw_is_reachable(card)) { 164 rc = qeth_bridgeport_an_set(card, enable); 165 /* sbp_lock ensures ordering vs notifications-stopped events */ 166 if (!rc) 167 card->options.sbp.hostnotification = enable; 168 } else 169 card->options.sbp.hostnotification = enable; 170 171 mutex_unlock(&card->sbp_lock); 172 mutex_unlock(&card->conf_mutex); 173 174 return rc ? rc : count; 175 } 176 177 static DEVICE_ATTR(bridge_hostnotify, 0644, 178 qeth_bridgeport_hostnotification_show, 179 qeth_bridgeport_hostnotification_store); 180 181 static ssize_t qeth_bridgeport_reflect_show(struct device *dev, 182 struct device_attribute *attr, char *buf) 183 { 184 struct qeth_card *card = dev_get_drvdata(dev); 185 char *state; 186 187 if (!qeth_bridgeport_allowed(card)) 188 return sysfs_emit(buf, "n/a (VNIC characteristics)\n"); 189 190 if (card->options.sbp.reflect_promisc) { 191 if (card->options.sbp.reflect_promisc_primary) 192 state = "primary"; 193 else 194 state = "secondary"; 195 } else 196 state = "none"; 197 198 return sysfs_emit(buf, "%s\n", state); 199 } 200 201 static ssize_t qeth_bridgeport_reflect_store(struct device *dev, 202 struct device_attribute *attr, const char *buf, size_t count) 203 { 204 struct qeth_card *card = dev_get_drvdata(dev); 205 int enable, primary; 206 int rc = 0; 207 208 if (sysfs_streq(buf, "none")) { 209 enable = 0; 210 primary = 0; 211 } else if (sysfs_streq(buf, "primary")) { 212 enable = 1; 213 primary = 1; 214 } else if (sysfs_streq(buf, "secondary")) { 215 enable = 1; 216 primary = 0; 217 } else 218 return -EINVAL; 219 220 mutex_lock(&card->conf_mutex); 221 mutex_lock(&card->sbp_lock); 222 223 if (!qeth_bridgeport_allowed(card)) 224 rc = -EBUSY; 225 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE) 226 rc = -EPERM; 227 else { 228 card->options.sbp.reflect_promisc = enable; 229 card->options.sbp.reflect_promisc_primary = primary; 230 rc = 0; 231 } 232 233 mutex_unlock(&card->sbp_lock); 234 mutex_unlock(&card->conf_mutex); 235 236 return rc ? rc : count; 237 } 238 239 static DEVICE_ATTR(bridge_reflect_promisc, 0644, 240 qeth_bridgeport_reflect_show, 241 qeth_bridgeport_reflect_store); 242 243 static struct attribute *qeth_l2_bridgeport_attrs[] = { 244 &dev_attr_bridge_role.attr, 245 &dev_attr_bridge_state.attr, 246 &dev_attr_bridge_hostnotify.attr, 247 &dev_attr_bridge_reflect_promisc.attr, 248 NULL, 249 }; 250 251 static struct attribute_group qeth_l2_bridgeport_attr_group = { 252 .attrs = qeth_l2_bridgeport_attrs, 253 }; 254 255 /* VNIC CHARS support */ 256 257 /* convert sysfs attr name to VNIC characteristic */ 258 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name) 259 { 260 if (sysfs_streq(attr_name, "flooding")) 261 return QETH_VNICC_FLOODING; 262 else if (sysfs_streq(attr_name, "mcast_flooding")) 263 return QETH_VNICC_MCAST_FLOODING; 264 else if (sysfs_streq(attr_name, "learning")) 265 return QETH_VNICC_LEARNING; 266 else if (sysfs_streq(attr_name, "takeover_setvmac")) 267 return QETH_VNICC_TAKEOVER_SETVMAC; 268 else if (sysfs_streq(attr_name, "takeover_learning")) 269 return QETH_VNICC_TAKEOVER_LEARNING; 270 else if (sysfs_streq(attr_name, "bridge_invisible")) 271 return QETH_VNICC_BRIDGE_INVISIBLE; 272 else if (sysfs_streq(attr_name, "rx_bcast")) 273 return QETH_VNICC_RX_BCAST; 274 275 return 0; 276 } 277 278 /* get current timeout setting */ 279 static ssize_t qeth_vnicc_timeout_show(struct device *dev, 280 struct device_attribute *attr, char *buf) 281 { 282 struct qeth_card *card = dev_get_drvdata(dev); 283 u32 timeout; 284 int rc; 285 286 rc = qeth_l2_vnicc_get_timeout(card, &timeout); 287 if (rc == -EBUSY) 288 return sysfs_emit(buf, "n/a (BridgePort)\n"); 289 if (rc == -EOPNOTSUPP) 290 return sysfs_emit(buf, "n/a\n"); 291 return rc ? rc : sysfs_emit(buf, "%d\n", timeout); 292 } 293 294 /* change timeout setting */ 295 static ssize_t qeth_vnicc_timeout_store(struct device *dev, 296 struct device_attribute *attr, 297 const char *buf, size_t count) 298 { 299 struct qeth_card *card = dev_get_drvdata(dev); 300 u32 timeout; 301 int rc; 302 303 rc = kstrtou32(buf, 10, &timeout); 304 if (rc) 305 return rc; 306 307 mutex_lock(&card->conf_mutex); 308 rc = qeth_l2_vnicc_set_timeout(card, timeout); 309 mutex_unlock(&card->conf_mutex); 310 return rc ? rc : count; 311 } 312 313 /* get current setting of characteristic */ 314 static ssize_t qeth_vnicc_char_show(struct device *dev, 315 struct device_attribute *attr, char *buf) 316 { 317 struct qeth_card *card = dev_get_drvdata(dev); 318 bool state; 319 u32 vnicc; 320 int rc; 321 322 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name); 323 rc = qeth_l2_vnicc_get_state(card, vnicc, &state); 324 325 if (rc == -EBUSY) 326 return sysfs_emit(buf, "n/a (BridgePort)\n"); 327 if (rc == -EOPNOTSUPP) 328 return sysfs_emit(buf, "n/a\n"); 329 return rc ? rc : sysfs_emit(buf, "%d\n", state); 330 } 331 332 /* change setting of characteristic */ 333 static ssize_t qeth_vnicc_char_store(struct device *dev, 334 struct device_attribute *attr, 335 const char *buf, size_t count) 336 { 337 struct qeth_card *card = dev_get_drvdata(dev); 338 bool state; 339 u32 vnicc; 340 int rc; 341 342 if (kstrtobool(buf, &state)) 343 return -EINVAL; 344 345 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name); 346 mutex_lock(&card->conf_mutex); 347 rc = qeth_l2_vnicc_set_state(card, vnicc, state); 348 mutex_unlock(&card->conf_mutex); 349 350 return rc ? rc : count; 351 } 352 353 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 354 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show, 355 qeth_vnicc_char_store); 356 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 357 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show, 358 qeth_vnicc_timeout_store); 359 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show, 360 qeth_vnicc_char_store); 361 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show, 362 qeth_vnicc_char_store); 363 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show, 364 qeth_vnicc_char_store); 365 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 366 367 static struct attribute *qeth_l2_vnicc_attrs[] = { 368 &dev_attr_flooding.attr, 369 &dev_attr_mcast_flooding.attr, 370 &dev_attr_learning.attr, 371 &dev_attr_learning_timeout.attr, 372 &dev_attr_takeover_setvmac.attr, 373 &dev_attr_takeover_learning.attr, 374 &dev_attr_bridge_invisible.attr, 375 &dev_attr_rx_bcast.attr, 376 NULL, 377 }; 378 379 static struct attribute_group qeth_l2_vnicc_attr_group = { 380 .attrs = qeth_l2_vnicc_attrs, 381 .name = "vnicc", 382 }; 383 384 const struct attribute_group *qeth_l2_attr_groups[] = { 385 &qeth_l2_bridgeport_attr_group, 386 &qeth_l2_vnicc_attr_group, 387 NULL, 388 }; 389