Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  qeth_l2_sys.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 *    Copyright IBM Corp. 2013
 *    Author(s): Eugene Crosser <eugene.crosser@ru.ibm.com>
 */


#include <linux/slab.h>
#include <asm/ebcdic.h>
#include "qeth_core.h"
#include "qeth_l2.h"

static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
    struct device_attribute *attr, char *buf,
    int show_state)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE;
 int rc = 0;
 char *word;

 if (!qeth_bridgeport_allowed(card))
  return sysfs_emit(buf, "n/a (VNIC characteristics)\n");

 mutex_lock(&card->sbp_lock);
 if (qeth_card_hw_is_reachable(card) &&
     card->options.sbp.supported_funcs)
  rc = qeth_bridgeport_query_ports(card,
   &card->options.sbp.role, &state);
 if (!rc) {
  if (show_state)
   switch (state) {
   case QETH_SBP_STATE_INACTIVE:
    word = "inactive"break;
   case QETH_SBP_STATE_STANDBY:
    word = "standby"break;
   case QETH_SBP_STATE_ACTIVE:
    word = "active"break;
   default:
    rc = -EIO;
   }
  else
   switch (card->options.sbp.role) {
   case QETH_SBP_ROLE_NONE:
    word = "none"break;
   case QETH_SBP_ROLE_PRIMARY:
    word = "primary"break;
   case QETH_SBP_ROLE_SECONDARY:
    word = "secondary"break;
   default:
    rc = -EIO;
   }
  if (rc)
   QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
    card->options.sbp.role, state);
  else
   rc = sysfs_emit(buf, "%s\n", word);
 }
 mutex_unlock(&card->sbp_lock);

 return rc;
}

static ssize_t qeth_bridge_port_role_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);

 if (!qeth_bridgeport_allowed(card))
  return sysfs_emit(buf, "n/a (VNIC characteristics)\n");

 return qeth_bridge_port_role_state_show(dev, attr, buf, 0);
}

static ssize_t qeth_bridge_port_role_store(struct device *dev,
  struct device_attribute *attr, const char *buf, size_t count)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 int rc = 0;
 enum qeth_sbp_roles role;

 if (sysfs_streq(buf, "primary"))
  role = QETH_SBP_ROLE_PRIMARY;
 else if (sysfs_streq(buf, "secondary"))
  role = QETH_SBP_ROLE_SECONDARY;
 else if (sysfs_streq(buf, "none"))
  role = QETH_SBP_ROLE_NONE;
 else
  return -EINVAL;

 mutex_lock(&card->conf_mutex);
 mutex_lock(&card->sbp_lock);

 if (!qeth_bridgeport_allowed(card))
  rc = -EBUSY;
 else if (card->options.sbp.reflect_promisc)
  /* Forbid direct manipulation */
  rc = -EPERM;
 else if (qeth_card_hw_is_reachable(card)) {
  rc = qeth_bridgeport_setrole(card, role);
  if (!rc)
   card->options.sbp.role = role;
 } else
  card->options.sbp.role = role;

 mutex_unlock(&card->sbp_lock);
 mutex_unlock(&card->conf_mutex);

 return rc ? rc : count;
}

static DEVICE_ATTR(bridge_role, 0644, qeth_bridge_port_role_show,
     qeth_bridge_port_role_store);

static ssize_t qeth_bridge_port_state_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);

 if (!qeth_bridgeport_allowed(card))
  return sysfs_emit(buf, "n/a (VNIC characteristics)\n");

 return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
}

static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
     NULL);

static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 int enabled;

 if (!qeth_bridgeport_allowed(card))
  return sysfs_emit(buf, "n/a (VNIC characteristics)\n");

 enabled = card->options.sbp.hostnotification;

 return sysfs_emit(buf, "%d\n", enabled);
}

static ssize_t qeth_bridgeport_hostnotification_store(struct device *dev,
  struct device_attribute *attr, const char *buf, size_t count)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 bool enable;
 int rc;

 rc = kstrtobool(buf, &enable);
 if (rc)
  return rc;

 mutex_lock(&card->conf_mutex);
 mutex_lock(&card->sbp_lock);

 if (!qeth_bridgeport_allowed(card))
  rc = -EBUSY;
 else if (qeth_card_hw_is_reachable(card)) {
  rc = qeth_bridgeport_an_set(card, enable);
  /* sbp_lock ensures ordering vs notifications-stopped events */
  if (!rc)
   card->options.sbp.hostnotification = enable;
 } else
  card->options.sbp.hostnotification = enable;

 mutex_unlock(&card->sbp_lock);
 mutex_unlock(&card->conf_mutex);

 return rc ? rc : count;
}

static DEVICE_ATTR(bridge_hostnotify, 0644,
   qeth_bridgeport_hostnotification_show,
   qeth_bridgeport_hostnotification_store);

static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 char *state;

 if (!qeth_bridgeport_allowed(card))
  return sysfs_emit(buf, "n/a (VNIC characteristics)\n");

 if (card->options.sbp.reflect_promisc) {
  if (card->options.sbp.reflect_promisc_primary)
   state = "primary";
  else
   state = "secondary";
 } else
  state = "none";

 return sysfs_emit(buf, "%s\n", state);
}

static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
  struct device_attribute *attr, const char *buf, size_t count)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 int enable, primary;
 int rc = 0;

 if (sysfs_streq(buf, "none")) {
  enable = 0;
  primary = 0;
 } else if (sysfs_streq(buf, "primary")) {
  enable = 1;
  primary = 1;
 } else if (sysfs_streq(buf, "secondary")) {
  enable = 1;
  primary = 0;
 } else
  return -EINVAL;

 mutex_lock(&card->conf_mutex);
 mutex_lock(&card->sbp_lock);

 if (!qeth_bridgeport_allowed(card))
  rc = -EBUSY;
 else if (card->options.sbp.role != QETH_SBP_ROLE_NONE)
  rc = -EPERM;
 else {
  card->options.sbp.reflect_promisc = enable;
  card->options.sbp.reflect_promisc_primary = primary;
  rc = 0;
 }

 mutex_unlock(&card->sbp_lock);
 mutex_unlock(&card->conf_mutex);

 return rc ? rc : count;
}

static DEVICE_ATTR(bridge_reflect_promisc, 0644,
   qeth_bridgeport_reflect_show,
   qeth_bridgeport_reflect_store);

static struct attribute *qeth_l2_bridgeport_attrs[] = {
 &dev_attr_bridge_role.attr,
 &dev_attr_bridge_state.attr,
 &dev_attr_bridge_hostnotify.attr,
 &dev_attr_bridge_reflect_promisc.attr,
 NULL,
};

static struct attribute_group qeth_l2_bridgeport_attr_group = {
 .attrs = qeth_l2_bridgeport_attrs,
};

/* VNIC CHARS support */

/* convert sysfs attr name to VNIC characteristic */
static u32 qeth_l2_vnicc_sysfs_attr_to_char(const char *attr_name)
{
 if (sysfs_streq(attr_name, "flooding"))
  return QETH_VNICC_FLOODING;
 else if (sysfs_streq(attr_name, "mcast_flooding"))
  return QETH_VNICC_MCAST_FLOODING;
 else if (sysfs_streq(attr_name, "learning"))
  return QETH_VNICC_LEARNING;
 else if (sysfs_streq(attr_name, "takeover_setvmac"))
  return QETH_VNICC_TAKEOVER_SETVMAC;
 else if (sysfs_streq(attr_name, "takeover_learning"))
  return QETH_VNICC_TAKEOVER_LEARNING;
 else if (sysfs_streq(attr_name, "bridge_invisible"))
  return QETH_VNICC_BRIDGE_INVISIBLE;
 else if (sysfs_streq(attr_name, "rx_bcast"))
  return QETH_VNICC_RX_BCAST;

 return 0;
}

/* get current timeout setting */
static ssize_t qeth_vnicc_timeout_show(struct device *dev,
           struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 u32 timeout;
 int rc;

 rc = qeth_l2_vnicc_get_timeout(card, &timeout);
 if (rc == -EBUSY)
  return sysfs_emit(buf, "n/a (BridgePort)\n");
 if (rc == -EOPNOTSUPP)
  return sysfs_emit(buf, "n/a\n");
 return rc ? rc : sysfs_emit(buf, "%d\n", timeout);
}

/* change timeout setting */
static ssize_t qeth_vnicc_timeout_store(struct device *dev,
     struct device_attribute *attr,
     const char *buf, size_t count)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 u32 timeout;
 int rc;

 rc = kstrtou32(buf, 10, &timeout);
 if (rc)
  return rc;

 mutex_lock(&card->conf_mutex);
 rc = qeth_l2_vnicc_set_timeout(card, timeout);
 mutex_unlock(&card->conf_mutex);
 return rc ? rc : count;
}

/* get current setting of characteristic */
static ssize_t qeth_vnicc_char_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 bool state;
 u32 vnicc;
 int rc;

 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
 rc = qeth_l2_vnicc_get_state(card, vnicc, &state);

 if (rc == -EBUSY)
  return sysfs_emit(buf, "n/a (BridgePort)\n");
 if (rc == -EOPNOTSUPP)
  return sysfs_emit(buf, "n/a\n");
 return rc ? rc : sysfs_emit(buf, "%d\n", state);
}

/* change setting of characteristic */
static ssize_t qeth_vnicc_char_store(struct device *dev,
         struct device_attribute *attr,
         const char *buf, size_t count)
{
 struct qeth_card *card = dev_get_drvdata(dev);
 bool state;
 u32 vnicc;
 int rc;

 if (kstrtobool(buf, &state))
  return -EINVAL;

 vnicc = qeth_l2_vnicc_sysfs_attr_to_char(attr->attr.name);
 mutex_lock(&card->conf_mutex);
 rc = qeth_l2_vnicc_set_state(card, vnicc, state);
 mutex_unlock(&card->conf_mutex);

 return rc ? rc : count;
}

static DEVICE_ATTR(flooding, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
static DEVICE_ATTR(mcast_flooding, 0644, qeth_vnicc_char_show,
     qeth_vnicc_char_store);
static DEVICE_ATTR(learning, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);
static DEVICE_ATTR(learning_timeout, 0644, qeth_vnicc_timeout_show,
     qeth_vnicc_timeout_store);
static DEVICE_ATTR(takeover_setvmac, 0644, qeth_vnicc_char_show,
     qeth_vnicc_char_store);
static DEVICE_ATTR(takeover_learning, 0644, qeth_vnicc_char_show,
     qeth_vnicc_char_store);
static DEVICE_ATTR(bridge_invisible, 0644, qeth_vnicc_char_show,
     qeth_vnicc_char_store);
static DEVICE_ATTR(rx_bcast, 0644, qeth_vnicc_char_show, qeth_vnicc_char_store);

static struct attribute *qeth_l2_vnicc_attrs[] = {
 &dev_attr_flooding.attr,
 &dev_attr_mcast_flooding.attr,
 &dev_attr_learning.attr,
 &dev_attr_learning_timeout.attr,
 &dev_attr_takeover_setvmac.attr,
 &dev_attr_takeover_learning.attr,
 &dev_attr_bridge_invisible.attr,
 &dev_attr_rx_bcast.attr,
 NULL,
};

static struct attribute_group qeth_l2_vnicc_attr_group = {
 .attrs = qeth_l2_vnicc_attrs,
 .name = "vnicc",
};

const struct attribute_group *qeth_l2_attr_groups[] = {
 &qeth_l2_bridgeport_attr_group,
 &qeth_l2_vnicc_attr_group,
 NULL,
};

Messung V0.5
C=97 H=94 G=95

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge