blob: e85883ecdaac4e80b2afd6f77480498291a910c0 [file] [log] [blame]
/* Crossdriver (bcmdhd/brcmfmac) logic extracted from bcmdhd bcmwifi_channels.c.
*
* Copyright 1999-2016, Broadcom Corporation
* All rights reserved,
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* This software is provided by the copyright holder "as is" and any express or
* implied warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose are disclaimed. In no event
* shall copyright holder be liable for any direct, indirect, incidental, special,
* exemplary, or consequential damages (including, but not limited to, procurement
* of substitute goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether in
* contract, strict liability, or tort (including negligence or otherwise) arising
* in any way out of the use of this software, even if advised of the possibility
* of such damage
*/
#include "bcmwifi_channels.h"
bool chspec_malformed(chanspec_t chanspec) {
uint16_t chspec_bw = CHSPEC_BW(chanspec);
uint16_t chspec_ch = CHSPEC_CHANNEL(chanspec);
/* must be 2G or 5G band */
if (CHSPEC_IS2G(chanspec)) {
/* must be valid bandwidth */
if (!BW_LE40(chspec_bw)) {
return true;
}
} else if (CHSPEC_IS5G(chanspec)) {
if (chspec_bw == WL_CHANSPEC_BW_8080) {
uint16_t ch1_id, ch2_id;
/* channel IDs in 80+80 must be in range */
ch1_id = CHSPEC_CHAN1(chanspec);
ch2_id = CHSPEC_CHAN2(chanspec);
if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS)
return true;
} else if (BW_LE160(chspec_bw)) {
if (chspec_ch > MAXCHANNEL) {
return true;
}
} else {
/* invalid bandwidth */
return true;
}
} else {
/* must be 2G or 5G band */
return true;
}
/* side band needs to be consistent with bandwidth */
if (BW_LE20(chspec_bw)) {
if (CHSPEC_CTL_SB(chanspec) != WL_CHANSPEC_CTL_SB_LLL)
return true;
} else if (chspec_bw == WL_CHANSPEC_BW_40) {
if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LLU)
return true;
} else if (chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_8080) {
if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LUU)
return true;
} else if (chspec_bw == WL_CHANSPEC_BW_160) {
// This condition was originally an assertion, which is inverted here.
// Assertion was: ASSERT(CHSPEC_CTL_SB(chanspec) <= WL_CHANSPEC_CTL_SB_UUU);
if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_UUU) {
return true;
}
}
return false;
}