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 int rc = 0; 19 char *word; 20 21 if (!card) 22 return -EINVAL; 23 24 if (qeth_l2_vnicc_is_in_use(card)) 25 return sprintf(buf, "n/a (VNIC characteristics)\n"); 26 27 mutex_lock(&card->sbp_lock); 28 if (qeth_card_hw_is_reachable(card) && 29 card->options.sbp.supported_funcs) 30 rc = qeth_bridgeport_query_ports(card, 31 &card->options.sbp.role, &state); 32 if (!rc) { 33 if (show_state) 34 switch (state) { 35 case QETH_SBP_STATE_INACTIVE: 36 word = "inactive"; break; 37 case QETH_SBP_STATE_STANDBY: 38 word = "standby"; break; 39 case QETH_SBP_STATE_ACTIVE: 40 word = "active"; break; 41 default: 42 rc = -EIO; 43 } 44 else 45 switch (card->options.sbp.role) { 46 case QETH_SBP_ROLE_NONE: 47 word = "none"; break; 48 case QETH_SBP_ROLE_PRIMARY: 49 word = "primary"; break; 50 case QETH_SBP_ROLE_SECONDARY: 51 word = "secondary"; break; 52 default: 53 rc = -EIO; 54 } 55 if (rc) 56 QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x", 57 card->options.sbp.role, state); 58 else 59 rc = sprintf(buf, "%s\n", word); 60 } 61 mutex_unlock(&card->sbp_lock); 62 63 return rc; 64 } 65 66 static ssize_t qeth_bridge_port_role_show(struct device *dev, 67 struct device_attribute *attr, char *buf) 68 { 69 struct qeth_card *card = dev_get_drvdata(dev); 70 71 if (qeth_l2_vnicc_is_in_use(card)) 72 return sprintf(buf, "n/a (VNIC characteristics)\n"); 73 74 return qeth_bridge_port_role_state_show(dev, attr, buf, 0); 75 } 76 77 static ssize_t qeth_bridge_port_role_store(struct device *dev, 78 struct device_attribute *attr, const char *buf, size_t count) 79 { 80 struct qeth_card *card = dev_get_drvdata(dev); 81 int rc = 0; 82 enum qeth_sbp_roles role; 83 84 if (!card) 85 return -EINVAL; 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_l2_vnicc_is_in_use(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_l2_vnicc_is_in_use(card)) 125 return sprintf(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 (!card) 140 return -EINVAL; 141 142 if (qeth_l2_vnicc_is_in_use(card)) 143 return sprintf(buf, "n/a (VNIC characteristics)\n"); 144 145 enabled = card->options.sbp.hostnotification; 146 147 return sprintf(buf, "%d\n", enabled); 148 } 149 150 static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev, 151 struct device_attribute *attr, const char *buf, size_t count) 152 { 153 struct qeth_card *card = dev_get_drvdata(dev); 154 bool enable; 155 int rc; 156 157 if (!card) 158 return -EINVAL; 159 160 rc = kstrtobool(buf, &enable); 161 if (rc) 162 return rc; 163 164 mutex_lock(&card->conf_mutex); 165 mutex_lock(&card->sbp_lock); 166 167 if (qeth_l2_vnicc_is_in_use(card)) 168 rc = -EBUSY; 169 else if (qeth_card_hw_is_reachable(card)) { 170 rc = qeth_bridgeport_an_set(card, enable); 171 if (!rc) 172 card->options.sbp.hostnotification = enable; 173 } else 174 card->options.sbp.hostnotification = enable; 175 176 mutex_unlock(&card->sbp_lock); 177 mutex_unlock(&card->conf_mutex); 178 179 return rc ? rc : count; 180 } 181 182 static DEVICE_ATTR(bridge_hostnotify, 0644, 183 qeth_bridgeport_hostnotification_show, 184 qeth_bridgeport_hostnotification_store); 185 186 static ssize_t qeth_bridgeport_reflect_show(struct device *dev, 187 struct device_attribute *attr, char *buf) 188 { 189 struct qeth_card *card = dev_get_drvdata(dev); 190 char *state; 191 192 if (!card) 193 return -EINVAL; 194 195 if (qeth_l2_vnicc_is_in_use(card)) 196 return sprintf(buf, "n/a (VNIC characteristics)\n"); 197 198 if (card->options.sbp.reflect_promisc) { 199 if (card->options.sbp.reflect_promisc_primary) 200 state = "primary"; 201 else 202 state = "secondary"; 203 } else 204 state = "none"; 205 206 return sprintf(buf, "%s\n", state); 207 } 208 209 static ssize_t qeth_bridgeport_reflect_store(struct device *dev, 210 struct device_attribute *attr, const char *buf, size_t count) 211 { 212 struct qeth_card *card = dev_get_drvdata(dev); 213 int enable, primary; 214 int rc = 0; 215 216 if (!card) 217 return -EINVAL; 218 219 if (sysfs_streq(buf, "none")) { 220 enable = 0; 221 primary = 0; 222 } else if (sysfs_streq(buf, "primary")) { 223 enable = 1; 224 primary = 1; 225 } else if (sysfs_streq(buf, "secondary")) { 226 enable = 1; 227 primary = 0; 228 } else 229 return -EINVAL; 230 231 mutex_lock(&card->conf_mutex); 232 mutex_lock(&card->sbp_lock); 233 234 if (qeth_l2_vnicc_is_in_use(card)) 235 rc = -EBUSY; 236 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE) 237 rc = -EPERM; 238 else { 239 card->options.sbp.reflect_promisc = enable; 240 card->options.sbp.reflect_promisc_primary = primary; 241 rc = 0; 242 } 243 244 mutex_unlock(&card->sbp_lock); 245 mutex_unlock(&card->conf_mutex); 246 247 return rc ? rc : count; 248 } 249 250 static DEVICE_ATTR(bridge_reflect_promisc, 0644, 251 qeth_bridgeport_reflect_show, 252 qeth_bridgeport_reflect_store); 253 254 static struct attribute *qeth_l2_bridgeport_attrs[] = { 255 &dev_attr_bridge_role.attr, 256 &dev_attr_bridge_state.attr, 257 &dev_attr_bridge_hostnotify.attr, 258 &dev_attr_bridge_reflect_promisc.attr, 259 NULL, 260 }; 261 262 static struct attribute_group qeth_l2_bridgeport_attr_group = { 263 .attrs = qeth_l2_bridgeport_attrs, 264 }; 265 266 /** 267 * qeth_l2_setup_bridgeport_attrs() - set/restore attrs when turning online. 268 * @card: qeth_card structure pointer 269 * 270 * Note: this function is called with conf_mutex held by the caller 271 */ 272 void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) 273 { 274 int rc; 275 276 if (!card) 277 return; 278 if (!card->options.sbp.supported_funcs) 279 return; 280 281 mutex_lock(&card->sbp_lock); 282 if (card->options.sbp.role != QETH_SBP_ROLE_NONE) { 283 /* Conditional to avoid spurious error messages */ 284 qeth_bridgeport_setrole(card, card->options.sbp.role); 285 /* Let the callback function refresh the stored role value. */ 286 qeth_bridgeport_query_ports(card, 287 &card->options.sbp.role, NULL); 288 } 289 if (card->options.sbp.hostnotification) { 290 rc = qeth_bridgeport_an_set(card, 1); 291 if (rc) 292 card->options.sbp.hostnotification = 0; 293 } else { 294 qeth_bridgeport_an_set(card, 0); 295 } 296 mutex_unlock(&card->sbp_lock); 297 } 298 299 /* VNIC CHARS support */ 300 301 /* convert sysfs attr name to VNIC characteristic */ 302 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name) 303 { 304 if (sysfs_streq(attr_name, "flooding")) 305 return QETH_VNICC_FLOODING; 306 else if (sysfs_streq(attr_name, "mcast_flooding")) 307 return QETH_VNICC_MCAST_FLOODING; 308 else if (sysfs_streq(attr_name, "learning")) 309 return QETH_VNICC_LEARNING; 310 else if (sysfs_streq(attr_name, "takeover_setvmac")) 311 return QETH_VNICC_TAKEOVER_SETVMAC; 312 else if (sysfs_streq(attr_name, "takeover_learning")) 313 return QETH_VNICC_TAKEOVER_LEARNING; 314 else if (sysfs_streq(attr_name, "bridge_invisible")) 315 return QETH_VNICC_BRIDGE_INVISIBLE; 316 else if (sysfs_streq(attr_name, "rx_bcast")) 317 return QETH_VNICC_RX_BCAST; 318 319 return 0; 320 } 321 322 /* get current timeout setting */ 323 static ssize_t qeth_vnicc_timeout_show(struct device *dev, 324 struct device_attribute *attr, char *buf) 325 { 326 struct qeth_card *card = dev_get_drvdata(dev); 327 u32 timeout; 328 int rc; 329 330 if (!card) 331 return -EINVAL; 332 333 rc = qeth_l2_vnicc_get_timeout(card, &timeout); 334 if (rc == -EBUSY) 335 return sprintf(buf, "n/a (BridgePort)\n"); 336 if (rc == -EOPNOTSUPP) 337 return sprintf(buf, "n/a\n"); 338 return rc ? rc : sprintf(buf, "%d\n", timeout); 339 } 340 341 /* change timeout setting */ 342 static ssize_t qeth_vnicc_timeout_store(struct device *dev, 343 struct device_attribute *attr, 344 const char *buf, size_t count) 345 { 346 struct qeth_card *card = dev_get_drvdata(dev); 347 u32 timeout; 348 int rc; 349 350 if (!card) 351 return -EINVAL; 352 353 rc = kstrtou32(buf, 10, &timeout); 354 if (rc) 355 return rc; 356 357 mutex_lock(&card->conf_mutex); 358 rc = qeth_l2_vnicc_set_timeout(card, timeout); 359 mutex_unlock(&card->conf_mutex); 360 return rc ? rc : count; 361 } 362 363 /* get current setting of characteristic */ 364 static ssize_t qeth_vnicc_char_show(struct device *dev, 365 struct device_attribute *attr, char *buf) 366 { 367 struct qeth_card *card = dev_get_drvdata(dev); 368 bool state; 369 u32 vnicc; 370 int rc; 371 372 if (!card) 373 return -EINVAL; 374 375 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name); 376 rc = qeth_l2_vnicc_get_state(card, vnicc, &state); 377 378 if (rc == -EBUSY) 379 return sprintf(buf, "n/a (BridgePort)\n"); 380 if (rc == -EOPNOTSUPP) 381 return sprintf(buf, "n/a\n"); 382 return rc ? rc : sprintf(buf, "%d\n", state); 383 } 384 385 /* change setting of characteristic */ 386 static ssize_t qeth_vnicc_char_store(struct device *dev, 387 struct device_attribute *attr, 388 const char *buf, size_t count) 389 { 390 struct qeth_card *card = dev_get_drvdata(dev); 391 bool state; 392 u32 vnicc; 393 int rc; 394 395 if (!card) 396 return -EINVAL; 397 398 if (kstrtobool(buf, &state)) 399 return -EINVAL; 400 401 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name); 402 mutex_lock(&card->conf_mutex); 403 rc = qeth_l2_vnicc_set_state(card, vnicc, state); 404 mutex_unlock(&card->conf_mutex); 405 406 return rc ? rc : count; 407 } 408 409 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 410 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show, 411 qeth_vnicc_char_store); 412 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 413 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show, 414 qeth_vnicc_timeout_store); 415 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show, 416 qeth_vnicc_char_store); 417 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show, 418 qeth_vnicc_char_store); 419 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show, 420 qeth_vnicc_char_store); 421 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 422 423 static struct attribute *qeth_l2_vnicc_attrs[] = { 424 &dev_attr_flooding.attr, 425 &dev_attr_mcast_flooding.attr, 426 &dev_attr_learning.attr, 427 &dev_attr_learning_timeout.attr, 428 &dev_attr_takeover_setvmac.attr, 429 &dev_attr_takeover_learning.attr, 430 &dev_attr_bridge_invisible.attr, 431 &dev_attr_rx_bcast.attr, 432 NULL, 433 }; 434 435 static struct attribute_group qeth_l2_vnicc_attr_group = { 436 .attrs = qeth_l2_vnicc_attrs, 437 .name = "vnicc", 438 }; 439 440 static const struct attribute_group *qeth_l2_only_attr_groups[] = { 441 &qeth_l2_bridgeport_attr_group, 442 &qeth_l2_vnicc_attr_group, 443 NULL, 444 }; 445 446 int qeth_l2_create_device_attributes(struct device *dev) 447 { 448 return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups); 449 } 450 451 void qeth_l2_remove_device_attributes(struct device *dev) 452 { 453 sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups); 454 } 455 456 const struct attribute_group *qeth_l2_attr_groups[] = { 457 &qeth_device_attr_group, 458 &qeth_device_blkt_group, 459 /* l2 specific, see qeth_l2_only_attr_groups: */ 460 &qeth_l2_bridgeport_attr_group, 461 &qeth_l2_vnicc_attr_group, 462 NULL, 463 }; 464