// SPDX-License-Identifier: ISC /* * Copyright (c) 2012 Broadcom Corporation */ #include <linux/slab.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/rtnetlink.h> #include <net/cfg80211.h> #include <brcmu_wifi.h> #include <brcmu_utils.h> #include <defs.h> #include "core.h" #include "debug.h" #include "fwil.h" #include "fwil_types.h" #include "p2p.h" #include "cfg80211.h" #include "feature.h" /* parameters used for p2p escan */ #define P2PAPI_SCAN_NPROBES … #define P2PAPI_SCAN_DWELL_TIME_MS … #define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS … #define P2PAPI_SCAN_HOME_TIME_MS … #define P2PAPI_SCAN_NPROBS_TIME_MS … #define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS … #define WL_SCAN_CONNECT_DWELL_TIME_MS … #define WL_SCAN_JOIN_PROBE_INTERVAL_MS … #define BRCMF_P2P_WILDCARD_SSID … #define BRCMF_P2P_WILDCARD_SSID_LEN … #define SOCIAL_CHAN_1 … #define SOCIAL_CHAN_2 … #define SOCIAL_CHAN_3 … #define IS_P2P_SOCIAL_CHANNEL(channel) … #define BRCMF_P2P_TEMP_CHAN … #define SOCIAL_CHAN_CNT … #define AF_PEER_SEARCH_CNT … #define BRCMF_SCB_TIMEOUT_VALUE … #define P2P_VER … #define P2P_PUB_AF_CATEGORY … #define P2P_PUB_AF_ACTION … #define P2P_AF_CATEGORY … #define P2P_OUI … #define P2P_OUI_LEN … /* Action Frame Constants */ #define DOT11_ACTION_HDR_LEN … #define DOT11_ACTION_CAT_OFF … #define DOT11_ACTION_ACT_OFF … #define P2P_AF_DWELL_TIME … #define P2P_AF_MIN_DWELL_TIME … #define P2P_AF_MED_DWELL_TIME … #define P2P_AF_LONG_DWELL_TIME … #define P2P_AF_TX_MAX_RETRY … #define P2P_AF_MAX_WAIT_TIME … #define P2P_INVALID_CHANNEL … #define P2P_CHANNEL_SYNC_RETRY … #define P2P_AF_FRM_SCAN_MAX_WAIT … #define P2P_DEFAULT_SLEEP_TIME_VSDB … #define P2P_AF_RETRY_DELAY_TIME … /* WiFi P2P Public Action Frame OUI Subtypes */ #define P2P_PAF_GON_REQ … #define P2P_PAF_GON_RSP … #define P2P_PAF_GON_CONF … #define P2P_PAF_INVITE_REQ … #define P2P_PAF_INVITE_RSP … #define P2P_PAF_DEVDIS_REQ … #define P2P_PAF_DEVDIS_RSP … #define P2P_PAF_PROVDIS_REQ … #define P2P_PAF_PROVDIS_RSP … #define P2P_PAF_SUBTYPE_INVALID … /* WiFi P2P Action Frame OUI Subtypes */ #define P2P_AF_NOTICE_OF_ABSENCE … #define P2P_AF_PRESENCE_REQ … #define P2P_AF_PRESENCE_RSP … #define P2P_AF_GO_DISC_REQ … /* P2P Service Discovery related */ #define P2PSD_ACTION_CATEGORY … #define P2PSD_ACTION_ID_GAS_IREQ … #define P2PSD_ACTION_ID_GAS_IRESP … #define P2PSD_ACTION_ID_GAS_CREQ … #define P2PSD_ACTION_ID_GAS_CRESP … #define BRCMF_P2P_DISABLE_TIMEOUT … /* Mask for retry counter of custom dwell time */ #define CUSTOM_RETRY_MASK … /** * struct brcmf_p2p_disc_st_le - set discovery state in firmware. * * @state: requested discovery state (see enum brcmf_p2p_disc_state). * @chspec: channel parameter for %WL_P2P_DISC_ST_LISTEN state. * @dwell: dwell time in ms for %WL_P2P_DISC_ST_LISTEN state. */ struct brcmf_p2p_disc_st_le { … }; /** * enum brcmf_p2p_disc_state - P2P discovery state values * * @WL_P2P_DISC_ST_SCAN: P2P discovery with wildcard SSID and P2P IE. * @WL_P2P_DISC_ST_LISTEN: P2P discovery off-channel for specified time. * @WL_P2P_DISC_ST_SEARCH: P2P discovery with P2P wildcard SSID and P2P IE. */ enum brcmf_p2p_disc_state { … }; /** * struct brcmf_p2p_scan_le - P2P specific scan request. * * @type: type of scan method requested (values: 'E' or 'S'). * @reserved: reserved (ignored). * @eparams: parameters used for type 'E'. * @sparams: parameters used for type 'S'. */ struct brcmf_p2p_scan_le { … }; /** * struct brcmf_p2p_pub_act_frame - WiFi P2P Public Action Frame * * @category: P2P_PUB_AF_CATEGORY * @action: P2P_PUB_AF_ACTION * @oui: P2P_OUI * @oui_type: OUI type - P2P_VER * @subtype: OUI subtype - P2P_TYPE_* * @dialog_token: nonzero, identifies req/rsp transaction * @elts: Variable length information elements. */ struct brcmf_p2p_pub_act_frame { … }; /** * struct brcmf_p2p_action_frame - WiFi P2P Action Frame * * @category: P2P_AF_CATEGORY * @oui: OUI - P2P_OUI * @type: OUI Type - P2P_VER * @subtype: OUI Subtype - P2P_AF_* * @dialog_token: nonzero, identifies req/resp tranaction * @elts: Variable length information elements. */ struct brcmf_p2p_action_frame { … }; /** * struct brcmf_p2psd_gas_pub_act_frame - Wi-Fi GAS Public Action Frame * * @category: 0x04 Public Action Frame * @action: 0x6c Advertisement Protocol * @dialog_token: nonzero, identifies req/rsp transaction * @query_data: Query Data. SD gas ireq SD gas iresp */ struct brcmf_p2psd_gas_pub_act_frame { … }; /** * struct brcmf_config_af_params - Action Frame Parameters for tx. * * @mpc_onoff: To make sure to send successfully action frame, we have to * turn off mpc 0: off, 1: on, (-1): do nothing * @search_channel: 1: search peer's channel to send af * @extra_listen: keep the dwell time to get af response frame. */ struct brcmf_config_af_params { … }; /** * brcmf_p2p_is_pub_action() - true if p2p public type frame. * * @frame: action frame data. * @frame_len: length of action frame data. * * Determine if action frame is p2p public action type */ static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len) { … } /** * brcmf_p2p_is_p2p_action() - true if p2p action type frame. * * @frame: action frame data. * @frame_len: length of action frame data. * * Determine if action frame is p2p action type */ static bool brcmf_p2p_is_p2p_action(void *frame, u32 frame_len) { … } /** * brcmf_p2p_is_gas_action() - true if p2p gas action type frame. * * @frame: action frame data. * @frame_len: length of action frame data. * * Determine if action frame is p2p gas action type */ static bool brcmf_p2p_is_gas_action(void *frame, u32 frame_len) { … } /** * brcmf_p2p_print_actframe() - debug print routine. * * @tx: Received or to be transmitted * @frame: action frame data. * @frame_len: length of action frame data. * * Print information about the p2p action frame */ #ifdef DEBUG static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len) { … } #else static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len) { } #endif /** * brcmf_p2p_set_firmware() - prepare firmware for peer-to-peer operation. * * @ifp: ifp to use for iovars (primary). * @p2p_mac: mac address to configure for p2p_da_override */ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac) { … } /** * brcmf_p2p_generate_bss_mac() - derive mac addresses for P2P. * * @p2p: P2P specific data. * @dev_addr: optional device address. * * P2P needs mac addresses for P2P device and interface. If no device * address it specified, these are derived from a random ethernet * address. */ static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) { … } /** * brcmf_p2p_scan_is_p2p_request() - is cfg80211 scan request a P2P scan. * * @request: the scan request as received from cfg80211. * * returns true if one of the ssids in the request matches the * P2P wildcard ssid; otherwise returns false. */ static bool brcmf_p2p_scan_is_p2p_request(struct cfg80211_scan_request *request) { … } /** * brcmf_p2p_set_discover_state - set discover state in firmware. * * @ifp: low-level interface object. * @state: discover state to set. * @chanspec: channel parameters (for state @WL_P2P_DISC_ST_LISTEN only). * @listen_ms: duration to listen (for state @WL_P2P_DISC_ST_LISTEN only). */ static s32 brcmf_p2p_set_discover_state(struct brcmf_if *ifp, u8 state, u16 chanspec, u16 listen_ms) { … } /** * brcmf_p2p_deinit_discovery() - disable P2P device discovery. * * @p2p: P2P specific data. * * Resets the discovery state and disables it in firmware. */ static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p) { … } /** * brcmf_p2p_enable_discovery() - initialize and configure discovery. * * @p2p: P2P specific data. * * Initializes the discovery device and configure the virtual interface. */ static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p) { … } /** * brcmf_p2p_escan() - initiate a P2P scan. * * @p2p: P2P specific data. * @num_chans: number of channels to scan. * @chanspecs: channel parameters for @num_chans channels. * @search_state: P2P discover state to use. * @bss_type: type of P2P bss. */ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans, u16 chanspecs[], s32 search_state, enum p2p_bss_type bss_type) { … } /** * brcmf_p2p_run_escan() - escan callback for peer-to-peer. * * @cfg: driver private data for cfg80211 interface. * @ifp: interface control. * @request: scan request from cfg80211. * * Determines the P2P discovery state based to scan request parameters and * validates the channels in the request. */ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, struct cfg80211_scan_request *request) { … } /** * brcmf_p2p_find_listen_channel() - find listen channel in ie string. * * @ie: string of information elements. * @ie_len: length of string. * * Scan ie for p2p ie and look for attribute 6 channel. If available determine * channel and return it. */ static s32 brcmf_p2p_find_listen_channel(const u8 *ie, u32 ie_len) { … } /** * brcmf_p2p_scan_prep() - prepare scan based on request. * * @wiphy: wiphy device. * @request: scan request from cfg80211. * @vif: vif on which scan request is to be executed. * * Prepare the scan appropriately for type of scan requested. Overrides the * escan .run() callback for peer-to-peer scanning. */ int brcmf_p2p_scan_prep(struct wiphy *wiphy, struct cfg80211_scan_request *request, struct brcmf_cfg80211_vif *vif) { … } /** * brcmf_p2p_discover_listen() - set firmware to discover listen state. * * @p2p: p2p device. * @channel: channel nr for discover listen. * @duration: time in ms to stay on channel. * */ static s32 brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) { … } /** * brcmf_p2p_remain_on_channel() - put device on channel and stay there. * * @wiphy: wiphy device. * @wdev: wireless device. * @channel: channel to stay on. * @duration: time in ms to remain on channel. * @cookie: cookie. */ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, struct ieee80211_channel *channel, unsigned int duration, u64 *cookie) { … } /** * brcmf_p2p_notify_listen_complete() - p2p listen has completed. * * @ifp: interfac control. * @e: event message. Not used, to make it usable for fweh event dispatcher. * @data: payload of message. Not used. * */ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp, const struct brcmf_event_msg *e, void *data) { … } /** * brcmf_p2p_cancel_remain_on_channel() - cancel p2p listen state. * * @ifp: interfac control. * */ void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp) { … } /** * brcmf_p2p_act_frm_search() - search function for action frame. * * @p2p: p2p device. * @channel: channel on which action frame is to be trasmitted. * * search function to reach at common channel to send action frame. When * channel is 0 then all social channels will be used to send af */ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) { … } /** * brcmf_p2p_afx_handler() - afx worker thread. * * @work: * */ static void brcmf_p2p_afx_handler(struct work_struct *work) { … } /** * brcmf_p2p_af_searching_channel() - search channel. * * @p2p: p2p device info struct. * */ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) { … } /** * brcmf_p2p_scan_finding_common_channel() - was escan used for finding channel * * @cfg: common configuration struct. * @bi: bss info struct, result from scan. * */ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, struct brcmf_bss_info_le *bi) { … } /** * brcmf_p2p_abort_action_frame() - abort action frame. * * @cfg: common configuration struct. * */ static s32 brcmf_p2p_abort_action_frame(struct brcmf_cfg80211_info *cfg) { … } /** * brcmf_p2p_stop_wait_next_action_frame() - finish scan if af tx complete. * * @cfg: common configuration struct. * */ static void brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg) { … } /** * brcmf_p2p_gon_req_collision() - Check if go negotiaton collission * * @p2p: p2p device info struct. * @mac: MAC address. * * return true if recevied action frame is to be dropped. */ static bool brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac) { … } /** * brcmf_p2p_notify_action_frame_rx() - received action frame. * * @ifp: interfac control. * @e: event message. Not used, to make it usable for fweh event dispatcher. * @data: payload of message, containing action frame data. * */ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, const struct brcmf_event_msg *e, void *data) { … } /** * brcmf_p2p_notify_action_tx_complete() - transmit action frame complete * * @ifp: interfac control. * @e: event message. Not used, to make it usable for fweh event dispatcher. * @data: not used. * */ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp, const struct brcmf_event_msg *e, void *data) { … } /** * brcmf_p2p_tx_action_frame() - send action frame over fil. * * @p2p: p2p info struct for vif. * @af_params: action frame data/info. * * Send an action frame immediately without doing channel synchronization. * * This function waits for a completion event before returning. * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action * frame is transmitted. */ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, struct brcmf_fil_af_params_le *af_params) { … } /** * brcmf_p2p_pub_af_tx() - public action frame tx routine. * * @cfg: driver private data for cfg80211 interface. * @af_params: action frame data/info. * @config_af_params: configuration data for action frame. * * routine which transmits ation frame public type. */ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg, struct brcmf_fil_af_params_le *af_params, struct brcmf_config_af_params *config_af_params) { … } static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell, unsigned long dwell_jiffies) { … } /** * brcmf_p2p_send_action_frame() - send action frame . * * @cfg: driver private data for cfg80211 interface. * @ndev: net device to transmit on. * @af_params: configuration data for action frame. */ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, struct brcmf_fil_af_params_le *af_params) { … } /** * brcmf_p2p_notify_rx_mgmt_p2p_probereq() - Event handler for p2p probe req. * * @ifp: interface pointer for which event was received. * @e: even message. * @data: payload of event message (probe request). */ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, const struct brcmf_event_msg *e, void *data) { … } /** * brcmf_p2p_get_current_chanspec() - Get current operation channel. * * @p2p: P2P specific data. * @chanspec: chanspec to be returned. */ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p, u16 *chanspec) { … } /** * brcmf_p2p_ifchange - Change a P2P Role. * @cfg: driver private data for cfg80211 interface. * @if_type: interface type. * Returns 0 if success. */ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg, enum brcmf_fil_p2p_if_types if_type) { … } static int brcmf_p2p_request_p2p_if(struct brcmf_p2p_info *p2p, struct brcmf_if *ifp, u8 ea[ETH_ALEN], enum brcmf_fil_p2p_if_types iftype) { … } static int brcmf_p2p_disable_p2p_if(struct brcmf_cfg80211_vif *vif) { … } static int brcmf_p2p_release_p2p_if(struct brcmf_cfg80211_vif *vif) { … } /** * brcmf_p2p_create_p2pdev() - create a P2P_DEVICE virtual interface. * * @p2p: P2P specific data. * @wiphy: wiphy device of new interface. * @addr: mac address for this new interface. */ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p, struct wiphy *wiphy, u8 *addr) { … } static int brcmf_p2p_get_conn_idx(struct brcmf_cfg80211_info *cfg) { … } /** * brcmf_p2p_add_vif() - create a new P2P virtual interface. * * @wiphy: wiphy device of new interface. * @name: name of the new interface. * @name_assign_type: origin of the interface name * @type: nl80211 interface type. * @params: contains mac address for P2P device. */ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, unsigned char name_assign_type, enum nl80211_iftype type, struct vif_params *params) { … } /** * brcmf_p2p_del_vif() - delete a P2P virtual interface. * * @wiphy: wiphy device of interface. * @wdev: wireless device of interface. */ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) { … } void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool locked) { … } int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev) { … } void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev) { … } /** * brcmf_p2p_attach() - attach for P2P. * * @cfg: driver private data for cfg80211 interface. * @p2pdev_forced: create p2p device interface at attach. */ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced) { … } /** * brcmf_p2p_detach() - detach P2P. * * @p2p: P2P specific data. */ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) { … }