15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/*
25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Wired Ethernet driver interface for QCA MACsec driver
35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2004, Gunter Burchardt <tira@isx.de>
55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt *
75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * This software may be distributed under the terms of the BSD license.
85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * See README for more details.
95a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "includes.h"
125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <sys/ioctl.h>
135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <net/if.h>
147d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt#include <inttypes.h>
155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef __linux__
165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <netpacket/packet.h>
175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <net/if_arp.h>
185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <net/if.h>
195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* __linux__ */
205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <net/if_dl.h>
225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <net/if_media.h>
235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef __sun__
255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <sys/sockio.h>
265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* __sun__ */
275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/common.h"
295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/eloop.h"
305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/defs.h"
315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/ieee802_1x_defs.h"
329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#include "pae/ieee802_1x_kay.h"
335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "driver.h"
34abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt#include "driver_wired_common.h"
355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "nss_macsec_secy.h"
375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "nss_macsec_secy_rx.h"
385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "nss_macsec_secy_tx.h"
395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MAXSC 16
415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* TCI field definition */
435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TCI_ES                0x40
445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TCI_SC                0x20
455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TCI_SCB               0x10
465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TCI_E                 0x08
475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TCI_C                 0x04
485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef _MSC_VER
505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#pragma pack(push, 1)
515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* _MSC_VER */
525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef _MSC_VER
545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#pragma pack(pop)
555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* _MSC_VER */
565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
579839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstruct channel_map {
589839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	struct ieee802_1x_mka_sci sci;
599839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt};
609839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct macsec_qca_data {
62abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	struct driver_wired_common_data common;
635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
64abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	u32 secy_id;
655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* shadow */
675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean always_include_sci;
685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean use_es;
695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean use_scb;
705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean protect_frames;
715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean replay_protect;
725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 replay_window;
739839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
749839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	struct channel_map receive_channel_map[MAXSC];
759839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	struct channel_map transmit_channel_map[MAXSC];
765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void __macsec_drv_init(struct macsec_qca_data *drv)
805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_rx_ctl_filt_t rx_ctl_filt;
835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_tx_ctl_filt_t tx_ctl_filt;
845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_INFO, "%s: secy_id=%d", __func__, drv->secy_id);
865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* Enable Secy and Let EAPoL bypass */
885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret = nss_macsec_secy_en_set(drv->secy_id, TRUE);
895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (ret)
905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "nss_macsec_secy_en_set: FAIL");
915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret = nss_macsec_secy_sc_sa_mapping_mode_set(drv->secy_id,
935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt						     FAL_SC_SA_MAP_1_4);
945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (ret)
955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR,
965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			   "nss_macsec_secy_sc_sa_mapping_mode_set: FAIL");
975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&rx_ctl_filt, 0, sizeof(rx_ctl_filt));
995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	rx_ctl_filt.bypass = 1;
1005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	rx_ctl_filt.match_type = IG_CTL_COMPARE_ETHER_TYPE;
1015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	rx_ctl_filt.match_mask = 0xffff;
1025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	rx_ctl_filt.ether_type_da_range = 0x888e;
1035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret = nss_macsec_secy_rx_ctl_filt_set(drv->secy_id, 0, &rx_ctl_filt);
1045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (ret)
1055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "nss_macsec_secy_rx_ctl_filt_set: FAIL");
1065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&tx_ctl_filt, 0, sizeof(tx_ctl_filt));
1085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	tx_ctl_filt.bypass = 1;
1095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	tx_ctl_filt.match_type = EG_CTL_COMPARE_ETHER_TYPE;
1105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	tx_ctl_filt.match_mask = 0xffff;
1115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	tx_ctl_filt.ether_type_da_range = 0x888e;
1125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret = nss_macsec_secy_tx_ctl_filt_set(drv->secy_id, 0, &tx_ctl_filt);
1135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (ret)
1145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "nss_macsec_secy_tx_ctl_filt_set: FAIL");
1155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void __macsec_drv_deinit(struct macsec_qca_data *drv)
1195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	nss_macsec_secy_en_set(drv->secy_id, FALSE);
1215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	nss_macsec_secy_rx_sc_del_all(drv->secy_id);
1225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	nss_macsec_secy_tx_sc_del_all(drv->secy_id);
1235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void * macsec_qca_init(void *ctx, const char *ifname)
1275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv;
1295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv = os_zalloc(sizeof(*drv));
1315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (drv == NULL)
1325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return NULL;
1335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* Board specific settings */
135abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	if (os_memcmp("eth2", ifname, 4) == 0)
1365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		drv->secy_id = 1;
137abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	else if (os_memcmp("eth3", ifname, 4) == 0)
1385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		drv->secy_id = 2;
1395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else
1405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		drv->secy_id = -1;
1415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
142abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
1435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_free(drv);
1445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return NULL;
1455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
1465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return drv;
1485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void macsec_qca_deinit(void *priv)
1525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
1545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
155abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	driver_wired_deinit_common(&drv->common);
1565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(drv);
1575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_macsec_init(void *priv, struct macsec_init_params *params)
1615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
1635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->always_include_sci = params->always_include_sci;
1655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->use_es = params->use_es;
1665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->use_scb = params->use_scb;
1675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: es=%d, scb=%d, sci=%d",
1695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		   __func__, drv->use_es, drv->use_scb,
1705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		   drv->always_include_sci);
1715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	__macsec_drv_init(drv);
1735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return 0;
1755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_macsec_deinit(void *priv)
1795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
1815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s", __func__);
1835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	__macsec_drv_deinit(drv);
1855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return 0;
1875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1909839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_get_capability(void *priv, enum macsec_cap *cap)
1919839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
1929839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s", __func__);
1939839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
1949839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	*cap = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
1959839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
1969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	return 0;
1979839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
1989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
1999839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_enable_protect_frames(void *priv, Boolean enabled)
2015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
2035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
2045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
2065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->protect_frames = enabled;
2085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
2105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_set_replay_protect(void *priv, Boolean enabled,
2145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					 unsigned int window)
2155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
2175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
2185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: enabled=%d, win=%u",
2205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		   __func__, enabled, window);
2215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->replay_protect = enabled;
2235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	drv->replay_window = window;
2245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
2265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2297d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidtstatic int macsec_qca_set_current_cipher_suite(void *priv, u64 cs)
2305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2317d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt	if (cs != CS_ID_GCM_AES_128) {
2327d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt		wpa_printf(MSG_ERROR,
2337d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt			   "%s: NOT supported CipherSuite: %016" PRIx64,
2347d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt			   __func__, cs);
2355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return -1;
2365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
2375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* Support default Cipher Suite 0080020001000001 (GCM-AES-128) */
2395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: default support aes-gcm-128", __func__);
2405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return 0;
2425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_enable_controlled_port(void *priv, Boolean enabled)
2465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
2485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
2495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: enable=%d", __func__, enabled);
2515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_controlled_port_en_set(drv->secy_id, enabled);
2535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
2555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2589839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_lookup_channel(struct channel_map *map,
2599839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt				     struct ieee802_1x_mka_sci *sci,
2609839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt				     u32 *channel)
2619839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
2629839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 i;
2639839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2649839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	for (i = 0; i < MAXSC; i++) {
2659839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		if (os_memcmp(&map[i].sci, sci,
2669839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt			      sizeof(struct ieee802_1x_mka_sci)) == 0) {
2679839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt			*channel = i;
2689839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt			return 0;
2699839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		}
2709839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	}
2719839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2729839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	return -1;
2739839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
2749839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2759839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2769839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic void macsec_qca_register_channel(struct channel_map *map,
2779839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					struct ieee802_1x_mka_sci *sci,
2789839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					u32 channel)
2799839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
2809839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	os_memcpy(&map[channel].sci, sci, sizeof(struct ieee802_1x_mka_sci));
2819839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
2829839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2839839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2849839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_lookup_receive_channel(struct macsec_qca_data *drv,
2859839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					     struct receive_sc *sc,
2869839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					     u32 *channel)
2879839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
2889839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	return macsec_qca_lookup_channel(drv->receive_channel_map, &sc->sci,
2899839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					 channel);
2909839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
2919839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2929839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
2939839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic void macsec_qca_register_receive_channel(struct macsec_qca_data *drv,
2949839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						struct receive_sc *sc,
2959839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						u32 channel)
2969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
2979839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	macsec_qca_register_channel(drv->receive_channel_map, &sc->sci,
2989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt				    channel);
2999839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
3009839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3019839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3029839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_lookup_transmit_channel(struct macsec_qca_data *drv,
3039839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					      struct transmit_sc *sc,
3049839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					      u32 *channel)
3059839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
3069839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	return macsec_qca_lookup_channel(drv->transmit_channel_map, &sc->sci,
3079839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					 channel);
3089839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
3099839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3109839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3119839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic void macsec_qca_register_transmit_channel(struct macsec_qca_data *drv,
3129839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						 struct transmit_sc *sc,
3139839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						 u32 channel)
3149839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt{
3159839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	macsec_qca_register_channel(drv->transmit_channel_map, &sc->sci,
3169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt				    channel);
3179839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt}
3189839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3199839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3209839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
3215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
3235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
3245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 next_pn = 0;
3255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	bool enabled = FALSE;
3265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 win;
3279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
3285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3299839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
3309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
3319839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
3329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3339839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, sa->an,
3345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt						 &next_pn);
3355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_replay_protect_get(drv->secy_id, channel,
3365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							&enabled);
3375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_anti_replay_window_get(drv->secy_id,
3385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							    channel, &win);
3395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (enabled)
3419839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		sa->lowest_pn = (next_pn > win) ? (next_pn - win) : 1;
3425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else
3439839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		sa->lowest_pn = next_pn;
3445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3459839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, sa->lowest_pn);
3465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
3485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3519839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
3525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
3545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
3559839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
3569839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3579839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
3589839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
3599839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
3605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3619839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, sa->an,
3629839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						 &sa->next_pn);
3635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3649839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, sa->next_pn);
3655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
3675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3709839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtint macsec_qca_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
3715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
3735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
3749839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
3755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3769839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
3779839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
3789839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
3795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3809839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
3819839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						 sa->next_pn);
3829839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
3839839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, sa->next_pn);
3845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
3865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_get_available_receive_sc(void *priv, u32 *channel)
3905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
3925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
3935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 sc_ch = 0;
3945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	bool in_use = FALSE;
3955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	for (sc_ch = 0; sc_ch < MAXSC; sc_ch++) {
3975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		ret = nss_macsec_secy_rx_sc_in_used_get(drv->secy_id, sc_ch,
3985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							&in_use);
3995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (ret)
4005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			continue;
4015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (!in_use) {
4035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			*channel = sc_ch;
4045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: channel=%d",
4055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				   __func__, *channel);
4065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			return 0;
4075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		}
4085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
4095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: no available channel", __func__);
4115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return -1;
4135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
4145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc,
4175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					unsigned int conf_offset,
4185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					int validation)
4195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
4205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
4215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int ret = 0;
4225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_rx_prc_lut_t entry;
4235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_rx_sc_validate_frame_e vf;
4245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum validate_frames validate_frames = validation;
4259839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
4269839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	const u8 *sci_addr = sc->sci.addr;
4279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u16 sci_port = be_to_host16(sc->sci.port);
4289839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
4299839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_get_available_receive_sc(priv, &channel);
4309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
4319839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
4325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
4345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* rx prc lut */
4365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&entry, 0, sizeof(entry));
4375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(entry.sci, sci_addr, ETH_ALEN);
4395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.sci[6] = (sci_port >> 8) & 0xf;
4405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.sci[7] = sci_port & 0xf;
4415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.sci_mask = 0xf;
4425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.valid = 1;
4445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.channel = channel;
4455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.action = FAL_RX_PRC_ACTION_PROCESS;
4465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.offset = conf_offset;
4475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* rx validate frame  */
4495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (validate_frames == Strict)
4505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		vf = FAL_RX_SC_VALIDATE_FRAME_STRICT;
4515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else if (validate_frames == Checked)
4525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		vf = FAL_RX_SC_VALIDATE_FRAME_CHECK;
4535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else
4545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		vf = FAL_RX_SC_VALIDATE_FRAME_DISABLED;
4555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_prc_lut_set(drv->secy_id, channel, &entry);
4575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_create(drv->secy_id, channel);
4585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_validate_frame_set(drv->secy_id, channel,
4595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							vf);
4605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_replay_protect_set(drv->secy_id, channel,
4615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							drv->replay_protect);
4625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_anti_replay_window_set(drv->secy_id,
4635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							    channel,
4645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt							    drv->replay_window);
4655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4669839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	macsec_qca_register_receive_channel(drv, sc, channel);
4679839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
4685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
4695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
4705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4729839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc)
4735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
4745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
4759839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
4765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_rx_prc_lut_t entry;
4779839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
4789839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
4799839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_receive_channel(priv, sc, &channel);
4809839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
4819839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
4825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
4845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* rx prc lut */
4865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&entry, 0, sizeof(entry));
4875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_sc_del(drv->secy_id, channel);
4895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_rx_prc_lut_set(drv->secy_id, channel, &entry);
4905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
4925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
4935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4959839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa)
4965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
4975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
4989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
4995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_rx_sak_t rx_sak;
5005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int i = 0;
5019839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
5029839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
5039839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
5049839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
5059839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
5065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s, channel=%d, an=%d, lpn=0x%x",
5089839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   __func__, channel, sa->an, sa->lowest_pn);
5095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&rx_sak, 0, sizeof(rx_sak));
5115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	for (i = 0; i < 16; i++)
5129839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		rx_sak.sak[i] = sa->pkey->key[15 - i];
5135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5149839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, sa->an);
5159839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, sa->an,
5169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					  &rx_sak);
5175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
5195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa)
5235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
5259839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
5269839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
5275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5289839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
5299839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
5309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
53178a5dac804c22aa6e4ec8226a864d3b0d6ccddbbDmitry Shmidt
5329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
5339839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   sa->an);
5349839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
5359839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
5369839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					    TRUE);
5375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
5395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5429839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa)
5435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
5459839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
5469839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
5479839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
5489839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
5499839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
5509839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
5515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5529839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
5539839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   sa->an);
5545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5559839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
5569839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					    FALSE);
5575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
5595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int macsec_qca_get_available_transmit_sc(void *priv, u32 *channel)
5635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
5655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 sc_ch = 0;
5665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	bool in_use = FALSE;
5675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	for (sc_ch = 0; sc_ch < MAXSC; sc_ch++) {
5699839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		if (nss_macsec_secy_tx_sc_in_used_get(drv->secy_id, sc_ch,
5709839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						      &in_use))
5715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			continue;
5725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (!in_use) {
5745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			*channel = sc_ch;
5755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			wpa_printf(MSG_DEBUG, "%s: channel=%d",
5765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				   __func__, *channel);
5775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			return 0;
5785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		}
5795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
5805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: no avaiable channel", __func__);
5825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return -1;
5845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5879839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc,
5885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					 unsigned int conf_offset)
5895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
5919839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
5925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_tx_class_lut_t entry;
5935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 psci[ETH_ALEN + 2];
5949839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
5959839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
5969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_get_available_transmit_sc(priv, &channel);
5979839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
5989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
5995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
6015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* class lut */
6035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&entry, 0, sizeof(entry));
6045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.valid = 1;
6065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.action = FAL_TX_CLASS_ACTION_FORWARD;
6075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	entry.channel = channel;
6085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6099839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	os_memcpy(psci, sc->sci.addr, ETH_ALEN);
6109839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	psci[6] = (sc->sci.port >> 8) & 0xf;
6119839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	psci[7] = sc->sci.port & 0xf;
6125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry);
6145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_sc_create(drv->secy_id, channel, psci, 8);
6155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_sc_protect_set(drv->secy_id, channel,
6165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt						 drv->protect_frames);
6175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_sc_confidentiality_offset_set(drv->secy_id,
6185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt								channel,
6195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt								conf_offset);
6205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6219839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	macsec_qca_register_transmit_channel(drv, sc, channel);
6229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
6235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
6245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc)
6285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
6309839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
6315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_tx_class_lut_t entry;
6329839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
6339839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
6349839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sc, &channel);
6359839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
6369839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
6375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
6395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* class lut */
6415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&entry, 0, sizeof(entry));
6425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry);
6445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_sc_del(drv->secy_id, channel);
6455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
6475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6509839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa)
6515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
6539839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
6545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 tci = 0;
6555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	fal_tx_sak_t tx_sak;
6565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int i;
6579839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
6589839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
6599839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
6609839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
6619839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
6625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG,
6645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		   "%s: channel=%d, an=%d, next_pn=0x%x, confidentiality=%d",
6659839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   __func__, channel, sa->an, sa->next_pn, sa->confidentiality);
6665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (drv->always_include_sci)
6685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		tci |= TCI_SC;
6695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else if (drv->use_es)
6705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		tci |= TCI_ES;
6715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	else if (drv->use_scb)
6725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		tci |= TCI_SCB;
6735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6749839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (sa->confidentiality)
6755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		tci |= TCI_E | TCI_C;
6765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memset(&tx_sak, 0, sizeof(tx_sak));
6785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	for (i = 0; i < 16; i++)
6799839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		tx_sak.sak[i] = sa->pkey->key[15 - i];
6805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6819839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
6829839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt						 sa->next_pn);
6839839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, sa->an,
6849839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					  &tx_sak);
6855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ret += nss_macsec_secy_tx_sc_tci_7_2_set(drv->secy_id, channel,
6865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt						 (tci >> 2));
6879839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, sa->an);
6885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
6905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6939839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa)
6945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
6969839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
6979839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
6989839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
6999839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
7009839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
7019839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
7025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7039839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
7049839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   sa->an);
7055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7069839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
7079839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					    TRUE);
7085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
7105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
7115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7139839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidtstatic int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa)
7145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
7155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct macsec_qca_data *drv = priv;
7169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	int ret;
7179839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	u32 channel;
7189839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt
7199839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
7209839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	if (ret != 0)
7219839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		return ret;
7225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7239839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
7249839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt		   sa->an);
7255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7269839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
7279839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt					    FALSE);
7285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return ret;
7305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
7315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst struct wpa_driver_ops wpa_driver_macsec_qca_ops = {
7345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.name = "macsec_qca",
7355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.desc = "QCA MACsec Ethernet driver",
736abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	.get_ssid = driver_wired_get_ssid,
737abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	.get_bssid = driver_wired_get_bssid,
738abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt	.get_capa = driver_wired_get_capa,
7395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.init = macsec_qca_init,
7405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.deinit = macsec_qca_deinit,
7415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.macsec_init = macsec_qca_macsec_init,
7435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.macsec_deinit = macsec_qca_macsec_deinit,
7449839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt	.macsec_get_capability = macsec_qca_get_capability,
7455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.enable_protect_frames = macsec_qca_enable_protect_frames,
7465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.set_replay_protect = macsec_qca_set_replay_protect,
7475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.set_current_cipher_suite = macsec_qca_set_current_cipher_suite,
7485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.enable_controlled_port = macsec_qca_enable_controlled_port,
7495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.get_receive_lowest_pn = macsec_qca_get_receive_lowest_pn,
7505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.get_transmit_next_pn = macsec_qca_get_transmit_next_pn,
7515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.set_transmit_next_pn = macsec_qca_set_transmit_next_pn,
7525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.create_receive_sc = macsec_qca_create_receive_sc,
7535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.delete_receive_sc = macsec_qca_delete_receive_sc,
7545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.create_receive_sa = macsec_qca_create_receive_sa,
7555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.enable_receive_sa = macsec_qca_enable_receive_sa,
7565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.disable_receive_sa = macsec_qca_disable_receive_sa,
7575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.create_transmit_sc = macsec_qca_create_transmit_sc,
7585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.delete_transmit_sc = macsec_qca_delete_transmit_sc,
7595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.create_transmit_sa = macsec_qca_create_transmit_sa,
7605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.enable_transmit_sa = macsec_qca_enable_transmit_sa,
7615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	.disable_transmit_sa = macsec_qca_disable_transmit_sa,
7625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
763