diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/net/wireless/ti/wl18xx | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/net/wireless/ti/wl18xx')
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/acx.c | 27 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/acx.h | 138 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/debugfs.c | 230 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/event.c | 13 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/event.h | 12 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/main.c | 131 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/reg.h | 1 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/scan.c | 25 | ||||
-rw-r--r-- | kernel/drivers/net/wireless/ti/wl18xx/scan.h | 4 |
9 files changed, 413 insertions, 168 deletions
diff --git a/kernel/drivers/net/wireless/ti/wl18xx/acx.c b/kernel/drivers/net/wireless/ti/wl18xx/acx.c index 67f2a0eec..4be040930 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/acx.c +++ b/kernel/drivers/net/wireless/ti/wl18xx/acx.c @@ -282,3 +282,30 @@ out: kfree(acx); return ret; } + +int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl) +{ + struct acx_dynamic_fw_traces_cfg *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx dynamic fw traces config %d", + wl->dynamic_fw_traces); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->dynamic_fw_traces = cpu_to_le32(wl->dynamic_fw_traces); + + ret = wl1271_cmd_configure(wl, ACX_DYNAMIC_TRACES_CFG, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx config dynamic fw traces failed: %d", ret); + goto out; + } +out: + kfree(acx); + return ret; +} diff --git a/kernel/drivers/net/wireless/ti/wl18xx/acx.h b/kernel/drivers/net/wireless/ti/wl18xx/acx.h index 4afccd4b9..342a2993e 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/acx.h +++ b/kernel/drivers/net/wireless/ti/wl18xx/acx.h @@ -35,7 +35,8 @@ enum { ACX_PEER_CAP = 0x0056, ACX_INTERRUPT_NOTIFY = 0x0057, ACX_RX_BA_FILTER = 0x0058, - ACX_AP_SLEEP_CFG = 0x0059 + ACX_AP_SLEEP_CFG = 0x0059, + ACX_DYNAMIC_TRACES_CFG = 0x005A, }; /* numbers of bits the length field takes (add 1 for the actual number) */ @@ -92,27 +93,26 @@ struct wl18xx_acx_checksum_state { struct wl18xx_acx_error_stats { - u32 error_frame; - u32 error_null_Frame_tx_start; - u32 error_numll_frame_cts_start; - u32 error_bar_retry; - u32 error_frame_cts_nul_flid; -} __packed; - -struct wl18xx_acx_debug_stats { - u32 debug1; - u32 debug2; - u32 debug3; - u32 debug4; - u32 debug5; - u32 debug6; -} __packed; - -struct wl18xx_acx_ring_stats { - u32 prepared_descs; - u32 tx_cmplt; + u32 error_frame_non_ctrl; + u32 error_frame_ctrl; + u32 error_frame_during_protection; + u32 null_frame_tx_start; + u32 null_frame_cts_start; + u32 bar_retry; + u32 num_frame_cts_nul_flid; + u32 tx_abort_failure; + u32 tx_resume_failure; + u32 rx_cmplt_db_overflow_cnt; + u32 elp_while_rx_exch; + u32 elp_while_tx_exch; + u32 elp_while_tx; + u32 elp_while_nvic_pending; + u32 rx_excessive_frame_len; + u32 burst_mismatch; + u32 tbc_exch_mismatch; } __packed; +#define NUM_OF_RATES_INDEXES 30 struct wl18xx_acx_tx_stats { u32 tx_prepared_descs; u32 tx_cmplt; @@ -122,7 +122,7 @@ struct wl18xx_acx_tx_stats { u32 tx_data_programmed; u32 tx_burst_programmed; u32 tx_starts; - u32 tx_imm_resp; + u32 tx_stop; u32 tx_start_templates; u32 tx_start_int_templates; u32 tx_start_fw_gen; @@ -131,13 +131,14 @@ struct wl18xx_acx_tx_stats { u32 tx_exch; u32 tx_retry_template; u32 tx_retry_data; + u32 tx_retry_per_rate[NUM_OF_RATES_INDEXES]; u32 tx_exch_pending; u32 tx_exch_expiry; u32 tx_done_template; u32 tx_done_data; u32 tx_done_int_template; - u32 tx_frame_checksum; - u32 tx_checksum_result; + u32 tx_cfe1; + u32 tx_cfe2; u32 frag_called; u32 frag_mpdu_alloc_failed; u32 frag_init_called; @@ -165,11 +166,8 @@ struct wl18xx_acx_rx_stats { u32 rx_cmplt_task; u32 rx_phy_hdr; u32 rx_timeout; + u32 rx_rts_timeout; u32 rx_timeout_wa; - u32 rx_wa_density_dropped_frame; - u32 rx_wa_ba_not_expected; - u32 rx_frame_checksum; - u32 rx_checksum_result; u32 defrag_called; u32 defrag_init_called; u32 defrag_in_process_called; @@ -179,6 +177,7 @@ struct wl18xx_acx_rx_stats { u32 decrypt_key_not_found; u32 defrag_need_decrypt; u32 rx_tkip_replays; + u32 rx_xfr; } __packed; struct wl18xx_acx_isr_stats { @@ -193,21 +192,13 @@ struct wl18xx_acx_pwr_stats { u32 connection_out_of_sync; u32 cont_miss_bcns_spread[PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD]; u32 rcvd_awake_bcns_cnt; -} __packed; - -struct wl18xx_acx_event_stats { - u32 calibration; - u32 rx_mismatch; - u32 rx_mem_empty; -} __packed; - -struct wl18xx_acx_ps_poll_stats { - u32 ps_poll_timeouts; - u32 upsd_timeouts; - u32 upsd_max_ap_turn; - u32 ps_poll_max_ap_turn; - u32 ps_poll_utilization; - u32 upsd_utilization; + u32 sleep_time_count; + u32 sleep_time_avg; + u32 sleep_cycle_avg; + u32 sleep_percent; + u32 ap_sleep_active_conf; + u32 ap_sleep_user_conf; + u32 ap_sleep_counter; } __packed; struct wl18xx_acx_rx_filter_stats { @@ -227,11 +218,11 @@ struct wl18xx_acx_rx_rate_stats { } __packed; #define AGGR_STATS_TX_AGG 16 -#define AGGR_STATS_TX_RATE 16 #define AGGR_STATS_RX_SIZE_LEN 16 struct wl18xx_acx_aggr_stats { - u32 tx_agg_vs_rate[AGGR_STATS_TX_AGG * AGGR_STATS_TX_RATE]; + u32 tx_agg_rate[AGGR_STATS_TX_AGG]; + u32 tx_agg_len[AGGR_STATS_TX_AGG]; u32 rx_size[AGGR_STATS_RX_SIZE_LEN]; } __packed; @@ -240,8 +231,6 @@ struct wl18xx_acx_aggr_stats { struct wl18xx_acx_pipeline_stats { u32 hs_tx_stat_fifo_int; u32 hs_rx_stat_fifo_int; - u32 tcp_tx_stat_fifo_int; - u32 tcp_rx_stat_fifo_int; u32 enc_tx_stat_fifo_int; u32 enc_rx_stat_fifo_int; u32 rx_complete_stat_fifo_int; @@ -249,38 +238,61 @@ struct wl18xx_acx_pipeline_stats { u32 post_proc_swi; u32 sec_frag_swi; u32 pre_to_defrag_swi; - u32 defrag_to_csum_swi; - u32 csum_to_rx_xfer_swi; + u32 defrag_to_rx_xfer_swi; u32 dec_packet_in; u32 dec_packet_in_fifo_full; u32 dec_packet_out; - u32 cs_rx_packet_in; - u32 cs_rx_packet_out; u16 pipeline_fifo_full[PIPE_STATS_HW_FIFO]; + u16 padding; +} __packed; + +#define DIVERSITY_STATS_NUM_OF_ANT 2 + +struct wl18xx_acx_diversity_stats { + u32 num_of_packets_per_ant[DIVERSITY_STATS_NUM_OF_ANT]; + u32 total_num_of_toggles; } __packed; -struct wl18xx_acx_mem_stats { - u32 rx_free_mem_blks; - u32 tx_free_mem_blks; - u32 fwlog_free_mem_blks; - u32 fw_gen_free_mem_blks; +struct wl18xx_acx_thermal_stats { + u16 irq_thr_low; + u16 irq_thr_high; + u16 tx_stop; + u16 tx_resume; + u16 false_irq; + u16 adc_source_unexpected; +} __packed; + +#define WL18XX_NUM_OF_CALIBRATIONS_ERRORS 18 +struct wl18xx_acx_calib_failure_stats { + u16 fail_count[WL18XX_NUM_OF_CALIBRATIONS_ERRORS]; + u32 calib_count; +} __packed; + +struct wl18xx_roaming_stats { + s32 rssi_level; +} __packed; + +struct wl18xx_dfs_stats { + u32 num_of_radar_detections; } __packed; struct wl18xx_acx_statistics { struct acx_header header; struct wl18xx_acx_error_stats error; - struct wl18xx_acx_debug_stats debug; struct wl18xx_acx_tx_stats tx; struct wl18xx_acx_rx_stats rx; struct wl18xx_acx_isr_stats isr; struct wl18xx_acx_pwr_stats pwr; - struct wl18xx_acx_ps_poll_stats ps_poll; struct wl18xx_acx_rx_filter_stats rx_filter; struct wl18xx_acx_rx_rate_stats rx_rate; struct wl18xx_acx_aggr_stats aggr_size; struct wl18xx_acx_pipeline_stats pipeline; - struct wl18xx_acx_mem_stats mem; + struct wl18xx_acx_diversity_stats diversity; + struct wl18xx_acx_thermal_stats thermal; + struct wl18xx_acx_calib_failure_stats calib; + struct wl18xx_roaming_stats roaming; + struct wl18xx_dfs_stats dfs; } __packed; struct wl18xx_acx_clear_statistics { @@ -367,6 +379,15 @@ struct acx_ap_sleep_cfg { u8 idle_conn_thresh; } __packed; +/* + * ACX_DYNAMIC_TRACES_CFG + * configure the FW dynamic traces + */ +struct acx_dynamic_fw_traces_cfg { + struct acx_header header; + __le32 dynamic_fw_traces; +} __packed; + int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, u32 sdio_blk_size, u32 extra_mem_blks, u32 len_field_size); @@ -380,5 +401,6 @@ int wl18xx_acx_set_peer_cap(struct wl1271 *wl, int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl, bool action); int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action); int wl18xx_acx_ap_sleep(struct wl1271 *wl); +int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl); #endif /* __WL18XX_ACX_H__ */ diff --git a/kernel/drivers/net/wireless/ti/wl18xx/debugfs.c b/kernel/drivers/net/wireless/ti/wl18xx/debugfs.c index 5fbd2230f..4edfe2839 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/debugfs.c +++ b/kernel/drivers/net/wireless/ti/wl18xx/debugfs.c @@ -36,18 +36,23 @@ DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c, wl18xx_acx_statistics) -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug1, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug2, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug3, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug4, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug5, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug6, "%u"); - -WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(error, error_null_Frame_tx_start, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(error, error_numll_frame_cts_start, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(error, error_bar_retry, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_cts_nul_flid, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_non_ctrl, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_ctrl, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_during_protection, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, null_frame_tx_start, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, null_frame_cts_start, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, bar_retry, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, num_frame_cts_nul_flid, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, tx_abort_failure, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, tx_resume_failure, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, rx_cmplt_db_overflow_cnt, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_rx_exch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_tx_exch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_tx, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, elp_while_nvic_pending, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, rx_excessive_frame_len, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, burst_mismatch, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(error, tbc_exch_mismatch, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_prepared_descs, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cmplt, "%u"); @@ -57,7 +62,7 @@ WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_programmed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_programmed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_burst_programmed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_starts, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_imm_resp, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_stop, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_templates, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_int_templates, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_fw_gen, "%u"); @@ -66,13 +71,15 @@ WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_null_frame, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_template, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_data, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(tx, tx_retry_per_rate, + NUM_OF_RATES_INDEXES); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_pending, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_expiry, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_template, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_data, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_int_template, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_frame_checksum, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_checksum_result, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cfe1, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cfe2, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_called, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_mpdu_alloc_failed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_init_called, "%u"); @@ -97,11 +104,8 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_rts_timeout, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout_wa, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_density_dropped_frame, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_ba_not_expected, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_frame_checksum, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_checksum_result, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_called, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_init_called, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_in_process_called, "%u"); @@ -111,6 +115,7 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_decrypt_failed, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, decrypt_key_not_found, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_decrypt, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_tkip_replays, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_xfr, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); @@ -120,14 +125,13 @@ WL18XX_DEBUGFS_FWSTATS_FILE(pwr, connection_out_of_sync, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD); WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u"); - - -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_timeouts, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_timeouts, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_max_ap_turn, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_max_ap_turn, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_utilization, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_utilization, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_time_count, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_time_avg, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_cycle_avg, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, sleep_percent, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_active_conf, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_user_conf, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pwr, ap_sleep_counter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, beacon_filter, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, arp_filter, "%u"); @@ -141,14 +145,14 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(rx_rate, rx_frames_per_rates, 50); -WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_vs_rate, - AGGR_STATS_TX_AGG*AGGR_STATS_TX_RATE); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_rate, + AGGR_STATS_TX_AGG); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_len, + AGGR_STATS_TX_AGG); WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, rx_size, AGGR_STATS_RX_SIZE_LEN); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, hs_tx_stat_fifo_int, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_tx_stat_fifo_int, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_rx_stat_fifo_int, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_tx_stat_fifo_int, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_rx_stat_fifo_int, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, rx_complete_stat_fifo_int, "%u"); @@ -156,21 +160,32 @@ WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_proc_swi, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, post_proc_swi, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, sec_frag_swi, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_to_defrag_swi, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, defrag_to_csum_swi, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, csum_to_rx_xfer_swi, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, defrag_to_rx_xfer_swi, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in_fifo_full, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_out, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_in, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_out, "%u"); WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pipeline, pipeline_fifo_full, PIPE_STATS_HW_FIFO); -WL18XX_DEBUGFS_FWSTATS_FILE(mem, rx_free_mem_blks, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); -WL18XX_DEBUGFS_FWSTATS_FILE(mem, fw_gen_free_mem_blks, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(diversity, num_of_packets_per_ant, + DIVERSITY_STATS_NUM_OF_ANT); +WL18XX_DEBUGFS_FWSTATS_FILE(diversity, total_num_of_toggles, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, irq_thr_low, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, irq_thr_high, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, tx_stop, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, tx_resume, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, false_irq, "%u"); +WL18XX_DEBUGFS_FWSTATS_FILE(thermal, adc_source_unexpected, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(calib, fail_count, + WL18XX_NUM_OF_CALIBRATIONS_ERRORS); +WL18XX_DEBUGFS_FWSTATS_FILE(calib, calib_count, "%u"); + +WL18XX_DEBUGFS_FWSTATS_FILE(roaming, rssi_level, "%d"); + +WL18XX_DEBUGFS_FWSTATS_FILE(dfs, num_of_radar_detections, "%d"); static ssize_t conf_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -281,6 +296,55 @@ static const struct file_operations radar_detection_ops = { .llseek = default_llseek, }; +static ssize_t dynamic_fw_traces_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + unsigned long value; + int ret; + + ret = kstrtoul_from_user(user_buf, count, 0, &value); + if (ret < 0) + return ret; + + mutex_lock(&wl->mutex); + + wl->dynamic_fw_traces = value; + + if (unlikely(wl->state != WLCORE_STATE_ON)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl18xx_acx_dynamic_fw_traces(wl); + if (ret < 0) + count = ret; + + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + return count; +} + +static ssize_t dynamic_fw_traces_read(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + return wl1271_format_buffer(userbuf, count, ppos, + "%d\n", wl->dynamic_fw_traces); +} + +static const struct file_operations dynamic_fw_traces_ops = { + .read = dynamic_fw_traces_read, + .write = dynamic_fw_traces_write, + .open = simple_open, + .llseek = default_llseek, +}; + int wl18xx_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -301,18 +365,23 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(clear_fw_stats, stats); - DEBUGFS_FWSTATS_ADD(debug, debug1); - DEBUGFS_FWSTATS_ADD(debug, debug2); - DEBUGFS_FWSTATS_ADD(debug, debug3); - DEBUGFS_FWSTATS_ADD(debug, debug4); - DEBUGFS_FWSTATS_ADD(debug, debug5); - DEBUGFS_FWSTATS_ADD(debug, debug6); - - DEBUGFS_FWSTATS_ADD(error, error_frame); - DEBUGFS_FWSTATS_ADD(error, error_null_Frame_tx_start); - DEBUGFS_FWSTATS_ADD(error, error_numll_frame_cts_start); - DEBUGFS_FWSTATS_ADD(error, error_bar_retry); - DEBUGFS_FWSTATS_ADD(error, error_frame_cts_nul_flid); + DEBUGFS_FWSTATS_ADD(error, error_frame_non_ctrl); + DEBUGFS_FWSTATS_ADD(error, error_frame_ctrl); + DEBUGFS_FWSTATS_ADD(error, error_frame_during_protection); + DEBUGFS_FWSTATS_ADD(error, null_frame_tx_start); + DEBUGFS_FWSTATS_ADD(error, null_frame_cts_start); + DEBUGFS_FWSTATS_ADD(error, bar_retry); + DEBUGFS_FWSTATS_ADD(error, num_frame_cts_nul_flid); + DEBUGFS_FWSTATS_ADD(error, tx_abort_failure); + DEBUGFS_FWSTATS_ADD(error, tx_resume_failure); + DEBUGFS_FWSTATS_ADD(error, rx_cmplt_db_overflow_cnt); + DEBUGFS_FWSTATS_ADD(error, elp_while_rx_exch); + DEBUGFS_FWSTATS_ADD(error, elp_while_tx_exch); + DEBUGFS_FWSTATS_ADD(error, elp_while_tx); + DEBUGFS_FWSTATS_ADD(error, elp_while_nvic_pending); + DEBUGFS_FWSTATS_ADD(error, rx_excessive_frame_len); + DEBUGFS_FWSTATS_ADD(error, burst_mismatch); + DEBUGFS_FWSTATS_ADD(error, tbc_exch_mismatch); DEBUGFS_FWSTATS_ADD(tx, tx_prepared_descs); DEBUGFS_FWSTATS_ADD(tx, tx_cmplt); @@ -322,7 +391,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(tx, tx_data_programmed); DEBUGFS_FWSTATS_ADD(tx, tx_burst_programmed); DEBUGFS_FWSTATS_ADD(tx, tx_starts); - DEBUGFS_FWSTATS_ADD(tx, tx_imm_resp); + DEBUGFS_FWSTATS_ADD(tx, tx_stop); DEBUGFS_FWSTATS_ADD(tx, tx_start_templates); DEBUGFS_FWSTATS_ADD(tx, tx_start_int_templates); DEBUGFS_FWSTATS_ADD(tx, tx_start_fw_gen); @@ -331,13 +400,14 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(tx, tx_exch); DEBUGFS_FWSTATS_ADD(tx, tx_retry_template); DEBUGFS_FWSTATS_ADD(tx, tx_retry_data); + DEBUGFS_FWSTATS_ADD(tx, tx_retry_per_rate); DEBUGFS_FWSTATS_ADD(tx, tx_exch_pending); DEBUGFS_FWSTATS_ADD(tx, tx_exch_expiry); DEBUGFS_FWSTATS_ADD(tx, tx_done_template); DEBUGFS_FWSTATS_ADD(tx, tx_done_data); DEBUGFS_FWSTATS_ADD(tx, tx_done_int_template); - DEBUGFS_FWSTATS_ADD(tx, tx_frame_checksum); - DEBUGFS_FWSTATS_ADD(tx, tx_checksum_result); + DEBUGFS_FWSTATS_ADD(tx, tx_cfe1); + DEBUGFS_FWSTATS_ADD(tx, tx_cfe2); DEBUGFS_FWSTATS_ADD(tx, frag_called); DEBUGFS_FWSTATS_ADD(tx, frag_mpdu_alloc_failed); DEBUGFS_FWSTATS_ADD(tx, frag_init_called); @@ -362,11 +432,8 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); DEBUGFS_FWSTATS_ADD(rx, rx_timeout); + DEBUGFS_FWSTATS_ADD(rx, rx_rts_timeout); DEBUGFS_FWSTATS_ADD(rx, rx_timeout_wa); - DEBUGFS_FWSTATS_ADD(rx, rx_wa_density_dropped_frame); - DEBUGFS_FWSTATS_ADD(rx, rx_wa_ba_not_expected); - DEBUGFS_FWSTATS_ADD(rx, rx_frame_checksum); - DEBUGFS_FWSTATS_ADD(rx, rx_checksum_result); DEBUGFS_FWSTATS_ADD(rx, defrag_called); DEBUGFS_FWSTATS_ADD(rx, defrag_init_called); DEBUGFS_FWSTATS_ADD(rx, defrag_in_process_called); @@ -376,6 +443,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx, decrypt_key_not_found); DEBUGFS_FWSTATS_ADD(rx, defrag_need_decrypt); DEBUGFS_FWSTATS_ADD(rx, rx_tkip_replays); + DEBUGFS_FWSTATS_ADD(rx, rx_xfr); DEBUGFS_FWSTATS_ADD(isr, irqs); @@ -384,13 +452,13 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(pwr, connection_out_of_sync); DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); - - DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_timeouts); - DEBUGFS_FWSTATS_ADD(ps_poll, upsd_timeouts); - DEBUGFS_FWSTATS_ADD(ps_poll, upsd_max_ap_turn); - DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_max_ap_turn); - DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_utilization); - DEBUGFS_FWSTATS_ADD(ps_poll, upsd_utilization); + DEBUGFS_FWSTATS_ADD(pwr, sleep_time_count); + DEBUGFS_FWSTATS_ADD(pwr, sleep_time_avg); + DEBUGFS_FWSTATS_ADD(pwr, sleep_cycle_avg); + DEBUGFS_FWSTATS_ADD(pwr, sleep_percent); + DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_active_conf); + DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_user_conf); + DEBUGFS_FWSTATS_ADD(pwr, ap_sleep_counter); DEBUGFS_FWSTATS_ADD(rx_filter, beacon_filter); DEBUGFS_FWSTATS_ADD(rx_filter, arp_filter); @@ -404,12 +472,11 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(rx_rate, rx_frames_per_rates); - DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_vs_rate); + DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_rate); + DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_len); DEBUGFS_FWSTATS_ADD(aggr_size, rx_size); DEBUGFS_FWSTATS_ADD(pipeline, hs_tx_stat_fifo_int); - DEBUGFS_FWSTATS_ADD(pipeline, tcp_tx_stat_fifo_int); - DEBUGFS_FWSTATS_ADD(pipeline, tcp_rx_stat_fifo_int); DEBUGFS_FWSTATS_ADD(pipeline, enc_tx_stat_fifo_int); DEBUGFS_FWSTATS_ADD(pipeline, enc_rx_stat_fifo_int); DEBUGFS_FWSTATS_ADD(pipeline, rx_complete_stat_fifo_int); @@ -417,22 +484,33 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, DEBUGFS_FWSTATS_ADD(pipeline, post_proc_swi); DEBUGFS_FWSTATS_ADD(pipeline, sec_frag_swi); DEBUGFS_FWSTATS_ADD(pipeline, pre_to_defrag_swi); - DEBUGFS_FWSTATS_ADD(pipeline, defrag_to_csum_swi); - DEBUGFS_FWSTATS_ADD(pipeline, csum_to_rx_xfer_swi); + DEBUGFS_FWSTATS_ADD(pipeline, defrag_to_rx_xfer_swi); DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in); DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in_fifo_full); DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_out); - DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_in); - DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_out); DEBUGFS_FWSTATS_ADD(pipeline, pipeline_fifo_full); - DEBUGFS_FWSTATS_ADD(mem, rx_free_mem_blks); - DEBUGFS_FWSTATS_ADD(mem, tx_free_mem_blks); - DEBUGFS_FWSTATS_ADD(mem, fwlog_free_mem_blks); - DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks); + DEBUGFS_FWSTATS_ADD(diversity, num_of_packets_per_ant); + DEBUGFS_FWSTATS_ADD(diversity, total_num_of_toggles); + + DEBUGFS_FWSTATS_ADD(thermal, irq_thr_low); + DEBUGFS_FWSTATS_ADD(thermal, irq_thr_high); + DEBUGFS_FWSTATS_ADD(thermal, tx_stop); + DEBUGFS_FWSTATS_ADD(thermal, tx_resume); + DEBUGFS_FWSTATS_ADD(thermal, false_irq); + DEBUGFS_FWSTATS_ADD(thermal, adc_source_unexpected); + + DEBUGFS_FWSTATS_ADD(calib, fail_count); + + DEBUGFS_FWSTATS_ADD(calib, calib_count); + + DEBUGFS_FWSTATS_ADD(roaming, rssi_level); + + DEBUGFS_FWSTATS_ADD(dfs, num_of_radar_detections); DEBUGFS_ADD(conf, moddir); DEBUGFS_ADD(radar_detection, moddir); + DEBUGFS_ADD(dynamic_fw_traces, moddir); return 0; diff --git a/kernel/drivers/net/wireless/ti/wl18xx/event.c b/kernel/drivers/net/wireless/ti/wl18xx/event.c index 548bb9e7e..09c7e098f 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/event.c +++ b/kernel/drivers/net/wireless/ti/wl18xx/event.c @@ -112,6 +112,14 @@ static int wlcore_smart_config_decode_event(struct wl1271 *wl, return 0; } +static void wlcore_event_time_sync(struct wl1271 *wl, u16 tsf_msb, u16 tsf_lsb) +{ + u32 clock; + /* convert the MSB+LSB to a u32 TSF value */ + clock = (tsf_msb << 16) | tsf_lsb; + wl1271_info("TIME_SYNC_EVENT_ID: clock %u", clock); +} + int wl18xx_process_mailbox_events(struct wl1271 *wl) { struct wl18xx_event_mailbox *mbox = wl->mbox; @@ -128,6 +136,11 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl) wl18xx_scan_completed(wl, wl->scan_wlvif); } + if (vector & TIME_SYNC_EVENT_ID) + wlcore_event_time_sync(wl, + mbox->time_sync_tsf_msb, + mbox->time_sync_tsf_lsb); + if (vector & RADAR_DETECTED_EVENT_ID) { wl1271_info("radar event: channel %d type %s", mbox->radar_channel, diff --git a/kernel/drivers/net/wireless/ti/wl18xx/event.h b/kernel/drivers/net/wireless/ti/wl18xx/event.h index 266ee8783..f3d4f1337 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/event.h +++ b/kernel/drivers/net/wireless/ti/wl18xx/event.h @@ -38,8 +38,9 @@ enum { REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18), DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19), PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20), - SMART_CONFIG_SYNC_EVENT_ID = BIT(22), - SMART_CONFIG_DECODE_EVENT_ID = BIT(23), + SMART_CONFIG_SYNC_EVENT_ID = BIT(22), + SMART_CONFIG_DECODE_EVENT_ID = BIT(23), + TIME_SYNC_EVENT_ID = BIT(24), }; enum wl18xx_radar_types { @@ -95,13 +96,16 @@ struct wl18xx_event_mailbox { /* smart config sync channel */ u8 sc_sync_channel; u8 sc_sync_band; - u8 padding2[2]; + /* time sync msb*/ + u16 time_sync_tsf_msb; /* radar detect */ u8 radar_channel; u8 radar_type; - u8 padding3[2]; + /* time sync lsb*/ + u16 time_sync_tsf_lsb; + } __packed; int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event, diff --git a/kernel/drivers/net/wireless/ti/wl18xx/main.c b/kernel/drivers/net/wireless/ti/wl18xx/main.c index 717c4f5a0..50cce4208 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/main.c +++ b/kernel/drivers/net/wireless/ti/wl18xx/main.c @@ -24,6 +24,7 @@ #include <linux/ip.h> #include <linux/firmware.h> #include <linux/etherdevice.h> +#include <linux/irq.h> #include "../wlcore/wlcore.h" #include "../wlcore/debug.h" @@ -421,6 +422,8 @@ static struct wlcore_conf wl18xx_conf = { .num_probe_reqs = 2, .rssi_threshold = -90, .snr_threshold = 0, + .num_short_intervals = SCAN_MAX_SHORT_INTERVALS, + .long_interval = 30000, }, .ht = { .rx_ba_win_size = 32, @@ -578,7 +581,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { [PART_TOP_PRCM_ELP_SOC] = { - .mem = { .start = 0x00A02000, .size = 0x00010000 }, + .mem = { .start = 0x00A00000, .size = 0x00012000 }, .reg = { .start = 0x00807000, .size = 0x00005000 }, .mem2 = { .start = 0x00800000, .size = 0x0000B000 }, .mem3 = { .start = 0x00000000, .size = 0x00000000 }, @@ -862,6 +865,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl) { u32 tmp; int ret; + u16 irq_invert; BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) > WL18XX_PHY_INIT_MEM_SIZE); @@ -911,6 +915,28 @@ static int wl18xx_pre_upload(struct wl1271 *wl) /* re-enable FDSP clock */ ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, MEM_FDSP_CLK_120_ENABLE); + if (ret < 0) + goto out; + + ret = irq_get_trigger_type(wl->irq); + if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) { + wl1271_info("using inverted interrupt logic: %d", ret); + ret = wlcore_set_partition(wl, + &wl->ptable[PART_TOP_PRCM_ELP_SOC]); + if (ret < 0) + goto out; + + ret = wl18xx_top_reg_read(wl, TOP_FN0_CCCR_REG_32, &irq_invert); + if (ret < 0) + goto out; + + irq_invert |= BIT(1); + ret = wl18xx_top_reg_write(wl, TOP_FN0_CCCR_REG_32, irq_invert); + if (ret < 0) + goto out; + + ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + } out: return ret; @@ -1002,8 +1028,8 @@ static int wl18xx_boot(struct wl1271 *wl) CHANNEL_SWITCH_COMPLETE_EVENT_ID | DFS_CHANNELS_CONFIG_COMPLETE_EVENT | SMART_CONFIG_SYNC_EVENT_ID | - SMART_CONFIG_DECODE_EVENT_ID; -; + SMART_CONFIG_DECODE_EVENT_ID | + TIME_SYNC_EVENT_ID; wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; @@ -1135,6 +1161,11 @@ static int wl18xx_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + /* set the dynamic fw traces bitmap */ + ret = wl18xx_acx_dynamic_fw_traces(wl); + if (ret < 0) + return ret; + if (checksum_param) { ret = wl18xx_acx_set_checksum_state(wl); if (ret != 0) @@ -1351,9 +1382,10 @@ out: } #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" -static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) + +static int wl18xx_load_conf_file(struct device *dev, struct wlcore_conf *conf, + struct wl18xx_priv_conf *priv_conf) { - struct wl18xx_priv *priv = wl->priv; struct wlcore_conf_file *conf_file; const struct firmware *fw; int ret; @@ -1362,14 +1394,14 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) if (ret < 0) { wl1271_error("could not get configuration binary %s: %d", WL18XX_CONF_FILE_NAME, ret); - goto out_fallback; + return ret; } if (fw->size != WL18XX_CONF_SIZE) { wl1271_error("configuration binary file size is wrong, expected %zu got %zu", WL18XX_CONF_SIZE, fw->size); ret = -EINVAL; - goto out; + goto out_release; } conf_file = (struct wlcore_conf_file *) fw->data; @@ -1379,7 +1411,7 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC, conf_file->header.magic); ret = -EINVAL; - goto out; + goto out_release; } if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) { @@ -1387,28 +1419,32 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) "expected 0x%08x got 0x%08x", WL18XX_CONF_VERSION, conf_file->header.version); ret = -EINVAL; - goto out; + goto out_release; } - memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf)); - memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf)); + memcpy(conf, &conf_file->core, sizeof(*conf)); + memcpy(priv_conf, &conf_file->priv, sizeof(*priv_conf)); - goto out; +out_release: + release_firmware(fw); + return ret; +} + +static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) +{ + struct wl18xx_priv *priv = wl->priv; -out_fallback: - wl1271_warning("falling back to default config"); + if (wl18xx_load_conf_file(dev, &wl->conf, &priv->conf) < 0) { + wl1271_warning("falling back to default config"); - /* apply driver default configuration */ - memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); - /* apply default private configuration */ - memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); + /* apply driver default configuration */ + memcpy(&wl->conf, &wl18xx_conf, sizeof(wl->conf)); + /* apply default private configuration */ + memcpy(&priv->conf, &wl18xx_default_priv_conf, + sizeof(priv->conf)); + } - /* For now we just fallback */ return 0; - -out: - release_firmware(fw); - return ret; } static int wl18xx_plt_init(struct wl1271 *wl) @@ -1768,7 +1804,7 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { static const struct ieee80211_iface_limit wl18xx_iface_limits[] = { { - .max = 3, + .max = 2, .types = BIT(NL80211_IFTYPE_STATION), }, { @@ -1777,6 +1813,10 @@ static const struct ieee80211_iface_limit wl18xx_iface_limits[] = { BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT), }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE), + }, }; static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = { @@ -1784,6 +1824,48 @@ static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = { .max = 2, .types = BIT(NL80211_IFTYPE_AP), }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE), + }, +}; + +static const struct ieee80211_iface_limit wl18xx_iface_ap_cl_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_CLIENT), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE), + }, +}; + +static const struct ieee80211_iface_limit wl18xx_iface_ap_go_limits[] = { + { + .max = 1, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_GO), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE), + }, }; static const struct ieee80211_iface_combination @@ -2033,3 +2115,4 @@ MODULE_PARM_DESC(num_rx_desc_param, MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); MODULE_FIRMWARE(WL18XX_FW_NAME); +MODULE_FIRMWARE(WL18XX_CONF_FILE_NAME); diff --git a/kernel/drivers/net/wireless/ti/wl18xx/reg.h b/kernel/drivers/net/wireless/ti/wl18xx/reg.h index a433a75f3..bac2364c8 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/reg.h +++ b/kernel/drivers/net/wireless/ti/wl18xx/reg.h @@ -109,6 +109,7 @@ #define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) #define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) +#define TOP_FN0_CCCR_REG_32 (WL18XX_TOP_OCP_BASE + 0x64) /* PRCM registers */ #define PLATFORM_DETECTION 0xA0E3E0 diff --git a/kernel/drivers/net/wireless/ti/wl18xx/scan.c b/kernel/drivers/net/wireless/ti/wl18xx/scan.c index 98666f235..bc15aa2c3 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/scan.c +++ b/kernel/drivers/net/wireless/ti/wl18xx/scan.c @@ -51,7 +51,11 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif, goto out; } - cmd->role_id = wlvif->role_id; + /* scan on the dev role if the regular one is not started */ + if (wlcore_is_p2p_mgmt(wlvif)) + cmd->role_id = wlvif->dev_role_id; + else + cmd->role_id = wlvif->role_id; if (WARN_ON(cmd->role_id == WL12XX_INVALID_ROLE_ID)) { ret = -EINVAL; @@ -223,9 +227,22 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl, SCAN_TYPE_PERIODIC); wl18xx_adjust_channels(cmd, cmd_channels); - cmd->short_cycles_sec = 0; - cmd->long_cycles_sec = cpu_to_le16(req->interval); - cmd->short_cycles_count = 0; + if (c->num_short_intervals && c->long_interval && + c->long_interval > req->scan_plans[0].interval * MSEC_PER_SEC) { + cmd->short_cycles_msec = + cpu_to_le16(req->scan_plans[0].interval * MSEC_PER_SEC); + cmd->long_cycles_msec = cpu_to_le16(c->long_interval); + cmd->short_cycles_count = c->num_short_intervals; + } else { + cmd->short_cycles_msec = 0; + cmd->long_cycles_msec = + cpu_to_le16(req->scan_plans[0].interval * MSEC_PER_SEC); + cmd->short_cycles_count = 0; + } + wl1271_debug(DEBUG_SCAN, "short_interval: %d, long_interval: %d, num_short: %d", + le16_to_cpu(cmd->short_cycles_msec), + le16_to_cpu(cmd->long_cycles_msec), + cmd->short_cycles_count); cmd->total_cycles = 0; diff --git a/kernel/drivers/net/wireless/ti/wl18xx/scan.h b/kernel/drivers/net/wireless/ti/wl18xx/scan.h index 2e636aa5d..66a763f64 100644 --- a/kernel/drivers/net/wireless/ti/wl18xx/scan.h +++ b/kernel/drivers/net/wireless/ti/wl18xx/scan.h @@ -74,8 +74,8 @@ struct wl18xx_cmd_scan_params { u8 dfs; /* number of dfs channels in 5ghz */ u8 passive_active; /* number of passive before active channels 2.4ghz */ - __le16 short_cycles_sec; - __le16 long_cycles_sec; + __le16 short_cycles_msec; + __le16 long_cycles_msec; u8 short_cycles_count; u8 total_cycles; /* 0 - infinite */ u8 padding[2]; |