1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * NXP Wireless LAN device driver: utility functions
4 *
5 * Copyright 2011-2024 NXP
6 */
7
8 #ifndef _NXPWIFI_UTIL_H_
9 #define _NXPWIFI_UTIL_H_
10 #include "fw.h"
11
12 struct nxpwifi_adapter;
13
14 struct nxpwifi_private;
15
16 struct nxpwifi_dma_mapping {
17 dma_addr_t addr;
18 size_t len;
19 };
20
21 struct nxpwifi_cb {
22 struct nxpwifi_dma_mapping dma_mapping;
23 union {
24 struct nxpwifi_rxinfo rx_info;
25 struct nxpwifi_txinfo tx_info;
26 };
27 };
28
29 /* size/addr for nxpwifi_debug_info */
30 #define item_size(n) (sizeof_field(struct nxpwifi_debug_info, n))
31 #define item_addr(n) (offsetof(struct nxpwifi_debug_info, n))
32
33 /* size/addr for struct nxpwifi_adapter */
34 #define adapter_item_size(n) (sizeof_field(struct nxpwifi_adapter, n))
35 #define adapter_item_addr(n) (offsetof(struct nxpwifi_adapter, n))
36
37 struct nxpwifi_debug_data {
38 char name[32]; /* variable/array name */
39 u32 size; /* size of the variable/array */
40 size_t addr; /* address of the variable/array */
41 int num; /* number of variables in an array */
42 };
43
NXPWIFI_SKB_RXCB(struct sk_buff * skb)44 static inline struct nxpwifi_rxinfo *NXPWIFI_SKB_RXCB(struct sk_buff *skb)
45 {
46 struct nxpwifi_cb *cb = (struct nxpwifi_cb *)skb->cb;
47
48 BUILD_BUG_ON(sizeof(struct nxpwifi_cb) > sizeof(skb->cb));
49 return &cb->rx_info;
50 }
51
NXPWIFI_SKB_TXCB(struct sk_buff * skb)52 static inline struct nxpwifi_txinfo *NXPWIFI_SKB_TXCB(struct sk_buff *skb)
53 {
54 struct nxpwifi_cb *cb = (struct nxpwifi_cb *)skb->cb;
55
56 return &cb->tx_info;
57 }
58
nxpwifi_store_mapping(struct sk_buff * skb,struct nxpwifi_dma_mapping * mapping)59 static inline void nxpwifi_store_mapping(struct sk_buff *skb,
60 struct nxpwifi_dma_mapping *mapping)
61 {
62 struct nxpwifi_cb *cb = (struct nxpwifi_cb *)skb->cb;
63
64 memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
65 }
66
nxpwifi_get_mapping(struct sk_buff * skb,struct nxpwifi_dma_mapping * mapping)67 static inline void nxpwifi_get_mapping(struct sk_buff *skb,
68 struct nxpwifi_dma_mapping *mapping)
69 {
70 struct nxpwifi_cb *cb = (struct nxpwifi_cb *)skb->cb;
71
72 memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
73 }
74
NXPWIFI_SKB_DMA_ADDR(struct sk_buff * skb)75 static inline dma_addr_t NXPWIFI_SKB_DMA_ADDR(struct sk_buff *skb)
76 {
77 struct nxpwifi_dma_mapping mapping;
78
79 nxpwifi_get_mapping(skb, &mapping);
80
81 return mapping.addr;
82 }
83
84 int nxpwifi_debug_info_to_buffer(struct nxpwifi_private *priv, char *buf,
85 struct nxpwifi_debug_info *info);
86
le16_unaligned_add_cpu(__le16 * var,u16 val)87 static inline void le16_unaligned_add_cpu(__le16 *var, u16 val)
88 {
89 put_unaligned_le16(get_unaligned_le16(var) + val, var);
90 }
91
92 /*
93 * Iterate over TLVs safely.
94 * Ensures no out-of-bound access even if firmware sends malformed data.
95 */
96 #define nxpwifi_for_each_tlv(tlv, buf, buf_len) \
97 for (tlv = (const struct nxpwifi_tlv *)(buf); \
98 (u8 *)(tlv) + sizeof(*tlv) <= (u8 *)(buf) + (buf_len) && \
99 (u8 *)(tlv) + sizeof(*tlv) + le16_to_cpu(tlv->len) <= \
100 (u8 *)(buf) + (buf_len); \
101 tlv = (const struct nxpwifi_tlv *)((u8 *)(tlv) + sizeof(*tlv) + \
102 le16_to_cpu(tlv->len)))
103
104 /* Return first TLV matching @type in given buffer. */
105 static inline const struct nxpwifi_tlv *
nxpwifi_find_tlv(u16 type,const u8 * buf,u32 buf_len)106 nxpwifi_find_tlv(u16 type, const u8 *buf, u32 buf_len)
107 {
108 const struct nxpwifi_tlv *tlv;
109
110 nxpwifi_for_each_tlv(tlv, buf, buf_len) {
111 if (le16_to_cpu(tlv->type) == type)
112 return tlv;
113 }
114
115 return NULL;
116 }
117
118 int nxpwifi_append_data_tlv(u16 id, u8 *data, int len, u8 *pos, u8 *cmd_end);
119
120 int nxpwifi_download_vdll_block(struct nxpwifi_adapter *adapter,
121 u8 *block, u16 block_len);
122
123 int nxpwifi_process_vdll_event(struct nxpwifi_private *priv,
124 struct sk_buff *skb);
125
126 u64 nxpwifi_roc_cookie(struct nxpwifi_adapter *adapter);
127
128 void nxpwifi_queue_work(struct nxpwifi_adapter *adapter,
129 struct work_struct *work);
130
131 void nxpwifi_queue_delayed_work(struct nxpwifi_adapter *adapter,
132 struct delayed_work *dwork,
133 unsigned long delay);
134
135 void nxpwifi_queue_wiphy_work(struct nxpwifi_adapter *adapter,
136 struct wiphy_work *work);
137
138 void nxpwifi_queue_delayed_wiphy_work(struct nxpwifi_adapter *adapter,
139 struct wiphy_delayed_work *dwork,
140 unsigned long delay);
141
142 /*
143 * Firmware cannot run AP and STA on different channels simultaneously,
144 * and doing so may trigger a crash. Check whether check_chan can be set
145 * safely; return true if allowed, false if another channel is already
146 * active in firmware.
147 */
148 bool nxpwifi_is_channel_setting_allowable(struct nxpwifi_private *priv,
149 struct ieee80211_channel *check_chan);
150
151 void nxpwifi_convert_chan_to_band_cfg(struct nxpwifi_private *priv,
152 u8 *band_cfg,
153 struct cfg80211_chan_def *chan_def);
154
155 #endif /* !_NXPWIFI_UTIL_H_ */
156