#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeirq.h>
#include "wlcore.h"
#include "debug.h"
#include "wl12xx_80211.h"
#include "io.h"
#include "tx.h"
#include "ps.h"
#include "init.h"
#include "debugfs.h"
#include "testmode.h"
#include "vendor_cmd.h"
#include "scan.h"
#include "hw_ops.h"
#include "sysfs.h"
#define WL1271_BOOT_RETRIES …
#define WL1271_WAKEUP_TIMEOUT …
static char *fwlog_param;
static int fwlog_mem_blocks = …;
static int bug_on_recovery = …;
static int no_recovery = …;
static void __wl1271_op_remove_interface(struct wl1271 *wl,
struct ieee80211_vif *vif,
bool reset_tx_queues);
static void wlcore_op_stop_locked(struct wl1271 *wl);
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
static int wl12xx_set_authorized(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static void wl1271_reg_notify(struct wiphy *wiphy,
struct regulatory_request *request)
{ … }
static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
bool enable)
{ … }
int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static void wl1271_rx_streaming_enable_work(struct work_struct *work)
{ … }
static void wl1271_rx_streaming_disable_work(struct work_struct *work)
{ … }
static void wl1271_rx_streaming_timer(struct timer_list *t)
{ … }
void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
{ … }
static void wlcore_rc_update_work(struct work_struct *work)
{ … }
static void wl12xx_tx_watchdog_work(struct work_struct *work)
{ … }
static void wlcore_adjust_conf(struct wl1271 *wl)
{ … }
static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
u8 hlid, u8 tx_pkts)
{ … }
static void wl12xx_irq_update_links_status(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct wl_fw_status *status)
{ … }
static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
{ … }
static void wl1271_flush_deferred_work(struct wl1271 *wl)
{ … }
static void wl1271_netstack_work(struct work_struct *work)
{ … }
#define WL1271_IRQ_MAX_LOOPS …
static int wlcore_irq_locked(struct wl1271 *wl)
{ … }
static irqreturn_t wlcore_irq(int irq, void *cookie)
{ … }
struct vif_counter_data { … };
static void wl12xx_vif_count_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{ … }
static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
struct ieee80211_vif *cur_vif,
struct vif_counter_data *data)
{ … }
static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
{ … }
void wl12xx_queue_recovery_work(struct wl1271 *wl)
{ … }
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
{ … }
static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
{ … }
static void wlcore_save_freed_pkts(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 hlid, struct ieee80211_sta *sta)
{ … }
static void wlcore_save_freed_pkts_addr(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
u8 hlid, const u8 *addr)
{ … }
static void wlcore_print_recovery(struct wl1271 *wl)
{ … }
static void wl1271_recovery_work(struct work_struct *work)
{ … }
static int wlcore_fw_wakeup(struct wl1271 *wl)
{ … }
static int wl1271_setup(struct wl1271 *wl)
{ … }
static int wl12xx_set_power_on(struct wl1271 *wl)
{ … }
static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
{ … }
int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
{ … }
int wl1271_plt_stop(struct wl1271 *wl)
{ … }
static void wl1271_op_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
{ … }
int wl1271_tx_dummy_packet(struct wl1271 *wl)
{ … }
#define TOTAL_TX_DUMMY_PACKET_SIZE …
static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
{ … }
static int
wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
{ … }
struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void)
{ … }
void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter)
{ … }
int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
u16 offset, u8 flags,
const u8 *pattern, u8 len)
{ … }
int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter)
{ … }
void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
u8 *buf)
{ … }
static int
wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
struct wl12xx_rx_filter **f)
{ … }
static int wl1271_configure_wowlan(struct wl1271 *wl,
struct cfg80211_wowlan *wow)
{ … }
static int wl1271_configure_suspend_sta(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_wowlan *wow)
{ … }
static int wl1271_configure_suspend_ap(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_wowlan *wow)
{ … }
static int wl1271_configure_suspend(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_wowlan *wow)
{ … }
static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wow)
{ … }
static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
{ … }
static int wl1271_op_start(struct ieee80211_hw *hw)
{ … }
static void wlcore_op_stop_locked(struct wl1271 *wl)
{ … }
static void wlcore_op_stop(struct ieee80211_hw *hw, bool suspend)
{ … }
static void wlcore_channel_switch_work(struct work_struct *work)
{ … }
static void wlcore_connection_loss_work(struct work_struct *work)
{ … }
static void wlcore_pending_auth_complete_work(struct work_struct *work)
{ … }
static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
{ … }
static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx)
{ … }
static int wlcore_allocate_klv_template(struct wl1271 *wl, u8 *idx)
{ … }
static void wlcore_free_klv_template(struct wl1271 *wl, u8 *idx)
{ … }
static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
{ … }
static int wl12xx_init_fw(struct wl1271 *wl)
{ … }
static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
{ … }
static bool wl12xx_need_fw_change(struct wl1271 *wl,
struct vif_counter_data vif_counter_data,
bool add)
{ … }
static void wl12xx_force_active_psm(struct wl1271 *wl)
{ … }
struct wlcore_hw_queue_iter_data { … };
static void wlcore_hw_queue_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{ … }
static int wlcore_allocate_hw_queue_base(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{ … }
static int wl1271_op_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static void __wl1271_op_remove_interface(struct wl1271 *wl,
struct ieee80211_vif *vif,
bool reset_tx_queues)
{ … }
static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum nl80211_iftype new_type, bool p2p)
{ … }
static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int wl1271_ssid_set(struct wl12xx_vif *wlvif, struct sk_buff *skb,
int offset)
{ … }
static int wlcore_set_ssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct ieee80211_bss_conf *bss_conf,
u32 sta_rate_set)
{ … }
static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
bool idle)
{ … }
static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct ieee80211_conf *conf, u32 changed)
{ … }
static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
{ … }
struct wl1271_filter_params { … };
static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list)
{ … }
#define WL1271_SUPPORTED_FILTERS …
static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
unsigned int changed,
unsigned int *total, u64 multicast)
{ … }
static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 id, u8 key_type, u8 key_size,
const u8 *key, u8 hlid, u32 tx_seq_32,
u16 tx_seq_16, bool is_pairwise)
{ … }
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int wl1271_ap_init_hwenc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u16 action, u8 id, u8 key_type,
u8 key_size, const u8 *key, u32 tx_seq_32,
u16 tx_seq_16, struct ieee80211_sta *sta,
bool is_pairwise)
{ … }
static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key_conf)
{ … }
int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key_conf)
{ … }
EXPORT_SYMBOL_GPL(…);
static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
int key_idx)
{ … }
void wlcore_regdomain_config(struct wl1271 *wl)
{ … }
static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_scan_request *hw_req)
{ … }
static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
struct ieee80211_scan_ies *ies)
{ … }
static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
{ … }
static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{ … }
static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
{ … }
static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
unsigned int oui, u8 oui_type,
int ieoffset)
{ … }
static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
struct ieee80211_vif *vif)
{ … }
static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
struct ieee80211_vif *vif,
u8 *probe_rsp_data,
size_t probe_rsp_len,
u32 rates)
{ … }
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{ … }
static int wlcore_set_beacon_template(struct wl1271 *wl,
struct ieee80211_vif *vif,
bool is_ap)
{ … }
static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{ … }
static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{ … }
static int wlcore_set_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct ieee80211_vif *vif, u32 sta_rate_set)
{ … }
static int wlcore_clear_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{ … }
static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{ … }
static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u64 changed)
{ … }
static int wlcore_op_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{ … }
static void wlcore_op_remove_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{ … }
static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx,
u32 changed)
{ … }
static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_chanctx_conf *ctx)
{ … }
static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_chanctx_conf *ctx)
{ … }
static int __wlcore_switch_vif_chan(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_chanctx_conf *new_ctx)
{ … }
static int
wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif_chanctx_switch *vifs,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode)
{ … }
static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
unsigned int link_id, u16 queue,
const struct ieee80211_tx_queue_params *params)
{ … }
static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey)
{ … }
static int wl1271_allocate_sta(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_sta *sta)
{ … }
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
{ … }
static int wl12xx_sta_add(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_sta *sta)
{ … }
static int wl12xx_sta_remove(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_sta *sta)
{ … }
static void wlcore_roc_if_possible(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{ … }
void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct wl1271_station *wl_sta, bool in_conn)
{ … }
static int wl12xx_update_sta_state(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_sta *sta,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state)
{ … }
static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state)
{ … }
static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_ampdu_params *params)
{ … }
static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
{ … }
static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel_switch *ch_switch)
{ … }
static const void *wlcore_get_beacon_ie(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
u8 eid)
{ … }
static int wlcore_get_csa_count(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 *csa_count)
{ … }
static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef)
{ … }
static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ … }
static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel *chan,
int duration,
enum ieee80211_roc_type type)
{ … }
static int __wlcore_roc_completed(struct wl1271 *wl)
{ … }
static int wlcore_roc_completed(struct wl1271 *wl)
{ … }
static void wlcore_roc_complete_work(struct work_struct *work)
{ … }
static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{ … }
static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u32 changed)
{ … }
static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct station_info *sinfo)
{ … }
static u32 wlcore_op_get_expected_throughput(struct ieee80211_hw *hw,
struct ieee80211_sta *sta)
{ … }
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
{ … }
static struct ieee80211_rate wl1271_rates[] = …;
static struct ieee80211_channel wl1271_channels[] = …;
static struct ieee80211_supported_band wl1271_band_2ghz = …;
static struct ieee80211_rate wl1271_rates_5ghz[] = …;
static struct ieee80211_channel wl1271_channels_5ghz[] = …;
static struct ieee80211_supported_band wl1271_band_5ghz = …;
static const struct ieee80211_ops wl1271_ops = …;
u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum nl80211_band band)
{ … }
static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
{ … }
static int wl12xx_get_hw_info(struct wl1271 *wl)
{ … }
static int wl1271_register_hw(struct wl1271 *wl)
{ … }
static void wl1271_unregister_hw(struct wl1271 *wl)
{ … }
static int wl1271_init_ieee80211(struct wl1271 *wl)
{ … }
struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
u32 mbox_size)
{ … }
EXPORT_SYMBOL_GPL(…);
int wlcore_free_hw(struct wl1271 *wl)
{ … }
EXPORT_SYMBOL_GPL(…);
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support wlcore_wowlan_support = …;
#endif
static irqreturn_t wlcore_hardirq(int irq, void *cookie)
{ … }
static void wlcore_nvs_cb(const struct firmware *fw, void *context)
{ … }
static int __maybe_unused wlcore_runtime_suspend(struct device *dev)
{ … }
static int __maybe_unused wlcore_runtime_resume(struct device *dev)
{ … }
static const struct dev_pm_ops wlcore_pm_ops = …;
int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
{ … }
EXPORT_SYMBOL_GPL(…);
void wlcore_remove(struct platform_device *pdev)
{ … }
EXPORT_SYMBOL_GPL(…);
u32 wl12xx_debug_level = …;
EXPORT_SYMBOL_GPL(…);
module_param_named(debug_level, wl12xx_debug_level, uint, 0600);
MODULE_PARM_DESC(…) …;
module_param_named(fwlog, fwlog_param, charp, 0);
MODULE_PARM_DESC(…) …;
module_param(fwlog_mem_blocks, int, 0600);
MODULE_PARM_DESC(…) …;
module_param(bug_on_recovery, int, 0600);
MODULE_PARM_DESC(…) …;
module_param(no_recovery, int, 0600);
MODULE_PARM_DESC(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;