diff options
| -rw-r--r-- | Documentation/devicetree/bindings/net/wireless/qcom,wcn3990-wifi.txt | 16 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/snoc.c | 169 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/snoc.h | 203 |
3 files changed, 388 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,wcn3990-wifi.txt b/Documentation/devicetree/bindings/net/wireless/qcom,wcn3990-wifi.txt new file mode 100644 index 000000000000..626ca2124366 --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/qcom,wcn3990-wifi.txt @@ -0,0 +1,16 @@ +* Qualcomm Technologies, Inc. WCN3990 chipset WLAN platform Driver + +This driver adds support for the Integrated WCN3990 WLAN module, WCN3990 +is integrated 802.11ac chipset with SNOC bus interface. It also add support +for SNOC bus registration, copy engine configuration for the WCN3990 chipset, +shadow register configuration, create host to target communication interface +to interact with WLAN firmware, WLAN module interface control and data +receive(RX)/transmit(TX) control. + +Required properties: + - compatible: "qcom,wcn3990-wifi"; + +Example: + qcom,msm_ath10k@18000000 { + compatible = "qcom,wcn3990-wifi"; + }; diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c new file mode 100644 index 000000000000..8c8b6f54ee14 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -0,0 +1,169 @@ +/* Copyright (c) 2017, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include "debug.h" +#include "hif.h" +#include "htc.h" +#include "ce.h" +#include "snoc.h" +#include <soc/qcom/icnss.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +void ath10k_snoc_write32(void *ar, u32 offset, u32 value) +{ +} + +u32 ath10k_snoc_read32(void *ar, u32 offset) +{ + u32 val = 0; + return val; +} + +static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id, + struct ath10k_hif_sg_item *items, int n_items) +{ + return 0; +} + +static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) +{ + return 0; +} + +static void ath10k_snoc_hif_send_complete_check(struct ath10k *ar, u8 pipe, + int force) +{ +} + +static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar, + u16 service_id, + u8 *ul_pipe, u8 *dl_pipe) +{ + return 0; +} + +static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar, + u8 *ul_pipe, u8 *dl_pipe) +{ +} + +static void ath10k_snoc_hif_stop(struct ath10k *ar) +{ +} + +static void ath10k_snoc_hif_power_down(struct ath10k *ar) +{ +} + +static int ath10k_snoc_hif_start(struct ath10k *ar) +{ + return 0; +} + +static int ath10k_snoc_hif_power_up(struct ath10k *ar) +{ + return 0; +} + +static const struct ath10k_hif_ops ath10k_snoc_hif_ops = { + .tx_sg = ath10k_snoc_hif_tx_sg, + .start = ath10k_snoc_hif_start, + .stop = ath10k_snoc_hif_stop, + .map_service_to_pipe = ath10k_snoc_hif_map_service_to_pipe, + .get_default_pipe = ath10k_snoc_hif_get_default_pipe, + .send_complete_check = ath10k_snoc_hif_send_complete_check, + .get_free_queue_number = ath10k_snoc_hif_get_free_queue_number, + .power_up = ath10k_snoc_hif_power_up, + .power_down = ath10k_snoc_hif_power_down, + .read32 = ath10k_snoc_read32, + .write32 = ath10k_snoc_write32, +}; + +static int ath10k_snoc_probe(struct platform_device *pdev) +{ + int ret = 0; + struct ath10k *ar; + struct ath10k_snoc *ar_snoc; + enum ath10k_hw_rev hw_rev; + struct device *dev; + + dev = &pdev->dev; + hw_rev = ATH10K_HW_WCN3990; + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(37)); + ar = ath10k_core_create(sizeof(*ar_snoc), dev, ATH10K_BUS_SNOC, + hw_rev, &ath10k_snoc_hif_ops); + if (!ar) { + dev_err(dev, "failed to allocate core\n"); + return -ENOMEM; + } + ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 probed\n", __func__); + + return ret; +} + +static int ath10k_snoc_remove(struct platform_device *pdev) +{ + struct ath10k *ar = platform_get_drvdata(pdev); + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + + if (!ar) + return -EINVAL; + + if (!ar_snoc) + return -EINVAL; + + ath10k_core_destroy(ar); + ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 removed\n", __func__); + + return 0; +} + +static const struct of_device_id ath10k_snoc_dt_match[] = { + {.compatible = "qcom,wcn3990-wifi"}, + {} +}; +MODULE_DEVICE_TABLE(of, ath10k_snoc_dt_match); + +static struct platform_driver ath10k_snoc_driver = { + .probe = ath10k_snoc_probe, + .remove = ath10k_snoc_remove, + .driver = { + .name = "ath10k_snoc", + .owner = THIS_MODULE, + .of_match_table = ath10k_snoc_dt_match, + }, +}; + +static int __init ath10k_snoc_init(void) +{ + int ret; + + ret = platform_driver_register(&ath10k_snoc_driver); + if (ret) + pr_err("failed to register ath10k snoc driver: %d\n", + ret); + + return ret; +} +module_init(ath10k_snoc_init); + +static void __exit ath10k_snoc_exit(void) +{ + platform_driver_unregister(&ath10k_snoc_driver); +} +module_exit(ath10k_snoc_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices"); diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h new file mode 100644 index 000000000000..c6447e6dc9ff --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/snoc.h @@ -0,0 +1,203 @@ +/* Copyright (c) 2017, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _SNOC_H_ +#define _SNOC_H_ + +#include "hw.h" +#include "ce.h" +#include "pci.h" +#define ATH10K_SNOC_RX_POST_RETRY_MS 50 + +/* struct snoc_state: SNOC target state + * @pipe_cfg_addr: pipe configuration address + * @svc_to_pipe_map: pipe services + */ +struct snoc_state { + u32 pipe_cfg_addr; + u32 svc_to_pipe_map; +}; + +/* struct ath10k_snoc_pipe: SNOC pipe configuration + * @ath10k_ce_pipe: pipe handle + * @pipe_num: pipe number + * @hif_ce_state: pointer to ce state + * @buf_sz: buffer size + * @pipe_lock: pipe lock + * @ar_snoc: snoc private structure + * @intr: tasklet structure + */ + +struct ath10k_snoc_pipe { + struct ath10k_ce_pipe *ce_hdl; + u8 pipe_num; + struct ath10k *hif_ce_state; + size_t buf_sz; + /* protect ce info */ + spinlock_t pipe_lock; + struct ath10k_snoc *ar_snoc; + struct tasklet_struct intr; +}; + +/* struct ath10k_snoc_supp_chip: supported chip set + * @dev_id: device id + * @rev_id: revison id + */ +struct ath10k_snoc_supp_chip { + u32 dev_id; + u32 rev_id; +}; + +/* struct ath10k_snoc_info: SNOC info struct + * @v_addr: base virtual address + * @p_addr: base physical address + * @chip_id: chip id + * @chip_family: chip family + * @board_id: board id + * @soc_id: soc id + * @fw_version: fw version + */ +struct ath10k_snoc_info { + void __iomem *v_addr; + phys_addr_t p_addr; + u32 chip_id; + u32 chip_family; + u32 board_id; + u32 soc_id; + u32 fw_version; +}; + +/* struct ath10k_target_info: SNOC target info + * @target_version: target version + * @target_type: target type + * @target_revision: target revision + * @soc_version: target soc version + */ +struct ath10k_target_info { + u32 target_version; + u32 target_type; + u32 target_revision; + u32 soc_version; +}; + +/* struct ath10k_snoc: SNOC info struct + * @dev: device structure + * @ar:ath10k base structure + * @mem: mem base virtual address + * @mem_pa: mem base physical address + * @target_info: snoc target info + * @mem_len: mempry map length + * @intr_tq: rx tasklet handle + * @pipe_info: pipe info struct + * @ce_lock: protect ce structures + * @ce_states: maps ce id to ce state + * @rx_post_retry: rx buffer post processing timer + * @vaddr_rri_on_ddr: virtual address for RRI + * @is_driver_probed: flag to indicate driver state + */ +struct ath10k_snoc { + struct device *dev; + struct ath10k *ar; + void __iomem *mem; + dma_addr_t mem_pa; + struct ath10k_target_info target_info; + size_t mem_len; + struct tasklet_struct intr_tq; + struct ath10k_snoc_pipe pipe_info[CE_COUNT_MAX]; + /* protects CE info */ + spinlock_t ce_lock; + struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; + struct timer_list rx_post_retry; + u32 *vaddr_rri_on_ddr; + bool is_driver_probed; +}; + +/* struct ath10k_ce_tgt_pipe_cfg: target pipe configuration + * @pipe_num: pipe number + * @pipe_dir: pipe direction + * @nentries: entries in pipe + * @nbytes_max: pipe max size + * @flags: pipe flags + * @reserved: reserved + */ +struct ath10k_ce_tgt_pipe_cfg { + u32 pipe_num; + u32 pipe_dir; + u32 nentries; + u32 nbytes_max; + u32 flags; + u32 reserved; +}; + +/* struct ath10k_ce_svc_pipe_cfg: service pipe configuration + * @service_id: target version + * @pipe_dir: pipe direction + * @pipe_num: pipe number + */ +struct ath10k_ce_svc_pipe_cfg { + u32 service_id; + u32 pipe_dir; + u32 pipe_num; +}; + +/* struct ath10k_shadow_reg_cfg: shadow register configuration + * @ce_id: copy engine id + * @reg_offset: offset to copy engine + */ +struct ath10k_shadow_reg_cfg { + u16 ce_id; + u16 reg_offset; +}; + +/* struct ath10k_wlan_enable_cfg: wlan enable configuration + * @num_ce_tgt_cfg: no of ce target configuration + * @ce_tgt_cfg: target ce configuration + * @num_ce_svc_pipe_cfg: no of ce service configuration + * @ce_svc_cfg: ce service configuration + * @num_shadow_reg_cfg: no of shadow registers + * @shadow_reg_cfg: shadow register configuration + */ +struct ath10k_wlan_enable_cfg { + u32 num_ce_tgt_cfg; + struct ath10k_ce_tgt_pipe_cfg *ce_tgt_cfg; + u32 num_ce_svc_pipe_cfg; + struct ath10k_ce_svc_pipe_cfg *ce_svc_cfg; + u32 num_shadow_reg_cfg; + struct ath10k_shadow_reg_cfg *shadow_reg_cfg; +}; + +/* enum ath10k_driver_mode: ath10k driver mode + * @ATH10K_MISSION: mission mode + * @ATH10K_FTM: ftm mode + * @ATH10K_EPPING: epping mode + * @ATH10K_OFF: off mode + */ +enum ath10k_driver_mode { + ATH10K_MISSION, + ATH10K_FTM, + ATH10K_EPPING, + ATH10K_OFF +}; + +static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) +{ + return (struct ath10k_snoc *)ar->drv_priv; +} + +void ath10k_snoc_write32(void *ar, u32 offset, u32 value); +void ath10k_snoc_soc_write32(struct ath10k *ar, u32 addr, u32 val); +void ath10k_snoc_reg_write32(struct ath10k *ar, u32 addr, u32 val); +u32 ath10k_snoc_read32(void *ar, u32 offset); +u32 ath10k_snoc_soc_read32(struct ath10k *ar, u32 addr); +u32 ath10k_snoc_reg_read32(struct ath10k *ar, u32 addr); + +#endif /* _SNOC_H_ */ |
