From: Tom Zhao <tz...@solarflare.com>

Various MCDI functions (especially in filter handling) need to check the
 datapath caps, but those live in nic_data (since they don't exist on
 Siena).  Decouple from ef10-specific data structures by adding check_caps
 to the nic_type, to allow using these functions from non-ef10 drivers.

Also add a convenience macro efx_has_cap() to reduce the amount of
 boilerplate involved in calling it.

Signed-off-by: Edward Cree <ec...@solarflare.com>
---
 drivers/net/ethernet/sfc/ef10.c       | 18 ++++++++++++++++++
 drivers/net/ethernet/sfc/mcdi.h       | 12 ++++++++++++
 drivers/net/ethernet/sfc/net_driver.h |  3 +++
 drivers/net/ethernet/sfc/siena.c      |  7 +++++++
 4 files changed, 40 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 0ad311ff6796..7b3c6214dee6 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -3961,6 +3961,22 @@ static int efx_ef10_udp_tnl_del_port(struct efx_nic *efx,
        return rc;
 }
 
+static unsigned int ef10_check_caps(const struct efx_nic *efx,
+                                   u8 flag,
+                                   u32 offset)
+{
+       const struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
+       switch (offset) {
+       case(MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_OFST):
+               return nic_data->datapath_caps & BIT_ULL(flag);
+       case(MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_OFST):
+               return nic_data->datapath_caps2 & BIT_ULL(flag);
+       default:
+               return 0;
+       }
+}
+
 #define EF10_OFFLOAD_FEATURES          \
        (NETIF_F_IP_CSUM |              \
         NETIF_F_HW_VLAN_CTAG_FILTER |  \
@@ -4073,6 +4089,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
        .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
                            1 << HWTSTAMP_FILTER_ALL,
        .rx_hash_key_size = 40,
+       .check_caps = ef10_check_caps,
 };
 
 const struct efx_nic_type efx_hunt_a0_nic_type = {
@@ -4208,4 +4225,5 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
        .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
                            1 << HWTSTAMP_FILTER_ALL,
        .rx_hash_key_size = 40,
+       .check_caps = ef10_check_caps,
 };
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index 54a45010b576..b107e4c00285 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -326,6 +326,18 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, 
efx_qword_t *ev);
 #define MCDI_EVENT_FIELD(_ev, _field)                  \
        EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
 
+#define MCDI_CAPABILITY(field)                                         \
+       MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _LBN
+
+#define MCDI_CAPABILITY_OFST(field) \
+       MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _OFST
+
+/* field is FLAGS1 or FLAGS2 */
+#define efx_has_cap(efx, flag, field) \
+       efx->type->check_caps(efx, \
+                             MCDI_CAPABILITY(flag), \
+                             MCDI_CAPABILITY_OFST(field))
+
 void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len);
 int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
                           u16 *fw_subtype_list, u32 *capabilities);
diff --git a/drivers/net/ethernet/sfc/net_driver.h 
b/drivers/net/ethernet/sfc/net_driver.h
index d43f22c8f31c..bdeea48ff938 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -1354,6 +1354,9 @@ struct efx_nic_type {
        void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
        int (*set_wol)(struct efx_nic *efx, u32 type);
        void (*resume_wol)(struct efx_nic *efx);
+       unsigned int (*check_caps)(const struct efx_nic *efx,
+                                  u8 flag,
+                                  u32 offset);
        int (*test_chip)(struct efx_nic *efx, struct efx_self_tests *tests);
        int (*test_nvram)(struct efx_nic *efx);
        void (*mcdi_request)(struct efx_nic *efx,
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index baa464161626..ed1cb6caa69d 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -948,6 +948,13 @@ static int siena_mtd_probe(struct efx_nic *efx)
 
 #endif /* CONFIG_SFC_MTD */
 
+unsigned int siena_check_caps(const struct efx_nic *efx,
+                             u8 flag, u32 offset)
+{
+       /* Siena did not support MC_CMD_GET_CAPABILITIES */
+       return 0;
+}
+
 /**************************************************************************
  *
  * Revision-dependent attributes used by efx.c and nic.c

Reply via email to