18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * MAC commands interface 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2007-2012 Siemens AG 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Written by: 88c2ecf20Sopenharmony_ci * Sergey Lapin <slapin@ossfans.org> 98c2ecf20Sopenharmony_ci * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 108c2ecf20Sopenharmony_ci * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 148c2ecf20Sopenharmony_ci#include <linux/if_arp.h> 158c2ecf20Sopenharmony_ci#include <linux/ieee802154.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <net/ieee802154_netdev.h> 188c2ecf20Sopenharmony_ci#include <net/cfg802154.h> 198c2ecf20Sopenharmony_ci#include <net/mac802154.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include "ieee802154_i.h" 228c2ecf20Sopenharmony_ci#include "driver-ops.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic int mac802154_mlme_start_req(struct net_device *dev, 258c2ecf20Sopenharmony_ci struct ieee802154_addr *addr, 268c2ecf20Sopenharmony_ci u8 channel, u8 page, 278c2ecf20Sopenharmony_ci u8 bcn_ord, u8 sf_ord, 288c2ecf20Sopenharmony_ci u8 pan_coord, u8 blx, 298c2ecf20Sopenharmony_ci u8 coord_realign) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci struct ieee802154_llsec_params params; 328c2ecf20Sopenharmony_ci int changed = 0; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci ASSERT_RTNL(); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci BUG_ON(addr->mode != IEEE802154_ADDR_SHORT); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci dev->ieee802154_ptr->pan_id = addr->pan_id; 398c2ecf20Sopenharmony_ci dev->ieee802154_ptr->short_addr = addr->short_addr; 408c2ecf20Sopenharmony_ci mac802154_dev_set_page_channel(dev, page, channel); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci params.pan_id = addr->pan_id; 438c2ecf20Sopenharmony_ci changed |= IEEE802154_LLSEC_PARAM_PAN_ID; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci params.hwaddr = ieee802154_devaddr_from_raw(dev->dev_addr); 468c2ecf20Sopenharmony_ci changed |= IEEE802154_LLSEC_PARAM_HWADDR; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci params.coord_hwaddr = params.hwaddr; 498c2ecf20Sopenharmony_ci changed |= IEEE802154_LLSEC_PARAM_COORD_HWADDR; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci params.coord_shortaddr = addr->short_addr; 528c2ecf20Sopenharmony_ci changed |= IEEE802154_LLSEC_PARAM_COORD_SHORTADDR; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci return mac802154_set_params(dev, ¶ms, changed); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic int mac802154_set_mac_params(struct net_device *dev, 588c2ecf20Sopenharmony_ci const struct ieee802154_mac_params *params) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 618c2ecf20Sopenharmony_ci struct ieee802154_local *local = sdata->local; 628c2ecf20Sopenharmony_ci struct wpan_dev *wpan_dev = &sdata->wpan_dev; 638c2ecf20Sopenharmony_ci int ret; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci ASSERT_RTNL(); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci /* PHY */ 688c2ecf20Sopenharmony_ci wpan_dev->wpan_phy->transmit_power = params->transmit_power; 698c2ecf20Sopenharmony_ci wpan_dev->wpan_phy->cca = params->cca; 708c2ecf20Sopenharmony_ci wpan_dev->wpan_phy->cca_ed_level = params->cca_ed_level; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* MAC */ 738c2ecf20Sopenharmony_ci wpan_dev->min_be = params->min_be; 748c2ecf20Sopenharmony_ci wpan_dev->max_be = params->max_be; 758c2ecf20Sopenharmony_ci wpan_dev->csma_retries = params->csma_retries; 768c2ecf20Sopenharmony_ci wpan_dev->frame_retries = params->frame_retries; 778c2ecf20Sopenharmony_ci wpan_dev->lbt = params->lbt; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (local->hw.phy->flags & WPAN_PHY_FLAG_TXPOWER) { 808c2ecf20Sopenharmony_ci ret = drv_set_tx_power(local, params->transmit_power); 818c2ecf20Sopenharmony_ci if (ret < 0) 828c2ecf20Sopenharmony_ci return ret; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if (local->hw.phy->flags & WPAN_PHY_FLAG_CCA_MODE) { 868c2ecf20Sopenharmony_ci ret = drv_set_cca_mode(local, ¶ms->cca); 878c2ecf20Sopenharmony_ci if (ret < 0) 888c2ecf20Sopenharmony_ci return ret; 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci if (local->hw.phy->flags & WPAN_PHY_FLAG_CCA_ED_LEVEL) { 928c2ecf20Sopenharmony_ci ret = drv_set_cca_ed_level(local, params->cca_ed_level); 938c2ecf20Sopenharmony_ci if (ret < 0) 948c2ecf20Sopenharmony_ci return ret; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci return 0; 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic void mac802154_get_mac_params(struct net_device *dev, 1018c2ecf20Sopenharmony_ci struct ieee802154_mac_params *params) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 1048c2ecf20Sopenharmony_ci struct wpan_dev *wpan_dev = &sdata->wpan_dev; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci ASSERT_RTNL(); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci /* PHY */ 1098c2ecf20Sopenharmony_ci params->transmit_power = wpan_dev->wpan_phy->transmit_power; 1108c2ecf20Sopenharmony_ci params->cca = wpan_dev->wpan_phy->cca; 1118c2ecf20Sopenharmony_ci params->cca_ed_level = wpan_dev->wpan_phy->cca_ed_level; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci /* MAC */ 1148c2ecf20Sopenharmony_ci params->min_be = wpan_dev->min_be; 1158c2ecf20Sopenharmony_ci params->max_be = wpan_dev->max_be; 1168c2ecf20Sopenharmony_ci params->csma_retries = wpan_dev->csma_retries; 1178c2ecf20Sopenharmony_ci params->frame_retries = wpan_dev->frame_retries; 1188c2ecf20Sopenharmony_ci params->lbt = wpan_dev->lbt; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic const struct ieee802154_llsec_ops mac802154_llsec_ops = { 1228c2ecf20Sopenharmony_ci .get_params = mac802154_get_params, 1238c2ecf20Sopenharmony_ci .set_params = mac802154_set_params, 1248c2ecf20Sopenharmony_ci .add_key = mac802154_add_key, 1258c2ecf20Sopenharmony_ci .del_key = mac802154_del_key, 1268c2ecf20Sopenharmony_ci .add_dev = mac802154_add_dev, 1278c2ecf20Sopenharmony_ci .del_dev = mac802154_del_dev, 1288c2ecf20Sopenharmony_ci .add_devkey = mac802154_add_devkey, 1298c2ecf20Sopenharmony_ci .del_devkey = mac802154_del_devkey, 1308c2ecf20Sopenharmony_ci .add_seclevel = mac802154_add_seclevel, 1318c2ecf20Sopenharmony_ci .del_seclevel = mac802154_del_seclevel, 1328c2ecf20Sopenharmony_ci .lock_table = mac802154_lock_table, 1338c2ecf20Sopenharmony_ci .get_table = mac802154_get_table, 1348c2ecf20Sopenharmony_ci .unlock_table = mac802154_unlock_table, 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistruct ieee802154_mlme_ops mac802154_mlme_wpan = { 1388c2ecf20Sopenharmony_ci .start_req = mac802154_mlme_start_req, 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci .llsec = &mac802154_llsec_ops, 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci .set_mac_params = mac802154_set_mac_params, 1438c2ecf20Sopenharmony_ci .get_mac_params = mac802154_get_mac_params, 1448c2ecf20Sopenharmony_ci}; 145