Search Linux Wireless

[RFC v1 098/256] cl8k: add hw.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/hw.c | 166 ++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/hw.c

diff --git a/drivers/net/wireless/celeno/cl8k/hw.c b/drivers/net/wireless/celeno/cl8k/hw.c
new file mode 100644
index 000000000000..0f7e7dcc659d
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/hw.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "hw.h"
+#include "rate_ctrl.h"
+#include <linux/spinlock.h>
+#include "reg/reg_access.h"
+
+static void cl_hw_init_tcv0(struct cl_hw *cl_hw)
+{
+       struct cl_controller_reg *controller_reg = &cl_hw->controller_reg;
+
+       cl_hw->fw_dst_kern_id = KERN_LMAC;
+       cl_hw->fw_prefix = 'l';
+
+       controller_reg->breset = LMAC_BRESET;
+       controller_reg->debug_enable = LMAC_DEBUG_ENABLE;
+       controller_reg->dreset = LMAC_DRESET;
+       controller_reg->ocd_halt_on_reset = LMAC_OCD_HALT_ON_RESET;
+       controller_reg->run_stall = LMAC_RUN_STALL;
+
+       cl_hw->mac_hw_regs_offset = 0;
+       cl_hw->phy_regs_offset = 0;
+}
+
+static void cl_hw_init_tcv1(struct cl_hw *cl_hw)
+{
+       struct cl_controller_reg *controller_reg = &cl_hw->controller_reg;
+
+       cl_hw->fw_dst_kern_id = KERN_SMAC;
+       cl_hw->fw_prefix = 's';
+
+       controller_reg->breset = SMAC_BRESET;
+       controller_reg->debug_enable = SMAC_DEBUG_ENABLE;
+       controller_reg->dreset = SMAC_DRESET;
+       controller_reg->ocd_halt_on_reset = SMAC_OCD_HALT_ON_RESET;
+       controller_reg->run_stall = SMAC_RUN_STALL;
+
+       cl_hw->mac_hw_regs_offset = REG_MAC_HW_SMAC_OFFSET;
+       cl_hw->phy_regs_offset = REG_PHY_SMAC_OFFSET;
+}
+
+void cl_hw_init(struct cl_chip *chip, struct cl_hw *cl_hw, u8 tcv_idx)
+{
+       write_lock(&chip->cl_hw_lock);
+       chip->cl_hw_lut[tcv_idx] = cl_hw;
+       write_unlock(&chip->cl_hw_lock);
+
+       if (tcv_idx == TCV0)
+               cl_hw_init_tcv0(cl_hw);
+       else
+               cl_hw_init_tcv1(cl_hw);
+}
+
+void cl_hw_deinit(struct cl_hw *cl_hw, u8 tcv_idx)
+{
+       struct cl_chip *chip = cl_hw->chip;
+
+       write_lock(&chip->cl_hw_lock);
+       chip->cl_hw_lut[tcv_idx] = NULL;
+       write_unlock(&chip->cl_hw_lock);
+}
+
+void cl_hw_lock(struct cl_hw *cl_hw)
+{
+       read_lock(&cl_hw->chip->cl_hw_lock);
+}
+
+void cl_hw_unlock(struct cl_hw *cl_hw)
+{
+       read_unlock(&cl_hw->chip->cl_hw_lock);
+}
+
+struct cl_hw *cl_hw_other_tcv(struct cl_hw *cl_hw)
+{
+       /* This function must be called after read lock is taken */
+       return cl_hw->chip->cl_hw_lut[1 - cl_hw->tcv_idx];
+}
+
+bool cl_hw_is_tcv0(struct cl_hw *cl_hw)
+{
+       return (cl_hw->tcv_idx == TCV0);
+}
+
+bool cl_hw_is_tcv1(struct cl_hw *cl_hw)
+{
+       return (cl_hw->tcv_idx == TCV1);
+}
+
+int cl_hw_set_antennas(struct cl_hw *cl_hw)
+{
+       struct cl_chip *chip = cl_hw->chip;
+       u8 ant_shift = cl_hw_ant_shift(cl_hw);
+
+       /* Set num_antennas and max_antennas + masks for both. */
+       switch (chip->fem.wiring_id) {
+       case FEM_WIRING_0_TCV0_6_TCV1_6:
+       case FEM_WIRING_1_TCV0_6_TCV1_6:
+       case FEM_WIRING_2_TCV0_6_TCV1_6:
+       case FEM_WIRING_3_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_4_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_5_TCV0_2_ELASTIC_4_TCV1_2:
+       case FEM_WIRING_6_TCV0_2_ELASTIC_4_TCV1_2:
+               cl_hw->max_antennas = 6;
+               break;
+       case FEM_WIRING_7_TCV0_4_TCV1_4:
+       case FEM_WIRING_8_TCV0_4_TCV1_4:
+       case FEM_WIRING_9_TCV0_4_TCV1_4:
+       case FEM_WIRING_10_TCV0_4_TCV1_4:
+       case FEM_WIRING_11_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_12_TCV0_4_TCV1_4_RX_ONLY:
+       case FEM_WIRING_15_CHAMELEON_4TX_4RX:
+       case FEM_WIRING_18_TCV0_4_TCV1_4:
+       case FEM_WIRING_19_TCV0_2_TCV1_2_SWAPPED:
+               cl_hw->max_antennas = 4;
+               break;
+       case FEM_WIRING_13_SENSING_4RX_2TX:
+       case FEM_WIRING_14_SENSING_4TX_2RX:
+       case FEM_WIRING_20_TCV0_4_TCV1_2:
+       case FEM_WIRING_21_TCV0_4_TCV1_2:
+               cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 4 : 2;
+               break;
+       case FEM_WIRING_17_TCV0_4_TCV1_0:
+               cl_hw->max_antennas = cl_hw_is_tcv0(cl_hw) ? 4 : 0;
+               break;
+       case FEM_WIRING_16_TCV0_2_TCV1_2:
+               cl_hw->max_antennas = 2;
+               break;
+       default:
+               if (chip->conf->ce_production_mode)
+                       cl_hw->max_antennas = chip->max_antennas / 2;
+               else
+                       return -1;
+               break;
+       }
+
+       cl_hw->num_antennas = cl_hw->conf->ce_num_antennas;
+       cl_hw->mask_num_antennas = ANT_MASK(cl_hw->num_antennas);
+       cl_hw->first_ant = ant_shift;
+       cl_hw->last_ant = cl_hw->num_antennas + ant_shift - 1;
+
+       cl_dbg_trace(cl_hw, "num_antennas = %u, max_antennas = %u\n",
+                    cl_hw->num_antennas, cl_hw->max_antennas);
+
+       if (cl_hw->num_antennas > cl_hw->max_antennas) {
+               CL_DBG_ERROR(cl_hw, "num_antennas (%u) > max_antennas (%u)\n",
+                            cl_hw->num_antennas, cl_hw->max_antennas);
+               return -1;
+       }
+
+       return 0;
+}
+
+u8 cl_hw_ant_shift(struct cl_hw *cl_hw)
+{
+       struct cl_chip *chip = cl_hw->chip;
+
+       /* CL808x uses chains 0 - 3 for both bands */
+       if (cl_chip_is_8ant(chip))
+               return 0;
+
+       /* CL804x uses chains 0 - 1 for TCV0 and chains 2 - 3 for TCV1 */
+       /* CL806x uses chains 0 - 3 for TCV0 and chains 2 - 3 for TCV1 */
+       return cl_hw_is_tcv0(cl_hw) ? 0 : 2;
+}
+
--
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