Commit 4439cbcd authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville

brcm80211: extend channel conversion functions for 80MHz support

The channel values used by firmware is handled using conversion functions
depending on the type of chip. These functions were already in place but
lacked proper support for 80MHz channel definitions. This patch adds the
support for that.
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: default avatarFranky Lin <frankyl@broadcom.com>
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a9a56878
...@@ -21,43 +21,81 @@ ...@@ -21,43 +21,81 @@
#include <brcmu_wifi.h> #include <brcmu_wifi.h>
#include <brcmu_d11.h> #include <brcmu_d11.h>
static void brcmu_d11n_encchspec(struct brcmu_chan *ch) static u16 d11n_sb(enum brcmu_chan_sb sb)
{ {
ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; switch (sb) {
case BRCMU_CHAN_SB_NONE:
return BRCMU_CHSPEC_D11N_SB_N;
case BRCMU_CHAN_SB_L:
return BRCMU_CHSPEC_D11N_SB_L;
case BRCMU_CHAN_SB_U:
return BRCMU_CHSPEC_D11N_SB_U;
default:
WARN_ON(1);
}
return 0;
}
switch (ch->bw) { static u16 d11n_bw(enum brcmu_chan_bw bw)
{
switch (bw) {
case BRCMU_CHAN_BW_20: case BRCMU_CHAN_BW_20:
ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N; return BRCMU_CHSPEC_D11N_BW_20;
break;
case BRCMU_CHAN_BW_40: case BRCMU_CHAN_BW_40:
return BRCMU_CHSPEC_D11N_BW_40;
default: default:
WARN_ON_ONCE(1); WARN_ON(1);
break;
} }
return 0;
}
static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
{
if (ch->bw == BRCMU_CHAN_BW_20)
ch->sb = BRCMU_CHAN_SB_NONE;
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,
0, d11n_sb(ch->sb));
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
0, d11n_bw(ch->bw));
ch->chspec &= ~BRCMU_CHSPEC_D11N_BND_MASK;
if (ch->chnum <= CH_MAX_2G_CHANNEL) if (ch->chnum <= CH_MAX_2G_CHANNEL)
ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G; ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
else else
ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G; ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
} }
static void brcmu_d11ac_encchspec(struct brcmu_chan *ch) static u16 d11ac_bw(enum brcmu_chan_bw bw)
{ {
ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; switch (bw) {
switch (ch->bw) {
case BRCMU_CHAN_BW_20: case BRCMU_CHAN_BW_20:
ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20; return BRCMU_CHSPEC_D11AC_BW_20;
break;
case BRCMU_CHAN_BW_40: case BRCMU_CHAN_BW_40:
return BRCMU_CHSPEC_D11AC_BW_40;
case BRCMU_CHAN_BW_80: case BRCMU_CHAN_BW_80:
case BRCMU_CHAN_BW_80P80: return BRCMU_CHSPEC_D11AC_BW_80;
case BRCMU_CHAN_BW_160:
default: default:
WARN_ON_ONCE(1); WARN_ON(1);
break;
} }
return 0;
}
static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
{
if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
ch->sb = BRCMU_CHAN_SB_L;
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);
brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,
0, d11ac_bw(ch->bw));
ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
if (ch->chnum <= CH_MAX_2G_CHANNEL) if (ch->chnum <= CH_MAX_2G_CHANNEL)
ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
else else
...@@ -73,6 +111,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch) ...@@ -73,6 +111,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
case BRCMU_CHSPEC_D11N_BW_20: case BRCMU_CHSPEC_D11N_BW_20:
ch->bw = BRCMU_CHAN_BW_20; ch->bw = BRCMU_CHAN_BW_20;
ch->sb = BRCMU_CHAN_SB_NONE;
break; break;
case BRCMU_CHSPEC_D11N_BW_40: case BRCMU_CHSPEC_D11N_BW_40:
ch->bw = BRCMU_CHAN_BW_40; ch->bw = BRCMU_CHAN_BW_40;
...@@ -112,6 +151,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) ...@@ -112,6 +151,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
case BRCMU_CHSPEC_D11AC_BW_20: case BRCMU_CHSPEC_D11AC_BW_20:
ch->bw = BRCMU_CHAN_BW_20; ch->bw = BRCMU_CHAN_BW_20;
ch->sb = BRCMU_CHAN_SB_NONE;
break; break;
case BRCMU_CHSPEC_D11AC_BW_40: case BRCMU_CHSPEC_D11AC_BW_40:
ch->bw = BRCMU_CHAN_BW_40; ch->bw = BRCMU_CHAN_BW_40;
...@@ -128,6 +168,25 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) ...@@ -128,6 +168,25 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
break; break;
case BRCMU_CHSPEC_D11AC_BW_80: case BRCMU_CHSPEC_D11AC_BW_80:
ch->bw = BRCMU_CHAN_BW_80; ch->bw = BRCMU_CHAN_BW_80;
ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
BRCMU_CHSPEC_D11AC_SB_SHIFT);
switch (ch->sb) {
case BRCMU_CHAN_SB_LL:
ch->chnum -= CH_30MHZ_APART;
break;
case BRCMU_CHAN_SB_LU:
ch->chnum -= CH_10MHZ_APART;
break;
case BRCMU_CHAN_SB_UL:
ch->chnum += CH_10MHZ_APART;
break;
case BRCMU_CHAN_SB_UU:
ch->chnum += CH_30MHZ_APART;
break;
default:
WARN_ON_ONCE(1);
break;
}
break; break;
case BRCMU_CHSPEC_D11AC_BW_8080: case BRCMU_CHSPEC_D11AC_BW_8080:
case BRCMU_CHSPEC_D11AC_BW_160: case BRCMU_CHSPEC_D11AC_BW_160:
......
...@@ -108,13 +108,7 @@ enum brcmu_chan_bw { ...@@ -108,13 +108,7 @@ enum brcmu_chan_bw {
}; };
enum brcmu_chan_sb { enum brcmu_chan_sb {
BRCMU_CHAN_SB_NONE = 0, BRCMU_CHAN_SB_NONE = -1,
BRCMU_CHAN_SB_L,
BRCMU_CHAN_SB_U,
BRCMU_CHAN_SB_LL,
BRCMU_CHAN_SB_LU,
BRCMU_CHAN_SB_UL,
BRCMU_CHAN_SB_UU,
BRCMU_CHAN_SB_LLL, BRCMU_CHAN_SB_LLL,
BRCMU_CHAN_SB_LLU, BRCMU_CHAN_SB_LLU,
BRCMU_CHAN_SB_LUL, BRCMU_CHAN_SB_LUL,
...@@ -123,6 +117,12 @@ enum brcmu_chan_sb { ...@@ -123,6 +117,12 @@ enum brcmu_chan_sb {
BRCMU_CHAN_SB_ULU, BRCMU_CHAN_SB_ULU,
BRCMU_CHAN_SB_UUL, BRCMU_CHAN_SB_UUL,
BRCMU_CHAN_SB_UUU, BRCMU_CHAN_SB_UUU,
BRCMU_CHAN_SB_L = BRCMU_CHAN_SB_LLL,
BRCMU_CHAN_SB_U = BRCMU_CHAN_SB_LLU,
BRCMU_CHAN_SB_LL = BRCMU_CHAN_SB_LLL,
BRCMU_CHAN_SB_LU = BRCMU_CHAN_SB_LLU,
BRCMU_CHAN_SB_UL = BRCMU_CHAN_SB_LUL,
BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
}; };
struct brcmu_chan { struct brcmu_chan {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define CH_UPPER_SB 0x01 #define CH_UPPER_SB 0x01
#define CH_LOWER_SB 0x02 #define CH_LOWER_SB 0x02
#define CH_EWA_VALID 0x04 #define CH_EWA_VALID 0x04
#define CH_30MHZ_APART 6
#define CH_20MHZ_APART 4 #define CH_20MHZ_APART 4
#define CH_10MHZ_APART 2 #define CH_10MHZ_APART 2
#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment