18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Authors:
58c2ecf20Sopenharmony_ci * Alexander Aring <aar@pengutronix.de>
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Based on: net/mac80211/cfg.c
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <net/rtnetlink.h>
118c2ecf20Sopenharmony_ci#include <net/cfg802154.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "ieee802154_i.h"
148c2ecf20Sopenharmony_ci#include "driver-ops.h"
158c2ecf20Sopenharmony_ci#include "cfg.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cistatic struct net_device *
188c2ecf20Sopenharmony_ciieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
198c2ecf20Sopenharmony_ci				const char *name,
208c2ecf20Sopenharmony_ci				unsigned char name_assign_type, int type)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
238c2ecf20Sopenharmony_ci	struct net_device *dev;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	rtnl_lock();
268c2ecf20Sopenharmony_ci	dev = ieee802154_if_add(local, name, name_assign_type, type,
278c2ecf20Sopenharmony_ci				cpu_to_le64(0x0000000000000000ULL));
288c2ecf20Sopenharmony_ci	rtnl_unlock();
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	return dev;
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
348c2ecf20Sopenharmony_ci					    struct net_device *dev)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	ieee802154_if_remove(sdata);
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
428c2ecf20Sopenharmony_cistatic int ieee802154_suspend(struct wpan_phy *wpan_phy)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	if (!local->open_count)
478c2ecf20Sopenharmony_ci		goto suspend;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	ieee802154_stop_queue(&local->hw);
508c2ecf20Sopenharmony_ci	synchronize_net();
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/* stop hardware - this must stop RX */
538c2ecf20Sopenharmony_ci	ieee802154_stop_device(local);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cisuspend:
568c2ecf20Sopenharmony_ci	local->suspended = true;
578c2ecf20Sopenharmony_ci	return 0;
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic int ieee802154_resume(struct wpan_phy *wpan_phy)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
638c2ecf20Sopenharmony_ci	int ret;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* nothing to do if HW shouldn't run */
668c2ecf20Sopenharmony_ci	if (!local->open_count)
678c2ecf20Sopenharmony_ci		goto wake_up;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	/* restart hardware */
708c2ecf20Sopenharmony_ci	ret = drv_start(local);
718c2ecf20Sopenharmony_ci	if (ret)
728c2ecf20Sopenharmony_ci		return ret;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciwake_up:
758c2ecf20Sopenharmony_ci	ieee802154_wake_queue(&local->hw);
768c2ecf20Sopenharmony_ci	local->suspended = false;
778c2ecf20Sopenharmony_ci	return 0;
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci#else
808c2ecf20Sopenharmony_ci#define ieee802154_suspend NULL
818c2ecf20Sopenharmony_ci#define ieee802154_resume NULL
828c2ecf20Sopenharmony_ci#endif
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic int
858c2ecf20Sopenharmony_ciieee802154_add_iface(struct wpan_phy *phy, const char *name,
868c2ecf20Sopenharmony_ci		     unsigned char name_assign_type,
878c2ecf20Sopenharmony_ci		     enum nl802154_iftype type, __le64 extended_addr)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(phy);
908c2ecf20Sopenharmony_ci	struct net_device *err;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	err = ieee802154_if_add(local, name, name_assign_type, type,
938c2ecf20Sopenharmony_ci				extended_addr);
948c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(err);
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic int
988c2ecf20Sopenharmony_ciieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev));
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	return 0;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int
1068c2ecf20Sopenharmony_ciieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
1098c2ecf20Sopenharmony_ci	int ret;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	ASSERT_RTNL();
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	if (wpan_phy->current_page == page &&
1148c2ecf20Sopenharmony_ci	    wpan_phy->current_channel == channel)
1158c2ecf20Sopenharmony_ci		return 0;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	ret = drv_set_channel(local, page, channel);
1188c2ecf20Sopenharmony_ci	if (!ret) {
1198c2ecf20Sopenharmony_ci		wpan_phy->current_page = page;
1208c2ecf20Sopenharmony_ci		wpan_phy->current_channel = channel;
1218c2ecf20Sopenharmony_ci	}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	return ret;
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic int
1278c2ecf20Sopenharmony_ciieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
1288c2ecf20Sopenharmony_ci			const struct wpan_phy_cca *cca)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
1318c2ecf20Sopenharmony_ci	int ret;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	ASSERT_RTNL();
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
1368c2ecf20Sopenharmony_ci		return 0;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	ret = drv_set_cca_mode(local, cca);
1398c2ecf20Sopenharmony_ci	if (!ret)
1408c2ecf20Sopenharmony_ci		wpan_phy->cca = *cca;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	return ret;
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic int
1468c2ecf20Sopenharmony_ciieee802154_set_cca_ed_level(struct wpan_phy *wpan_phy, s32 ed_level)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
1498c2ecf20Sopenharmony_ci	int ret;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	ASSERT_RTNL();
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	if (wpan_phy->cca_ed_level == ed_level)
1548c2ecf20Sopenharmony_ci		return 0;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	ret = drv_set_cca_ed_level(local, ed_level);
1578c2ecf20Sopenharmony_ci	if (!ret)
1588c2ecf20Sopenharmony_ci		wpan_phy->cca_ed_level = ed_level;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	return ret;
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic int
1648c2ecf20Sopenharmony_ciieee802154_set_tx_power(struct wpan_phy *wpan_phy, s32 power)
1658c2ecf20Sopenharmony_ci{
1668c2ecf20Sopenharmony_ci	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
1678c2ecf20Sopenharmony_ci	int ret;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	ASSERT_RTNL();
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	if (wpan_phy->transmit_power == power)
1728c2ecf20Sopenharmony_ci		return 0;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	ret = drv_set_tx_power(local, power);
1758c2ecf20Sopenharmony_ci	if (!ret)
1768c2ecf20Sopenharmony_ci		wpan_phy->transmit_power = power;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	return ret;
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic int
1828c2ecf20Sopenharmony_ciieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
1838c2ecf20Sopenharmony_ci		      __le16 pan_id)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	int ret;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	ASSERT_RTNL();
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	if (wpan_dev->pan_id == pan_id)
1908c2ecf20Sopenharmony_ci		return 0;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	ret = mac802154_wpan_update_llsec(wpan_dev->netdev);
1938c2ecf20Sopenharmony_ci	if (!ret)
1948c2ecf20Sopenharmony_ci		wpan_dev->pan_id = pan_id;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	return ret;
1978c2ecf20Sopenharmony_ci}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic int
2008c2ecf20Sopenharmony_ciieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
2018c2ecf20Sopenharmony_ci				struct wpan_dev *wpan_dev,
2028c2ecf20Sopenharmony_ci				u8 min_be, u8 max_be)
2038c2ecf20Sopenharmony_ci{
2048c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	wpan_dev->min_be = min_be;
2078c2ecf20Sopenharmony_ci	wpan_dev->max_be = max_be;
2088c2ecf20Sopenharmony_ci	return 0;
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_cistatic int
2128c2ecf20Sopenharmony_ciieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
2138c2ecf20Sopenharmony_ci			  __le16 short_addr)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	wpan_dev->short_addr = short_addr;
2188c2ecf20Sopenharmony_ci	return 0;
2198c2ecf20Sopenharmony_ci}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistatic int
2228c2ecf20Sopenharmony_ciieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
2238c2ecf20Sopenharmony_ci				 struct wpan_dev *wpan_dev,
2248c2ecf20Sopenharmony_ci				 u8 max_csma_backoffs)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	wpan_dev->csma_retries = max_csma_backoffs;
2298c2ecf20Sopenharmony_ci	return 0;
2308c2ecf20Sopenharmony_ci}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic int
2338c2ecf20Sopenharmony_ciieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
2348c2ecf20Sopenharmony_ci				 struct wpan_dev *wpan_dev,
2358c2ecf20Sopenharmony_ci				 s8 max_frame_retries)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	wpan_dev->frame_retries = max_frame_retries;
2408c2ecf20Sopenharmony_ci	return 0;
2418c2ecf20Sopenharmony_ci}
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_cistatic int
2448c2ecf20Sopenharmony_ciieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
2458c2ecf20Sopenharmony_ci			bool mode)
2468c2ecf20Sopenharmony_ci{
2478c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	wpan_dev->lbt = mode;
2508c2ecf20Sopenharmony_ci	return 0;
2518c2ecf20Sopenharmony_ci}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_cistatic int
2548c2ecf20Sopenharmony_ciieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
2558c2ecf20Sopenharmony_ci			      struct wpan_dev *wpan_dev, bool ackreq)
2568c2ecf20Sopenharmony_ci{
2578c2ecf20Sopenharmony_ci	ASSERT_RTNL();
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	wpan_dev->ackreq = ackreq;
2608c2ecf20Sopenharmony_ci	return 0;
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2648c2ecf20Sopenharmony_cistatic void
2658c2ecf20Sopenharmony_ciieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
2668c2ecf20Sopenharmony_ci			   struct wpan_dev *wpan_dev,
2678c2ecf20Sopenharmony_ci			   struct ieee802154_llsec_table **table)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
2708c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	*table = &sdata->sec.table;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_cistatic void
2768c2ecf20Sopenharmony_ciieee802154_lock_llsec_table(struct wpan_phy *wpan_phy,
2778c2ecf20Sopenharmony_ci			    struct wpan_dev *wpan_dev)
2788c2ecf20Sopenharmony_ci{
2798c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
2808c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_cistatic void
2868c2ecf20Sopenharmony_ciieee802154_unlock_llsec_table(struct wpan_phy *wpan_phy,
2878c2ecf20Sopenharmony_ci			      struct wpan_dev *wpan_dev)
2888c2ecf20Sopenharmony_ci{
2898c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
2908c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
2938c2ecf20Sopenharmony_ci}
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_cistatic int
2968c2ecf20Sopenharmony_ciieee802154_set_llsec_params(struct wpan_phy *wpan_phy,
2978c2ecf20Sopenharmony_ci			    struct wpan_dev *wpan_dev,
2988c2ecf20Sopenharmony_ci			    const struct ieee802154_llsec_params *params,
2998c2ecf20Sopenharmony_ci			    int changed)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3028c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3038c2ecf20Sopenharmony_ci	int res;
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3068c2ecf20Sopenharmony_ci	res = mac802154_llsec_set_params(&sdata->sec, params, changed);
3078c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	return res;
3108c2ecf20Sopenharmony_ci}
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_cistatic int
3138c2ecf20Sopenharmony_ciieee802154_get_llsec_params(struct wpan_phy *wpan_phy,
3148c2ecf20Sopenharmony_ci			    struct wpan_dev *wpan_dev,
3158c2ecf20Sopenharmony_ci			    struct ieee802154_llsec_params *params)
3168c2ecf20Sopenharmony_ci{
3178c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3188c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3198c2ecf20Sopenharmony_ci	int res;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3228c2ecf20Sopenharmony_ci	res = mac802154_llsec_get_params(&sdata->sec, params);
3238c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	return res;
3268c2ecf20Sopenharmony_ci}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_cistatic int
3298c2ecf20Sopenharmony_ciieee802154_add_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
3308c2ecf20Sopenharmony_ci			 const struct ieee802154_llsec_key_id *id,
3318c2ecf20Sopenharmony_ci			 const struct ieee802154_llsec_key *key)
3328c2ecf20Sopenharmony_ci{
3338c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3348c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3358c2ecf20Sopenharmony_ci	int res;
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3388c2ecf20Sopenharmony_ci	res = mac802154_llsec_key_add(&sdata->sec, id, key);
3398c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci	return res;
3428c2ecf20Sopenharmony_ci}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_cistatic int
3458c2ecf20Sopenharmony_ciieee802154_del_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
3468c2ecf20Sopenharmony_ci			 const struct ieee802154_llsec_key_id *id)
3478c2ecf20Sopenharmony_ci{
3488c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3498c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3508c2ecf20Sopenharmony_ci	int res;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3538c2ecf20Sopenharmony_ci	res = mac802154_llsec_key_del(&sdata->sec, id);
3548c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	return res;
3578c2ecf20Sopenharmony_ci}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_cistatic int
3608c2ecf20Sopenharmony_ciieee802154_add_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
3618c2ecf20Sopenharmony_ci			const struct ieee802154_llsec_seclevel *sl)
3628c2ecf20Sopenharmony_ci{
3638c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3648c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3658c2ecf20Sopenharmony_ci	int res;
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3688c2ecf20Sopenharmony_ci	res = mac802154_llsec_seclevel_add(&sdata->sec, sl);
3698c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	return res;
3728c2ecf20Sopenharmony_ci}
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_cistatic int
3758c2ecf20Sopenharmony_ciieee802154_del_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
3768c2ecf20Sopenharmony_ci			const struct ieee802154_llsec_seclevel *sl)
3778c2ecf20Sopenharmony_ci{
3788c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3798c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3808c2ecf20Sopenharmony_ci	int res;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3838c2ecf20Sopenharmony_ci	res = mac802154_llsec_seclevel_del(&sdata->sec, sl);
3848c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci	return res;
3878c2ecf20Sopenharmony_ci}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_cistatic int
3908c2ecf20Sopenharmony_ciieee802154_add_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
3918c2ecf20Sopenharmony_ci		      const struct ieee802154_llsec_device *dev_desc)
3928c2ecf20Sopenharmony_ci{
3938c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
3948c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
3958c2ecf20Sopenharmony_ci	int res;
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
3988c2ecf20Sopenharmony_ci	res = mac802154_llsec_dev_add(&sdata->sec, dev_desc);
3998c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci	return res;
4028c2ecf20Sopenharmony_ci}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_cistatic int
4058c2ecf20Sopenharmony_ciieee802154_del_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
4068c2ecf20Sopenharmony_ci		      __le64 extended_addr)
4078c2ecf20Sopenharmony_ci{
4088c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
4098c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
4108c2ecf20Sopenharmony_ci	int res;
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
4138c2ecf20Sopenharmony_ci	res = mac802154_llsec_dev_del(&sdata->sec, extended_addr);
4148c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	return res;
4178c2ecf20Sopenharmony_ci}
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_cistatic int
4208c2ecf20Sopenharmony_ciieee802154_add_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
4218c2ecf20Sopenharmony_ci		      __le64 extended_addr,
4228c2ecf20Sopenharmony_ci		      const struct ieee802154_llsec_device_key *key)
4238c2ecf20Sopenharmony_ci{
4248c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
4258c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
4268c2ecf20Sopenharmony_ci	int res;
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
4298c2ecf20Sopenharmony_ci	res = mac802154_llsec_devkey_add(&sdata->sec, extended_addr, key);
4308c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ci	return res;
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_cistatic int
4368c2ecf20Sopenharmony_ciieee802154_del_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
4378c2ecf20Sopenharmony_ci		      __le64 extended_addr,
4388c2ecf20Sopenharmony_ci		      const struct ieee802154_llsec_device_key *key)
4398c2ecf20Sopenharmony_ci{
4408c2ecf20Sopenharmony_ci	struct net_device *dev = wpan_dev->netdev;
4418c2ecf20Sopenharmony_ci	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
4428c2ecf20Sopenharmony_ci	int res;
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	mutex_lock(&sdata->sec_mtx);
4458c2ecf20Sopenharmony_ci	res = mac802154_llsec_devkey_del(&sdata->sec, extended_addr, key);
4468c2ecf20Sopenharmony_ci	mutex_unlock(&sdata->sec_mtx);
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	return res;
4498c2ecf20Sopenharmony_ci}
4508c2ecf20Sopenharmony_ci#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ciconst struct cfg802154_ops mac802154_config_ops = {
4538c2ecf20Sopenharmony_ci	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
4548c2ecf20Sopenharmony_ci	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
4558c2ecf20Sopenharmony_ci	.suspend = ieee802154_suspend,
4568c2ecf20Sopenharmony_ci	.resume = ieee802154_resume,
4578c2ecf20Sopenharmony_ci	.add_virtual_intf = ieee802154_add_iface,
4588c2ecf20Sopenharmony_ci	.del_virtual_intf = ieee802154_del_iface,
4598c2ecf20Sopenharmony_ci	.set_channel = ieee802154_set_channel,
4608c2ecf20Sopenharmony_ci	.set_cca_mode = ieee802154_set_cca_mode,
4618c2ecf20Sopenharmony_ci	.set_cca_ed_level = ieee802154_set_cca_ed_level,
4628c2ecf20Sopenharmony_ci	.set_tx_power = ieee802154_set_tx_power,
4638c2ecf20Sopenharmony_ci	.set_pan_id = ieee802154_set_pan_id,
4648c2ecf20Sopenharmony_ci	.set_short_addr = ieee802154_set_short_addr,
4658c2ecf20Sopenharmony_ci	.set_backoff_exponent = ieee802154_set_backoff_exponent,
4668c2ecf20Sopenharmony_ci	.set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
4678c2ecf20Sopenharmony_ci	.set_max_frame_retries = ieee802154_set_max_frame_retries,
4688c2ecf20Sopenharmony_ci	.set_lbt_mode = ieee802154_set_lbt_mode,
4698c2ecf20Sopenharmony_ci	.set_ackreq_default = ieee802154_set_ackreq_default,
4708c2ecf20Sopenharmony_ci#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
4718c2ecf20Sopenharmony_ci	.get_llsec_table = ieee802154_get_llsec_table,
4728c2ecf20Sopenharmony_ci	.lock_llsec_table = ieee802154_lock_llsec_table,
4738c2ecf20Sopenharmony_ci	.unlock_llsec_table = ieee802154_unlock_llsec_table,
4748c2ecf20Sopenharmony_ci	/* TODO above */
4758c2ecf20Sopenharmony_ci	.set_llsec_params = ieee802154_set_llsec_params,
4768c2ecf20Sopenharmony_ci	.get_llsec_params = ieee802154_get_llsec_params,
4778c2ecf20Sopenharmony_ci	.add_llsec_key = ieee802154_add_llsec_key,
4788c2ecf20Sopenharmony_ci	.del_llsec_key = ieee802154_del_llsec_key,
4798c2ecf20Sopenharmony_ci	.add_seclevel = ieee802154_add_seclevel,
4808c2ecf20Sopenharmony_ci	.del_seclevel = ieee802154_del_seclevel,
4818c2ecf20Sopenharmony_ci	.add_device = ieee802154_add_device,
4828c2ecf20Sopenharmony_ci	.del_device = ieee802154_del_device,
4838c2ecf20Sopenharmony_ci	.add_devkey = ieee802154_add_devkey,
4848c2ecf20Sopenharmony_ci	.del_devkey = ieee802154_del_devkey,
4858c2ecf20Sopenharmony_ci#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
4868c2ecf20Sopenharmony_ci};
487