cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cfg.c (11724B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * Authors:
      5 * Alexander Aring <aar@pengutronix.de>
      6 *
      7 * Based on: net/mac80211/cfg.c
      8 */
      9
     10#include <net/rtnetlink.h>
     11#include <net/cfg802154.h>
     12
     13#include "ieee802154_i.h"
     14#include "driver-ops.h"
     15#include "cfg.h"
     16
     17static struct net_device *
     18ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
     19				const char *name,
     20				unsigned char name_assign_type, int type)
     21{
     22	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
     23	struct net_device *dev;
     24
     25	rtnl_lock();
     26	dev = ieee802154_if_add(local, name, name_assign_type, type,
     27				cpu_to_le64(0x0000000000000000ULL));
     28	rtnl_unlock();
     29
     30	return dev;
     31}
     32
     33static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
     34					    struct net_device *dev)
     35{
     36	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
     37
     38	ieee802154_if_remove(sdata);
     39}
     40
     41#ifdef CONFIG_PM
     42static int ieee802154_suspend(struct wpan_phy *wpan_phy)
     43{
     44	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
     45
     46	if (!local->open_count)
     47		goto suspend;
     48
     49	ieee802154_stop_queue(&local->hw);
     50	synchronize_net();
     51
     52	/* stop hardware - this must stop RX */
     53	ieee802154_stop_device(local);
     54
     55suspend:
     56	local->suspended = true;
     57	return 0;
     58}
     59
     60static int ieee802154_resume(struct wpan_phy *wpan_phy)
     61{
     62	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
     63	int ret;
     64
     65	/* nothing to do if HW shouldn't run */
     66	if (!local->open_count)
     67		goto wake_up;
     68
     69	/* restart hardware */
     70	ret = drv_start(local);
     71	if (ret)
     72		return ret;
     73
     74wake_up:
     75	ieee802154_wake_queue(&local->hw);
     76	local->suspended = false;
     77	return 0;
     78}
     79#else
     80#define ieee802154_suspend NULL
     81#define ieee802154_resume NULL
     82#endif
     83
     84static int
     85ieee802154_add_iface(struct wpan_phy *phy, const char *name,
     86		     unsigned char name_assign_type,
     87		     enum nl802154_iftype type, __le64 extended_addr)
     88{
     89	struct ieee802154_local *local = wpan_phy_priv(phy);
     90	struct net_device *err;
     91
     92	err = ieee802154_if_add(local, name, name_assign_type, type,
     93				extended_addr);
     94	return PTR_ERR_OR_ZERO(err);
     95}
     96
     97static int
     98ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev)
     99{
    100	ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev));
    101
    102	return 0;
    103}
    104
    105static int
    106ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
    107{
    108	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
    109	int ret;
    110
    111	ASSERT_RTNL();
    112
    113	if (wpan_phy->current_page == page &&
    114	    wpan_phy->current_channel == channel)
    115		return 0;
    116
    117	ret = drv_set_channel(local, page, channel);
    118	if (!ret) {
    119		wpan_phy->current_page = page;
    120		wpan_phy->current_channel = channel;
    121		ieee802154_configure_durations(wpan_phy);
    122	}
    123
    124	return ret;
    125}
    126
    127static int
    128ieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
    129			const struct wpan_phy_cca *cca)
    130{
    131	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
    132	int ret;
    133
    134	ASSERT_RTNL();
    135
    136	if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
    137		return 0;
    138
    139	ret = drv_set_cca_mode(local, cca);
    140	if (!ret)
    141		wpan_phy->cca = *cca;
    142
    143	return ret;
    144}
    145
    146static int
    147ieee802154_set_cca_ed_level(struct wpan_phy *wpan_phy, s32 ed_level)
    148{
    149	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
    150	int ret;
    151
    152	ASSERT_RTNL();
    153
    154	if (wpan_phy->cca_ed_level == ed_level)
    155		return 0;
    156
    157	ret = drv_set_cca_ed_level(local, ed_level);
    158	if (!ret)
    159		wpan_phy->cca_ed_level = ed_level;
    160
    161	return ret;
    162}
    163
    164static int
    165ieee802154_set_tx_power(struct wpan_phy *wpan_phy, s32 power)
    166{
    167	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
    168	int ret;
    169
    170	ASSERT_RTNL();
    171
    172	if (wpan_phy->transmit_power == power)
    173		return 0;
    174
    175	ret = drv_set_tx_power(local, power);
    176	if (!ret)
    177		wpan_phy->transmit_power = power;
    178
    179	return ret;
    180}
    181
    182static int
    183ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    184		      __le16 pan_id)
    185{
    186	int ret;
    187
    188	ASSERT_RTNL();
    189
    190	if (wpan_dev->pan_id == pan_id)
    191		return 0;
    192
    193	ret = mac802154_wpan_update_llsec(wpan_dev->netdev);
    194	if (!ret)
    195		wpan_dev->pan_id = pan_id;
    196
    197	return ret;
    198}
    199
    200static int
    201ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
    202				struct wpan_dev *wpan_dev,
    203				u8 min_be, u8 max_be)
    204{
    205	ASSERT_RTNL();
    206
    207	wpan_dev->min_be = min_be;
    208	wpan_dev->max_be = max_be;
    209	return 0;
    210}
    211
    212static int
    213ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    214			  __le16 short_addr)
    215{
    216	ASSERT_RTNL();
    217
    218	wpan_dev->short_addr = short_addr;
    219	return 0;
    220}
    221
    222static int
    223ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
    224				 struct wpan_dev *wpan_dev,
    225				 u8 max_csma_backoffs)
    226{
    227	ASSERT_RTNL();
    228
    229	wpan_dev->csma_retries = max_csma_backoffs;
    230	return 0;
    231}
    232
    233static int
    234ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
    235				 struct wpan_dev *wpan_dev,
    236				 s8 max_frame_retries)
    237{
    238	ASSERT_RTNL();
    239
    240	wpan_dev->frame_retries = max_frame_retries;
    241	return 0;
    242}
    243
    244static int
    245ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    246			bool mode)
    247{
    248	ASSERT_RTNL();
    249
    250	wpan_dev->lbt = mode;
    251	return 0;
    252}
    253
    254static int
    255ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
    256			      struct wpan_dev *wpan_dev, bool ackreq)
    257{
    258	ASSERT_RTNL();
    259
    260	wpan_dev->ackreq = ackreq;
    261	return 0;
    262}
    263
    264#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
    265static void
    266ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
    267			   struct wpan_dev *wpan_dev,
    268			   struct ieee802154_llsec_table **table)
    269{
    270	struct net_device *dev = wpan_dev->netdev;
    271	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    272
    273	*table = &sdata->sec.table;
    274}
    275
    276static void
    277ieee802154_lock_llsec_table(struct wpan_phy *wpan_phy,
    278			    struct wpan_dev *wpan_dev)
    279{
    280	struct net_device *dev = wpan_dev->netdev;
    281	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    282
    283	mutex_lock(&sdata->sec_mtx);
    284}
    285
    286static void
    287ieee802154_unlock_llsec_table(struct wpan_phy *wpan_phy,
    288			      struct wpan_dev *wpan_dev)
    289{
    290	struct net_device *dev = wpan_dev->netdev;
    291	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    292
    293	mutex_unlock(&sdata->sec_mtx);
    294}
    295
    296static int
    297ieee802154_set_llsec_params(struct wpan_phy *wpan_phy,
    298			    struct wpan_dev *wpan_dev,
    299			    const struct ieee802154_llsec_params *params,
    300			    int changed)
    301{
    302	struct net_device *dev = wpan_dev->netdev;
    303	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    304	int res;
    305
    306	mutex_lock(&sdata->sec_mtx);
    307	res = mac802154_llsec_set_params(&sdata->sec, params, changed);
    308	mutex_unlock(&sdata->sec_mtx);
    309
    310	return res;
    311}
    312
    313static int
    314ieee802154_get_llsec_params(struct wpan_phy *wpan_phy,
    315			    struct wpan_dev *wpan_dev,
    316			    struct ieee802154_llsec_params *params)
    317{
    318	struct net_device *dev = wpan_dev->netdev;
    319	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    320	int res;
    321
    322	mutex_lock(&sdata->sec_mtx);
    323	res = mac802154_llsec_get_params(&sdata->sec, params);
    324	mutex_unlock(&sdata->sec_mtx);
    325
    326	return res;
    327}
    328
    329static int
    330ieee802154_add_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    331			 const struct ieee802154_llsec_key_id *id,
    332			 const struct ieee802154_llsec_key *key)
    333{
    334	struct net_device *dev = wpan_dev->netdev;
    335	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    336	int res;
    337
    338	mutex_lock(&sdata->sec_mtx);
    339	res = mac802154_llsec_key_add(&sdata->sec, id, key);
    340	mutex_unlock(&sdata->sec_mtx);
    341
    342	return res;
    343}
    344
    345static int
    346ieee802154_del_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    347			 const struct ieee802154_llsec_key_id *id)
    348{
    349	struct net_device *dev = wpan_dev->netdev;
    350	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    351	int res;
    352
    353	mutex_lock(&sdata->sec_mtx);
    354	res = mac802154_llsec_key_del(&sdata->sec, id);
    355	mutex_unlock(&sdata->sec_mtx);
    356
    357	return res;
    358}
    359
    360static int
    361ieee802154_add_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    362			const struct ieee802154_llsec_seclevel *sl)
    363{
    364	struct net_device *dev = wpan_dev->netdev;
    365	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    366	int res;
    367
    368	mutex_lock(&sdata->sec_mtx);
    369	res = mac802154_llsec_seclevel_add(&sdata->sec, sl);
    370	mutex_unlock(&sdata->sec_mtx);
    371
    372	return res;
    373}
    374
    375static int
    376ieee802154_del_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    377			const struct ieee802154_llsec_seclevel *sl)
    378{
    379	struct net_device *dev = wpan_dev->netdev;
    380	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    381	int res;
    382
    383	mutex_lock(&sdata->sec_mtx);
    384	res = mac802154_llsec_seclevel_del(&sdata->sec, sl);
    385	mutex_unlock(&sdata->sec_mtx);
    386
    387	return res;
    388}
    389
    390static int
    391ieee802154_add_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    392		      const struct ieee802154_llsec_device *dev_desc)
    393{
    394	struct net_device *dev = wpan_dev->netdev;
    395	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    396	int res;
    397
    398	mutex_lock(&sdata->sec_mtx);
    399	res = mac802154_llsec_dev_add(&sdata->sec, dev_desc);
    400	mutex_unlock(&sdata->sec_mtx);
    401
    402	return res;
    403}
    404
    405static int
    406ieee802154_del_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    407		      __le64 extended_addr)
    408{
    409	struct net_device *dev = wpan_dev->netdev;
    410	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    411	int res;
    412
    413	mutex_lock(&sdata->sec_mtx);
    414	res = mac802154_llsec_dev_del(&sdata->sec, extended_addr);
    415	mutex_unlock(&sdata->sec_mtx);
    416
    417	return res;
    418}
    419
    420static int
    421ieee802154_add_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    422		      __le64 extended_addr,
    423		      const struct ieee802154_llsec_device_key *key)
    424{
    425	struct net_device *dev = wpan_dev->netdev;
    426	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    427	int res;
    428
    429	mutex_lock(&sdata->sec_mtx);
    430	res = mac802154_llsec_devkey_add(&sdata->sec, extended_addr, key);
    431	mutex_unlock(&sdata->sec_mtx);
    432
    433	return res;
    434}
    435
    436static int
    437ieee802154_del_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
    438		      __le64 extended_addr,
    439		      const struct ieee802154_llsec_device_key *key)
    440{
    441	struct net_device *dev = wpan_dev->netdev;
    442	struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
    443	int res;
    444
    445	mutex_lock(&sdata->sec_mtx);
    446	res = mac802154_llsec_devkey_del(&sdata->sec, extended_addr, key);
    447	mutex_unlock(&sdata->sec_mtx);
    448
    449	return res;
    450}
    451#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
    452
    453const struct cfg802154_ops mac802154_config_ops = {
    454	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
    455	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
    456	.suspend = ieee802154_suspend,
    457	.resume = ieee802154_resume,
    458	.add_virtual_intf = ieee802154_add_iface,
    459	.del_virtual_intf = ieee802154_del_iface,
    460	.set_channel = ieee802154_set_channel,
    461	.set_cca_mode = ieee802154_set_cca_mode,
    462	.set_cca_ed_level = ieee802154_set_cca_ed_level,
    463	.set_tx_power = ieee802154_set_tx_power,
    464	.set_pan_id = ieee802154_set_pan_id,
    465	.set_short_addr = ieee802154_set_short_addr,
    466	.set_backoff_exponent = ieee802154_set_backoff_exponent,
    467	.set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
    468	.set_max_frame_retries = ieee802154_set_max_frame_retries,
    469	.set_lbt_mode = ieee802154_set_lbt_mode,
    470	.set_ackreq_default = ieee802154_set_ackreq_default,
    471#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
    472	.get_llsec_table = ieee802154_get_llsec_table,
    473	.lock_llsec_table = ieee802154_lock_llsec_table,
    474	.unlock_llsec_table = ieee802154_unlock_llsec_table,
    475	/* TODO above */
    476	.set_llsec_params = ieee802154_set_llsec_params,
    477	.get_llsec_params = ieee802154_get_llsec_params,
    478	.add_llsec_key = ieee802154_add_llsec_key,
    479	.del_llsec_key = ieee802154_del_llsec_key,
    480	.add_seclevel = ieee802154_add_seclevel,
    481	.del_seclevel = ieee802154_del_seclevel,
    482	.add_device = ieee802154_add_device,
    483	.del_device = ieee802154_del_device,
    484	.add_devkey = ieee802154_add_devkey,
    485	.del_devkey = ieee802154_del_devkey,
    486#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
    487};