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