qed: Add Light L2 support
[linux-2.6-microblaze.git] / drivers / net / ethernet / qlogic / qed / qed_main.c
index 54976cc..48cdf62 100644 (file)
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/qed/qed_if.h>
+#include <linux/qed/qed_ll2_if.h>
 
 #include "qed.h"
 #include "qed_sriov.h"
 #include "qed_sp.h"
 #include "qed_dev_api.h"
+#include "qed_ll2.h"
 #include "qed_mcp.h"
 #include "qed_hw.h"
 #include "qed_selftest.h"
@@ -588,6 +590,8 @@ static int qed_nic_stop(struct qed_dev *cdev)
                }
        }
 
+       qed_dbg_pf_exit(cdev);
+
        return rc;
 }
 
@@ -606,7 +610,16 @@ static int qed_nic_reset(struct qed_dev *cdev)
 
 static int qed_nic_setup(struct qed_dev *cdev)
 {
-       int rc;
+       int rc, i;
+
+       /* Determine if interface is going to require LL2 */
+       if (QED_LEADING_HWFN(cdev)->hw_info.personality != QED_PCI_ETH) {
+               for (i = 0; i < cdev->num_hwfns; i++) {
+                       struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
+
+                       p_hwfn->using_ll2 = true;
+               }
+       }
 
        rc = qed_resc_alloc(cdev);
        if (rc)
@@ -841,13 +854,13 @@ static int qed_slowpath_start(struct qed_dev *cdev,
        if (IS_PF(cdev)) {
                /* Allocate stream for unzipping */
                rc = qed_alloc_stream_mem(cdev);
-               if (rc) {
-                       DP_NOTICE(cdev, "Failed to allocate stream memory\n");
+               if (rc)
                        goto err2;
-               }
 
                /* First Dword used to diffrentiate between various sources */
                data = cdev->firmware->data + sizeof(u32);
+
+               qed_dbg_pf_init(cdev);
        }
 
        memset(&tunn_info, 0, sizeof(tunn_info));
@@ -871,6 +884,12 @@ static int qed_slowpath_start(struct qed_dev *cdev,
        DP_INFO(cdev,
                "HW initialization and function start completed successfully\n");
 
+       /* Allocate LL2 interface if needed */
+       if (QED_LEADING_HWFN(cdev)->using_ll2) {
+               rc = qed_ll2_alloc_if(cdev);
+               if (rc)
+                       goto err3;
+       }
        if (IS_PF(cdev)) {
                hwfn = QED_LEADING_HWFN(cdev);
                drv_version.version = (params->drv_major << 24) |
@@ -891,6 +910,8 @@ static int qed_slowpath_start(struct qed_dev *cdev,
 
        return 0;
 
+err3:
+       qed_hw_stop(cdev);
 err2:
        qed_hw_timers_stop_all(cdev);
        if (IS_PF(cdev))
@@ -913,6 +934,8 @@ static int qed_slowpath_stop(struct qed_dev *cdev)
        if (!cdev)
                return -ENODEV;
 
+       qed_ll2_dealloc_if(cdev);
+
        if (IS_PF(cdev)) {
                qed_free_stream_mem(cdev);
                if (IS_QED_ETH_IF(cdev))
@@ -1396,9 +1419,32 @@ const struct qed_common_ops qed_common_ops_pass = {
        .get_link = &qed_get_current_link,
        .drain = &qed_drain,
        .update_msglvl = &qed_init_dp,
+       .dbg_all_data = &qed_dbg_all_data,
+       .dbg_all_data_size = &qed_dbg_all_data_size,
        .chain_alloc = &qed_chain_alloc,
        .chain_free = &qed_chain_free,
        .get_coalesce = &qed_get_coalesce,
        .set_coalesce = &qed_set_coalesce,
        .set_led = &qed_set_led,
 };
+
+void qed_get_protocol_stats(struct qed_dev *cdev,
+                           enum qed_mcp_protocol_type type,
+                           union qed_mcp_protocol_stats *stats)
+{
+       struct qed_eth_stats eth_stats;
+
+       memset(stats, 0, sizeof(*stats));
+
+       switch (type) {
+       case QED_MCP_LAN_STATS:
+               qed_get_vport_stats(cdev, &eth_stats);
+               stats->lan_stats.ucast_rx_pkts = eth_stats.rx_ucast_pkts;
+               stats->lan_stats.ucast_tx_pkts = eth_stats.tx_ucast_pkts;
+               stats->lan_stats.fcs_err = -1;
+               break;
+       default:
+               DP_ERR(cdev, "Invalid protocol type = %d\n", type);
+               return;
+       }
+}