qed: Add support for changing LED state
authorSudarsana Kalluru <Sudarsana.Kalluru@qlogic.com>
Mon, 30 Nov 2015 10:25:03 +0000 (12:25 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Dec 2015 21:02:40 +0000 (16:02 -0500)
Physical LEDs are being controlled by the management FW.
This adds the qed functionality required to request management FW to
change the LED configuration, as well as the necessary APIs for this
functionality to later be used by the protocol drivers.

Signed-off-by: Sudarsana Kalluru <Sudarsana.Kalluru@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_hsi.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
include/linux/qed/qed_if.h

index b2f8e854dfd1c4f858d00632a0ae3e827158d712..264e954675d1f390f1991b031e83779f6d7424b3 100644 (file)
@@ -3993,6 +3993,8 @@ struct public_drv_mb {
 #define DRV_MSG_CODE_PHY_CORE_WRITE             0x000e0000
 #define DRV_MSG_CODE_SET_VERSION                0x000f0000
 
+#define DRV_MSG_CODE_SET_LED_MODE               0x00200000
+
 #define DRV_MSG_SEQ_NUMBER_MASK                 0x0000ffff
 
        u32 drv_mb_param;
@@ -4044,6 +4046,10 @@ struct public_drv_mb {
 #define DRV_MB_PARAM_CFG_VF_MSIX_SB_NUM_SHIFT   8
 #define DRV_MB_PARAM_CFG_VF_MSIX_SB_NUM_MASK    0x0000FF00
 
+#define DRV_MB_PARAM_SET_LED_MODE_OPER          0x0
+#define DRV_MB_PARAM_SET_LED_MODE_ON            0x1
+#define DRV_MB_PARAM_SET_LED_MODE_OFF           0x2
+
        u32 fw_mb_header;
 #define FW_MSG_CODE_MASK                        0xffff0000
 #define FW_MSG_CODE_DRV_LOAD_ENGINE             0x10100000
index 947c7af72b25b32db163dc3ea47ca7d63db50490..6b02e113436016ca62728b82f16b9f3876d02f97 100644 (file)
@@ -1135,6 +1135,23 @@ static int qed_drain(struct qed_dev *cdev)
        return 0;
 }
 
+static int qed_set_led(struct qed_dev *cdev, enum qed_led_mode mode)
+{
+       struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
+       struct qed_ptt *ptt;
+       int status = 0;
+
+       ptt = qed_ptt_acquire(hwfn);
+       if (!ptt)
+               return -EAGAIN;
+
+       status = qed_mcp_set_led(hwfn, ptt, mode);
+
+       qed_ptt_release(hwfn, ptt);
+
+       return status;
+}
+
 const struct qed_common_ops qed_common_ops_pass = {
        .probe = &qed_probe,
        .remove = &qed_remove,
@@ -1155,6 +1172,7 @@ const struct qed_common_ops qed_common_ops_pass = {
        .update_msglvl = &qed_init_dp,
        .chain_alloc = &qed_chain_alloc,
        .chain_free = &qed_chain_free,
+       .set_led = &qed_set_led,
 };
 
 u32 qed_get_protocol_version(enum qed_protocol protocol)
index 20d048cdcb8821bf8d18b644be42afcb1146a2b8..ba1b1f1ef789b65381b47692c66d00a8556ba9be 100644 (file)
@@ -858,3 +858,30 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
 
        return 0;
 }
+
+int qed_mcp_set_led(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                   enum qed_led_mode mode)
+{
+       u32 resp = 0, param = 0, drv_mb_param;
+       int rc;
+
+       switch (mode) {
+       case QED_LED_MODE_ON:
+               drv_mb_param = DRV_MB_PARAM_SET_LED_MODE_ON;
+               break;
+       case QED_LED_MODE_OFF:
+               drv_mb_param = DRV_MB_PARAM_SET_LED_MODE_OFF;
+               break;
+       case QED_LED_MODE_RESTORE:
+               drv_mb_param = DRV_MB_PARAM_SET_LED_MODE_OPER;
+               break;
+       default:
+               DP_NOTICE(p_hwfn, "Invalid LED mode %d\n", mode);
+               return -EINVAL;
+       }
+
+       rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_LED_MODE,
+                        drv_mb_param, &resp, &param);
+
+       return rc;
+}
index dbaae586b4a728d3a3b50f76b288106875d00bff..506197d5c3dda19c6404bf8c382769f2ac64c26d 100644 (file)
@@ -224,6 +224,19 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
                         struct qed_ptt *p_ptt,
                         struct qed_mcp_drv_version *p_ver);
 
+/**
+ * @brief Set LED status
+ *
+ *  @param p_hwfn
+ *  @param p_ptt
+ *  @param mode - LED mode
+ *
+ * @return int - 0 - operation was successful.
+ */
+int qed_mcp_set_led(struct qed_hwfn *p_hwfn,
+                   struct qed_ptt *p_ptt,
+                   enum qed_led_mode mode);
+
 /* Using hwfn number (and not pf_num) is required since in CMT mode,
  * same pf_num may be used by two different hwfn
  * TODO - this shouldn't really be in .h file, but until all fields
index dc9a1353f9710566c656d91ff10057a81a1f9e88..d4a32e87818049101ae21b16f4c55ed3ab8b0fce 100644 (file)
 #include <linux/qed/common_hsi.h>
 #include <linux/qed/qed_chain.h>
 
+enum qed_led_mode {
+       QED_LED_MODE_OFF,
+       QED_LED_MODE_ON,
+       QED_LED_MODE_RESTORE
+};
+
 #define DIRECT_REG_WR(reg_addr, val) writel((u32)val, \
                                            (void __iomem *)(reg_addr))
 
@@ -252,6 +258,17 @@ struct qed_common_ops {
 
        void            (*chain_free)(struct qed_dev *cdev,
                                      struct qed_chain *p_chain);
+
+/**
+ * @brief set_led - Configure LED mode
+ *
+ * @param cdev
+ * @param mode - LED mode
+ *
+ * @return 0 on success, error otherwise.
+ */
+       int (*set_led)(struct qed_dev *cdev,
+                      enum qed_led_mode mode);
 };
 
 /**