wifiHal:Skip invalid channel when setting unsafe channels
When an invalid channel is present in the list of unsafe
channels, we exit function wifi_set_coex_unsafe_channels.
The commit ignores the invalid channel and allows
the function to add other unsafe channels.
CRs-Fixed: 3468916
Change-Id: I11241d2d05382d899ac6e1602fc054903d085206
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 03ae563..a6fa064 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -596,6 +596,15 @@
struct nlattr *nl_attr_unsafe_chan = NULL;
struct nlattr *unsafe_channels_attr = NULL;
hal_info *info = NULL;
+ int freq_cnt = 0;
+ u32 *freq = (u32 *) malloc(sizeof(u32) * num_channels);
+ u32 *power_cap_dbm = (u32 *) malloc(sizeof(u32) * num_channels);
+
+ if (!freq || !power_cap_dbm) {
+ ALOGE("%s: Failed to allocate memory", __FUNCTION__);
+ ret = WIFI_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
if (!handle) {
ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__);
@@ -644,6 +653,25 @@
}
ALOGD("%s: num_channels:%d, restrictions:%x", __FUNCTION__, num_channels,
restrictions);
+ for (int i = 0; i < num_channels; i++)
+ {
+ u32 frequency = get_frequency_from_channel(unsafeChannels[i].channel,
+ unsafeChannels[i].band);
+ if (frequency != 0)
+ {
+ freq[freq_cnt] = frequency;
+ power_cap_dbm[freq_cnt] = unsafeChannels[i].power_cap_dbm;
+ freq_cnt++;
+ ALOGV("%s: channel:%d, freq:%d, power_cap_dbm:%d, band:%d",
+ __FUNCTION__, unsafeChannels[i].channel, frequency,
+ unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+ }
+ else {
+ ALOGV("%s: Invalid channel found, channel:%d, power_cap_dbm:%d, band:%d",
+ __FUNCTION__, unsafeChannels[i].channel,
+ unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+ }
+ }
if (num_channels == 0) {
unsafe_channels_attr = cmd->attr_start(0);
if (!unsafe_channels_attr) {
@@ -675,61 +703,59 @@
ret = WIFI_ERROR_INVALID_ARGS;
goto cleanup;
}
- }
- for (int i = 0; i < num_channels; i++) {
- unsafe_channels_attr = cmd->attr_start(i);
- if (!unsafe_channels_attr) {
- ALOGE("%s: failed attr_start for unsafe_channels_attr of"
+
+ if(freq_cnt == 0)
+ {
+ ALOGE("%s: No valid frequency, ignore channel list", __FUNCTION__);
+ ret = WIFI_ERROR_INVALID_ARGS;
+ goto cleanup;
+ }
+ for (int i = 0; i < freq_cnt; i++) {
+ unsafe_channels_attr = cmd->attr_start(i);
+ if (!unsafe_channels_attr) {
+ ALOGE("%s: failed attr_start for unsafe_channels_attr of"
" index:%d", __FUNCTION__, i);
- ret = WIFI_ERROR_OUT_OF_MEMORY;
- goto cleanup;
- }
- u32 freq = get_frequency_from_channel(unsafeChannels[i].channel,
- unsafeChannels[i].band);
- if (!freq) {
- ALOGE("%s: Failed to get frequency of band:%d, channel:%d",
- __FUNCTION__, (int)unsafeChannels[i].band,
- unsafeChannels[i].channel);
- ret = WIFI_ERROR_INVALID_ARGS;
- goto cleanup;
- }
- ret = cmd->put_u32(
- QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, freq);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: Failed to put frequency start, ret:%d",
+ ret = WIFI_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = cmd->put_u32(
+ QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, freq[i]);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: Failed to put frequency start, ret:%d",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+ ret = cmd->put_u32(
+ QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, freq[i]);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: Failed to put frequency end, ret:%d",
__FUNCTION__, ret);
- goto cleanup;
- }
- ret = cmd->put_u32(
- QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, freq);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: Failed to put frequency end, ret:%d",
- __FUNCTION__, ret);
- goto cleanup;
- }
- /**
- * WIFI_COEX_NO_POWER_CAP (0x7FFFFFF) is specific to android
- * framework, this value denotes that framework/wifihal is not
- * providing any power cap and allow driver/firmware to operate on
- * current power cap dbm. As driver is supposed to work on with
- * LA/LE etc, we are skipping to send 0x7FFFFFF down to driver,
- * hence driver will be operating as per current power cap calculated
- * based on regulatory or other constraints.
- */
- if (unsafeChannels[i].power_cap_dbm != WIFI_COEX_NO_POWER_CAP) {
- ret = cmd->put_s32(
- QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM,
- unsafeChannels[i].power_cap_dbm);
- if (ret != WIFI_SUCCESS) {
- ALOGE("%s: Failed to put power_cap_dbm, ret:%d",
- __FUNCTION__, ret);
- goto cleanup;
- }
- }
- cmd->attr_end(unsafe_channels_attr);
- ALOGD("%s: channel:%d, freq:%d, power_cap_dbm:%d, band:%d",
- __FUNCTION__, unsafeChannels[i].channel, freq,
- unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band);
+ goto cleanup;
+ }
+ /**
+ * WIFI_COEX_NO_POWER_CAP (0x7FFFFFF) is specific to android
+ * framework, this value denotes that framework/wifihal is not
+ * providing any power cap and allow driver/firmware to operate on
+ * current power cap dbm. As driver is supposed to work on with
+ * LA/LE etc, we are skipping to send 0x7FFFFFF down to driver,
+ * hence driver will be operating as per current power cap calculated
+ * based on regulatory or other constraints.
+ */
+ if (power_cap_dbm[i] != WIFI_COEX_NO_POWER_CAP) {
+ ret = cmd->put_s32(
+ QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM,
+ power_cap_dbm[i]);
+ if (ret != WIFI_SUCCESS) {
+ ALOGE("%s: Failed to put power_cap_dbm, ret:%d",
+ __FUNCTION__, ret);
+ goto cleanup;
+ }
+ }
+ ALOGD("%s: freq:%d, power_cap_dbm:%d",
+ __FUNCTION__, freq[i], power_cap_dbm[i]);
+ cmd->attr_end(unsafe_channels_attr);
+ }
}
cmd->attr_end(nl_attr_unsafe_chan);
if (num_channels > 0) {
@@ -753,6 +779,10 @@
cleanup:
if (cmd)
delete cmd;
+ if (freq)
+ free (freq);
+ if (power_cap_dbm)
+ free (power_cap_dbm);
return ret;
}