Skip to content

Commit 05cc6c5

Browse files
committed
Merge branch 'net-atlantic-MACSec-support-for-AQC-devices'
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 <[email protected]>
2 parents 673040c + e8e9e13 commit 05cc6c5

File tree

23 files changed

+6411
-181
lines changed

23 files changed

+6411
-181
lines changed

drivers/net/ethernet/aquantia/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ config AQTION
2020
tristate "aQuantia AQtion(tm) Support"
2121
depends on PCI
2222
depends on X86_64 || ARM64 || COMPILE_TEST
23+
depends on MACSEC || MACSEC=n
2324
---help---
2425
This enables the support for the aQuantia AQtion(tm) Ethernet card.
2526

drivers/net/ethernet/aquantia/atlantic/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
obj-$(CONFIG_AQTION) += atlantic.o
1010

11+
ccflags-y += -I$(src)
12+
1113
atlantic-objs := aq_main.o \
1214
aq_nic.o \
1315
aq_pci_func.o \
@@ -22,6 +24,9 @@ atlantic-objs := aq_main.o \
2224
hw_atl/hw_atl_b0.o \
2325
hw_atl/hw_atl_utils.o \
2426
hw_atl/hw_atl_utils_fw2x.o \
25-
hw_atl/hw_atl_llh.o
27+
hw_atl/hw_atl_llh.o \
28+
macsec/macsec_api.o
29+
30+
atlantic-$(CONFIG_MACSEC) += aq_macsec.o
2631

2732
atlantic-$(CONFIG_PTP_1588_CLOCK) += aq_ptp.o

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c

Lines changed: 143 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "aq_vec.h"
1212
#include "aq_ptp.h"
1313
#include "aq_filters.h"
14+
#include "aq_macsec.h"
1415

1516
#include <linux/ptp_clock_kernel.h>
1617

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

100+
#if IS_ENABLED(CONFIG_MACSEC)
101+
static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
102+
"MACSec InCtlPackets",
103+
"MACSec InTaggedMissPackets",
104+
"MACSec InUntaggedMissPackets",
105+
"MACSec InNotagPackets",
106+
"MACSec InUntaggedPackets",
107+
"MACSec InBadTagPackets",
108+
"MACSec InNoSciPackets",
109+
"MACSec InUnknownSciPackets",
110+
"MACSec InCtrlPortPassPackets",
111+
"MACSec InUnctrlPortPassPackets",
112+
"MACSec InCtrlPortFailPackets",
113+
"MACSec InUnctrlPortFailPackets",
114+
"MACSec InTooLongPackets",
115+
"MACSec InIgpocCtlPackets",
116+
"MACSec InEccErrorPackets",
117+
"MACSec InUnctrlHitDropRedir",
118+
"MACSec OutCtlPackets",
119+
"MACSec OutUnknownSaPackets",
120+
"MACSec OutUntaggedPackets",
121+
"MACSec OutTooLong",
122+
"MACSec OutEccErrorPackets",
123+
"MACSec OutUnctrlHitDropRedir",
124+
};
125+
126+
static const char *aq_macsec_txsc_stat_names[] = {
127+
"MACSecTXSC%d ProtectedPkts",
128+
"MACSecTXSC%d EncryptedPkts",
129+
"MACSecTXSC%d ProtectedOctets",
130+
"MACSecTXSC%d EncryptedOctets",
131+
};
132+
133+
static const char *aq_macsec_txsa_stat_names[] = {
134+
"MACSecTXSC%dSA%d HitDropRedirect",
135+
"MACSecTXSC%dSA%d Protected2Pkts",
136+
"MACSecTXSC%dSA%d ProtectedPkts",
137+
"MACSecTXSC%dSA%d EncryptedPkts",
138+
};
139+
140+
static const char *aq_macsec_rxsa_stat_names[] = {
141+
"MACSecRXSC%dSA%d UntaggedHitPkts",
142+
"MACSecRXSC%dSA%d CtrlHitDrpRedir",
143+
"MACSecRXSC%dSA%d NotUsingSa",
144+
"MACSecRXSC%dSA%d UnusedSa",
145+
"MACSecRXSC%dSA%d NotValidPkts",
146+
"MACSecRXSC%dSA%d InvalidPkts",
147+
"MACSecRXSC%dSA%d OkPkts",
148+
"MACSecRXSC%dSA%d LatePkts",
149+
"MACSecRXSC%dSA%d DelayedPkts",
150+
"MACSecRXSC%dSA%d UncheckedPkts",
151+
"MACSecRXSC%dSA%d ValidatedOctets",
152+
"MACSecRXSC%dSA%d DecryptedOctets",
153+
};
154+
#endif
155+
99156
static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
100157
"DMASystemLoopback",
101158
"PKTSystemLoopback",
@@ -104,30 +161,48 @@ static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
104161
"PHYExternalLoopback",
105162
};
106163

164+
static u32 aq_ethtool_n_stats(struct net_device *ndev)
165+
{
166+
struct aq_nic_s *nic = netdev_priv(ndev);
167+
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
168+
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
169+
ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;
170+
171+
#if IS_ENABLED(CONFIG_MACSEC)
172+
if (nic->macsec_cfg) {
173+
n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
174+
ARRAY_SIZE(aq_macsec_txsc_stat_names) *
175+
aq_macsec_tx_sc_cnt(nic) +
176+
ARRAY_SIZE(aq_macsec_txsa_stat_names) *
177+
aq_macsec_tx_sa_cnt(nic) +
178+
ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
179+
aq_macsec_rx_sa_cnt(nic);
180+
}
181+
#endif
182+
183+
return n_stats;
184+
}
185+
107186
static void aq_ethtool_stats(struct net_device *ndev,
108187
struct ethtool_stats *stats, u64 *data)
109188
{
110189
struct aq_nic_s *aq_nic = netdev_priv(ndev);
111-
struct aq_nic_cfg_s *cfg;
112190

113-
cfg = aq_nic_get_cfg(aq_nic);
114-
115-
memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
116-
ARRAY_SIZE(aq_ethtool_queue_stat_names) *
117-
cfg->vecs) * sizeof(u64));
118-
aq_nic_get_stats(aq_nic, data);
191+
memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
192+
data = aq_nic_get_stats(aq_nic, data);
193+
#if IS_ENABLED(CONFIG_MACSEC)
194+
data = aq_macsec_get_stats(aq_nic, data);
195+
#endif
119196
}
120197

121198
static void aq_ethtool_get_drvinfo(struct net_device *ndev,
122199
struct ethtool_drvinfo *drvinfo)
123200
{
124201
struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
125202
struct aq_nic_s *aq_nic = netdev_priv(ndev);
126-
struct aq_nic_cfg_s *cfg;
127203
u32 firmware_version;
128204
u32 regs_count;
129205

130-
cfg = aq_nic_get_cfg(aq_nic);
131206
firmware_version = aq_nic_get_fw_version(aq_nic);
132207
regs_count = aq_nic_get_regs_count(aq_nic);
133208

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

140215
strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
141216
sizeof(drvinfo->bus_info));
142-
drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
143-
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
217+
drvinfo->n_stats = aq_ethtool_n_stats(ndev);
144218
drvinfo->testinfo_len = 0;
145219
drvinfo->regdump_len = regs_count;
146220
drvinfo->eedump_len = 0;
@@ -153,6 +227,9 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
153227
struct aq_nic_cfg_s *cfg;
154228
u8 *p = data;
155229
int i, si;
230+
#if IS_ENABLED(CONFIG_MACSEC)
231+
int sa;
232+
#endif
156233

157234
cfg = aq_nic_get_cfg(aq_nic);
158235

@@ -170,6 +247,60 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
170247
p += ETH_GSTRING_LEN;
171248
}
172249
}
250+
#if IS_ENABLED(CONFIG_MACSEC)
251+
if (!aq_nic->macsec_cfg)
252+
break;
253+
254+
memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
255+
p = p + sizeof(aq_macsec_stat_names);
256+
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
257+
struct aq_macsec_txsc *aq_txsc;
258+
259+
if (!(test_bit(i, &aq_nic->macsec_cfg->txsc_idx_busy)))
260+
continue;
261+
262+
for (si = 0;
263+
si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
264+
si++) {
265+
snprintf(p, ETH_GSTRING_LEN,
266+
aq_macsec_txsc_stat_names[si], i);
267+
p += ETH_GSTRING_LEN;
268+
}
269+
aq_txsc = &aq_nic->macsec_cfg->aq_txsc[i];
270+
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
271+
if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
272+
continue;
273+
for (si = 0;
274+
si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
275+
si++) {
276+
snprintf(p, ETH_GSTRING_LEN,
277+
aq_macsec_txsa_stat_names[si],
278+
i, sa);
279+
p += ETH_GSTRING_LEN;
280+
}
281+
}
282+
}
283+
for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
284+
struct aq_macsec_rxsc *aq_rxsc;
285+
286+
if (!(test_bit(i, &aq_nic->macsec_cfg->rxsc_idx_busy)))
287+
continue;
288+
289+
aq_rxsc = &aq_nic->macsec_cfg->aq_rxsc[i];
290+
for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
291+
if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
292+
continue;
293+
for (si = 0;
294+
si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
295+
si++) {
296+
snprintf(p, ETH_GSTRING_LEN,
297+
aq_macsec_rxsa_stat_names[si],
298+
i, sa);
299+
p += ETH_GSTRING_LEN;
300+
}
301+
}
302+
}
303+
#endif
173304
break;
174305
case ETH_SS_PRIV_FLAGS:
175306
memcpy(p, aq_ethtool_priv_flag_names,
@@ -209,16 +340,11 @@ static int aq_ethtool_set_phys_id(struct net_device *ndev,
209340

210341
static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
211342
{
212-
struct aq_nic_s *aq_nic = netdev_priv(ndev);
213-
struct aq_nic_cfg_s *cfg;
214343
int ret = 0;
215344

216-
cfg = aq_nic_get_cfg(aq_nic);
217-
218345
switch (stringset) {
219346
case ETH_SS_STATS:
220-
ret = ARRAY_SIZE(aq_ethtool_stat_names) +
221-
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
347+
ret = aq_ethtool_n_stats(ndev);
222348
break;
223349
case ETH_SS_PRIV_FLAGS:
224350
ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ struct aq_fw_ops {
343343

344344
int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
345345
u32 *supported_rates);
346+
347+
u32 (*get_link_capabilities)(struct aq_hw_s *self);
348+
349+
int (*send_macsec_req)(struct aq_hw_s *self,
350+
struct macsec_msg_fw_request *msg,
351+
struct macsec_msg_fw_response *resp);
346352
};
347353

348354
#endif /* AQ_HW_H */

0 commit comments

Comments
 (0)