qed: Align local and global PTT to propagate through the APIs.
authorRahul Verma <Rahul.Verma@cavium.com>
Tue, 16 Oct 2018 10:59:18 +0000 (03:59 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 1 Dec 2019 08:13:27 +0000 (09:13 +0100)
[ Upstream commit 706d08913d1f68610c32b4a001026aa989878dd9 ]

    Align the use of local PTT to propagate through the qed_mcp* API's.
    Global ptt should not be used.

    Register access should be done through layers. Register address is
    mapped into a PTT, PF translation table. Several interface functions
    require a PTT to direct read/write into register. There is a pool of
    PTT maintained, and several PTT are used simultaneously to access
    device registers in different flows. Same PTT should not be used in
    flows that can run concurrently.
    To avoid running out of PTT resources, too many PTT should not be
    acquired without releasing them. Every PF has a global PTT, which is
    used throughout the life of PF, in most important flows for register
    access. Generic functions acquire the PTT locally and release after
    the use. This patch aligns the use of Global PTT and Local PTT
    accordingly.

Signed-off-by: Rahul Verma <rahul.verma@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/qlogic/qed/qed.h
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_mcp.h
drivers/net/ethernet/qlogic/qed/qed_vf.c

index 91003bc6f00bd8599d3908811956fc5459e902ae..6c4714a8b54ced6d228acec07aca58f9499f95e2 100644 (file)
@@ -829,7 +829,7 @@ u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf);
 /* Prototypes */
 int qed_fill_dev_info(struct qed_dev *cdev,
                      struct qed_dev_info *dev_info);
-void qed_link_update(struct qed_hwfn *hwfn);
+void qed_link_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt);
 u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
                   u32 input_len, u8 *input_buf,
                   u32 max_size, u8 *unzip_buf);
index 557332f1f886c0e024e8b777bb725841e789e105..52e747fd9c8396616d11700193390ea118fe18c7 100644 (file)
@@ -1389,6 +1389,7 @@ static int qed_get_link_data(struct qed_hwfn *hwfn,
 }
 
 static void qed_fill_link(struct qed_hwfn *hwfn,
+                         struct qed_ptt *ptt,
                          struct qed_link_output *if_link)
 {
        struct qed_mcp_link_params params;
@@ -1469,7 +1470,7 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
 
        /* TODO - fill duplex properly */
        if_link->duplex = DUPLEX_FULL;
-       qed_mcp_get_media_type(hwfn->cdev, &media_type);
+       qed_mcp_get_media_type(hwfn, ptt, &media_type);
        if_link->port = qed_get_port_type(media_type);
 
        if_link->autoneg = params.speed.autoneg;
@@ -1525,21 +1526,34 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
 static void qed_get_current_link(struct qed_dev *cdev,
                                 struct qed_link_output *if_link)
 {
+       struct qed_hwfn *hwfn;
+       struct qed_ptt *ptt;
        int i;
 
-       qed_fill_link(&cdev->hwfns[0], if_link);
+       hwfn = &cdev->hwfns[0];
+       if (IS_PF(cdev)) {
+               ptt = qed_ptt_acquire(hwfn);
+               if (ptt) {
+                       qed_fill_link(hwfn, ptt, if_link);
+                       qed_ptt_release(hwfn, ptt);
+               } else {
+                       DP_NOTICE(hwfn, "Failed to fill link; No PTT\n");
+               }
+       } else {
+               qed_fill_link(hwfn, NULL, if_link);
+       }
 
        for_each_hwfn(cdev, i)
                qed_inform_vf_link_state(&cdev->hwfns[i]);
 }
 
-void qed_link_update(struct qed_hwfn *hwfn)
+void qed_link_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt)
 {
        void *cookie = hwfn->cdev->ops_cookie;
        struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common;
        struct qed_link_output if_link;
 
-       qed_fill_link(hwfn, &if_link);
+       qed_fill_link(hwfn, ptt, &if_link);
        qed_inform_vf_link_state(hwfn);
 
        if (IS_LEAD_HWFN(hwfn) && cookie)
index 7938abe9a30106450245ff94f8a28a155dcac54f..ef17ca09d30389534a166752930e2389f75b4279 100644 (file)
@@ -1352,7 +1352,7 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
        if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE)
                qed_mcp_read_eee_config(p_hwfn, p_ptt, p_link);
 
-       qed_link_update(p_hwfn);
+       qed_link_update(p_hwfn, p_ptt);
 out:
        spin_unlock_bh(&p_hwfn->mcp_info->link_lock);
 }
@@ -1722,12 +1722,10 @@ int qed_mcp_get_mbi_ver(struct qed_hwfn *p_hwfn,
        return 0;
 }
 
-int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
+int qed_mcp_get_media_type(struct qed_hwfn *p_hwfn,
+                          struct qed_ptt *p_ptt, u32 *p_media_type)
 {
-       struct qed_hwfn *p_hwfn = &cdev->hwfns[0];
-       struct qed_ptt  *p_ptt;
-
-       if (IS_VF(cdev))
+       if (IS_VF(p_hwfn->cdev))
                return -EINVAL;
 
        if (!qed_mcp_is_init(p_hwfn)) {
@@ -1735,16 +1733,15 @@ int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
                return -EBUSY;
        }
 
-       *p_media_type = MEDIA_UNSPECIFIED;
-
-       p_ptt = qed_ptt_acquire(p_hwfn);
-       if (!p_ptt)
-               return -EBUSY;
-
-       *p_media_type = qed_rd(p_hwfn, p_ptt, p_hwfn->mcp_info->port_addr +
-                              offsetof(struct public_port, media_type));
+       if (!p_ptt) {
+               *p_media_type = MEDIA_UNSPECIFIED;
+               return -EINVAL;
+       }
 
-       qed_ptt_release(p_hwfn, p_ptt);
+       *p_media_type = qed_rd(p_hwfn, p_ptt,
+                              p_hwfn->mcp_info->port_addr +
+                              offsetof(struct public_port,
+                                       media_type));
 
        return 0;
 }
index f1fe5e3427ea54f55831563e2a89e4aeea7ad2aa..8fcdb2c3e5dba4a38b0c6b4cde6115cc8be14f93 100644 (file)
@@ -284,14 +284,15 @@ int qed_mcp_get_mbi_ver(struct qed_hwfn *p_hwfn,
  * @brief Get media type value of the port.
  *
  * @param cdev      - qed dev pointer
+ * @param p_ptt
  * @param mfw_ver    - media type value
  *
  * @return int -
  *      0 - Operation was successul.
  *      -EBUSY - Operation failed
  */
-int qed_mcp_get_media_type(struct qed_dev      *cdev,
-                          u32                  *media_type);
+int qed_mcp_get_media_type(struct qed_hwfn *p_hwfn,
+                          struct qed_ptt *p_ptt, u32 *media_type);
 
 /**
  * @brief General function for sending commands to the MCP
index 3220086f99dea873c271c228e10ae4b19e7f7508..a2a9921b467b18ce63b7b57be4cd821dc8e3c27e 100644 (file)
@@ -1669,7 +1669,7 @@ static void qed_handle_bulletin_change(struct qed_hwfn *hwfn)
        ops->ports_update(cookie, vxlan_port, geneve_port);
 
        /* Always update link configuration according to bulletin */
-       qed_link_update(hwfn);
+       qed_link_update(hwfn, NULL);
 }
 
 void qed_iov_vf_task(struct work_struct *work)