Search Linux Wireless

[RFC v1 042/256] cl8k: add chip.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Viktor Barna <viktor.barna@xxxxxxxxxx>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx>
---
 drivers/net/wireless/celeno/cl8k/chip.c | 241 ++++++++++++++++++++++++
 1 file changed, 241 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/chip.c

diff --git a/drivers/net/wireless/celeno/cl8k/chip.c b/drivers/net/wireless/celeno/cl8k/chip.c
new file mode 100644
index 000000000000..5876b1da1857
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/chip.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include <linux/dmapool.h>
+#include "chip.h"
+#include "chip_config.h"
+#include "utils/utils.h"
+#include "reg/reg_access.h"
+#include "reg/reg_ipc.h"
+#include "temperature.h"
+#include "fem.h"
+#include "e2p.h"
+#include "ela.h"
+#include "utils/string.h"
+#include "main.h"
+#include "netlink.h"
+#include "data_rates.h"
+#ifdef CONFIG_CL_PCIE
+#include "bus/pci/irq.h"
+#endif
+
+#define CL_ALIGN_BOUND_64KB BIT(16)
+
+static void cl_chip_set_max_antennas(struct cl_chip *chip)
+{
+       switch (chip->pci_dev->device) {
+       case 0x8040:
+       case 0x8046:
+               chip->max_antennas = MAX_ANTENNAS_CL804X;
+               break;
+       case 0x8060:
+       case 0x8066:
+               chip->max_antennas = MAX_ANTENNAS_CL806X;
+               break;
+       case 0x8080:
+       case 0x8086:
+       default:
+               chip->max_antennas = MAX_ANTENNAS_CL808X;
+               break;
+       }
+
+       cl_dbg_chip_trace(chip, "max_antennas = %u\n", chip->max_antennas);
+}
+
+static int cl_chip_print_serial_number(struct cl_chip *chip)
+{
+       u8 serial_number[SIZE_GEN_SERIAL_NUMBER + 1] = {0};
+
+       if (cl_e2p_read(chip, (u8 *)&serial_number, SIZE_GEN_SERIAL_NUMBER, ADDR_GEN_SERIAL_NUMBER))
+               return -1;
+
+       if (strlen(serial_number) == 0)
+               CL_DBG_WARNING_CHIP(chip, "Serial-number in not set in EEPROM\n");
+       else
+               cl_dbg_chip_verbose(chip, "Serial-number = %s\n", serial_number);
+
+       return 0;
+}
+
+static int cl_chip_ring_indices_init(struct cl_chip *chip)
+{
+       struct cl_ring_indices *ring_indices = &chip->ring_indices;
+
+       ring_indices->pool = dma_pool_create("cl_ring_indices_pool", chip->dev,
+                                            (sizeof(struct cl_ipc_ring_indices) * TCV_MAX),
+                                            CL_ALIGN_BOUND_64KB, CL_ALIGN_BOUND_64KB);
+
+       if (!ring_indices->pool) {
+               cl_dbg_chip_err(chip, "ring_indices pool create failed !!!\n");
+               return -ENOMEM;
+       }
+
+       ring_indices->params = dma_pool_alloc(ring_indices->pool, GFP_KERNEL,
+                                             &ring_indices->dma_addr);
+       if (!ring_indices->params)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void cl_chip_ring_indices_deinit(struct cl_chip *chip)
+{
+       if (chip->ring_indices.params) {
+               dma_pool_free(chip->ring_indices.pool,
+                             chip->ring_indices.params,
+                             chip->ring_indices.dma_addr);
+               chip->ring_indices.params = NULL;
+       }
+
+       dma_pool_destroy(chip->ring_indices.pool);
+       chip->ring_indices.pool = NULL;
+}
+
+struct cl_chip *cl_chip_alloc(u8 idx)
+{
+       struct cl_chip *chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+
+       if (!chip)
+               return NULL;
+
+       chip->idx = idx;
+       return chip;
+}
+
+void cl_chip_dealloc(struct cl_chip *chip)
+{
+       cl_chip_config_dealloc(chip);
+       kfree(chip);
+}
+
+int cl_chip_init(struct cl_chip *chip)
+{
+       int ret = 0;
+
+       chip->agc_table_entry = U8_MAX;
+
+       spin_lock_init(&chip->isr_lock);
+       spin_lock_init(&chip->spi_lock);
+
+       rwlock_init(&chip->cl_hw_lock);
+
+       cl_chip_set_max_antennas(chip);
+
+#ifdef CONFIG_CL_PCIE
+       ret = cl_irq_request(chip);
+       if (ret)
+               return ret;
+#endif
+       ipc_host_global_int_en_set(chip, 1);
+
+       cl_temperature_init(chip);
+
+       ret = cl_e2p_init(chip);
+       if (ret) {
+               cl_dbg_chip_err(chip, "cl_e2p_init failed %d\n", ret);
+               return ret;
+       }
+
+       ret = cl_fem_init(chip);
+       if (ret)
+               return ret;
+
+       ret = cl_chip_ring_indices_init(chip);
+       if (ret)
+               return ret;
+
+       cl_chip_print_serial_number(chip);
+
+       cl_wrs_tables_global_build();
+       cl_data_rates_inverse_build();
+
+       return ret;
+}
+
+void cl_chip_deinit(struct cl_chip *chip)
+{
+       cl_chip_ring_indices_deinit(chip);
+       cl_temperature_close(chip);
+       cl_e2p_close(chip);
+       ipc_host_global_int_en_set(chip, 0);
+
+#ifdef CONFIG_CL_PCIE
+       cl_irq_free(chip);
+#endif
+}
+
+bool cl_chip_is_enabled(struct cl_chip *chip)
+{
+       return cl_chip_is_tcv0_enabled(chip) || cl_chip_is_tcv1_enabled(chip);
+}
+
+bool cl_chip_is_both_enabled(struct cl_chip *chip)
+{
+       return cl_chip_is_tcv0_enabled(chip) && cl_chip_is_tcv1_enabled(chip);
+}
+
+bool cl_chip_is_tcv_enabled(struct cl_chip *chip, u8 tcv_idx)
+{
+       return chip->conf->ce_tcv_enabled[tcv_idx];
+}
+
+bool cl_chip_is_tcv0_enabled(struct cl_chip *chip)
+{
+       return chip->conf->ce_tcv_enabled[TCV0];
+}
+
+bool cl_chip_is_tcv1_enabled(struct cl_chip *chip)
+{
+       return chip->conf->ce_tcv_enabled[TCV1];
+}
+
+void cl_chip_set_hw(struct cl_chip *chip, struct cl_hw *cl_hw)
+{
+       if (cl_hw_is_tcv0(cl_hw))
+               chip->cl_hw_tcv0 = cl_hw;
+       else
+               chip->cl_hw_tcv1 = cl_hw;
+}
+
+void cl_chip_unset_hw(struct cl_chip *chip, struct cl_hw *cl_hw)
+{
+       if (cl_hw_is_tcv0(cl_hw))
+               chip->cl_hw_tcv0 = NULL;
+       else
+               chip->cl_hw_tcv1 = NULL;
+}
+
+bool cl_chip_is_8ant(struct cl_chip *chip)
+{
+       return chip->max_antennas == MAX_ANTENNAS_CL808X;
+}
+
+bool cl_chip_is_6ant(struct cl_chip *chip)
+{
+       return chip->max_antennas == MAX_ANTENNAS_CL806X;
+}
+
+bool cl_chip_is_4ant(struct cl_chip *chip)
+{
+       return chip->max_antennas == MAX_ANTENNAS_CL804X;
+}
+
+static u16 cl_chip_get_device_id(struct cl_chip *chip)
+{
+       u16 device_id = chip->pci_dev->device;
+
+       /* If device-id is default, set it accoridng to phy-dev. */
+       if (device_id == 0x8000 || device_id == 0x8001)
+               device_id = IS_PHY_ATHOS(chip) ? 0x8086 : 0x8080;
+
+       return device_id;
+}
+
+bool cl_chip_is_6g(struct cl_chip *chip)
+{
+       u16 device_id = cl_chip_get_device_id(chip);
+       u8 band = device_id & 0xf;
+
+       return (band == 6);
+}
+
--
2.30.0

________________________________
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any retransmission, dissemination, copying or other use of, or taking of any action in reliance upon this information is prohibited. If you received this in error, please contact the sender and delete the material from any computer. Nothing contained herein shall be deemed as a representation, warranty or a commitment by Celeno. No warranties are expressed or implied, including, but not limited to, any implied warranties of non-infringement, merchantability and fitness for a particular purpose.
________________________________





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux