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