bnxt_en: Add ethtool set_wol method.
authorMichael Chan <michael.chan@broadcom.com>
Tue, 4 Apr 2017 22:14:10 +0000 (18:14 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 5 Apr 2017 13:24:26 +0000 (06:24 -0700)
And add functions to set and free magic packet filter.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 10a9cdaf2c173817072e06dea37f990bbb08990e..e432d0a92d5261475d11e18ec545f8d4fecf8fbc 100644 (file)
@@ -5842,6 +5842,38 @@ static int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
        return 0;
 }
 
+int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp)
+{
+       struct hwrm_wol_filter_alloc_input req = {0};
+       struct hwrm_wol_filter_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+       int rc;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_WOL_FILTER_ALLOC, -1, -1);
+       req.port_id = cpu_to_le16(bp->pf.port_id);
+       req.wol_type = WOL_FILTER_ALLOC_REQ_WOL_TYPE_MAGICPKT;
+       req.enables = cpu_to_le32(WOL_FILTER_ALLOC_REQ_ENABLES_MAC_ADDRESS);
+       memcpy(req.mac_address, bp->dev->dev_addr, ETH_ALEN);
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (!rc)
+               bp->wol_filter_id = resp->wol_filter_id;
+       mutex_unlock(&bp->hwrm_cmd_lock);
+       return rc;
+}
+
+int bnxt_hwrm_free_wol_fltr(struct bnxt *bp)
+{
+       struct hwrm_wol_filter_free_input req = {0};
+       int rc;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_WOL_FILTER_FREE, -1, -1);
+       req.port_id = cpu_to_le16(bp->pf.port_id);
+       req.enables = cpu_to_le32(WOL_FILTER_FREE_REQ_ENABLES_WOL_FILTER_ID);
+       req.wol_filter_id = bp->wol_filter_id;
+       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       return rc;
+}
+
 static u16 bnxt_hwrm_get_wol_fltrs(struct bnxt *bp, u16 handle)
 {
        struct hwrm_wol_filter_qcfg_input req = {0};
index 02de812dd966ca372e981e61207381a22973e342..aba25ba365fcb4794bc677d81940c201b5e762e0 100644 (file)
@@ -1242,6 +1242,8 @@ void bnxt_tx_disable(struct bnxt *bp);
 void bnxt_tx_enable(struct bnxt *bp);
 int bnxt_hwrm_set_pause(struct bnxt *);
 int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
+int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp);
+int bnxt_hwrm_free_wol_fltr(struct bnxt *bp);
 int bnxt_hwrm_fw_set_time(struct bnxt *);
 int bnxt_open_nic(struct bnxt *, bool, bool);
 int bnxt_close_nic(struct bnxt *, bool, bool);
index 2b947048aaba2c38d6cd1ae1852f02289ee30ffb..84cd4ca43c04a4bd21aa6a9e29f9082fa73e57f0 100644 (file)
@@ -847,6 +847,31 @@ static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        }
 }
 
+static int bnxt_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct bnxt *bp = netdev_priv(dev);
+
+       if (wol->wolopts & ~WAKE_MAGIC)
+               return -EINVAL;
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               if (!(bp->flags & BNXT_FLAG_WOL_CAP))
+                       return -EINVAL;
+               if (!bp->wol) {
+                       if (bnxt_hwrm_alloc_wol_fltr(bp))
+                               return -EBUSY;
+                       bp->wol = 1;
+               }
+       } else {
+               if (bp->wol) {
+                       if (bnxt_hwrm_free_wol_fltr(bp))
+                               return -EBUSY;
+                       bp->wol = 0;
+               }
+       }
+       return 0;
+}
+
 u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause)
 {
        u32 speed_mask = 0;
@@ -2150,6 +2175,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
        .set_pauseparam         = bnxt_set_pauseparam,
        .get_drvinfo            = bnxt_get_drvinfo,
        .get_wol                = bnxt_get_wol,
+       .set_wol                = bnxt_set_wol,
        .get_coalesce           = bnxt_get_coalesce,
        .set_coalesce           = bnxt_set_coalesce,
        .get_msglevel           = bnxt_get_msglevel,