Skip to content

Commit

Permalink
Merge branch 'net-atlantic-MACSec-support-for-AQC-devices'
Browse files Browse the repository at this point in the history
Igor Russkikh says:

====================
net: atlantic: MACSec support for AQC devices

This patchset introduces MACSec HW offloading support in
Marvell(Aquantia) AQC atlantic driver.

This implementation is a joint effort of Marvell developers on top of
the work started by Antoine Tenart.

v2:
 * clean up the generated code (removed useless bit operations);
 * use WARN_ONCE to avoid log spam;
 * use put_unaligned_be64;
 * removed trailing \0 and length limit for format strings;

v1: https://patchwork.ozlabs.org/cover/1259998/

RFC v2: https://patchwork.ozlabs.org/cover/1252204/

RFC v1: https://patchwork.ozlabs.org/cover/1238082/

Several patches introduce backward-incompatible changes and are
subject for discussion/drop:

1) patch 0007:
  multicast/broadcast when offloading is needed to handle ARP requests,
  because they have broadcast destination address;
  With this patch we also match and encrypt/decrypt packets between macsec
  hw and realdev based on device's mac address.
  This can potentially be used to support multiple macsec offloaded
  interfaces on top of one realdev.
  However in some environments this could lead to problems, e.g. the
  'bridge over macsec' configuration will expect the packets with unknown
  src MAC should come through macsec.
  The patch is questionable, we've used it because our current hw setup
  and requirements both assume that the decryption is done based on mac
  address match only.
  This could be changed by encrypting/decripting all the traffic (except
  control).

2) patch 0009:
  real_dev features are now propagated to macsec device (when HW
  offloading is enabled), otherwise feature set might lead to HW
  reconfiguration during MACSec configuration.
  Also, HW offloaded macsec should be able to keep LRO LSO features,
  since they are transparent for macsec engine (at least in our hardware).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 27, 2020
2 parents 673040c + e8e9e13 commit 05cc6c5
Show file tree
Hide file tree
Showing 23 changed files with 6,411 additions and 181 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/aquantia/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ config AQTION
tristate "aQuantia AQtion(tm) Support"
depends on PCI
depends on X86_64 || ARM64 || COMPILE_TEST
depends on MACSEC || MACSEC=n
---help---
This enables the support for the aQuantia AQtion(tm) Ethernet card.

Expand Down
7 changes: 6 additions & 1 deletion drivers/net/ethernet/aquantia/atlantic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

obj-$(CONFIG_AQTION) += atlantic.o

ccflags-y += -I$(src)

atlantic-objs := aq_main.o \
aq_nic.o \
aq_pci_func.o \
Expand All @@ -22,6 +24,9 @@ atlantic-objs := aq_main.o \
hw_atl/hw_atl_b0.o \
hw_atl/hw_atl_utils.o \
hw_atl/hw_atl_utils_fw2x.o \
hw_atl/hw_atl_llh.o
hw_atl/hw_atl_llh.o \
macsec/macsec_api.o

atlantic-$(CONFIG_MACSEC) += aq_macsec.o

atlantic-$(CONFIG_PTP_1588_CLOCK) += aq_ptp.o
160 changes: 143 additions & 17 deletions drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "aq_vec.h"
#include "aq_ptp.h"
#include "aq_filters.h"
#include "aq_macsec.h"

#include <linux/ptp_clock_kernel.h>

Expand Down Expand Up @@ -96,6 +97,62 @@ static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
"Queue[%d] InErrors",
};

#if IS_ENABLED(CONFIG_MACSEC)
static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
"MACSec InCtlPackets",
"MACSec InTaggedMissPackets",
"MACSec InUntaggedMissPackets",
"MACSec InNotagPackets",
"MACSec InUntaggedPackets",
"MACSec InBadTagPackets",
"MACSec InNoSciPackets",
"MACSec InUnknownSciPackets",
"MACSec InCtrlPortPassPackets",
"MACSec InUnctrlPortPassPackets",
"MACSec InCtrlPortFailPackets",
"MACSec InUnctrlPortFailPackets",
"MACSec InTooLongPackets",
"MACSec InIgpocCtlPackets",
"MACSec InEccErrorPackets",
"MACSec InUnctrlHitDropRedir",
"MACSec OutCtlPackets",
"MACSec OutUnknownSaPackets",
"MACSec OutUntaggedPackets",
"MACSec OutTooLong",
"MACSec OutEccErrorPackets",
"MACSec OutUnctrlHitDropRedir",
};

static const char *aq_macsec_txsc_stat_names[] = {
"MACSecTXSC%d ProtectedPkts",
"MACSecTXSC%d EncryptedPkts",
"MACSecTXSC%d ProtectedOctets",
"MACSecTXSC%d EncryptedOctets",
};

static const char *aq_macsec_txsa_stat_names[] = {
"MACSecTXSC%dSA%d HitDropRedirect",
"MACSecTXSC%dSA%d Protected2Pkts",
"MACSecTXSC%dSA%d ProtectedPkts",
"MACSecTXSC%dSA%d EncryptedPkts",
};

static const char *aq_macsec_rxsa_stat_names[] = {
"MACSecRXSC%dSA%d UntaggedHitPkts",
"MACSecRXSC%dSA%d CtrlHitDrpRedir",
"MACSecRXSC%dSA%d NotUsingSa",
"MACSecRXSC%dSA%d UnusedSa",
"MACSecRXSC%dSA%d NotValidPkts",
"MACSecRXSC%dSA%d InvalidPkts",
"MACSecRXSC%dSA%d OkPkts",
"MACSecRXSC%dSA%d LatePkts",
"MACSecRXSC%dSA%d DelayedPkts",
"MACSecRXSC%dSA%d UncheckedPkts",
"MACSecRXSC%dSA%d ValidatedOctets",
"MACSecRXSC%dSA%d DecryptedOctets",
};
#endif

static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
"DMASystemLoopback",
"PKTSystemLoopback",
Expand All @@ -104,30 +161,48 @@ static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
"PHYExternalLoopback",
};

static u32 aq_ethtool_n_stats(struct net_device *ndev)
{
struct aq_nic_s *nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;

#if IS_ENABLED(CONFIG_MACSEC)
if (nic->macsec_cfg) {
n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
ARRAY_SIZE(aq_macsec_txsc_stat_names) *
aq_macsec_tx_sc_cnt(nic) +
ARRAY_SIZE(aq_macsec_txsa_stat_names) *
aq_macsec_tx_sa_cnt(nic) +
ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
aq_macsec_rx_sa_cnt(nic);
}
#endif

return n_stats;
}

static void aq_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *stats, u64 *data)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg;

cfg = aq_nic_get_cfg(aq_nic);

memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
ARRAY_SIZE(aq_ethtool_queue_stat_names) *
cfg->vecs) * sizeof(u64));
aq_nic_get_stats(aq_nic, data);
memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
data = aq_nic_get_stats(aq_nic, data);
#if IS_ENABLED(CONFIG_MACSEC)
data = aq_macsec_get_stats(aq_nic, data);
#endif
}

static void aq_ethtool_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *drvinfo)
{
struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
struct aq_nic_s *aq_nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg;
u32 firmware_version;
u32 regs_count;

cfg = aq_nic_get_cfg(aq_nic);
firmware_version = aq_nic_get_fw_version(aq_nic);
regs_count = aq_nic_get_regs_count(aq_nic);

Expand All @@ -139,8 +214,7 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,

strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
sizeof(drvinfo->bus_info));
drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
drvinfo->n_stats = aq_ethtool_n_stats(ndev);
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = regs_count;
drvinfo->eedump_len = 0;
Expand All @@ -153,6 +227,9 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
struct aq_nic_cfg_s *cfg;
u8 *p = data;
int i, si;
#if IS_ENABLED(CONFIG_MACSEC)
int sa;
#endif

cfg = aq_nic_get_cfg(aq_nic);

Expand All @@ -170,6 +247,60 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
p += ETH_GSTRING_LEN;
}
}
#if IS_ENABLED(CONFIG_MACSEC)
if (!aq_nic->macsec_cfg)
break;

memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
p = p + sizeof(aq_macsec_stat_names);
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
struct aq_macsec_txsc *aq_txsc;

if (!(test_bit(i, &aq_nic->macsec_cfg->txsc_idx_busy)))
continue;

for (si = 0;
si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
si++) {
snprintf(p, ETH_GSTRING_LEN,
aq_macsec_txsc_stat_names[si], i);
p += ETH_GSTRING_LEN;
}
aq_txsc = &aq_nic->macsec_cfg->aq_txsc[i];
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
continue;
for (si = 0;
si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
si++) {
snprintf(p, ETH_GSTRING_LEN,
aq_macsec_txsa_stat_names[si],
i, sa);
p += ETH_GSTRING_LEN;
}
}
}
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
struct aq_macsec_rxsc *aq_rxsc;

if (!(test_bit(i, &aq_nic->macsec_cfg->rxsc_idx_busy)))
continue;

aq_rxsc = &aq_nic->macsec_cfg->aq_rxsc[i];
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
continue;
for (si = 0;
si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
si++) {
snprintf(p, ETH_GSTRING_LEN,
aq_macsec_rxsa_stat_names[si],
i, sa);
p += ETH_GSTRING_LEN;
}
}
}
#endif
break;
case ETH_SS_PRIV_FLAGS:
memcpy(p, aq_ethtool_priv_flag_names,
Expand Down Expand Up @@ -209,16 +340,11 @@ static int aq_ethtool_set_phys_id(struct net_device *ndev,

static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg;
int ret = 0;

cfg = aq_nic_get_cfg(aq_nic);

switch (stringset) {
case ETH_SS_STATS:
ret = ARRAY_SIZE(aq_ethtool_stat_names) +
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
ret = aq_ethtool_n_stats(ndev);
break;
case ETH_SS_PRIV_FLAGS:
ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ struct aq_fw_ops {

int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
u32 *supported_rates);

u32 (*get_link_capabilities)(struct aq_hw_s *self);

int (*send_macsec_req)(struct aq_hw_s *self,
struct macsec_msg_fw_request *msg,
struct macsec_msg_fw_response *resp);
};

#endif /* AQ_HW_H */
Loading

0 comments on commit 05cc6c5

Please sign in to comment.