M7350/external/compat-wireless/drivers/net/wireless/ath/ath6kl-3.5/p2p.h

375 lines
10 KiB
C
Raw Permalink Normal View History

2024-09-09 08:57:42 +00:00
/*
* Copyright (c) 2004-2012 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef P2P_H
#define P2P_H
#define ATH6KL_P2P_BMISS_TIME (100)
#define ATH6KL_P2P_PS_MAX_NOA_DESCRIPTORS 4
#define ATH6KL_P2P_PS_FLAGS_NOA_ENABLED BIT(0)
#define ATH6KL_P2P_PS_FLAGS_OPPPS_ENABLED BIT(1)
#define NL80211_IFTYPE_P2P_DEVICE_QCA (0xff)
enum {
IEEE80211_P2P_ATTR_NOTICE_OF_ABSENCE = 12,
};
enum {
WLAN_PUB_ACTION_VENDER_SPECIFIC = 9,
};
enum {
WLAN_P2P_GO_NEG_REG = 0,
WLAN_P2P_GO_NEG_RESP = 1,
WLAN_P2P_GO_NEG_CONF = 2,
WLAN_P2P_INVITATION_REQ = 3,
WLAN_P2P_INVITATION_RESP = 4,
WLAN_P2P_DEV_DISC_REQ = 5,
WLAN_P2P_DEV_DISC_RESP = 6,
WLAN_P2P_PROV_DISC_REQ = 7,
WLAN_P2P_PROV_DISC_RESP = 8
};
struct ieee80211_p2p_action_public {
u8 category;
u8 action_code;
u32 oui;
u8 action_subtype;
u8 variable[0];
} __packed;
struct ieee80211_p2p_action_vendor {
u8 category;
u32 oui;
u8 action_subtype;
u8 variable[0];
} __packed;
struct ieee80211_p2p_noa_descriptor {
u8 count_or_type; /* 255: continuous schedule, 0: reserved */
__le32 duration;
__le32 interval;
__le32 start_or_offset;
} __packed;
struct ieee80211_p2p_noa_info {
u8 index;
u8 ctwindow_opps_param;
struct ieee80211_p2p_noa_descriptor
noas[ATH6KL_P2P_PS_MAX_NOA_DESCRIPTORS];
} __packed;
struct ieee80211_p2p_noa_ie {
u8 element_id;
u8 len;
u32 oui;
u8 attr;
u16 attr_len;
struct ieee80211_p2p_noa_info noa_info;
} __packed;
struct p2p_ps_info {
struct ath6kl_vif *vif;
spinlock_t p2p_ps_lock;
/* P2P-GO */
u32 go_flags;
u8 go_noa_enable_idx;
struct ieee80211_p2p_noa_info go_noa;
/* Cached information */
u8 *go_last_beacon_app_ie;
u16 go_last_beacon_app_ie_len;
u8 *go_last_noa_ie;
u16 go_last_noa_ie_len;
u8 *go_working_buffer;
/* counter */
u32 go_noa_notif_cnt;
};
/* P2P Flowctrl */
#define ATH6KL_P2P_FLOWCTRL_NULL_CONNID (0xff)
#define ATH6KL_P2P_FLOWCTRL_RECYCLE_LIMIT (10)
#define ATH6KL_P2P_FLOWCTRL_NETIF_STOP (0x00)
#define ATH6KL_P2P_FLOWCTRL_NETIF_WAKE (0x01)
#define ATH6KL_P2P_FLOWCTRL_REQ_STEP (30)
#define ATH6KL_P2P_FLOWCTRL_TXQ_LIMIT (50)
struct ath6kl_fw_conn_list {
struct list_head conn_queue;
struct list_head re_queue;
u8 connId; /* ID sync between host and target. */
u8 parent_connId; /* For P2P_FLOWCTRL_SCHE_TYPE_INTERFACE */
u8 mac_addr[ETH_ALEN];
struct ath6kl_vif *vif;
union {
struct {
u8 bk_uapsd:1;
u8 be_uapsd:1;
u8 vi_uapsd:1;
u8 vo_uapsd:1;
u8 ps:1; /* 1 means power saved */
u8 ocs:1; /* 1 means off channel */
u8 res:2;
};
u8 connect_status;
};
bool previous_can_send;
/* stat */
int sche_tx_queued;
u32 sche_tx;
u32 sche_re_tx;
u32 sche_re_tx_aging;
};
enum p2p_flowctrl_sche_type {
P2P_FLOWCTRL_SCHE_TYPE_CONNECTION,
P2P_FLOWCTRL_SCHE_TYPE_INTERFACE,
};
struct ath6kl_p2p_flowctrl {
struct ath6kl *ar;
spinlock_t p2p_flowctrl_lock;
enum p2p_flowctrl_sche_type sche_type;
struct ath6kl_fw_conn_list fw_conn_list[NUM_CONN];
u32 p2p_flowctrl_event_cnt;
};
/* P2P RecommendChannel */
#define ATH6KL_RC_FLAGS_NEED_UPDATED (1 << 0)
#define ATH6KL_RC_FLAGS_DONE (1 << 1)
#define ATH6KL_RC_FLAGS_HIGH_CHAN (1 << 2)
#define ATH6KL_RC_FLAGS_ALWAYS_FRESH (1 << 3)
#define ATH6KL_RC_FLAGS_CHAN_RECORD_FETCHED (1 << 4)
#define ATH6KL_RC_MAX_2G_CHAN_RECORD (14)
#define ATH6KL_RC_MAX_5G_CHAN_RECORD (66)
#define ATH6KL_RC_MAX_CHAN_RECORD (ATH6KL_RC_MAX_2G_CHAN_RECORD + \
ATH6KL_RC_MAX_5G_CHAN_RECORD)
#define ATH6KL_RC_AVERAGE_CHAN_CNT (5) /* 20MHz width */
#define ATH6KL_RC_AVERAGE_CHAN_OFFSET (2) /* 10MHz plus or minus */
#define ATH6KL_RC_AVERAGE_CHAN_START (2412) /* Channel 1 */
#define ATH6KL_RC_AVERAGE_CHAN_END (2472) /* Channel 13 */
#define ATH6KL_RC_FRESH_TIME msecs_to_jiffies(5 * 60 * 1000)
enum p2p_rc_user_chan_type {
P2P_RC_USER_BLACK_CHAN, /* Black channel list */
P2P_RC_USER_WHITE_CHAN, /* White channel list */
};
enum p2p_rc_type {
P2P_RC_TYPE_2GALL, /* the best in all 2G channels */
P2P_RC_TYPE_5GALL, /* the best in all 5G channels */
P2P_RC_TYPE_OVERALL, /* the best in all channels */
P2P_RC_TYPE_SOCAIL, /* the best in 1, 6 abd 11 channels */
P2P_RC_TYPE_2GP2P, /* the best in P2P 2G channels */
P2P_RC_TYPE_5GP2P, /* the best in P2P 5G channels */
P2P_RC_TYPE_ALLP2P, /* the best in P2P channels */
P2P_RC_TYPE_5GNODFS, /* the best in all 5G channels w/o DFS */
P2P_RC_TYPE_OVERALLNODFS, /* the best in all channels w/o DFS */
P2P_RC_TYPE_2GNOLTE, /* the best in 2G channels w/o LTE */
P2P_RC_TYPE_OVERALLNOLTE, /* the best in all channels w/o LTE */
P2P_RC_TYPE_OVERALLNOLTEDFS, /* the best in all channels w/o LTE/DFS */
P2P_RC_TYPE_USER_CHAN, /* the best in user's channels */
P2P_RC_TYPE_MAX, /* keep last */
};
struct p2p_rc_bss_info {
struct list_head list;
struct ieee80211_channel *channel;
u8 rssi;
};
struct p2p_rc_chan_record {
struct ieee80211_channel *channel;
#define P2P_RC_MAX_SNR (96)
#define P2P_RC_NULL_SNR (P2P_RC_MAX_SNR + 1)
u8 best_snr;
u8 aver_snr; /* for 2G */
};
struct ath6kl_p2p_rc_info {
struct ath6kl *ar;
u32 flags;
spinlock_t p2p_rc_lock;
int chan_record_cnt;
struct p2p_rc_chan_record chan_record[ATH6KL_RC_MAX_CHAN_RECORD];
unsigned long last_update; /* in jiffies */
#define P2P_RC_DEF_SNR_COMP (0)
int snr_compensation;
enum p2p_rc_user_chan_type user_chan_type;
u16 user_chan_list[ATH6KL_RC_MAX_CHAN_RECORD];
/* Keep the latest result. */
struct p2p_rc_chan_record *last_p2p_rc[P2P_RC_TYPE_MAX];
};
struct ath6kl_rc_report {
u16 rc_2g;
u16 rc_5g;
u16 rc_all;
u16 rc_p2p_so;
u16 rc_p2p_2g;
u16 rc_p2p_5g;
u16 rc_p2p_all;
u16 rc_5g_nodfs;
u16 rc_all_nodfs;
u16 rc_2g_nolte;
u16 rc_all_nolte;
u16 rc_user_chan;
u16 rc_all_noltedfs;
};
struct p2p_oper_chan {
u16 oper_class;
u32 min_chan_freq;
u32 max_chan_freq;
u32 inc_freq;
#define P2P_OPER_CHAN_BW_NULL 0
#define P2P_OPER_CHAN_BW_HT20 1
#define P2P_OPER_CHAN_BW_HT40_PLUS 2
#define P2P_OPER_CHAN_BW_HT40_MINUS 3
u8 bw;
};
struct p2p_pending_connect_info {
#define ATH6KL_P2P_MAX_PENDING_INFO_IELEN 512
u8 bssid[ETH_ALEN];
u8 req_ie[ATH6KL_P2P_MAX_PENDING_INFO_IELEN];
size_t req_ie_len;
u8 resp_ie[ATH6KL_P2P_MAX_PENDING_INFO_IELEN];
size_t resp_ie_len;
u16 status;
gfp_t gfp;
};
struct p2p_ps_info *ath6kl_p2p_ps_init(struct ath6kl_vif *vif);
void ath6kl_p2p_ps_deinit(struct ath6kl_vif *vif);
int ath6kl_p2p_ps_reset_noa(struct p2p_ps_info *p2p_ps);
int ath6kl_p2p_ps_setup_noa(struct p2p_ps_info *p2p_ps,
int noa_id,
u8 count_type,
u32 interval,
u32 start_offset,
u32 duration);
int ath6kl_p2p_ps_reset_opps(struct p2p_ps_info *p2p_ps);
int ath6kl_p2p_ps_setup_opps(struct p2p_ps_info *p2p_ps,
u8 enabled,
u8 ctwindows);
int ath6kl_p2p_ps_update_notif(struct p2p_ps_info *p2p_ps);
void ath6kl_p2p_ps_user_app_ie(struct p2p_ps_info *p2p_ps, u8 mgmt_frm_type,
u8 **ie, int *len);
int ath6kl_p2p_utils_trans_porttype(enum nl80211_iftype type,
u8 *opmode,
u8 *subopmode);
int ath6kl_p2p_utils_init_port(struct ath6kl_vif *vif,
enum nl80211_iftype type);
int ath6kl_p2p_utils_check_port(struct ath6kl_vif *vif,
u8 port_id);
struct ath6kl_p2p_flowctrl *ath6kl_p2p_flowctrl_conn_list_init(
struct ath6kl *ar);
void ath6kl_p2p_flowctrl_conn_collect_by_conn(
struct ath6kl_fw_conn_list *fw_conn, struct list_head *pcontainer,
int *preclaim);
void ath6kl_p2p_flowctrl_conn_list_deinit(struct ath6kl *ar);
void ath6kl_p2p_flowctrl_conn_list_cleanup(struct ath6kl *ar);
void ath6kl_p2p_flowctrl_conn_list_cleanup_by_if(struct ath6kl_vif *vif);
void ath6kl_p2p_flowctrl_netif_transition(struct ath6kl *ar,
u8 new_state);
void ath6kl_p2p_flowctrl_tx_schedule(struct ath6kl *ar);
int ath6kl_p2p_flowctrl_tx_schedule_pkt(struct ath6kl *ar, void *pkt);
void ath6kl_p2p_flowctrl_state_change(struct ath6kl *ar);
void ath6kl_p2p_flowctrl_state_update(struct ath6kl *ar,
u8 numConn,
u8 ac_map[],
u8 ac_queue_depth[]);
void ath6kl_p2p_flowctrl_set_conn_id(struct ath6kl_vif *vif,
u8 mac_addr[],
u8 connId);
u8 ath6kl_p2p_flowctrl_get_conn_id(struct ath6kl_vif *vif,
struct sk_buff *skb);
int ath6kl_p2p_flowctrl_stat(struct ath6kl *ar,
u8 *buf, int buf_len);
struct ath6kl_p2p_rc_info *ath6kl_p2p_rc_init(struct ath6kl *ar);
void ath6kl_p2p_rc_deinit(struct ath6kl *ar);
void ath6kl_p2p_rc_fetch_chan(struct ath6kl *ar);
void ath6kl_p2p_rc_bss_info(struct ath6kl_vif *vif,
u8 snr,
struct ieee80211_channel *channel);
void ath6kl_p2p_rc_scan_start(struct ath6kl_vif *vif, bool local_scan);
int ath6kl_p2p_rc_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
int ath6kl_p2p_rc_get(struct ath6kl *ar, struct ath6kl_rc_report *rc_report);
int ath6kl_p2p_rc_dump(struct ath6kl *ar, u8 *buf, int buf_len);
void ath6kl_p2p_rc_config(struct ath6kl *ar, u16 freq, int type);
bool ath6kl_p2p_frame_retry(struct ath6kl *ar, u8 *frm, int len);
bool ath6kl_p2p_is_p2p_frame(struct ath6kl *ar, const u8 *frm, size_t len);
void ath6kl_p2p_connect_event(struct ath6kl_vif *vif,
u8 beacon_ie_len,
u8 assoc_req_len,
u8 assoc_resp_len,
u8 *assoc_info);
void ath6kl_p2p_reconfig_ps(struct ath6kl *ar,
bool mcc,
bool call_on_disconnect);
bool ath6kl_p2p_pending_connect_event(struct ath6kl_vif *vif,
const u8 *bssid,
const u8 *req_ie,
size_t req_ie_len,
const u8 *resp_ie,
size_t resp_ie_len,
u16 status,
gfp_t gfp);
void ath6kl_p2p_pending_disconnect_event(struct ath6kl_vif *vif,
u16 reason,
u8 *ie,
size_t ie_len,
gfp_t gfp);
bool ath6kl_p2p_ie_append(struct ath6kl_vif *vif, u8 mgmt_frame_type);
bool ath6kl_p2p_is_p2p_channel(u32 freq);
bool ath6kl_p2p_is_social_channel(u32 freq);
int ath6kl_p2p_build_scan_chan(struct ath6kl_vif *vif,
u32 req_chan_num,
u16 *chan_list);
#endif