xref: /linux/drivers/net/wireless/nxp/nxpwifi/util.h (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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