/* 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"

#include <zircon/errors.h>
#include <zircon/status.h>

static const uint8_t chspec_bw_mhz[] = {5, 10, 20, 40, 80, 160, 160};

#define WF_NUM_BW (sizeof(chspec_bw_mhz) / sizeof(uint8_t))

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;
}

// bw in MHz, return the channel count from the center channel to the the channel at the edge of the
// band
static uint8_t center_chan_to_edge(uint32_t bw) {
  // edge channels separated by BW - 10MHz on each side delta from cf to edge is half of that, MHz
  // to channel num conversion is 5MHz/channel
  return (uint8_t)(((bw - 20) / 2) / 5);
}

// return channel number of the low edge of the band given the center channel and BW
static uint8_t channel_low_edge(uint32_t center_ch, uint32_t bw) {
  return (uint8_t)(center_ch - center_chan_to_edge(bw));
}

// return control channel given center channel and side band
static uint8_t channel_to_ctl_chan(uint32_t center_ch, uint32_t bw, uint32_t sb) {
  return (uint8_t)(channel_low_edge(center_ch, bw) + sb * 4);
}

// convert bandwidth from chanspec to MHz
static uint32_t bw_chspec_to_mhz(chanspec_t chspec) {
  uint32_t bw;

  bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT;
  return (bw >= WF_NUM_BW ? 0 : chspec_bw_mhz[bw]);
}

// Return the control channel of the given chanspec.
zx_status_t chspec_ctlchan(chanspec_t chspec, uint8_t* ctrl_chan) {
  uint32_t center_chan;
  uint32_t bw_mhz;
  uint32_t sb;

  if (chspec_malformed(chspec) || ctrl_chan == nullptr)
    return ZX_ERR_INVALID_ARGS;

  // Is there a sideband ?
  if (CHSPEC_BW_LE20(chspec)) {
    *ctrl_chan = CHSPEC_CHANNEL(chspec);
  } else {
    sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT;

    if (CHSPEC_IS8080(chspec)) {
      // For an 80+80 MHz channel, the sideband 'sb' field is an 80 MHz sideband (LL, LU, UL, LU)
      // for the 80 MHz frequency segment 0.
      uint32_t chan_id = CHSPEC_CHAN1(chspec);

      bw_mhz = 80;

      // convert from channel index to channel number
      center_chan = wf_5g_80m_chans[chan_id];
    } else {
      bw_mhz = bw_chspec_to_mhz(chspec);
      center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT;
    }

    *ctrl_chan = channel_to_ctl_chan(center_chan, bw_mhz, sb);
  }
  return ZX_OK;
}
