diff --git a/README.md b/README.md index 434eeb6..78c1b82 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # uccp420wlan -This is a SoftMAC (mac80211) based WiFi driver for Imagination's Explorer RPU uccp420. -This supports Dual Band WiFi with 2.4GHz - 2x2 b/g/n 40MHz, 5GHz - 2x2 a/n/11ac 80MHz modes. +This is a SoftMAC (mac80211) based WiFi driver for Imagination's Explorer RPU Series 4 (uccp420). +This driver supports + - Dual Band 2x2 MIMO WiFi with 2.4GHz - b/g/n 40MHz, 5GHz - a/n/ac 80MHz modes. + - STA, SoftAP, P2P-GC/GO and IBSS modes diff --git a/firmware/MAC_LOADER.ldr b/firmware/MAC_LOADER.ldr index f32b480..493f75c 100644 Binary files a/firmware/MAC_LOADER.ldr and b/firmware/MAC_LOADER.ldr differ diff --git a/firmware/MCP_LOADER.ldr b/firmware/MCP_LOADER.ldr index 472e93e..bd2dd9e 100644 Binary files a/firmware/MCP_LOADER.ldr and b/firmware/MCP_LOADER.ldr differ diff --git a/inc/core.h b/inc/core.h index d635ff8..efdf06c 100755 --- a/inc/core.h +++ b/inc/core.h @@ -143,7 +143,7 @@ extern spinlock_t tsf_lock; #define CH_PROG_TIMEOUT 500 /* In milli-seconds*/ #define CH_PROG_TIMEOUT_TICKS msecs_to_jiffies(CH_PROG_TIMEOUT) -#define QUEUE_FLUSH_TIMEOUT 2000 /* Specify delay in milli-seconds*/ +#define QUEUE_FLUSH_TIMEOUT 5000 /* Specify delay in milli-seconds*/ #define QUEUE_FLUSH_TIMEOUT_TICKS msecs_to_jiffies(QUEUE_FLUSH_TIMEOUT) #define TX_DEINIT_TIMEOUT 5000 @@ -498,6 +498,7 @@ struct wifi_stats { * RX circular buffers */ unsigned int rx_mic_fail_cnt; /* Num of MIC failures */ + unsigned int deagg_bufOverFlow_cnt; /* RX buffer overflow count */ /* HAL related */ unsigned int hal_cmd_cnt; /* Num of commands received by HAL from the @@ -507,6 +508,7 @@ struct wifi_stats { unsigned int hal_ext_ptr_null_cnt; /* Num of packets dropped due to lack * of Ext Ram buffers from host */ + unsigned int hal_int_ptr_null_cnt; /*RF Calibration Data*/ unsigned int rf_calib_data_length; @@ -826,6 +828,8 @@ __s32 __attribute__((weak)) frc_to_atu(__u32 frccnt, __u64 *patu, s32 dir); int __attribute__((weak)) get_evt_timer_freq(unsigned int *mask, unsigned int *num, unsigned int *denom); +int __attribute__((weak)) atu_get_cur_timestamps(unsigned long long *t, + unsigned int *ts); int tx_queue_map(int queue); int tx_queue_unmap(int queue); diff --git a/inc/hal.h b/inc/hal.h index eda5f28..a191eb8 100644 --- a/inc/hal.h +++ b/inc/hal.h @@ -25,13 +25,113 @@ #ifndef _UCCP420WLAN_HAL_H_ #define _UCCP420WLAN_HAL_H_ +#define _PACKED_ __attribute__((__packed__)) + #define HOST_MOD_ID 0 #define UMAC_MOD_ID 1 #define LMAC_MOD_ID 2 #define MODULE_MAX 3 +#define MAX_RX_BUF_PTR_PER_CMD (16) +#define MAX_DATA_SIZE_12K (12 * 1024) +#define MAX_DATA_SIZE_8K (8 * 1024) +#define MAX_DATA_SIZE_2K (2 * 1024) + +#define NUM_TX_DESC 12 +#define NUM_FRAMES_IN_TX_DESC 32 +#define NUM_BYTES_PER_FRAME 9 +#define TX_DESC_HAL_SIZE (NUM_FRAMES_IN_TX_DESC * NUM_BYTES_PER_FRAME) + #define HAL_PRIV_DATA_SIZE 8 +#define HAL_HOST_ZONE_DMA_LEN (64 * 1024 * 1024) +#define HAL_SHARED_MEM_MAX_MSG_SIZE 60 +#define HAL_SHARED_MEM_MAX_TX_SIZE 0xD80 + +/* Command, Event, Tx Data and Buff mappping offsets */ +#define HAL_COMMAND_OFFSET (0) +#define HAL_EVENT_OFFSET (HAL_COMMAND_OFFSET + HAL_SHARED_MEM_MAX_MSG_SIZE) +#define HAL_TX_DATA_OFFSET (HAL_EVENT_OFFSET + HAL_SHARED_MEM_MAX_MSG_SIZE) +#define HAL_AXD_DATA_OFFSET (HAL_TX_DATA_OFFSET + HAL_SHARED_MEM_MAX_TX_SIZE) + +#define HAL_GRAM_CMD_START ((hpriv->gram_mem_addr) + HAL_COMMAND_OFFSET) +#define HAL_GRAM_EVENT_START ((hpriv->gram_mem_addr) + HAL_EVENT_OFFSET) +#define HAL_GRAM_TX_DATA_START ((hpriv->gram_mem_addr) + HAL_TX_DATA_OFFSET) +#define HAL_AXD_DATA_START ((hpriv->gram_mem_addr) + HAL_AXD_DATA_OFFSET) + +#define HAL_GRAM_CMD_LEN (HAL_GRAM_CMD_START + 8) +#define HAL_GRAM_TX_DATA_LEN (HAL_GRAM_TX_DATA_START + 0) +#define HAL_GRAM_TX_DATA_OFFSET (HAL_GRAM_TX_DATA_START + 3) +#define HAL_GRAM_TX_DATA_ADDR (HAL_GRAM_TX_DATA_START + 6) + +#define HAL_HOST_BOUNCE_BUF_LEN (4 * 1024 * 1024) +#define HAL_HOST_NON_BOUNCE_BUF_LEN (60 * 1024 * 1024) + +/*RPU DUMP Regions and Commands*/ +#define UCCP_REGION_TYPE_COREA 0 +#define UCCP_REGION_TYPE_COREB 1 + +enum hal_rpu_testmode_cmd { + HAL_RPU_TM_CMD_ALL = 0, + HAL_RPU_TM_CMD_GRAM = 1, + HAL_RPU_TM_CMD_COREA = 2, + HAL_RPU_TM_CMD_COREB = 3, + HAL_RPU_TM_CMD_PERIP = 4, + HAL_RPU_TM_CMD_SYSBUS = 5, +}; + +struct buf_info { + dma_addr_t dma_buf; + void __iomem *src_ptr; + unsigned int dma_buf_len; + unsigned int dma_buf_priv; /* Is the DMA buffer in our private area */ + struct sk_buff *skb; +} _PACKED_; + +struct hal_tx_data { + unsigned int data_len:24; + unsigned long address:24; + unsigned long offset:24; +} _PACKED_; + +struct hal_hdr { + /*! 0xffffffff - hal command or hal event + * 0x0 - lmac command or lmac event + */ + unsigned int id; + /*! Data pointer of commands with payload + * this field is valid only if descriptor id + * of command header is set to some value + * other. + */ + unsigned int data_ptr; +} _PACKED_; + +struct hal_rx_pkt_info { + /* Rx descriptor */ + unsigned int desc; + unsigned int ptr; +} _PACKED_; + +struct hal_rx_command { + unsigned int rx_pkt_cnt; + struct hal_rx_pkt_info rx_pkt[MAX_RX_BUF_PTR_PER_CMD]; +} _PACKED_; + +struct cmd_hal { + struct hal_hdr hdr; + struct hal_rx_command rx_pkt_data; +} _PACKED_; + +struct event_hal { + struct hal_hdr hdr; + unsigned int rx_pkt_cnt; + unsigned int rx_pkt_desc[16]; +} _PACKED_; + +int _uccp420wlan_80211if_init(struct proc_dir_entry **); +void _uccp420wlan_80211if_exit(void); +int reset_hal_params(void); typedef int (*msg_handler)(void *, unsigned char); struct hal_ops_tag { @@ -59,6 +159,8 @@ struct hal_ops_tag { int (*get_dump_perip)(unsigned long *dump_start); int (*get_dump_sysbus)(unsigned long *dump_start); int (*get_dump_len)(unsigned long); + int (*update_axd_timestamps)(void); + unsigned int (*get_axd_buf_phy_addr)(void); }; extern struct hal_ops_tag hal_ops; diff --git a/inc/hal_hostport.h b/inc/hal_hostport.h new file mode 100644 index 0000000..7fb84fa --- /dev/null +++ b/inc/hal_hostport.h @@ -0,0 +1,97 @@ +/* + * File Name : hal_hostport.h + * + * This file contains the definitions specific to HOSPORT comms + * + * Copyright (c) 2011, 2012, 2013, 2014 Imagination Technologies Ltd. + * All rights reserved + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef _UCCP420WLAN_HAL_HOSTPORT_H_ +#define _UCCP420WLAN_HAL_HOSTPORT_H_ + +#include +#include + +#include + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +struct hal_priv { + /* UCCP Host RAM mappings*/ + void __iomem *base_addr_uccp_host_ram; + void __iomem *tx_base_addr_uccp_host_ram; + void __iomem *rx_base_addr_uccp_host_ram; + + /* UCCP and GRAM mappings */ + unsigned long uccp_mem_addr; + unsigned long gram_mem_addr; + unsigned long uccp_sysbus_base_addr; + unsigned long uccp_perip_base_addr; + unsigned long gram_base_addr; + unsigned long shm_offset; + unsigned long hal_disabled; + unsigned long gram_b4_addr; + + /* DTS entries */ + unsigned long uccp_sysbus_base; + unsigned long uccp_sysbus_len; + unsigned long uccp_perip_base; + unsigned long uccp_perip_len; + unsigned long uccp_pkd_gram_base; + unsigned long uccp_pkd_gram_len; + unsigned long uccp_gram_base; + unsigned long uccp_gram_len; + + /* TX */ + struct sk_buff_head txq; + struct tasklet_struct tx_tasklet; + unsigned short cmd_cnt; + struct buf_info *tx_buf_info; + struct hal_tx_data *hal_tx_data; + + /* RX */ + struct sk_buff_head rxq; + struct tasklet_struct rx_tasklet; + struct tasklet_struct recv_tasklet; + unsigned short event_cnt; + msg_handler rcv_handler; + struct buf_info *rx_buf_info; + + /* Buffers info from IF layer*/ + unsigned int tx_bufs; + unsigned int rx_bufs_2k; + unsigned int rx_bufs_12k; + unsigned int max_data_size; + + /* Temp storage to refill first and process next*/ + struct sk_buff_head refillq; + int irq; +}; + + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _UCCP420WLAN_HAL_HOSTPORT_H_ */ + +/* EOF */ diff --git a/inc/host_umac_if.h b/inc/host_umac_if.h index cf06daf..a5f443c 100644 --- a/inc/host_umac_if.h +++ b/inc/host_umac_if.h @@ -72,6 +72,11 @@ #define RF_PARAMS_SIZE 369 #define MAX_RF_CALIB_DATA 900 + +/* AXD */ +#define STREAM_SYNC_MAGIC_NUM 0xCCCCFFFF +#define AXD_BUF_ADDR 0x3f8000 + struct hal_data { unsigned char hal_data[HAL_PRIV_DATA_SIZE]; } __packed; @@ -265,6 +270,7 @@ struct umac_event_mac_stats { unsigned int roc_stop; unsigned int roc_complete; unsigned int roc_stop_complete; + unsigned int deagg_bufOverFlow_cnt; /* TX related */ unsigned int tx_cmd_cnt; /* Num of TX commands received from host */ unsigned int tx_done_cnt; /* Num of Tx done events sent to host */ @@ -306,6 +312,9 @@ struct umac_event_mac_stats { unsigned int hal_ext_ptr_null_cnt; /* Num of packets dropped due to lack * of Ext Ram buffers from host */ + unsigned int hal_int_ptr_null_cnt; /* Num of packets droped due to lack + * of internal hal event buffers + */ } __packed; diff --git a/inc/rpu.h b/inc/rpu.h new file mode 100644 index 0000000..fad5d78 --- /dev/null +++ b/inc/rpu.h @@ -0,0 +1,89 @@ +/* RPU Porting information: Based on RPU Config. + * These are the only values which need to be modified as per + * a) host memory map + * b) HOSt <->MCU interrupt configuration. + * c) RPU Config specific details + */ + +/********************************************************************* + * RPU Config Specific Details + ********************************************************************* + */ +#define HAL_UCCP_GRAM_BASE 0xB7000000 +#define HAL_UCCP_GRAM_LEN 0x1eac0 +#define HAL_SHARED_MEM_OFFSET 0x45ffc +/* fwldr.c converts these to HOST addresses + * so pass RPU addresses here. + * From: uccrunTime/Platform/configs + */ +#define UCCP_COREA_REGION_START 0x80880000 +#define UCCP_COREA_REGION_LEN 0x4C000 + +#define UCCP_COREB_REGION_START 0x82000000 +#define UCCP_COREB_REGION_LEN 0x4C000 +/********************************************************************* + */ + +/******************************************************************** + * HOST processor to Meta Processor on RPU Communications Registers + ******************************************************************** + * Refer: Volt UCCP.Technical Reference Manual.pdf + * The host_to_mtx_cmd register is written to by the host in order to + * send data to the META. The act of writing causes an event on the META + * (the host_int interrupt occurs). The META handles this event by reading + * host_to_mtx_cmd, collecting the message data. + * + * The META clears the interrupt and in the process acknowledges reception + * of the message by writing to the mtx_to_host_ack register. The host checks + * for this acknowledgement by reading host_to_mtx_cmd, checking the state of + * the HOST_INT bit. + * + * A message initiated by the META and destined for the host uses the same + * scheme, but utilising the mtx_to_host_cmd and host_to_mtx_ack registers and + * by responding to the mtx_int interrupt. + */ + +/* SYSBUS - System Control - REGSYSREG + * UCCP_CORE_REG is a subset of System Bus Registers + */ +#define HAL_UCCP_CORE_REG_OFFSET 0x400 + +/* Register HOST_TO_MTX_CMD */ +#define HOST_TO_MTX_CMD 0x0030 +#define HOST_TO_MTX_CMD_ADDR ((hpriv->uccp_mem_addr) + \ + HOST_TO_MTX_CMD) +#define MTX_HOST_INT_SHIFT 31 + +/* Register MTX_TO_HOST_CMD */ +#define MTX_TO_HOST_CMD 0x0034 +#define MTX_TO_HOST_CMD_ADDR ((hpriv->uccp_mem_addr) + \ + MTX_TO_HOST_CMD) + +/* Register HOST_TO_MTX_ACK */ +#define HOST_TO_MTX_ACK 0x0038 +#define HOST_TO_MTX_ACK_ADDR ((hpriv->uccp_mem_addr) + \ + HOST_TO_MTX_ACK) +#define MTX_INT_CLR_SHIFT 31 + +/* Register MTX_TO_HOST_ACK */ +#define MTX_TO_HOST_ACK 0x003C +#define MTX_TO_HOST_ACK_ADDR ((hpriv->uccp_mem_addr) + \ + MTX_TO_HOST_ACK) + +/* Register MTX_INT_ENABLE + * Enable INT line within META Block + */ +#define MTX_INT_ENABLE 0x0044 +#define MTX_INT_ENABLE_ADDR ((hpriv->uccp_mem_addr) + \ + MTX_INT_ENABLE) +#define MTX_INT_EN_SHIFT 31 + +/* System Level Interrupt Control for each block. + * Enable INT line for META block. + */ +#define SYS_INT_ENAB 0x0000 +#define SYS_INT_ENAB_ADDR ((hpriv->uccp_mem_addr) + SYS_INT_ENAB) +#define SYS_INT_MTX_IRQ_ENAB_SHIFT 15 + +/********************************************************************* + */ diff --git a/inc/soc.h b/inc/soc.h new file mode 100644 index 0000000..e8f5950 --- /dev/null +++ b/inc/soc.h @@ -0,0 +1,30 @@ +/*SoC Porting information: + */ + +/* Refer: Danube SoC Functional Spec + * + * The below values should be populated in the dtb file for SoC. + * + * Configure the RPU view addresses in dtb, they should directly accessible + * using memory mapped io in Danube SoC. + * (Ref: Volt UCCP.Technical Reference Manual.pdf) + * This might change depending on the SoC. + * Sample entries looks like below + * compatible = "img,pistachio-uccp"; + * reg = <0x18480000 0x9000>, <0x184C0000 0x80000>, + * <0x1a000000 0x00066CC0>; + * reg-names = "uccp_sysbus_base", "uccp_perip_base", + * "uccp_pkd_gram_base"; + * interrupts = ; + * interrupt-names = "uccpirq"; + * uccp_sysbus_base ==> Slave Host System Bus (IMG Bus 2.0 compliant) + * interface for connection to an external processor, allowing + * the external processor to access all internal RPU registers + * and GRAM. + * uccp_perip_base ==> Master External System Bus (IMG Bus 1.0 compliant) + * interface for connection of peripherals that can be controlled by + * RPU’s internal META LTP processor. + * uccp_pkd_gram_base ==> Byte Access of GRAM + * uccp_gram_base ==> Word Access of GRAM + * uccpirq ==> IRQ Line assigned to RPU + */ diff --git a/inc/version.h b/inc/version.h index 1a24b91..7774132 100644 --- a/inc/version.h +++ b/inc/version.h @@ -23,7 +23,7 @@ */ #ifndef _UCCP420WLAN_VERSION_H #define _UCCP420WLAN_VERSION_H -#define UCCP_DRIVER_VERSION "6_0_5" +#define UCCP_DRIVER_VERSION "6_0_6" #define UCCP_DRIVER_NAME "UCCP420WIFI" #endif /* _UCCP420WLAN_VERSION_H */ diff --git a/src/80211_if.c b/src/80211_if.c index 6291194..16abd45 100644 --- a/src/80211_if.c +++ b/src/80211_if.c @@ -547,11 +547,6 @@ static int start(struct ieee80211_hw *hw) UCCP_DEBUG_80211IF("%s-80211IF: In start\n", dev->name); - if ((wifi->params.fw_loading == 1) && load_fw(hw)) { - UCCP_DEBUG_80211IF("%s-80211IF: FW load failed\n", dev->name); - return -ENODEV; - } - mutex_lock(&dev->mutex); if ((uccp420wlan_core_init(dev, ftm)) < 0) { UCCP_DEBUG_80211IF("%s-80211IF: umac init failed\n", dev->name); @@ -1402,6 +1397,7 @@ static void init_hw(struct ieee80211_hw *hw) ieee80211_hw_set(hw, CONNECTION_MONITOR); ieee80211_hw_set(hw, CHANCTX_STA_CSA); ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); + ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); hw->wiphy->max_scan_ssids = MAX_NUM_SSIDS; /* 4 */ /* Low priority bg scan */ @@ -1462,6 +1458,8 @@ static void init_hw(struct ieee80211_hw *hw) #ifdef CONFIG_PM hw->wiphy->wowlan = &uccp_wowlan_support; #endif + if ((wifi->params.fw_loading == 1) && load_fw(hw)) + UCCP_DEBUG_80211IF("%s-80211IF: FW load failed\n", dev->name); } @@ -3279,6 +3277,8 @@ static int proc_read_config(struct seq_file *m, void *v) (wifi->stats.uccp420_lmac_version[0] - '0'), (wifi->stats.uccp420_lmac_version[2] - '0')); } + seq_printf(m, "rpu_axd_address = %x\n", + hal_ops.get_axd_buf_phy_addr()); return 0; } @@ -3665,14 +3665,16 @@ static int proc_read_mac_stats(struct seq_file *m, void *v) wifi->stats.rx_circular_buffer_free_cnt); seq_printf(m, "rx_mic_fail_cnt =%d\n", wifi->stats.rx_mic_fail_cnt); - - /* HAL related */ - seq_printf(m, "hal_cmd_cnt =%d\n", - wifi->stats.hal_cmd_cnt); - seq_printf(m, "hal_event_cnt =%d\n", - wifi->stats.hal_event_cnt); - seq_printf(m, "hal_ext_ptr_null_cnt =%d\n", + /* RPU Frame Drops*/ + seq_puts(m, "================\n"); + seq_puts(m, "RPU Frame Drops\n"); + seq_puts(m, "================\n"); + seq_printf(m, "rpu_ext_drops =%d\n", wifi->stats.hal_ext_ptr_null_cnt); + seq_printf(m, "rpu_int_drops =%d\n", + wifi->stats.hal_int_ptr_null_cnt); + seq_printf(m, "rpu_deagg_drops =%d\n", + wifi->stats.deagg_bufOverFlow_cnt); return 0; @@ -4488,6 +4490,8 @@ static ssize_t proc_write_config(struct file *file, #endif } else if (param_get_val(buf, "fw_loading=", &val)) { wifi->params.fw_loading = val; + } else if (param_get_val(buf, "axd_event=", &val)) { + hal_ops.update_axd_timestamps(); } else if (param_get_val(buf, "bt_state=", &val)) { if (dev->state != STARTED) { pr_err("Interface is not initialized\n"); @@ -4678,7 +4682,7 @@ static int proc_init(struct proc_dir_entry ***main_dir_entry) wifi->params.max_tx_cmds = MAX_SUBFRAMES_IN_AMPDU_HT; wifi->params.disable_power_save = 0; wifi->params.disable_sm_power_save = 0; - wifi->params.rate_protection_type = 0; /* Disable protection by def */ + wifi->params.rate_protection_type = 1; wifi->params.prod_mode_rate_preamble_type = 1; /* LONG */ wifi->params.prod_mode_stbc_enabled = 0; wifi->params.prod_mode_bcc_or_ldpc = 0; diff --git a/src/core.c b/src/core.c index b5bfb35..7d0b28b 100644 --- a/src/core.c +++ b/src/core.c @@ -1044,6 +1044,7 @@ void uccp420wlan_mac_stats(struct umac_event_mac_stats *mac_stats, dev->stats->rx_circular_buffer_free_cnt = mac_stats->rx_circular_buffer_free_cnt; dev->stats->rx_mic_fail_cnt = mac_stats->rx_mic_fail_cnt; + dev->stats->deagg_bufOverFlow_cnt = mac_stats->deagg_bufOverFlow_cnt; /* HAL related */ dev->stats->hal_cmd_cnt = mac_stats->hal_cmd_cnt; diff --git a/src/hal_hostport.c b/src/hal_hostport.c index 32f680e..5633d23 100644 --- a/src/hal_hostport.c +++ b/src/hal_hostport.c @@ -46,6 +46,8 @@ #include "fwldr.h" #include "hal.h" #include "hal_hostport.h" +#include "rpu.h" +#include "soc.h" #define COMMAND_START_MAGIC 0xDEAD @@ -74,6 +76,8 @@ unsigned int alloc_skb_priv_rx_region; unsigned int alloc_skb_priv_runtime; static unsigned int uccp_ddr_base; +static unsigned int phys_64mb; +static void __iomem *sixfour_mb_base; #ifdef PERF_PROFILING /* The timing markers */ @@ -303,9 +307,9 @@ static int hal_ready(struct hal_priv *priv) unsigned int value = 0; /* Check the ACK register bit */ - value = readl((void __iomem *)(HOST_TO_UCCP_CORE_CMD_ADDR)); + value = readl((void __iomem *)(HOST_TO_MTX_CMD_ADDR)); - if (value & BIT(UCCP_CORE_HOST_INT_SHIFT)) + if (value & BIT(MTX_HOST_INT_SHIFT)) return 0; else return 1; @@ -363,7 +367,7 @@ static void tx_tasklet_fn(unsigned long data) start_addr += ((priv->gram_mem_addr)-(priv->shm_offset)); if ((start_addr < priv->gram_mem_addr) || - (start_addr > (priv->gram_mem_addr + HAL_WLAN_GRAM_LEN))) { + (start_addr > (priv->gram_mem_addr + HAL_UCCP_GRAM_LEN))) { pr_err("%s: Invalid cmd addr 0x%08x, dropping cmd\n", hal_name, (unsigned int)start_addr); dev_kfree_skb_any(skb); @@ -377,7 +381,7 @@ static void tx_tasklet_fn(unsigned long data) value = (unsigned int) (priv->cmd_cnt); value |= 0x7fff0000; - writel(value, (void __iomem *)(HOST_TO_UCCP_CORE_CMD_ADDR)); + writel(value, (void __iomem *)(HOST_TO_MTX_CMD_ADDR)); priv->cmd_cnt++; hal_cmd_sent++; @@ -819,7 +823,7 @@ static irqreturn_t hal_irq_handler(int irq, void *p) spurious = 0; - value = readl((void __iomem *)(UCCP_CORE_TO_HOST_CMD_ADDR)) & + value = readl((void __iomem *)(MTX_TO_HOST_CMD_ADDR)) & 0x7fffffff; if (value == (0x7fff0000 | priv->event_cnt)) { #ifdef PERF_PROFILING @@ -907,9 +911,9 @@ static irqreturn_t hal_irq_handler(int irq, void *p) if (!spurious) { /* Clear the uccp interrupt */ value = 0; - value |= BIT(UCCP_CORE_INT_CLR_SHIFT); + value |= BIT(MTX_INT_CLR_SHIFT); writel(*((unsigned long *)&(value)), - (void __iomem *)(HOST_TO_UCCP_CORE_ACK_ADDR)); + (void __iomem *)(HOST_TO_MTX_ACK_ADDR)); } else { pr_warn("%s: Spurious interrupt received\n", hal_name); @@ -942,17 +946,17 @@ static void hal_enable_int(void *p) unsigned int value = 0; /* Set external pin irq enable for host_irq and uccp_irq */ - value = readl((void __iomem *)UCCP_CORE_INT_ENAB_ADDR); - value |= BIT(UCCP_CORE_INT_IRQ_ENAB_SHIFT); + value = readl((void __iomem *)SYS_INT_ENAB_ADDR); + value |= BIT(SYS_INT_MTX_IRQ_ENAB_SHIFT); writel(*((unsigned long *)&(value)), - (void __iomem *)(UCCP_CORE_INT_ENAB_ADDR)); + (void __iomem *)(SYS_INT_ENAB_ADDR)); /* Enable raising uccp_int when UCCP_INT = 1 */ value = 0; - value |= BIT(UCCP_CORE_INT_EN_SHIFT); + value |= BIT(MTX_INT_EN_SHIFT); writel(*((unsigned long *)&(value)), - (void __iomem *)(UCCP_CORE_INT_ENABLE_ADDR)); + (void __iomem *)(MTX_INT_ENABLE_ADDR)); } @@ -961,16 +965,16 @@ static void hal_disable_int(void *p) unsigned int value = 0; /* Reset external pin irq enable for host_irq and uccp_irq */ - value = readl((void __iomem *)UCCP_CORE_INT_ENAB_ADDR); - value &= ~(BIT(UCCP_CORE_INT_IRQ_ENAB_SHIFT)); + value = readl((void __iomem *)SYS_INT_ENAB_ADDR); + value &= ~(BIT(SYS_INT_MTX_IRQ_ENAB_SHIFT)); writel(*((unsigned long *)&(value)), - (void __iomem *)(UCCP_CORE_INT_ENAB_ADDR)); + (void __iomem *)(SYS_INT_ENAB_ADDR)); /* Disable raising uccp_int when UCCP_INT = 1 */ value = 0; - value &= ~(BIT(UCCP_CORE_INT_EN_SHIFT)); + value &= ~(BIT(MTX_INT_EN_SHIFT)); writel(*((unsigned long *)&(value)), - (void __iomem *)(UCCP_CORE_INT_ENABLE_ADDR)); + (void __iomem *)(MTX_INT_ENABLE_ADDR)); } @@ -1445,8 +1449,30 @@ struct platform_driver img_uccp_driver = { }, }; +static unsigned int hal_get_axd_buf_phy_addr(void) +{ + return (phys_64mb + AXD_BUF_ADDR + 0xa0000000); +} +static int hal_update_axd_timestamps(void) +{ + unsigned int *addr = (unsigned int *)HAL_AXD_DATA_START; + unsigned long long t; + unsigned int ts; + if (atu_get_cur_timestamps) { + if (atu_get_cur_timestamps(&t, &ts) < 0) + return -1; + } else { + return -1; + } + *addr = STREAM_SYNC_MAGIC_NUM; + *(addr + 1) = phys_64mb - (unsigned int)sixfour_mb_base + AXD_BUF_ADDR; + *((unsigned long long *)(addr + 2)) = t; + *(addr + 4) = ts; + + return 0; +} static int hal_deinit(void *dev) { @@ -1485,8 +1511,6 @@ static int hal_init(void *dev) int err = 0; unsigned int value = 0; unsigned char *rpusocwrap; - void __iomem *sixfour_mb_base; - unsigned int phys_64mb; (void) (dev); @@ -1589,7 +1613,6 @@ static int hal_init(void *dev) */ sixfour_mb_base = get_base_address_64mb(phys_64mb); - rpusocwrap = (unsigned char *)(hpriv->uccp_sysbus_base_addr + 0x38000); value = ((unsigned int)sixfour_mb_base) / (4 * 1024); @@ -2130,6 +2153,8 @@ struct hal_ops_tag hal_ops = { .get_dump_perip = hal_get_dump_perip, .get_dump_sysbus = hal_get_dump_sysbus, .get_dump_len = hal_get_dump_len, + .update_axd_timestamps = hal_update_axd_timestamps, + .get_axd_buf_phy_addr = hal_get_axd_buf_phy_addr, }; #ifdef CONFIG_PM diff --git a/src/hal_hostport.h b/src/hal_hostport.h deleted file mode 100644 index 0f7419f..0000000 --- a/src/hal_hostport.h +++ /dev/null @@ -1,275 +0,0 @@ -/* - * File Name : hal_hostport.h - * - * This file contains the definitions specific to HOSPORT comms - * - * Copyright (c) 2011, 2012, 2013, 2014 Imagination Technologies Ltd. - * All rights reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - */ - -#ifndef _UCCP420WLAN_HAL_HOSTPORT_H_ -#define _UCCP420WLAN_HAL_HOSTPORT_H_ - -#include -#include - -#include - -#define _PACKED_ __attribute__((__packed__)) - -#define MAX_RX_BUF_PTR_PER_CMD (16) -#define MAX_DATA_SIZE_12K (12 * 1024) -#define MAX_DATA_SIZE_8K (8 * 1024) -#define MAX_DATA_SIZE_2K (2 * 1024) - -#define NUM_TX_DESC 12 -#define NUM_FRAMES_IN_TX_DESC 32 -#define NUM_BYTES_PER_FRAME 9 -#define TX_DESC_HAL_SIZE (NUM_FRAMES_IN_TX_DESC * NUM_BYTES_PER_FRAME) - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -struct buf_info { - dma_addr_t dma_buf; - void __iomem *src_ptr; - unsigned int dma_buf_len; - unsigned int dma_buf_priv; /* Is the DMA buffer in our private area */ - struct sk_buff *skb; -} _PACKED_; - -struct hal_tx_data { - unsigned int data_len:24; - unsigned long address:24; - unsigned long offset:24; -} _PACKED_; - -struct hal_priv { - /* UCCP Host RAM mappings*/ - void __iomem *base_addr_uccp_host_ram; - void __iomem *tx_base_addr_uccp_host_ram; - void __iomem *rx_base_addr_uccp_host_ram; - - /* UCCP and GRAM mappings */ - unsigned long uccp_mem_addr; - unsigned long gram_mem_addr; - unsigned long uccp_sysbus_base_addr; - unsigned long uccp_perip_base_addr; - unsigned long gram_base_addr; - unsigned long shm_offset; - unsigned long hal_disabled; - unsigned long gram_b4_addr; - - /* DTS entries */ - unsigned long uccp_sysbus_base; - unsigned long uccp_sysbus_len; /* HAL_HOST_UCCP_LEN */ - unsigned long uccp_perip_base; /* HAL_PERIP_BASE */ - unsigned long uccp_perip_len; /* HOST_PERIP_BASE_LEN */ - unsigned long uccp_pkd_gram_base; - unsigned long uccp_pkd_gram_len; - unsigned long uccp_gram_base; /* b4addr */ - unsigned long uccp_gram_len; /* b4addr length */ - - /* TX */ - struct sk_buff_head txq; - struct tasklet_struct tx_tasklet; - unsigned short cmd_cnt; - struct buf_info *tx_buf_info; - struct hal_tx_data *hal_tx_data; - - /* RX */ - struct sk_buff_head rxq; - struct tasklet_struct rx_tasklet; - struct tasklet_struct recv_tasklet; - unsigned short event_cnt; - msg_handler rcv_handler; - struct buf_info *rx_buf_info; - - /* Buffers info from IF layer*/ - unsigned int tx_bufs; - unsigned int rx_bufs_2k; - unsigned int rx_bufs_12k; - unsigned int max_data_size; - - /* Temp storage to refill first and process next*/ - struct sk_buff_head refillq; - int irq; - /* physical address mapping for address */ - unsigned long wifi_t0_addr; - unsigned long wifi_t1_addr; -}; - -struct hal_hdr { - /*! 0xffffffff - hal command or hal event - * 0x0 - lmac command or lmac event - */ - unsigned int id; - /*! Data pointer of commands with payload - * this field is valid only if descriptor id - * of command header is set to some value - * other. - */ - unsigned int data_ptr; -} _PACKED_; - -struct hal_rx_pkt_info { - /* Rx descriptor */ - unsigned int desc; - unsigned int ptr; -} _PACKED_; - -struct hal_rx_command { - unsigned int rx_pkt_cnt; - struct hal_rx_pkt_info rx_pkt[MAX_RX_BUF_PTR_PER_CMD]; -} _PACKED_; - -struct cmd_hal { - struct hal_hdr hdr; - struct hal_rx_command rx_pkt_data; -} _PACKED_; - -struct event_hal { - struct hal_hdr hdr; - unsigned int rx_pkt_cnt; - unsigned int rx_pkt_desc[16]; -} _PACKED_; - - -int _uccp420wlan_80211if_init(struct proc_dir_entry **); -void _uccp420wlan_80211if_exit(void); - -/*Porting information: - * HAL_UCCP_IRQ_LINE: This is the interrupt number assigned to UCCP host port - * interrupt. - * HAL_HOST_UCCP_RAM_START: This is the physical address of the start of - * Host RAM which is reserved for UCCP - * HAL_HOST_ZONE_DMA_START: This is the physical address of the start of 64MB - * ZONE_DMA area which is currently assigned a dummy - * value of 0xABABABAB. TSB needs to provide the actual - * value for this. - * - * These are the only values which need to be modified as per host memory - * map and interrupt configuration. - * The values for HAL_SHARED_MEM_OFFSET, HAL_WLAN_GRAM_LEN, HAL_COMMAND_OFFSET, - * and HAL_EVENT_OFFSET can be changed by IMG in future software releases. - */ - -#define HAL_HOST_UCCP_LEN 0x0003E800 -#define HAL_UCCP_GRAM_BASE 0xB7000000 - -#define HAL_UCCP_CORE_REG_OFFSET 0x400 - -/* Register HOST_TO_UCCP_CORE_CMD */ -#define HOST_TO_UCCP_CORE_CMD 0x0030 -#define HOST_TO_UCCP_CORE_CMD_ADDR ((hpriv->uccp_mem_addr) + \ - HOST_TO_UCCP_CORE_CMD) -#define UCCP_CORE_HOST_INT_SHIFT 31 - -/* Register UCCP_CORE_TO_HOST_CMD */ -#define UCCP_CORE_TO_HOST_CMD 0x0034 -#define UCCP_CORE_TO_HOST_CMD_ADDR ((hpriv->uccp_mem_addr) + \ - UCCP_CORE_TO_HOST_CMD) - -/* Register HOST_TO_UCCP_CORE_ACK */ -#define HOST_TO_UCCP_CORE_ACK 0x0038 -#define HOST_TO_UCCP_CORE_ACK_ADDR ((hpriv->uccp_mem_addr) + \ - HOST_TO_UCCP_CORE_ACK) -#define UCCP_CORE_INT_CLR_SHIFT 31 - -/* Register UCCP_CORE_TO_HOST_ACK */ -#define UCCP_CORE_TO_HOST_ACK 0x003C -#define UCCP_CORE_TO_HOST_ACK_ADDR ((hpriv->uccp_mem_addr) + \ - UCCP_CORE_TO_HOST_ACK) - -/* Register UCCP_CORE_INT_ENABLE */ -#define UCCP_CORE_INT_ENABLE 0x0044 -#define UCCP_CORE_INT_ENABLE_ADDR ((hpriv->uccp_mem_addr) + \ - UCCP_CORE_INT_ENABLE) -#define UCCP_CORE_INT_EN_SHIFT 31 - -#define UCCP_CORE_INT_ENAB 0x0000 -#define UCCP_CORE_INT_ENAB_ADDR ((hpriv->uccp_mem_addr) + UCCP_CORE_INT_ENAB) -#define UCCP_CORE_INT_IRQ_ENAB_SHIFT 15 - -/******************************************************************************/ -#define HAL_SHARED_MEM_OFFSET 0x45ffc -#define HAL_SHARED_MEM_MAX_MSG_SIZE 60 -#define HAL_WLAN_GRAM_LEN 0x1eac0 - -/* Command, Event, Tx Data and Buff mappping offsets */ -#define HAL_COMMAND_OFFSET (0) -#define HAL_EVENT_OFFSET (HAL_COMMAND_OFFSET + HAL_SHARED_MEM_MAX_MSG_SIZE) -#define HAL_TX_DATA_OFFSET (HAL_EVENT_OFFSET + HAL_SHARED_MEM_MAX_MSG_SIZE) - -#define HAL_GRAM_CMD_START ((hpriv->gram_mem_addr) + HAL_COMMAND_OFFSET) -#define HAL_GRAM_EVENT_START ((hpriv->gram_mem_addr) + HAL_EVENT_OFFSET) -#define HAL_GRAM_TX_DATA_START ((hpriv->gram_mem_addr) + HAL_TX_DATA_OFFSET) - -#define HAL_GRAM_CMD_LEN (HAL_GRAM_CMD_START + 8) -#define HAL_GRAM_TX_DATA_LEN (HAL_GRAM_TX_DATA_START + 0) -#define HAL_GRAM_TX_DATA_OFFSET (HAL_GRAM_TX_DATA_START + 3) -#define HAL_GRAM_TX_DATA_ADDR (HAL_GRAM_TX_DATA_START + 6) - -#define HAL_HOST_BOUNCE_BUF_LEN (4 * 1024 * 1024) -#define HAL_HOST_NON_BOUNCE_BUF_LEN (60 * 1024 * 1024) - -/* Shift the amount of movement of each the offset */ - -/* 32bit - valid offset 8bit - start pos 0bit*/ -#define WLN_CGN_HOST_SYS_ADDR_SHIFT (24) - -#define HAL_HOST_ZONE_DMA_START 0xABABABAB -#define HAL_HOST_ZONE_DMA_LEN (64 * 1024 * 1024) - -/*RPU DUMP Regions and Commands*/ -#define UCCP_REGION_TYPE_COREA 0 -#define UCCP_REGION_TYPE_COREB 1 - -/* fwldr.c converts these to HOST addresses - * so pass RPU addresses here. - * From: uccrunTime/Platform/configs - */ -#define UCCP_COREA_REGION_START 0x80880000 -#define UCCP_COREA_REGION_LEN 0x4C000 - -#define UCCP_COREB_REGION_START 0x82000000 -#define UCCP_COREB_REGION_LEN 0x4C000 - -/* Interrupt number assigned to UCCP host port interrupt */ -#define HAL_IRQ_LINE 74 - -enum hal_rpu_testmode_cmd { - HAL_RPU_TM_CMD_ALL = 0, - HAL_RPU_TM_CMD_GRAM = 1, - HAL_RPU_TM_CMD_COREA = 2, - HAL_RPU_TM_CMD_COREB = 3, - HAL_RPU_TM_CMD_PERIP = 4, - HAL_RPU_TM_CMD_SYSBUS = 5, -}; - -int reset_hal_params(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus */ - -#endif /* _UCCP420WLAN_HAL_HOSTPORT_H_ */ - -/* EOF */ diff --git a/src/umac_if.c b/src/umac_if.c index a0949e0..7ae2161 100644 --- a/src/umac_if.c +++ b/src/umac_if.c @@ -425,13 +425,6 @@ static void get_rate(struct sk_buff *skb, else prot_type = USE_PROTECTION_NONE; - if (txcmd->aggregate_mpdu == AMPDU_AGGR_ENABLED) - prot_type = USE_PROTECTION_RTS; - - if (c->control.rates[index].flags & - IEEE80211_TX_RC_40_MHZ_WIDTH) - prot_type = USE_PROTECTION_RTS; - /*RTS threshold: Check for PSDU length * Need to add all HW added lenghts to skb, * sw added lengths are already part of skb->len @@ -457,10 +450,6 @@ static void get_rate(struct sk_buff *skb, } - /*No 3rd party device is using this, so disable for now*/ - if (txcmd->rate_flags[index] & ENABLE_VHT_FORMAT) - prot_type = USE_PROTECTION_NONE; - txcmd->rate_protection_type[index] = prot_type;