diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 80 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/nvram.c | 220 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 206 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmutil/d11.c | 93 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/include/brcmu_d11.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/include/brcmu_wifi.h | 1 |
13 files changed, 515 insertions, 190 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 939d6b132922..16f9ab2568a8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -186,7 +186,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); u32 brcmf_get_chip_info(struct brcmf_if *ifp); -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, bool success); /* Sets dongle media info (drv_version, mac address). */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index c4535616064e..c5dcd82e884b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -99,6 +99,7 @@ struct brcmf_bus { unsigned long tx_realloc; u32 chip; u32 chiprev; + bool always_use_fws_queue; struct brcmf_bus_ops *ops; }; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 6a8983a1fb9c..ed3e32ce8c23 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -32,6 +32,9 @@ #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" +/* boost value for RSSI_DELTA in preferred join selection */ +#define BRCMF_JOIN_PREF_RSSI_BOOST 8 + bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) @@ -246,6 +249,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) { s8 eventmask[BRCMF_EVENTING_MASK_LEN]; u8 buf[BRCMF_DCMD_SMLEN]; + struct brcmf_join_pref_params join_pref_params[2]; char *ptr; s32 err; @@ -298,6 +302,20 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) goto done; } + /* Setup join_pref to select target by RSSI(with boost on 5GHz) */ + join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA; + join_pref_params[0].len = 2; + join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST; + join_pref_params[0].band = WLC_BAND_5G; + join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI; + join_pref_params[1].len = 2; + join_pref_params[1].rssi_gain = 0; + join_pref_params[1].band = 0; + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, + sizeof(join_pref_params)); + if (err) + brcmf_err("Set join_pref error (%d)\n", err); + /* Setup event_msgs, enable E_IF */ err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 7d28cd385092..4cacc3d85212 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -190,7 +190,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, int ret; struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; - struct ethhdr *eh; + struct ethhdr *eh = (struct ethhdr *)(skb->data); brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); @@ -236,6 +236,9 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, goto done; } + if (eh->h_proto == htons(ETH_P_PAE)) + atomic_inc(&ifp->pend_8021x_cnt); + ret = brcmf_fws_process_skb(ifp, skb); done: @@ -538,31 +541,26 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb) brcmf_netif_rx(ifp, skb); } -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, bool success) { struct brcmf_if *ifp; struct ethhdr *eh; - u8 ifidx; u16 type; - int res; - - res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp); ifp = drvr->iflist[ifidx]; if (!ifp) goto done; - if (res == 0) { - eh = (struct ethhdr *)(txp->data); - type = ntohs(eh->h_proto); + eh = (struct ethhdr *)(txp->data); + type = ntohs(eh->h_proto); - if (type == ETH_P_PAE) { - atomic_dec(&ifp->pend_8021x_cnt); - if (waitqueue_active(&ifp->pend_8021x_wait)) - wake_up(&ifp->pend_8021x_wait); - } + if (type == ETH_P_PAE) { + atomic_dec(&ifp->pend_8021x_cnt); + if (waitqueue_active(&ifp->pend_8021x_wait)) + wake_up(&ifp->pend_8021x_wait); } + if (!success) ifp->stats.tx_errors++; done: @@ -573,13 +571,17 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; + u8 ifidx; /* await txstatus signal for firmware if active */ if (brcmf_fws_fc_active(drvr->fws)) { if (!success) brcmf_fws_bustxfail(drvr->fws, txp); } else { - brcmf_txfinalize(drvr, txp, success); + if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp)) + brcmu_pkt_buf_free_skb(txp); + else + brcmf_txfinalize(drvr, txp, ifidx, success); } } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h index 614e4888504f..2bc68a2137fc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h @@ -53,6 +53,14 @@ #define BRCMF_OBSS_COEX_OFF 0 #define BRCMF_OBSS_COEX_ON 1 +/* join preference types for join_pref iovar */ +enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, + BRCMF_JOIN_PREF_WPA, + BRCMF_JOIN_PREF_BAND, + BRCMF_JOIN_PREF_RSSI_DELTA, +}; + enum brcmf_fil_p2p_if_types { BRCMF_FIL_P2P_IF_CLIENT, BRCMF_FIL_P2P_IF_GO, @@ -282,6 +290,22 @@ struct brcmf_assoc_params_le { __le16 chanspec_list[1]; }; +/** + * struct join_pref params - parameters for preferred join selection. + * + * @type: preference type (see enum brcmf_join_pref_types). + * @len: length of bytes following (currently always 2). + * @rssi_gain: signal gain for selection (only when @type is RSSI_DELTA). + * @band: band to which selection preference applies. + * This is used if @type is BAND or RSSI_DELTA. + */ +struct brcmf_join_pref_params { + u8 type; + u8 len; + u8 rssi_gain; + u8 band; +}; + /* used for join with or without a specific bssid and channel list */ struct brcmf_join_params { struct brcmf_ssid_le ssid_le; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index c3e7d76dbf35..699908de314a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -476,6 +476,7 @@ struct brcmf_fws_info { bool bus_flow_blocked; bool creditmap_received; u8 mode; + bool avoid_queueing; }; /* @@ -1369,13 +1370,12 @@ done: } static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, - struct sk_buff *skb, u32 genbit, - u16 seq) + struct sk_buff *skb, u8 ifidx, + u32 genbit, u16 seq) { struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; u32 hslot; int ret; - u8 ifidx; hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); @@ -1389,29 +1389,21 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, entry->generation = genbit; - ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); - if (ret == 0) { - brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); - brcmf_skbcb(skb)->htod_seq = seq; - if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1); - brcmf_skb_htod_seq_set_field(skb, FROMFW, 0); - } else { - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0); - } - ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, - skb); + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); + brcmf_skbcb(skb)->htod_seq = seq; + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1); + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0); + } else { + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0); } + ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb); if (ret != 0) { - /* suppress q is full or hdrpull failed, drop this packet */ - brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, - true); + /* suppress q is full drop this packet */ + brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true); } else { - /* - * Mark suppressed to avoid a double free during - * wlfc cleanup - */ + /* Mark suppressed to avoid a double free during wlfc cleanup */ brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot); } @@ -1428,6 +1420,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, struct sk_buff *skb; struct brcmf_skbuff_cb *skcb; struct brcmf_fws_mac_descriptor *entry = NULL; + u8 ifidx; brcmf_dbg(DATA, "flags %d\n", flags); @@ -1476,12 +1469,15 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, } brcmf_fws_macdesc_return_req_credit(skb); + if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) { + brcmu_pkt_buf_free_skb(skb); + return -EINVAL; + } if (!remove_from_hanger) - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit, - seq); - + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx, + genbit, seq); if (remove_from_hanger || ret) - brcmf_txfinalize(fws->drvr, skb, true); + brcmf_txfinalize(fws->drvr, skb, ifidx, true); return 0; } @@ -1868,7 +1864,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) struct ethhdr *eh = (struct ethhdr *)(skb->data); int fifo = BRCMF_FWS_FIFO_BCMC; bool multicast = is_multicast_ether_addr(eh->h_dest); - bool pae = eh->h_proto == htons(ETH_P_PAE); + int rc = 0; brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); /* determine the priority */ @@ -1876,8 +1872,13 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) skb->priority = cfg80211_classify8021d(skb, NULL); drvr->tx_multicast += !!multicast; - if (pae) - atomic_inc(&ifp->pend_8021x_cnt); + + if (fws->avoid_queueing) { + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); + if (rc < 0) + brcmf_txfinalize(drvr, skb, ifp->ifidx, false); + return rc; + } /* set control buffer information */ skcb->if_flags = 0; @@ -1899,15 +1900,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) brcmf_fws_schedule_deq(fws); } else { brcmf_err("drop skb: no hanger slot\n"); - if (pae) { - atomic_dec(&ifp->pend_8021x_cnt); - if (waitqueue_active(&ifp->pend_8021x_wait)) - wake_up(&ifp->pend_8021x_wait); - } - brcmu_pkt_buf_free_skb(skb); + brcmf_txfinalize(drvr, skb, ifp->ifidx, false); + rc = -ENOMEM; } brcmf_fws_unlock(fws); - return 0; + + return rc; } void brcmf_fws_reset_interface(struct brcmf_if *ifp) @@ -1982,7 +1980,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) ret = brcmf_proto_txdata(drvr, ifidx, 0, skb); brcmf_fws_lock(fws); if (ret < 0) - brcmf_txfinalize(drvr, skb, false); + brcmf_txfinalize(drvr, skb, ifidx, + false); if (fws->bus_flow_blocked) break; } @@ -2039,6 +2038,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr) fws->drvr = drvr; fws->fcmode = fcmode; + if ((drvr->bus_if->always_use_fws_queue == false) && + (fcmode == BRCMF_FWS_FCMODE_NONE)) { + fws->avoid_queueing = true; + brcmf_dbg(INFO, "FWS queueing will be avoided\n"); + return 0; + } + fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq"); if (fws->fws_wq == NULL) { brcmf_err("workqueue creation failed\n"); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c index d5ef86db631b..5c450d11dbc9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c @@ -18,72 +18,205 @@ #include <linux/slab.h> #include <linux/firmware.h> +#include "dhd_dbg.h" #include "nvram.h" -/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file +enum nvram_parser_state { + IDLE, + KEY, + VALUE, + COMMENT, + END +}; + +/** + * struct nvram_parser - internal info for parser. + * + * @state: current parser state. + * @fwnv: input buffer being parsed. + * @nvram: output buffer with parse result. + * @nvram_len: lenght of parse result. + * @line: current line. + * @column: current column in line. + * @pos: byte offset in input buffer. + * @entry: start position of key,value entry. + */ +struct nvram_parser { + enum nvram_parser_state state; + const struct firmware *fwnv; + u8 *nvram; + u32 nvram_len; + u32 line; + u32 column; + u32 pos; + u32 entry; +}; + +static bool is_nvram_char(char c) +{ + /* comment marker excluded */ + if (c == '#') + return false; + + /* key and value may have any other readable character */ + return (c > 0x20 && c < 0x7f); +} + +static bool is_whitespace(char c) +{ + return (c == ' ' || c == '\r' || c == '\n' || c == '\t'); +} + +static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp) +{ + char c; + + c = nvp->fwnv->data[nvp->pos]; + if (c == '\n') + return COMMENT; + if (is_whitespace(c)) + goto proceed; + if (c == '#') + return COMMENT; + if (is_nvram_char(c)) { + nvp->entry = nvp->pos; + return KEY; + } + brcmf_dbg(INFO, "warning: ln=%d:col=%d: ignoring invalid character\n", + nvp->line, nvp->column); +proceed: + nvp->column++; + nvp->pos++; + return IDLE; +} + +static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp) +{ + enum nvram_parser_state st = nvp->state; + char c; + + c = nvp->fwnv->data[nvp->pos]; + if (c == '=') { + st = VALUE; + } else if (!is_nvram_char(c)) { + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", + nvp->line, nvp->column); + return COMMENT; + } + + nvp->column++; + nvp->pos++; + return st; +} + +static enum nvram_parser_state +brcmf_nvram_handle_value(struct nvram_parser *nvp) +{ + char c; + char *skv; + char *ekv; + u32 cplen; + + c = nvp->fwnv->data[nvp->pos]; + if (!is_nvram_char(c)) { + /* key,value pair complete */ + ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; + skv = (u8 *)&nvp->fwnv->data[nvp->entry]; + cplen = ekv - skv; + /* copy to output buffer */ + memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen); + nvp->nvram_len += cplen; + nvp->nvram[nvp->nvram_len] = '\0'; + nvp->nvram_len++; + return IDLE; + } + nvp->pos++; + nvp->column++; + return VALUE; +} + +static enum nvram_parser_state +brcmf_nvram_handle_comment(struct nvram_parser *nvp) +{ + char *eol, *sol; + + sol = (char *)&nvp->fwnv->data[nvp->pos]; + eol = strchr(sol, '\n'); + if (eol == NULL) + return END; + + /* eat all moving to next line */ + nvp->line++; + nvp->column = 1; + nvp->pos += (eol - sol) + 1; + return IDLE; +} + +static enum nvram_parser_state brcmf_nvram_handle_end(struct nvram_parser *nvp) +{ + /* final state */ + return END; +} + +static enum nvram_parser_state +(*nv_parser_states[])(struct nvram_parser *nvp) = { + brcmf_nvram_handle_idle, + brcmf_nvram_handle_key, + brcmf_nvram_handle_value, + brcmf_nvram_handle_comment, + brcmf_nvram_handle_end +}; + +static int brcmf_init_nvram_parser(struct nvram_parser *nvp, + const struct firmware *nv) +{ + memset(nvp, 0, sizeof(*nvp)); + nvp->fwnv = nv; + /* Alloc for extra 0 byte + roundup by 4 + length field */ + nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL); + if (!nvp->nvram) + return -ENOMEM; + + nvp->line = 1; + nvp->column = 1; + return 0; +} + +/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil * and ending in a NUL. Removes carriage returns, empty lines, comment lines, * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. * End of buffer is completed with token identifying length of buffer. */ void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length) { - u8 *nvram; - u32 i; - u32 len; - u32 column; - u8 val; - bool comment; + struct nvram_parser nvp; + u32 pad; u32 token; __le32 token_le; - /* Alloc for extra 0 byte + roundup by 4 + length field */ - nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL); - if (!nvram) + if (brcmf_init_nvram_parser(&nvp, nv) < 0) return NULL; - len = 0; - column = 0; - comment = false; - for (i = 0; i < nv->size; i++) { - val = nv->data[i]; - if (val == 0) + while (nvp.pos < nv->size) { + nvp.state = nv_parser_states[nvp.state](&nvp); + if (nvp.state == END) break; - if (val == '\r') - continue; - if (comment && (val != '\n')) - continue; - comment = false; - if (val == '#') { - comment = true; - continue; - } - if (val == '\n') { - if (column == 0) - continue; - nvram[len] = 0; - len++; - column = 0; - continue; - } - nvram[len] = val; - len++; - column++; } - column = len; - *new_length = roundup(len + 1, 4); - while (column != *new_length) { - nvram[column] = 0; - column++; + pad = nvp.nvram_len; + *new_length = roundup(nvp.nvram_len + 1, 4); + while (pad != *new_length) { + nvp.nvram[pad] = 0; + pad++; } token = *new_length / 4; token = (~token << 16) | (token & 0x0000FFFF); token_le = cpu_to_le32(token); - memcpy(&nvram[*new_length], &token_le, sizeof(token_le)); + memcpy(&nvp.nvram[*new_length], &token_le, sizeof(token_le)); *new_length += sizeof(token_le); - return nvram; + return nvp.nvram; } void brcmf_nvram_free(void *nvram) @@ -91,4 +224,3 @@ void brcmf_nvram_free(void *nvram) kfree(nvram); } - diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 24f65cd53859..3ce0e7cfd027 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1254,6 +1254,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->chip = bus_pub->devid; bus->chiprev = bus_pub->chiprev; bus->proto_type = BRCMF_PROTO_BCDC; + bus->always_use_fws_queue = true; /* Attach to the common driver interface */ ret = brcmf_attach(dev); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index be1985296bdc..92cb29a2003f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -221,9 +221,9 @@ static const struct ieee80211_regdomain brcmf_regdom = { */ REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), /* IEEE 802.11a, channel 36..64 */ - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), + REG_RULE(5150-10, 5350+10, 80, 6, 20, 0), /* IEEE 802.11a, channel 100..165 */ - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } }; static const u32 __wl_cipher_suites[] = { @@ -341,6 +341,60 @@ static u8 brcmf_mw_to_qdbm(u16 mw) return qdbm; } +u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, + struct cfg80211_chan_def *ch) +{ + struct brcmu_chan ch_inf; + s32 primary_offset; + + brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n", + ch->chan->center_freq, ch->center_freq1, ch->width); + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1); + primary_offset = ch->center_freq1 - ch->chan->center_freq; + switch (ch->width) { + case NL80211_CHAN_WIDTH_20: + ch_inf.bw = BRCMU_CHAN_BW_20; + WARN_ON(primary_offset != 0); + break; + case NL80211_CHAN_WIDTH_40: + ch_inf.bw = BRCMU_CHAN_BW_40; + if (primary_offset < 0) + ch_inf.sb = BRCMU_CHAN_SB_U; + else + ch_inf.sb = BRCMU_CHAN_SB_L; + break; + case NL80211_CHAN_WIDTH_80: + ch_inf.bw = BRCMU_CHAN_BW_80; + if (primary_offset < 0) { + if (primary_offset < -CH_10MHZ_APART) + ch_inf.sb = BRCMU_CHAN_SB_UU; + else + ch_inf.sb = BRCMU_CHAN_SB_UL; + } else { + if (primary_offset > CH_10MHZ_APART) + ch_inf.sb = BRCMU_CHAN_SB_LL; + else + ch_inf.sb = BRCMU_CHAN_SB_LU; + } + break; + default: + WARN_ON_ONCE(1); + } + switch (ch->chan->band) { + case IEEE80211_BAND_2GHZ: + ch_inf.band = BRCMU_CHAN_BAND_2G; + break; + case IEEE80211_BAND_5GHZ: + ch_inf.band = BRCMU_CHAN_BAND_5G; + break; + default: + WARN_ON_ONCE(1); + } + d11inf->encchspec(&ch_inf); + + return ch_inf.chspec; +} + u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, struct ieee80211_channel *ch) { @@ -1236,8 +1290,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, params->chandef.chan->center_freq); if (params->channel_fixed) { /* adding chanspec */ - chanspec = channel_to_chanspec(&cfg->d11inf, - params->chandef.chan); + chanspec = chandef_to_chanspec(&cfg->d11inf, + ¶ms->chandef); join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec); join_params.params_le.chanspec_num = cpu_to_le32(1); @@ -2182,7 +2236,7 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, - u8 *mac, struct station_info *sinfo) + const u8 *mac, struct station_info *sinfo) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; @@ -3734,23 +3788,6 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, } static s32 -brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg, - struct brcmf_if *ifp, - struct ieee80211_channel *channel) -{ - u16 chanspec; - s32 err; - - brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band, - channel->center_freq); - - chanspec = channel_to_chanspec(&cfg->d11inf, channel); - err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); - - return err; -} - -static s32 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ap_settings *settings) { @@ -3765,11 +3802,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_join_params join_params; enum nl80211_iftype dev_role; struct brcmf_fil_bss_enable_le bss_enable; + u16 chanspec; - brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", - cfg80211_get_chandef_type(&settings->chandef), - settings->beacon_interval, - settings->dtim_period); + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", + settings->chandef.chan->hw_value, + settings->chandef.center_freq1, settings->chandef.width, + settings->beacon_interval, settings->dtim_period); brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", settings->ssid, settings->ssid_len, settings->auth_type, settings->inactivity_timeout); @@ -3826,9 +3864,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); - err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan); + chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef); + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); if (err < 0) { - brcmf_err("Set Channel failed, %d\n", err); + brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err); goto exit; } @@ -3975,7 +4014,7 @@ brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, - u8 *mac) + const u8 *mac) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_scb_val_le scbval; @@ -4203,7 +4242,7 @@ static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper) } static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy, - struct net_device *ndev, u8 *peer, + struct net_device *ndev, const u8 *peer, enum nl80211_tdls_operation oper) { struct brcmf_if *ifp; @@ -4364,6 +4403,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_SUPPORTS_TDLS; + if (!brcmf_roamoff) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; wiphy->mgmt_stypes = brcmf_txrx_stypes; wiphy->max_remain_on_channel_duration = 5000; brcmf_wiphy_pno_params(wiphy); @@ -4685,7 +4726,6 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct ieee80211_channel *chan; s32 err = 0; - u16 reason; if (brcmf_is_apmode(ifp->vif)) { err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); @@ -4706,16 +4746,6 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, brcmf_dbg(CONN, "Linkdown\n"); if (!brcmf_is_ibssmode(ifp->vif)) { brcmf_bss_connect_done(cfg, ndev, e, false); - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state)) { - reason = 0; - if (((e->event_code == BRCMF_E_DEAUTH_IND) || - (e->event_code == BRCMF_E_DISASSOC_IND)) && - (e->reason != WLAN_REASON_UNSPECIFIED)) - reason = e->reason; - cfg80211_disconnected(ndev, reason, NULL, 0, - GFP_KERNEL); - } } brcmf_link_down(ifp->vif); brcmf_init_prof(ndev_to_prof(ndev)); @@ -5215,6 +5245,9 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && ch.bw == BRCMU_CHAN_BW_40) continue; + if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) && + ch.bw == BRCMU_CHAN_BW_80) + continue; update = false; for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { if (band_chan_arr[j].hw_value == ch.chnum) { @@ -5231,10 +5264,13 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, ieee80211_channel_to_frequency(ch.chnum, band); band_chan_arr[index].hw_value = ch.chnum; - if (ch.bw == BRCMU_CHAN_BW_40) { - /* assuming the order is HT20, HT40 Upper, - * HT40 lower from chanspecs - */ + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. + */ + if (ch.bw == BRCMU_CHAN_BW_80) { + band_chan_arr[index].flags &= + ~IEEE80211_CHAN_NO_80MHZ; + } else if (ch.bw == BRCMU_CHAN_BW_40) { ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; if (ch.sb == BRCMU_CHAN_SB_U) { @@ -5255,8 +5291,13 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, IEEE80211_CHAN_NO_HT40MINUS; } } else { + /* disable other bandwidths for now as mentioned + * order assure they are enabled for subsequent + * chanspecs. + */ band_chan_arr[index].flags = - IEEE80211_CHAN_NO_HT40; + IEEE80211_CHAN_NO_HT40 | + IEEE80211_CHAN_NO_80MHZ; ch.bw = BRCMU_CHAN_BW_20; cfg->d11inf.encchspec(&ch); channel = ch.chspec; @@ -5323,13 +5364,63 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) } } +static void brcmf_update_ht_cap(struct ieee80211_supported_band *band, + u32 bw_cap[2], u32 nchain) +{ + band->ht_cap.ht_supported = true; + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; + band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; + band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; + band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + memset(band->ht_cap.mcs.rx_mask, 0xff, nchain); + band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; +} + +static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp) +{ + u16 mcs_map; + int i; + + for (i = 0, mcs_map = 0xFFFF; i < nchain; i++) + mcs_map = (mcs_map << 2) | supp; + + return cpu_to_le16(mcs_map); +} + +static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, + u32 bw_cap[2], u32 nchain) +{ + __le16 mcs_map; + + /* not allowed in 2.4G band */ + if (band->band == IEEE80211_BAND_2GHZ) + return; + + band->vht_cap.vht_supported = true; + /* 80MHz is mandatory */ + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; + if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) { + band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160; + } + /* all support 256-QAM */ + mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9); + band->vht_cap.vht_mcs.rx_mcs_map = mcs_map; + band->vht_cap.vht_mcs.tx_mcs_map = mcs_map; +} + static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) { struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct wiphy *wiphy; s32 phy_list; u32 band_list[3]; - u32 nmode; + u32 nmode = 0; + u32 vhtmode = 0; u32 bw_cap[2] = { 0, 0 }; u32 rxchain; u32 nchain; @@ -5360,14 +5451,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n", band_list[0], band_list[1], band_list[2]); + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); if (err) { brcmf_err("nmode error (%d)\n", err); } else { brcmf_get_bwcap(ifp, bw_cap); } - brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, - bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); + brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n", + nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ], + bw_cap[IEEE80211_BAND_5GHZ]); err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); if (err) { @@ -5398,17 +5491,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) else continue; - if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; - band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; - } - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; - band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; - band->ht_cap.ht_supported = true; - band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; - memset(band->ht_cap.mcs.rx_mask, 0xff, nchain); - band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + if (nmode) + brcmf_update_ht_cap(band, bw_cap, nchain); + if (vhtmode) + brcmf_update_vht_cap(band, bw_cap, nchain); bands[band->band] = band; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 9417cb5a2553..af8ba64ace39 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -4870,14 +4870,11 @@ static void brcms_c_detach_module(struct brcms_c_info *wlc) /* * low level detach */ -static int brcms_b_detach(struct brcms_c_info *wlc) +static void brcms_b_detach(struct brcms_c_info *wlc) { uint i; struct brcms_hw_band *band; struct brcms_hardware *wlc_hw = wlc->hw; - int callbacks; - - callbacks = 0; brcms_b_detach_dmapio(wlc_hw); @@ -4900,9 +4897,6 @@ static int brcms_b_detach(struct brcms_c_info *wlc) ai_detach(wlc_hw->sih); wlc_hw->sih = NULL; } - - return callbacks; - } /* @@ -4917,14 +4911,15 @@ static int brcms_b_detach(struct brcms_c_info *wlc) */ uint brcms_c_detach(struct brcms_c_info *wlc) { - uint callbacks = 0; + uint callbacks; if (wlc == NULL) return 0; - callbacks += brcms_b_detach(wlc); + brcms_b_detach(wlc); /* delete software timers */ + callbacks = 0; if (!brcms_c_radio_monitor_stop(wlc)) callbacks++; diff --git a/drivers/net/wireless/brcm80211/brcmutil/d11.c b/drivers/net/wireless/brcm80211/brcmutil/d11.c index 30e54e2c6c9b..6cbc33d0fc19 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/d11.c +++ b/drivers/net/wireless/brcm80211/brcmutil/d11.c @@ -21,43 +21,81 @@ #include <brcmu_wifi.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: - ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N; - break; + return BRCMU_CHSPEC_D11N_BW_20; case BRCMU_CHAN_BW_40: + return BRCMU_CHSPEC_D11N_BW_40; default: - WARN_ON_ONCE(1); - break; + WARN_ON(1); } + 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) ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G; else 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 (ch->bw) { + switch (bw) { case BRCMU_CHAN_BW_20: - ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20; - break; + return BRCMU_CHSPEC_D11AC_BW_20; case BRCMU_CHAN_BW_40: + return BRCMU_CHSPEC_D11AC_BW_40; case BRCMU_CHAN_BW_80: - case BRCMU_CHAN_BW_80P80: - case BRCMU_CHAN_BW_160: + return BRCMU_CHSPEC_D11AC_BW_80; default: - WARN_ON_ONCE(1); - break; + WARN_ON(1); } + 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) ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; else @@ -73,6 +111,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch) switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { case BRCMU_CHSPEC_D11N_BW_20: ch->bw = BRCMU_CHAN_BW_20; + ch->sb = BRCMU_CHAN_SB_NONE; break; case BRCMU_CHSPEC_D11N_BW_40: ch->bw = BRCMU_CHAN_BW_40; @@ -112,6 +151,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { case BRCMU_CHSPEC_D11AC_BW_20: ch->bw = BRCMU_CHAN_BW_20; + ch->sb = BRCMU_CHAN_SB_NONE; break; case BRCMU_CHSPEC_D11AC_BW_40: ch->bw = BRCMU_CHAN_BW_40; @@ -128,6 +168,25 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) break; case BRCMU_CHSPEC_D11AC_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; case BRCMU_CHSPEC_D11AC_BW_8080: case BRCMU_CHSPEC_D11AC_BW_160: diff --git a/drivers/net/wireless/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/brcm80211/include/brcmu_d11.h index 8660a2cba098..f9745ea8b3e0 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_d11.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_d11.h @@ -108,13 +108,7 @@ enum brcmu_chan_bw { }; enum brcmu_chan_sb { - BRCMU_CHAN_SB_NONE = 0, - 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_NONE = -1, BRCMU_CHAN_SB_LLL, BRCMU_CHAN_SB_LLU, BRCMU_CHAN_SB_LUL, @@ -123,6 +117,12 @@ enum brcmu_chan_sb { BRCMU_CHAN_SB_ULU, BRCMU_CHAN_SB_UUL, 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 { diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h index 74419d4bd123..76b5d3a86294 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h @@ -29,6 +29,7 @@ #define CH_UPPER_SB 0x01 #define CH_LOWER_SB 0x02 #define CH_EWA_VALID 0x04 +#define CH_30MHZ_APART 6 #define CH_20MHZ_APART 4 #define CH_10MHZ_APART 2 #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ |