162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2007, 2008, 2009 Siemens AG
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Written by:
662306a36Sopenharmony_ci * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef __NET_CFG802154_H
1062306a36Sopenharmony_ci#define __NET_CFG802154_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/ieee802154.h>
1362306a36Sopenharmony_ci#include <linux/netdevice.h>
1462306a36Sopenharmony_ci#include <linux/spinlock.h>
1562306a36Sopenharmony_ci#include <linux/bug.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <net/nl802154.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistruct wpan_phy;
2062306a36Sopenharmony_cistruct wpan_phy_cca;
2162306a36Sopenharmony_cistruct cfg802154_scan_request;
2262306a36Sopenharmony_cistruct cfg802154_beacon_request;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
2562306a36Sopenharmony_cistruct ieee802154_llsec_device_key;
2662306a36Sopenharmony_cistruct ieee802154_llsec_seclevel;
2762306a36Sopenharmony_cistruct ieee802154_llsec_params;
2862306a36Sopenharmony_cistruct ieee802154_llsec_device;
2962306a36Sopenharmony_cistruct ieee802154_llsec_table;
3062306a36Sopenharmony_cistruct ieee802154_llsec_key_id;
3162306a36Sopenharmony_cistruct ieee802154_llsec_key;
3262306a36Sopenharmony_ci#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct cfg802154_ops {
3562306a36Sopenharmony_ci	struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
3662306a36Sopenharmony_ci							   const char *name,
3762306a36Sopenharmony_ci							   unsigned char name_assign_type,
3862306a36Sopenharmony_ci							   int type);
3962306a36Sopenharmony_ci	void	(*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
4062306a36Sopenharmony_ci					       struct net_device *dev);
4162306a36Sopenharmony_ci	int	(*suspend)(struct wpan_phy *wpan_phy);
4262306a36Sopenharmony_ci	int	(*resume)(struct wpan_phy *wpan_phy);
4362306a36Sopenharmony_ci	int	(*add_virtual_intf)(struct wpan_phy *wpan_phy,
4462306a36Sopenharmony_ci				    const char *name,
4562306a36Sopenharmony_ci				    unsigned char name_assign_type,
4662306a36Sopenharmony_ci				    enum nl802154_iftype type,
4762306a36Sopenharmony_ci				    __le64 extended_addr);
4862306a36Sopenharmony_ci	int	(*del_virtual_intf)(struct wpan_phy *wpan_phy,
4962306a36Sopenharmony_ci				    struct wpan_dev *wpan_dev);
5062306a36Sopenharmony_ci	int	(*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
5162306a36Sopenharmony_ci	int	(*set_cca_mode)(struct wpan_phy *wpan_phy,
5262306a36Sopenharmony_ci				const struct wpan_phy_cca *cca);
5362306a36Sopenharmony_ci	int     (*set_cca_ed_level)(struct wpan_phy *wpan_phy, s32 ed_level);
5462306a36Sopenharmony_ci	int     (*set_tx_power)(struct wpan_phy *wpan_phy, s32 power);
5562306a36Sopenharmony_ci	int	(*set_pan_id)(struct wpan_phy *wpan_phy,
5662306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev, __le16 pan_id);
5762306a36Sopenharmony_ci	int	(*set_short_addr)(struct wpan_phy *wpan_phy,
5862306a36Sopenharmony_ci				  struct wpan_dev *wpan_dev, __le16 short_addr);
5962306a36Sopenharmony_ci	int	(*set_backoff_exponent)(struct wpan_phy *wpan_phy,
6062306a36Sopenharmony_ci					struct wpan_dev *wpan_dev, u8 min_be,
6162306a36Sopenharmony_ci					u8 max_be);
6262306a36Sopenharmony_ci	int	(*set_max_csma_backoffs)(struct wpan_phy *wpan_phy,
6362306a36Sopenharmony_ci					 struct wpan_dev *wpan_dev,
6462306a36Sopenharmony_ci					 u8 max_csma_backoffs);
6562306a36Sopenharmony_ci	int	(*set_max_frame_retries)(struct wpan_phy *wpan_phy,
6662306a36Sopenharmony_ci					 struct wpan_dev *wpan_dev,
6762306a36Sopenharmony_ci					 s8 max_frame_retries);
6862306a36Sopenharmony_ci	int	(*set_lbt_mode)(struct wpan_phy *wpan_phy,
6962306a36Sopenharmony_ci				struct wpan_dev *wpan_dev, bool mode);
7062306a36Sopenharmony_ci	int	(*set_ackreq_default)(struct wpan_phy *wpan_phy,
7162306a36Sopenharmony_ci				      struct wpan_dev *wpan_dev, bool ackreq);
7262306a36Sopenharmony_ci	int	(*trigger_scan)(struct wpan_phy *wpan_phy,
7362306a36Sopenharmony_ci				struct cfg802154_scan_request *request);
7462306a36Sopenharmony_ci	int	(*abort_scan)(struct wpan_phy *wpan_phy,
7562306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev);
7662306a36Sopenharmony_ci	int	(*send_beacons)(struct wpan_phy *wpan_phy,
7762306a36Sopenharmony_ci				struct cfg802154_beacon_request *request);
7862306a36Sopenharmony_ci	int	(*stop_beacons)(struct wpan_phy *wpan_phy,
7962306a36Sopenharmony_ci				struct wpan_dev *wpan_dev);
8062306a36Sopenharmony_ci#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
8162306a36Sopenharmony_ci	void	(*get_llsec_table)(struct wpan_phy *wpan_phy,
8262306a36Sopenharmony_ci				   struct wpan_dev *wpan_dev,
8362306a36Sopenharmony_ci				   struct ieee802154_llsec_table **table);
8462306a36Sopenharmony_ci	void	(*lock_llsec_table)(struct wpan_phy *wpan_phy,
8562306a36Sopenharmony_ci				    struct wpan_dev *wpan_dev);
8662306a36Sopenharmony_ci	void	(*unlock_llsec_table)(struct wpan_phy *wpan_phy,
8762306a36Sopenharmony_ci				      struct wpan_dev *wpan_dev);
8862306a36Sopenharmony_ci	/* TODO remove locking/get table callbacks, this is part of the
8962306a36Sopenharmony_ci	 * nl802154 interface and should be accessible from ieee802154 layer.
9062306a36Sopenharmony_ci	 */
9162306a36Sopenharmony_ci	int	(*get_llsec_params)(struct wpan_phy *wpan_phy,
9262306a36Sopenharmony_ci				    struct wpan_dev *wpan_dev,
9362306a36Sopenharmony_ci				    struct ieee802154_llsec_params *params);
9462306a36Sopenharmony_ci	int	(*set_llsec_params)(struct wpan_phy *wpan_phy,
9562306a36Sopenharmony_ci				    struct wpan_dev *wpan_dev,
9662306a36Sopenharmony_ci				    const struct ieee802154_llsec_params *params,
9762306a36Sopenharmony_ci				    int changed);
9862306a36Sopenharmony_ci	int	(*add_llsec_key)(struct wpan_phy *wpan_phy,
9962306a36Sopenharmony_ci				 struct wpan_dev *wpan_dev,
10062306a36Sopenharmony_ci				 const struct ieee802154_llsec_key_id *id,
10162306a36Sopenharmony_ci				 const struct ieee802154_llsec_key *key);
10262306a36Sopenharmony_ci	int	(*del_llsec_key)(struct wpan_phy *wpan_phy,
10362306a36Sopenharmony_ci				 struct wpan_dev *wpan_dev,
10462306a36Sopenharmony_ci				 const struct ieee802154_llsec_key_id *id);
10562306a36Sopenharmony_ci	int	(*add_seclevel)(struct wpan_phy *wpan_phy,
10662306a36Sopenharmony_ci				 struct wpan_dev *wpan_dev,
10762306a36Sopenharmony_ci				 const struct ieee802154_llsec_seclevel *sl);
10862306a36Sopenharmony_ci	int	(*del_seclevel)(struct wpan_phy *wpan_phy,
10962306a36Sopenharmony_ci				 struct wpan_dev *wpan_dev,
11062306a36Sopenharmony_ci				 const struct ieee802154_llsec_seclevel *sl);
11162306a36Sopenharmony_ci	int	(*add_device)(struct wpan_phy *wpan_phy,
11262306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev,
11362306a36Sopenharmony_ci			      const struct ieee802154_llsec_device *dev);
11462306a36Sopenharmony_ci	int	(*del_device)(struct wpan_phy *wpan_phy,
11562306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev, __le64 extended_addr);
11662306a36Sopenharmony_ci	int	(*add_devkey)(struct wpan_phy *wpan_phy,
11762306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev,
11862306a36Sopenharmony_ci			      __le64 extended_addr,
11962306a36Sopenharmony_ci			      const struct ieee802154_llsec_device_key *key);
12062306a36Sopenharmony_ci	int	(*del_devkey)(struct wpan_phy *wpan_phy,
12162306a36Sopenharmony_ci			      struct wpan_dev *wpan_dev,
12262306a36Sopenharmony_ci			      __le64 extended_addr,
12362306a36Sopenharmony_ci			      const struct ieee802154_llsec_device_key *key);
12462306a36Sopenharmony_ci#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic inline bool
12862306a36Sopenharmony_ciwpan_phy_supported_bool(bool b, enum nl802154_supported_bool_states st)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	switch (st) {
13162306a36Sopenharmony_ci	case NL802154_SUPPORTED_BOOL_TRUE:
13262306a36Sopenharmony_ci		return b;
13362306a36Sopenharmony_ci	case NL802154_SUPPORTED_BOOL_FALSE:
13462306a36Sopenharmony_ci		return !b;
13562306a36Sopenharmony_ci	case NL802154_SUPPORTED_BOOL_BOTH:
13662306a36Sopenharmony_ci		return true;
13762306a36Sopenharmony_ci	default:
13862306a36Sopenharmony_ci		WARN_ON(1);
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	return false;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistruct wpan_phy_supported {
14562306a36Sopenharmony_ci	u32 channels[IEEE802154_MAX_PAGE + 1],
14662306a36Sopenharmony_ci	    cca_modes, cca_opts, iftypes;
14762306a36Sopenharmony_ci	enum nl802154_supported_bool_states lbt;
14862306a36Sopenharmony_ci	u8 min_minbe, max_minbe, min_maxbe, max_maxbe,
14962306a36Sopenharmony_ci	   min_csma_backoffs, max_csma_backoffs;
15062306a36Sopenharmony_ci	s8 min_frame_retries, max_frame_retries;
15162306a36Sopenharmony_ci	size_t tx_powers_size, cca_ed_levels_size;
15262306a36Sopenharmony_ci	const s32 *tx_powers, *cca_ed_levels;
15362306a36Sopenharmony_ci};
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistruct wpan_phy_cca {
15662306a36Sopenharmony_ci	enum nl802154_cca_modes mode;
15762306a36Sopenharmony_ci	enum nl802154_cca_opts opt;
15862306a36Sopenharmony_ci};
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic inline bool
16162306a36Sopenharmony_ciwpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	if (a->mode != b->mode)
16462306a36Sopenharmony_ci		return false;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	if (a->mode == NL802154_CCA_ENERGY_CARRIER)
16762306a36Sopenharmony_ci		return a->opt == b->opt;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	return true;
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/**
17362306a36Sopenharmony_ci * enum wpan_phy_flags - WPAN PHY state flags
17462306a36Sopenharmony_ci * @WPAN_PHY_FLAG_TXPOWER: Indicates that transceiver will support
17562306a36Sopenharmony_ci *	transmit power setting.
17662306a36Sopenharmony_ci * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed
17762306a36Sopenharmony_ci *	level setting.
17862306a36Sopenharmony_ci * @WPAN_PHY_FLAG_CCA_MODE: Indicates that transceiver will support cca mode
17962306a36Sopenharmony_ci *	setting.
18062306a36Sopenharmony_ci * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
18162306a36Sopenharmony_ci *	temporarily stopped.
18262306a36Sopenharmony_ci * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
18362306a36Sopenharmony_ci *	send/receive datagrams.
18462306a36Sopenharmony_ci */
18562306a36Sopenharmony_cienum wpan_phy_flags {
18662306a36Sopenharmony_ci	WPAN_PHY_FLAG_TXPOWER		= BIT(1),
18762306a36Sopenharmony_ci	WPAN_PHY_FLAG_CCA_ED_LEVEL	= BIT(2),
18862306a36Sopenharmony_ci	WPAN_PHY_FLAG_CCA_MODE		= BIT(3),
18962306a36Sopenharmony_ci	WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
19062306a36Sopenharmony_ci	WPAN_PHY_FLAG_DATAGRAMS_ONLY	= BIT(5),
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistruct wpan_phy {
19462306a36Sopenharmony_ci	/* If multiple wpan_phys are registered and you're handed e.g.
19562306a36Sopenharmony_ci	 * a regular netdev with assigned ieee802154_ptr, you won't
19662306a36Sopenharmony_ci	 * know whether it points to a wpan_phy your driver has registered
19762306a36Sopenharmony_ci	 * or not. Assign this to something global to your driver to
19862306a36Sopenharmony_ci	 * help determine whether you own this wpan_phy or not.
19962306a36Sopenharmony_ci	 */
20062306a36Sopenharmony_ci	const void *privid;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	unsigned long flags;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	/*
20562306a36Sopenharmony_ci	 * This is a PIB according to 802.15.4-2011.
20662306a36Sopenharmony_ci	 * We do not provide timing-related variables, as they
20762306a36Sopenharmony_ci	 * aren't used outside of driver
20862306a36Sopenharmony_ci	 */
20962306a36Sopenharmony_ci	u8 current_channel;
21062306a36Sopenharmony_ci	u8 current_page;
21162306a36Sopenharmony_ci	struct wpan_phy_supported supported;
21262306a36Sopenharmony_ci	/* current transmit_power in mBm */
21362306a36Sopenharmony_ci	s32 transmit_power;
21462306a36Sopenharmony_ci	struct wpan_phy_cca cca;
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	__le64 perm_extended_addr;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/* current cca ed threshold in mBm */
21962306a36Sopenharmony_ci	s32 cca_ed_level;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* PHY depended MAC PIB values */
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	/* 802.15.4 acronym: Tdsym in nsec */
22462306a36Sopenharmony_ci	u32 symbol_duration;
22562306a36Sopenharmony_ci	/* lifs and sifs periods timing */
22662306a36Sopenharmony_ci	u16 lifs_period;
22762306a36Sopenharmony_ci	u16 sifs_period;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	struct device dev;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	/* the network namespace this phy lives in currently */
23262306a36Sopenharmony_ci	possible_net_t _net;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	/* Transmission monitoring and control */
23562306a36Sopenharmony_ci	spinlock_t queue_lock;
23662306a36Sopenharmony_ci	atomic_t ongoing_txs;
23762306a36Sopenharmony_ci	atomic_t hold_txs;
23862306a36Sopenharmony_ci	wait_queue_head_t sync_txq;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	/* Current filtering level on reception.
24162306a36Sopenharmony_ci	 * Only allowed to be changed if phy is not operational.
24262306a36Sopenharmony_ci	 */
24362306a36Sopenharmony_ci	enum ieee802154_filtering_level filtering;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	char priv[] __aligned(NETDEV_ALIGN);
24662306a36Sopenharmony_ci};
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_cistatic inline struct net *wpan_phy_net(struct wpan_phy *wpan_phy)
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	return read_pnet(&wpan_phy->_net);
25162306a36Sopenharmony_ci}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_cistatic inline void wpan_phy_net_set(struct wpan_phy *wpan_phy, struct net *net)
25462306a36Sopenharmony_ci{
25562306a36Sopenharmony_ci	write_pnet(&wpan_phy->_net, net);
25662306a36Sopenharmony_ci}
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic inline bool ieee802154_chan_is_valid(struct wpan_phy *phy,
25962306a36Sopenharmony_ci					    u8 page, u8 channel)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	if (page > IEEE802154_MAX_PAGE ||
26262306a36Sopenharmony_ci	    channel > IEEE802154_MAX_CHANNEL ||
26362306a36Sopenharmony_ci	    !(phy->supported.channels[page] & BIT(channel)))
26462306a36Sopenharmony_ci		return false;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	return true;
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci/**
27062306a36Sopenharmony_ci * struct ieee802154_addr - IEEE802.15.4 device address
27162306a36Sopenharmony_ci * @mode: Address mode from frame header. Can be one of:
27262306a36Sopenharmony_ci *        - @IEEE802154_ADDR_NONE
27362306a36Sopenharmony_ci *        - @IEEE802154_ADDR_SHORT
27462306a36Sopenharmony_ci *        - @IEEE802154_ADDR_LONG
27562306a36Sopenharmony_ci * @pan_id: The PAN ID this address belongs to
27662306a36Sopenharmony_ci * @short_addr: address if @mode is @IEEE802154_ADDR_SHORT
27762306a36Sopenharmony_ci * @extended_addr: address if @mode is @IEEE802154_ADDR_LONG
27862306a36Sopenharmony_ci */
27962306a36Sopenharmony_cistruct ieee802154_addr {
28062306a36Sopenharmony_ci	u8 mode;
28162306a36Sopenharmony_ci	__le16 pan_id;
28262306a36Sopenharmony_ci	union {
28362306a36Sopenharmony_ci		__le16 short_addr;
28462306a36Sopenharmony_ci		__le64 extended_addr;
28562306a36Sopenharmony_ci	};
28662306a36Sopenharmony_ci};
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/**
28962306a36Sopenharmony_ci * struct ieee802154_coord_desc - Coordinator descriptor
29062306a36Sopenharmony_ci * @addr: PAN ID and coordinator address
29162306a36Sopenharmony_ci * @page: page this coordinator is using
29262306a36Sopenharmony_ci * @channel: channel this coordinator is using
29362306a36Sopenharmony_ci * @superframe_spec: SuperFrame specification as received
29462306a36Sopenharmony_ci * @link_quality: link quality indicator at which the beacon was received
29562306a36Sopenharmony_ci * @gts_permit: the coordinator accepts GTS requests
29662306a36Sopenharmony_ci */
29762306a36Sopenharmony_cistruct ieee802154_coord_desc {
29862306a36Sopenharmony_ci	struct ieee802154_addr addr;
29962306a36Sopenharmony_ci	u8 page;
30062306a36Sopenharmony_ci	u8 channel;
30162306a36Sopenharmony_ci	u16 superframe_spec;
30262306a36Sopenharmony_ci	u8 link_quality;
30362306a36Sopenharmony_ci	bool gts_permit;
30462306a36Sopenharmony_ci};
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/**
30762306a36Sopenharmony_ci * struct cfg802154_scan_request - Scan request
30862306a36Sopenharmony_ci *
30962306a36Sopenharmony_ci * @type: type of scan to be performed
31062306a36Sopenharmony_ci * @page: page on which to perform the scan
31162306a36Sopenharmony_ci * @channels: channels in te %page to be scanned
31262306a36Sopenharmony_ci * @duration: time spent on each channel, calculated with:
31362306a36Sopenharmony_ci *            aBaseSuperframeDuration * (2 ^ duration + 1)
31462306a36Sopenharmony_ci * @wpan_dev: the wpan device on which to perform the scan
31562306a36Sopenharmony_ci * @wpan_phy: the wpan phy on which to perform the scan
31662306a36Sopenharmony_ci */
31762306a36Sopenharmony_cistruct cfg802154_scan_request {
31862306a36Sopenharmony_ci	enum nl802154_scan_types type;
31962306a36Sopenharmony_ci	u8 page;
32062306a36Sopenharmony_ci	u32 channels;
32162306a36Sopenharmony_ci	u8 duration;
32262306a36Sopenharmony_ci	struct wpan_dev *wpan_dev;
32362306a36Sopenharmony_ci	struct wpan_phy *wpan_phy;
32462306a36Sopenharmony_ci};
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci/**
32762306a36Sopenharmony_ci * struct cfg802154_beacon_request - Beacon request descriptor
32862306a36Sopenharmony_ci *
32962306a36Sopenharmony_ci * @interval: interval n between sendings, in multiple order of the super frame
33062306a36Sopenharmony_ci *            duration: aBaseSuperframeDuration * (2^n) unless the interval
33162306a36Sopenharmony_ci *            order is greater or equal to 15, in this case beacons won't be
33262306a36Sopenharmony_ci *            passively sent out at a fixed rate but instead inform the device
33362306a36Sopenharmony_ci *            that it should answer beacon requests as part of active scan
33462306a36Sopenharmony_ci *            procedures
33562306a36Sopenharmony_ci * @wpan_dev: the concerned wpan device
33662306a36Sopenharmony_ci * @wpan_phy: the wpan phy this was for
33762306a36Sopenharmony_ci */
33862306a36Sopenharmony_cistruct cfg802154_beacon_request {
33962306a36Sopenharmony_ci	u8 interval;
34062306a36Sopenharmony_ci	struct wpan_dev *wpan_dev;
34162306a36Sopenharmony_ci	struct wpan_phy *wpan_phy;
34262306a36Sopenharmony_ci};
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci/**
34562306a36Sopenharmony_ci * struct cfg802154_mac_pkt - MAC packet descriptor (beacon/command)
34662306a36Sopenharmony_ci * @node: MAC packets to process list member
34762306a36Sopenharmony_ci * @skb: the received sk_buff
34862306a36Sopenharmony_ci * @sdata: the interface on which @skb was received
34962306a36Sopenharmony_ci * @page: page configuration when @skb was received
35062306a36Sopenharmony_ci * @channel: channel configuration when @skb was received
35162306a36Sopenharmony_ci */
35262306a36Sopenharmony_cistruct cfg802154_mac_pkt {
35362306a36Sopenharmony_ci	struct list_head node;
35462306a36Sopenharmony_ci	struct sk_buff *skb;
35562306a36Sopenharmony_ci	struct ieee802154_sub_if_data *sdata;
35662306a36Sopenharmony_ci	u8 page;
35762306a36Sopenharmony_ci	u8 channel;
35862306a36Sopenharmony_ci};
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistruct ieee802154_llsec_key_id {
36162306a36Sopenharmony_ci	u8 mode;
36262306a36Sopenharmony_ci	u8 id;
36362306a36Sopenharmony_ci	union {
36462306a36Sopenharmony_ci		struct ieee802154_addr device_addr;
36562306a36Sopenharmony_ci		__le32 short_source;
36662306a36Sopenharmony_ci		__le64 extended_source;
36762306a36Sopenharmony_ci	};
36862306a36Sopenharmony_ci};
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#define IEEE802154_LLSEC_KEY_SIZE 16
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistruct ieee802154_llsec_key {
37362306a36Sopenharmony_ci	u8 frame_types;
37462306a36Sopenharmony_ci	u32 cmd_frame_ids;
37562306a36Sopenharmony_ci	/* TODO replace with NL802154_KEY_SIZE */
37662306a36Sopenharmony_ci	u8 key[IEEE802154_LLSEC_KEY_SIZE];
37762306a36Sopenharmony_ci};
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistruct ieee802154_llsec_key_entry {
38062306a36Sopenharmony_ci	struct list_head list;
38162306a36Sopenharmony_ci	struct rcu_head rcu;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	struct ieee802154_llsec_key_id id;
38462306a36Sopenharmony_ci	struct ieee802154_llsec_key *key;
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_cistruct ieee802154_llsec_params {
38862306a36Sopenharmony_ci	bool enabled;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	__be32 frame_counter;
39162306a36Sopenharmony_ci	u8 out_level;
39262306a36Sopenharmony_ci	struct ieee802154_llsec_key_id out_key;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	__le64 default_key_source;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	__le16 pan_id;
39762306a36Sopenharmony_ci	__le64 hwaddr;
39862306a36Sopenharmony_ci	__le64 coord_hwaddr;
39962306a36Sopenharmony_ci	__le16 coord_shortaddr;
40062306a36Sopenharmony_ci};
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_cistruct ieee802154_llsec_table {
40362306a36Sopenharmony_ci	struct list_head keys;
40462306a36Sopenharmony_ci	struct list_head devices;
40562306a36Sopenharmony_ci	struct list_head security_levels;
40662306a36Sopenharmony_ci};
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistruct ieee802154_llsec_seclevel {
40962306a36Sopenharmony_ci	struct list_head list;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	u8 frame_type;
41262306a36Sopenharmony_ci	u8 cmd_frame_id;
41362306a36Sopenharmony_ci	bool device_override;
41462306a36Sopenharmony_ci	u32 sec_levels;
41562306a36Sopenharmony_ci};
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistruct ieee802154_llsec_device {
41862306a36Sopenharmony_ci	struct list_head list;
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	__le16 pan_id;
42162306a36Sopenharmony_ci	__le16 short_addr;
42262306a36Sopenharmony_ci	__le64 hwaddr;
42362306a36Sopenharmony_ci	u32 frame_counter;
42462306a36Sopenharmony_ci	bool seclevel_exempt;
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	u8 key_mode;
42762306a36Sopenharmony_ci	struct list_head keys;
42862306a36Sopenharmony_ci};
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistruct ieee802154_llsec_device_key {
43162306a36Sopenharmony_ci	struct list_head list;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	struct ieee802154_llsec_key_id key_id;
43462306a36Sopenharmony_ci	u32 frame_counter;
43562306a36Sopenharmony_ci};
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_cistruct wpan_dev_header_ops {
43862306a36Sopenharmony_ci	/* TODO create callback currently assumes ieee802154_mac_cb inside
43962306a36Sopenharmony_ci	 * skb->cb. This should be changed to give these information as
44062306a36Sopenharmony_ci	 * parameter.
44162306a36Sopenharmony_ci	 */
44262306a36Sopenharmony_ci	int	(*create)(struct sk_buff *skb, struct net_device *dev,
44362306a36Sopenharmony_ci			  const struct ieee802154_addr *daddr,
44462306a36Sopenharmony_ci			  const struct ieee802154_addr *saddr,
44562306a36Sopenharmony_ci			  unsigned int len);
44662306a36Sopenharmony_ci};
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_cistruct wpan_dev {
44962306a36Sopenharmony_ci	struct wpan_phy *wpan_phy;
45062306a36Sopenharmony_ci	int iftype;
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	/* the remainder of this struct should be private to cfg802154 */
45362306a36Sopenharmony_ci	struct list_head list;
45462306a36Sopenharmony_ci	struct net_device *netdev;
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	const struct wpan_dev_header_ops *header_ops;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	/* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
45962306a36Sopenharmony_ci	struct net_device *lowpan_dev;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	u32 identifier;
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	/* MAC PIB */
46462306a36Sopenharmony_ci	__le16 pan_id;
46562306a36Sopenharmony_ci	__le16 short_addr;
46662306a36Sopenharmony_ci	__le64 extended_addr;
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci	/* MAC BSN field */
46962306a36Sopenharmony_ci	atomic_t bsn;
47062306a36Sopenharmony_ci	/* MAC DSN field */
47162306a36Sopenharmony_ci	atomic_t dsn;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	u8 min_be;
47462306a36Sopenharmony_ci	u8 max_be;
47562306a36Sopenharmony_ci	u8 csma_retries;
47662306a36Sopenharmony_ci	s8 frame_retries;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	bool lbt;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	/* fallback for acknowledgment bit setting */
48162306a36Sopenharmony_ci	bool ackreq;
48262306a36Sopenharmony_ci};
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci#define to_phy(_dev)	container_of(_dev, struct wpan_phy, dev)
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
48762306a36Sopenharmony_cistatic inline int
48862306a36Sopenharmony_ciwpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
48962306a36Sopenharmony_ci		     const struct ieee802154_addr *daddr,
49062306a36Sopenharmony_ci		     const struct ieee802154_addr *saddr,
49162306a36Sopenharmony_ci		     unsigned int len)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
49662306a36Sopenharmony_ci}
49762306a36Sopenharmony_ci#endif
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_cistruct wpan_phy *
50062306a36Sopenharmony_ciwpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size);
50162306a36Sopenharmony_cistatic inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev)
50262306a36Sopenharmony_ci{
50362306a36Sopenharmony_ci	phy->dev.parent = dev;
50462306a36Sopenharmony_ci}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ciint wpan_phy_register(struct wpan_phy *phy);
50762306a36Sopenharmony_civoid wpan_phy_unregister(struct wpan_phy *phy);
50862306a36Sopenharmony_civoid wpan_phy_free(struct wpan_phy *phy);
50962306a36Sopenharmony_ci/* Same semantics as for class_for_each_device */
51062306a36Sopenharmony_ciint wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data), void *data);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_cistatic inline void *wpan_phy_priv(struct wpan_phy *phy)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	BUG_ON(!phy);
51562306a36Sopenharmony_ci	return &phy->priv;
51662306a36Sopenharmony_ci}
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_cistruct wpan_phy *wpan_phy_find(const char *str);
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic inline void wpan_phy_put(struct wpan_phy *phy)
52162306a36Sopenharmony_ci{
52262306a36Sopenharmony_ci	put_device(&phy->dev);
52362306a36Sopenharmony_ci}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_cistatic inline const char *wpan_phy_name(struct wpan_phy *phy)
52662306a36Sopenharmony_ci{
52762306a36Sopenharmony_ci	return dev_name(&phy->dev);
52862306a36Sopenharmony_ci}
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_civoid ieee802154_configure_durations(struct wpan_phy *phy,
53162306a36Sopenharmony_ci				    unsigned int page, unsigned int channel);
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci#endif /* __NET_CFG802154_H */
534