s390/qeth: fix promiscuous mode after reset
authorJulian Wiedmann <jwi@linux.ibm.com>
Wed, 18 Dec 2019 15:32:27 +0000 (16:32 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 21 Dec 2019 05:00:27 +0000 (21:00 -0800)
When managing the promiscuous mode during an RX modeset, qeth caches the
current HW state to avoid repeated programming of the same state on each
modeset.

But while tearing down a device, we forget to clear the cached state. So
when the device is later set online again, the initial RX modeset
doesn't program the promiscuous mode since we believe it is already
enabled.
Fix this by clearing the cached state in the tear-down path.

Note that for the SBP variant of promiscuous mode, this accidentally
works right now because we unconditionally restore the SBP role while
re-initializing.

Fixes: 4a71df50047f ("qeth: new qeth device driver")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l2_sys.c
drivers/s390/net/qeth_l3_main.c

index 9086bc04fa6bd6eb5ccf1e9b62229b6716f7a888..8c95e6019bacd3f036ba25ecb26453c04af110de 100644 (file)
@@ -295,6 +295,7 @@ static void qeth_l2_stop_card(struct qeth_card *card)
 
        flush_workqueue(card->event_wq);
        card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
+       card->info.promisc_mode = 0;
 }
 
 static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
index f70c7aac2dcc3aeda624fc8851a70cbb525c6029..7fa325cf6f8d36323c43f6dacb72445830848a17 100644 (file)
@@ -262,7 +262,8 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
                return;
 
        mutex_lock(&card->sbp_lock);
-       if (card->options.sbp.role != QETH_SBP_ROLE_NONE) {
+       if (!card->options.sbp.reflect_promisc &&
+           card->options.sbp.role != QETH_SBP_ROLE_NONE) {
                /* Conditional to avoid spurious error messages */
                qeth_bridgeport_setrole(card, card->options.sbp.role);
                /* Let the callback function refresh the stored role value. */
index 27126330a4b003bd4e83e01e6ac654d191df04b0..04e301de376f0957796100e6fbadc8a022c7ba80 100644 (file)
@@ -1314,6 +1314,7 @@ static void qeth_l3_stop_card(struct qeth_card *card)
        }
 
        flush_workqueue(card->event_wq);
+       card->info.promisc_mode = 0;
 }
 
 static void qeth_l3_set_promisc_mode(struct qeth_card *card)