struct ncsi_channel_mode    modes[NCSI_MODE_MAX];
        struct ncsi_channel_filter  *filters[NCSI_FILTER_MAX];
        struct ncsi_channel_stats   stats;
-       struct timer_list           timer;      /* Link monitor timer  */
-       bool                        enabled;    /* Timer is enabled    */
-       unsigned int                timeout;    /* Times of timeout    */
+       struct {
+               struct timer_list   timer;
+               bool                enabled;
+               unsigned int        state;
+#define NCSI_CHANNEL_MONITOR_START     0
+#define NCSI_CHANNEL_MONITOR_RETRY     1
+#define NCSI_CHANNEL_MONITOR_WAIT      2
+#define NCSI_CHANNEL_MONITOR_WAIT_MAX  5
+       } monitor;
        struct list_head            node;
        struct list_head            link;
 };
 
        struct ncsi_dev_priv *ndp = np->ndp;
        struct ncsi_cmd_arg nca;
        bool enabled, chained;
-       unsigned int timeout;
+       unsigned int monitor_state;
        unsigned long flags;
        int state, ret;
 
        spin_lock_irqsave(&nc->lock, flags);
        state = nc->state;
        chained = !list_empty(&nc->link);
-       timeout = nc->timeout;
-       enabled = nc->enabled;
+       enabled = nc->monitor.enabled;
+       monitor_state = nc->monitor.state;
        spin_unlock_irqrestore(&nc->lock, flags);
 
        if (!enabled || chained)
            state != NCSI_CHANNEL_ACTIVE)
                return;
 
-       if (!(timeout % 2)) {
+       switch (monitor_state) {
+       case NCSI_CHANNEL_MONITOR_START:
+       case NCSI_CHANNEL_MONITOR_RETRY:
                nca.ndp = ndp;
                nca.package = np->id;
                nca.channel = nc->id;
                                   ret);
                        return;
                }
-       }
 
-       if (timeout + 1 >= 3) {
+               break;
+       case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX:
+               break;
+       default:
                if (!(ndp->flags & NCSI_DEV_HWA) &&
-                   state == NCSI_CHANNEL_ACTIVE)
+                   state == NCSI_CHANNEL_ACTIVE) {
                        ncsi_report_link(ndp, true);
+                       ndp->flags |= NCSI_DEV_RESHUFFLE;
+               }
 
                spin_lock_irqsave(&nc->lock, flags);
                nc->state = NCSI_CHANNEL_INVISIBLE;
        }
 
        spin_lock_irqsave(&nc->lock, flags);
-       nc->timeout = timeout + 1;
-       nc->enabled = true;
+       nc->monitor.state++;
        spin_unlock_irqrestore(&nc->lock, flags);
-       mod_timer(&nc->timer, jiffies + HZ * (1 << (nc->timeout / 2)));
+       mod_timer(&nc->monitor.timer, jiffies + HZ);
 }
 
 void ncsi_start_channel_monitor(struct ncsi_channel *nc)
        unsigned long flags;
 
        spin_lock_irqsave(&nc->lock, flags);
-       WARN_ON_ONCE(nc->enabled);
-       nc->timeout = 0;
-       nc->enabled = true;
+       WARN_ON_ONCE(nc->monitor.enabled);
+       nc->monitor.enabled = true;
+       nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
        spin_unlock_irqrestore(&nc->lock, flags);
 
-       mod_timer(&nc->timer, jiffies + HZ * (1 << (nc->timeout / 2)));
+       mod_timer(&nc->monitor.timer, jiffies + HZ);
 }
 
 void ncsi_stop_channel_monitor(struct ncsi_channel *nc)
        unsigned long flags;
 
        spin_lock_irqsave(&nc->lock, flags);
-       if (!nc->enabled) {
+       if (!nc->monitor.enabled) {
                spin_unlock_irqrestore(&nc->lock, flags);
                return;
        }
-       nc->enabled = false;
+       nc->monitor.enabled = false;
        spin_unlock_irqrestore(&nc->lock, flags);
 
-       del_timer_sync(&nc->timer);
+       del_timer_sync(&nc->monitor.timer);
 }
 
 struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
        nc->id = id;
        nc->package = np;
        nc->state = NCSI_CHANNEL_INACTIVE;
-       nc->enabled = false;
-       setup_timer(&nc->timer, ncsi_channel_monitor, (unsigned long)nc);
+       nc->monitor.enabled = false;
+       setup_timer(&nc->monitor.timer,
+                   ncsi_channel_monitor, (unsigned long)nc);
        spin_lock_init(&nc->lock);
        INIT_LIST_HEAD(&nc->link);
        for (index = 0; index < NCSI_CAP_MAX; index++)