driver_macsec_qca.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. /*
  2. * Wired Ethernet driver interface for QCA MACsec driver
  3. * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2004, Gunter Burchardt <tira@isx.de>
  5. * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
  6. *
  7. * This software may be distributed under the terms of the BSD license.
  8. * See README for more details.
  9. */
  10. #include "includes.h"
  11. #include <sys/ioctl.h>
  12. #include <net/if.h>
  13. #include <inttypes.h>
  14. #ifdef __linux__
  15. #include <netpacket/packet.h>
  16. #include <net/if_arp.h>
  17. #include <net/if.h>
  18. #endif /* __linux__ */
  19. #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
  20. #include <net/if_dl.h>
  21. #include <net/if_media.h>
  22. #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
  23. #ifdef __sun__
  24. #include <sys/sockio.h>
  25. #endif /* __sun__ */
  26. #include "utils/common.h"
  27. #include "utils/eloop.h"
  28. #include "common/defs.h"
  29. #include "common/ieee802_1x_defs.h"
  30. #include "pae/ieee802_1x_kay.h"
  31. #include "driver.h"
  32. #include "driver_wired_common.h"
  33. #include "nss_macsec_secy.h"
  34. #include "nss_macsec_secy_rx.h"
  35. #include "nss_macsec_secy_tx.h"
  36. #define MAXSC 16
  37. /* TCI field definition */
  38. #define TCI_ES 0x40
  39. #define TCI_SC 0x20
  40. #define TCI_SCB 0x10
  41. #define TCI_E 0x08
  42. #define TCI_C 0x04
  43. #ifdef _MSC_VER
  44. #pragma pack(push, 1)
  45. #endif /* _MSC_VER */
  46. #ifdef _MSC_VER
  47. #pragma pack(pop)
  48. #endif /* _MSC_VER */
  49. struct channel_map {
  50. struct ieee802_1x_mka_sci sci;
  51. };
  52. struct macsec_qca_data {
  53. struct driver_wired_common_data common;
  54. u32 secy_id;
  55. /* shadow */
  56. Boolean always_include_sci;
  57. Boolean use_es;
  58. Boolean use_scb;
  59. Boolean protect_frames;
  60. Boolean replay_protect;
  61. u32 replay_window;
  62. struct channel_map receive_channel_map[MAXSC];
  63. struct channel_map transmit_channel_map[MAXSC];
  64. };
  65. static void __macsec_drv_init(struct macsec_qca_data *drv)
  66. {
  67. int ret = 0;
  68. fal_rx_ctl_filt_t rx_ctl_filt;
  69. fal_tx_ctl_filt_t tx_ctl_filt;
  70. wpa_printf(MSG_INFO, "%s: secy_id=%d", __func__, drv->secy_id);
  71. /* Enable Secy and Let EAPoL bypass */
  72. ret = nss_macsec_secy_en_set(drv->secy_id, TRUE);
  73. if (ret)
  74. wpa_printf(MSG_ERROR, "nss_macsec_secy_en_set: FAIL");
  75. ret = nss_macsec_secy_sc_sa_mapping_mode_set(drv->secy_id,
  76. FAL_SC_SA_MAP_1_4);
  77. if (ret)
  78. wpa_printf(MSG_ERROR,
  79. "nss_macsec_secy_sc_sa_mapping_mode_set: FAIL");
  80. os_memset(&rx_ctl_filt, 0, sizeof(rx_ctl_filt));
  81. rx_ctl_filt.bypass = 1;
  82. rx_ctl_filt.match_type = IG_CTL_COMPARE_ETHER_TYPE;
  83. rx_ctl_filt.match_mask = 0xffff;
  84. rx_ctl_filt.ether_type_da_range = 0x888e;
  85. ret = nss_macsec_secy_rx_ctl_filt_set(drv->secy_id, 0, &rx_ctl_filt);
  86. if (ret)
  87. wpa_printf(MSG_ERROR, "nss_macsec_secy_rx_ctl_filt_set: FAIL");
  88. os_memset(&tx_ctl_filt, 0, sizeof(tx_ctl_filt));
  89. tx_ctl_filt.bypass = 1;
  90. tx_ctl_filt.match_type = EG_CTL_COMPARE_ETHER_TYPE;
  91. tx_ctl_filt.match_mask = 0xffff;
  92. tx_ctl_filt.ether_type_da_range = 0x888e;
  93. ret = nss_macsec_secy_tx_ctl_filt_set(drv->secy_id, 0, &tx_ctl_filt);
  94. if (ret)
  95. wpa_printf(MSG_ERROR, "nss_macsec_secy_tx_ctl_filt_set: FAIL");
  96. }
  97. static void __macsec_drv_deinit(struct macsec_qca_data *drv)
  98. {
  99. nss_macsec_secy_en_set(drv->secy_id, FALSE);
  100. nss_macsec_secy_rx_sc_del_all(drv->secy_id);
  101. nss_macsec_secy_tx_sc_del_all(drv->secy_id);
  102. }
  103. static void * macsec_qca_init(void *ctx, const char *ifname)
  104. {
  105. struct macsec_qca_data *drv;
  106. drv = os_zalloc(sizeof(*drv));
  107. if (drv == NULL)
  108. return NULL;
  109. /* Board specific settings */
  110. if (os_memcmp("eth2", ifname, 4) == 0)
  111. drv->secy_id = 1;
  112. else if (os_memcmp("eth3", ifname, 4) == 0)
  113. drv->secy_id = 2;
  114. else
  115. drv->secy_id = -1;
  116. if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
  117. os_free(drv);
  118. return NULL;
  119. }
  120. return drv;
  121. }
  122. static void macsec_qca_deinit(void *priv)
  123. {
  124. struct macsec_qca_data *drv = priv;
  125. driver_wired_deinit_common(&drv->common);
  126. os_free(drv);
  127. }
  128. static int macsec_qca_macsec_init(void *priv, struct macsec_init_params *params)
  129. {
  130. struct macsec_qca_data *drv = priv;
  131. drv->always_include_sci = params->always_include_sci;
  132. drv->use_es = params->use_es;
  133. drv->use_scb = params->use_scb;
  134. wpa_printf(MSG_DEBUG, "%s: es=%d, scb=%d, sci=%d",
  135. __func__, drv->use_es, drv->use_scb,
  136. drv->always_include_sci);
  137. __macsec_drv_init(drv);
  138. return 0;
  139. }
  140. static int macsec_qca_macsec_deinit(void *priv)
  141. {
  142. struct macsec_qca_data *drv = priv;
  143. wpa_printf(MSG_DEBUG, "%s", __func__);
  144. __macsec_drv_deinit(drv);
  145. return 0;
  146. }
  147. static int macsec_qca_get_capability(void *priv, enum macsec_cap *cap)
  148. {
  149. wpa_printf(MSG_DEBUG, "%s", __func__);
  150. *cap = MACSEC_CAP_INTEG_AND_CONF_0_30_50;
  151. return 0;
  152. }
  153. static int macsec_qca_enable_protect_frames(void *priv, Boolean enabled)
  154. {
  155. struct macsec_qca_data *drv = priv;
  156. int ret = 0;
  157. wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
  158. drv->protect_frames = enabled;
  159. return ret;
  160. }
  161. static int macsec_qca_set_replay_protect(void *priv, Boolean enabled,
  162. unsigned int window)
  163. {
  164. struct macsec_qca_data *drv = priv;
  165. int ret = 0;
  166. wpa_printf(MSG_DEBUG, "%s: enabled=%d, win=%u",
  167. __func__, enabled, window);
  168. drv->replay_protect = enabled;
  169. drv->replay_window = window;
  170. return ret;
  171. }
  172. static int macsec_qca_set_current_cipher_suite(void *priv, u64 cs)
  173. {
  174. if (cs != CS_ID_GCM_AES_128) {
  175. wpa_printf(MSG_ERROR,
  176. "%s: NOT supported CipherSuite: %016" PRIx64,
  177. __func__, cs);
  178. return -1;
  179. }
  180. /* Support default Cipher Suite 0080020001000001 (GCM-AES-128) */
  181. wpa_printf(MSG_DEBUG, "%s: default support aes-gcm-128", __func__);
  182. return 0;
  183. }
  184. static int macsec_qca_enable_controlled_port(void *priv, Boolean enabled)
  185. {
  186. struct macsec_qca_data *drv = priv;
  187. int ret = 0;
  188. wpa_printf(MSG_DEBUG, "%s: enable=%d", __func__, enabled);
  189. ret += nss_macsec_secy_controlled_port_en_set(drv->secy_id, enabled);
  190. return ret;
  191. }
  192. static int macsec_qca_lookup_channel(struct channel_map *map,
  193. struct ieee802_1x_mka_sci *sci,
  194. u32 *channel)
  195. {
  196. u32 i;
  197. for (i = 0; i < MAXSC; i++) {
  198. if (os_memcmp(&map[i].sci, sci,
  199. sizeof(struct ieee802_1x_mka_sci)) == 0) {
  200. *channel = i;
  201. return 0;
  202. }
  203. }
  204. return -1;
  205. }
  206. static void macsec_qca_register_channel(struct channel_map *map,
  207. struct ieee802_1x_mka_sci *sci,
  208. u32 channel)
  209. {
  210. os_memcpy(&map[channel].sci, sci, sizeof(struct ieee802_1x_mka_sci));
  211. }
  212. static int macsec_qca_lookup_receive_channel(struct macsec_qca_data *drv,
  213. struct receive_sc *sc,
  214. u32 *channel)
  215. {
  216. return macsec_qca_lookup_channel(drv->receive_channel_map, &sc->sci,
  217. channel);
  218. }
  219. static void macsec_qca_register_receive_channel(struct macsec_qca_data *drv,
  220. struct receive_sc *sc,
  221. u32 channel)
  222. {
  223. macsec_qca_register_channel(drv->receive_channel_map, &sc->sci,
  224. channel);
  225. }
  226. static int macsec_qca_lookup_transmit_channel(struct macsec_qca_data *drv,
  227. struct transmit_sc *sc,
  228. u32 *channel)
  229. {
  230. return macsec_qca_lookup_channel(drv->transmit_channel_map, &sc->sci,
  231. channel);
  232. }
  233. static void macsec_qca_register_transmit_channel(struct macsec_qca_data *drv,
  234. struct transmit_sc *sc,
  235. u32 channel)
  236. {
  237. macsec_qca_register_channel(drv->transmit_channel_map, &sc->sci,
  238. channel);
  239. }
  240. static int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa)
  241. {
  242. struct macsec_qca_data *drv = priv;
  243. int ret = 0;
  244. u32 next_pn = 0;
  245. bool enabled = FALSE;
  246. u32 win;
  247. u32 channel;
  248. ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
  249. if (ret != 0)
  250. return ret;
  251. ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, sa->an,
  252. &next_pn);
  253. ret += nss_macsec_secy_rx_sc_replay_protect_get(drv->secy_id, channel,
  254. &enabled);
  255. ret += nss_macsec_secy_rx_sc_anti_replay_window_get(drv->secy_id,
  256. channel, &win);
  257. if (enabled)
  258. sa->lowest_pn = (next_pn > win) ? (next_pn - win) : 1;
  259. else
  260. sa->lowest_pn = next_pn;
  261. wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, sa->lowest_pn);
  262. return ret;
  263. }
  264. static int macsec_qca_get_transmit_next_pn(void *priv, struct transmit_sa *sa)
  265. {
  266. struct macsec_qca_data *drv = priv;
  267. int ret = 0;
  268. u32 channel;
  269. ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
  270. if (ret != 0)
  271. return ret;
  272. ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, sa->an,
  273. &sa->next_pn);
  274. wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, sa->next_pn);
  275. return ret;
  276. }
  277. int macsec_qca_set_transmit_next_pn(void *priv, struct transmit_sa *sa)
  278. {
  279. struct macsec_qca_data *drv = priv;
  280. int ret = 0;
  281. u32 channel;
  282. ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
  283. if (ret != 0)
  284. return ret;
  285. ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
  286. sa->next_pn);
  287. wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, sa->next_pn);
  288. return ret;
  289. }
  290. static int macsec_qca_get_available_receive_sc(void *priv, u32 *channel)
  291. {
  292. struct macsec_qca_data *drv = priv;
  293. int ret = 0;
  294. u32 sc_ch = 0;
  295. bool in_use = FALSE;
  296. for (sc_ch = 0; sc_ch < MAXSC; sc_ch++) {
  297. ret = nss_macsec_secy_rx_sc_in_used_get(drv->secy_id, sc_ch,
  298. &in_use);
  299. if (ret)
  300. continue;
  301. if (!in_use) {
  302. *channel = sc_ch;
  303. wpa_printf(MSG_DEBUG, "%s: channel=%d",
  304. __func__, *channel);
  305. return 0;
  306. }
  307. }
  308. wpa_printf(MSG_DEBUG, "%s: no available channel", __func__);
  309. return -1;
  310. }
  311. static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc,
  312. unsigned int conf_offset,
  313. int validation)
  314. {
  315. struct macsec_qca_data *drv = priv;
  316. int ret = 0;
  317. fal_rx_prc_lut_t entry;
  318. fal_rx_sc_validate_frame_e vf;
  319. enum validate_frames validate_frames = validation;
  320. u32 channel;
  321. const u8 *sci_addr = sc->sci.addr;
  322. u16 sci_port = be_to_host16(sc->sci.port);
  323. ret = macsec_qca_get_available_receive_sc(priv, &channel);
  324. if (ret != 0)
  325. return ret;
  326. wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
  327. /* rx prc lut */
  328. os_memset(&entry, 0, sizeof(entry));
  329. os_memcpy(entry.sci, sci_addr, ETH_ALEN);
  330. entry.sci[6] = (sci_port >> 8) & 0xf;
  331. entry.sci[7] = sci_port & 0xf;
  332. entry.sci_mask = 0xf;
  333. entry.valid = 1;
  334. entry.channel = channel;
  335. entry.action = FAL_RX_PRC_ACTION_PROCESS;
  336. entry.offset = conf_offset;
  337. /* rx validate frame */
  338. if (validate_frames == Strict)
  339. vf = FAL_RX_SC_VALIDATE_FRAME_STRICT;
  340. else if (validate_frames == Checked)
  341. vf = FAL_RX_SC_VALIDATE_FRAME_CHECK;
  342. else
  343. vf = FAL_RX_SC_VALIDATE_FRAME_DISABLED;
  344. ret += nss_macsec_secy_rx_prc_lut_set(drv->secy_id, channel, &entry);
  345. ret += nss_macsec_secy_rx_sc_create(drv->secy_id, channel);
  346. ret += nss_macsec_secy_rx_sc_validate_frame_set(drv->secy_id, channel,
  347. vf);
  348. ret += nss_macsec_secy_rx_sc_replay_protect_set(drv->secy_id, channel,
  349. drv->replay_protect);
  350. ret += nss_macsec_secy_rx_sc_anti_replay_window_set(drv->secy_id,
  351. channel,
  352. drv->replay_window);
  353. macsec_qca_register_receive_channel(drv, sc, channel);
  354. return ret;
  355. }
  356. static int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc)
  357. {
  358. struct macsec_qca_data *drv = priv;
  359. int ret;
  360. fal_rx_prc_lut_t entry;
  361. u32 channel;
  362. ret = macsec_qca_lookup_receive_channel(priv, sc, &channel);
  363. if (ret != 0)
  364. return ret;
  365. wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
  366. /* rx prc lut */
  367. os_memset(&entry, 0, sizeof(entry));
  368. ret += nss_macsec_secy_rx_sc_del(drv->secy_id, channel);
  369. ret += nss_macsec_secy_rx_prc_lut_set(drv->secy_id, channel, &entry);
  370. return ret;
  371. }
  372. static int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa)
  373. {
  374. struct macsec_qca_data *drv = priv;
  375. int ret;
  376. fal_rx_sak_t rx_sak;
  377. int i = 0;
  378. u32 channel;
  379. ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
  380. if (ret != 0)
  381. return ret;
  382. wpa_printf(MSG_DEBUG, "%s, channel=%d, an=%d, lpn=0x%x",
  383. __func__, channel, sa->an, sa->lowest_pn);
  384. os_memset(&rx_sak, 0, sizeof(rx_sak));
  385. for (i = 0; i < 16; i++)
  386. rx_sak.sak[i] = sa->pkey->key[15 - i];
  387. ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, sa->an);
  388. ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, sa->an,
  389. &rx_sak);
  390. return ret;
  391. }
  392. static int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa)
  393. {
  394. struct macsec_qca_data *drv = priv;
  395. int ret;
  396. u32 channel;
  397. ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
  398. if (ret != 0)
  399. return ret;
  400. wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
  401. sa->an);
  402. ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
  403. TRUE);
  404. return ret;
  405. }
  406. static int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa)
  407. {
  408. struct macsec_qca_data *drv = priv;
  409. int ret;
  410. u32 channel;
  411. ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel);
  412. if (ret != 0)
  413. return ret;
  414. wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
  415. sa->an);
  416. ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an,
  417. FALSE);
  418. return ret;
  419. }
  420. static int macsec_qca_get_available_transmit_sc(void *priv, u32 *channel)
  421. {
  422. struct macsec_qca_data *drv = priv;
  423. u32 sc_ch = 0;
  424. bool in_use = FALSE;
  425. for (sc_ch = 0; sc_ch < MAXSC; sc_ch++) {
  426. if (nss_macsec_secy_tx_sc_in_used_get(drv->secy_id, sc_ch,
  427. &in_use))
  428. continue;
  429. if (!in_use) {
  430. *channel = sc_ch;
  431. wpa_printf(MSG_DEBUG, "%s: channel=%d",
  432. __func__, *channel);
  433. return 0;
  434. }
  435. }
  436. wpa_printf(MSG_DEBUG, "%s: no avaiable channel", __func__);
  437. return -1;
  438. }
  439. static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc,
  440. unsigned int conf_offset)
  441. {
  442. struct macsec_qca_data *drv = priv;
  443. int ret;
  444. fal_tx_class_lut_t entry;
  445. u8 psci[ETH_ALEN + 2];
  446. u32 channel;
  447. ret = macsec_qca_get_available_transmit_sc(priv, &channel);
  448. if (ret != 0)
  449. return ret;
  450. wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
  451. /* class lut */
  452. os_memset(&entry, 0, sizeof(entry));
  453. entry.valid = 1;
  454. entry.action = FAL_TX_CLASS_ACTION_FORWARD;
  455. entry.channel = channel;
  456. os_memcpy(psci, sc->sci.addr, ETH_ALEN);
  457. psci[6] = (sc->sci.port >> 8) & 0xf;
  458. psci[7] = sc->sci.port & 0xf;
  459. ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry);
  460. ret += nss_macsec_secy_tx_sc_create(drv->secy_id, channel, psci, 8);
  461. ret += nss_macsec_secy_tx_sc_protect_set(drv->secy_id, channel,
  462. drv->protect_frames);
  463. ret += nss_macsec_secy_tx_sc_confidentiality_offset_set(drv->secy_id,
  464. channel,
  465. conf_offset);
  466. macsec_qca_register_transmit_channel(drv, sc, channel);
  467. return ret;
  468. }
  469. static int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc)
  470. {
  471. struct macsec_qca_data *drv = priv;
  472. int ret;
  473. fal_tx_class_lut_t entry;
  474. u32 channel;
  475. ret = macsec_qca_lookup_transmit_channel(priv, sc, &channel);
  476. if (ret != 0)
  477. return ret;
  478. wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel);
  479. /* class lut */
  480. os_memset(&entry, 0, sizeof(entry));
  481. ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry);
  482. ret += nss_macsec_secy_tx_sc_del(drv->secy_id, channel);
  483. return ret;
  484. }
  485. static int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa)
  486. {
  487. struct macsec_qca_data *drv = priv;
  488. int ret;
  489. u8 tci = 0;
  490. fal_tx_sak_t tx_sak;
  491. int i;
  492. u32 channel;
  493. ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
  494. if (ret != 0)
  495. return ret;
  496. wpa_printf(MSG_DEBUG,
  497. "%s: channel=%d, an=%d, next_pn=0x%x, confidentiality=%d",
  498. __func__, channel, sa->an, sa->next_pn, sa->confidentiality);
  499. if (drv->always_include_sci)
  500. tci |= TCI_SC;
  501. else if (drv->use_es)
  502. tci |= TCI_ES;
  503. else if (drv->use_scb)
  504. tci |= TCI_SCB;
  505. if (sa->confidentiality)
  506. tci |= TCI_E | TCI_C;
  507. os_memset(&tx_sak, 0, sizeof(tx_sak));
  508. for (i = 0; i < 16; i++)
  509. tx_sak.sak[i] = sa->pkey->key[15 - i];
  510. ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an,
  511. sa->next_pn);
  512. ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, sa->an,
  513. &tx_sak);
  514. ret += nss_macsec_secy_tx_sc_tci_7_2_set(drv->secy_id, channel,
  515. (tci >> 2));
  516. ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, sa->an);
  517. return ret;
  518. }
  519. static int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa)
  520. {
  521. struct macsec_qca_data *drv = priv;
  522. int ret;
  523. u32 channel;
  524. ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
  525. if (ret != 0)
  526. return ret;
  527. wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
  528. sa->an);
  529. ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
  530. TRUE);
  531. return ret;
  532. }
  533. static int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa)
  534. {
  535. struct macsec_qca_data *drv = priv;
  536. int ret;
  537. u32 channel;
  538. ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel);
  539. if (ret != 0)
  540. return ret;
  541. wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel,
  542. sa->an);
  543. ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an,
  544. FALSE);
  545. return ret;
  546. }
  547. const struct wpa_driver_ops wpa_driver_macsec_qca_ops = {
  548. .name = "macsec_qca",
  549. .desc = "QCA MACsec Ethernet driver",
  550. .get_ssid = driver_wired_get_ssid,
  551. .get_bssid = driver_wired_get_bssid,
  552. .get_capa = driver_wired_get_capa,
  553. .init = macsec_qca_init,
  554. .deinit = macsec_qca_deinit,
  555. .macsec_init = macsec_qca_macsec_init,
  556. .macsec_deinit = macsec_qca_macsec_deinit,
  557. .macsec_get_capability = macsec_qca_get_capability,
  558. .enable_protect_frames = macsec_qca_enable_protect_frames,
  559. .set_replay_protect = macsec_qca_set_replay_protect,
  560. .set_current_cipher_suite = macsec_qca_set_current_cipher_suite,
  561. .enable_controlled_port = macsec_qca_enable_controlled_port,
  562. .get_receive_lowest_pn = macsec_qca_get_receive_lowest_pn,
  563. .get_transmit_next_pn = macsec_qca_get_transmit_next_pn,
  564. .set_transmit_next_pn = macsec_qca_set_transmit_next_pn,
  565. .create_receive_sc = macsec_qca_create_receive_sc,
  566. .delete_receive_sc = macsec_qca_delete_receive_sc,
  567. .create_receive_sa = macsec_qca_create_receive_sa,
  568. .enable_receive_sa = macsec_qca_enable_receive_sa,
  569. .disable_receive_sa = macsec_qca_disable_receive_sa,
  570. .create_transmit_sc = macsec_qca_create_transmit_sc,
  571. .delete_transmit_sc = macsec_qca_delete_transmit_sc,
  572. .create_transmit_sa = macsec_qca_create_transmit_sa,
  573. .enable_transmit_sa = macsec_qca_enable_transmit_sa,
  574. .disable_transmit_sa = macsec_qca_disable_transmit_sa,
  575. };