diff options
author | Eugene Crosser <Eugene.Crosser@ru.ibm.com> | 2015-05-18 15:27:55 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-18 19:14:17 +0300 |
commit | 0db587b065cb3d0417c4e84be851e787d207e8e0 (patch) | |
tree | 2d72c37c650e391963f0a5031e4501fd9666e0d6 /drivers/s390/net/qeth_l2_main.c | |
parent | d3c29a5c3fb81b9e2eef65c9edd3b43e7f7510f2 (diff) | |
download | linux-0db587b065cb3d0417c4e84be851e787d207e8e0.tar.xz |
qeth: IFF_PROMISC flag to BRIDGE PORT mode
OSA and HiperSocket devices do not support promiscuous mode proper,
but they support "BRIDGE PORT" mode that is functionally similar.
This update introduces sysfs attribute that, when set, makes the driver
try to "reflect" setting and resetting of the IFF_PROMISC flag on the
interface into setting and resetting PRIMARY or SECONDARY bridge port
role on the underlying OSA or HiperSocket device.
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Signed-off-by: Eugene Crosser <Eugene.Crosser@ru.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/qeth_l2_main.c')
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 1cdefaea866c..0ff926d4d63d 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -683,6 +683,39 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return rc ? -EINVAL : 0; } +static void qeth_promisc_to_bridge(struct qeth_card *card) +{ + struct net_device *dev = card->dev; + enum qeth_ipa_promisc_modes promisc_mode; + int role; + int rc; + + QETH_CARD_TEXT(card, 3, "pmisc2br"); + + if (!card->options.sbp.reflect_promisc) + return; + promisc_mode = (dev->flags & IFF_PROMISC) ? SET_PROMISC_MODE_ON + : SET_PROMISC_MODE_OFF; + if (promisc_mode == card->info.promisc_mode) + return; + + if (promisc_mode == SET_PROMISC_MODE_ON) { + if (card->options.sbp.reflect_promisc_primary) + role = QETH_SBP_ROLE_PRIMARY; + else + role = QETH_SBP_ROLE_SECONDARY; + } else + role = QETH_SBP_ROLE_NONE; + + rc = qeth_bridgeport_setrole(card, role); + QETH_DBF_TEXT_(SETUP, 2, "bpm%c%04x", + (promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc); + if (!rc) { + card->options.sbp.role = role; + card->info.promisc_mode = promisc_mode; + } +} + static void qeth_l2_set_multicast_list(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; @@ -704,9 +737,10 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) qeth_l2_add_mc(card, ha->addr, 1); spin_unlock_bh(&card->mclock); - if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) - return; - qeth_setadp_promisc_mode(card); + if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) + qeth_setadp_promisc_mode(card); + else + qeth_promisc_to_bridge(card); } static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |