diff options
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/wlcore.h')
| -rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore.h | 270 |
1 files changed, 227 insertions, 43 deletions
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 0b3f0b586f4..95a54504f0c 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -24,23 +24,39 @@ #include <linux/platform_device.h> -#include "wl12xx.h" +#include "wlcore_i.h" #include "event.h" +#include "boot.h" /* The maximum number of Tx descriptors in all chip families */ #define WLCORE_MAX_TX_DESCRIPTORS 32 +/* + * We always allocate this number of mac addresses. If we don't + * have enough allocated addresses, the LAA bit is used + */ +#define WLCORE_NUM_MAC_ADDRESSES 3 + +/* wl12xx/wl18xx maximum transmission power (in dBm) */ +#define WLCORE_MAX_TXPWR 25 + /* forward declaration */ struct wl1271_tx_hw_descr; enum wl_rx_buf_align; +struct wl1271_rx_descriptor; struct wlcore_ops { + int (*setup)(struct wl1271 *wl); int (*identify_chip)(struct wl1271 *wl); int (*identify_fw)(struct wl1271 *wl); int (*boot)(struct wl1271 *wl); - void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, - void *buf, size_t len); - void (*ack_event)(struct wl1271 *wl); + int (*plt_init)(struct wl1271 *wl); + int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, + void *buf, size_t len); + int (*ack_event)(struct wl1271 *wl); + int (*wait_for_event)(struct wl1271 *wl, enum wlcore_wait_event event, + bool *timeout); + int (*process_mailbox_events)(struct wl1271 *wl); u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); void (*set_tx_desc_blocks)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, @@ -50,17 +66,57 @@ struct wlcore_ops { struct sk_buff *skb); enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl, u32 rx_desc); - void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); + int (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data, u32 data_len); - void (*tx_delayed_compl)(struct wl1271 *wl); + int (*tx_delayed_compl)(struct wl1271 *wl); void (*tx_immediate_compl)(struct wl1271 *wl); int (*hw_init)(struct wl1271 *wl); int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); + void (*convert_fw_status)(struct wl1271 *wl, void *raw_fw_status, + struct wl_fw_status *fw_status); u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl, struct wl12xx_vif *wlvif); - s8 (*get_pg_ver)(struct wl1271 *wl); - void (*get_mac)(struct wl1271 *wl); + int (*get_pg_ver)(struct wl1271 *wl, s8 *ver); + int (*get_mac)(struct wl1271 *wl); + void (*set_tx_desc_csum)(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb); + void (*set_rx_csum)(struct wl1271 *wl, + struct wl1271_rx_descriptor *desc, + struct sk_buff *skb); + u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, + struct wl12xx_vif *wlvif); + int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); + int (*handle_static_data)(struct wl1271 *wl, + struct wl1271_static_data *static_data); + int (*scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct cfg80211_scan_request *req); + int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); + int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct cfg80211_sched_scan_request *req, + struct ieee80211_sched_scan_ies *ies); + void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); + int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); + int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key_conf); + int (*channel_switch)(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_channel_switch *ch_switch); + u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); + void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta, u32 changed); + int (*set_peer_cap)(struct wl1271 *wl, + struct ieee80211_sta_ht_cap *ht_cap, + bool allow_ht_operation, + u32 rate_set, u8 hlid); + u32 (*convert_hwaddr)(struct wl1271 *wl, u32 hwaddr); + bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid, + struct wl1271_link *lnk); + bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid, + struct wl1271_link *lnk); }; enum wlcore_partitions { @@ -109,25 +165,36 @@ enum wlcore_registers { REG_TABLE_LEN, }; +struct wl1271_stats { + void *fw_stats; + unsigned long fw_stats_update; + size_t fw_stats_len; + + unsigned int retry_count; + unsigned int excessive_retries; +}; + struct wl1271 { + bool initialized; struct ieee80211_hw *hw; bool mac80211_registered; struct device *dev; + struct platform_device *pdev; void *if_priv; struct wl1271_if_operations *if_ops; - void (*set_power)(bool enable); int irq; - int ref_clock; spinlock_t wl_lock; - enum wl1271_state state; + enum wlcore_state state; enum wl12xx_fw_type fw_type; bool plt; + enum plt_mode plt_mode; + u8 fem_manuf; u8 last_vif_count; struct mutex mutex; @@ -151,15 +218,19 @@ struct wl1271 { u32 fuse_nic_addr; /* we have up to 2 MAC addresses */ - struct mac_address addresses[2]; + struct mac_address addresses[WLCORE_NUM_MAC_ADDRESSES]; int channel; u8 system_hlid; - unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; + unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)]; unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; unsigned long rate_policies_map[ BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)]; + unsigned long klv_templates_map[ + BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; + + u8 session_ids[WLCORE_MAX_LINKS]; struct list_head wlvif_list; @@ -186,7 +257,8 @@ struct wl1271 { /* Frames scheduled for transmission, not handled yet */ int tx_queue_count[NUM_TX_QUEUES]; - long stopped_queues_map; + unsigned long queue_stop_reasons[ + NUM_TX_QUEUES * WLCORE_NUM_MAC_ADDRESSES]; /* Frames received, not handled yet by mac80211 */ struct sk_buff_head deferred_rx_queue; @@ -205,11 +277,9 @@ struct wl1271 { /* FW Rx counter */ u32 rx_counter; - /* Rx memory pool address */ - struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; - /* Intermediate buffer, used for packet aggregation */ u8 *aggr_buf; + u32 aggr_buf_size; /* Reusable dummy packet template */ struct sk_buff *dummy_packet; @@ -223,30 +293,45 @@ struct wl1271 { /* Number of valid bytes in the FW log buffer */ ssize_t fwlog_size; + /* FW log end marker */ + u32 fwlog_end; + + /* FW memory block size */ + u32 fw_mem_block_size; + /* Sysfs FW log entry readers wait queue */ wait_queue_head_t fwlog_waitq; /* Hardware recovery work */ struct work_struct recovery_work; + bool watchdog_recovery; + + /* Reg domain last configuration */ + u32 reg_ch_conf_last[2]; + /* Reg domain pending configuration */ + u32 reg_ch_conf_pending[2]; /* Pointer that holds DMA-friendly block for the mailbox */ - struct event_mailbox *mbox; + void *mbox; /* The mbox event mask */ u32 event_mask; + /* events to unmask only when ap interface is up */ + u32 ap_event_mask; /* Mailbox pointers */ + u32 mbox_size; u32 mbox_ptr[2]; /* Are we currently scanning */ - struct ieee80211_vif *scan_vif; + struct wl12xx_vif *scan_wlvif; struct wl1271_scan scan; struct delayed_work scan_complete_work; - /* Connection loss work */ - struct delayed_work connection_loss_work; + struct ieee80211_vif *roc_vif; + struct delayed_work roc_complete_work; - bool sched_scanning; + struct wl12xx_vif *sched_vif; /* The current band */ enum ieee80211_band band; @@ -259,10 +344,11 @@ struct wl1271 { struct wl1271_stats stats; - __le32 buffer_32; + __le32 *buffer_32; u32 buffer_cmd; u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; + void *raw_fw_status; struct wl_fw_status *fw_status; struct wl1271_tx_hw_res_if *tx_res_if; @@ -273,13 +359,13 @@ struct wl1271 { bool enable_11a; + int recovery_count; + /* Most recently reported noise in dBm */ s8 noise; /* bands supported by this instance of wl12xx */ - struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; - - int tcxo_clock; + struct ieee80211_supported_band bands[WLCORE_NUM_BANDS]; /* * wowlan trigger was configured during suspend. @@ -292,7 +378,13 @@ struct wl1271 { * AP-mode - links indexed by HLID. The global and broadcast links * are always active. */ - struct wl1271_link links[WL12XX_MAX_LINKS]; + struct wl1271_link links[WLCORE_MAX_LINKS]; + + /* number of currently active links */ + int active_link_count; + + /* Fast/slow links bitmap according to FW */ + u32 fw_fast_lnk_map; /* AP-mode - a bitmap of links currently in PS mode according to FW */ u32 ap_fw_ps_map; @@ -309,9 +401,15 @@ struct wl1271 { /* number of currently active RX BA sessions */ int ba_rx_session_count; + /* Maximum number of supported RX BA sessions */ + int ba_rx_session_count_max; + /* AP-mode - number of currently connected stations */ int active_sta_count; + /* Flag determining whether AP should broadcast OFDM-only rates */ + bool ofdm_only_ap; + /* last wlvif we transmitted from */ struct wl12xx_vif *last_wlvif; @@ -328,15 +426,23 @@ struct wl1271 { const char *sr_fw_name; const char *mr_fw_name; + u8 scan_templ_id_2_4; + u8 scan_templ_id_5; + u8 sched_scan_templ_id_2_4; + u8 sched_scan_templ_id_5; + u8 max_channels_5; + /* per-chip-family private structure */ void *priv; /* number of TX descriptors the HW supports. */ u32 num_tx_desc; - - /* spare Tx blocks for normal/GEM operating modes */ - u32 normal_tx_spare; - u32 gem_tx_spare; + /* number of RX descriptors the HW supports. */ + u32 num_rx_desc; + /* number of links the HW supports */ + u8 num_links; + /* max stations a single AP can support */ + u8 max_ap_stations; /* translate HW Tx rates to standard rate-indices */ const u8 **band_rate_to_idx; @@ -348,19 +454,85 @@ struct wl1271 { u8 hw_min_ht_rate; /* HW HT (11n) capabilities */ - struct ieee80211_sta_ht_cap ht_cap; + struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS]; /* size of the private FW status data */ + size_t fw_status_len; size_t fw_status_priv_len; /* RX Data filter rule state - enabled/disabled */ - bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; + unsigned long rx_filter_enabled[BITS_TO_LONGS(WL1271_MAX_RX_FILTERS)]; + + /* size of the private static data */ + size_t static_data_priv_len; + + /* the current channel type */ + enum nl80211_channel_type channel_type; + + /* mutex for protecting the tx_flush function */ + struct mutex flush_mutex; + + /* sleep auth value currently configured to FW */ + int sleep_auth; + + /* the number of allocated MAC addresses in this chip */ + int num_mac_addr; + + /* minimum FW version required for the driver to work in single-role */ + unsigned int min_sr_fw_ver[NUM_FW_VER]; + + /* minimum FW version required for the driver to work in multi-role */ + unsigned int min_mr_fw_ver[NUM_FW_VER]; + + struct completion nvs_loading_complete; + + /* interface combinations supported by the hw */ + const struct ieee80211_iface_combination *iface_combinations; + u8 n_iface_combinations; }; -int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); -int __devexit wlcore_remove(struct platform_device *pdev); -struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); +int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); +int wlcore_remove(struct platform_device *pdev); +struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, + u32 mbox_size); int wlcore_free_hw(struct wl1271 *wl); +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); +void wlcore_regdomain_config(struct wl1271 *wl); +void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct wl1271_station *wl_sta, bool in_conn); + +static inline void +wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, + struct ieee80211_sta_ht_cap *ht_cap) +{ + memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); +} + +/* Tell wlcore not to care about this element when checking the version */ +#define WLCORE_FW_VER_IGNORE -1 + +static inline void +wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, + unsigned int iftype_sr, unsigned int major_sr, + unsigned int subtype_sr, unsigned int minor_sr, + unsigned int iftype_mr, unsigned int major_mr, + unsigned int subtype_mr, unsigned int minor_mr) +{ + wl->min_sr_fw_ver[FW_VER_CHIP] = chip; + wl->min_sr_fw_ver[FW_VER_IF_TYPE] = iftype_sr; + wl->min_sr_fw_ver[FW_VER_MAJOR] = major_sr; + wl->min_sr_fw_ver[FW_VER_SUBTYPE] = subtype_sr; + wl->min_sr_fw_ver[FW_VER_MINOR] = minor_sr; + + wl->min_mr_fw_ver[FW_VER_CHIP] = chip; + wl->min_mr_fw_ver[FW_VER_IF_TYPE] = iftype_mr; + wl->min_mr_fw_ver[FW_VER_MAJOR] = major_mr; + wl->min_mr_fw_ver[FW_VER_SUBTYPE] = subtype_mr; + wl->min_mr_fw_ver[FW_VER_MINOR] = minor_mr; +} /* Firmware image load chunk size */ #define CHUNK_SIZE 16384 @@ -370,6 +542,9 @@ int wlcore_free_hw(struct wl1271 *wl); /* Each RX/TX transaction requires an end-of-transaction transfer */ #define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0) +/* the first start_role(sta) sometimes doesn't work on wl12xx */ +#define WLCORE_QUIRK_START_STA_FAILS BIT(1) + /* wl127x and SPI don't support SDIO block size alignment */ #define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2) @@ -382,14 +557,23 @@ int wlcore_free_hw(struct wl1271 *wl); /* Older firmwares use an old NVS format */ #define WLCORE_QUIRK_LEGACY_NVS BIT(5) -/* Some firmwares may not support ELP */ -#define WLCORE_QUIRK_NO_ELP BIT(6) +/* pad only the last frame in the aggregate buffer */ +#define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7) + +/* extra header space is required for TKIP */ +#define WLCORE_QUIRK_TKIP_HEADER_SPACE BIT(8) + +/* Some firmwares not support sched scans while connected */ +#define WLCORE_QUIRK_NO_SCHED_SCAN_WHILE_CONN BIT(9) + +/* separate probe response templates for one-shot and sched scans */ +#define WLCORE_QUIRK_DUAL_PROBE_TMPL BIT(10) + +/* Firmware requires reg domain configuration for active calibration */ +#define WLCORE_QUIRK_REGDOMAIN_CONF BIT(11) -/* TODO: move to the lower drivers when all usages are abstracted */ -#define CHIP_ID_1271_PG10 (0x4030101) -#define CHIP_ID_1271_PG20 (0x4030111) -#define CHIP_ID_1283_PG10 (0x05030101) -#define CHIP_ID_1283_PG20 (0x05030111) +/* The FW only support a zero session id for AP */ +#define WLCORE_QUIRK_AP_ZERO_SESSION_ID BIT(12) /* TODO: move all these common registers and values elsewhere */ #define HW_ACCESS_ELP_CTRL_REG 0x1FFFC |
