net/ncsi: Don't mark configured channels inactive
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>
Fri, 16 Nov 2018 04:51:57 +0000 (15:51 +1100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 18 Nov 2018 05:09:49 +0000 (21:09 -0800)
The concepts of a channel being 'active' and it having link are slightly
muddled in the NCSI driver. Tweak this slightly so that
NCSI_CHANNEL_ACTIVE represents a channel that has been configured and
enabled, and NCSI_CHANNEL_INACTIVE represents a de-configured channel.
This distinction is important because a channel can be 'active' but have
its link down; in this case the channel may still need to be configured
so that it may receive AEN link-state-change packets.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ncsi/ncsi-aen.c
net/ncsi/ncsi-manage.c

index 65f47a648be3da67c7b5ed5dba3deb77e33f25e9..57f77e5d381a01c53e2d3529c43293a22494118d 100644 (file)
@@ -57,6 +57,7 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
        int state;
        unsigned long old_data, data;
        unsigned long flags;
+       bool had_link, has_link;
 
        /* Find the NCSI channel */
        ncsi_find_package_and_channel(ndp, h->common.channel, NULL, &nc);
@@ -73,6 +74,9 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
        ncm->data[2] = data;
        ncm->data[4] = ntohl(lsc->oem_status);
 
+       had_link = !!(old_data & 0x1);
+       has_link = !!(data & 0x1);
+
        netdev_dbg(ndp->ndev.dev, "NCSI: LSC AEN - channel %u state %s\n",
                   nc->id, data & 0x1 ? "up" : "down");
 
@@ -80,15 +84,16 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
        state = nc->state;
        spin_unlock_irqrestore(&nc->lock, flags);
 
-       if (!((old_data ^ data) & 0x1) || chained)
-               return 0;
-       if (!(state == NCSI_CHANNEL_INACTIVE && (data & 0x1)) &&
-           !(state == NCSI_CHANNEL_ACTIVE && !(data & 0x1)))
+       if (state == NCSI_CHANNEL_INACTIVE)
+               netdev_warn(ndp->ndev.dev,
+                           "NCSI: Inactive channel %u received AEN!\n",
+                           nc->id);
+
+       if ((had_link == has_link) || chained)
                return 0;
 
-       if (state == NCSI_CHANNEL_ACTIVE)
+       if (had_link)
                ndp->flags |= NCSI_DEV_RESHUFFLE;
-
        ncsi_stop_channel_monitor(nc);
        spin_lock_irqsave(&ndp->lock, flags);
        list_add_tail_rcu(&nc->link, &ndp->channel_queue);
index b8b4e765a04c22308c9727f87d3cead98ca6b8d5..b9de5b78c4e981d9cd6e0f8de44ab01556f21ca4 100644 (file)
@@ -916,12 +916,11 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
                        break;
                }
 
+               nc->state = NCSI_CHANNEL_ACTIVE;
                if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
                        hot_nc = nc;
-                       nc->state = NCSI_CHANNEL_ACTIVE;
                } else {
                        hot_nc = NULL;
-                       nc->state = NCSI_CHANNEL_INACTIVE;
                        netdev_dbg(ndp->ndev.dev,
                                   "NCSI: channel %u link down after config\n",
                                   nc->id);