@@ -1194,6 +1194,93 @@ int oci_from_chandef(const struct band_chandef *own, uint8_t oci[static 3])
return -ENOENT;
}
+/* Find an HT chandef for the frequency */
+int band_freq_to_ht_chandef(uint32_t freq, const struct band_freq_attrs *attr,
+ struct band_chandef *chandef)
+{
+ enum band_freq band;
+ enum band_chandef_width width;
+ unsigned int i;
+ const struct operating_class_info *best = NULL;
+
+ if (attr->disabled || !attr->supported)
+ return -EINVAL;
+
+ if (!band_freq_to_channel(freq, &band))
+ return -EINVAL;
+
+ for (i = 0; i < L_ARRAY_SIZE(e4_operating_classes); i++) {
+ const struct operating_class_info *info =
+ &e4_operating_classes[i];
+ enum band_chandef_width w;
+
+ if (e4_has_frequency(info, freq) < 0)
+ continue;
+
+ /* Any restrictions for this channel width? */
+ switch (info->channel_spacing) {
+ case 20:
+ w = BAND_CHANDEF_WIDTH_20;
+ break;
+ case 40:
+ w = BAND_CHANDEF_WIDTH_40;
+
+ /* 6GHz remove the upper/lower 40mhz channel concept */
+ if (band == BAND_FREQ_6_GHZ)
+ break;
+
+ if (info->flags & PRIMARY_CHANNEL_UPPER &&
+ attr->no_ht40_plus)
+ continue;
+
+ if (info->flags & PRIMARY_CHANNEL_LOWER &&
+ attr->no_ht40_minus)
+ continue;
+
+ break;
+ default:
+ continue;
+ }
+
+ if (!best || best->channel_spacing < info->channel_spacing) {
+ best = info;
+ width = w;
+ }
+ }
+
+ if (!best)
+ return -ENOENT;
+
+ chandef->frequency = freq;
+ chandef->channel_width = width;
+
+ /*
+ * Choose a secondary channel frequency:
+ * - 20mhz no secondary
+ * - 40mhz we can base the selection off the channel flags, either
+ * higher or lower.
+ */
+ switch (width) {
+ case BAND_CHANDEF_WIDTH_20:
+ return 0;
+ case BAND_CHANDEF_WIDTH_40:
+ if (band == BAND_FREQ_6_GHZ)
+ return 0;
+
+ if (best->flags & PRIMARY_CHANNEL_UPPER)
+ chandef->center1_frequency = freq - 10;
+ else
+ chandef->center1_frequency = freq + 10;
+
+ return 0;
+ default:
+ /* Should never happen */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
uint8_t band_freq_to_channel(uint32_t freq, enum band_freq *out_band)
{
uint32_t channel = 0;
@@ -101,6 +101,8 @@ int band_estimate_nonht_rate(const struct band *band,
const uint8_t *supported_rates,
const uint8_t *ext_supported_rates,
int32_t rssi, uint64_t *out_data_rate);
+int band_freq_to_ht_chandef(uint32_t freq, const struct band_freq_attrs *attr,
+ struct band_chandef *chandef);
int oci_to_frequency(uint32_t operating_class, uint32_t channel);