qlge: Add firmware info to ethtool get regs.
authorRon Mercer <ron.mercer@qlogic.com>
Wed, 10 Nov 2010 09:29:45 +0000 (09:29 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 10 Nov 2010 20:07:08 +0000 (12:07 -0800)
By default we add firmware information to ethtool get regs.
Optionally firmware info can instead be sent to log.

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_dbg.c
drivers/net/qlge/qlge_ethtool.c
drivers/net/qlge/qlge_mpi.c

index 22821398fc63765054eff056ab2529beedfb30fc..b1e815127cde39dd1139a8453311efdb75f0e3cb 100644 (file)
@@ -2221,6 +2221,7 @@ int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data);
 int ql_unpause_mpi_risc(struct ql_adapter *qdev);
 int ql_pause_mpi_risc(struct ql_adapter *qdev);
 int ql_hard_reset_mpi_risc(struct ql_adapter *qdev);
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev);
 int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf,
                u32 ram_addr, int word_count);
 int ql_core_dump(struct ql_adapter *qdev,
@@ -2236,6 +2237,7 @@ int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
 int ql_mb_get_port_cfg(struct ql_adapter *qdev);
 int ql_mb_set_port_cfg(struct ql_adapter *qdev);
 int ql_wait_fifo_empty(struct ql_adapter *qdev);
+void ql_get_dump(struct ql_adapter *qdev, void *buff);
 void ql_gen_reg_dump(struct ql_adapter *qdev,
                        struct ql_reg_dump *mpi_coredump);
 netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev);
index 4747492935ef8bf190cc575fe7146e3072417623..fca804f36d61a2e6f2d79140945adee3732a2ec1 100644 (file)
@@ -1317,9 +1317,28 @@ void ql_gen_reg_dump(struct ql_adapter *qdev,
        status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
        if (status)
                return;
+}
+
+void ql_get_dump(struct ql_adapter *qdev, void *buff)
+{
+       /*
+        * If the dump has already been taken and is stored
+        * in our internal buffer and if force dump is set then
+        * just start the spool to dump it to the log file
+        * and also, take a snapshot of the general regs to
+        * to the user's buffer or else take complete dump
+        * to the user's buffer if force is not set.
+        */
 
-       if (test_bit(QL_FRC_COREDUMP, &qdev->flags))
+       if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) {
+               if (!ql_core_dump(qdev, buff))
+                       ql_soft_reset_mpi_risc(qdev);
+               else
+                       netif_err(qdev, drv, qdev->ndev, "coredump failed!\n");
+       } else {
+               ql_gen_reg_dump(qdev, buff);
                ql_get_core_dump(qdev);
+       }
 }
 
 /* Coredump to messages log file using separate worker thread */
index 4892d64f4e054b2a630a13f2249f6ca1be7f83cb..8149cc9de4ca05a0bfaca39f396359eae1eac070 100644 (file)
@@ -375,7 +375,10 @@ static void ql_get_drvinfo(struct net_device *ndev,
        strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32);
        drvinfo->n_stats = 0;
        drvinfo->testinfo_len = 0;
-       drvinfo->regdump_len = 0;
+       if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+               drvinfo->regdump_len = sizeof(struct ql_mpi_coredump);
+       else
+               drvinfo->regdump_len = sizeof(struct ql_reg_dump);
        drvinfo->eedump_len = 0;
 }
 
@@ -547,7 +550,12 @@ static void ql_self_test(struct net_device *ndev,
 
 static int ql_get_regs_len(struct net_device *ndev)
 {
-       return sizeof(struct ql_reg_dump);
+       struct ql_adapter *qdev = netdev_priv(ndev);
+
+       if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+               return sizeof(struct ql_mpi_coredump);
+       else
+               return sizeof(struct ql_reg_dump);
 }
 
 static void ql_get_regs(struct net_device *ndev,
@@ -555,7 +563,12 @@ static void ql_get_regs(struct net_device *ndev,
 {
        struct ql_adapter *qdev = netdev_priv(ndev);
 
-       ql_gen_reg_dump(qdev, p);
+       ql_get_dump(qdev, p);
+       qdev->core_is_dumped = 0;
+       if (!test_bit(QL_FRC_COREDUMP, &qdev->flags))
+               regs->len = sizeof(struct ql_mpi_coredump);
+       else
+               regs->len = sizeof(struct ql_reg_dump);
 }
 
 static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
index 0e7c7c7ee1647006baf561ffd90308290fbd2399..100a462cc9163e578ed48c5ce505c69a41cbbea6 100644 (file)
@@ -87,7 +87,7 @@ exit:
        return status;
 }
 
-static int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
 {
        int status;
        status = ql_write_mpi_reg(qdev, 0x00001010, 1);