cxgb4: Decode link down reason code obtained from firmware
authorHariprasad Shenai <hariprasad@chelsio.com>
Tue, 26 Apr 2016 14:40:29 +0000 (20:10 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 26 Apr 2016 17:23:58 +0000 (13:23 -0400)
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h

index 911fe11d32c6816a4e4c8d3ae4522af3713c2805..6af5242e6d214b110e29c8922bcb0edfcd59258d 100644 (file)
@@ -396,6 +396,7 @@ struct link_config {
        unsigned char  fc;               /* actual link flow control */
        unsigned char  autoneg;          /* autonegotiating? */
        unsigned char  link_ok;          /* link up? */
+       unsigned char  link_down_rc;     /* link down reason */
 };
 
 #define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16)
index cf3efbf4a37a066eccdae120c183dc0750ff1328..7907d85efa4ca934189852d88257efaed96b7d95 100644 (file)
@@ -7102,6 +7102,32 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
        return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
 
+/**
+ *     t4_link_down_rc_str - return a string for a Link Down Reason Code
+ *     @adap: the adapter
+ *     @link_down_rc: Link Down Reason Code
+ *
+ *     Returns a string representation of the Link Down Reason Code.
+ */
+static const char *t4_link_down_rc_str(unsigned char link_down_rc)
+{
+       static const char * const reason[] = {
+               "Link Down",
+               "Remote Fault",
+               "Auto-negotiation Failure",
+               "Reserved",
+               "Insufficient Airflow",
+               "Unable To Determine Reason",
+               "No RX Signal Detected",
+               "Reserved",
+       };
+
+       if (link_down_rc >= ARRAY_SIZE(reason))
+               return "Bad Reason Code";
+
+       return reason[link_down_rc];
+}
+
 /**
  *     t4_handle_get_port_info - process a FW reply message
  *     @pi: the port info
@@ -7142,6 +7168,14 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
        }
        if (link_ok != lc->link_ok || speed != lc->speed ||
            fc != lc->fc) {     /* something changed */
+               if (!link_ok && lc->link_ok) {
+                       unsigned char rc = FW_PORT_CMD_LINKDNRC_G(stat);
+
+                       lc->link_down_rc = rc;
+                       dev_warn(adap->pdev_dev,
+                                "Port %d link down, reason: %s\n",
+                                pi->port_id, t4_link_down_rc_str(rc));
+               }
                lc->link_ok = link_ok;
                lc->speed = speed;
                lc->fc = fc;
index 7ad6d4e75b2aa73eae5e8bfe29dda0f61d272a2a..392d6644fdd8d2e633e775654d8affc00ee3446e 100644 (file)
@@ -2510,6 +2510,11 @@ struct fw_port_cmd {
 #define FW_PORT_CMD_PTYPE_G(x) \
        (((x) >> FW_PORT_CMD_PTYPE_S) & FW_PORT_CMD_PTYPE_M)
 
+#define FW_PORT_CMD_LINKDNRC_S         5
+#define FW_PORT_CMD_LINKDNRC_M         0x7
+#define FW_PORT_CMD_LINKDNRC_G(x)      \
+       (((x) >> FW_PORT_CMD_LINKDNRC_S) & FW_PORT_CMD_LINKDNRC_M)
+
 #define FW_PORT_CMD_MODTYPE_S          0
 #define FW_PORT_CMD_MODTYPE_M          0x1f
 #define FW_PORT_CMD_MODTYPE_V(x)       ((x) << FW_PORT_CMD_MODTYPE_S)