1a868b486SRadu Pirea (NXP OSS) // SPDX-License-Identifier: GPL-2.0
2a868b486SRadu Pirea (NXP OSS) /* NXP C45 PTP PHY driver interface
3a868b486SRadu Pirea (NXP OSS)  * Copyright 2023 NXP
4a868b486SRadu Pirea (NXP OSS)  * Author: Radu Pirea <radu-nicolae.pirea@oss.nxp.com>
5a868b486SRadu Pirea (NXP OSS)  */
6a868b486SRadu Pirea (NXP OSS) 
7a868b486SRadu Pirea (NXP OSS) #include <linux/delay.h>
8a868b486SRadu Pirea (NXP OSS) #include <linux/ethtool_netlink.h>
9a868b486SRadu Pirea (NXP OSS) #include <linux/kernel.h>
10a868b486SRadu Pirea (NXP OSS) #include <linux/mii.h>
11a868b486SRadu Pirea (NXP OSS) #include <linux/module.h>
12a868b486SRadu Pirea (NXP OSS) #include <linux/phy.h>
13a868b486SRadu Pirea (NXP OSS) #include <linux/processor.h>
14*dc1a0038SRadu Pirea (NXP OSS) #include <net/dst_metadata.h>
15a868b486SRadu Pirea (NXP OSS) #include <net/macsec.h>
16a868b486SRadu Pirea (NXP OSS) 
17a868b486SRadu Pirea (NXP OSS) #include "nxp-c45-tja11xx.h"
18a868b486SRadu Pirea (NXP OSS) 
19a868b486SRadu Pirea (NXP OSS) #define MACSEC_REG_SIZE			32
20a868b486SRadu Pirea (NXP OSS) #define TX_SC_MAX			4
21a868b486SRadu Pirea (NXP OSS) 
22a868b486SRadu Pirea (NXP OSS) #define TX_SC_BIT(secy_id)		BIT(MACSEC_REG_SIZE - (secy_id) - 1)
23a868b486SRadu Pirea (NXP OSS) 
24a868b486SRadu Pirea (NXP OSS) #define VEND1_MACSEC_BASE		0x9000
25a868b486SRadu Pirea (NXP OSS) 
26a868b486SRadu Pirea (NXP OSS) #define MACSEC_CFG			0x0000
27a868b486SRadu Pirea (NXP OSS) #define MACSEC_CFG_BYPASS		BIT(1)
28a868b486SRadu Pirea (NXP OSS) #define MACSEC_CFG_S0I			BIT(0)
29a868b486SRadu Pirea (NXP OSS) 
30a868b486SRadu Pirea (NXP OSS) #define MACSEC_TPNET			0x0044
31a868b486SRadu Pirea (NXP OSS) #define PN_WRAP_THRESHOLD		0xffffffff
32a868b486SRadu Pirea (NXP OSS) 
33a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSCA			0x0080
34a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSCKA			0x0084
35a868b486SRadu Pirea (NXP OSS) 
36a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSCA			0x00C0
37a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSCKA			0x00C4
38a868b486SRadu Pirea (NXP OSS) 
39a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_SCI_1H		0x0100
40a868b486SRadu Pirea (NXP OSS) 
41a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG			0x0128
42a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_XPN		BIT(25)
43a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_AES_256		BIT(24)
44a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_SCI_EN		BIT(11)
45a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_RP		BIT(10)
46a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_VF_MASK		GENMASK(9, 8)
47a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSC_CFG_VF_OFF		8
48a868b486SRadu Pirea (NXP OSS) 
49a868b486SRadu Pirea (NXP OSS) #define MACSEC_RPW			0x012C
50a868b486SRadu Pirea (NXP OSS) 
51a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_CS		0x0180
52a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_NPN		0x0184
53a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_XNPN		0x0188
54a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_LNPN		0x018C
55a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_LXNPN		0x0190
56a868b486SRadu Pirea (NXP OSS) 
57a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_CS		0x01C0
58a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_NPN		0x01C4
59a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_XNPN		0x01C8
60a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_LNPN		0x01CC
61a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_LXNPN		0x01D0
62a868b486SRadu Pirea (NXP OSS) 
63a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_CS_AN_OFF		1
64a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_CS_EN		BIT(0)
65a868b486SRadu Pirea (NXP OSS) 
66a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_SCI_1H		0x0200
67a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG			0x0228
68a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_XPN		BIT(25)
69a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_AES_256		BIT(24)
70a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_AN_MASK		GENMASK(19, 18)
71a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_AN_OFF		18
72a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_ASA		BIT(17)
73a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_SCE		BIT(16)
74a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_ENCRYPT		BIT(4)
75a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_PROTECT		BIT(3)
76a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_SEND_SCI	BIT(2)
77a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_END_STATION	BIT(1)
78a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSC_CFG_SCB		BIT(0)
79a868b486SRadu Pirea (NXP OSS) 
80a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_CS		0x0280
81a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_NPN		0x0284
82a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_XNPN		0x0288
83a868b486SRadu Pirea (NXP OSS) 
84a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_CS		0x02C0
85a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_NPN		0x02C4
86a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_XNPN		0x02C8
87a868b486SRadu Pirea (NXP OSS) 
88a868b486SRadu Pirea (NXP OSS) #define MACSEC_SA_CS_A			BIT(31)
89a868b486SRadu Pirea (NXP OSS) 
90a868b486SRadu Pirea (NXP OSS) #define MACSEC_EVR			0x0400
91a868b486SRadu Pirea (NXP OSS) #define MACSEC_EVER			0x0404
92a868b486SRadu Pirea (NXP OSS) 
93a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_KA		0x0700
94a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_SSCI		0x0720
95a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_SALT		0x0724
96a868b486SRadu Pirea (NXP OSS) 
97a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_KA		0x0740
98a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_SSCI		0x0760
99a868b486SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_SALT		0x0764
100a868b486SRadu Pirea (NXP OSS) 
101a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_KA		0x0780
102a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_SSCI		0x07A0
103a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_SALT		0x07A4
104a868b486SRadu Pirea (NXP OSS) 
105a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_KA		0x07C0
106a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_SSCI		0x07E0
107a868b486SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_SALT		0x07E4
108a868b486SRadu Pirea (NXP OSS) 
109a868b486SRadu Pirea (NXP OSS) #define MACSEC_UPFR0D2			0x0A08
110a868b486SRadu Pirea (NXP OSS) #define MACSEC_UPFR0M1			0x0A10
111a868b486SRadu Pirea (NXP OSS) #define MACSEC_OVP			BIT(12)
112a868b486SRadu Pirea (NXP OSS) 
113a868b486SRadu Pirea (NXP OSS) #define	MACSEC_UPFR0M2			0x0A14
114a868b486SRadu Pirea (NXP OSS) #define ETYPE_MASK			0xffff
115a868b486SRadu Pirea (NXP OSS) 
116a868b486SRadu Pirea (NXP OSS) #define MACSEC_UPFR0R			0x0A18
117a868b486SRadu Pirea (NXP OSS) #define MACSEC_UPFR_EN			BIT(0)
118a868b486SRadu Pirea (NXP OSS) 
119a868b486SRadu Pirea (NXP OSS) #define ADPTR_CNTRL			0x0F00
120a868b486SRadu Pirea (NXP OSS) #define ADPTR_CNTRL_CONFIG_EN		BIT(14)
121a868b486SRadu Pirea (NXP OSS) #define ADPTR_CNTRL_ADPTR_EN		BIT(12)
122*dc1a0038SRadu Pirea (NXP OSS) #define ADPTR_TX_TAG_CNTRL		0x0F0C
123*dc1a0038SRadu Pirea (NXP OSS) #define ADPTR_TX_TAG_CNTRL_ENA		BIT(31)
124a868b486SRadu Pirea (NXP OSS) 
125a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_BASE			0x800
126a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_SIZE			0x10
127a868b486SRadu Pirea (NXP OSS) #define TX_FLT_BASE(flt_id)		(TX_SC_FLT_BASE + \
128a868b486SRadu Pirea (NXP OSS) 	TX_SC_FLT_SIZE * (flt_id))
129a868b486SRadu Pirea (NXP OSS) 
130a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_OFF_MAC_DA_SA		0x04
131a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_OFF_MAC_SA		0x08
132a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_OFF_MAC_CFG		0x0C
133a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_BY_SA			BIT(14)
134a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_EN			BIT(8)
135a868b486SRadu Pirea (NXP OSS) 
136a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_MAC_DA_SA(base)	((base) + TX_SC_FLT_OFF_MAC_DA_SA)
137a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_MAC_SA(base)		((base) + TX_SC_FLT_OFF_MAC_SA)
138a868b486SRadu Pirea (NXP OSS) #define TX_SC_FLT_MAC_CFG(base)		((base) + TX_SC_FLT_OFF_MAC_CFG)
139a868b486SRadu Pirea (NXP OSS) 
140a868b486SRadu Pirea (NXP OSS) #define ADAPTER_EN	BIT(6)
141a868b486SRadu Pirea (NXP OSS) #define MACSEC_EN	BIT(5)
142a868b486SRadu Pirea (NXP OSS) 
14331a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INOV1HS			0x0140
14431a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INOV2HS			0x0144
14531a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INOD1HS			0x0148
14631a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INOD2HS			0x014C
14731a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSCIPUS			0x0150
14831a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSCIPDS			0x0154
14931a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSCIPLS			0x0158
15031a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXAN0INUSS		0x0160
15131a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXAN0IPUSS		0x0170
15231a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_IPOS		0x0194
15331a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_IPIS		0x01B0
15431a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_A_IPNVS		0x01B4
15531a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_IPOS		0x01D4
15631a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_IPIS		0x01F0
15731a99fc0SRadu Pirea (NXP OSS) #define MACSEC_RXSA_B_IPNVS		0x01F4
15831a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OPUS			0x021C
15931a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OPTLS			0x022C
16031a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OOP1HS			0x0240
16131a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OOP2HS			0x0244
16231a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OOE1HS			0x0248
16331a99fc0SRadu Pirea (NXP OSS) #define MACSEC_OOE2HS			0x024C
16431a99fc0SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_OPPS		0x028C
16531a99fc0SRadu Pirea (NXP OSS) #define MACSEC_TXSA_A_OPES		0x0290
16631a99fc0SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_OPPS		0x02CC
16731a99fc0SRadu Pirea (NXP OSS) #define MACSEC_TXSA_B_OPES		0x02D0
16831a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INPWTS			0x0630
16931a99fc0SRadu Pirea (NXP OSS) #define MACSEC_INPBTS			0x0638
17031a99fc0SRadu Pirea (NXP OSS) #define MACSEC_IPSNFS			0x063C
17131a99fc0SRadu Pirea (NXP OSS) 
172*dc1a0038SRadu Pirea (NXP OSS) #define TJA11XX_TLV_TX_NEEDED_HEADROOM	(32)
173*dc1a0038SRadu Pirea (NXP OSS) #define TJA11XX_TLV_NEEDED_TAILROOM	(0)
174*dc1a0038SRadu Pirea (NXP OSS) 
175*dc1a0038SRadu Pirea (NXP OSS) #define ETH_P_TJA11XX_TLV		(0x4e58)
176*dc1a0038SRadu Pirea (NXP OSS) 
177a868b486SRadu Pirea (NXP OSS) enum nxp_c45_sa_type {
178a868b486SRadu Pirea (NXP OSS) 	TX_SA,
179a868b486SRadu Pirea (NXP OSS) 	RX_SA,
180a868b486SRadu Pirea (NXP OSS) };
181a868b486SRadu Pirea (NXP OSS) 
182a868b486SRadu Pirea (NXP OSS) struct nxp_c45_sa {
183a868b486SRadu Pirea (NXP OSS) 	void *sa;
184a868b486SRadu Pirea (NXP OSS) 	const struct nxp_c45_sa_regs *regs;
185a868b486SRadu Pirea (NXP OSS) 	enum nxp_c45_sa_type type;
186a868b486SRadu Pirea (NXP OSS) 	bool is_key_a;
187a868b486SRadu Pirea (NXP OSS) 	u8 an;
188a868b486SRadu Pirea (NXP OSS) 	struct list_head list;
189a868b486SRadu Pirea (NXP OSS) };
190a868b486SRadu Pirea (NXP OSS) 
191a868b486SRadu Pirea (NXP OSS) struct nxp_c45_secy {
192a868b486SRadu Pirea (NXP OSS) 	struct macsec_secy *secy;
193a868b486SRadu Pirea (NXP OSS) 	struct macsec_rx_sc *rx_sc;
194a868b486SRadu Pirea (NXP OSS) 	struct list_head sa_list;
195a868b486SRadu Pirea (NXP OSS) 	int secy_id;
196a868b486SRadu Pirea (NXP OSS) 	bool rx_sc0_impl;
197a868b486SRadu Pirea (NXP OSS) 	struct list_head list;
198a868b486SRadu Pirea (NXP OSS) };
199a868b486SRadu Pirea (NXP OSS) 
200a868b486SRadu Pirea (NXP OSS) struct nxp_c45_macsec {
201a868b486SRadu Pirea (NXP OSS) 	struct list_head secy_list;
202a868b486SRadu Pirea (NXP OSS) 	DECLARE_BITMAP(secy_bitmap, TX_SC_MAX);
203a868b486SRadu Pirea (NXP OSS) 	DECLARE_BITMAP(tx_sc_bitmap, TX_SC_MAX);
204a868b486SRadu Pirea (NXP OSS) };
205a868b486SRadu Pirea (NXP OSS) 
206a868b486SRadu Pirea (NXP OSS) struct nxp_c45_sa_regs {
207a868b486SRadu Pirea (NXP OSS) 	u16 cs;
208a868b486SRadu Pirea (NXP OSS) 	u16 npn;
209a868b486SRadu Pirea (NXP OSS) 	u16 xnpn;
210a868b486SRadu Pirea (NXP OSS) 	u16 lnpn;
211a868b486SRadu Pirea (NXP OSS) 	u16 lxnpn;
212a868b486SRadu Pirea (NXP OSS) 	u16 ka;
213a868b486SRadu Pirea (NXP OSS) 	u16 ssci;
214a868b486SRadu Pirea (NXP OSS) 	u16 salt;
21531a99fc0SRadu Pirea (NXP OSS) 	u16 ipis;
21631a99fc0SRadu Pirea (NXP OSS) 	u16 ipnvs;
21731a99fc0SRadu Pirea (NXP OSS) 	u16 ipos;
21831a99fc0SRadu Pirea (NXP OSS) 	u16 opps;
21931a99fc0SRadu Pirea (NXP OSS) 	u16 opes;
220a868b486SRadu Pirea (NXP OSS) };
221a868b486SRadu Pirea (NXP OSS) 
222a868b486SRadu Pirea (NXP OSS) static const struct nxp_c45_sa_regs rx_sa_a_regs = {
223a868b486SRadu Pirea (NXP OSS) 	.cs	= MACSEC_RXSA_A_CS,
224a868b486SRadu Pirea (NXP OSS) 	.npn	= MACSEC_RXSA_A_NPN,
225a868b486SRadu Pirea (NXP OSS) 	.xnpn	= MACSEC_RXSA_A_XNPN,
226a868b486SRadu Pirea (NXP OSS) 	.lnpn	= MACSEC_RXSA_A_LNPN,
227a868b486SRadu Pirea (NXP OSS) 	.lxnpn	= MACSEC_RXSA_A_LXNPN,
228a868b486SRadu Pirea (NXP OSS) 	.ka	= MACSEC_RXSA_A_KA,
229a868b486SRadu Pirea (NXP OSS) 	.ssci	= MACSEC_RXSA_A_SSCI,
230a868b486SRadu Pirea (NXP OSS) 	.salt	= MACSEC_RXSA_A_SALT,
23131a99fc0SRadu Pirea (NXP OSS) 	.ipis	= MACSEC_RXSA_A_IPIS,
23231a99fc0SRadu Pirea (NXP OSS) 	.ipnvs	= MACSEC_RXSA_A_IPNVS,
23331a99fc0SRadu Pirea (NXP OSS) 	.ipos	= MACSEC_RXSA_A_IPOS,
234a868b486SRadu Pirea (NXP OSS) };
235a868b486SRadu Pirea (NXP OSS) 
236a868b486SRadu Pirea (NXP OSS) static const struct nxp_c45_sa_regs rx_sa_b_regs = {
237a868b486SRadu Pirea (NXP OSS) 	.cs	= MACSEC_RXSA_B_CS,
238a868b486SRadu Pirea (NXP OSS) 	.npn	= MACSEC_RXSA_B_NPN,
239a868b486SRadu Pirea (NXP OSS) 	.xnpn	= MACSEC_RXSA_B_XNPN,
240a868b486SRadu Pirea (NXP OSS) 	.lnpn	= MACSEC_RXSA_B_LNPN,
241a868b486SRadu Pirea (NXP OSS) 	.lxnpn	= MACSEC_RXSA_B_LXNPN,
242a868b486SRadu Pirea (NXP OSS) 	.ka	= MACSEC_RXSA_B_KA,
243a868b486SRadu Pirea (NXP OSS) 	.ssci	= MACSEC_RXSA_B_SSCI,
244a868b486SRadu Pirea (NXP OSS) 	.salt	= MACSEC_RXSA_B_SALT,
24531a99fc0SRadu Pirea (NXP OSS) 	.ipis	= MACSEC_RXSA_B_IPIS,
24631a99fc0SRadu Pirea (NXP OSS) 	.ipnvs	= MACSEC_RXSA_B_IPNVS,
24731a99fc0SRadu Pirea (NXP OSS) 	.ipos	= MACSEC_RXSA_B_IPOS,
248a868b486SRadu Pirea (NXP OSS) };
249a868b486SRadu Pirea (NXP OSS) 
250a868b486SRadu Pirea (NXP OSS) static const struct nxp_c45_sa_regs tx_sa_a_regs = {
251a868b486SRadu Pirea (NXP OSS) 	.cs	= MACSEC_TXSA_A_CS,
252a868b486SRadu Pirea (NXP OSS) 	.npn	= MACSEC_TXSA_A_NPN,
253a868b486SRadu Pirea (NXP OSS) 	.xnpn	= MACSEC_TXSA_A_XNPN,
254a868b486SRadu Pirea (NXP OSS) 	.ka	= MACSEC_TXSA_A_KA,
255a868b486SRadu Pirea (NXP OSS) 	.ssci	= MACSEC_TXSA_A_SSCI,
256a868b486SRadu Pirea (NXP OSS) 	.salt	= MACSEC_TXSA_A_SALT,
25731a99fc0SRadu Pirea (NXP OSS) 	.opps	= MACSEC_TXSA_A_OPPS,
25831a99fc0SRadu Pirea (NXP OSS) 	.opes	= MACSEC_TXSA_A_OPES,
259a868b486SRadu Pirea (NXP OSS) };
260a868b486SRadu Pirea (NXP OSS) 
261a868b486SRadu Pirea (NXP OSS) static const struct nxp_c45_sa_regs tx_sa_b_regs = {
262a868b486SRadu Pirea (NXP OSS) 	.cs	= MACSEC_TXSA_B_CS,
263a868b486SRadu Pirea (NXP OSS) 	.npn	= MACSEC_TXSA_B_NPN,
264a868b486SRadu Pirea (NXP OSS) 	.xnpn	= MACSEC_TXSA_B_XNPN,
265a868b486SRadu Pirea (NXP OSS) 	.ka	= MACSEC_TXSA_B_KA,
266a868b486SRadu Pirea (NXP OSS) 	.ssci	= MACSEC_TXSA_B_SSCI,
267a868b486SRadu Pirea (NXP OSS) 	.salt	= MACSEC_TXSA_B_SALT,
26831a99fc0SRadu Pirea (NXP OSS) 	.opps	= MACSEC_TXSA_B_OPPS,
26931a99fc0SRadu Pirea (NXP OSS) 	.opes	= MACSEC_TXSA_B_OPES,
270a868b486SRadu Pirea (NXP OSS) };
271a868b486SRadu Pirea (NXP OSS) 
272a868b486SRadu Pirea (NXP OSS) static const
nxp_c45_sa_regs_get(enum nxp_c45_sa_type sa_type,bool key_a)273a868b486SRadu Pirea (NXP OSS) struct nxp_c45_sa_regs *nxp_c45_sa_regs_get(enum nxp_c45_sa_type sa_type,
274a868b486SRadu Pirea (NXP OSS) 					    bool key_a)
275a868b486SRadu Pirea (NXP OSS) {
276a868b486SRadu Pirea (NXP OSS) 	if (sa_type == RX_SA)
277a868b486SRadu Pirea (NXP OSS) 		if (key_a)
278a868b486SRadu Pirea (NXP OSS) 			return &rx_sa_a_regs;
279a868b486SRadu Pirea (NXP OSS) 		else
280a868b486SRadu Pirea (NXP OSS) 			return &rx_sa_b_regs;
281a868b486SRadu Pirea (NXP OSS) 	else if (sa_type == TX_SA)
282a868b486SRadu Pirea (NXP OSS) 		if (key_a)
283a868b486SRadu Pirea (NXP OSS) 			return &tx_sa_a_regs;
284a868b486SRadu Pirea (NXP OSS) 		else
285a868b486SRadu Pirea (NXP OSS) 			return &tx_sa_b_regs;
286a868b486SRadu Pirea (NXP OSS) 	else
287a868b486SRadu Pirea (NXP OSS) 		return NULL;
288a868b486SRadu Pirea (NXP OSS) }
289a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_write(struct phy_device * phydev,u16 addr,u32 value)290a868b486SRadu Pirea (NXP OSS) static int nxp_c45_macsec_write(struct phy_device *phydev, u16 addr, u32 value)
291a868b486SRadu Pirea (NXP OSS) {
292a868b486SRadu Pirea (NXP OSS) 	u32 lvalue = value;
293a868b486SRadu Pirea (NXP OSS) 	u16 laddr;
294a868b486SRadu Pirea (NXP OSS) 	int ret;
295a868b486SRadu Pirea (NXP OSS) 
296a868b486SRadu Pirea (NXP OSS) 	WARN_ON_ONCE(addr % 4);
297a868b486SRadu Pirea (NXP OSS) 
298a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "write addr 0x%x value 0x%x\n", addr, value);
299a868b486SRadu Pirea (NXP OSS) 
300a868b486SRadu Pirea (NXP OSS) 	laddr = VEND1_MACSEC_BASE + addr / 2;
301a868b486SRadu Pirea (NXP OSS) 	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, laddr, lvalue);
302a868b486SRadu Pirea (NXP OSS) 	if (ret)
303a868b486SRadu Pirea (NXP OSS) 		return ret;
304a868b486SRadu Pirea (NXP OSS) 
305a868b486SRadu Pirea (NXP OSS) 	laddr += 1;
306a868b486SRadu Pirea (NXP OSS) 	lvalue >>= 16;
307a868b486SRadu Pirea (NXP OSS) 	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, laddr, lvalue);
308a868b486SRadu Pirea (NXP OSS) 
309a868b486SRadu Pirea (NXP OSS) 	return ret;
310a868b486SRadu Pirea (NXP OSS) }
311a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_read(struct phy_device * phydev,u16 addr,u32 * value)312a868b486SRadu Pirea (NXP OSS) static int nxp_c45_macsec_read(struct phy_device *phydev, u16 addr, u32 *value)
313a868b486SRadu Pirea (NXP OSS) {
314a868b486SRadu Pirea (NXP OSS) 	u32 lvalue;
315a868b486SRadu Pirea (NXP OSS) 	u16 laddr;
316a868b486SRadu Pirea (NXP OSS) 	int ret;
317a868b486SRadu Pirea (NXP OSS) 
318a868b486SRadu Pirea (NXP OSS) 	WARN_ON_ONCE(addr % 4);
319a868b486SRadu Pirea (NXP OSS) 
320a868b486SRadu Pirea (NXP OSS) 	laddr = VEND1_MACSEC_BASE + addr / 2;
321a868b486SRadu Pirea (NXP OSS) 	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, laddr);
322a868b486SRadu Pirea (NXP OSS) 	if (ret < 0)
323a868b486SRadu Pirea (NXP OSS) 		return ret;
324a868b486SRadu Pirea (NXP OSS) 
325a868b486SRadu Pirea (NXP OSS) 	laddr += 1;
326a868b486SRadu Pirea (NXP OSS) 	lvalue = (u32)ret & 0xffff;
327a868b486SRadu Pirea (NXP OSS) 	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, laddr);
328a868b486SRadu Pirea (NXP OSS) 	if (ret < 0)
329a868b486SRadu Pirea (NXP OSS) 		return ret;
330a868b486SRadu Pirea (NXP OSS) 
331a868b486SRadu Pirea (NXP OSS) 	lvalue |= (u32)ret << 16;
332a868b486SRadu Pirea (NXP OSS) 	*value = lvalue;
333a868b486SRadu Pirea (NXP OSS) 
334a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "read addr 0x%x value 0x%x\n", addr, *value);
335a868b486SRadu Pirea (NXP OSS) 
336a868b486SRadu Pirea (NXP OSS) 	return 0;
337a868b486SRadu Pirea (NXP OSS) }
338a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_read32_64(struct phy_device * phydev,u16 addr,u64 * value)33931a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_macsec_read32_64(struct phy_device *phydev, u16 addr,
34031a99fc0SRadu Pirea (NXP OSS) 				     u64 *value)
34131a99fc0SRadu Pirea (NXP OSS) {
34231a99fc0SRadu Pirea (NXP OSS) 	u32 lvalue;
34331a99fc0SRadu Pirea (NXP OSS) 
34431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, addr, &lvalue);
34531a99fc0SRadu Pirea (NXP OSS) 	*value = lvalue;
34631a99fc0SRadu Pirea (NXP OSS) }
34731a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_macsec_read64(struct phy_device * phydev,u16 addr,u64 * value)34831a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_macsec_read64(struct phy_device *phydev, u16 addr,
34931a99fc0SRadu Pirea (NXP OSS) 				  u64 *value)
35031a99fc0SRadu Pirea (NXP OSS) {
35131a99fc0SRadu Pirea (NXP OSS) 	u32 lvalue;
35231a99fc0SRadu Pirea (NXP OSS) 
35331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, addr, &lvalue);
35431a99fc0SRadu Pirea (NXP OSS) 	*value = (u64)lvalue << 32;
35531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, addr + 4, &lvalue);
35631a99fc0SRadu Pirea (NXP OSS) 	*value |= lvalue;
35731a99fc0SRadu Pirea (NXP OSS) }
35831a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_secy_irq_en(struct phy_device * phydev,struct nxp_c45_secy * phy_secy,bool en)359a868b486SRadu Pirea (NXP OSS) static void nxp_c45_secy_irq_en(struct phy_device *phydev,
360a868b486SRadu Pirea (NXP OSS) 				struct nxp_c45_secy *phy_secy, bool en)
361a868b486SRadu Pirea (NXP OSS) {
362a868b486SRadu Pirea (NXP OSS) 	u32 reg;
363a868b486SRadu Pirea (NXP OSS) 
364a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_EVER, &reg);
365a868b486SRadu Pirea (NXP OSS) 	if (en)
366a868b486SRadu Pirea (NXP OSS) 		reg |= TX_SC_BIT(phy_secy->secy_id);
367a868b486SRadu Pirea (NXP OSS) 	else
368a868b486SRadu Pirea (NXP OSS) 		reg &= ~TX_SC_BIT(phy_secy->secy_id);
369a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_EVER, reg);
370a868b486SRadu Pirea (NXP OSS) }
371a868b486SRadu Pirea (NXP OSS) 
nxp_c45_find_secy(struct list_head * secy_list,sci_t sci)372a868b486SRadu Pirea (NXP OSS) static struct nxp_c45_secy *nxp_c45_find_secy(struct list_head *secy_list,
373a868b486SRadu Pirea (NXP OSS) 					      sci_t sci)
374a868b486SRadu Pirea (NXP OSS) {
375a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *pos, *tmp;
376a868b486SRadu Pirea (NXP OSS) 
377a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, secy_list, list)
378a868b486SRadu Pirea (NXP OSS) 		if (pos->secy->sci == sci)
379a868b486SRadu Pirea (NXP OSS) 			return pos;
380a868b486SRadu Pirea (NXP OSS) 
381a868b486SRadu Pirea (NXP OSS) 	return ERR_PTR(-EINVAL);
382a868b486SRadu Pirea (NXP OSS) }
383a868b486SRadu Pirea (NXP OSS) 
384a868b486SRadu Pirea (NXP OSS) static struct
nxp_c45_find_secy_by_id(struct list_head * secy_list,int id)385a868b486SRadu Pirea (NXP OSS) nxp_c45_secy *nxp_c45_find_secy_by_id(struct list_head *secy_list,
386a868b486SRadu Pirea (NXP OSS) 				      int id)
387a868b486SRadu Pirea (NXP OSS) {
388a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *pos, *tmp;
389a868b486SRadu Pirea (NXP OSS) 
390a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, secy_list, list)
391a868b486SRadu Pirea (NXP OSS) 		if (pos->secy_id == id)
392a868b486SRadu Pirea (NXP OSS) 			return pos;
393a868b486SRadu Pirea (NXP OSS) 
394a868b486SRadu Pirea (NXP OSS) 	return ERR_PTR(-EINVAL);
395a868b486SRadu Pirea (NXP OSS) }
396a868b486SRadu Pirea (NXP OSS) 
nxp_c45_secy_free(struct nxp_c45_secy * phy_secy)397a868b486SRadu Pirea (NXP OSS) static void nxp_c45_secy_free(struct nxp_c45_secy *phy_secy)
398a868b486SRadu Pirea (NXP OSS) {
399a868b486SRadu Pirea (NXP OSS) 	list_del(&phy_secy->list);
400a868b486SRadu Pirea (NXP OSS) 	kfree(phy_secy);
401a868b486SRadu Pirea (NXP OSS) }
402a868b486SRadu Pirea (NXP OSS) 
nxp_c45_find_sa(struct list_head * sa_list,enum nxp_c45_sa_type sa_type,u8 an)403a868b486SRadu Pirea (NXP OSS) static struct nxp_c45_sa *nxp_c45_find_sa(struct list_head *sa_list,
404a868b486SRadu Pirea (NXP OSS) 					  enum nxp_c45_sa_type sa_type, u8 an)
405a868b486SRadu Pirea (NXP OSS) {
406a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
407a868b486SRadu Pirea (NXP OSS) 
408a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, sa_list, list)
409a868b486SRadu Pirea (NXP OSS) 		if (pos->an == an && pos->type == sa_type)
410a868b486SRadu Pirea (NXP OSS) 			return pos;
411a868b486SRadu Pirea (NXP OSS) 
412a868b486SRadu Pirea (NXP OSS) 	return ERR_PTR(-EINVAL);
413a868b486SRadu Pirea (NXP OSS) }
414a868b486SRadu Pirea (NXP OSS) 
nxp_c45_sa_alloc(struct list_head * sa_list,void * sa,enum nxp_c45_sa_type sa_type,u8 an)415a868b486SRadu Pirea (NXP OSS) static struct nxp_c45_sa *nxp_c45_sa_alloc(struct list_head *sa_list, void *sa,
416a868b486SRadu Pirea (NXP OSS) 					   enum nxp_c45_sa_type sa_type, u8 an)
417a868b486SRadu Pirea (NXP OSS) {
418a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *first = NULL, *pos, *tmp;
419a868b486SRadu Pirea (NXP OSS) 	int occurrences = 0;
420a868b486SRadu Pirea (NXP OSS) 
421a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, sa_list, list) {
422a868b486SRadu Pirea (NXP OSS) 		if (pos->type != sa_type)
423a868b486SRadu Pirea (NXP OSS) 			continue;
424a868b486SRadu Pirea (NXP OSS) 
425a868b486SRadu Pirea (NXP OSS) 		if (pos->an == an)
426a868b486SRadu Pirea (NXP OSS) 			return ERR_PTR(-EINVAL);
427a868b486SRadu Pirea (NXP OSS) 
428a868b486SRadu Pirea (NXP OSS) 		first = pos;
429a868b486SRadu Pirea (NXP OSS) 		occurrences++;
430a868b486SRadu Pirea (NXP OSS) 		if (occurrences >= 2)
431a868b486SRadu Pirea (NXP OSS) 			return ERR_PTR(-ENOSPC);
432a868b486SRadu Pirea (NXP OSS) 	}
433a868b486SRadu Pirea (NXP OSS) 
434a868b486SRadu Pirea (NXP OSS) 	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
435a868b486SRadu Pirea (NXP OSS) 	if (!tmp)
436a868b486SRadu Pirea (NXP OSS) 		return ERR_PTR(-ENOMEM);
437a868b486SRadu Pirea (NXP OSS) 
438a868b486SRadu Pirea (NXP OSS) 	if (first)
439a868b486SRadu Pirea (NXP OSS) 		tmp->is_key_a = !first->is_key_a;
440a868b486SRadu Pirea (NXP OSS) 	else
441a868b486SRadu Pirea (NXP OSS) 		tmp->is_key_a = true;
442a868b486SRadu Pirea (NXP OSS) 
443a868b486SRadu Pirea (NXP OSS) 	tmp->sa = sa;
444a868b486SRadu Pirea (NXP OSS) 	tmp->type = sa_type;
445a868b486SRadu Pirea (NXP OSS) 	tmp->an = an;
446a868b486SRadu Pirea (NXP OSS) 	tmp->regs = nxp_c45_sa_regs_get(tmp->type, tmp->is_key_a);
447a868b486SRadu Pirea (NXP OSS) 	list_add_tail(&tmp->list, sa_list);
448a868b486SRadu Pirea (NXP OSS) 
449a868b486SRadu Pirea (NXP OSS) 	return tmp;
450a868b486SRadu Pirea (NXP OSS) }
451a868b486SRadu Pirea (NXP OSS) 
nxp_c45_sa_free(struct nxp_c45_sa * sa)452a868b486SRadu Pirea (NXP OSS) static void nxp_c45_sa_free(struct nxp_c45_sa *sa)
453a868b486SRadu Pirea (NXP OSS) {
454a868b486SRadu Pirea (NXP OSS) 	list_del(&sa->list);
455a868b486SRadu Pirea (NXP OSS) 	kfree(sa);
456a868b486SRadu Pirea (NXP OSS) }
457a868b486SRadu Pirea (NXP OSS) 
nxp_c45_sa_list_free(struct list_head * sa_list)458a868b486SRadu Pirea (NXP OSS) static void nxp_c45_sa_list_free(struct list_head *sa_list)
459a868b486SRadu Pirea (NXP OSS) {
460a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
461a868b486SRadu Pirea (NXP OSS) 
462a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, sa_list, list)
463a868b486SRadu Pirea (NXP OSS) 		nxp_c45_sa_free(pos);
464a868b486SRadu Pirea (NXP OSS) }
465a868b486SRadu Pirea (NXP OSS) 
nxp_c45_sa_set_pn(struct phy_device * phydev,struct nxp_c45_sa * sa,u64 pn,u32 replay_window)466a868b486SRadu Pirea (NXP OSS) static void nxp_c45_sa_set_pn(struct phy_device *phydev,
467a868b486SRadu Pirea (NXP OSS) 			      struct nxp_c45_sa *sa, u64 pn,
468a868b486SRadu Pirea (NXP OSS) 			      u32 replay_window)
469a868b486SRadu Pirea (NXP OSS) {
470a868b486SRadu Pirea (NXP OSS) 	const struct nxp_c45_sa_regs *sa_regs = sa->regs;
471a868b486SRadu Pirea (NXP OSS) 	pn_t npn = {.full64 = pn};
472a868b486SRadu Pirea (NXP OSS) 	pn_t lnpn;
473a868b486SRadu Pirea (NXP OSS) 
474a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->npn, npn.lower);
475a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->xnpn, npn.upper);
476a868b486SRadu Pirea (NXP OSS) 	if (sa->type != RX_SA)
477a868b486SRadu Pirea (NXP OSS) 		return;
478a868b486SRadu Pirea (NXP OSS) 
479a868b486SRadu Pirea (NXP OSS) 	if (pn > replay_window)
480a868b486SRadu Pirea (NXP OSS) 		lnpn.full64 = pn - replay_window;
481a868b486SRadu Pirea (NXP OSS) 	else
482a868b486SRadu Pirea (NXP OSS) 		lnpn.full64 = 1;
483a868b486SRadu Pirea (NXP OSS) 
484a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->lnpn, lnpn.lower);
485a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->lxnpn, lnpn.upper);
486a868b486SRadu Pirea (NXP OSS) }
487a868b486SRadu Pirea (NXP OSS) 
nxp_c45_sa_set_key(struct macsec_context * ctx,const struct nxp_c45_sa_regs * sa_regs,u8 * salt,ssci_t ssci)488a868b486SRadu Pirea (NXP OSS) static void nxp_c45_sa_set_key(struct macsec_context *ctx,
489a868b486SRadu Pirea (NXP OSS) 			       const struct nxp_c45_sa_regs *sa_regs,
490a868b486SRadu Pirea (NXP OSS) 			       u8 *salt, ssci_t ssci)
491a868b486SRadu Pirea (NXP OSS) {
492a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
493a868b486SRadu Pirea (NXP OSS) 	u32 key_size = ctx->secy->key_len / 4;
494a868b486SRadu Pirea (NXP OSS) 	u32 salt_size = MACSEC_SALT_LEN / 4;
495a868b486SRadu Pirea (NXP OSS) 	u32 *key_u32 = (u32 *)ctx->sa.key;
496a868b486SRadu Pirea (NXP OSS) 	u32 *salt_u32 = (u32 *)salt;
497a868b486SRadu Pirea (NXP OSS) 	u32 reg, value;
498a868b486SRadu Pirea (NXP OSS) 	int i;
499a868b486SRadu Pirea (NXP OSS) 
500a868b486SRadu Pirea (NXP OSS) 	for (i = 0; i < key_size; i++) {
501a868b486SRadu Pirea (NXP OSS) 		reg = sa_regs->ka + i * 4;
502a868b486SRadu Pirea (NXP OSS) 		value = (__force u32)cpu_to_be32(key_u32[i]);
503a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, reg, value);
504a868b486SRadu Pirea (NXP OSS) 	}
505a868b486SRadu Pirea (NXP OSS) 
506a868b486SRadu Pirea (NXP OSS) 	if (ctx->secy->xpn) {
507a868b486SRadu Pirea (NXP OSS) 		for (i = 0; i < salt_size; i++) {
508a868b486SRadu Pirea (NXP OSS) 			reg = sa_regs->salt + (2 - i) * 4;
509a868b486SRadu Pirea (NXP OSS) 			value = (__force u32)cpu_to_be32(salt_u32[i]);
510a868b486SRadu Pirea (NXP OSS) 			nxp_c45_macsec_write(phydev, reg, value);
511a868b486SRadu Pirea (NXP OSS) 		}
512a868b486SRadu Pirea (NXP OSS) 
513a868b486SRadu Pirea (NXP OSS) 		value = (__force u32)cpu_to_be32((__force u32)ssci);
514a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, sa_regs->ssci, value);
515a868b486SRadu Pirea (NXP OSS) 	}
516a868b486SRadu Pirea (NXP OSS) 
517a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->cs, MACSEC_SA_CS_A);
518a868b486SRadu Pirea (NXP OSS) }
519a868b486SRadu Pirea (NXP OSS) 
nxp_c45_rx_sa_clear_stats(struct phy_device * phydev,struct nxp_c45_sa * sa)52031a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_rx_sa_clear_stats(struct phy_device *phydev,
52131a99fc0SRadu Pirea (NXP OSS) 				      struct nxp_c45_sa *sa)
52231a99fc0SRadu Pirea (NXP OSS) {
52331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa->regs->ipis, 0);
52431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa->regs->ipnvs, 0);
52531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa->regs->ipos, 0);
52631a99fc0SRadu Pirea (NXP OSS) 
52731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXAN0INUSS + sa->an * 4, 0);
52831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXAN0IPUSS + sa->an * 4, 0);
52931a99fc0SRadu Pirea (NXP OSS) }
53031a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_rx_sa_read_stats(struct phy_device * phydev,struct nxp_c45_sa * sa,struct macsec_rx_sa_stats * stats)53131a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_rx_sa_read_stats(struct phy_device *phydev,
53231a99fc0SRadu Pirea (NXP OSS) 				     struct nxp_c45_sa *sa,
53331a99fc0SRadu Pirea (NXP OSS) 				     struct macsec_rx_sa_stats *stats)
53431a99fc0SRadu Pirea (NXP OSS) {
53531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, sa->regs->ipis, &stats->InPktsInvalid);
53631a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, sa->regs->ipnvs, &stats->InPktsNotValid);
53731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, sa->regs->ipos, &stats->InPktsOK);
53831a99fc0SRadu Pirea (NXP OSS) }
53931a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_tx_sa_clear_stats(struct phy_device * phydev,struct nxp_c45_sa * sa)54031a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_tx_sa_clear_stats(struct phy_device *phydev,
54131a99fc0SRadu Pirea (NXP OSS) 				      struct nxp_c45_sa *sa)
54231a99fc0SRadu Pirea (NXP OSS) {
54331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa->regs->opps, 0);
54431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa->regs->opes, 0);
54531a99fc0SRadu Pirea (NXP OSS) }
54631a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_tx_sa_read_stats(struct phy_device * phydev,struct nxp_c45_sa * sa,struct macsec_tx_sa_stats * stats)54731a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_tx_sa_read_stats(struct phy_device *phydev,
54831a99fc0SRadu Pirea (NXP OSS) 				     struct nxp_c45_sa *sa,
54931a99fc0SRadu Pirea (NXP OSS) 				     struct macsec_tx_sa_stats *stats)
55031a99fc0SRadu Pirea (NXP OSS) {
55131a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, sa->regs->opps, &stats->OutPktsProtected);
55231a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, sa->regs->opes, &stats->OutPktsEncrypted);
55331a99fc0SRadu Pirea (NXP OSS) }
55431a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_rx_sa_update(struct phy_device * phydev,struct nxp_c45_sa * sa,bool en)555a868b486SRadu Pirea (NXP OSS) static void nxp_c45_rx_sa_update(struct phy_device *phydev,
556a868b486SRadu Pirea (NXP OSS) 				 struct nxp_c45_sa *sa, bool en)
557a868b486SRadu Pirea (NXP OSS) {
558a868b486SRadu Pirea (NXP OSS) 	const struct nxp_c45_sa_regs *sa_regs = sa->regs;
559a868b486SRadu Pirea (NXP OSS) 	u32 cfg;
560a868b486SRadu Pirea (NXP OSS) 
561a868b486SRadu Pirea (NXP OSS) 	cfg = sa->an << MACSEC_RXSA_CS_AN_OFF;
562a868b486SRadu Pirea (NXP OSS) 	cfg |= en ? MACSEC_RXSA_CS_EN : 0;
563a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sa_regs->cs, cfg);
564a868b486SRadu Pirea (NXP OSS) }
565a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sa_update(struct phy_device * phydev,struct nxp_c45_sa * sa,bool en)566a868b486SRadu Pirea (NXP OSS) static void nxp_c45_tx_sa_update(struct phy_device *phydev,
567a868b486SRadu Pirea (NXP OSS) 				 struct nxp_c45_sa *sa, bool en)
568a868b486SRadu Pirea (NXP OSS) {
569a868b486SRadu Pirea (NXP OSS) 	u32 cfg = 0;
570a868b486SRadu Pirea (NXP OSS) 
571a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_TXSC_CFG, &cfg);
572a868b486SRadu Pirea (NXP OSS) 
573a868b486SRadu Pirea (NXP OSS) 	cfg &= ~MACSEC_TXSC_CFG_AN_MASK;
574a868b486SRadu Pirea (NXP OSS) 	cfg |= sa->an << MACSEC_TXSC_CFG_AN_OFF;
575a868b486SRadu Pirea (NXP OSS) 
576a868b486SRadu Pirea (NXP OSS) 	if (sa->is_key_a)
577a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_ASA;
578a868b486SRadu Pirea (NXP OSS) 	else
579a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_ASA;
580a868b486SRadu Pirea (NXP OSS) 
581a868b486SRadu Pirea (NXP OSS) 	if (en)
582a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_SCE;
583a868b486SRadu Pirea (NXP OSS) 	else
584a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_SCE;
585a868b486SRadu Pirea (NXP OSS) 
586a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_TXSC_CFG, cfg);
587a868b486SRadu Pirea (NXP OSS) }
588a868b486SRadu Pirea (NXP OSS) 
nxp_c45_set_sci(struct phy_device * phydev,u16 sci_base_addr,sci_t sci)589a868b486SRadu Pirea (NXP OSS) static void nxp_c45_set_sci(struct phy_device *phydev, u16 sci_base_addr,
590a868b486SRadu Pirea (NXP OSS) 			    sci_t sci)
591a868b486SRadu Pirea (NXP OSS) {
592a868b486SRadu Pirea (NXP OSS) 	u64 lsci = sci_to_cpu(sci);
593a868b486SRadu Pirea (NXP OSS) 
594a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sci_base_addr, lsci >> 32);
595a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, sci_base_addr + 4, lsci);
596a868b486SRadu Pirea (NXP OSS) }
597a868b486SRadu Pirea (NXP OSS) 
nxp_c45_port_is_1(sci_t sci)598a868b486SRadu Pirea (NXP OSS) static bool nxp_c45_port_is_1(sci_t sci)
599a868b486SRadu Pirea (NXP OSS) {
600a868b486SRadu Pirea (NXP OSS) 	u16 port = sci_to_cpu(sci);
601a868b486SRadu Pirea (NXP OSS) 
602a868b486SRadu Pirea (NXP OSS) 	return port == 1;
603a868b486SRadu Pirea (NXP OSS) }
604a868b486SRadu Pirea (NXP OSS) 
nxp_c45_select_secy(struct phy_device * phydev,u8 id)605a868b486SRadu Pirea (NXP OSS) static void nxp_c45_select_secy(struct phy_device *phydev, u8 id)
606a868b486SRadu Pirea (NXP OSS) {
607a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSCA, id);
608a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSCKA, id);
609a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_TXSCA, id);
610a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_TXSCKA, id);
611a868b486SRadu Pirea (NXP OSS) }
612a868b486SRadu Pirea (NXP OSS) 
nxp_c45_secy_valid(struct nxp_c45_secy * phy_secy,bool can_rx_sc0_impl)613a868b486SRadu Pirea (NXP OSS) static bool nxp_c45_secy_valid(struct nxp_c45_secy *phy_secy,
614a868b486SRadu Pirea (NXP OSS) 			       bool can_rx_sc0_impl)
615a868b486SRadu Pirea (NXP OSS) {
616a868b486SRadu Pirea (NXP OSS) 	bool end_station = phy_secy->secy->tx_sc.end_station;
617a868b486SRadu Pirea (NXP OSS) 	bool scb = phy_secy->secy->tx_sc.scb;
618a868b486SRadu Pirea (NXP OSS) 
619a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc0_impl = false;
620a868b486SRadu Pirea (NXP OSS) 
621a868b486SRadu Pirea (NXP OSS) 	if (end_station) {
622a868b486SRadu Pirea (NXP OSS) 		if (!nxp_c45_port_is_1(phy_secy->secy->sci))
623a868b486SRadu Pirea (NXP OSS) 			return false;
624a868b486SRadu Pirea (NXP OSS) 		if (!phy_secy->rx_sc)
625a868b486SRadu Pirea (NXP OSS) 			return true;
626a868b486SRadu Pirea (NXP OSS) 		return nxp_c45_port_is_1(phy_secy->rx_sc->sci);
627a868b486SRadu Pirea (NXP OSS) 	}
628a868b486SRadu Pirea (NXP OSS) 
629a868b486SRadu Pirea (NXP OSS) 	if (scb)
630a868b486SRadu Pirea (NXP OSS) 		return false;
631a868b486SRadu Pirea (NXP OSS) 
632a868b486SRadu Pirea (NXP OSS) 	if (!can_rx_sc0_impl)
633a868b486SRadu Pirea (NXP OSS) 		return false;
634a868b486SRadu Pirea (NXP OSS) 
635a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy_id != 0)
636a868b486SRadu Pirea (NXP OSS) 		return false;
637a868b486SRadu Pirea (NXP OSS) 
638a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc0_impl = true;
639a868b486SRadu Pirea (NXP OSS) 
640a868b486SRadu Pirea (NXP OSS) 	return true;
641a868b486SRadu Pirea (NXP OSS) }
642a868b486SRadu Pirea (NXP OSS) 
nxp_c45_rx_sc0_impl(struct nxp_c45_secy * phy_secy)643a868b486SRadu Pirea (NXP OSS) static bool nxp_c45_rx_sc0_impl(struct nxp_c45_secy *phy_secy)
644a868b486SRadu Pirea (NXP OSS) {
645a868b486SRadu Pirea (NXP OSS) 	bool end_station = phy_secy->secy->tx_sc.end_station;
646a868b486SRadu Pirea (NXP OSS) 	bool send_sci = phy_secy->secy->tx_sc.send_sci;
647a868b486SRadu Pirea (NXP OSS) 	bool scb = phy_secy->secy->tx_sc.scb;
648a868b486SRadu Pirea (NXP OSS) 
649a868b486SRadu Pirea (NXP OSS) 	return !end_station && !send_sci && !scb;
650a868b486SRadu Pirea (NXP OSS) }
651a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mac_addr_free(struct macsec_context * ctx)652a868b486SRadu Pirea (NXP OSS) static bool nxp_c45_mac_addr_free(struct macsec_context *ctx)
653a868b486SRadu Pirea (NXP OSS) {
654a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = ctx->phydev->priv;
655a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *pos, *tmp;
656a868b486SRadu Pirea (NXP OSS) 
657a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &priv->macsec->secy_list, list) {
658a868b486SRadu Pirea (NXP OSS) 		if (pos->secy == ctx->secy)
659a868b486SRadu Pirea (NXP OSS) 			continue;
660a868b486SRadu Pirea (NXP OSS) 
661a868b486SRadu Pirea (NXP OSS) 		if (memcmp(pos->secy->netdev->dev_addr,
662a868b486SRadu Pirea (NXP OSS) 			   ctx->secy->netdev->dev_addr, ETH_ALEN) == 0)
663a868b486SRadu Pirea (NXP OSS) 			return false;
664a868b486SRadu Pirea (NXP OSS) 	}
665a868b486SRadu Pirea (NXP OSS) 
666a868b486SRadu Pirea (NXP OSS) 	return true;
667a868b486SRadu Pirea (NXP OSS) }
668a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sc_en_flt(struct phy_device * phydev,int secy_id,bool en)669a868b486SRadu Pirea (NXP OSS) static void nxp_c45_tx_sc_en_flt(struct phy_device *phydev, int secy_id,
670a868b486SRadu Pirea (NXP OSS) 				 bool en)
671a868b486SRadu Pirea (NXP OSS) {
672a868b486SRadu Pirea (NXP OSS) 	u32 tx_flt_base = TX_FLT_BASE(secy_id);
673a868b486SRadu Pirea (NXP OSS) 	u32 reg = 0;
674a868b486SRadu Pirea (NXP OSS) 
675a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, TX_SC_FLT_MAC_CFG(tx_flt_base), &reg);
676a868b486SRadu Pirea (NXP OSS) 	if (en)
677a868b486SRadu Pirea (NXP OSS) 		reg |= TX_SC_FLT_EN;
678a868b486SRadu Pirea (NXP OSS) 	else
679a868b486SRadu Pirea (NXP OSS) 		reg &= ~TX_SC_FLT_EN;
680a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, TX_SC_FLT_MAC_CFG(tx_flt_base), reg);
681a868b486SRadu Pirea (NXP OSS) }
682a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sc_set_flt(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)683a868b486SRadu Pirea (NXP OSS) static void nxp_c45_tx_sc_set_flt(struct phy_device *phydev,
684a868b486SRadu Pirea (NXP OSS) 				  struct nxp_c45_secy *phy_secy)
685a868b486SRadu Pirea (NXP OSS) {
686a868b486SRadu Pirea (NXP OSS) 	const u8 *dev_addr = phy_secy->secy->netdev->dev_addr;
687a868b486SRadu Pirea (NXP OSS) 	u32 tx_flt_base = TX_FLT_BASE(phy_secy->secy_id);
688a868b486SRadu Pirea (NXP OSS) 	u32 reg;
689a868b486SRadu Pirea (NXP OSS) 
690a868b486SRadu Pirea (NXP OSS) 	reg = dev_addr[0] << 8 | dev_addr[1];
691a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, TX_SC_FLT_MAC_DA_SA(tx_flt_base), reg);
692a868b486SRadu Pirea (NXP OSS) 	reg = dev_addr[5] | dev_addr[4] << 8 | dev_addr[3] << 16 |
693a868b486SRadu Pirea (NXP OSS) 		dev_addr[2] << 24;
694a868b486SRadu Pirea (NXP OSS) 
695a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, TX_SC_FLT_MAC_SA(tx_flt_base), reg);
696a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, TX_SC_FLT_MAC_CFG(tx_flt_base), &reg);
697a868b486SRadu Pirea (NXP OSS) 	reg &= TX_SC_FLT_EN;
698a868b486SRadu Pirea (NXP OSS) 	reg |= TX_SC_FLT_BY_SA | phy_secy->secy_id;
699a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, TX_SC_FLT_MAC_CFG(tx_flt_base), reg);
700a868b486SRadu Pirea (NXP OSS) }
701a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sc_update(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)702a868b486SRadu Pirea (NXP OSS) static void nxp_c45_tx_sc_update(struct phy_device *phydev,
703a868b486SRadu Pirea (NXP OSS) 				 struct nxp_c45_secy *phy_secy)
704a868b486SRadu Pirea (NXP OSS) {
705a868b486SRadu Pirea (NXP OSS) 	u32 cfg = 0;
706a868b486SRadu Pirea (NXP OSS) 
707a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_TXSC_CFG, &cfg);
708a868b486SRadu Pirea (NXP OSS) 
709a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "XPN %s\n", phy_secy->secy->xpn ? "on" : "off");
710a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->xpn)
711a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_XPN;
712a868b486SRadu Pirea (NXP OSS) 	else
713a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_XPN;
714a868b486SRadu Pirea (NXP OSS) 
715a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "key len %u\n", phy_secy->secy->key_len);
716a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->key_len == 32)
717a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_AES_256;
718a868b486SRadu Pirea (NXP OSS) 	else
719a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_AES_256;
720a868b486SRadu Pirea (NXP OSS) 
721a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "encryption %s\n",
722a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->tx_sc.encrypt ? "on" : "off");
723a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->tx_sc.encrypt)
724a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_ENCRYPT;
725a868b486SRadu Pirea (NXP OSS) 	else
726a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_ENCRYPT;
727a868b486SRadu Pirea (NXP OSS) 
728a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "protect frames %s\n",
729a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->protect_frames ? "on" : "off");
730a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->protect_frames)
731a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_PROTECT;
732a868b486SRadu Pirea (NXP OSS) 	else
733a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_PROTECT;
734a868b486SRadu Pirea (NXP OSS) 
735a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "send sci %s\n",
736a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->tx_sc.send_sci ? "on" : "off");
737a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->tx_sc.send_sci)
738a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_SEND_SCI;
739a868b486SRadu Pirea (NXP OSS) 	else
740a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_SEND_SCI;
741a868b486SRadu Pirea (NXP OSS) 
742a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "end station %s\n",
743a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->tx_sc.end_station ? "on" : "off");
744a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->tx_sc.end_station)
745a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_END_STATION;
746a868b486SRadu Pirea (NXP OSS) 	else
747a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_END_STATION;
748a868b486SRadu Pirea (NXP OSS) 
749a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "scb %s\n",
750a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->tx_sc.scb ? "on" : "off");
751a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->tx_sc.scb)
752a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_TXSC_CFG_SCB;
753a868b486SRadu Pirea (NXP OSS) 	else
754a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_TXSC_CFG_SCB;
755a868b486SRadu Pirea (NXP OSS) 
756a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_TXSC_CFG, cfg);
757a868b486SRadu Pirea (NXP OSS) }
758a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sc_clear_stats(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)75931a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_tx_sc_clear_stats(struct phy_device *phydev,
76031a99fc0SRadu Pirea (NXP OSS) 				      struct nxp_c45_secy *phy_secy)
76131a99fc0SRadu Pirea (NXP OSS) {
76231a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
76331a99fc0SRadu Pirea (NXP OSS) 
76431a99fc0SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &phy_secy->sa_list, list)
76531a99fc0SRadu Pirea (NXP OSS) 		if (pos->type == TX_SA)
76631a99fc0SRadu Pirea (NXP OSS) 			nxp_c45_tx_sa_clear_stats(phydev, pos);
76731a99fc0SRadu Pirea (NXP OSS) 
76831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OPUS, 0);
76931a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OPTLS, 0);
77031a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OOP1HS, 0);
77131a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OOP2HS, 0);
77231a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OOE1HS, 0);
77331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_OOE2HS, 0);
77431a99fc0SRadu Pirea (NXP OSS) }
77531a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_set_rx_sc0_impl(struct phy_device * phydev,bool enable)776a868b486SRadu Pirea (NXP OSS) static void nxp_c45_set_rx_sc0_impl(struct phy_device *phydev,
777a868b486SRadu Pirea (NXP OSS) 				    bool enable)
778a868b486SRadu Pirea (NXP OSS) {
779a868b486SRadu Pirea (NXP OSS) 	u32 reg = 0;
780a868b486SRadu Pirea (NXP OSS) 
781a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_CFG, &reg);
782a868b486SRadu Pirea (NXP OSS) 	if (enable)
783a868b486SRadu Pirea (NXP OSS) 		reg |= MACSEC_CFG_S0I;
784a868b486SRadu Pirea (NXP OSS) 	else
785a868b486SRadu Pirea (NXP OSS) 		reg &= ~MACSEC_CFG_S0I;
786a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_CFG, reg);
787a868b486SRadu Pirea (NXP OSS) }
788a868b486SRadu Pirea (NXP OSS) 
nxp_c45_is_rx_sc0_impl(struct list_head * secy_list)789a868b486SRadu Pirea (NXP OSS) static bool nxp_c45_is_rx_sc0_impl(struct list_head *secy_list)
790a868b486SRadu Pirea (NXP OSS) {
791a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *pos, *tmp;
792a868b486SRadu Pirea (NXP OSS) 
793a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, secy_list, list)
794a868b486SRadu Pirea (NXP OSS) 		if (pos->rx_sc0_impl)
795a868b486SRadu Pirea (NXP OSS) 			return pos->rx_sc0_impl;
796a868b486SRadu Pirea (NXP OSS) 
797a868b486SRadu Pirea (NXP OSS) 	return false;
798a868b486SRadu Pirea (NXP OSS) }
799a868b486SRadu Pirea (NXP OSS) 
nxp_c45_rx_sc_en(struct phy_device * phydev,struct macsec_rx_sc * rx_sc,bool en)800a868b486SRadu Pirea (NXP OSS) static void nxp_c45_rx_sc_en(struct phy_device *phydev,
801a868b486SRadu Pirea (NXP OSS) 			     struct macsec_rx_sc *rx_sc, bool en)
802a868b486SRadu Pirea (NXP OSS) {
803a868b486SRadu Pirea (NXP OSS) 	u32 reg = 0;
804a868b486SRadu Pirea (NXP OSS) 
805a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_RXSC_CFG, &reg);
806a868b486SRadu Pirea (NXP OSS) 	if (rx_sc->active && en)
807a868b486SRadu Pirea (NXP OSS) 		reg |= MACSEC_RXSC_CFG_SCI_EN;
808a868b486SRadu Pirea (NXP OSS) 	else
809a868b486SRadu Pirea (NXP OSS) 		reg &= ~MACSEC_RXSC_CFG_SCI_EN;
810a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSC_CFG, reg);
811a868b486SRadu Pirea (NXP OSS) }
812a868b486SRadu Pirea (NXP OSS) 
nxp_c45_rx_sc_update(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)813a868b486SRadu Pirea (NXP OSS) static void nxp_c45_rx_sc_update(struct phy_device *phydev,
814a868b486SRadu Pirea (NXP OSS) 				 struct nxp_c45_secy *phy_secy)
815a868b486SRadu Pirea (NXP OSS) {
816a868b486SRadu Pirea (NXP OSS) 	struct macsec_rx_sc *rx_sc = phy_secy->rx_sc;
817a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
818a868b486SRadu Pirea (NXP OSS) 	u32 cfg = 0;
819a868b486SRadu Pirea (NXP OSS) 
820a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_RXSC_CFG, &cfg);
821a868b486SRadu Pirea (NXP OSS) 	cfg &= ~MACSEC_RXSC_CFG_VF_MASK;
822a868b486SRadu Pirea (NXP OSS) 	cfg = phy_secy->secy->validate_frames << MACSEC_RXSC_CFG_VF_OFF;
823a868b486SRadu Pirea (NXP OSS) 
824a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "validate frames %u\n",
825a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->validate_frames);
826a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "replay_protect %s window %u\n",
827a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->replay_protect ? "on" : "off",
828a868b486SRadu Pirea (NXP OSS) 		   phy_secy->secy->replay_window);
829a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->replay_protect) {
830a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_RXSC_CFG_RP;
831a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, MACSEC_RPW,
832a868b486SRadu Pirea (NXP OSS) 				     phy_secy->secy->replay_window);
833a868b486SRadu Pirea (NXP OSS) 	} else {
834a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_RXSC_CFG_RP;
835a868b486SRadu Pirea (NXP OSS) 	}
836a868b486SRadu Pirea (NXP OSS) 
837a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "rx_sc->active %s\n",
838a868b486SRadu Pirea (NXP OSS) 		   rx_sc->active ? "on" : "off");
839a868b486SRadu Pirea (NXP OSS) 	if (rx_sc->active &&
840a868b486SRadu Pirea (NXP OSS) 	    test_bit(phy_secy->secy_id, priv->macsec->secy_bitmap))
841a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_RXSC_CFG_SCI_EN;
842a868b486SRadu Pirea (NXP OSS) 	else
843a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_RXSC_CFG_SCI_EN;
844a868b486SRadu Pirea (NXP OSS) 
845a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "key len %u\n", phy_secy->secy->key_len);
846a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->key_len == 32)
847a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_RXSC_CFG_AES_256;
848a868b486SRadu Pirea (NXP OSS) 	else
849a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_RXSC_CFG_AES_256;
850a868b486SRadu Pirea (NXP OSS) 
851a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "XPN %s\n", phy_secy->secy->xpn ? "on" : "off");
852a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->xpn)
853a868b486SRadu Pirea (NXP OSS) 		cfg |= MACSEC_RXSC_CFG_XPN;
854a868b486SRadu Pirea (NXP OSS) 	else
855a868b486SRadu Pirea (NXP OSS) 		cfg &= ~MACSEC_RXSC_CFG_XPN;
856a868b486SRadu Pirea (NXP OSS) 
857a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSC_CFG, cfg);
858a868b486SRadu Pirea (NXP OSS) }
859a868b486SRadu Pirea (NXP OSS) 
nxp_c45_rx_sc_clear_stats(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)86031a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_rx_sc_clear_stats(struct phy_device *phydev,
86131a99fc0SRadu Pirea (NXP OSS) 				      struct nxp_c45_secy *phy_secy)
86231a99fc0SRadu Pirea (NXP OSS) {
86331a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
86431a99fc0SRadu Pirea (NXP OSS) 	int i;
86531a99fc0SRadu Pirea (NXP OSS) 
86631a99fc0SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &phy_secy->sa_list, list)
86731a99fc0SRadu Pirea (NXP OSS) 		if (pos->type == RX_SA)
86831a99fc0SRadu Pirea (NXP OSS) 			nxp_c45_rx_sa_clear_stats(phydev, pos);
86931a99fc0SRadu Pirea (NXP OSS) 
87031a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INOD1HS, 0);
87131a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INOD2HS, 0);
87231a99fc0SRadu Pirea (NXP OSS) 
87331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INOV1HS, 0);
87431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INOV2HS, 0);
87531a99fc0SRadu Pirea (NXP OSS) 
87631a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSCIPDS, 0);
87731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSCIPLS, 0);
87831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSCIPUS, 0);
87931a99fc0SRadu Pirea (NXP OSS) 
88031a99fc0SRadu Pirea (NXP OSS) 	for (i = 0; i < MACSEC_NUM_AN; i++) {
88131a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, MACSEC_RXAN0INUSS + i * 4, 0);
88231a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, MACSEC_RXAN0IPUSS + i * 4, 0);
88331a99fc0SRadu Pirea (NXP OSS) 	}
88431a99fc0SRadu Pirea (NXP OSS) }
88531a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_rx_sc_del(struct phy_device * phydev,struct nxp_c45_secy * phy_secy)886a868b486SRadu Pirea (NXP OSS) static void nxp_c45_rx_sc_del(struct phy_device *phydev,
887a868b486SRadu Pirea (NXP OSS) 			      struct nxp_c45_secy *phy_secy)
888a868b486SRadu Pirea (NXP OSS) {
889a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
890a868b486SRadu Pirea (NXP OSS) 
891a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RXSC_CFG, 0);
892a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_RPW, 0);
893a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_sci(phydev, MACSEC_RXSC_SCI_1H, 0);
894a868b486SRadu Pirea (NXP OSS) 
89531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_rx_sc_clear_stats(phydev, phy_secy);
89631a99fc0SRadu Pirea (NXP OSS) 
897a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &phy_secy->sa_list, list) {
898a868b486SRadu Pirea (NXP OSS) 		if (pos->type == RX_SA) {
899a868b486SRadu Pirea (NXP OSS) 			nxp_c45_rx_sa_update(phydev, pos, false);
900a868b486SRadu Pirea (NXP OSS) 			nxp_c45_sa_free(pos);
901a868b486SRadu Pirea (NXP OSS) 		}
902a868b486SRadu Pirea (NXP OSS) 	}
903a868b486SRadu Pirea (NXP OSS) }
904a868b486SRadu Pirea (NXP OSS) 
nxp_c45_clear_global_stats(struct phy_device * phydev)90531a99fc0SRadu Pirea (NXP OSS) static void nxp_c45_clear_global_stats(struct phy_device *phydev)
90631a99fc0SRadu Pirea (NXP OSS) {
90731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INPBTS, 0);
90831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_INPWTS, 0);
90931a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_IPSNFS, 0);
91031a99fc0SRadu Pirea (NXP OSS) }
91131a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_macsec_en(struct phy_device * phydev,bool en)912a868b486SRadu Pirea (NXP OSS) static void nxp_c45_macsec_en(struct phy_device *phydev, bool en)
913a868b486SRadu Pirea (NXP OSS) {
914a868b486SRadu Pirea (NXP OSS) 	u32 reg;
915a868b486SRadu Pirea (NXP OSS) 
916a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_CFG, &reg);
917a868b486SRadu Pirea (NXP OSS) 	if (en)
918a868b486SRadu Pirea (NXP OSS) 		reg |= MACSEC_CFG_BYPASS;
919a868b486SRadu Pirea (NXP OSS) 	else
920a868b486SRadu Pirea (NXP OSS) 		reg &= ~MACSEC_CFG_BYPASS;
921a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_write(phydev, MACSEC_CFG, reg);
922a868b486SRadu Pirea (NXP OSS) }
923a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_dev_open(struct macsec_context * ctx)924a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_dev_open(struct macsec_context *ctx)
925a868b486SRadu Pirea (NXP OSS) {
926a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
927a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
928a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
929a868b486SRadu Pirea (NXP OSS) 	int any_bit_set;
930a868b486SRadu Pirea (NXP OSS) 
931a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
932a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
933a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
934a868b486SRadu Pirea (NXP OSS) 
935a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
936a868b486SRadu Pirea (NXP OSS) 
937a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_en_flt(phydev, phy_secy->secy_id, true);
938a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_rx_sc0_impl(phydev, phy_secy->rx_sc0_impl);
939a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc)
940a868b486SRadu Pirea (NXP OSS) 		nxp_c45_rx_sc_en(phydev, phy_secy->rx_sc, true);
941a868b486SRadu Pirea (NXP OSS) 
942a868b486SRadu Pirea (NXP OSS) 	any_bit_set = find_first_bit(priv->macsec->secy_bitmap, TX_SC_MAX);
943a868b486SRadu Pirea (NXP OSS) 	if (any_bit_set == TX_SC_MAX)
944a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_en(phydev, true);
945a868b486SRadu Pirea (NXP OSS) 
946a868b486SRadu Pirea (NXP OSS) 	set_bit(phy_secy->secy_id, priv->macsec->secy_bitmap);
947a868b486SRadu Pirea (NXP OSS) 
948a868b486SRadu Pirea (NXP OSS) 	return 0;
949a868b486SRadu Pirea (NXP OSS) }
950a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_dev_stop(struct macsec_context * ctx)951a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_dev_stop(struct macsec_context *ctx)
952a868b486SRadu Pirea (NXP OSS) {
953a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
954a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
955a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
956a868b486SRadu Pirea (NXP OSS) 	int any_bit_set;
957a868b486SRadu Pirea (NXP OSS) 
958a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
959a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
960a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
961a868b486SRadu Pirea (NXP OSS) 
962a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
963a868b486SRadu Pirea (NXP OSS) 
964a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_en_flt(phydev, phy_secy->secy_id, false);
965a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc)
966a868b486SRadu Pirea (NXP OSS) 		nxp_c45_rx_sc_en(phydev, phy_secy->rx_sc, false);
967a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_rx_sc0_impl(phydev, false);
968a868b486SRadu Pirea (NXP OSS) 
969a868b486SRadu Pirea (NXP OSS) 	clear_bit(phy_secy->secy_id, priv->macsec->secy_bitmap);
970a868b486SRadu Pirea (NXP OSS) 	any_bit_set = find_first_bit(priv->macsec->secy_bitmap, TX_SC_MAX);
971a868b486SRadu Pirea (NXP OSS) 	if (any_bit_set == TX_SC_MAX)
972a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_en(phydev, false);
973a868b486SRadu Pirea (NXP OSS) 
974a868b486SRadu Pirea (NXP OSS) 	return 0;
975a868b486SRadu Pirea (NXP OSS) }
976a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_add_secy(struct macsec_context * ctx)977a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_add_secy(struct macsec_context *ctx)
978a868b486SRadu Pirea (NXP OSS) {
979a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
980a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
981a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
982a868b486SRadu Pirea (NXP OSS) 	bool can_rx_sc0_impl;
983a868b486SRadu Pirea (NXP OSS) 	int idx;
984a868b486SRadu Pirea (NXP OSS) 
985a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "add SecY SCI %016llx\n",
986a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
987a868b486SRadu Pirea (NXP OSS) 
988a868b486SRadu Pirea (NXP OSS) 	if (!nxp_c45_mac_addr_free(ctx))
989a868b486SRadu Pirea (NXP OSS) 		return -EBUSY;
990a868b486SRadu Pirea (NXP OSS) 
991a868b486SRadu Pirea (NXP OSS) 	if (nxp_c45_is_rx_sc0_impl(&priv->macsec->secy_list))
992a868b486SRadu Pirea (NXP OSS) 		return -EBUSY;
993a868b486SRadu Pirea (NXP OSS) 
994a868b486SRadu Pirea (NXP OSS) 	idx = find_first_zero_bit(priv->macsec->tx_sc_bitmap, TX_SC_MAX);
995a868b486SRadu Pirea (NXP OSS) 	if (idx == TX_SC_MAX)
996a868b486SRadu Pirea (NXP OSS) 		return -ENOSPC;
997a868b486SRadu Pirea (NXP OSS) 
998a868b486SRadu Pirea (NXP OSS) 	phy_secy = kzalloc(sizeof(*phy_secy), GFP_KERNEL);
999a868b486SRadu Pirea (NXP OSS) 	if (!phy_secy)
1000a868b486SRadu Pirea (NXP OSS) 		return -ENOMEM;
1001a868b486SRadu Pirea (NXP OSS) 
1002a868b486SRadu Pirea (NXP OSS) 	INIT_LIST_HEAD(&phy_secy->sa_list);
1003a868b486SRadu Pirea (NXP OSS) 	phy_secy->secy = ctx->secy;
1004a868b486SRadu Pirea (NXP OSS) 	phy_secy->secy_id = idx;
1005a868b486SRadu Pirea (NXP OSS) 
1006a868b486SRadu Pirea (NXP OSS) 	/* If the point to point mode should be enabled, we should have no
1007a868b486SRadu Pirea (NXP OSS) 	 * SecY added yet.
1008a868b486SRadu Pirea (NXP OSS) 	 */
1009a868b486SRadu Pirea (NXP OSS) 	can_rx_sc0_impl = list_count_nodes(&priv->macsec->secy_list) == 0;
1010a868b486SRadu Pirea (NXP OSS) 	if (!nxp_c45_secy_valid(phy_secy, can_rx_sc0_impl)) {
1011a868b486SRadu Pirea (NXP OSS) 		kfree(phy_secy);
1012a868b486SRadu Pirea (NXP OSS) 		return -EINVAL;
1013a868b486SRadu Pirea (NXP OSS) 	}
1014a868b486SRadu Pirea (NXP OSS) 
1015a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc0_impl = nxp_c45_rx_sc0_impl(phy_secy);
1016a868b486SRadu Pirea (NXP OSS) 
1017a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1018a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_sci(phydev, MACSEC_TXSC_SCI_1H, ctx->secy->sci);
1019a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_set_flt(phydev, phy_secy);
1020a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_update(phydev, phy_secy);
1021a868b486SRadu Pirea (NXP OSS) 	if (phy_interrupt_is_valid(phydev))
1022a868b486SRadu Pirea (NXP OSS) 		nxp_c45_secy_irq_en(phydev, phy_secy, true);
1023a868b486SRadu Pirea (NXP OSS) 
1024a868b486SRadu Pirea (NXP OSS) 	set_bit(idx, priv->macsec->tx_sc_bitmap);
1025a868b486SRadu Pirea (NXP OSS) 	list_add_tail(&phy_secy->list, &priv->macsec->secy_list);
1026a868b486SRadu Pirea (NXP OSS) 
1027a868b486SRadu Pirea (NXP OSS) 	return 0;
1028a868b486SRadu Pirea (NXP OSS) }
1029a868b486SRadu Pirea (NXP OSS) 
nxp_c45_tx_sa_next(struct nxp_c45_secy * phy_secy,struct nxp_c45_sa * next_sa,u8 encoding_sa)1030a868b486SRadu Pirea (NXP OSS) static void nxp_c45_tx_sa_next(struct nxp_c45_secy *phy_secy,
1031a868b486SRadu Pirea (NXP OSS) 			       struct nxp_c45_sa *next_sa, u8 encoding_sa)
1032a868b486SRadu Pirea (NXP OSS) {
1033a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1034a868b486SRadu Pirea (NXP OSS) 
1035a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, TX_SA, encoding_sa);
1036a868b486SRadu Pirea (NXP OSS) 	if (!IS_ERR(sa)) {
1037a868b486SRadu Pirea (NXP OSS) 		memcpy(next_sa, sa, sizeof(*sa));
1038a868b486SRadu Pirea (NXP OSS) 	} else {
1039a868b486SRadu Pirea (NXP OSS) 		next_sa->is_key_a = true;
1040a868b486SRadu Pirea (NXP OSS) 		next_sa->an = encoding_sa;
1041a868b486SRadu Pirea (NXP OSS) 	}
1042a868b486SRadu Pirea (NXP OSS) }
1043a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_upd_secy(struct macsec_context * ctx)1044a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_upd_secy(struct macsec_context *ctx)
1045a868b486SRadu Pirea (NXP OSS) {
1046a868b486SRadu Pirea (NXP OSS) 	u8 encoding_sa = ctx->secy->tx_sc.encoding_sa;
1047a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1048a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1049a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1050a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa next_sa;
1051a868b486SRadu Pirea (NXP OSS) 	bool can_rx_sc0_impl;
1052a868b486SRadu Pirea (NXP OSS) 
1053a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "update SecY SCI %016llx\n",
1054a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
1055a868b486SRadu Pirea (NXP OSS) 
1056a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1057a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1058a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1059a868b486SRadu Pirea (NXP OSS) 
1060a868b486SRadu Pirea (NXP OSS) 	if (!nxp_c45_mac_addr_free(ctx))
1061a868b486SRadu Pirea (NXP OSS) 		return -EBUSY;
1062a868b486SRadu Pirea (NXP OSS) 
1063a868b486SRadu Pirea (NXP OSS) 	/* If the point to point mode should be enabled, we should have only
1064a868b486SRadu Pirea (NXP OSS) 	 * one SecY added, respectively the updated one.
1065a868b486SRadu Pirea (NXP OSS) 	 */
1066a868b486SRadu Pirea (NXP OSS) 	can_rx_sc0_impl = list_count_nodes(&priv->macsec->secy_list) == 1;
1067a868b486SRadu Pirea (NXP OSS) 	if (!nxp_c45_secy_valid(phy_secy, can_rx_sc0_impl))
1068a868b486SRadu Pirea (NXP OSS) 		return -EINVAL;
1069a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc0_impl = nxp_c45_rx_sc0_impl(phy_secy);
1070a868b486SRadu Pirea (NXP OSS) 
1071a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1072a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_set_flt(phydev, phy_secy);
1073a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_update(phydev, phy_secy);
1074a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_next(phy_secy, &next_sa, encoding_sa);
1075a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_update(phydev, &next_sa, ctx->secy->operational);
1076a868b486SRadu Pirea (NXP OSS) 
1077a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_rx_sc0_impl(phydev, phy_secy->rx_sc0_impl);
1078a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc)
1079a868b486SRadu Pirea (NXP OSS) 		nxp_c45_rx_sc_update(phydev, phy_secy);
1080a868b486SRadu Pirea (NXP OSS) 
1081a868b486SRadu Pirea (NXP OSS) 	return 0;
1082a868b486SRadu Pirea (NXP OSS) }
1083a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_del_secy(struct macsec_context * ctx)1084a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_del_secy(struct macsec_context *ctx)
1085a868b486SRadu Pirea (NXP OSS) {
1086a868b486SRadu Pirea (NXP OSS) 	u8 encoding_sa = ctx->secy->tx_sc.encoding_sa;
1087a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1088a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1089a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1090a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa next_sa;
1091a868b486SRadu Pirea (NXP OSS) 
1092a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "delete SecY SCI %016llx\n",
1093a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
1094a868b486SRadu Pirea (NXP OSS) 
1095a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1096a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1097a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1098a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1099a868b486SRadu Pirea (NXP OSS) 
1100a868b486SRadu Pirea (NXP OSS) 	nxp_c45_mdo_dev_stop(ctx);
1101a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_next(phy_secy, &next_sa, encoding_sa);
1102a868b486SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_update(phydev, &next_sa, false);
110331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_tx_sc_clear_stats(phydev, phy_secy);
1104a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc)
1105a868b486SRadu Pirea (NXP OSS) 		nxp_c45_rx_sc_del(phydev, phy_secy);
1106a868b486SRadu Pirea (NXP OSS) 
1107a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_list_free(&phy_secy->sa_list);
1108a868b486SRadu Pirea (NXP OSS) 	if (phy_interrupt_is_valid(phydev))
1109a868b486SRadu Pirea (NXP OSS) 		nxp_c45_secy_irq_en(phydev, phy_secy, false);
1110a868b486SRadu Pirea (NXP OSS) 
1111a868b486SRadu Pirea (NXP OSS) 	clear_bit(phy_secy->secy_id, priv->macsec->tx_sc_bitmap);
1112a868b486SRadu Pirea (NXP OSS) 	nxp_c45_secy_free(phy_secy);
1113a868b486SRadu Pirea (NXP OSS) 
111431a99fc0SRadu Pirea (NXP OSS) 	if (list_empty(&priv->macsec->secy_list))
111531a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_clear_global_stats(phydev);
111631a99fc0SRadu Pirea (NXP OSS) 
1117a868b486SRadu Pirea (NXP OSS) 	return 0;
1118a868b486SRadu Pirea (NXP OSS) }
1119a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_add_rxsc(struct macsec_context * ctx)1120a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_add_rxsc(struct macsec_context *ctx)
1121a868b486SRadu Pirea (NXP OSS) {
1122a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1123a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1124a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1125a868b486SRadu Pirea (NXP OSS) 
1126a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "add RX SC SCI %016llx %s\n",
1127a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->rx_sc->sci),
1128a868b486SRadu Pirea (NXP OSS) 		   ctx->rx_sc->active ? "enabled" : "disabled");
1129a868b486SRadu Pirea (NXP OSS) 
1130a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1131a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1132a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1133a868b486SRadu Pirea (NXP OSS) 
1134a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc)
1135a868b486SRadu Pirea (NXP OSS) 		return -ENOSPC;
1136a868b486SRadu Pirea (NXP OSS) 
1137a868b486SRadu Pirea (NXP OSS) 	if (phy_secy->secy->tx_sc.end_station &&
1138a868b486SRadu Pirea (NXP OSS) 	    !nxp_c45_port_is_1(ctx->rx_sc->sci))
1139a868b486SRadu Pirea (NXP OSS) 		return -EINVAL;
1140a868b486SRadu Pirea (NXP OSS) 
1141a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc = ctx->rx_sc;
1142a868b486SRadu Pirea (NXP OSS) 
1143a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1144a868b486SRadu Pirea (NXP OSS) 	nxp_c45_set_sci(phydev, MACSEC_RXSC_SCI_1H, ctx->rx_sc->sci);
1145a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sc_update(phydev, phy_secy);
1146a868b486SRadu Pirea (NXP OSS) 
1147a868b486SRadu Pirea (NXP OSS) 	return 0;
1148a868b486SRadu Pirea (NXP OSS) }
1149a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_upd_rxsc(struct macsec_context * ctx)1150a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_upd_rxsc(struct macsec_context *ctx)
1151a868b486SRadu Pirea (NXP OSS) {
1152a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1153a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1154a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1155a868b486SRadu Pirea (NXP OSS) 
1156a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "update RX SC SCI %016llx %s\n",
1157a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->rx_sc->sci),
1158a868b486SRadu Pirea (NXP OSS) 		   ctx->rx_sc->active ? "enabled" : "disabled");
1159a868b486SRadu Pirea (NXP OSS) 
1160a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1161a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1162a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1163a868b486SRadu Pirea (NXP OSS) 
1164a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1165a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sc_update(phydev, phy_secy);
1166a868b486SRadu Pirea (NXP OSS) 
1167a868b486SRadu Pirea (NXP OSS) 	return 0;
1168a868b486SRadu Pirea (NXP OSS) }
1169a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_del_rxsc(struct macsec_context * ctx)1170a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_del_rxsc(struct macsec_context *ctx)
1171a868b486SRadu Pirea (NXP OSS) {
1172a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1173a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1174a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1175a868b486SRadu Pirea (NXP OSS) 
1176a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "delete RX SC SCI %016llx %s\n",
1177a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->rx_sc->sci),
1178a868b486SRadu Pirea (NXP OSS) 		   ctx->rx_sc->active ? "enabled" : "disabled");
1179a868b486SRadu Pirea (NXP OSS) 
1180a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1181a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1182a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1183a868b486SRadu Pirea (NXP OSS) 
1184a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1185a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sc_del(phydev, phy_secy);
1186a868b486SRadu Pirea (NXP OSS) 	phy_secy->rx_sc = NULL;
1187a868b486SRadu Pirea (NXP OSS) 
1188a868b486SRadu Pirea (NXP OSS) 	return 0;
1189a868b486SRadu Pirea (NXP OSS) }
1190a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_add_rxsa(struct macsec_context * ctx)1191a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_add_rxsa(struct macsec_context *ctx)
1192a868b486SRadu Pirea (NXP OSS) {
1193a868b486SRadu Pirea (NXP OSS) 	struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;
1194a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1195a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1196a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1197a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1198a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1199a868b486SRadu Pirea (NXP OSS) 
1200a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "add RX SA %u %s to RX SC SCI %016llx\n",
1201a868b486SRadu Pirea (NXP OSS) 		   an, rx_sa->active ? "enabled" : "disabled",
1202a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(rx_sa->sc->sci));
1203a868b486SRadu Pirea (NXP OSS) 
1204a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1205a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1206a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1207a868b486SRadu Pirea (NXP OSS) 
1208a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_sa_alloc(&phy_secy->sa_list, rx_sa, RX_SA, an);
1209a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1210a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1211a868b486SRadu Pirea (NXP OSS) 
1212a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1213a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_set_pn(phydev, sa, rx_sa->next_pn,
1214a868b486SRadu Pirea (NXP OSS) 			  ctx->secy->replay_window);
1215a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_set_key(ctx, sa->regs, rx_sa->key.salt.bytes, rx_sa->ssci);
1216a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sa_update(phydev, sa, rx_sa->active);
1217a868b486SRadu Pirea (NXP OSS) 
1218a868b486SRadu Pirea (NXP OSS) 	return 0;
1219a868b486SRadu Pirea (NXP OSS) }
1220a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_upd_rxsa(struct macsec_context * ctx)1221a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_upd_rxsa(struct macsec_context *ctx)
1222a868b486SRadu Pirea (NXP OSS) {
1223a868b486SRadu Pirea (NXP OSS) 	struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;
1224a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1225a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1226a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1227a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1228a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1229a868b486SRadu Pirea (NXP OSS) 
1230a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "update RX SA %u %s to RX SC SCI %016llx\n",
1231a868b486SRadu Pirea (NXP OSS) 		   an, rx_sa->active ? "enabled" : "disabled",
1232a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(rx_sa->sc->sci));
1233a868b486SRadu Pirea (NXP OSS) 
1234a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1235a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1236a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1237a868b486SRadu Pirea (NXP OSS) 
1238a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, RX_SA, an);
1239a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1240a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1241a868b486SRadu Pirea (NXP OSS) 
1242a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1243a868b486SRadu Pirea (NXP OSS) 	if (ctx->sa.update_pn)
1244a868b486SRadu Pirea (NXP OSS) 		nxp_c45_sa_set_pn(phydev, sa, rx_sa->next_pn,
1245a868b486SRadu Pirea (NXP OSS) 				  ctx->secy->replay_window);
1246a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sa_update(phydev, sa, rx_sa->active);
1247a868b486SRadu Pirea (NXP OSS) 
1248a868b486SRadu Pirea (NXP OSS) 	return 0;
1249a868b486SRadu Pirea (NXP OSS) }
1250a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_del_rxsa(struct macsec_context * ctx)1251a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_del_rxsa(struct macsec_context *ctx)
1252a868b486SRadu Pirea (NXP OSS) {
1253a868b486SRadu Pirea (NXP OSS) 	struct macsec_rx_sa *rx_sa = ctx->sa.rx_sa;
1254a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1255a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1256a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1257a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1258a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1259a868b486SRadu Pirea (NXP OSS) 
1260a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "delete RX SA %u %s to RX SC SCI %016llx\n",
1261a868b486SRadu Pirea (NXP OSS) 		   an, rx_sa->active ? "enabled" : "disabled",
1262a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(rx_sa->sc->sci));
1263a868b486SRadu Pirea (NXP OSS) 
1264a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1265a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1266a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1267a868b486SRadu Pirea (NXP OSS) 
1268a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, RX_SA, an);
1269a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1270a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1271a868b486SRadu Pirea (NXP OSS) 
1272a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1273a868b486SRadu Pirea (NXP OSS) 	nxp_c45_rx_sa_update(phydev, sa, false);
127431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_rx_sa_clear_stats(phydev, sa);
1275a868b486SRadu Pirea (NXP OSS) 
1276a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_free(sa);
1277a868b486SRadu Pirea (NXP OSS) 
1278a868b486SRadu Pirea (NXP OSS) 	return 0;
1279a868b486SRadu Pirea (NXP OSS) }
1280a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_add_txsa(struct macsec_context * ctx)1281a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_add_txsa(struct macsec_context *ctx)
1282a868b486SRadu Pirea (NXP OSS) {
1283a868b486SRadu Pirea (NXP OSS) 	struct macsec_tx_sa *tx_sa = ctx->sa.tx_sa;
1284a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1285a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1286a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1287a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1288a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1289a868b486SRadu Pirea (NXP OSS) 
1290a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "add TX SA %u %s to TX SC %016llx\n",
1291a868b486SRadu Pirea (NXP OSS) 		   an, ctx->sa.tx_sa->active ? "enabled" : "disabled",
1292a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
1293a868b486SRadu Pirea (NXP OSS) 
1294a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1295a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1296a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1297a868b486SRadu Pirea (NXP OSS) 
1298a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_sa_alloc(&phy_secy->sa_list, tx_sa, TX_SA, an);
1299a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1300a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1301a868b486SRadu Pirea (NXP OSS) 
1302a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1303a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_set_pn(phydev, sa, tx_sa->next_pn, 0);
1304a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_set_key(ctx, sa->regs, tx_sa->key.salt.bytes, tx_sa->ssci);
1305a868b486SRadu Pirea (NXP OSS) 	if (ctx->secy->tx_sc.encoding_sa == sa->an)
1306a868b486SRadu Pirea (NXP OSS) 		nxp_c45_tx_sa_update(phydev, sa, tx_sa->active);
1307a868b486SRadu Pirea (NXP OSS) 
1308a868b486SRadu Pirea (NXP OSS) 	return 0;
1309a868b486SRadu Pirea (NXP OSS) }
1310a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_upd_txsa(struct macsec_context * ctx)1311a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_upd_txsa(struct macsec_context *ctx)
1312a868b486SRadu Pirea (NXP OSS) {
1313a868b486SRadu Pirea (NXP OSS) 	struct macsec_tx_sa *tx_sa = ctx->sa.tx_sa;
1314a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1315a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1316a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1317a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1318a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1319a868b486SRadu Pirea (NXP OSS) 
1320a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "update TX SA %u %s to TX SC %016llx\n",
1321a868b486SRadu Pirea (NXP OSS) 		   an, ctx->sa.tx_sa->active ? "enabled" : "disabled",
1322a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
1323a868b486SRadu Pirea (NXP OSS) 
1324a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1325a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1326a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1327a868b486SRadu Pirea (NXP OSS) 
1328a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, TX_SA, an);
1329a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1330a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1331a868b486SRadu Pirea (NXP OSS) 
1332a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1333a868b486SRadu Pirea (NXP OSS) 	if (ctx->sa.update_pn)
1334a868b486SRadu Pirea (NXP OSS) 		nxp_c45_sa_set_pn(phydev, sa, tx_sa->next_pn, 0);
1335a868b486SRadu Pirea (NXP OSS) 	if (ctx->secy->tx_sc.encoding_sa == sa->an)
1336a868b486SRadu Pirea (NXP OSS) 		nxp_c45_tx_sa_update(phydev, sa, tx_sa->active);
1337a868b486SRadu Pirea (NXP OSS) 
1338a868b486SRadu Pirea (NXP OSS) 	return 0;
1339a868b486SRadu Pirea (NXP OSS) }
1340a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_del_txsa(struct macsec_context * ctx)1341a868b486SRadu Pirea (NXP OSS) static int nxp_c45_mdo_del_txsa(struct macsec_context *ctx)
1342a868b486SRadu Pirea (NXP OSS) {
1343a868b486SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
1344a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1345a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
1346a868b486SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
1347a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1348a868b486SRadu Pirea (NXP OSS) 
1349a868b486SRadu Pirea (NXP OSS) 	phydev_dbg(phydev, "delete TX SA %u %s to TX SC %016llx\n",
1350a868b486SRadu Pirea (NXP OSS) 		   an, ctx->sa.tx_sa->active ? "enabled" : "disabled",
1351a868b486SRadu Pirea (NXP OSS) 		   sci_to_cpu(ctx->secy->sci));
1352a868b486SRadu Pirea (NXP OSS) 
1353a868b486SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
1354a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
1355a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
1356a868b486SRadu Pirea (NXP OSS) 
1357a868b486SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, TX_SA, an);
1358a868b486SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
1359a868b486SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
1360a868b486SRadu Pirea (NXP OSS) 
1361a868b486SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
1362a868b486SRadu Pirea (NXP OSS) 	if (ctx->secy->tx_sc.encoding_sa == sa->an)
1363a868b486SRadu Pirea (NXP OSS) 		nxp_c45_tx_sa_update(phydev, sa, false);
136431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_clear_stats(phydev, sa);
1365a868b486SRadu Pirea (NXP OSS) 
1366a868b486SRadu Pirea (NXP OSS) 	nxp_c45_sa_free(sa);
1367a868b486SRadu Pirea (NXP OSS) 
1368a868b486SRadu Pirea (NXP OSS) 	return 0;
1369a868b486SRadu Pirea (NXP OSS) }
1370a868b486SRadu Pirea (NXP OSS) 
nxp_c45_mdo_get_dev_stats(struct macsec_context * ctx)137131a99fc0SRadu Pirea (NXP OSS) static int nxp_c45_mdo_get_dev_stats(struct macsec_context *ctx)
137231a99fc0SRadu Pirea (NXP OSS) {
137331a99fc0SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
137431a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
137531a99fc0SRadu Pirea (NXP OSS) 	struct macsec_dev_stats  *dev_stats;
137631a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
137731a99fc0SRadu Pirea (NXP OSS) 
137831a99fc0SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
137931a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
138031a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
138131a99fc0SRadu Pirea (NXP OSS) 
138231a99fc0SRadu Pirea (NXP OSS) 	dev_stats = ctx->stats.dev_stats;
138331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
138431a99fc0SRadu Pirea (NXP OSS) 
138531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_OPUS,
138631a99fc0SRadu Pirea (NXP OSS) 				 &dev_stats->OutPktsUntagged);
138731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_OPTLS,
138831a99fc0SRadu Pirea (NXP OSS) 				 &dev_stats->OutPktsTooLong);
138931a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_INPBTS,
139031a99fc0SRadu Pirea (NXP OSS) 				 &dev_stats->InPktsBadTag);
139131a99fc0SRadu Pirea (NXP OSS) 
139231a99fc0SRadu Pirea (NXP OSS) 	if (phy_secy->secy->validate_frames == MACSEC_VALIDATE_STRICT)
139331a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read32_64(phydev, MACSEC_INPWTS,
139431a99fc0SRadu Pirea (NXP OSS) 					 &dev_stats->InPktsNoTag);
139531a99fc0SRadu Pirea (NXP OSS) 	else
139631a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read32_64(phydev, MACSEC_INPWTS,
139731a99fc0SRadu Pirea (NXP OSS) 					 &dev_stats->InPktsUntagged);
139831a99fc0SRadu Pirea (NXP OSS) 
139931a99fc0SRadu Pirea (NXP OSS) 	if (phy_secy->secy->validate_frames == MACSEC_VALIDATE_STRICT)
140031a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read32_64(phydev, MACSEC_IPSNFS,
140131a99fc0SRadu Pirea (NXP OSS) 					 &dev_stats->InPktsNoSCI);
140231a99fc0SRadu Pirea (NXP OSS) 	else
140331a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read32_64(phydev, MACSEC_IPSNFS,
140431a99fc0SRadu Pirea (NXP OSS) 					 &dev_stats->InPktsUnknownSCI);
140531a99fc0SRadu Pirea (NXP OSS) 
140631a99fc0SRadu Pirea (NXP OSS) 	/* Always 0. */
140731a99fc0SRadu Pirea (NXP OSS) 	dev_stats->InPktsOverrun = 0;
140831a99fc0SRadu Pirea (NXP OSS) 
140931a99fc0SRadu Pirea (NXP OSS) 	return 0;
141031a99fc0SRadu Pirea (NXP OSS) }
141131a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_mdo_get_tx_sc_stats(struct macsec_context * ctx)141231a99fc0SRadu Pirea (NXP OSS) static int nxp_c45_mdo_get_tx_sc_stats(struct macsec_context *ctx)
141331a99fc0SRadu Pirea (NXP OSS) {
141431a99fc0SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
141531a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
141631a99fc0SRadu Pirea (NXP OSS) 	struct macsec_tx_sa_stats tx_sa_stats;
141731a99fc0SRadu Pirea (NXP OSS) 	struct macsec_tx_sc_stats *stats;
141831a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
141931a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
142031a99fc0SRadu Pirea (NXP OSS) 
142131a99fc0SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
142231a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
142331a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
142431a99fc0SRadu Pirea (NXP OSS) 
142531a99fc0SRadu Pirea (NXP OSS) 	stats = ctx->stats.tx_sc_stats;
142631a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
142731a99fc0SRadu Pirea (NXP OSS) 
142831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read64(phydev, MACSEC_OOE1HS,
142931a99fc0SRadu Pirea (NXP OSS) 			      &stats->OutOctetsEncrypted);
143031a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read64(phydev, MACSEC_OOP1HS,
143131a99fc0SRadu Pirea (NXP OSS) 			      &stats->OutOctetsProtected);
143231a99fc0SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &phy_secy->sa_list, list) {
143331a99fc0SRadu Pirea (NXP OSS) 		if (pos->type != TX_SA)
143431a99fc0SRadu Pirea (NXP OSS) 			continue;
143531a99fc0SRadu Pirea (NXP OSS) 
143631a99fc0SRadu Pirea (NXP OSS) 		memset(&tx_sa_stats, 0, sizeof(tx_sa_stats));
143731a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_tx_sa_read_stats(phydev, pos, &tx_sa_stats);
143831a99fc0SRadu Pirea (NXP OSS) 
143931a99fc0SRadu Pirea (NXP OSS) 		stats->OutPktsEncrypted += tx_sa_stats.OutPktsEncrypted;
144031a99fc0SRadu Pirea (NXP OSS) 		stats->OutPktsProtected += tx_sa_stats.OutPktsProtected;
144131a99fc0SRadu Pirea (NXP OSS) 	}
144231a99fc0SRadu Pirea (NXP OSS) 
144331a99fc0SRadu Pirea (NXP OSS) 	return 0;
144431a99fc0SRadu Pirea (NXP OSS) }
144531a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_mdo_get_tx_sa_stats(struct macsec_context * ctx)144631a99fc0SRadu Pirea (NXP OSS) static int nxp_c45_mdo_get_tx_sa_stats(struct macsec_context *ctx)
144731a99fc0SRadu Pirea (NXP OSS) {
144831a99fc0SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
144931a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
145031a99fc0SRadu Pirea (NXP OSS) 	struct macsec_tx_sa_stats *stats;
145131a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
145231a99fc0SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
145331a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
145431a99fc0SRadu Pirea (NXP OSS) 
145531a99fc0SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
145631a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
145731a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
145831a99fc0SRadu Pirea (NXP OSS) 
145931a99fc0SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, TX_SA, an);
146031a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
146131a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
146231a99fc0SRadu Pirea (NXP OSS) 
146331a99fc0SRadu Pirea (NXP OSS) 	stats = ctx->stats.tx_sa_stats;
146431a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
146531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_tx_sa_read_stats(phydev, sa, stats);
146631a99fc0SRadu Pirea (NXP OSS) 
146731a99fc0SRadu Pirea (NXP OSS) 	return 0;
146831a99fc0SRadu Pirea (NXP OSS) }
146931a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_mdo_get_rx_sc_stats(struct macsec_context * ctx)147031a99fc0SRadu Pirea (NXP OSS) static int nxp_c45_mdo_get_rx_sc_stats(struct macsec_context *ctx)
147131a99fc0SRadu Pirea (NXP OSS) {
147231a99fc0SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
147331a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
147431a99fc0SRadu Pirea (NXP OSS) 	struct macsec_rx_sa_stats rx_sa_stats;
147531a99fc0SRadu Pirea (NXP OSS) 	struct macsec_rx_sc_stats *stats;
147631a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
147731a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *pos, *tmp;
147831a99fc0SRadu Pirea (NXP OSS) 	u32 reg = 0;
147931a99fc0SRadu Pirea (NXP OSS) 	int i;
148031a99fc0SRadu Pirea (NXP OSS) 
148131a99fc0SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
148231a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
148331a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
148431a99fc0SRadu Pirea (NXP OSS) 
148531a99fc0SRadu Pirea (NXP OSS) 	if (phy_secy->rx_sc != ctx->rx_sc)
148631a99fc0SRadu Pirea (NXP OSS) 		return -EINVAL;
148731a99fc0SRadu Pirea (NXP OSS) 
148831a99fc0SRadu Pirea (NXP OSS) 	stats = ctx->stats.rx_sc_stats;
148931a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
149031a99fc0SRadu Pirea (NXP OSS) 
149131a99fc0SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(pos, tmp, &phy_secy->sa_list, list) {
149231a99fc0SRadu Pirea (NXP OSS) 		if (pos->type != RX_SA)
149331a99fc0SRadu Pirea (NXP OSS) 			continue;
149431a99fc0SRadu Pirea (NXP OSS) 
149531a99fc0SRadu Pirea (NXP OSS) 		memset(&rx_sa_stats, 0, sizeof(rx_sa_stats));
149631a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_rx_sa_read_stats(phydev, pos, &rx_sa_stats);
149731a99fc0SRadu Pirea (NXP OSS) 
149831a99fc0SRadu Pirea (NXP OSS) 		stats->InPktsInvalid += rx_sa_stats.InPktsInvalid;
149931a99fc0SRadu Pirea (NXP OSS) 		stats->InPktsNotValid += rx_sa_stats.InPktsNotValid;
150031a99fc0SRadu Pirea (NXP OSS) 		stats->InPktsOK += rx_sa_stats.InPktsOK;
150131a99fc0SRadu Pirea (NXP OSS) 	}
150231a99fc0SRadu Pirea (NXP OSS) 
150331a99fc0SRadu Pirea (NXP OSS) 	for (i = 0; i < MACSEC_NUM_AN; i++) {
150431a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read(phydev, MACSEC_RXAN0INUSS + i * 4, &reg);
150531a99fc0SRadu Pirea (NXP OSS) 		stats->InPktsNotUsingSA += reg;
150631a99fc0SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read(phydev, MACSEC_RXAN0IPUSS + i * 4, &reg);
150731a99fc0SRadu Pirea (NXP OSS) 		stats->InPktsUnusedSA += reg;
150831a99fc0SRadu Pirea (NXP OSS) 	}
150931a99fc0SRadu Pirea (NXP OSS) 
151031a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read64(phydev, MACSEC_INOD1HS,
151131a99fc0SRadu Pirea (NXP OSS) 			      &stats->InOctetsDecrypted);
151231a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read64(phydev, MACSEC_INOV1HS,
151331a99fc0SRadu Pirea (NXP OSS) 			      &stats->InOctetsValidated);
151431a99fc0SRadu Pirea (NXP OSS) 
151531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_RXSCIPDS,
151631a99fc0SRadu Pirea (NXP OSS) 				 &stats->InPktsDelayed);
151731a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_RXSCIPLS,
151831a99fc0SRadu Pirea (NXP OSS) 				 &stats->InPktsLate);
151931a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read32_64(phydev, MACSEC_RXSCIPUS,
152031a99fc0SRadu Pirea (NXP OSS) 				 &stats->InPktsUnchecked);
152131a99fc0SRadu Pirea (NXP OSS) 
152231a99fc0SRadu Pirea (NXP OSS) 	return 0;
152331a99fc0SRadu Pirea (NXP OSS) }
152431a99fc0SRadu Pirea (NXP OSS) 
nxp_c45_mdo_get_rx_sa_stats(struct macsec_context * ctx)152531a99fc0SRadu Pirea (NXP OSS) static int nxp_c45_mdo_get_rx_sa_stats(struct macsec_context *ctx)
152631a99fc0SRadu Pirea (NXP OSS) {
152731a99fc0SRadu Pirea (NXP OSS) 	struct phy_device *phydev = ctx->phydev;
152831a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
152931a99fc0SRadu Pirea (NXP OSS) 	struct macsec_rx_sa_stats *stats;
153031a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *phy_secy;
153131a99fc0SRadu Pirea (NXP OSS) 	u8 an = ctx->sa.assoc_num;
153231a99fc0SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
153331a99fc0SRadu Pirea (NXP OSS) 
153431a99fc0SRadu Pirea (NXP OSS) 	phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
153531a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(phy_secy))
153631a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(phy_secy);
153731a99fc0SRadu Pirea (NXP OSS) 
153831a99fc0SRadu Pirea (NXP OSS) 	sa = nxp_c45_find_sa(&phy_secy->sa_list, RX_SA, an);
153931a99fc0SRadu Pirea (NXP OSS) 	if (IS_ERR(sa))
154031a99fc0SRadu Pirea (NXP OSS) 		return PTR_ERR(sa);
154131a99fc0SRadu Pirea (NXP OSS) 
154231a99fc0SRadu Pirea (NXP OSS) 	stats = ctx->stats.rx_sa_stats;
154331a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_select_secy(phydev, phy_secy->secy_id);
154431a99fc0SRadu Pirea (NXP OSS) 
154531a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_rx_sa_read_stats(phydev, sa, stats);
154631a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_RXAN0INUSS + an * 4,
154731a99fc0SRadu Pirea (NXP OSS) 			    &stats->InPktsNotUsingSA);
154831a99fc0SRadu Pirea (NXP OSS) 	nxp_c45_macsec_read(phydev, MACSEC_RXAN0IPUSS + an * 4,
154931a99fc0SRadu Pirea (NXP OSS) 			    &stats->InPktsUnusedSA);
155031a99fc0SRadu Pirea (NXP OSS) 
155131a99fc0SRadu Pirea (NXP OSS) 	return 0;
155231a99fc0SRadu Pirea (NXP OSS) }
155331a99fc0SRadu Pirea (NXP OSS) 
1554*dc1a0038SRadu Pirea (NXP OSS) struct tja11xx_tlv_header {
1555*dc1a0038SRadu Pirea (NXP OSS) 	struct ethhdr eth;
1556*dc1a0038SRadu Pirea (NXP OSS) 	u8 subtype;
1557*dc1a0038SRadu Pirea (NXP OSS) 	u8 len;
1558*dc1a0038SRadu Pirea (NXP OSS) 	u8 payload[28];
1559*dc1a0038SRadu Pirea (NXP OSS) };
1560*dc1a0038SRadu Pirea (NXP OSS) 
nxp_c45_mdo_insert_tx_tag(struct phy_device * phydev,struct sk_buff * skb)1561*dc1a0038SRadu Pirea (NXP OSS) static int nxp_c45_mdo_insert_tx_tag(struct phy_device *phydev,
1562*dc1a0038SRadu Pirea (NXP OSS) 				     struct sk_buff *skb)
1563*dc1a0038SRadu Pirea (NXP OSS) {
1564*dc1a0038SRadu Pirea (NXP OSS) 	struct tja11xx_tlv_header *tlv;
1565*dc1a0038SRadu Pirea (NXP OSS) 	struct ethhdr *eth;
1566*dc1a0038SRadu Pirea (NXP OSS) 
1567*dc1a0038SRadu Pirea (NXP OSS) 	eth = eth_hdr(skb);
1568*dc1a0038SRadu Pirea (NXP OSS) 	tlv = skb_push(skb, TJA11XX_TLV_TX_NEEDED_HEADROOM);
1569*dc1a0038SRadu Pirea (NXP OSS) 	memmove(tlv, eth, sizeof(*eth));
1570*dc1a0038SRadu Pirea (NXP OSS) 	skb_reset_mac_header(skb);
1571*dc1a0038SRadu Pirea (NXP OSS) 	tlv->eth.h_proto = htons(ETH_P_TJA11XX_TLV);
1572*dc1a0038SRadu Pirea (NXP OSS) 	tlv->subtype = 1;
1573*dc1a0038SRadu Pirea (NXP OSS) 	tlv->len = sizeof(tlv->payload);
1574*dc1a0038SRadu Pirea (NXP OSS) 	memset(tlv->payload, 0, sizeof(tlv->payload));
1575*dc1a0038SRadu Pirea (NXP OSS) 
1576*dc1a0038SRadu Pirea (NXP OSS) 	return 0;
1577*dc1a0038SRadu Pirea (NXP OSS) }
1578*dc1a0038SRadu Pirea (NXP OSS) 
1579a868b486SRadu Pirea (NXP OSS) static const struct macsec_ops nxp_c45_macsec_ops = {
1580a868b486SRadu Pirea (NXP OSS) 	.mdo_dev_open = nxp_c45_mdo_dev_open,
1581a868b486SRadu Pirea (NXP OSS) 	.mdo_dev_stop = nxp_c45_mdo_dev_stop,
1582a868b486SRadu Pirea (NXP OSS) 	.mdo_add_secy = nxp_c45_mdo_add_secy,
1583a868b486SRadu Pirea (NXP OSS) 	.mdo_upd_secy = nxp_c45_mdo_upd_secy,
1584a868b486SRadu Pirea (NXP OSS) 	.mdo_del_secy = nxp_c45_mdo_del_secy,
1585a868b486SRadu Pirea (NXP OSS) 	.mdo_add_rxsc = nxp_c45_mdo_add_rxsc,
1586a868b486SRadu Pirea (NXP OSS) 	.mdo_upd_rxsc = nxp_c45_mdo_upd_rxsc,
1587a868b486SRadu Pirea (NXP OSS) 	.mdo_del_rxsc = nxp_c45_mdo_del_rxsc,
1588a868b486SRadu Pirea (NXP OSS) 	.mdo_add_rxsa = nxp_c45_mdo_add_rxsa,
1589a868b486SRadu Pirea (NXP OSS) 	.mdo_upd_rxsa = nxp_c45_mdo_upd_rxsa,
1590a868b486SRadu Pirea (NXP OSS) 	.mdo_del_rxsa = nxp_c45_mdo_del_rxsa,
1591a868b486SRadu Pirea (NXP OSS) 	.mdo_add_txsa = nxp_c45_mdo_add_txsa,
1592a868b486SRadu Pirea (NXP OSS) 	.mdo_upd_txsa = nxp_c45_mdo_upd_txsa,
1593a868b486SRadu Pirea (NXP OSS) 	.mdo_del_txsa = nxp_c45_mdo_del_txsa,
159431a99fc0SRadu Pirea (NXP OSS) 	.mdo_get_dev_stats = nxp_c45_mdo_get_dev_stats,
159531a99fc0SRadu Pirea (NXP OSS) 	.mdo_get_tx_sc_stats = nxp_c45_mdo_get_tx_sc_stats,
159631a99fc0SRadu Pirea (NXP OSS) 	.mdo_get_tx_sa_stats = nxp_c45_mdo_get_tx_sa_stats,
159731a99fc0SRadu Pirea (NXP OSS) 	.mdo_get_rx_sc_stats = nxp_c45_mdo_get_rx_sc_stats,
159831a99fc0SRadu Pirea (NXP OSS) 	.mdo_get_rx_sa_stats = nxp_c45_mdo_get_rx_sa_stats,
1599*dc1a0038SRadu Pirea (NXP OSS) 	.mdo_insert_tx_tag = nxp_c45_mdo_insert_tx_tag,
1600*dc1a0038SRadu Pirea (NXP OSS) 	.needed_headroom = TJA11XX_TLV_TX_NEEDED_HEADROOM,
1601*dc1a0038SRadu Pirea (NXP OSS) 	.needed_tailroom = TJA11XX_TLV_NEEDED_TAILROOM,
1602a868b486SRadu Pirea (NXP OSS) };
1603a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_config_init(struct phy_device * phydev)1604a868b486SRadu Pirea (NXP OSS) int nxp_c45_macsec_config_init(struct phy_device *phydev)
1605a868b486SRadu Pirea (NXP OSS) {
1606a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1607a868b486SRadu Pirea (NXP OSS) 	int ret;
1608a868b486SRadu Pirea (NXP OSS) 
1609a868b486SRadu Pirea (NXP OSS) 	if (!priv->macsec)
1610a868b486SRadu Pirea (NXP OSS) 		return 0;
1611a868b486SRadu Pirea (NXP OSS) 
1612a868b486SRadu Pirea (NXP OSS) 	ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_FUNC_ENABLES,
1613a868b486SRadu Pirea (NXP OSS) 			       MACSEC_EN | ADAPTER_EN);
1614a868b486SRadu Pirea (NXP OSS) 	if (ret)
1615a868b486SRadu Pirea (NXP OSS) 		return ret;
1616a868b486SRadu Pirea (NXP OSS) 
1617a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, ADPTR_CNTRL, ADPTR_CNTRL_CONFIG_EN |
1618a868b486SRadu Pirea (NXP OSS) 				   ADPTR_CNTRL_ADPTR_EN);
1619a868b486SRadu Pirea (NXP OSS) 	if (ret)
1620a868b486SRadu Pirea (NXP OSS) 		return ret;
1621a868b486SRadu Pirea (NXP OSS) 
1622*dc1a0038SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, ADPTR_TX_TAG_CNTRL,
1623*dc1a0038SRadu Pirea (NXP OSS) 				   ADPTR_TX_TAG_CNTRL_ENA);
1624*dc1a0038SRadu Pirea (NXP OSS) 	if (ret)
1625*dc1a0038SRadu Pirea (NXP OSS) 		return ret;
1626*dc1a0038SRadu Pirea (NXP OSS) 
1627a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, ADPTR_CNTRL, ADPTR_CNTRL_ADPTR_EN);
1628a868b486SRadu Pirea (NXP OSS) 	if (ret)
1629a868b486SRadu Pirea (NXP OSS) 		return ret;
1630a868b486SRadu Pirea (NXP OSS) 
1631a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, MACSEC_TPNET, PN_WRAP_THRESHOLD);
1632a868b486SRadu Pirea (NXP OSS) 	if (ret)
1633a868b486SRadu Pirea (NXP OSS) 		return ret;
1634a868b486SRadu Pirea (NXP OSS) 
1635a868b486SRadu Pirea (NXP OSS) 	/* Set MKA filter. */
1636a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, MACSEC_UPFR0D2, ETH_P_PAE);
1637a868b486SRadu Pirea (NXP OSS) 	if (ret)
1638a868b486SRadu Pirea (NXP OSS) 		return ret;
1639a868b486SRadu Pirea (NXP OSS) 
1640a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, MACSEC_UPFR0M1, MACSEC_OVP);
1641a868b486SRadu Pirea (NXP OSS) 	if (ret)
1642a868b486SRadu Pirea (NXP OSS) 		return ret;
1643a868b486SRadu Pirea (NXP OSS) 
1644a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, MACSEC_UPFR0M2, ETYPE_MASK);
1645a868b486SRadu Pirea (NXP OSS) 	if (ret)
1646a868b486SRadu Pirea (NXP OSS) 		return ret;
1647a868b486SRadu Pirea (NXP OSS) 
1648a868b486SRadu Pirea (NXP OSS) 	ret = nxp_c45_macsec_write(phydev, MACSEC_UPFR0R, MACSEC_UPFR_EN);
1649a868b486SRadu Pirea (NXP OSS) 
1650a868b486SRadu Pirea (NXP OSS) 	return ret;
1651a868b486SRadu Pirea (NXP OSS) }
1652a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_probe(struct phy_device * phydev)1653a868b486SRadu Pirea (NXP OSS) int nxp_c45_macsec_probe(struct phy_device *phydev)
1654a868b486SRadu Pirea (NXP OSS) {
1655a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1656a868b486SRadu Pirea (NXP OSS) 	struct device *dev = &phydev->mdio.dev;
1657a868b486SRadu Pirea (NXP OSS) 
1658a868b486SRadu Pirea (NXP OSS) 	priv->macsec = devm_kzalloc(dev, sizeof(*priv->macsec), GFP_KERNEL);
1659a868b486SRadu Pirea (NXP OSS) 	if (!priv->macsec)
1660a868b486SRadu Pirea (NXP OSS) 		return -ENOMEM;
1661a868b486SRadu Pirea (NXP OSS) 
1662a868b486SRadu Pirea (NXP OSS) 	INIT_LIST_HEAD(&priv->macsec->secy_list);
1663a868b486SRadu Pirea (NXP OSS) 	phydev->macsec_ops = &nxp_c45_macsec_ops;
1664a868b486SRadu Pirea (NXP OSS) 
1665a868b486SRadu Pirea (NXP OSS) 	return 0;
1666a868b486SRadu Pirea (NXP OSS) }
1667a868b486SRadu Pirea (NXP OSS) 
nxp_c45_macsec_remove(struct phy_device * phydev)1668a868b486SRadu Pirea (NXP OSS) void nxp_c45_macsec_remove(struct phy_device *phydev)
1669a868b486SRadu Pirea (NXP OSS) {
1670a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1671a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *secy_p, *secy_t;
1672a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa_p, *sa_t;
1673a868b486SRadu Pirea (NXP OSS) 	struct list_head *secy_list;
1674a868b486SRadu Pirea (NXP OSS) 
1675a868b486SRadu Pirea (NXP OSS) 	if (!priv->macsec)
1676a868b486SRadu Pirea (NXP OSS) 		return;
1677a868b486SRadu Pirea (NXP OSS) 
1678a868b486SRadu Pirea (NXP OSS) 	secy_list = &priv->macsec->secy_list;
1679a868b486SRadu Pirea (NXP OSS) 	nxp_c45_macsec_en(phydev, false);
1680a868b486SRadu Pirea (NXP OSS) 
1681a868b486SRadu Pirea (NXP OSS) 	list_for_each_entry_safe(secy_p, secy_t, secy_list, list) {
1682a868b486SRadu Pirea (NXP OSS) 		list_for_each_entry_safe(sa_p, sa_t, &secy_p->sa_list, list)
1683a868b486SRadu Pirea (NXP OSS) 			nxp_c45_sa_free(sa_p);
1684a868b486SRadu Pirea (NXP OSS) 		nxp_c45_secy_free(secy_p);
1685a868b486SRadu Pirea (NXP OSS) 	}
1686a868b486SRadu Pirea (NXP OSS) }
1687a868b486SRadu Pirea (NXP OSS) 
nxp_c45_handle_macsec_interrupt(struct phy_device * phydev,irqreturn_t * ret)1688a868b486SRadu Pirea (NXP OSS) void nxp_c45_handle_macsec_interrupt(struct phy_device *phydev,
1689a868b486SRadu Pirea (NXP OSS) 				     irqreturn_t *ret)
1690a868b486SRadu Pirea (NXP OSS) {
1691a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_phy *priv = phydev->priv;
1692a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_secy *secy;
1693a868b486SRadu Pirea (NXP OSS) 	struct nxp_c45_sa *sa;
1694a868b486SRadu Pirea (NXP OSS) 	u8 encoding_sa;
1695a868b486SRadu Pirea (NXP OSS) 	int secy_id;
1696a868b486SRadu Pirea (NXP OSS) 	u32 reg = 0;
1697a868b486SRadu Pirea (NXP OSS) 
1698a868b486SRadu Pirea (NXP OSS) 	if (!priv->macsec)
1699a868b486SRadu Pirea (NXP OSS) 		return;
1700a868b486SRadu Pirea (NXP OSS) 
1701a868b486SRadu Pirea (NXP OSS) 	do {
1702a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_read(phydev, MACSEC_EVR, &reg);
1703a868b486SRadu Pirea (NXP OSS) 		if (!reg)
1704a868b486SRadu Pirea (NXP OSS) 			return;
1705a868b486SRadu Pirea (NXP OSS) 
1706a868b486SRadu Pirea (NXP OSS) 		secy_id = MACSEC_REG_SIZE - ffs(reg);
1707a868b486SRadu Pirea (NXP OSS) 		secy = nxp_c45_find_secy_by_id(&priv->macsec->secy_list,
1708a868b486SRadu Pirea (NXP OSS) 					       secy_id);
1709a868b486SRadu Pirea (NXP OSS) 		if (IS_ERR(secy)) {
1710a868b486SRadu Pirea (NXP OSS) 			WARN_ON(1);
1711a868b486SRadu Pirea (NXP OSS) 			goto macsec_ack_irq;
1712a868b486SRadu Pirea (NXP OSS) 		}
1713a868b486SRadu Pirea (NXP OSS) 
1714a868b486SRadu Pirea (NXP OSS) 		encoding_sa = secy->secy->tx_sc.encoding_sa;
1715a868b486SRadu Pirea (NXP OSS) 		phydev_dbg(phydev, "pn_wrapped: TX SC %d, encoding_sa %u\n",
1716a868b486SRadu Pirea (NXP OSS) 			   secy->secy_id, encoding_sa);
1717a868b486SRadu Pirea (NXP OSS) 
1718a868b486SRadu Pirea (NXP OSS) 		sa = nxp_c45_find_sa(&secy->sa_list, TX_SA, encoding_sa);
1719a868b486SRadu Pirea (NXP OSS) 		if (!IS_ERR(sa))
1720a868b486SRadu Pirea (NXP OSS) 			macsec_pn_wrapped(secy->secy, sa->sa);
1721a868b486SRadu Pirea (NXP OSS) 		else
1722a868b486SRadu Pirea (NXP OSS) 			WARN_ON(1);
1723a868b486SRadu Pirea (NXP OSS) 
1724a868b486SRadu Pirea (NXP OSS) macsec_ack_irq:
1725a868b486SRadu Pirea (NXP OSS) 		nxp_c45_macsec_write(phydev, MACSEC_EVR,
1726a868b486SRadu Pirea (NXP OSS) 				     TX_SC_BIT(secy_id));
1727a868b486SRadu Pirea (NXP OSS) 		*ret = IRQ_HANDLED;
1728a868b486SRadu Pirea (NXP OSS) 	} while (reg);
1729a868b486SRadu Pirea (NXP OSS) }
1730