Skip to content

Commit 62c1c2e

Browse files
logostdavem330
authored andcommitted
net: atlantic: MACSec offload skeleton
This patch adds basic functionality for MACSec offloading for Atlantic NICs. MACSec offloading functionality is enabled if network card has appropriate FW that has MACSec offloading enabled in config. Actual functionality (ingress, egress, etc) will be added in follow-up patches. Signed-off-by: Dmitry Bogdanov <[email protected]> Signed-off-by: Mark Starovoytov <[email protected]> Signed-off-by: Igor Russkikh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c850240 commit 62c1c2e

File tree

10 files changed

+373
-8
lines changed

10 files changed

+373
-8
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: 4 additions & 0 deletions
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 \
@@ -24,4 +26,6 @@ atlantic-objs := aq_main.o \
2426
hw_atl/hw_atl_utils_fw2x.o \
2527
hw_atl/hw_atl_llh.o
2628

29+
atlantic-$(CONFIG_MACSEC) += aq_macsec.o
30+
2731
atlantic-$(CONFIG_PTP_1588_CLOCK) += aq_ptp.o

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 */
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Atlantic Network Driver
3+
* Copyright (C) 2020 Marvell International Ltd.
4+
*/
5+
6+
#include "aq_macsec.h"
7+
#include "aq_nic.h"
8+
#include <linux/rtnetlink.h>
9+
10+
static int aq_mdo_dev_open(struct macsec_context *ctx)
11+
{
12+
return 0;
13+
}
14+
15+
static int aq_mdo_dev_stop(struct macsec_context *ctx)
16+
{
17+
return 0;
18+
}
19+
20+
static int aq_mdo_add_secy(struct macsec_context *ctx)
21+
{
22+
return -EOPNOTSUPP;
23+
}
24+
25+
static int aq_mdo_upd_secy(struct macsec_context *ctx)
26+
{
27+
return -EOPNOTSUPP;
28+
}
29+
30+
static int aq_mdo_del_secy(struct macsec_context *ctx)
31+
{
32+
return -EOPNOTSUPP;
33+
}
34+
35+
static int aq_mdo_add_txsa(struct macsec_context *ctx)
36+
{
37+
return -EOPNOTSUPP;
38+
}
39+
40+
static int aq_mdo_upd_txsa(struct macsec_context *ctx)
41+
{
42+
return -EOPNOTSUPP;
43+
}
44+
45+
static int aq_mdo_del_txsa(struct macsec_context *ctx)
46+
{
47+
return -EOPNOTSUPP;
48+
}
49+
50+
static int aq_mdo_add_rxsc(struct macsec_context *ctx)
51+
{
52+
return -EOPNOTSUPP;
53+
}
54+
55+
static int aq_mdo_upd_rxsc(struct macsec_context *ctx)
56+
{
57+
return -EOPNOTSUPP;
58+
}
59+
60+
static int aq_mdo_del_rxsc(struct macsec_context *ctx)
61+
{
62+
return -EOPNOTSUPP;
63+
}
64+
65+
static int aq_mdo_add_rxsa(struct macsec_context *ctx)
66+
{
67+
return -EOPNOTSUPP;
68+
}
69+
70+
static int aq_mdo_upd_rxsa(struct macsec_context *ctx)
71+
{
72+
return -EOPNOTSUPP;
73+
}
74+
75+
static int aq_mdo_del_rxsa(struct macsec_context *ctx)
76+
{
77+
return -EOPNOTSUPP;
78+
}
79+
80+
static void aq_check_txsa_expiration(struct aq_nic_s *nic)
81+
{
82+
}
83+
84+
const struct macsec_ops aq_macsec_ops = {
85+
.mdo_dev_open = aq_mdo_dev_open,
86+
.mdo_dev_stop = aq_mdo_dev_stop,
87+
.mdo_add_secy = aq_mdo_add_secy,
88+
.mdo_upd_secy = aq_mdo_upd_secy,
89+
.mdo_del_secy = aq_mdo_del_secy,
90+
.mdo_add_rxsc = aq_mdo_add_rxsc,
91+
.mdo_upd_rxsc = aq_mdo_upd_rxsc,
92+
.mdo_del_rxsc = aq_mdo_del_rxsc,
93+
.mdo_add_rxsa = aq_mdo_add_rxsa,
94+
.mdo_upd_rxsa = aq_mdo_upd_rxsa,
95+
.mdo_del_rxsa = aq_mdo_del_rxsa,
96+
.mdo_add_txsa = aq_mdo_add_txsa,
97+
.mdo_upd_txsa = aq_mdo_upd_txsa,
98+
.mdo_del_txsa = aq_mdo_del_txsa,
99+
};
100+
101+
int aq_macsec_init(struct aq_nic_s *nic)
102+
{
103+
struct aq_macsec_cfg *cfg;
104+
u32 caps_lo;
105+
106+
if (!nic->aq_fw_ops->get_link_capabilities)
107+
return 0;
108+
109+
caps_lo = nic->aq_fw_ops->get_link_capabilities(nic->aq_hw);
110+
111+
if (!(caps_lo & BIT(CAPS_LO_MACSEC)))
112+
return 0;
113+
114+
nic->macsec_cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
115+
if (!nic->macsec_cfg)
116+
return -ENOMEM;
117+
118+
nic->ndev->features |= NETIF_F_HW_MACSEC;
119+
nic->ndev->macsec_ops = &aq_macsec_ops;
120+
121+
return 0;
122+
}
123+
124+
void aq_macsec_free(struct aq_nic_s *nic)
125+
{
126+
kfree(nic->macsec_cfg);
127+
nic->macsec_cfg = NULL;
128+
}
129+
130+
int aq_macsec_enable(struct aq_nic_s *nic)
131+
{
132+
struct macsec_msg_fw_response resp = { 0 };
133+
struct macsec_msg_fw_request msg = { 0 };
134+
struct aq_hw_s *hw = nic->aq_hw;
135+
int ret = 0;
136+
137+
if (!nic->macsec_cfg)
138+
return 0;
139+
140+
rtnl_lock();
141+
142+
if (nic->aq_fw_ops->send_macsec_req) {
143+
struct macsec_cfg_request cfg = { 0 };
144+
145+
cfg.enabled = 1;
146+
cfg.egress_threshold = 0xffffffff;
147+
cfg.ingress_threshold = 0xffffffff;
148+
cfg.interrupts_enabled = 1;
149+
150+
msg.msg_type = macsec_cfg_msg;
151+
msg.cfg = cfg;
152+
153+
ret = nic->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
154+
if (ret)
155+
goto unlock;
156+
}
157+
158+
unlock:
159+
rtnl_unlock();
160+
return ret;
161+
}
162+
163+
void aq_macsec_work(struct aq_nic_s *nic)
164+
{
165+
if (!nic->macsec_cfg)
166+
return;
167+
168+
if (!netif_carrier_ok(nic->ndev))
169+
return;
170+
171+
rtnl_lock();
172+
aq_check_txsa_expiration(nic);
173+
rtnl_unlock();
174+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* Atlantic Network Driver
3+
* Copyright (C) 2020 Marvell International Ltd.
4+
*/
5+
6+
#ifndef AQ_MACSEC_H
7+
#define AQ_MACSEC_H
8+
9+
#include <linux/netdevice.h>
10+
#if IS_ENABLED(CONFIG_MACSEC)
11+
12+
#include "net/macsec.h"
13+
14+
struct aq_nic_s;
15+
16+
#define AQ_MACSEC_MAX_SC 32
17+
#define AQ_MACSEC_MAX_SA 32
18+
19+
enum aq_macsec_sc_sa {
20+
aq_macsec_sa_sc_4sa_8sc,
21+
aq_macsec_sa_sc_not_used,
22+
aq_macsec_sa_sc_2sa_16sc,
23+
aq_macsec_sa_sc_1sa_32sc,
24+
};
25+
26+
struct aq_macsec_txsc {
27+
};
28+
29+
struct aq_macsec_rxsc {
30+
};
31+
32+
struct aq_macsec_cfg {
33+
enum aq_macsec_sc_sa sc_sa;
34+
/* Egress channel configuration */
35+
unsigned long txsc_idx_busy;
36+
struct aq_macsec_txsc aq_txsc[AQ_MACSEC_MAX_SC];
37+
/* Ingress channel configuration */
38+
unsigned long rxsc_idx_busy;
39+
struct aq_macsec_rxsc aq_rxsc[AQ_MACSEC_MAX_SC];
40+
};
41+
42+
extern const struct macsec_ops aq_macsec_ops;
43+
44+
int aq_macsec_init(struct aq_nic_s *nic);
45+
void aq_macsec_free(struct aq_nic_s *nic);
46+
int aq_macsec_enable(struct aq_nic_s *nic);
47+
void aq_macsec_work(struct aq_nic_s *nic);
48+
49+
#endif
50+
51+
#endif /* AQ_MACSEC_H */

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "aq_vec.h"
1212
#include "aq_hw.h"
1313
#include "aq_pci_func.h"
14+
#include "aq_macsec.h"
1415
#include "aq_main.h"
1516
#include "aq_phy.h"
1617
#include "aq_ptp.h"
@@ -176,6 +177,9 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
176177
aq_utils_obj_clear(&self->flags,
177178
AQ_NIC_LINK_DOWN);
178179
netif_carrier_on(self->ndev);
180+
#if IS_ENABLED(CONFIG_MACSEC)
181+
aq_macsec_enable(self);
182+
#endif
179183
netif_tx_wake_all_queues(self->ndev);
180184
}
181185
if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) {
@@ -217,6 +221,10 @@ static void aq_nic_service_task(struct work_struct *work)
217221
if (err)
218222
return;
219223

224+
#if IS_ENABLED(CONFIG_MACSEC)
225+
aq_macsec_work(self);
226+
#endif
227+
220228
mutex_lock(&self->fwreq_mutex);
221229
if (self->aq_fw_ops->update_stats)
222230
self->aq_fw_ops->update_stats(self->aq_hw);
@@ -262,6 +270,10 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
262270
if (err)
263271
goto err_exit;
264272

273+
#if IS_ENABLED(CONFIG_MACSEC)
274+
aq_macsec_init(self);
275+
#endif
276+
265277
mutex_lock(&self->fwreq_mutex);
266278
err = self->aq_fw_ops->get_mac_permanent(self->aq_hw,
267279
self->ndev->dev_addr);
@@ -296,6 +308,10 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
296308
goto err_exit;
297309

298310
err_exit:
311+
#if IS_ENABLED(CONFIG_MACSEC)
312+
if (err)
313+
aq_macsec_free(self);
314+
#endif
299315
return err;
300316
}
301317

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct aq_ring_s;
1717
struct aq_hw_ops;
1818
struct aq_fw_s;
1919
struct aq_vec_s;
20+
struct aq_macsec_cfg;
2021
struct aq_ptp_s;
2122
enum aq_rx_filter_type;
2223

@@ -129,6 +130,9 @@ struct aq_nic_s {
129130
u32 irqvecs;
130131
/* mutex to serialize FW interface access operations */
131132
struct mutex fwreq_mutex;
133+
#if IS_ENABLED(CONFIG_MACSEC)
134+
struct aq_macsec_cfg *macsec_cfg;
135+
#endif
132136
/* PTP support */
133137
struct aq_ptp_s *aq_ptp;
134138
struct aq_hw_rx_fltrs_s aq_hw_rx_fltrs;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "hw_atl/hw_atl_b0.h"
1919
#include "aq_filters.h"
2020
#include "aq_drvinfo.h"
21+
#include "aq_macsec.h"
2122

2223
static const struct pci_device_id aq_pci_tbl[] = {
2324
{ PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_0001), },
@@ -324,6 +325,10 @@ static void aq_pci_remove(struct pci_dev *pdev)
324325
aq_clear_rxnfc_all_rules(self);
325326
if (self->ndev->reg_state == NETREG_REGISTERED)
326327
unregister_netdev(self->ndev);
328+
329+
#if IS_ENABLED(CONFIG_MACSEC)
330+
aq_macsec_free(self);
331+
#endif
327332
aq_nic_free_vectors(self);
328333
aq_pci_free_irq_vectors(self);
329334
iounmap(self->aq_hw->mmio);

0 commit comments

Comments
 (0)