aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/net/wireless/morsemicro/mm81x/rate_code.h
blob: c60fcb9447c4abfa4891ffc4256c0c52de1f1a61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2026 Morse Micro
 */

#ifndef _MM81X_RATE_CODE_H_
#define _MM81X_RATE_CODE_H_

#include <linux/types.h>

enum dot11_bandwidth {
	DOT11_BANDWIDTH_1MHZ = 0,
	DOT11_BANDWIDTH_2MHZ = 1,
	DOT11_BANDWIDTH_4MHZ = 2,
	DOT11_BANDWIDTH_8MHZ = 3,
	DOT11_BANDWIDTH_16MHZ = 4,

	DOT11_MAX_BANDWIDTH = DOT11_BANDWIDTH_16MHZ,
	DOT11_INVALID_BANDWIDTH = 5
};

enum mm81x_rate_preamble {
	/* S1G LONG format (with SIG-A and SIG-B) */
	MM81X_RATE_PREAMBLE_S1G_LONG = 0,
	/* This is the most common format used */
	MM81X_RATE_PREAMBLE_S1G_SHORT = 1,
	/* S1G 1M format */
	MM81X_RATE_PREAMBLE_S1G_1M = 2,

	MM81X_RATE_MAX_PREAMBLE = MM81X_RATE_PREAMBLE_S1G_1M,
	MM81X_RATE_INVALID_PREAMBLE = 7
};

typedef __le32 mm81x_rate_code_t;

#define MM81X_RATECODE_PREAMBLE (0x0000000F)
#define MM81X_RATECODE_MCS_INDEX (0x000000F0)
#define MM81X_RATECODE_NSS_INDEX (0x00000700)
#define MM81X_RATECODE_BW_INDEX (0x00003800)
#define MM81X_RATECODE_RTS_FLAG (0x00010000)
#define MM81X_RATECODE_SHORT_GI_FLAG (0x00040000)
#define MM81X_RATECODE_DUP_BW_INDEX (0x01C00000)

static inline enum mm81x_rate_preamble
mm81x_ratecode_preamble_get(mm81x_rate_code_t rc)
{
	return (enum mm81x_rate_preamble)(
		le32_get_bits(rc, MM81X_RATECODE_PREAMBLE));
}

static inline u8 mm81x_ratecode_mcs_index_get(mm81x_rate_code_t rc)
{
	return le32_get_bits(rc, MM81X_RATECODE_MCS_INDEX);
}

static inline u8 mm81x_ratecode_nss_index_get(mm81x_rate_code_t rc)
{
	return le32_get_bits(rc, MM81X_RATECODE_NSS_INDEX);
}

static inline enum dot11_bandwidth
mm81x_ratecode_bw_index_get(mm81x_rate_code_t rc)
{
	return (enum dot11_bandwidth)(
		le32_get_bits(rc, MM81X_RATECODE_BW_INDEX));
}

static inline bool mm81x_ratecode_rts_get(mm81x_rate_code_t rc)
{
	return le32_get_bits(rc, MM81X_RATECODE_RTS_FLAG);
}

static inline bool mm81x_ratecode_sgi_get(mm81x_rate_code_t rc)
{
	return le32_get_bits(rc, MM81X_RATECODE_SHORT_GI_FLAG);
}

static inline enum dot11_bandwidth
mm81x_ratecode_dup_bw_index_get(mm81x_rate_code_t rc)
{
	return (enum dot11_bandwidth)(
		le32_get_bits(rc, MM81X_RATECODE_DUP_BW_INDEX));
}

#define MM81X_RATECODE_INIT(bw_idx, nss_idx, mcs_idx, preamble)  \
	(le32_encode_bits((bw_idx), MM81X_RATECODE_BW_INDEX) |   \
	 le32_encode_bits((nss_idx), MM81X_RATECODE_NSS_INDEX) | \
	 le32_encode_bits((mcs_idx), MM81X_RATECODE_MCS_INDEX) | \
	 le32_encode_bits((preamble), MM81X_RATECODE_PREAMBLE))

static inline mm81x_rate_code_t
mm81x_ratecode_init(enum dot11_bandwidth bw_index, u32 nss_index, u32 mcs_index,
		    enum mm81x_rate_preamble preamble)
{
	return MM81X_RATECODE_INIT(bw_index, nss_index, mcs_index, preamble);
}

static inline void
mm81x_ratecode_preamble_set(mm81x_rate_code_t *rc,
			    enum mm81x_rate_preamble preamble)
{
	*rc = (*rc & cpu_to_le32(~MM81X_RATECODE_PREAMBLE)) |
	      le32_encode_bits(preamble, MM81X_RATECODE_PREAMBLE);
}

static inline void mm81x_ratecode_mcs_index_set(mm81x_rate_code_t *rc,
						u32 mcs_index)
{
	*rc = (*rc & cpu_to_le32(~MM81X_RATECODE_MCS_INDEX)) |
	      le32_encode_bits(mcs_index, MM81X_RATECODE_MCS_INDEX);
}

static inline void mm81x_ratecode_nss_index_set(mm81x_rate_code_t *rc,
						u32 nss_index)
{
	*rc = (*rc & cpu_to_le32(~MM81X_RATECODE_NSS_INDEX)) |
	      le32_encode_bits(nss_index, MM81X_RATECODE_NSS_INDEX);
}

static inline void mm81x_ratecode_bw_index_set(mm81x_rate_code_t *rc,
					       enum dot11_bandwidth bw_index)
{
	*rc = (*rc & cpu_to_le32(~MM81X_RATECODE_BW_INDEX)) |
	      le32_encode_bits(bw_index, MM81X_RATECODE_BW_INDEX);
}

static inline void
mm81x_ratecode_update_s1g_bw_preamble(mm81x_rate_code_t *rc,
				      enum dot11_bandwidth bw_index)
{
	enum mm81x_rate_preamble pream = MM81X_RATE_PREAMBLE_S1G_SHORT;

	if (bw_index == DOT11_BANDWIDTH_1MHZ)
		pream = MM81X_RATE_PREAMBLE_S1G_1M;

	mm81x_ratecode_preamble_set(rc, pream);
	mm81x_ratecode_bw_index_set(rc, bw_index);
}

static inline void
mm81x_ratecode_dup_bw_index_set(mm81x_rate_code_t *rc,
				enum dot11_bandwidth dup_bw_index)
{
	*rc = (*rc & cpu_to_le32(~MM81X_RATECODE_DUP_BW_INDEX)) |
	      le32_encode_bits(dup_bw_index, MM81X_RATECODE_DUP_BW_INDEX);
}

static inline void mm81x_ratecode_enable_rts(mm81x_rate_code_t *rc)
{
	*rc |= cpu_to_le32(MM81X_RATECODE_RTS_FLAG);
}

static inline void mm81x_ratecode_enable_sgi(mm81x_rate_code_t *rc)
{
	*rc |= cpu_to_le32(MM81X_RATECODE_SHORT_GI_FLAG);
}

static inline enum dot11_bandwidth mm81x_ratecode_bw_mhz_to_bw_index(u8 bw_mhz)
{
	return ((bw_mhz == 1) ? DOT11_BANDWIDTH_1MHZ :
		(bw_mhz == 2) ? DOT11_BANDWIDTH_2MHZ :
		(bw_mhz == 4) ? DOT11_BANDWIDTH_4MHZ :
		(bw_mhz == 8) ? DOT11_BANDWIDTH_8MHZ :
				DOT11_BANDWIDTH_2MHZ);
}

static inline u8
mm81x_ratecode_bw_index_to_s1g_bw_mhz(enum dot11_bandwidth bw_idx)
{
	return ((bw_idx == DOT11_BANDWIDTH_1MHZ) ? 1 :
		(bw_idx == DOT11_BANDWIDTH_2MHZ) ? 2 :
		(bw_idx == DOT11_BANDWIDTH_4MHZ) ? 4 :
		(bw_idx == DOT11_BANDWIDTH_8MHZ) ? 8 :
						   2);
}

#endif