Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.3-rc8 451 lines 12 kB view raw
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 12static 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 64static 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 75static 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 112static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show, 113 qeth_bridge_port_role_store); 114 115static 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 126static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show, 127 NULL); 128 129static 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 146static 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 176static DEVICE_ATTR(bridge_hostnotify, 0644, 177 qeth_bridgeport_hostnotification_show, 178 qeth_bridgeport_hostnotification_store); 179 180static 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 203static 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 242static DEVICE_ATTR(bridge_reflect_promisc, 0644, 243 qeth_bridgeport_reflect_show, 244 qeth_bridgeport_reflect_store); 245 246static 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 254static 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 */ 264void 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 */ 290static 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 */ 311static 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 */ 330static 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 */ 352static 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 */ 374static 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 397static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 398static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show, 399 qeth_vnicc_char_store); 400static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 401static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show, 402 qeth_vnicc_timeout_store); 403static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show, 404 qeth_vnicc_char_store); 405static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show, 406 qeth_vnicc_char_store); 407static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show, 408 qeth_vnicc_char_store); 409static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store); 410 411static 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 423static struct attribute_group qeth_l2_vnicc_attr_group = { 424 .attrs = qeth_l2_vnicc_attrs, 425 .name = "vnicc", 426}; 427 428static 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 434int qeth_l2_create_device_attributes(struct device *dev) 435{ 436 return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups); 437} 438 439void qeth_l2_remove_device_attributes(struct device *dev) 440{ 441 sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups); 442} 443 444const 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};