linux/drivers/net/ethernet/sfc/mcdi_filters.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/****************************************************************************
   3 * Driver for Solarflare network controllers and boards
   4 * Copyright 2019 Solarflare Communications Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License version 2 as published
   8 * by the Free Software Foundation, incorporated herein by reference.
   9 */
  10#ifndef EFX_MCDI_FILTERS_H
  11#define EFX_MCDI_FILTERS_H
  12
  13#include "net_driver.h"
  14#include "filter.h"
  15#include "mcdi_pcol.h"
  16
  17#define EFX_EF10_FILTER_DEV_UC_MAX      32
  18#define EFX_EF10_FILTER_DEV_MC_MAX      256
  19
  20enum efx_mcdi_filter_default_filters {
  21        EFX_EF10_BCAST,
  22        EFX_EF10_UCDEF,
  23        EFX_EF10_MCDEF,
  24        EFX_EF10_VXLAN4_UCDEF,
  25        EFX_EF10_VXLAN4_MCDEF,
  26        EFX_EF10_VXLAN6_UCDEF,
  27        EFX_EF10_VXLAN6_MCDEF,
  28        EFX_EF10_NVGRE4_UCDEF,
  29        EFX_EF10_NVGRE4_MCDEF,
  30        EFX_EF10_NVGRE6_UCDEF,
  31        EFX_EF10_NVGRE6_MCDEF,
  32        EFX_EF10_GENEVE4_UCDEF,
  33        EFX_EF10_GENEVE4_MCDEF,
  34        EFX_EF10_GENEVE6_UCDEF,
  35        EFX_EF10_GENEVE6_MCDEF,
  36
  37        EFX_EF10_NUM_DEFAULT_FILTERS
  38};
  39
  40/* Per-VLAN filters information */
  41struct efx_mcdi_filter_vlan {
  42        struct list_head list;
  43        u16 vid;
  44        u16 uc[EFX_EF10_FILTER_DEV_UC_MAX];
  45        u16 mc[EFX_EF10_FILTER_DEV_MC_MAX];
  46        u16 default_filters[EFX_EF10_NUM_DEFAULT_FILTERS];
  47};
  48
  49struct efx_mcdi_dev_addr {
  50        u8 addr[ETH_ALEN];
  51};
  52
  53struct efx_mcdi_filter_table {
  54/* The MCDI match masks supported by this fw & hw, in order of priority */
  55        u32 rx_match_mcdi_flags[
  56                MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM * 2];
  57        unsigned int rx_match_count;
  58        /* Our RSS context is exclusive (as opposed to shared) */
  59        bool rx_rss_context_exclusive;
  60
  61        struct rw_semaphore lock; /* Protects entries */
  62        struct {
  63                unsigned long spec;     /* pointer to spec plus flag bits */
  64/* AUTO_OLD is used to mark and sweep MAC filters for the device address lists. */
  65/* unused flag  1UL */
  66#define EFX_EF10_FILTER_FLAG_AUTO_OLD   2UL
  67#define EFX_EF10_FILTER_FLAGS           3UL
  68                u64 handle;             /* firmware handle */
  69        } *entry;
  70/* Shadow of net_device address lists, guarded by mac_lock */
  71        struct efx_mcdi_dev_addr dev_uc_list[EFX_EF10_FILTER_DEV_UC_MAX];
  72        struct efx_mcdi_dev_addr dev_mc_list[EFX_EF10_FILTER_DEV_MC_MAX];
  73        int dev_uc_count;
  74        int dev_mc_count;
  75        bool uc_promisc;
  76        bool mc_promisc;
  77/* Whether in multicast promiscuous mode when last changed */
  78        bool mc_promisc_last;
  79        bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */
  80        /* RSS contexts have yet to be restored after MC reboot */
  81        bool must_restore_rss_contexts;
  82        /* filters have yet to be restored after MC reboot */
  83        bool must_restore_filters;
  84        /* Multicast filter chaining allows less-specific filters to receive
  85         * multicast packets that matched more-specific filters.  Early EF10
  86         * firmware didn't support this (SF bug 26807); if mc_chaining == false
  87         * then we still subscribe the dev_mc_list even when mc_promisc to
  88         * prevent another VI stealing the traffic.
  89         */
  90        bool mc_chaining;
  91        bool vlan_filter;
  92        struct list_head vlan_list;
  93};
  94
  95int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining);
  96void efx_mcdi_filter_table_down(struct efx_nic *efx);
  97void efx_mcdi_filter_table_remove(struct efx_nic *efx);
  98void efx_mcdi_filter_table_restore(struct efx_nic *efx);
  99
 100void efx_mcdi_filter_table_reset_mc_allocations(struct efx_nic *efx);
 101
 102/*
 103 * The filter table(s) are managed by firmware and we have write-only
 104 * access.  When removing filters we must identify them to the
 105 * firmware by a 64-bit handle, but this is too wide for Linux kernel
 106 * interfaces (32-bit for RX NFC, 16-bit for RFS).  Also, we need to
 107 * be able to tell in advance whether a requested insertion will
 108 * replace an existing filter.  Therefore we maintain a software hash
 109 * table, which should be at least as large as the hardware hash
 110 * table.
 111 *
 112 * Huntington has a single 8K filter table shared between all filter
 113 * types and both ports.
 114 */
 115#define EFX_MCDI_FILTER_TBL_ROWS 8192
 116
 117bool efx_mcdi_filter_match_supported(struct efx_mcdi_filter_table *table,
 118                                     bool encap,
 119                                     enum efx_filter_match_flags match_flags);
 120
 121void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx);
 122s32 efx_mcdi_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec,
 123                           bool replace_equal);
 124int efx_mcdi_filter_remove_safe(struct efx_nic *efx,
 125                                enum efx_filter_priority priority,
 126                                u32 filter_id);
 127int efx_mcdi_filter_get_safe(struct efx_nic *efx,
 128                             enum efx_filter_priority priority,
 129                             u32 filter_id, struct efx_filter_spec *spec);
 130
 131u32 efx_mcdi_filter_count_rx_used(struct efx_nic *efx,
 132                                  enum efx_filter_priority priority);
 133int efx_mcdi_filter_clear_rx(struct efx_nic *efx,
 134                             enum efx_filter_priority priority);
 135u32 efx_mcdi_filter_get_rx_id_limit(struct efx_nic *efx);
 136s32 efx_mcdi_filter_get_rx_ids(struct efx_nic *efx,
 137                               enum efx_filter_priority priority,
 138                               u32 *buf, u32 size);
 139
 140void efx_mcdi_filter_cleanup_vlans(struct efx_nic *efx);
 141int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid);
 142struct efx_mcdi_filter_vlan *efx_mcdi_filter_find_vlan(struct efx_nic *efx, u16 vid);
 143void efx_mcdi_filter_del_vlan(struct efx_nic *efx, u16 vid);
 144
 145void efx_mcdi_rx_free_indir_table(struct efx_nic *efx);
 146int efx_mcdi_rx_push_rss_context_config(struct efx_nic *efx,
 147                                        struct efx_rss_context *ctx,
 148                                        const u32 *rx_indir_table,
 149                                        const u8 *key);
 150int efx_mcdi_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
 151                                   const u32 *rx_indir_table,
 152                                   const u8 *key);
 153int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
 154                                   const u32 *rx_indir_table
 155                                   __attribute__ ((unused)),
 156                                   const u8 *key
 157                                   __attribute__ ((unused)));
 158int efx_mcdi_push_default_indir_table(struct efx_nic *efx,
 159                                      unsigned int rss_spread);
 160int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx);
 161int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx,
 162                                        struct efx_rss_context *ctx);
 163int efx_mcdi_get_rss_context_flags(struct efx_nic *efx, u32 context,
 164                                   u32 *flags);
 165void efx_mcdi_set_rss_context_flags(struct efx_nic *efx,
 166                                    struct efx_rss_context *ctx);
 167void efx_mcdi_rx_restore_rss_contexts(struct efx_nic *efx);
 168
 169static inline void efx_mcdi_update_rx_scatter(struct efx_nic *efx)
 170{
 171        /* no need to do anything here */
 172}
 173
 174bool efx_mcdi_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
 175                                    unsigned int filter_idx);
 176
 177#endif
 178