1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2005-2014, 2018-2021, 2023 Intel Corporation
4 * Copyright (C) 2015 Intel Mobile Communications GmbH
6 #include <linux/types.h>
7 #include <linux/slab.h>
8 #include <linux/export.h>
10 #include "iwl-modparams.h"
11 #include "iwl-nvm-utils.h"
13 int iwl_init_sband_channels(struct iwl_nvm_data
*data
,
14 struct ieee80211_supported_band
*sband
,
15 int n_channels
, enum nl80211_band band
)
17 struct ieee80211_channel
*chan
= &data
->channels
[0];
20 while (idx
< n_channels
&& chan
->band
!= band
)
21 chan
= &data
->channels
[++idx
];
23 sband
->channels
= &data
->channels
[idx
];
25 while (idx
< n_channels
&& chan
->band
== band
) {
26 chan
= &data
->channels
[++idx
];
30 sband
->n_channels
= n
;
34 IWL_EXPORT_SYMBOL(iwl_init_sband_channels
);
36 #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
37 #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
39 void iwl_init_ht_hw_capab(struct iwl_trans
*trans
,
40 struct iwl_nvm_data
*data
,
41 struct ieee80211_sta_ht_cap
*ht_info
,
42 enum nl80211_band band
,
43 u8 tx_chains
, u8 rx_chains
)
45 const struct iwl_cfg
*cfg
= trans
->cfg
;
48 tx_chains
= hweight8(tx_chains
);
49 if (cfg
->rx_with_siso_diversity
)
52 rx_chains
= hweight8(rx_chains
);
54 if (!(data
->sku_cap_11n_enable
) ||
55 (iwlwifi_mod_params
.disable_11n
& IWL_DISABLE_HT_ALL
) ||
57 ht_info
->ht_supported
= false;
61 if (data
->sku_cap_mimo_disabled
)
64 ht_info
->ht_supported
= true;
65 ht_info
->cap
= IEEE80211_HT_CAP_DSSSCCK40
;
67 if (cfg
->ht_params
->stbc
) {
68 ht_info
->cap
|= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT
);
71 ht_info
->cap
|= IEEE80211_HT_CAP_TX_STBC
;
74 if (cfg
->ht_params
->ldpc
)
75 ht_info
->cap
|= IEEE80211_HT_CAP_LDPC_CODING
;
77 if (trans
->trans_cfg
->mq_rx_supported
||
78 iwlwifi_mod_params
.amsdu_size
>= IWL_AMSDU_8K
)
79 ht_info
->cap
|= IEEE80211_HT_CAP_MAX_AMSDU
;
81 ht_info
->ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
82 ht_info
->ampdu_density
= IEEE80211_HT_MPDU_DENSITY_4
;
84 ht_info
->mcs
.rx_mask
[0] = 0xFF;
85 ht_info
->mcs
.rx_mask
[1] = 0x00;
86 ht_info
->mcs
.rx_mask
[2] = 0x00;
89 ht_info
->mcs
.rx_mask
[1] = 0xFF;
91 ht_info
->mcs
.rx_mask
[2] = 0xFF;
93 if (cfg
->ht_params
->ht_greenfield_support
)
94 ht_info
->cap
|= IEEE80211_HT_CAP_GRN_FLD
;
95 ht_info
->cap
|= IEEE80211_HT_CAP_SGI_20
;
97 max_bit_rate
= MAX_BIT_RATE_20_MHZ
;
99 if (cfg
->ht_params
->ht40_bands
& BIT(band
)) {
100 ht_info
->cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
101 ht_info
->cap
|= IEEE80211_HT_CAP_SGI_40
;
102 max_bit_rate
= MAX_BIT_RATE_40_MHZ
;
105 /* Highest supported Rx data rate */
106 max_bit_rate
*= rx_chains
;
107 WARN_ON(max_bit_rate
& ~IEEE80211_HT_MCS_RX_HIGHEST_MASK
);
108 ht_info
->mcs
.rx_highest
= cpu_to_le16(max_bit_rate
);
110 /* Tx MCS capabilities */
111 ht_info
->mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
112 if (tx_chains
!= rx_chains
) {
113 ht_info
->mcs
.tx_params
|= IEEE80211_HT_MCS_TX_RX_DIFF
;
114 ht_info
->mcs
.tx_params
|= ((tx_chains
- 1) <<
115 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT
);
118 IWL_EXPORT_SYMBOL(iwl_init_ht_hw_capab
);