root/drivers/s390/net/qeth_l2_sys.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qeth_bridge_port_role_state_show
  2. qeth_bridge_port_role_show
  3. qeth_bridge_port_role_store
  4. qeth_bridge_port_state_show
  5. qeth_bridgeport_hostnotification_show
  6. qeth_bridgeport_hostnotification_store
  7. qeth_bridgeport_reflect_show
  8. qeth_bridgeport_reflect_store
  9. qeth_l2_setup_bridgeport_attrs
  10. qeth_l2_vnicc_sysfs_attr_to_char
  11. qeth_vnicc_timeout_show
  12. qeth_vnicc_timeout_store
  13. qeth_vnicc_char_show
  14. qeth_vnicc_char_store
  15. qeth_l2_create_device_attributes
  16. qeth_l2_remove_device_attributes

   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.reflect_promisc &&
 283             card->options.sbp.role != QETH_SBP_ROLE_NONE) {
 284                 /* Conditional to avoid spurious error messages */
 285                 qeth_bridgeport_setrole(card, card->options.sbp.role);
 286                 /* Let the callback function refresh the stored role value. */
 287                 qeth_bridgeport_query_ports(card,
 288                         &card->options.sbp.role, NULL);
 289         }
 290         if (card->options.sbp.hostnotification) {
 291                 rc = qeth_bridgeport_an_set(card, 1);
 292                 if (rc)
 293                         card->options.sbp.hostnotification = 0;
 294         } else {
 295                 qeth_bridgeport_an_set(card, 0);
 296         }
 297         mutex_unlock(&card->sbp_lock);
 298 }
 299 
 300 /* VNIC CHARS support */
 301 
 302 /* convert sysfs attr name to VNIC characteristic */
 303 static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
 304 {
 305         if (sysfs_streq(attr_name, "flooding"))
 306                 return QETH_VNICC_FLOODING;
 307         else if (sysfs_streq(attr_name, "mcast_flooding"))
 308                 return QETH_VNICC_MCAST_FLOODING;
 309         else if (sysfs_streq(attr_name, "learning"))
 310                 return QETH_VNICC_LEARNING;
 311         else if (sysfs_streq(attr_name, "takeover_setvmac"))
 312                 return QETH_VNICC_TAKEOVER_SETVMAC;
 313         else if (sysfs_streq(attr_name, "takeover_learning"))
 314                 return QETH_VNICC_TAKEOVER_LEARNING;
 315         else if (sysfs_streq(attr_name, "bridge_invisible"))
 316                 return QETH_VNICC_BRIDGE_INVISIBLE;
 317         else if (sysfs_streq(attr_name, "rx_bcast"))
 318                 return QETH_VNICC_RX_BCAST;
 319 
 320         return 0;
 321 }
 322 
 323 /* get current timeout setting */
 324 static ssize_t qeth_vnicc_timeout_show(struct device *dev,
 325                                        struct device_attribute *attr, char *buf)
 326 {
 327         struct qeth_card *card = dev_get_drvdata(dev);
 328         u32 timeout;
 329         int rc;
 330 
 331         if (!card)
 332                 return -EINVAL;
 333 
 334         rc = qeth_l2_vnicc_get_timeout(card, &timeout);
 335         if (rc == -EBUSY)
 336                 return sprintf(buf, "n/a (BridgePort)\n");
 337         if (rc == -EOPNOTSUPP)
 338                 return sprintf(buf, "n/a\n");
 339         return rc ? rc : sprintf(buf, "%d\n", timeout);
 340 }
 341 
 342 /* change timeout setting */
 343 static ssize_t qeth_vnicc_timeout_store(struct device *dev,
 344                                         struct device_attribute *attr,
 345                                         const char *buf, size_t count)
 346 {
 347         struct qeth_card *card = dev_get_drvdata(dev);
 348         u32 timeout;
 349         int rc;
 350 
 351         if (!card)
 352                 return -EINVAL;
 353 
 354         rc = kstrtou32(buf, 10, &timeout);
 355         if (rc)
 356                 return rc;
 357 
 358         mutex_lock(&card->conf_mutex);
 359         rc = qeth_l2_vnicc_set_timeout(card, timeout);
 360         mutex_unlock(&card->conf_mutex);
 361         return rc ? rc : count;
 362 }
 363 
 364 /* get current setting of characteristic */
 365 static ssize_t qeth_vnicc_char_show(struct device *dev,
 366                                     struct device_attribute *attr, char *buf)
 367 {
 368         struct qeth_card *card = dev_get_drvdata(dev);
 369         bool state;
 370         u32 vnicc;
 371         int rc;
 372 
 373         if (!card)
 374                 return -EINVAL;
 375 
 376         vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
 377         rc = qeth_l2_vnicc_get_state(card, vnicc, &state);
 378 
 379         if (rc == -EBUSY)
 380                 return sprintf(buf, "n/a (BridgePort)\n");
 381         if (rc == -EOPNOTSUPP)
 382                 return sprintf(buf, "n/a\n");
 383         return rc ? rc : sprintf(buf, "%d\n", state);
 384 }
 385 
 386 /* change setting of characteristic */
 387 static ssize_t qeth_vnicc_char_store(struct device *dev,
 388                                      struct device_attribute *attr,
 389                                      const char *buf, size_t count)
 390 {
 391         struct qeth_card *card = dev_get_drvdata(dev);
 392         bool state;
 393         u32 vnicc;
 394         int rc;
 395 
 396         if (!card)
 397                 return -EINVAL;
 398 
 399         if (kstrtobool(buf, &state))
 400                 return -EINVAL;
 401 
 402         vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
 403         mutex_lock(&card->conf_mutex);
 404         rc = qeth_l2_vnicc_set_state(card, vnicc, state);
 405         mutex_unlock(&card->conf_mutex);
 406 
 407         return rc ? rc : count;
 408 }
 409 
 410 static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
 411 static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
 412                    qeth_vnicc_char_store);
 413 static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
 414 static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
 415                    qeth_vnicc_timeout_store);
 416 static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
 417                    qeth_vnicc_char_store);
 418 static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
 419                    qeth_vnicc_char_store);
 420 static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
 421                    qeth_vnicc_char_store);
 422 static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
 423 
 424 static struct attribute *qeth_l2_vnicc_attrs[] = {
 425         &dev_attr_flooding.attr,
 426         &dev_attr_mcast_flooding.attr,
 427         &dev_attr_learning.attr,
 428         &dev_attr_learning_timeout.attr,
 429         &dev_attr_takeover_setvmac.attr,
 430         &dev_attr_takeover_learning.attr,
 431         &dev_attr_bridge_invisible.attr,
 432         &dev_attr_rx_bcast.attr,
 433         NULL,
 434 };
 435 
 436 static struct attribute_group qeth_l2_vnicc_attr_group = {
 437         .attrs = qeth_l2_vnicc_attrs,
 438         .name = "vnicc",
 439 };
 440 
 441 static const struct attribute_group *qeth_l2_only_attr_groups[] = {
 442         &qeth_l2_bridgeport_attr_group,
 443         &qeth_l2_vnicc_attr_group,
 444         NULL,
 445 };
 446 
 447 int qeth_l2_create_device_attributes(struct device *dev)
 448 {
 449         return sysfs_create_groups(&dev->kobj, qeth_l2_only_attr_groups);
 450 }
 451 
 452 void qeth_l2_remove_device_attributes(struct device *dev)
 453 {
 454         sysfs_remove_groups(&dev->kobj, qeth_l2_only_attr_groups);
 455 }
 456 
 457 const struct attribute_group *qeth_l2_attr_groups[] = {
 458         &qeth_device_attr_group,
 459         &qeth_device_blkt_group,
 460         /* l2 specific, see qeth_l2_only_attr_groups: */
 461         &qeth_l2_bridgeport_attr_group,
 462         &qeth_l2_vnicc_attr_group,
 463         NULL,
 464 };

/* [<][>][^][v][top][bottom][index][help] */