1bfcc09ddSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2bfcc09ddSBjoern A. Zeeb /*
3*d9836fb4SBjoern A. Zeeb * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
4bfcc09ddSBjoern A. Zeeb * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5bfcc09ddSBjoern A. Zeeb * Copyright (C) 2016-2017 Intel Deutschland GmbH
6bfcc09ddSBjoern A. Zeeb */
7bfcc09ddSBjoern A. Zeeb #include "iwl-drv.h"
8bfcc09ddSBjoern A. Zeeb #include "runtime.h"
9bfcc09ddSBjoern A. Zeeb #include "fw/api/commands.h"
10bfcc09ddSBjoern A. Zeeb
iwl_parse_shared_mem_22000(struct iwl_fw_runtime * fwrt,struct iwl_rx_packet * pkt)11bfcc09ddSBjoern A. Zeeb static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt,
12bfcc09ddSBjoern A. Zeeb struct iwl_rx_packet *pkt)
13bfcc09ddSBjoern A. Zeeb {
14bfcc09ddSBjoern A. Zeeb struct iwl_shared_mem_cfg *mem_cfg = (void *)pkt->data;
15bfcc09ddSBjoern A. Zeeb int i, lmac;
16bfcc09ddSBjoern A. Zeeb int lmac_num = le32_to_cpu(mem_cfg->lmac_num);
17bfcc09ddSBjoern A. Zeeb u8 api_ver = iwl_fw_lookup_notif_ver(fwrt->fw, SYSTEM_GROUP,
18bfcc09ddSBjoern A. Zeeb SHARED_MEM_CFG_CMD, 0);
19bfcc09ddSBjoern A. Zeeb
20bfcc09ddSBjoern A. Zeeb if (WARN_ON(lmac_num > ARRAY_SIZE(mem_cfg->lmac_smem)))
21bfcc09ddSBjoern A. Zeeb return;
22bfcc09ddSBjoern A. Zeeb
23bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.num_lmacs = lmac_num;
24bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.num_txfifo_entries =
25bfcc09ddSBjoern A. Zeeb ARRAY_SIZE(mem_cfg->lmac_smem[0].txfifo_size);
26bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.rxfifo2_size = le32_to_cpu(mem_cfg->rxfifo2_size);
27bfcc09ddSBjoern A. Zeeb
28bfcc09ddSBjoern A. Zeeb if (api_ver >= 4 &&
29bfcc09ddSBjoern A. Zeeb !WARN_ON_ONCE(iwl_rx_packet_payload_len(pkt) < sizeof(*mem_cfg))) {
30bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.rxfifo2_control_size =
31bfcc09ddSBjoern A. Zeeb le32_to_cpu(mem_cfg->rxfifo2_control_size);
32bfcc09ddSBjoern A. Zeeb }
33bfcc09ddSBjoern A. Zeeb
34bfcc09ddSBjoern A. Zeeb for (lmac = 0; lmac < lmac_num; lmac++) {
35bfcc09ddSBjoern A. Zeeb struct iwl_shared_mem_lmac_cfg *lmac_cfg =
36bfcc09ddSBjoern A. Zeeb &mem_cfg->lmac_smem[lmac];
37bfcc09ddSBjoern A. Zeeb
38bfcc09ddSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(lmac_cfg->txfifo_size); i++)
39bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.lmac[lmac].txfifo_size[i] =
40bfcc09ddSBjoern A. Zeeb le32_to_cpu(lmac_cfg->txfifo_size[i]);
41bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.lmac[lmac].rxfifo1_size =
42bfcc09ddSBjoern A. Zeeb le32_to_cpu(lmac_cfg->rxfifo1_size);
43bfcc09ddSBjoern A. Zeeb }
44bfcc09ddSBjoern A. Zeeb }
45bfcc09ddSBjoern A. Zeeb
iwl_parse_shared_mem(struct iwl_fw_runtime * fwrt,struct iwl_rx_packet * pkt)46bfcc09ddSBjoern A. Zeeb static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
47bfcc09ddSBjoern A. Zeeb struct iwl_rx_packet *pkt)
48bfcc09ddSBjoern A. Zeeb {
49bfcc09ddSBjoern A. Zeeb struct iwl_shared_mem_cfg_v2 *mem_cfg = (void *)pkt->data;
50bfcc09ddSBjoern A. Zeeb int i;
51bfcc09ddSBjoern A. Zeeb
52bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.num_lmacs = 1;
53bfcc09ddSBjoern A. Zeeb
54bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.num_txfifo_entries = ARRAY_SIZE(mem_cfg->txfifo_size);
55bfcc09ddSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++)
56bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.lmac[0].txfifo_size[i] =
57bfcc09ddSBjoern A. Zeeb le32_to_cpu(mem_cfg->txfifo_size[i]);
58bfcc09ddSBjoern A. Zeeb
59bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.lmac[0].rxfifo1_size =
60bfcc09ddSBjoern A. Zeeb le32_to_cpu(mem_cfg->rxfifo_size[0]);
61bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.rxfifo2_size = le32_to_cpu(mem_cfg->rxfifo_size[1]);
62bfcc09ddSBjoern A. Zeeb
63bfcc09ddSBjoern A. Zeeb /* new API has more data, from rxfifo_addr field and on */
64bfcc09ddSBjoern A. Zeeb if (fw_has_capa(&fwrt->fw->ucode_capa,
65bfcc09ddSBjoern A. Zeeb IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
66bfcc09ddSBjoern A. Zeeb BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) !=
67bfcc09ddSBjoern A. Zeeb sizeof(mem_cfg->internal_txfifo_size));
68bfcc09ddSBjoern A. Zeeb
69bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.internal_txfifo_addr =
70bfcc09ddSBjoern A. Zeeb le32_to_cpu(mem_cfg->internal_txfifo_addr);
71bfcc09ddSBjoern A. Zeeb
72bfcc09ddSBjoern A. Zeeb for (i = 0;
73bfcc09ddSBjoern A. Zeeb i < ARRAY_SIZE(fwrt->smem_cfg.internal_txfifo_size);
74bfcc09ddSBjoern A. Zeeb i++)
75bfcc09ddSBjoern A. Zeeb fwrt->smem_cfg.internal_txfifo_size[i] =
76bfcc09ddSBjoern A. Zeeb le32_to_cpu(mem_cfg->internal_txfifo_size[i]);
77bfcc09ddSBjoern A. Zeeb }
78bfcc09ddSBjoern A. Zeeb }
79bfcc09ddSBjoern A. Zeeb
iwl_get_shared_mem_conf(struct iwl_fw_runtime * fwrt)80bfcc09ddSBjoern A. Zeeb void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt)
81bfcc09ddSBjoern A. Zeeb {
82bfcc09ddSBjoern A. Zeeb struct iwl_host_cmd cmd = {
83bfcc09ddSBjoern A. Zeeb .flags = CMD_WANT_SKB,
84bfcc09ddSBjoern A. Zeeb .data = { NULL, },
85bfcc09ddSBjoern A. Zeeb .len = { 0, },
86bfcc09ddSBjoern A. Zeeb };
87bfcc09ddSBjoern A. Zeeb struct iwl_rx_packet *pkt;
88bfcc09ddSBjoern A. Zeeb int ret;
89bfcc09ddSBjoern A. Zeeb
90bfcc09ddSBjoern A. Zeeb if (fw_has_capa(&fwrt->fw->ucode_capa,
91bfcc09ddSBjoern A. Zeeb IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
92*d9836fb4SBjoern A. Zeeb cmd.id = WIDE_ID(SYSTEM_GROUP, SHARED_MEM_CFG_CMD);
93bfcc09ddSBjoern A. Zeeb else
94bfcc09ddSBjoern A. Zeeb cmd.id = SHARED_MEM_CFG;
95bfcc09ddSBjoern A. Zeeb
96bfcc09ddSBjoern A. Zeeb ret = iwl_trans_send_cmd(fwrt->trans, &cmd);
97bfcc09ddSBjoern A. Zeeb
98bfcc09ddSBjoern A. Zeeb if (ret) {
99bfcc09ddSBjoern A. Zeeb WARN(ret != -ERFKILL,
100bfcc09ddSBjoern A. Zeeb "Could not send the SMEM command: %d\n", ret);
101bfcc09ddSBjoern A. Zeeb return;
102bfcc09ddSBjoern A. Zeeb }
103bfcc09ddSBjoern A. Zeeb
104bfcc09ddSBjoern A. Zeeb pkt = cmd.resp_pkt;
105bfcc09ddSBjoern A. Zeeb if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000)
106bfcc09ddSBjoern A. Zeeb iwl_parse_shared_mem_22000(fwrt, pkt);
107bfcc09ddSBjoern A. Zeeb else
108bfcc09ddSBjoern A. Zeeb iwl_parse_shared_mem(fwrt, pkt);
109bfcc09ddSBjoern A. Zeeb
110bfcc09ddSBjoern A. Zeeb IWL_DEBUG_INFO(fwrt, "SHARED MEM CFG: got memory offsets/sizes\n");
111bfcc09ddSBjoern A. Zeeb
112bfcc09ddSBjoern A. Zeeb iwl_free_resp(&cmd);
113bfcc09ddSBjoern A. Zeeb }
114bfcc09ddSBjoern A. Zeeb IWL_EXPORT_SYMBOL(iwl_get_shared_mem_conf);
115