/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * policy.c - provides attribute names and policies for commands.
 *
 * Copyright (C) 2022-2024 IOPSYS Software Solutions AB. All rights reserved.
 * Copyright (C) 2025 Genexis AB.
 *
 */

enum {
	SCAN_SSID,
	SCAN_BSSID,
	SCAN_CHANNEL,
	SCAN_OPCLASS,
	/* SCAN_TYPE,    // active, passsive, background */
	__SCAN_MAX,
};

static const struct blobmsg_policy wl_scan_policy[__SCAN_MAX] = {
	[SCAN_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
	[SCAN_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
	[SCAN_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[SCAN_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_INT32 },
	/* [SCAN_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 }, */
};

enum {
	SCAN_EX_SSID,
	SCAN_EX_BSSID,
	SCAN_EX_OPCLASS,
	SCAN_EX_CHANNEL,
	// SCAN_EX_TYPE,    // active, passsive, cached */
	SCAN_EX_DURATION,
	__SCAN_EX_MAX,
};

static const struct blobmsg_policy wl_scan_ex_policy[__SCAN_EX_MAX] = {
	[SCAN_EX_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_ARRAY },
	[SCAN_EX_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
	[SCAN_EX_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_ARRAY },
	[SCAN_EX_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_ARRAY },
	// [SCAN_EX_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
	[SCAN_EX_DURATION] = { .name = "duration", .type = BLOBMSG_TYPE_INT16 },
};

enum {
	SCANRES_BSSID,
	SCANRES_CACHE,
	__SCANRES_MAX,
};

static const struct blobmsg_policy wl_scanres_policy[__SCANRES_MAX] = {
	[SCANRES_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
	[SCANRES_CACHE] = { .name = "cache", .type = BLOBMSG_TYPE_BOOL },
};


enum {
	ACS_PARAM_EXCLUDE_DFS,
	ACS_PARAM_EXCLUDE_6GHZ_NON_PSC,
	ACS_PARAM_EXCLUDE_OPCLASS,
	ACS_PARAM_EXCLUDE_CHANNELS,
	ACS_PARAM_EXCLUDE_BANDWIDTH,
	ACS_PARAM_INCLUDE_CHANNELS,
	ACS_PARAM_INCLUDE_BANDWIDTH,
	ACS_PARAM_MODE,
	NUM_ACS_PARAMS,
};

enum {
	ACS_PARAM_CHANNEL_NUMBER,
	ACS_PARAM_CHANNEL_BANDWIDTH,
	ACS_PARAM_CHANNEL_WEIGHT,
	NUM_ACS_CHANNEL_PARAMS,
};

static const struct blobmsg_policy wl_acs_policy[NUM_ACS_PARAMS] = {
	[ACS_PARAM_EXCLUDE_DFS] = { .name = "exclude_dfs", .type = BLOBMSG_TYPE_BOOL },
	[ACS_PARAM_EXCLUDE_6GHZ_NON_PSC] = { .name = "exclude_6ghz_non_psc", .type = BLOBMSG_TYPE_BOOL },
	[ACS_PARAM_EXCLUDE_OPCLASS] = { .name = "exclude_opclass", .type = BLOBMSG_TYPE_ARRAY},
	[ACS_PARAM_EXCLUDE_CHANNELS] = { .name = "exclude_channels", .type = BLOBMSG_TYPE_ARRAY},
	[ACS_PARAM_EXCLUDE_BANDWIDTH] = { .name = "exclude_bandwidth", .type = BLOBMSG_TYPE_ARRAY},
	[ACS_PARAM_INCLUDE_CHANNELS] = { .name = "channels", .type = BLOBMSG_TYPE_ARRAY},
	[ACS_PARAM_INCLUDE_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_ARRAY},
	[ACS_PARAM_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING},
};

enum {
	CAC_CHANNEL,
	CAC_BANDWIDTH,
	CAC_METHOD,
	__CAC_MAX,
};

static const struct blobmsg_policy wl_cac_policy[__CAC_MAX] = {
	[CAC_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[CAC_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
	[CAC_METHOD] = { .name = "method", .type = BLOBMSG_TYPE_INT32 },
};


enum {
	ADD_IFACE_ARGS,
	ADD_IFACE_CONF,
	__ADD_IFACE_MAX,
};

static const struct blobmsg_policy add_iface_policy[__ADD_IFACE_MAX] = {
	[ADD_IFACE_ARGS] = { .name = "args", .type = BLOBMSG_TYPE_TABLE },
	[ADD_IFACE_CONF] = { .name = "config", .type = BLOBMSG_TYPE_BOOL },
};

enum {
	DEL_IFACE_IFNAME,
	DEL_IFACE_CONF,
	__DEL_IFACE_MAX,
};

static const struct blobmsg_policy del_iface_policy[__DEL_IFACE_MAX] = {
	[DEL_IFACE_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
	[DEL_IFACE_CONF] = { .name = "config", .type = BLOBMSG_TYPE_BOOL },
};


enum {
	DUMP_CHANNELS_FOR_BANDWIDTH,
	NUM_DUMP_CHANNELS,
};

static const struct blobmsg_policy wl_dump_channels_policy[NUM_DUMP_CHANNELS] = {
	[DUMP_CHANNELS_FOR_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
};


enum {
	RADAR_CHANNEL,
	RADAR_BANDWIDTH,
	RADAR_TYPE,
	RADAR_SUBBAND_MASK,
	__RADAR_MAX,
};

static const struct blobmsg_policy wl_radar_policy[__RADAR_MAX] = {
	[RADAR_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[RADAR_BANDWIDTH] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
	[RADAR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
	[RADAR_SUBBAND_MASK] = { .name = "subband_mask", .type = BLOBMSG_TYPE_INT32 },
};



enum {
	GET_PNAME,
	__GET_MAX,
};

static const struct blobmsg_policy radio_get_param_policy[__GET_MAX] = {
	[GET_PNAME] = { .name = "param", .type = BLOBMSG_TYPE_STRING },
};

enum {
	CHAN_SWITCH_COUNT,
	CHAN_SWITCH_CHANNEL,	/* primary ctrl-channel */
	CHAN_SWITCH_FREQ,
	CHAN_SWITCH_SEC_CHAN_OFFSET,
	CHAN_SWITCH_CF1,
	CHAN_SWITCH_CF2,
	CHAN_SWITCH_BW,
	CHAN_SWITCH_BLOCK_TX,
	CHAN_SWITCH_HT,
	CHAN_SWITCH_VHT,
	CHAN_SWITCH_HE,
	CHAN_SWITCH_EHT,
	CHAN_SWITCH_AUTO_HT,
	__CHAN_SWITCH_MAX,
};

static const struct blobmsg_policy chan_switch_policy[__CHAN_SWITCH_MAX] = {
	[CHAN_SWITCH_COUNT] = { .name = "count", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_SEC_CHAN_OFFSET] = { .name = "sec_chan_offset", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_CF1] = { .name = "cf1", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_CF2] = { .name = "cf2", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_BW] = { .name = "bw", .type = BLOBMSG_TYPE_INT32 },
	[CHAN_SWITCH_BLOCK_TX] = { .name = "blocktx", .type = BLOBMSG_TYPE_BOOL },
	[CHAN_SWITCH_HT] = { .name = "ht", .type = BLOBMSG_TYPE_BOOL },
	[CHAN_SWITCH_VHT] = { .name = "vht", .type = BLOBMSG_TYPE_BOOL },
	[CHAN_SWITCH_HE] = { .name = "he", .type = BLOBMSG_TYPE_BOOL },
	[CHAN_SWITCH_EHT] = { .name = "eht", .type = BLOBMSG_TYPE_BOOL },
	[CHAN_SWITCH_AUTO_HT] = { .name = "auto-ht", .type = BLOBMSG_TYPE_BOOL },
};


enum {
	DEBUG_LEVEL,
	__DEBUG_LEVEL_MAX,
};

static const struct blobmsg_policy wifi_set_debug_policy[__DEBUG_LEVEL_MAX] = {
	[DEBUG_LEVEL] = { .name = "level", .type = BLOBMSG_TYPE_INT32 },
};

/* detailed stainfo policy */
enum {
	STAINFO_MACADDR,    /* sta macaddress */
	__STAINFO_MAX,
};

static const struct blobmsg_policy stainfo_policy[__STAINFO_MAX] = {
	[STAINFO_MACADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};

/* list neighbors policy */
enum {
	NBR_LIST_SSID,    /* ssid filter */
	NBR_LIST_CLIENT,  /* from beacon report by client */
	__NBR_LIST_MAX,
};

static const struct blobmsg_policy nbr_list_policy[__NBR_LIST_MAX] = {
	[NBR_LIST_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
	[NBR_LIST_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
};

/* sta disconnect policy */
enum {
	STA_DISCONNECT_STA,   /* sta mac ':' separated */
	STA_DISCONNECT_REASON,
	__STA_DISCONNECT_MAX,
};

static const struct blobmsg_policy sta_disconnect_policy[__STA_DISCONNECT_MAX] = {
	[STA_DISCONNECT_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
	[STA_DISCONNECT_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32 }
};

/* sta monitor policy */
enum {
	STA_MONITOR_ADDR,   /* sta mac ':' separated */
	__STA_MONITOR_MAX,
};

static const struct blobmsg_policy sta_monitor_policy[__STA_MONITOR_MAX] = {
	[STA_MONITOR_ADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};

/* add neighbor policy */
enum {
	NBR_ADD_BSSID,   /* bssid ':' separated */
	NBR_ADD_CHANNEL,
	NBR_ADD_BINFO,   /* bssid info; default = 0x3 (reachable) */
	NBR_ADD_REG,     /* regulatory; default = 0 */
	NBR_ADD_PHY,     /* phytype; default = 9 = PHY_VHT */
	__NBR_ADD_MAX,
};

static const struct blobmsg_policy nbr_add_policy[__NBR_ADD_MAX] = {
	[NBR_ADD_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
	[NBR_ADD_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[NBR_ADD_BINFO] = { .name = "bssid_info", .type = BLOBMSG_TYPE_STRING },
	[NBR_ADD_REG] = { .name = "reg", .type = BLOBMSG_TYPE_INT32 },
	[NBR_ADD_PHY] = { .name = "phy", .type = BLOBMSG_TYPE_INT32 },
};

/* delete neighbor policy */
enum {
	NBR_DEL_BSSID,
	__NBR_DEL_MAX,
};

static const struct blobmsg_policy nbr_del_policy[__NBR_DEL_MAX] = {
	[NBR_DEL_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
};

/* send neighbor request policy */
enum {
	NBR_REQ_CLIENT,
	NBR_REQ_OPCLASS,
	NBR_REQ_CHANNEL,
	NBR_REQ_DURATION,
	NBR_REQ_MODE,
	NBR_REQ_BSSID,
	NBR_REQ_REP_DETAIL,
	NBR_REQ_SSID,
	NBR_REQ_CHAN_REPORT,
	NBR_REQ_ELEMENT_IDS,
	__NBR_REQ_MAX,
};

static const struct blobmsg_policy nbr_req_policy[__NBR_REQ_MAX] = {
	[NBR_REQ_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
	[NBR_REQ_OPCLASS] = { .name = "opclass", .type = BLOBMSG_TYPE_INT32 },
	[NBR_REQ_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
	[NBR_REQ_DURATION] = { .name = "duration", .type = BLOBMSG_TYPE_INT32 },
	[NBR_REQ_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
	[NBR_REQ_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
	[NBR_REQ_REP_DETAIL] = { .name = "reporting_detail", .type = BLOBMSG_TYPE_INT32  },
	[NBR_REQ_SSID] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
	[NBR_REQ_CHAN_REPORT] = { .name = "channel_report", .type = BLOBMSG_TYPE_ARRAY },
	[NBR_REQ_ELEMENT_IDS] = { .name = "request_element", .type = BLOBMSG_TYPE_ARRAY },
};

/* send btm request policy */
enum {
	BTM_REQ_STA,
	BTM_REQ_TARGET,
	BTM_REQ_MODE,
	BTM_REQ_DISASSOC_TMO,
	BTM_REQ_VALIDITY_INT,
	BTM_REQ_DIALOG_TOKEN,
	BTM_REQ_BSSTERM_DUR,
	BTM_REQ_MBO_REASON,        /* MBO r19, 4.2.6: Transition Reason Code Attribute (id=0x06) */
	BTM_REQ_MBO_CELL_PREF,     /* MBO r19, 4.2.5: Cellular Data Connection Preference (id=0x05) */
	BTM_REQ_MBO_REASSOC_DELAY, /* MBO r19, 4.2.8: Assoc retry delay (id=0x08), 0-65535 */
	__BTM_REQ_MAX,
};

static const struct blobmsg_policy btmreq_policy[__BTM_REQ_MAX] = {
	[BTM_REQ_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
	[BTM_REQ_TARGET] = { .name = "target_ap", .type = BLOBMSG_TYPE_ARRAY },
	[BTM_REQ_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_DISASSOC_TMO] = { .name = "disassoc_tmo", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_VALIDITY_INT] = { .name = "validity_int", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_DIALOG_TOKEN] = { .name = "dialog_token", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_BSSTERM_DUR] = { .name = "bssterm_dur", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_MBO_REASON] = { .name = "mbo_reason", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_MBO_CELL_PREF] = { .name = "mbo_cell_pref", .type = BLOBMSG_TYPE_INT32 },
	[BTM_REQ_MBO_REASSOC_DELAY] = { .name = "mbo_reassoc_delay", .type = BLOBMSG_TYPE_INT32 },
};

/* send association controll policy */
enum {
	ASSOC_CNTRL_CLIENT,
	ASSOC_CNTRL_ENABLE,
	__ASSOC_CNTRL_MAX,
};

static const struct blobmsg_policy assoc_cntrl_policy[__ASSOC_CNTRL_MAX] = {
	[ASSOC_CNTRL_CLIENT] = { .name = "client", .type = BLOBMSG_TYPE_ARRAY },
	[ASSOC_CNTRL_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_INT32  },
};

/* block station policy */
enum {
	BLOCK_STATION_MACADDR,
	BLOCK_STATION_BLOCK,
	__BLOCK_STATION_MAX,
};

static const struct blobmsg_policy block_station_policy[__BLOCK_STATION_MAX] = {
	[BLOCK_STATION_MACADDR] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
	[BLOCK_STATION_BLOCK] = { .name = "block", .type = BLOBMSG_TYPE_INT32 },
};

/* apmld block station policy */
enum {
	APMLD_BLOCK_STATION_MACADDR,
	APMLD_BLOCK_STATION_BLOCK,
	APMLD_BLOCK_STATION_BAND,
	__APMLD_BLOCK_STATION_MAX,
};

static const struct blobmsg_policy apmld_block_station_policy[__APMLD_BLOCK_STATION_MAX] = {
	[APMLD_BLOCK_STATION_MACADDR] = { .name = "client", .type = BLOBMSG_TYPE_STRING },
	[APMLD_BLOCK_STATION_BLOCK] = { .name = "block", .type = BLOBMSG_TYPE_INT32 },
	[APMLD_BLOCK_STATION_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};

/* apmld get blocked maclist */
enum {
	APMLD_BLOCKED_MACLIST_BAND,
	__APMLD_BLOCKED_MACLIST_MAX,
};

static const struct blobmsg_policy apmld_blocked_maclist_policy[__APMLD_BLOCKED_MACLIST_MAX] = {
	[APMLD_BLOCKED_MACLIST_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};

/* dump beacon policy */
enum {
	DUMP_BEACON_BAND,
	__DUMP_BEACON_MAX,
};

static const struct blobmsg_policy dump_beacon_policy[__DUMP_BEACON_MAX] = {
	[DUMP_BEACON_BAND] = { .name = "band", .type = BLOBMSG_TYPE_INT32 },
};

/* vendor_ie add/del policy */
enum {
	VSIE_MGMT_STYPE,       /* bitmask of (1 << mgmt frame subtype) */
	VSIE_OUI,
	VSIE_DATA,
	__VSIE_MAX,
};

static const struct blobmsg_policy vsie_policy[__VSIE_MAX] = {
	[VSIE_MGMT_STYPE] = { .name = "mgmt", .type = BLOBMSG_TYPE_INT32 },
	[VSIE_OUI] = { .name = "oui", .type = BLOBMSG_TYPE_STRING},
	[VSIE_DATA] = { .name = "data", .type = BLOBMSG_TYPE_STRING},
};

/* link measure request policy */
enum {
	LINKMEAS_STA,
	__LINKMEAS_MAX,
};

static const struct blobmsg_policy linkmeas_policy[__LINKMEAS_MAX] = {
	[LINKMEAS_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};

enum {
	MBO_DISALLOW_ASSOC_REASON,
	__MBO_DISALLOW_ASSOC_MAX,
};

static const struct blobmsg_policy mbo_disallow_assoc_policy[__MBO_DISALLOW_ASSOC_MAX] = {
	[MBO_DISALLOW_ASSOC_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32 },
};

/* send qos map policy */
enum {
	AP_SEND_QOS_MAP_CONF_ADDR,   /* sta mac ':' separated */
	__AP_SEND_QOS_MAP_CONF_MAX,
};

static const struct blobmsg_policy ap_send_qos_map_conf_policy[__AP_SEND_QOS_MAP_CONF_MAX] = {
	[AP_SEND_QOS_MAP_CONF_ADDR] = { .name = "sta", .type = BLOBMSG_TYPE_STRING },
};

/* set qos map policy */
enum {
	AP_SET_QOS_MAP_SET,   /* Array of u32 elements making up a QoS map */
	__AP_SET_QOS_MAP_SET_MAX,
};

static const struct blobmsg_policy ap_set_qos_map_policy[__AP_SET_QOS_MAP_SET_MAX] = {
	[AP_SET_QOS_MAP_SET] = { .name = "set", .type = BLOBMSG_TYPE_ARRAY },
};

/* disconnect from ap policy */
enum {
	AP_DISCONNECT_REASON,   /* deauth/disassoc reason code */
	__AP_DISCONNECT_MAX,
};

static const struct blobmsg_policy ap_disconnect_policy[__AP_DISCONNECT_MAX] = {
	[AP_DISCONNECT_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32}
};

enum {
	STA_4ADDR_ENABLE,
	__STA_4ADDR_MAX,
};

static const struct blobmsg_policy sta_4addr_policy[__STA_4ADDR_MAX] = {
	[STA_4ADDR_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_INT32}
};


enum {
	ACTION_DST,
	ACTION_WAIT,
	ACTION_FREQ,
	ACTION_FRAME,
	ACTION_SRC,
	__ACTION_MAX,
};

static const struct blobmsg_policy send_action_policy[__ACTION_MAX] = {
	[ACTION_DST] = { .name = "dst", .type = BLOBMSG_TYPE_STRING },
	[ACTION_WAIT] = { .name = "wait", .type = BLOBMSG_TYPE_INT32 },
	[ACTION_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 },
	[ACTION_FRAME] = { .name = "frame", .type = BLOBMSG_TYPE_STRING },
	[ACTION_SRC] = { .name = "src", .type = BLOBMSG_TYPE_STRING },
};

enum {
	DPP_LISTEN_FREQ,
	__DPP_LISTEN_MAX,
};


static const struct blobmsg_policy dpp_listen_policy[__DPP_LISTEN_MAX] = {
	[DPP_LISTEN_FREQ] = { .name = "freq", .type = BLOBMSG_TYPE_INT32 }
};

enum {
	SUBSCRIBE_FRAME_TYPE,
	SUBSCRIBE_FRAME_SUBTYPE,
	__SUBSCRIBE_FRAME_MAX,
};

static const struct blobmsg_policy subscribe_frame_policy[__SUBSCRIBE_FRAME_MAX] = {
	[SUBSCRIBE_FRAME_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_INT32 },
	[SUBSCRIBE_FRAME_SUBTYPE] = { .name = "stype", .type = BLOBMSG_TYPE_INT32 },
};

/* WPS attributes follow */
enum {
	ATTR_PIN,
	__ATTR_PIN_MAX,
};

static const struct blobmsg_policy pin_policy[__ATTR_PIN_MAX] = {
	[ATTR_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};

enum {
	WPS_ATTR_IFNAME,
	__ATTR_IFNAME_ONLY,
};

static const struct blobmsg_policy ifname_policy[__ATTR_IFNAME_ONLY] = {
	[WPS_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
};

enum {
	PIN_SET_IFNAME,
	PIN_SET_PIN,
	__PIN_SET_MAX,
};

static const struct blobmsg_policy pin_set_policy[__PIN_SET_MAX] = {
	[PIN_SET_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
	[PIN_SET_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};

enum {
	WPS_START_ATTR_IFNAME,
	WPS_START_ATTR_MODE,
	WPS_START_ATTR_ROLE,
	WPS_START_ATTR_STA_PIN,
	__WPS_START_ATTR_MAX,
};

static const struct blobmsg_policy wps_start_policy[__WPS_START_ATTR_MAX] = {
	[WPS_START_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
	[WPS_START_ATTR_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
	[WPS_START_ATTR_ROLE] = { .name = "role", .type = BLOBMSG_TYPE_STRING },
	[WPS_START_ATTR_STA_PIN] = { .name = "pin", .type = BLOBMSG_TYPE_STRING },
};

