summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h73
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c453
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c198
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c174
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c336
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h39
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c43
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1284
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h145
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c2
17 files changed, 1322 insertions, 1475 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 9d5170b..fe80b63 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -24,6 +24,7 @@ ccflags-y += -D__CHECK_ENDIAN__
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
brcmfmac-objs += \
wl_cfg80211.o \
+ fwil.o \
dhd_cdc.o \
dhd_common.o \
dhd_linux.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 17e7ae7..8704daa 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -318,6 +318,12 @@ struct brcmf_event {
#define BRCMF_E_LINK_ASSOC_REC 3
#define BRCMF_E_LINK_BSSCFG_DIS 4
+/* Small, medium and maximum buffer size for dcmd
+ */
+#define BRCMF_DCMD_SMLEN 256
+#define BRCMF_DCMD_MEDLEN 1536
+#define BRCMF_DCMD_MAXLEN 8192
+
/* Pattern matching filter. Specifies an offset within received packets to
* start matching, the pattern to match, the size of the pattern, and a bitmask
* that indicates which bits within the pattern should be matched.
@@ -623,7 +629,6 @@ struct brcmf_pub {
u8 wme_dp; /* wme discard priority */
/* Dongle media info */
- bool iswl; /* Dongle-resident driver is wl */
unsigned long drv_version; /* Version of dongle-resident driver */
u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
@@ -651,16 +656,10 @@ struct brcmf_pub {
int in_suspend; /* flag set to 1 when early suspend called */
int dtim_skip; /* dtim skip , default 0 means wake each dtim */
- /* Pkt filter defination */
- char *pktfilter[100];
- int pktfilter_count;
-
- u8 country_code[BRCM_CNTRY_BUF_SZ];
- char eventmask[BRCMF_EVENTING_MASK_LEN];
-
struct brcmf_if *iflist[BRCMF_MAX_IFS];
struct mutex proto_block;
+ unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
struct work_struct setmacaddr_work;
struct work_struct multicast_work;
@@ -671,6 +670,11 @@ struct brcmf_pub {
#endif
};
+struct bcmevent_name {
+ uint event;
+ const char *name;
+};
+
struct brcmf_if_event {
u8 ifidx;
u8 action;
@@ -678,47 +682,60 @@ struct brcmf_if_event {
u8 bssidx;
};
-struct bcmevent_name {
- uint event;
- const char *name;
+/* forward declaration */
+struct brcmf_cfg80211_vif;
+
+/**
+ * struct brcmf_if - interface control information.
+ *
+ * @drvr: points to device related information.
+ * @vif: points to cfg80211 specific interface information.
+ * @ndev: associated network device.
+ * @stats: interface specific network statistics.
+ * @idx: interface index in device firmware.
+ * @bssidx: index of bss associated with this interface.
+ * @mac_addr: assigned mac address.
+ */
+struct brcmf_if {
+ struct brcmf_pub *drvr;
+ struct brcmf_cfg80211_vif *vif;
+ struct net_device *ndev;
+ struct net_device_stats stats;
+ int idx;
+ s32 bssidx;
+ u8 mac_addr[ETH_ALEN];
};
+static inline s32 brcmf_ndev_bssidx(struct net_device *ndev)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ return ifp->bssidx;
+}
+
extern const struct bcmevent_name bcmevent_names[];
extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
char *buf, uint len);
-extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
- char *buf, uint buflen, s32 bssidx);
extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
-extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
-extern int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd);
-
/* Return pointer to interface name */
extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
/* Query dongle */
extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len);
-
-#ifdef DEBUG
-extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
-#endif /* DEBUG */
+extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
+ void *buf, uint len);
extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
void *pktdata, struct brcmf_event_msg *,
void **data_ptr);
+extern int brcmf_net_attach(struct brcmf_if *ifp);
+extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx,
+ char *name, u8 *mac_addr);
extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
-extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
-extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
- int enable, int master_mode);
-
-#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */
-#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */
-#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */
-
#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 9b8ee19..265580f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -111,9 +111,6 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
extern int brcmf_bus_start(struct device *dev);
-extern int brcmf_add_if(struct device *dev, int ifidx,
- char *name, u8 *mac_addr);
-
#ifdef CONFIG_BRCMFMAC_SDIO
extern void brcmf_sdio_exit(void);
extern void brcmf_sdio_init(void);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index a5c15ca..b9d8a5a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -458,35 +458,6 @@ void brcmf_proto_detach(struct brcmf_pub *drvr)
drvr->prot = NULL;
}
-int brcmf_proto_init(struct brcmf_pub *drvr)
-{
- int ret = 0;
- char buf[128];
-
- brcmf_dbg(TRACE, "Enter\n");
-
- mutex_lock(&drvr->proto_block);
-
- /* Get the device MAC address */
- strcpy(buf, "cur_etheraddr");
- ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
- buf, sizeof(buf));
- if (ret < 0) {
- mutex_unlock(&drvr->proto_block);
- return ret;
- }
- memcpy(drvr->mac, buf, ETH_ALEN);
-
- mutex_unlock(&drvr->proto_block);
-
- ret = brcmf_c_preinit_dcmds(drvr);
-
- /* Always assumes wl for now */
- drvr->iswl = true;
-
- return ret;
-}
-
void brcmf_proto_stop(struct brcmf_pub *drvr)
{
/* Nothing to do for CDC */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 15c5db5..866b669 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -28,12 +28,17 @@
#include "dhd_bus.h"
#include "dhd_proto.h"
#include "dhd_dbg.h"
+#include "fwil.h"
#define BRCM_OUI "\x00\x10\x18"
#define DOT11_OUI_LEN 3
#define BCMILCP_BCM_SUBTYPE_EVENT 1
-#define PKTFILTER_BUF_SIZE 2048
+#define PKTFILTER_BUF_SIZE 128
#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
+#define BRCMF_DEFAULT_BCN_TIMEOUT 3
+#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
+#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
+#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
#define MSGTRACE_VERSION 1
@@ -88,52 +93,6 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
return len;
}
-uint
-brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
- char *buf, uint buflen, s32 bssidx)
-{
- const s8 *prefix = "bsscfg:";
- s8 *p;
- u32 prefixlen;
- u32 namelen;
- u32 iolen;
- __le32 bssidx_le;
-
- if (bssidx == 0)
- return brcmf_c_mkiovar(name, data, datalen, buf, buflen);
-
- prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
- namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */
- iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
-
- if (buflen < 0 || iolen > (u32)buflen) {
- brcmf_dbg(ERROR, "buffer is too short\n");
- return 0;
- }
-
- p = buf;
-
- /* copy prefix, no null */
- memcpy(p, prefix, prefixlen);
- p += prefixlen;
-
- /* copy iovar name including null */
- memcpy(p, name, namelen);
- p += namelen;
-
- /* bss config index as first data */
- bssidx_le = cpu_to_le32(bssidx);
- memcpy(p, &bssidx_le, sizeof(bssidx_le));
- p += sizeof(bssidx_le);
-
- /* parameter buffer follows */
- if (datalen)
- memcpy(p, data, datalen);
-
- return iolen;
-
-}
-
bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
struct sk_buff *pkt, int prec)
{
@@ -490,6 +449,7 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
/* check whether packet is a BRCM event pkt */
struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
struct brcmf_if_event *ifevent;
+ struct brcmf_if *ifp;
char *event_data;
u32 type, status;
u16 flags;
@@ -525,12 +485,17 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
brcmf_dbg(TRACE, "if event\n");
if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
- if (ifevent->action == BRCMF_E_IF_ADD)
- brcmf_add_if(drvr->dev, ifevent->ifidx,
- event->ifname,
- pvt_data->eth.h_dest);
- else
+ if (ifevent->action == BRCMF_E_IF_ADD) {
+ ifp = brcmf_add_if(drvr->dev, ifevent->ifidx,
+ ifevent->bssidx,
+ event->ifname,
+ pvt_data->eth.h_dest);
+ if (IS_ERR(ifp))
+ return PTR_ERR(ifp);
+ brcmf_net_attach(ifp);
+ } else {
brcmf_del_if(drvr, ifevent->ifidx);
+ }
} else {
brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
ifevent->ifidx, event->ifname);
@@ -603,90 +568,57 @@ static int brcmf_c_pattern_atoh(char *src, char *dst)
return i;
}
-void
-brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
- int master_mode)
+static void
+brcmf_c_pktfilter_offload_enable(struct brcmf_if *ifp, char *arg, int enable,
+ int master_mode)
{
unsigned long res;
- char *argv[8];
- int i = 0;
- const char *str;
- int buf_len;
- int str_len;
+ char *argv;
char *arg_save = NULL, *arg_org = NULL;
- int rc;
- char buf[128];
+ s32 err;
struct brcmf_pkt_filter_enable_le enable_parm;
- struct brcmf_pkt_filter_enable_le *pkt_filterp;
- __le32 mmode_le;
- arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
+ arg_save = kstrdup(arg, GFP_ATOMIC);
if (!arg_save)
goto fail;
arg_org = arg_save;
- memcpy(arg_save, arg, strlen(arg) + 1);
- argv[i] = strsep(&arg_save, " ");
+ argv = strsep(&arg_save, " ");
- i = 0;
- if (NULL == argv[i]) {
+ if (argv == NULL) {
brcmf_dbg(ERROR, "No args provided\n");
goto fail;
}
- str = "pkt_filter_enable";
- str_len = strlen(str);
- strncpy(buf, str, str_len);
- buf[str_len] = '\0';
- buf_len = str_len + 1;
-
- pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
-
/* Parse packet filter id. */
enable_parm.id = 0;
- if (!kstrtoul(argv[i], 0, &res))
+ if (!kstrtoul(argv, 0, &res))
enable_parm.id = cpu_to_le32((u32)res);
- /* Parse enable/disable value. */
+ /* Enable/disable the specified filter. */
enable_parm.enable = cpu_to_le32(enable);
- buf_len += sizeof(enable_parm);
- memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
+ err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable", &enable_parm,
+ sizeof(enable_parm));
+ if (err)
+ brcmf_dbg(ERROR, "Set pkt_filter_enable error (%d)\n", err);
- /* Enable/disable the specified filter. */
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
- rc = rc >= 0 ? 0 : rc;
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
- else
- brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
-
- /* Contorl the master mode */
- mmode_le = cpu_to_le32(master_mode);
- brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
- sizeof(buf));
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
- sizeof(buf));
- rc = rc >= 0 ? 0 : rc;
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
+ /* Control the master mode */
+ err = brcmf_fil_iovar_int_set(ifp, "pkt_filter_mode", master_mode);
+ if (err)
+ brcmf_dbg(ERROR, "Set pkt_filter_mode error (%d)\n", err);
fail:
kfree(arg_org);
}
-void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
+static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg)
{
- const char *str;
- struct brcmf_pkt_filter_le pkt_filter;
- struct brcmf_pkt_filter_le *pkt_filterp;
+ struct brcmf_pkt_filter_le *pkt_filter;
unsigned long res;
int buf_len;
- int str_len;
- int rc;
+ s32 err;
u32 mask_size;
u32 pattern_size;
char *argv[8], *buf = NULL;
@@ -704,104 +636,64 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
goto fail;
argv[i] = strsep(&arg_save, " ");
- while (argv[i++])
+ while (argv[i]) {
+ i++;
+ if (i >= 8) {
+ brcmf_dbg(ERROR, "Too many parameters\n");
+ goto fail;
+ }
argv[i] = strsep(&arg_save, " ");
+ }
- i = 0;
- if (NULL == argv[i]) {
- brcmf_dbg(ERROR, "No args provided\n");
+ if (i != 6) {
+ brcmf_dbg(ERROR, "Not enough args provided %d\n", i);
goto fail;
}
- str = "pkt_filter_add";
- strcpy(buf, str);
- str_len = strlen(str);
- buf_len = str_len + 1;
-
- pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
+ pkt_filter = (struct brcmf_pkt_filter_le *)buf;
/* Parse packet filter id. */
- pkt_filter.id = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.id = cpu_to_le32((u32)res);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Polarity not provided\n");
- goto fail;
- }
+ pkt_filter->id = 0;
+ if (!kstrtoul(argv[0], 0, &res))
+ pkt_filter->id = cpu_to_le32((u32)res);
/* Parse filter polarity. */
- pkt_filter.negate_match = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.negate_match = cpu_to_le32((u32)res);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Filter type not provided\n");
- goto fail;
- }
+ pkt_filter->negate_match = 0;
+ if (!kstrtoul(argv[1], 0, &res))
+ pkt_filter->negate_match = cpu_to_le32((u32)res);
/* Parse filter type. */
- pkt_filter.type = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.type = cpu_to_le32((u32)res);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Offset not provided\n");
- goto fail;
- }
+ pkt_filter->type = 0;
+ if (!kstrtoul(argv[2], 0, &res))
+ pkt_filter->type = cpu_to_le32((u32)res);
/* Parse pattern filter offset. */
- pkt_filter.u.pattern.offset = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Bitmask not provided\n");
- goto fail;
- }
+ pkt_filter->u.pattern.offset = 0;
+ if (!kstrtoul(argv[3], 0, &res))
+ pkt_filter->u.pattern.offset = cpu_to_le32((u32)res);
/* Parse pattern filter mask. */
- mask_size =
- brcmf_c_pattern_atoh
- (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Pattern not provided\n");
- goto fail;
- }
+ mask_size = brcmf_c_pattern_atoh(argv[4],
+ (char *)pkt_filter->u.pattern.mask_and_pattern);
/* Parse pattern filter pattern. */
- pattern_size =
- brcmf_c_pattern_atoh(argv[i],
- (char *)&pkt_filterp->u.pattern.
- mask_and_pattern[mask_size]);
+ pattern_size = brcmf_c_pattern_atoh(argv[5],
+ (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]);
if (mask_size != pattern_size) {
brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
goto fail;
}
- pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
- buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
- buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
-
- /* Keep-alive attributes are set in local
- * variable (keep_alive_pkt), and
- ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
- ** guarantee that the buffer is properly aligned.
- */
- memcpy((char *)pkt_filterp,
- &pkt_filter,
- BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
-
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
- rc = rc >= 0 ? 0 : rc;
+ pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size);
+ buf_len = sizeof(*pkt_filter);
+ buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern);
+ buf_len += mask_size + pattern_size;
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
- else
- brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
+ err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter,
+ buf_len);
+ if (err)
+ brcmf_dbg(ERROR, "Set pkt_filter_add error (%d)\n", err);
fail:
kfree(arg_org);
@@ -809,130 +701,125 @@ fail:
kfree(buf);
}
-static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
+int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{
- char iovbuf[32];
- int retcode;
- __le32 arp_mode_le;
-
- arp_mode_le = cpu_to_le32(arp_mode);
- brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf,
- sizeof(iovbuf));
- retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
- retcode = retcode >= 0 ? 0 : retcode;
- if (retcode)
- brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
- arp_mode, retcode);
- else
- brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
- arp_mode);
-}
-
-static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
-{
- char iovbuf[32];
- int retcode;
- __le32 arp_enable_le;
-
- arp_enable_le = cpu_to_le32(arp_enable);
-
- brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4,
- iovbuf, sizeof(iovbuf));
- retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
- retcode = retcode >= 0 ? 0 : retcode;
- if (retcode)
- brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
- arp_enable, retcode);
- else
- brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
- arp_enable);
-}
-
-int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
-{
- char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
- "event_msgs" + '\0' + bitvec */
- char buf[128], *ptr;
- __le32 roaming_le = cpu_to_le32(1);
- __le32 bcn_timeout_le = cpu_to_le32(3);
- __le32 scan_assoc_time_le = cpu_to_le32(40);
- __le32 scan_unassoc_time_le = cpu_to_le32(40);
- int i;
+ s8 eventmask[BRCMF_EVENTING_MASK_LEN];
+ u8 buf[BRCMF_DCMD_SMLEN];
+ char *ptr;
+ s32 err;
struct brcmf_bus_dcmd *cmdlst;
struct list_head *cur, *q;
- mutex_lock(&drvr->proto_block);
-
- /* Set Country code */
- if (drvr->country_code[0] != 0) {
- if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
- drvr->country_code,
- sizeof(drvr->country_code)) < 0)
- brcmf_dbg(ERROR, "country code setting failed\n");
+ /* retreive mac address */
+ err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
+ sizeof(ifp->mac_addr));
+ if (err < 0) {
+ brcmf_dbg(ERROR, "Retreiving cur_etheraddr failed, %d\n",
+ err);
+ goto done;
}
+ memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
/* query for 'ver' to get version info from firmware */
memset(buf, 0, sizeof(buf));
- ptr = buf;
- brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
- brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
+ strcpy(buf, "ver");
+ err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
+ if (err < 0) {
+ brcmf_dbg(ERROR, "Retreiving version information failed, %d\n",
+ err);
+ goto done;
+ }
+ ptr = (char *)buf;
strsep(&ptr, "\n");
/* Print fw version info */
brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
- /* Setup timeout if Beacons are lost and roam is off to report
- link down */
- brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf,
- sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
+ /*
+ * Setup timeout if Beacons are lost and roam is off to report
+ * link down
+ */
+ err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout",
+ BRCMF_DEFAULT_BCN_TIMEOUT);
+ if (err) {
+ brcmf_dbg(ERROR, "bcn_timeout error (%d)\n", err);
+ goto done;
+ }
/* Enable/Disable build-in roaming to allowed ext supplicant to take
- of romaing */
- brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- /* Setup event_msgs */
- brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
- (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
- (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le));
-
- /* Set and enable ARP offload feature */
- brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
- brcmf_c_arp_offload_enable(drvr, true);
-
- /* Set up pkt filter */
- for (i = 0; i < drvr->pktfilter_count; i++) {
- brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
- brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
- 0, true);
+ * of romaing
+ */
+ err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
+ if (err) {
+ brcmf_dbg(ERROR, "roam_off error (%d)\n", err);
+ goto done;
+ }
+
+ /* Setup event_msgs, enable E_IF */
+ err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
+ BRCMF_EVENTING_MASK_LEN);
+ if (err) {
+ brcmf_dbg(ERROR, "Get event_msgs error (%d)\n", err);
+ goto done;
+ }
+ setbit(eventmask, BRCMF_E_IF);
+ err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
+ BRCMF_EVENTING_MASK_LEN);
+ if (err) {
+ brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err);
+ goto done;
+ }
+
+ /* Setup default scan channel time */
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
+ BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
+ if (err) {
+ brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
+ err);
+ goto done;
}
+ /* Setup default scan unassoc time */
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
+ BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
+ if (err) {
+ brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
+ err);
+ goto done;
+ }
+
+ /* Try to set and enable ARP offload feature, this may fail */
+ err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
+ if (err) {
+ brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+ BRCMF_ARPOL_MODE, err);
+ err = 0;
+ } else {
+ err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
+ if (err) {
+ brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
+ err);
+ err = 0;
+ } else
+ brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
+ BRCMF_ARPOL_MODE);
+ }
+
+ /* Setup packet filter */
+ brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
+ brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
+ 0, true);
+
/* set bus specific command if there is any */
- list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) {
+ list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) {
cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
- brcmf_c_mkiovar(cmdlst->name, cmdlst->param,
- cmdlst->param_len, iovbuf,
- sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
+ brcmf_fil_iovar_data_set(ifp, cmdlst->name,
+ cmdlst->param,
+ cmdlst->param_len);
}
list_del(cur);
kfree(cmdlst);
}
-
- mutex_unlock(&drvr->proto_block);
-
- return 0;
+done:
+ return err;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 7f89540..862d2ac 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -16,8 +16,10 @@
#include <linux/debugfs.h>
#include <linux/if_ether.h>
#include <linux/if.h>
+#include <linux/netdevice.h>
#include <linux/ieee80211.h>
#include <linux/module.h>
+#include <linux/netdevice.h>
#include <defs.h>
#include <brcmu_wifi.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index fb508c2..eefa6c2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -31,6 +31,7 @@
#define BRCMF_EVENT_VAL 0x0800
#define BRCMF_BTA_VAL 0x1000
#define BRCMF_ISCAN_VAL 0x2000
+#define BRCMF_FIL_VAL 0x4000
#if defined(DEBUG)
@@ -56,6 +57,7 @@ do { \
#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL)
+#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL)
#else /* (defined DEBUG) || (defined DEBUG) */
@@ -67,6 +69,7 @@ do { \
#define BRCMF_BYTES_ON() 0
#define BRCMF_GLOM_ON() 0
#define BRCMF_EVENT_ON() 0
+#define BRCMF_FIL_ON() 0
#endif /* defined(DEBUG) */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index d7c76ce..2976523 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -52,16 +52,6 @@ MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
MODULE_LICENSE("Dual BSD/GPL");
-/* Interface control information */
-struct brcmf_if {
- struct brcmf_pub *drvr; /* back pointer to brcmf_pub */
- /* OS/stack specifics */
- struct net_device *ndev;
- struct net_device_stats stats;
- int idx; /* iface idx in dongle */
- u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
-};
-
/* Error bits */
int brcmf_msg_level = BRCMF_ERROR_VAL;
module_param(brcmf_msg_level, int, 0);
@@ -629,12 +619,9 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
brcmf_dbg(ERROR, "dongle is not up\n");
return -ENODEV;
}
-
/* finally, report dongle driver type */
- else if (drvr->iswl)
- sprintf(info.driver, "wl");
else
- sprintf(info.driver, "xx");
+ sprintf(info.driver, "wl");
sprintf(info.version, "%lu", drvr->drv_version);
if (copy_to_user(uaddr, &info, sizeof(info)))
@@ -719,65 +706,6 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
return -EOPNOTSUPP;
}
-/* called only from within this driver. Sends a command to the dongle. */
-s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
-{
- struct brcmf_dcmd dcmd;
- s32 err = 0;
- int buflen = 0;
- bool is_set_key_cmd;
- struct brcmf_if *ifp = netdev_priv(ndev);
- struct brcmf_pub *drvr = ifp->drvr;
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = cmd;
- dcmd.buf = arg;
- dcmd.len = len;
-
- if (dcmd.buf != NULL)
- buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
-
- /* send to dongle (must be up, and wl) */
- if ((drvr->bus_if->state != BRCMF_BUS_DATA)) {
- brcmf_dbg(ERROR, "DONGLE_DOWN\n");
- err = -EIO;
- goto done;
- }
-
- if (!drvr->iswl) {
- err = -EIO;
- goto done;
- }
-
- /*
- * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
- * set key CMD to prevent M4 encryption.
- */
- is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
- ((dcmd.cmd == BRCMF_C_SET_VAR) &&
- !(strncmp("wsec_key", dcmd.buf, 9))) ||
- ((dcmd.cmd == BRCMF_C_SET_VAR) &&
- !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
- if (is_set_key_cmd)
- brcmf_netdev_wait_pend8021x(ndev);
-
- err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen);
-
-done:
- if (err > 0)
- err = 0;
-
- return err;
-}
-
-int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd)
-{
- brcmf_dbg(TRACE, "enter: cmd %x buf %p len %d\n",
- dcmd->cmd, dcmd->buf, dcmd->len);
-
- return brcmf_exec_dcmd(ndev, dcmd->cmd, dcmd->buf, dcmd->len);
-}
-
static int brcmf_netdev_stop(struct net_device *ndev)
{
struct brcmf_if *ifp = netdev_priv(ndev);
@@ -851,7 +779,7 @@ static const struct net_device_ops brcmf_netdev_ops_pri = {
.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
};
-static int brcmf_net_attach(struct brcmf_if *ifp)
+int brcmf_net_attach(struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = ifp->drvr;
struct net_device *ndev;
@@ -885,15 +813,6 @@ static int brcmf_net_attach(struct brcmf_if *ifp)
memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
- /* attach to cfg80211 for primary interface */
- if (!ifp->idx) {
- drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
- if (drvr->config == NULL) {
- brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
- goto fail;
- }
- }
-
if (register_netdev(ndev) != 0) {
brcmf_dbg(ERROR, "couldn't register the net device\n");
goto fail;
@@ -905,11 +824,12 @@ static int brcmf_net_attach(struct brcmf_if *ifp)
fail:
ndev->netdev_ops = NULL;
+ free_netdev(ndev);
return -EBADE;
}
-int
-brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
+struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx,
+ char *name, u8 *mac_addr)
{
struct brcmf_if *ifp;
struct net_device *ndev;
@@ -936,7 +856,7 @@ brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
if (!ndev) {
brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
ifp = netdev_priv(ndev);
@@ -944,20 +864,14 @@ brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
ifp->drvr = drvr;
drvr->iflist[ifidx] = ifp;
ifp->idx = ifidx;
+ ifp->bssidx = bssidx;
if (mac_addr != NULL)
memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
- if (brcmf_net_attach(ifp)) {
- brcmf_dbg(ERROR, "brcmf_net_attach failed");
- free_netdev(ifp->ndev);
- drvr->iflist[ifidx] = NULL;
- return -EOPNOTSUPP;
- }
-
brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
current->pid, ifp->ndev->name);
- return 0;
+ return ifp;
}
void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
@@ -1036,10 +950,9 @@ fail:
int brcmf_bus_start(struct device *dev)
{
int ret = -1;
- /* Room for "event_msgs" + '\0' + bitvec */
- char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_if *ifp;
brcmf_dbg(TRACE, "\n");
@@ -1050,49 +963,30 @@ int brcmf_bus_start(struct device *dev)
return ret;
}
- brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
- sizeof(iovbuf));
- memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
-
- setbit(drvr->eventmask, BRCMF_E_SET_SSID);
- setbit(drvr->eventmask, BRCMF_E_PRUNE);
- setbit(drvr->eventmask, BRCMF_E_AUTH);
- setbit(drvr->eventmask, BRCMF_E_REASSOC);
- setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
- setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_DISASSOC);
- setbit(drvr->eventmask, BRCMF_E_JOIN);
- setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
- setbit(drvr->eventmask, BRCMF_E_LINK);
- setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
- setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
- setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
- setbit(drvr->eventmask, BRCMF_E_TXFAIL);
- setbit(drvr->eventmask, BRCMF_E_JOIN_START);
- setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
-
-/* enable dongle roaming event */
-
- drvr->pktfilter_count = 1;
- /* Setup filter to allow only unicast */
- drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
-
- /* Bus is ready, do any protocol initialization */
- ret = brcmf_proto_init(drvr);
+ /* add primary networking interface */
+ ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL);
+ if (IS_ERR(ifp))
+ return PTR_ERR(ifp);
+
+ /* signal bus ready */
+ bus_if->state = BRCMF_BUS_DATA;
+
+ /* Bus is ready, do any initialization */
+ ret = brcmf_c_preinit_dcmds(ifp);
if (ret < 0)
return ret;
- /* add primary networking interface */
- ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac);
- if (ret < 0)
+ drvr->config = brcmf_cfg80211_attach(drvr);
+ if (drvr->config == NULL)
+ return -ENOMEM;
+
+ ret = brcmf_net_attach(ifp);
+ if (ret < 0) {
+ brcmf_dbg(ERROR, "brcmf_net_attach failed");
+ drvr->iflist[0] = NULL;
return ret;
+ }
- /* signal bus ready */
- bus_if->state = BRCMF_BUS_DATA;
return 0;
}
@@ -1163,42 +1057,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
return pend;
}
-#ifdef DEBUG
-int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
-{
- int ret = 0;
- struct file *fp;
- mm_segment_t old_fs;
- loff_t pos = 0;
-
- /* change to KERNEL_DS address limit */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- /* open file to write */
- fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
- if (!fp) {
- brcmf_dbg(ERROR, "open file error\n");
- ret = -1;
- goto exit;
- }
-
- /* Write buf to file */
- fp->f_op->write(fp, (char __user *)buf, size, &pos);
-
-exit:
- /* free buf before return */
- kfree(buf);
- /* close file before return */
- if (fp)
- filp_close(fp, NULL);
- /* restore previous address limit */
- set_fs(old_fs);
-
- return ret;
-}
-#endif /* DEBUG */
-
static void brcmf_driver_init(struct work_struct *work)
{
brcmf_debugfs_init();
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
index 6bc4425..7fe6779 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -27,11 +27,6 @@ extern int brcmf_proto_attach(struct brcmf_pub *drvr);
/* Unlink, frees allocated protocol memory (including brcmf_proto) */
extern void brcmf_proto_detach(struct brcmf_pub *drvr);
-/* Initialize protocol: sync w/dongle state.
- * Sets dongle media info (iswl, drv_version, mac address).
- */
-extern int brcmf_proto_init(struct brcmf_pub *drvr);
-
/* Stop protocol: sync w/dongle state. */
extern void brcmf_proto_stop(struct brcmf_pub *drvr);
@@ -45,7 +40,8 @@ extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
struct brcmf_dcmd *dcmd, int len);
-extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
+/* Sets dongle media info (drv_version, mac address). */
+extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 3564686..415f2be 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -614,6 +614,12 @@ static const uint max_roundup = 512;
#define ALIGNMENT 4
+enum brcmf_sdio_frmtype {
+ BRCMF_SDIO_FT_NORMAL,
+ BRCMF_SDIO_FT_SUPER,
+ BRCMF_SDIO_FT_SUB,
+};
+
static void pkt_align(struct sk_buff *p, int len, int align)
{
uint datalign;
@@ -1032,7 +1038,8 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
}
static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
- struct brcmf_sdio_read *rd)
+ struct brcmf_sdio_read *rd,
+ enum brcmf_sdio_frmtype type)
{
u16 len, checksum;
u8 rx_seq, fc, tx_seq_max;
@@ -1059,6 +1066,15 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
brcmf_dbg(ERROR, "HW header length error\n");
return false;
}
+ if (type == BRCMF_SDIO_FT_SUPER &&
+ (roundup(len, bus->blocksize) != rd->len)) {
+ brcmf_dbg(ERROR, "HW superframe header length error\n");
+ return false;
+ }
+ if (type == BRCMF_SDIO_FT_SUB && len > rd->len) {
+ brcmf_dbg(ERROR, "HW subframe header length error\n");
+ return false;
+ }
rd->len = len;
/*
@@ -1071,9 +1087,16 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
* Byte 5: Maximum Sequence number allow for Tx
* Byte 6~7: Reserved
*/
+ if (type == BRCMF_SDIO_FT_SUPER &&
+ SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) {
+ brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n");
+ rd->len = 0;
+ return false;
+ }
rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]);
rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]);
- if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL) {
+ if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
+ type != BRCMF_SDIO_FT_SUPER) {
brcmf_dbg(ERROR, "HW header length too long\n");
bus->sdiodev->bus_if->dstats.rx_errors++;
bus->sdcnt.rx_toolong++;
@@ -1081,6 +1104,17 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
rd->len = 0;
return false;
}
+ if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) {
+ brcmf_dbg(ERROR, "Wrong channel for superframe\n");
+ rd->len = 0;
+ return false;
+ }
+ if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL &&
+ rd->channel != SDPCM_EVENT_CHANNEL) {
+ brcmf_dbg(ERROR, "Wrong channel for subframe\n");
+ rd->len = 0;
+ return false;
+ }
rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]);
if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
brcmf_dbg(ERROR, "seq %d: bad data offset\n", rx_seq);
@@ -1095,6 +1129,9 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
bus->sdcnt.rx_badseq++;
rd->seq_num = rx_seq;
}
+ /* no need to check the reset for subframe */
+ if (type == BRCMF_SDIO_FT_SUB)
+ return true;
rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
/* only warm for NON glom packet */
@@ -1126,16 +1163,16 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
u16 dlen, totlen;
u8 *dptr, num = 0;
- u16 sublen, check;
+ u16 sublen;
struct sk_buff *pfirst, *pnext;
int errcode;
- u8 chan, seq, doff, sfdoff;
- u8 txmax;
+ u8 doff, sfdoff;
int ifidx = 0;
bool usechain = bus->use_rxchain;
- u16 next_len;
+
+ struct brcmf_sdio_read rd_new;
/* If packets, issue read(s) and send up packet chain */
/* Return sequence numbers consumed? */
@@ -1279,68 +1316,15 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->data, min_t(int, pfirst->len, 48),
"SUPERFRAME:\n");
- /* Validate the superframe header */
- dptr = (u8 *) (pfirst->data);
- sublen = get_unaligned_le16(dptr);
- check = get_unaligned_le16(dptr + sizeof(u16));
-
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
- next_len = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
- if ((next_len << 4) > MAX_RX_DATASZ) {
- brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
- next_len, seq);
- next_len = 0;
- }
- bus->cur_read.len = next_len << 4;
- doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
- txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-
- errcode = 0;
- if ((u16)~(sublen ^ check)) {
- brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
- sublen, check);
- errcode = -1;
- } else if (roundup(sublen, bus->blocksize) != dlen) {
- brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
- sublen, roundup(sublen, bus->blocksize),
- dlen);
- errcode = -1;
- } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
- SDPCM_GLOM_CHANNEL) {
- brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
- SDPCM_PACKET_CHANNEL(
- &dptr[SDPCM_FRAMETAG_LEN]));
- errcode = -1;
- } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
- brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
- errcode = -1;
- } else if ((doff < SDPCM_HDRLEN) ||
- (doff > (pfirst->len - SDPCM_HDRLEN))) {
- brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
- doff, sublen, pfirst->len, SDPCM_HDRLEN);
- errcode = -1;
- }
-
- /* Check sequence number of superframe SW header */
- if (rxseq != seq) {
- brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
- seq, rxseq);
- bus->sdcnt.rx_badseq++;
- rxseq = seq;
- }
-
- /* Check window for sanity */
- if ((u8) (txmax - bus->tx_seq) > 0x40) {
- brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
- txmax, bus->tx_seq);
- txmax = bus->tx_seq + 2;
- }
- bus->tx_max = txmax;
+ rd_new.seq_num = rxseq;
+ rd_new.len = dlen;
+ errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
+ BRCMF_SDIO_FT_SUPER);
+ bus->cur_read.len = rd_new.len_nxtfrm << 4;
/* Remove superframe header, remember offset */
- skb_pull(pfirst, doff);
- sfdoff = doff;
+ skb_pull(pfirst, rd_new.dat_offset);
+ sfdoff = rd_new.dat_offset;
num = 0;
/* Validate all the subframe headers */
@@ -1349,34 +1333,14 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
if (errcode)
break;
- dptr = (u8 *) (pnext->data);
- dlen = (u16) (pnext->len);
- sublen = get_unaligned_le16(dptr);
- check = get_unaligned_le16(dptr + sizeof(u16));
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+ rd_new.len = pnext->len;
+ rd_new.seq_num = rxseq++;
+ errcode = -!brcmf_sdio_hdparser(bus, pnext->data,
+ &rd_new,
+ BRCMF_SDIO_FT_SUB);
brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
- dptr, 32, "subframe:\n");
+ pnext->data, 32, "subframe:\n");
- if ((u16)~(sublen ^ check)) {
- brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
- num, sublen, check);
- errcode = -1;
- } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
- brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
- num, sublen, dlen);
- errcode = -1;
- } else if ((chan != SDPCM_DATA_CHANNEL) &&
- (chan != SDPCM_EVENT_CHANNEL)) {
- brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
- num, chan);
- errcode = -1;
- } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
- brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
- num, doff, sublen, SDPCM_HDRLEN);
- errcode = -1;
- }
- /* increase the subframe count */
num++;
}
@@ -1402,27 +1366,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
dptr = (u8 *) (pfirst->data);
sublen = get_unaligned_le16(dptr);
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
- brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
- num, pfirst, pfirst->data,
- pfirst->len, sublen, chan, seq);
-
- /* precondition: chan == SDPCM_DATA_CHANNEL ||
- chan == SDPCM_EVENT_CHANNEL */
-
- if (rxseq != seq) {
- brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
- seq, rxseq);
- bus->sdcnt.rx_badseq++;
- rxseq = seq;
- }
- rxseq++;
-
brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
- dptr, dlen, "Rx Subframe Data:\n");
+ dptr, pfirst->len,
+ "Rx Subframe Data:\n");
__skb_trim(pfirst, sublen);
skb_pull(pfirst, doff);
@@ -1642,7 +1590,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->rxhdr, SDPCM_HDRLEN,
"RxHdr:\n");
- if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd)) {
+ if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
+ BRCMF_SDIO_FT_NORMAL)) {
if (!bus->rxpending)
break;
else
@@ -1701,7 +1650,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
} else {
memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
rd_new.seq_num = rd->seq_num;
- if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new)) {
+ if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
+ BRCMF_SDIO_FT_NORMAL)) {
rd->len = 0;
brcmu_pkt_buf_free_skb(pkt);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
new file mode 100644
index 0000000..4b272c3
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2012 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* FWIL is the Firmware Interface Layer. In this module the support functions
+ * are located to set and get variables to and from the firmware.
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <defs.h>
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+#include "dhd.h"
+#include "dhd_bus.h"
+#include "dhd_dbg.h"
+#include "fwil.h"
+
+
+static s32
+brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ s32 err;
+
+ if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
+ brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
+ return -EIO;
+ }
+
+ if (data != NULL)
+ len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
+ if (set)
+ err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len);
+ else
+ err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data,
+ len);
+
+ if (err >= 0)
+ err = 0;
+ else
+ brcmf_dbg(ERROR, "Failed err=%d\n", err);
+
+ return err;
+}
+
+s32
+brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
+{
+ s32 err;
+
+ mutex_lock(&ifp->drvr->proto_block);
+
+ brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ err = brcmf_fil_cmd_data(ifp, cmd, data, len, true);
+ mutex_unlock(&ifp->drvr->proto_block);
+
+ return err;
+}
+
+s32
+brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len)
+{
+ s32 err;
+
+ mutex_lock(&ifp->drvr->proto_block);
+ err = brcmf_fil_cmd_data(ifp, cmd, data, len, false);
+
+ brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ mutex_unlock(&ifp->drvr->proto_block);
+
+ return err;
+}
+
+
+s32
+brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data)
+{
+ s32 err;
+ __le32 data_le = cpu_to_le32(data);
+
+ mutex_lock(&ifp->drvr->proto_block);
+ err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true);
+ mutex_unlock(&ifp->drvr->proto_block);
+
+ return err;
+}
+
+s32
+brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data)
+{
+ s32 err;
+ __le32 data_le = cpu_to_le32(*data);
+
+ mutex_lock(&ifp->drvr->proto_block);
+ err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false);
+ mutex_unlock(&ifp->drvr->proto_block);
+ *data = le32_to_cpu(data_le);
+
+ return err;
+}
+
+static u32
+brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen)
+{
+ u32 len;
+
+ len = strlen(name) + 1;
+
+ if ((len + datalen) > buflen)
+ return 0;
+
+ memcpy(buf, name, len);
+
+ /* append data onto the end of the name string */
+ if (data && datalen)
+ memcpy(&buf[len], data, datalen);
+
+ return len + datalen;
+}
+
+
+s32
+brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
+ u32 len)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ s32 err;
+ u32 buflen;
+
+ mutex_lock(&drvr->proto_block);
+
+ brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf,
+ sizeof(drvr->proto_buf));
+ if (buflen) {
+ err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf,
+ buflen, true);
+ } else {
+ err = -EPERM;
+ brcmf_dbg(ERROR, "Creating iovar failed\n");
+ }
+
+ mutex_unlock(&drvr->proto_block);
+ return err;
+}
+
+s32
+brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
+ u32 len)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ s32 err;
+ u32 buflen;
+
+ mutex_lock(&drvr->proto_block);
+
+ buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf,
+ sizeof(drvr->proto_buf));
+ if (buflen) {
+ err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf,
+ buflen, false);
+ if (err == 0)
+ memcpy(data, drvr->proto_buf, len);
+ } else {
+ err = -EPERM;
+ brcmf_dbg(ERROR, "Creating iovar failed\n");
+ }
+
+ brcmf_dbg(FIL, "name=%s, len=%d\n", name, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ mutex_unlock(&drvr->proto_block);
+ return err;
+}
+
+s32
+brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data)
+{
+ __le32 data_le = cpu_to_le32(data);
+
+ return brcmf_fil_iovar_data_set(ifp, name, &data_le, sizeof(data_le));
+}
+
+s32
+brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data)
+{
+ __le32 data_le = cpu_to_le32(*data);
+ s32 err;
+
+ err = brcmf_fil_iovar_data_get(ifp, name, &data_le, sizeof(data_le));
+ if (err == 0)
+ *data = le32_to_cpu(data_le);
+ return err;
+}
+
+static u32
+brcmf_create_bsscfg(s32 bssidx, char *name, char *data, u32 datalen, char *buf,
+ u32 buflen)
+{
+ const s8 *prefix = "bsscfg:";
+ s8 *p;
+ u32 prefixlen;
+ u32 namelen;
+ u32 iolen;
+ __le32 bssidx_le;
+
+ if (bssidx == 0)
+ return brcmf_create_iovar(name, data, datalen, buf, buflen);
+
+ prefixlen = strlen(prefix);
+ namelen = strlen(name) + 1; /* lengh of iovar name + null */
+ iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
+
+ if (buflen < iolen) {
+ brcmf_dbg(ERROR, "buffer is too short\n");
+ return 0;
+ }
+
+ p = buf;
+
+ /* copy prefix, no null */
+ memcpy(p, prefix, prefixlen);
+ p += prefixlen;
+
+ /* copy iovar name including null */
+ memcpy(p, name, namelen);
+ p += namelen;
+
+ /* bss config index as first data */
+ bssidx_le = cpu_to_le32(bssidx);
+ memcpy(p, &bssidx_le, sizeof(bssidx_le));
+ p += sizeof(bssidx_le);
+
+ /* parameter buffer follows */
+ if (datalen)
+ memcpy(p, data, datalen);
+
+ return iolen;
+}
+
+s32
+brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name,
+ void *data, u32 len)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ s32 err;
+ u32 buflen;
+
+ mutex_lock(&drvr->proto_block);
+
+ brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
+ drvr->proto_buf, sizeof(drvr->proto_buf));
+ if (buflen) {
+ err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf,
+ buflen, true);
+ } else {
+ err = -EPERM;
+ brcmf_dbg(ERROR, "Creating bsscfg failed\n");
+ }
+
+ mutex_unlock(&drvr->proto_block);
+ return err;
+}
+
+s32
+brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
+ void *data, u32 len)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ s32 err;
+ u32 buflen;
+
+ mutex_lock(&drvr->proto_block);
+
+ buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len,
+ drvr->proto_buf, sizeof(drvr->proto_buf));
+ if (buflen) {
+ err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf,
+ buflen, false);
+ if (err == 0)
+ memcpy(data, drvr->proto_buf, len);
+ } else {
+ err = -EPERM;
+ brcmf_dbg(ERROR, "Creating bsscfg failed\n");
+ }
+ brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len);
+ brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data");
+
+ mutex_unlock(&drvr->proto_block);
+ return err;
+
+}
+
+s32
+brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data)
+{
+ __le32 data_le = cpu_to_le32(data);
+
+ return brcmf_fil_bsscfg_data_set(ifp, name, &data_le,
+ sizeof(data_le));
+}
+
+s32
+brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data)
+{
+ __le32 data_le = cpu_to_le32(*data);
+ s32 err;
+
+ err = brcmf_fil_bsscfg_data_get(ifp, name, &data_le,
+ sizeof(data_le));
+ if (err == 0)
+ *data = le32_to_cpu(data_le);
+ return err;
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
new file mode 100644
index 0000000..16eb820
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _fwil_h_
+#define _fwil_h_
+
+s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
+s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
+s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
+s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data);
+
+s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
+ u32 len);
+s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
+ u32 len);
+s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data);
+s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data);
+
+s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, void *data,
+ u32 len);
+s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, void *data,
+ u32 len);
+s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data);
+s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data);
+
+#endif /* _fwil_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index a2b4b1e..484a6e4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -42,7 +42,6 @@
#define IOCTL_RESP_TIMEOUT 2000
-#define BRCMF_USB_SYNC_TIMEOUT 300 /* ms */
#define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */
#define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */
@@ -116,10 +115,6 @@ struct brcmf_usbdev_info {
u8 *image; /* buffer for combine fw and nvram */
int image_len;
- wait_queue_head_t wait;
- bool waitdone;
- int sync_urb_status;
-
struct usb_device *usbdev;
struct device *dev;
@@ -131,7 +126,6 @@ struct brcmf_usbdev_info {
int ctl_urb_status;
int ctl_completed;
wait_queue_head_t ioctl_resp_wait;
- wait_queue_head_t ctrl_wait;
ulong ctl_op;
struct urb *bulk_urb; /* used for FW download */
@@ -754,34 +748,14 @@ static void brcmf_usb_down(struct device *dev)
brcmf_usb_free_q(&devinfo->rx_postq, true);
}
-static int
-brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time)
-{
- int ret;
- int err = 0;
- int ms = time;
-
- ret = wait_event_interruptible_timeout(devinfo->wait,
- devinfo->waitdone == true, (ms * HZ / 1000));
-
- if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) {
- brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n",
- ret, devinfo->sync_urb_status);
- err = -EINVAL;
- }
- devinfo->waitdone = false;
- return err;
-}
-
static void
brcmf_usb_sync_complete(struct urb *urb)
{
struct brcmf_usbdev_info *devinfo =
(struct brcmf_usbdev_info *)urb->context;
- devinfo->waitdone = true;
- wake_up_interruptible(&devinfo->wait);
- devinfo->sync_urb_status = urb->status;
+ devinfo->ctl_completed = true;
+ brcmf_usb_ioctl_resp_wake(devinfo);
}
static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
@@ -813,6 +787,7 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
(void *) tmpbuf, size,
(usb_complete_t)brcmf_usb_sync_complete, devinfo);
+ devinfo->ctl_completed = false;
ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
if (ret < 0) {
brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
@@ -820,11 +795,11 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
return false;
}
- ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
+ ret = brcmf_usb_ioctl_resp_wait(devinfo);
memcpy(buffer, tmpbuf, buflen);
kfree(tmpbuf);
- return (ret == 0);
+ return ret;
}
static bool
@@ -918,13 +893,14 @@ brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len)
devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET;
+ devinfo->ctl_completed = false;
ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC);
if (ret) {
brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
return ret;
}
- ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
- return ret;
+ ret = brcmf_usb_ioctl_resp_wait(devinfo);
+ return (ret == 0);
}
static int
@@ -1284,7 +1260,6 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
goto error;
}
- init_waitqueue_head(&devinfo->wait);
if (!brcmf_usb_dlneeded(devinfo))
return &devinfo->bus_pub;
@@ -1339,7 +1314,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
}
ret = brcmf_bus_start(dev);
- if (ret == -ENOLINK) {
+ if (ret) {
brcmf_dbg(ERROR, "dongle is not responding\n");
brcmf_detach(dev);
goto fail;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 0e95209..cb30fea 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -35,6 +35,7 @@
#include <brcmu_wifi.h>
#include "dhd.h"
#include "wl_cfg80211.h"
+#include "fwil.h"
#define BRCMF_SCAN_IE_LEN_MAX 2048
#define BRCMF_PNO_VERSION 2
@@ -48,6 +49,8 @@
#define BRCMF_PNO_SCAN_COMPLETE 1
#define BRCMF_PNO_SCAN_INCOMPLETE 0
+#define BRCMF_IFACE_MAX_CNT 2
+
#define TLV_LEN_OFF 1 /* length offset */
#define TLV_HDR_LEN 2 /* header length */
#define TLV_BODY_OFF 2 /* body offset */
@@ -91,16 +94,13 @@
#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
-
static u32 brcmf_dbg_level = WL_DBG_ERR;
-static bool check_sys_up(struct wiphy *wiphy)
+static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- if (!test_bit(WL_STATUS_READY, &cfg->status)) {
- WL_INFO("device is not ready : status (%d)\n",
- (int)cfg->status);
+ if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
+ WL_INFO("device is not ready : status (%lu)\n",
+ vif->sme_state);
return false;
}
return true;
@@ -391,55 +391,29 @@ static u8 brcmf_mw_to_qdbm(u16 mw)
return qdbm;
}
-/* function for reading/writing a single u32 from/to the dongle */
-static int
-brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
+static u16 channel_to_chanspec(struct ieee80211_channel *ch)
{
- int err;
- __le32 par_le = cpu_to_le32(*par);
-
- err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
- *par = le32_to_cpu(par_le);
-
- return err;
-}
-
-static s32
-brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
- void *param, s32 paramlen,
- void *buf, s32 buflen, s32 bssidx)
-{
- s32 err = -ENOMEM;
- u32 len;
-
- len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
- buf, buflen, bssidx);
- BUG_ON(!len);
- if (len > 0)
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
- if (err)
- WL_ERR("error (%d)\n", err);
+ u16 chanspec;
- return err;
-}
+ chanspec = ieee80211_frequency_to_channel(ch->center_freq);
+ chanspec &= WL_CHANSPEC_CHAN_MASK;
-static s32
-brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
- void *param, s32 paramlen,
- void *buf, s32 buflen, s32 bssidx)
-{
- s32 err = -ENOMEM;
- u32 len;
-
- len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
- buf, buflen, bssidx);
- BUG_ON(!len);
- if (len > 0)
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
- if (err)
- WL_ERR("error (%d)\n", err);
+ if (ch->band == IEEE80211_BAND_2GHZ)
+ chanspec |= WL_CHANSPEC_BAND_2G;
+ else
+ chanspec |= WL_CHANSPEC_BAND_5G;
- return err;
+ if (ch->flags & IEEE80211_CHAN_NO_HT40) {
+ chanspec |= WL_CHANSPEC_BW_20;
+ chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+ } else {
+ chanspec |= WL_CHANSPEC_BW_40;
+ if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
+ chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
+ else
+ chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
+ }
+ return chanspec;
}
static void convert_key_from_CPU(struct brcmf_wsec_key *key,
@@ -457,18 +431,17 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
}
static int
-send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
- struct net_device *ndev, struct brcmf_wsec_key *key)
+send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
{
int err;
struct brcmf_wsec_key_le key_le;
convert_key_from_CPU(key, &key_le);
- err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
- sizeof(key_le),
- cfg->extra_buf,
- WL_EXTRA_BUF_MAX, bssidx);
+ brcmf_netdev_wait_pend8021x(ndev);
+
+ err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
+ sizeof(key_le));
if (err)
WL_ERR("wsec_key error (%d)\n", err);
@@ -480,6 +453,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
s32 infra = 0;
s32 ap = 0;
@@ -511,7 +485,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
}
if (ap) {
- set_bit(WL_STATUS_AP_CREATING, &cfg->status);
+ set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
if (!cfg->ap_info)
cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
GFP_KERNEL);
@@ -521,7 +495,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
}
WL_INFO("IF Type = AP\n");
} else {
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
+ BRCMF_C_SET_INFRA, infra);
if (err) {
WL_ERR("WLC_SET_INFRA error (%d)\n", err);
err = -EAGAIN;
@@ -539,99 +514,13 @@ done:
return err;
}
-static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
-{
- s8 buf[BRCMF_DCMD_SMLEN];
- u32 len;
- s32 err = 0;
- __le32 val_le;
-
- val_le = cpu_to_le32(val);
- len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
- sizeof(buf));
- BUG_ON(!len);
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
- if (err)
- WL_ERR("error (%d)\n", err);
-
- return err;
-}
-
-static s32
-brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
-{
- union {
- s8 buf[BRCMF_DCMD_SMLEN];
- __le32 val;
- } var;
- u32 len;
- u32 data_null;
- s32 err = 0;
-
- len =
- brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
- sizeof(var.buf));
- BUG_ON(!len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
- if (err)
- WL_ERR("error (%d)\n", err);
-
- *retval = le32_to_cpu(var.val);
-
- return err;
-}
-
-static s32
-brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
- s32 bssidx)
-{
- s8 buf[BRCMF_DCMD_SMLEN];
- __le32 val_le;
-
- val_le = cpu_to_le32(val);
-
- return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
- sizeof(val_le), buf, sizeof(buf),
- bssidx);
-}
-
-static s32
-brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
- s32 bssidx)
-{
- s8 buf[BRCMF_DCMD_SMLEN];
- s32 err;
- __le32 val_le;
-
- memset(buf, 0, sizeof(buf));
- err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
- sizeof(buf), bssidx);
- if (err == 0) {
- memcpy(&val_le, buf, sizeof(val_le));
- *val = le32_to_cpu(val_le);
- }
- return err;
-}
-
-
-/*
- * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
- * should return the ndev matching bssidx.
- */
-static s32
-brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
-{
- return 0;
-}
-
static void brcmf_set_mpc(struct net_device *ndev, int mpc)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- if (test_bit(WL_STATUS_READY, &cfg->status)) {
- err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
+ if (check_vif_up(ifp->vif)) {
+ err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
if (err) {
WL_ERR("fail to set mpc\n");
return;
@@ -643,7 +532,7 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
struct brcmf_ssid *ssid)
{
- memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
+ memset(params_le->bssid, 0xFF, ETH_ALEN);
params_le->bss_type = DOT11_BSSTYPE_ANY;
params_le->scan_type = 0;
params_le->channel_num = 0;
@@ -658,30 +547,6 @@ static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
}
static s32
-brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(!iolen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
-}
-
-static s32
-brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(!iolen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
-}
-
-static s32
brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
struct brcmf_ssid *ssid, u16 action)
{
@@ -703,8 +568,8 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
params->action = cpu_to_le16(action);
params->scan_duration = cpu_to_le16(0);
- err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
- iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
+ err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan",
+ params, params_size);
if (err) {
if (err == -EBUSY)
WL_INFO("system busy : iscan canceled\n");
@@ -721,7 +586,7 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_ssid ssid;
- __le32 passive_scan;
+ u32 passive_scan;
s32 err = 0;
/* Broadcast scan by default */
@@ -729,9 +594,9 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
iscan->state = WL_ISCAN_STATE_SCANING;
- passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ passive_scan = cfg->active_scan ? 0 : 1;
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
+ BRCMF_C_SET_PASSIVE_SCAN, passive_scan);
if (err) {
WL_ERR("error (%d)\n", err);
return err;
@@ -754,27 +619,27 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids;
struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
- __le32 passive_scan;
+ u32 passive_scan;
bool iscan_req;
bool spec_scan;
s32 err = 0;
u32 SSID_len;
- if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
- WL_ERR("Scanning already : status (%lu)\n", cfg->status);
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN;
}
- if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
- WL_ERR("Scanning being aborted : status (%lu)\n",
- cfg->status);
+ if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
+ WL_ERR("Scanning being aborted: status (%lu)\n",
+ cfg->scan_status);
return -EAGAIN;
}
- if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
- WL_ERR("Connecting : status (%lu)\n",
- cfg->status);
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
+ WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
return -EAGAIN;
}
@@ -792,7 +657,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
}
cfg->scan_request = request;
- set_bit(WL_STATUS_SCANNING, &cfg->status);
+ set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (iscan_req) {
err = brcmf_do_iscan(cfg);
if (!err)
@@ -813,16 +678,16 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
WL_SCAN("Broadcast scan\n");
}
- passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ passive_scan = cfg->active_scan ? 0 : 1;
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
+ passive_scan);
if (err) {
WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
goto scan_out;
}
brcmf_set_mpc(ndev, 0);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
- sizeof(sr->ssid_le));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
+ &sr->ssid_le, sizeof(sr->ssid_le));
if (err) {
if (err == -EBUSY)
WL_INFO("system busy : scan for \"%s\" "
@@ -838,7 +703,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
return 0;
scan_out:
- clear_bit(WL_STATUS_SCANNING, &cfg->status);
+ clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
cfg->scan_request = NULL;
return err;
}
@@ -851,12 +716,10 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
s32 i;
s32 offset;
u16 chanspec;
- u16 channel;
- struct ieee80211_channel *req_channel;
char *ptr;
struct brcmf_ssid_le ssid_le;
- memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
+ memset(params_le->bssid, 0xFF, ETH_ALEN);
params_le->bss_type = DOT11_BSSTYPE_ANY;
params_le->scan_type = 0;
params_le->channel_num = 0;
@@ -876,30 +739,9 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
if (n_channels > 0) {
for (i = 0; i < n_channels; i++) {
- chanspec = 0;
- req_channel = request->channels[i];
- channel = ieee80211_frequency_to_channel(
- req_channel->center_freq);
- if (req_channel->band == IEEE80211_BAND_2GHZ)
- chanspec |= WL_CHANSPEC_BAND_2G;
- else
- chanspec |= WL_CHANSPEC_BAND_5G;
-
- if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
- chanspec |= WL_CHANSPEC_BW_20;
- chanspec |= WL_CHANSPEC_CTL_SB_NONE;
- } else {
- chanspec |= WL_CHANSPEC_BW_40;
- if (req_channel->flags &
- IEEE80211_CHAN_NO_HT40PLUS)
- chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
- else
- chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
- }
-
- chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
+ chanspec = channel_to_chanspec(request->channels[i]);
WL_SCAN("Chan : %d, Channel spec: %x\n",
- channel, chanspec);
+ request->channels[i]->hw_value, chanspec);
params_le->channel_list[i] = cpu_to_le16(chanspec);
}
} else {
@@ -966,7 +808,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
/* Do a scan abort to stop the driver's scan engine */
WL_SCAN("ABORT scan in firmware\n");
memset(&params_le, 0, sizeof(params_le));
- memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
+ memset(params_le.bssid, 0xFF, ETH_ALEN);
params_le.bss_type = DOT11_BSSTYPE_ANY;
params_le.scan_type = 0;
params_le.channel_num = cpu_to_le32(1);
@@ -977,8 +819,8 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
/* Scan is aborted by setting channel_list[0] to -1 */
params_le.channel_list[0] = cpu_to_le16(-1);
/* E-Scan (or anyother type) can be aborted by SCAN */
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &params_le,
- sizeof(params_le));
+ err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
+ &params_le, sizeof(params_le));
if (err)
WL_ERR("Scan abort failed\n");
}
@@ -998,7 +840,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
cfg80211_scan_done(scan_request, aborted);
brcmf_set_mpc(ndev, 1);
}
- if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
+ if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n");
return -EPERM;
}
@@ -1036,8 +878,8 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
params->action = cpu_to_le16(action);
params->sync_id = cpu_to_le16(0x1234);
- err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
- cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
+ err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
+ params, params_size);
if (err) {
if (err == -EBUSY)
WL_INFO("system busy : escan canceled\n");
@@ -1055,16 +897,16 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
struct net_device *ndev, struct cfg80211_scan_request *request)
{
s32 err;
- __le32 passive_scan;
+ u32 passive_scan;
struct brcmf_scan_results *results;
WL_SCAN("Enter\n");
cfg->escan_info.ndev = ndev;
cfg->escan_info.wiphy = wiphy;
cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
- passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ passive_scan = cfg->active_scan ? 0 : 1;
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
+ passive_scan);
if (err) {
WL_ERR("error (%d)\n", err);
return err;
@@ -1086,10 +928,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids;
struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
- __le32 passive_scan;
+ u32 passive_scan;
bool escan_req;
bool spec_scan;
s32 err;
@@ -1097,18 +940,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
WL_SCAN("START ESCAN\n");
- if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
- WL_ERR("Scanning already : status (%lu)\n", cfg->status);
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN;
}
- if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
- WL_ERR("Scanning being aborted : status (%lu)\n",
- cfg->status);
+ if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
+ WL_ERR("Scanning being aborted: status (%lu)\n",
+ cfg->scan_status);
return -EAGAIN;
}
- if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
- WL_ERR("Connecting : status (%lu)\n",
- cfg->status);
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
+ WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
return -EAGAIN;
}
@@ -1128,7 +970,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
}
cfg->scan_request = request;
- set_bit(WL_STATUS_SCANNING, &cfg->status);
+ set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (escan_req) {
err = brcmf_do_escan(cfg, wiphy, ndev, request);
if (!err)
@@ -1149,16 +991,16 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
} else
WL_SCAN("Broadcast scan\n");
- passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
+ passive_scan = cfg->active_scan ? 0 : 1;
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
+ passive_scan);
if (err) {
WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
goto scan_out;
}
brcmf_set_mpc(ndev, 0);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
- sizeof(sr->ssid_le));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
+ &sr->ssid_le, sizeof(sr->ssid_le));
if (err) {
if (err == -EBUSY)
WL_INFO("BUSY: scan for \"%s\" canceled\n",
@@ -1174,7 +1016,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
return 0;
scan_out:
- clear_bit(WL_STATUS_SCANNING, &cfg->status);
+ clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (timer_pending(&cfg->escan_timeout))
del_timer_sync(&cfg->escan_timeout);
cfg->scan_request = NULL;
@@ -1182,8 +1024,7 @@ scan_out:
}
static s32
-brcmf_cfg80211_scan(struct wiphy *wiphy,
- struct cfg80211_scan_request *request)
+brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
struct net_device *ndev = request->wdev->netdev;
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
@@ -1191,7 +1032,8 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(container_of(request->wdev,
+ struct brcmf_cfg80211_vif, wdev)))
return -EIO;
if (cfg->iscan_on)
@@ -1210,7 +1052,8 @@ static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
{
s32 err = 0;
- err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
+ rts_threshold);
if (err)
WL_ERR("Error (%d)\n", err);
@@ -1221,7 +1064,8 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
{
s32 err = 0;
- err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
+ frag_threshold);
if (err)
WL_ERR("Error (%d)\n", err);
@@ -1233,7 +1077,7 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
s32 err = 0;
u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
- err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
if (err) {
WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
return err;
@@ -1245,10 +1089,11 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
@@ -1327,7 +1172,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
if (cfg->link_up) {
ndev = cfg_to_ndev(cfg);
WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
- err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
+ err = brcmf_fil_cmd_data_set(netdev_priv(ndev),
+ BRCMF_C_DISASSOC, NULL, 0);
if (err)
WL_ERR("WLC_DISASSOC failed (%d)\n", err);
cfg->link_up = false;
@@ -1340,7 +1186,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_ibss_params *params)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_join_params join_params;
size_t join_params_size = 0;
s32 err = 0;
@@ -1348,7 +1195,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
s32 bcnprd;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
if (params->ssid)
@@ -1358,7 +1205,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
return -EOPNOTSUPP;
}
- set_bit(WL_STATUS_CONNECTING, &cfg->status);
+ set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
if (params->bssid)
WL_CONN("BSSID: %pM\n", params->bssid);
@@ -1399,7 +1246,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
if (params->privacy)
wsec |= WEP_ENABLED;
- err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
+ err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
if (err) {
WL_ERR("wsec failed (%d)\n", err);
goto done;
@@ -1411,7 +1258,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
else
bcnprd = 100;
- err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
+ err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd);
if (err) {
WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
goto done;
@@ -1434,7 +1281,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
BRCMF_ASSOC_PARAMS_FIXED_SIZE;
memcpy(profile->bssid, params->bssid, ETH_ALEN);
} else {
- memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
+ memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
memset(profile->bssid, 0, ETH_ALEN);
}
@@ -1453,8 +1300,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
/* set channel for starter */
target_channel = cfg->channel;
- err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
- &target_channel);
+ err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL,
+ target_channel);
if (err) {
WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
goto done;
@@ -1465,8 +1312,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
cfg->ibss_starter = false;
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
- &join_params, join_params_size);
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+ &join_params, join_params_size);
if (err) {
WL_ERR("WLC_SET_SSID failed (%d)\n", err);
goto done;
@@ -1474,7 +1321,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
done:
if (err)
- clear_bit(WL_STATUS_CONNECTING, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
WL_TRACE("Exit\n");
return err;
}
@@ -1483,10 +1330,11 @@ static s32
brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
brcmf_link_down(cfg);
@@ -1499,8 +1347,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
static s32 brcmf_set_wpa_version(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1512,7 +1359,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
else
val = WPA_AUTH_DISABLED;
WL_CONN("setting wpa_auth to 0x%0x\n", val);
- err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
if (err) {
WL_ERR("set wpa_auth failed (%d)\n", err);
return err;
@@ -1525,8 +1372,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
static s32 brcmf_set_auth_type(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1552,7 +1398,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
break;
}
- err = brcmf_dev_intvar_set(ndev, "auth", val);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
if (err) {
WL_ERR("set auth failed (%d)\n", err);
return err;
@@ -1566,8 +1412,7 @@ static s32
brcmf_set_set_cipher(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
s32 pval = 0;
s32 gval = 0;
@@ -1617,7 +1462,7 @@ brcmf_set_set_cipher(struct net_device *ndev,
}
WL_CONN("pval (%d) gval (%d)\n", pval, gval);
- err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
if (err) {
WL_ERR("error (%d)\n", err);
return err;
@@ -1633,14 +1478,14 @@ brcmf_set_set_cipher(struct net_device *ndev,
static s32
brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
s32 val = 0;
s32 err = 0;
if (sme->crypto.n_akm_suites) {
- err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
+ err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
+ "wpa_auth", &val);
if (err) {
WL_ERR("could not get wpa_auth (%d)\n", err);
return err;
@@ -1674,7 +1519,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
}
WL_CONN("setting wpa_auth to %d\n", val);
- err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
+ err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
+ "wpa_auth", val);
if (err) {
WL_ERR("could not set wpa_auth (%d)\n", err);
return err;
@@ -1690,13 +1536,11 @@ static s32
brcmf_set_sharedkey(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
struct brcmf_wsec_key key;
s32 val;
s32 err = 0;
- s32 bssidx;
WL_CONN("key len (%d)\n", sme->key_len);
@@ -1739,15 +1583,14 @@ brcmf_set_sharedkey(struct net_device *ndev,
WL_CONN("key length (%d) key index (%d) algo (%d)\n",
key.len, key.index, key.algo);
WL_CONN("key \"%s\"\n", key.data);
- bssidx = brcmf_find_bssidx(cfg, ndev);
- err = send_key_to_dongle(cfg, bssidx, ndev, &key);
+ err = send_key_to_dongle(ndev, &key);
if (err)
return err;
if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
WL_CONN("set auth_type to shared key\n");
val = WL_AUTH_SHARED_KEY; /* shared key */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
+ err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
if (err)
WL_ERR("set auth failed (%d)\n", err);
}
@@ -1759,7 +1602,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct ieee80211_channel *chan = sme->channel;
struct brcmf_join_params join_params;
size_t join_params_size;
@@ -1768,7 +1612,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
if (!sme->ssid) {
@@ -1776,7 +1620,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
return -EOPNOTSUPP;
}
- set_bit(WL_STATUS_CONNECTING, &cfg->status);
+ set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
if (chan) {
cfg->channel =
@@ -1827,7 +1671,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
- memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
+ memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
WL_CONN("ssid \"%s\", len (%d)\n",
@@ -1835,14 +1679,14 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
brcmf_ch_to_chanspec(cfg->channel,
&join_params, &join_params_size);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
- &join_params, join_params_size);
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+ &join_params, join_params_size);
if (err)
WL_ERR("WLC_SET_SSID failed (%d)\n", err);
done:
if (err)
- clear_bit(WL_STATUS_CONNECTING, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
WL_TRACE("Exit\n");
return err;
}
@@ -1852,20 +1696,21 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
u16 reason_code)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_scb_val_le scbval;
s32 err = 0;
WL_TRACE("Enter. Reason code = %d\n", reason_code);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
- clear_bit(WL_STATUS_CONNECTED, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
scbval.val = cpu_to_le32(reason_code);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
- sizeof(struct brcmf_scb_val_le));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
+ &scbval, sizeof(scbval));
if (err)
WL_ERR("error (%d)\n", err);
@@ -1882,13 +1727,14 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(ndev);
u16 txpwrmw;
s32 err = 0;
s32 disable = 0;
s32 dbm = MBM_TO_DBM(mbm);
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
switch (type) {
@@ -1905,7 +1751,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
}
/* Make sure radio is off or on as far as software is concerned */
disable = WL_RADIO_SW_DISABLE << 16;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
if (err)
WL_ERR("WLC_SET_RADIO error (%d)\n", err);
@@ -1913,8 +1759,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
txpwrmw = 0xffff;
else
txpwrmw = (u16) dbm;
- err = brcmf_dev_intvar_set(ndev, "qtxpower",
- (s32) (brcmf_mw_to_qdbm(txpwrmw)));
+ err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
+ (s32)brcmf_mw_to_qdbm(txpwrmw));
if (err)
WL_ERR("qtxpower error (%d)\n", err);
cfg->conf->tx_power = dbm;
@@ -1927,16 +1773,16 @@ done:
static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
s32 txpwrdbm;
u8 result;
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
- err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
+ err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
if (err) {
WL_ERR("error (%d)\n", err);
goto done;
@@ -1954,19 +1800,17 @@ static s32
brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool unicast, bool multicast)
{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
u32 index;
u32 wsec;
s32 err = 0;
- s32 bssidx;
WL_TRACE("Enter\n");
WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
- bssidx = brcmf_find_bssidx(cfg, ndev);
- err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
+ err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
WL_ERR("WLC_GET_WSEC error (%d)\n", err);
goto done;
@@ -1975,8 +1819,8 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
if (wsec & WEP_ENABLED) {
/* Just select a new current key */
index = key_idx;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
- &index);
+ err = brcmf_fil_cmd_int_set(ifp,
+ BRCMF_C_SET_KEY_PRIMARY, index);
if (err)
WL_ERR("error (%d)\n", err);
}
@@ -1989,11 +1833,8 @@ static s32
brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, const u8 *mac_addr, struct key_params *params)
{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_wsec_key key;
- struct brcmf_wsec_key_le key_le;
s32 err = 0;
- s32 bssidx;
memset(&key, 0, sizeof(key));
key.index = (u32) key_idx;
@@ -2002,11 +1843,10 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
if (!is_multicast_ether_addr(mac_addr))
memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
key.len = (u32) params->key_len;
- bssidx = brcmf_find_bssidx(cfg, ndev);
/* check for key index change */
if (key.len == 0) {
/* key delete */
- err = send_key_to_dongle(cfg, bssidx, ndev, &key);
+ err = send_key_to_dongle(ndev, &key);
if (err)
WL_ERR("key delete error (%d)\n", err);
} else {
@@ -2061,13 +1901,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
return -EINVAL;
}
- convert_key_from_CPU(&key, &key_le);
-
- brcmf_netdev_wait_pend8021x(ndev);
- err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
- sizeof(key_le),
- cfg->extra_buf,
- WL_EXTRA_BUF_MAX, bssidx);
+ err = send_key_to_dongle(ndev, &key);
if (err)
WL_ERR("wsec_key error (%d)\n", err);
}
@@ -2080,16 +1914,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
struct key_params *params)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_wsec_key key;
s32 val;
s32 wsec;
s32 err = 0;
u8 keybuf[8];
- s32 bssidx;
WL_TRACE("Enter\n");
WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
if (mac_addr) {
@@ -2147,18 +1981,17 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
- bssidx = brcmf_find_bssidx(cfg, ndev);
- err = send_key_to_dongle(cfg, bssidx, ndev, &key);
+ err = send_key_to_dongle(ndev, &key);
if (err)
goto done;
- err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
+ err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
WL_ERR("get wsec error (%d)\n", err);
goto done;
}
wsec |= val;
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err) {
WL_ERR("set wsec error (%d)\n", err);
goto done;
@@ -2173,13 +2006,12 @@ static s32
brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool pairwise, const u8 *mac_addr)
{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_wsec_key key;
s32 err = 0;
- s32 bssidx;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
memset(&key, 0, sizeof(key));
@@ -2191,8 +2023,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
WL_CONN("key index (%d)\n", key_idx);
/* Set the new key/index */
- bssidx = brcmf_find_bssidx(cfg, ndev);
- err = send_key_to_dongle(cfg, bssidx, ndev, &key);
+ err = send_key_to_dongle(ndev, &key);
if (err) {
if (err == -EINVAL) {
if (key.index >= DOT11_MAX_DEFAULT_KEYS)
@@ -2213,22 +2044,20 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
void (*callback) (void *cookie, struct key_params * params))
{
struct key_params params;
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_security *sec;
s32 wsec;
s32 err = 0;
- s32 bssidx;
WL_TRACE("Enter\n");
WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
memset(&params, 0, sizeof(params));
- bssidx = brcmf_find_bssidx(cfg, ndev);
- err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
+ err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
WL_ERR("WLC_GET_WSEC error (%d)\n", err);
/* Ignore this error, may happen during DISASSOC */
@@ -2280,33 +2109,33 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
u8 *mac, struct station_info *sinfo)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_scb_val_le scb_val;
int rssi;
s32 rate;
s32 err = 0;
u8 *bssid = profile->bssid;
- struct brcmf_sta_info_le *sta_info_le;
+ struct brcmf_sta_info_le sta_info_le;
WL_TRACE("Enter, MAC %pM\n", mac);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
if (cfg->conf->mode == WL_MODE_AP) {
- err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
- cfg->dcmd_buf,
- WL_DCMD_LEN_MAX);
+ memcpy(&sta_info_le, mac, ETH_ALEN);
+ err = brcmf_fil_iovar_data_get(ifp, "sta_info",
+ &sta_info_le,
+ sizeof(sta_info_le));
if (err < 0) {
WL_ERR("GET STA INFO failed, %d\n", err);
goto done;
}
- sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
-
sinfo->filled = STATION_INFO_INACTIVE_TIME;
- sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
- if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
+ sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
+ if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
sinfo->filled |= STATION_INFO_CONNECTED_TIME;
- sinfo->connected_time = le32_to_cpu(sta_info_le->in);
+ sinfo->connected_time = le32_to_cpu(sta_info_le.in);
}
WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
sinfo->inactive_time, sinfo->connected_time);
@@ -2318,7 +2147,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
/* Report the current tx rate */
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
if (err) {
WL_ERR("Could not get rate (%d)\n", err);
goto done;
@@ -2328,10 +2157,11 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
WL_CONN("Rate %d Mbps\n", rate / 2);
}
- if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
memset(&scb_val, 0, sizeof(scb_val));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
- sizeof(scb_val));
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
+ &scb_val, sizeof(scb_val));
if (err) {
WL_ERR("Could not get rssi (%d)\n", err);
goto done;
@@ -2356,6 +2186,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
s32 pm;
s32 err = 0;
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
WL_TRACE("Enter\n");
@@ -2367,7 +2198,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
* FW later while initializing the dongle
*/
cfg->pwr_save = enabled;
- if (!test_bit(WL_STATUS_READY, &cfg->status)) {
+ if (!check_vif_up(ifp->vif)) {
WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
goto done;
@@ -2376,7 +2207,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
pm = enabled ? PM_FAST : PM_OFF;
WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
if (err) {
if (err == -ENODEV)
WL_ERR("net_device is not ready yet\n");
@@ -2393,6 +2224,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
const u8 *addr,
const struct cfg80211_bitrate_mask *mask)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcm_rateset_le rateset_le;
s32 rate;
s32 val;
@@ -2402,13 +2234,13 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
/* addr param is always NULL. ignore it */
/* Get current rateset */
- err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
- sizeof(rateset_le));
+ err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET,
+ &rateset_le, sizeof(rateset_le));
if (err) {
WL_ERR("could not get current rateset (%d)\n", err);
goto done;
@@ -2435,8 +2267,8 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
* Set rate override,
* Since the is a/b/g-blind, both a/bg_rate are enforced.
*/
- err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
- err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
+ err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
+ err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
if (err_bg && err_a) {
WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
err = err_bg | err_a;
@@ -2565,7 +2397,8 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
+ err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
+ buf, WL_BSS_INFO_MAX);
if (err) {
WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
goto CleanUp;
@@ -2674,7 +2507,7 @@ brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
return false;
}
-struct brcmf_vs_tlv *
+static struct brcmf_vs_tlv *
brcmf_find_wpaie(u8 *parse, u32 len)
{
struct brcmf_tlv *ie;
@@ -2689,7 +2522,9 @@ brcmf_find_wpaie(u8 *parse, u32 len)
static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
{
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_bss_info_le *bi;
struct brcmf_ssid *ssid;
struct brcmf_tlv *tim;
@@ -2706,8 +2541,8 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
ssid = &profile->ssid;
*(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
- cfg->extra_buf, WL_EXTRA_BUF_MAX);
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
+ cfg->extra_buf, WL_EXTRA_BUF_MAX);
if (err) {
WL_ERR("Could not get bss info %d\n", err);
goto update_bss_info_out;
@@ -2732,8 +2567,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
* so we speficially query dtim information to dongle.
*/
u32 var;
- err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
- "dtim_assoc", &var);
+ err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
if (err) {
WL_ERR("wl dtim_assoc failed (%d)\n", err);
goto update_bss_info_out;
@@ -2741,9 +2575,6 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
dtim_period = (u8)var;
}
- profile->beacon_interval = beacon_interval;
- profile->dtim_period = dtim_period;
-
update_bss_info_out:
WL_TRACE("Exit");
return err;
@@ -2755,7 +2586,7 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
struct escan_info *escan = &cfg->escan_info;
struct brcmf_ssid ssid;
- set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
+ set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
if (cfg->iscan_on) {
iscan->state = WL_ISCAN_STATE_IDLE;
@@ -2781,8 +2612,8 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
escan->escan_state = WL_ESCAN_STATE_IDLE;
brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
}
- clear_bit(WL_STATUS_SCANNING, &cfg->status);
- clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
+ clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
+ clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
}
static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
@@ -2791,7 +2622,7 @@ static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
struct net_device *ndev = cfg_to_ndev(cfg);
- if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
+ if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n");
return;
}
@@ -2820,7 +2651,6 @@ static s32
brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
struct brcmf_scan_results **bss_list)
{
- struct brcmf_iscan_results list;
struct brcmf_scan_results *results;
struct brcmf_scan_results_le *results_le;
struct brcmf_iscan_results *list_buf;
@@ -2830,15 +2660,13 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
results = &list_buf->results;
results_le = &list_buf->results_le;
- results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
- results->version = 0;
- results->count = 0;
+ results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf));
+ results_le->version = 0;
+ results_le->count = 0;
- memset(&list, 0, sizeof(list));
- list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
- err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
- BRCMF_ISCAN_RESULTS_FIXED_SIZE,
- iscan->scan_buf, WL_ISCAN_BUF_MAX);
+ err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults",
+ iscan->scan_buf,
+ sizeof(iscan->scan_buf));
if (err) {
WL_ERR("error (%d)\n", err);
return err;
@@ -3052,10 +2880,10 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
status = be32_to_cpu(e->status);
if (!ndev || !cfg->escan_on ||
- !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
+ !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
ndev, cfg->escan_on,
- !test_bit(WL_STATUS_SCANNING, &cfg->status));
+ !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
return -EPERM;
}
@@ -3159,16 +2987,17 @@ static __always_inline void brcmf_delay(u32 ms)
static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
/*
- * Check for WL_STATUS_READY before any function call which
+ * Check for BRCMF_VIF_STATUS_READY before any function call which
* could result is bus access. Don't block the resume for
* any driver error conditions
*/
WL_TRACE("Enter\n");
- if (test_bit(WL_STATUS_READY, &cfg->status))
- brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
+ if (check_vif_up(ifp->vif))
+ brcmf_invoke_iscan(cfg);
WL_TRACE("Exit\n");
return 0;
@@ -3179,85 +3008,53 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_cfg80211_vif *vif;
WL_TRACE("Enter\n");
/*
- * Check for WL_STATUS_READY before any function call which
- * could result is bus access. Don't block the suspend for
- * any driver error conditions
- */
-
- /*
- * While going to suspend if associated with AP disassociate
- * from AP to save power while system is in suspended state
+ * if the primary net_device is not READY there is nothing
+ * we can do but pray resume goes smoothly.
*/
- if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
- test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
- test_bit(WL_STATUS_READY, &cfg->status)) {
- WL_INFO("Disassociating from AP"
- " while entering suspend state\n");
- brcmf_link_down(cfg);
+ vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
+ if (!check_vif_up(vif))
+ goto exit;
+ list_for_each_entry(vif, &cfg->vif_list, list) {
+ if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
+ continue;
/*
- * Make sure WPA_Supplicant receives all the event
- * generated due to DISASSOC call to the fw to keep
- * the state fw and WPA_Supplicant state consistent
+ * While going to suspend if associated with AP disassociate
+ * from AP to save power while system is in suspended state
*/
- brcmf_delay(500);
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) ||
+ test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
+ WL_INFO("Disassociating from AP before suspend\n");
+ brcmf_link_down(cfg);
+
+ /* Make sure WPA_Supplicant receives all the event
+ * generated due to DISASSOC call to the fw to keep
+ * the state fw and WPA_Supplicant state consistent
+ */
+ brcmf_delay(500);
+ }
}
- if (test_bit(WL_STATUS_READY, &cfg->status))
+ /* end any scanning */
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
brcmf_abort_scanning(cfg);
- else
- clear_bit(WL_STATUS_SCANNING, &cfg->status);
/* Turn off watchdog timer */
- if (test_bit(WL_STATUS_READY, &cfg->status))
- brcmf_set_mpc(ndev, 1);
+ brcmf_set_mpc(ndev, 1);
+exit:
WL_TRACE("Exit\n");
-
+ /* clear any scanning activity */
+ cfg->scan_status = 0;
return 0;
}
static __used s32
-brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
-{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- u32 buflen;
-
- buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
- WL_DCMD_LEN_MAX);
- BUG_ON(!buflen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
- buflen);
-}
-
-static s32
-brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
- s32 buf_len)
-{
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- u32 len;
- s32 err = 0;
-
- len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
- WL_DCMD_LEN_MAX);
- BUG_ON(!len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
- WL_DCMD_LEN_MAX);
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- memcpy(buf, cfg->dcmd_buf, buf_len);
-
- return err;
-}
-
-static __used s32
brcmf_update_pmklist(struct net_device *ndev,
struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
{
@@ -3275,8 +3072,8 @@ brcmf_update_pmklist(struct net_device *ndev,
}
if (!err)
- brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
- sizeof(*pmk_list));
+ brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
+ (char *)pmk_list, sizeof(*pmk_list));
return err;
}
@@ -3286,13 +3083,14 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_pmksa *pmksa)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
s32 err = 0;
int i;
int pmkid_len;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
pmkid_len = le32_to_cpu(pmkids->npmkid);
@@ -3325,12 +3123,13 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_pmksa *pmksa)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct pmkid_list pmkid;
s32 err = 0;
int i, pmkid_len;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
@@ -3375,10 +3174,11 @@ static s32
brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
@@ -3478,15 +3278,15 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
if (request->n_ssids)
request->ssids = &ssid[0];
- if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
/* Abort any on-going scan */
brcmf_abort_scanning(cfg);
}
- set_bit(WL_STATUS_SCANNING, &cfg->status);
+ set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
err = brcmf_do_escan(cfg, wiphy, ndev, request);
if (err) {
- clear_bit(WL_STATUS_SCANNING, &cfg->status);
+ clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
goto out_err;
}
cfg->sched_escan = true;
@@ -3512,15 +3312,14 @@ out_err:
#ifndef CONFIG_BRCMISCAN
static int brcmf_dev_pno_clean(struct net_device *ndev)
{
- char iovbuf[128];
int ret;
/* Disable pfn */
- ret = brcmf_dev_intvar_set(ndev, "pfn", 0);
+ ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
if (ret == 0) {
/* clear pfn */
- ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0,
- iovbuf, sizeof(iovbuf));
+ ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
+ NULL, 0);
}
if (ret < 0)
WL_ERR("failed code %d\n", ret);
@@ -3531,7 +3330,6 @@ static int brcmf_dev_pno_clean(struct net_device *ndev)
static int brcmf_dev_pno_config(struct net_device *ndev)
{
struct brcmf_pno_param_le pfn_param;
- char iovbuf[128];
memset(&pfn_param, 0, sizeof(pfn_param));
pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
@@ -3544,9 +3342,8 @@ static int brcmf_dev_pno_config(struct net_device *ndev)
/* set up pno scan fr */
pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
- return brcmf_dev_iovar_setbuf(ndev, "pfn_set",
- &pfn_param, sizeof(pfn_param),
- iovbuf, sizeof(iovbuf));
+ return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
+ &pfn_param, sizeof(pfn_param));
}
static int
@@ -3554,7 +3351,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_sched_scan_request *request)
{
- char iovbuf[128];
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
struct brcmf_pno_net_param_le pfn;
int i;
@@ -3562,14 +3359,14 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
request->n_match_sets, request->n_ssids);
- if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
- WL_ERR("Scanning already : status (%lu)\n", cfg->status);
+ if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
return -EAGAIN;
}
if (!request || !request->n_ssids || !request->n_match_sets) {
WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
- request->n_ssids);
+ request ? request->n_ssids : 0);
return -EINVAL;
}
@@ -3620,15 +3417,14 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
- ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add",
- &pfn, sizeof(pfn),
- iovbuf, sizeof(iovbuf));
+ ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
+ sizeof(pfn));
WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
ret == 0 ? "set" : "failed",
ssid->ssid);
}
/* Enable the PNO */
- if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) {
+ if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
WL_ERR("PNO enable failed!! ret=%d\n", ret);
return -EINVAL;
}
@@ -3656,12 +3452,20 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg->wdev->netdev;
+ struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_dcmd *dcmd = data;
struct sk_buff *reply;
int ret;
- ret = brcmf_netlink_dcmd(ndev, dcmd);
+ WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
+ dcmd->buf, dcmd->len);
+
+ if (dcmd->set)
+ ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
+ dcmd->buf, dcmd->len);
+ else
+ ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
+ dcmd->buf, dcmd->len);
if (ret == 0) {
reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
@@ -3673,23 +3477,23 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err;
/* set auth */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
if (err < 0) {
WL_ERR("auth error %d\n", err);
return err;
}
/* set wsec */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
if (err < 0) {
WL_ERR("wsec error %d\n", err);
return err;
}
/* set upper-layer auth */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
- WPA_AUTH_NONE, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
if (err < 0) {
WL_ERR("wpa_auth error %d\n", err);
return err;
@@ -3710,6 +3514,7 @@ static s32
brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
bool is_rsn_ie, s32 bssidx)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
u32 auth = 0; /* d11 open authentication */
u16 count;
s32 err = 0;
@@ -3850,8 +3655,8 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
wme_bss_disable = 0;
}
/* set wme_bss_disable to sync RSN Capabilities */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
- wme_bss_disable, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
+ wme_bss_disable);
if (err < 0) {
WL_ERR("wme_bss_disable error %d\n", err);
goto exit;
@@ -3861,19 +3666,19 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
wsec = (pval | gval | SES_OW_ENABLED);
/* set auth */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
if (err < 0) {
WL_ERR("auth error %d\n", err);
goto exit;
}
/* set wsec */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err < 0) {
WL_ERR("wsec error %d\n", err);
goto exit;
}
/* set upper-layer auth */
- err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
+ err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
if (err < 0) {
WL_ERR("wpa_auth error %d\n", err);
goto exit;
@@ -3963,17 +3768,19 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
return ie_len + VNDR_IE_HDR_SIZE;
}
-s32
+static s32
brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev, s32 bssidx, s32 pktflag,
+ struct net_device *ndev, s32 pktflag,
u8 *vndr_ie_buf, u32 vndr_ie_len)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie;
s32 err = 0;
u8 *iovar_ie_buf;
u8 *curr_ie_buf;
u8 *mgmt_ie_buf = NULL;
- u32 mgmt_ie_buf_len = 0;
- u32 *mgmt_ie_len = 0;
+ int mgmt_ie_buf_len;
+ u32 *mgmt_ie_len;
u32 del_add_ie_buf_len = 0;
u32 total_ie_buf_len = 0;
u32 parsed_ie_buf_len = 0;
@@ -3982,33 +3789,31 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
struct parsed_vndr_ie_info *vndrie_info;
s32 i;
u8 *ptr;
- u32 remained_buf_len;
+ int remained_buf_len;
- WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
+ WL_TRACE("bssidx %d, pktflag : 0x%02X\n",
+ brcmf_ndev_bssidx(ndev), pktflag);
iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
if (!iovar_ie_buf)
return -ENOMEM;
curr_ie_buf = iovar_ie_buf;
- if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
- test_bit(WL_STATUS_AP_CREATED, &cfg->status)) {
+ if (ifp->vif->mode == WL_MODE_AP) {
switch (pktflag) {
case VNDR_IE_PRBRSP_FLAG:
- mgmt_ie_buf = cfg->ap_info->probe_res_ie;
- mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
- mgmt_ie_buf_len =
- sizeof(cfg->ap_info->probe_res_ie);
+ mgmt_ie_buf = saved_ie->probe_res_ie;
+ mgmt_ie_len = &saved_ie->probe_res_ie_len;
+ mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
break;
case VNDR_IE_BEACON_FLAG:
- mgmt_ie_buf = cfg->ap_info->beacon_ie;
- mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
- mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
+ mgmt_ie_buf = saved_ie->beacon_ie;
+ mgmt_ie_len = &saved_ie->beacon_ie_len;
+ mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
break;
default:
err = -EPERM;
WL_ERR("not suitable type\n");
goto exit;
}
- bssidx = 0;
} else {
err = -EPERM;
WL_ERR("not suitable type\n");
@@ -4104,11 +3909,8 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
}
}
if (total_ie_buf_len) {
- err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
- iovar_ie_buf,
- total_ie_buf_len,
- cfg->extra_buf,
- WL_EXTRA_BUF_MAX, bssidx);
+ err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
+ total_ie_buf_len);
if (err)
WL_ERR("vndr ie set error : %d\n", err);
}
@@ -4123,9 +3925,9 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_ap_settings *settings)
{
s32 ie_offset;
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_tlv *ssid_ie;
struct brcmf_ssid_le ssid_le;
- s32 ioctl_value;
s32 err = -EPERM;
struct brcmf_tlv *rsn_ie;
struct brcmf_vs_tlv *wpa_ie;
@@ -4140,7 +3942,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
settings->ssid, settings->ssid_len, settings->auth_type,
settings->inactivity_timeout);
- if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
+ if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
WL_ERR("Not in AP creation mode\n");
return -EPERM;
}
@@ -4164,20 +3966,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
}
brcmf_set_mpc(ndev, 0);
- ioctl_value = 1;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0) {
WL_ERR("BRCMF_C_DOWN error %d\n", err);
goto exit;
}
- ioctl_value = 1;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
if (err < 0) {
WL_ERR("SET INFRA error %d\n", err);
goto exit;
}
- ioctl_value = 1;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
if (err < 0) {
WL_ERR("setting AP mode failed %d\n", err);
goto exit;
@@ -4226,7 +4025,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
cfg->ap_info->security_mode = false;
}
/* Set Beacon IEs to FW */
- err = brcmf_set_management_ie(cfg, ndev, bssidx,
+ err = brcmf_set_management_ie(cfg, ndev,
VNDR_IE_BEACON_FLAG,
(u8 *)settings->beacon.tail,
settings->beacon.tail_len);
@@ -4236,7 +4035,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
WL_TRACE("Applied Vndr IEs for Beacon\n");
/* Set Probe Response IEs to FW */
- err = brcmf_set_management_ie(cfg, ndev, bssidx,
+ err = brcmf_set_management_ie(cfg, ndev,
VNDR_IE_PRBRSP_FLAG,
(u8 *)settings->beacon.proberesp_ies,
settings->beacon.proberesp_ies_len);
@@ -4246,25 +4045,22 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
WL_TRACE("Applied Vndr IEs for Probe Resp\n");
if (settings->beacon_interval) {
- ioctl_value = settings->beacon_interval;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
- &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
+ settings->beacon_interval);
if (err < 0) {
WL_ERR("Beacon Interval Set Error, %d\n", err);
goto exit;
}
}
if (settings->dtim_period) {
- ioctl_value = settings->dtim_period;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
- &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
+ settings->dtim_period);
if (err < 0) {
WL_ERR("DTIM Interval Set Error, %d\n", err);
goto exit;
}
}
- ioctl_value = 1;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0) {
WL_ERR("BRCMF_C_UP error (%d)\n", err);
goto exit;
@@ -4274,14 +4070,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
/* join parameters starts with ssid */
memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
/* create softap */
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
- sizeof(join_params));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+ &join_params, sizeof(join_params));
if (err < 0) {
WL_ERR("SET SSID error (%d)\n", err);
goto exit;
}
- clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
- set_bit(WL_STATUS_AP_CREATED, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
+ set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
exit:
if (err)
@@ -4291,8 +4087,8 @@ exit:
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- s32 ioctl_value;
s32 err = -EPERM;
WL_TRACE("Enter\n");
@@ -4301,21 +4097,20 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
/* Due to most likely deauths outstanding we sleep */
/* first to make sure they get processed by fw. */
msleep(400);
- ioctl_value = 0;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
+ BRCMF_C_SET_AP, 0);
if (err < 0) {
WL_ERR("setting AP mode failed %d\n", err);
goto exit;
}
- ioctl_value = 0;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0);
if (err < 0) {
WL_ERR("BRCMF_C_UP error %d\n", err);
goto exit;
}
brcmf_set_mpc(ndev, 1);
- clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
- clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
}
exit:
return err;
@@ -4326,6 +4121,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
u8 *mac)
{
struct brcmf_scb_val_le scbval;
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err;
if (!mac)
@@ -4333,13 +4129,13 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
WL_TRACE("Enter %pM\n", mac);
- if (!check_sys_up(wiphy))
+ if (!check_vif_up(ifp->vif))
return -EIO;
memcpy(&scbval.ea, mac, ETH_ALEN);
scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
- &scbval, sizeof(scbval));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
+ &scbval, sizeof(scbval));
if (err)
WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
@@ -4410,72 +4206,97 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
#endif
}
-static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
+static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
{
- struct wireless_dev *wdev;
+ struct wiphy *wiphy;
s32 err = 0;
- wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
- if (!wdev)
- return ERR_PTR(-ENOMEM);
-
- wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
- sizeof(struct brcmf_cfg80211_info));
- if (!wdev->wiphy) {
+ wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
+ if (!wiphy) {
WL_ERR("Could not allocate wiphy device\n");
- err = -ENOMEM;
- goto wiphy_new_out;
- }
- set_wiphy_dev(wdev->wiphy, ndev);
- wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
- wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
- wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP);
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
+ return ERR_PTR(-ENOMEM);
+ }
+ set_wiphy_dev(wiphy, phydev);
+ wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+ wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP);
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+ wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
* it as 11a by default.
* This will be updated with
* 11n phy tables in
* "ifconfig up"
* if phy has 11n capability
*/
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
- wdev->wiphy->cipher_suites = __wl_cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
- wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ wiphy->cipher_suites = __wl_cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+ wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
* save mode
* by default
*/
- brcmf_wiphy_pno_params(wdev->wiphy);
- err = wiphy_register(wdev->wiphy);
+ brcmf_wiphy_pno_params(wiphy);
+ err = wiphy_register(wiphy);
if (err < 0) {
WL_ERR("Could not register wiphy device (%d)\n", err);
- goto wiphy_register_out;
+ wiphy_free(wiphy);
+ return ERR_PTR(err);
}
- return wdev;
+ return wiphy;
+}
+
+static
+struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
+ struct net_device *netdev,
+ s32 mode, bool pm_block)
+{
+ struct brcmf_cfg80211_vif *vif;
+
+ if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
+ return ERR_PTR(-ENOSPC);
-wiphy_register_out:
- wiphy_free(wdev->wiphy);
+ vif = kzalloc(sizeof(*vif), GFP_KERNEL);
+ if (!vif)
+ return ERR_PTR(-ENOMEM);
+
+ vif->wdev.wiphy = cfg->wiphy;
+ vif->wdev.netdev = netdev;
+ vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
+
+ if (netdev) {
+ vif->ifp = netdev_priv(netdev);
+ netdev->ieee80211_ptr = &vif->wdev;
+ SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
+ }
-wiphy_new_out:
- kfree(wdev);
+ vif->mode = mode;
+ vif->pm_block = pm_block;
+ vif->roam_off = -1;
- return ERR_PTR(err);
+ brcmf_init_prof(&vif->profile);
+
+ list_add_tail(&vif->list, &cfg->vif_list);
+ cfg->vif_cnt++;
+ return vif;
}
-static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
+static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
{
- struct wireless_dev *wdev = cfg->wdev;
+ struct brcmf_cfg80211_info *cfg;
+ struct wiphy *wiphy;
- if (!wdev) {
- WL_ERR("wdev is invalid\n");
- return;
+ wiphy = vif->wdev.wiphy;
+ cfg = wiphy_priv(wiphy);
+ list_del(&vif->list);
+ cfg->vif_cnt--;
+
+ kfree(vif);
+ if (!cfg->vif_cnt) {
+ wiphy_unregister(wiphy);
+ wiphy_free(wiphy);
}
- wiphy_unregister(wdev->wiphy);
- wiphy_free(wdev->wiphy);
- kfree(wdev);
- cfg->wdev = NULL;
}
static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
@@ -4541,7 +4362,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
{
- struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
u32 req_len;
@@ -4550,8 +4371,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
brcmf_clear_assoc_ies(cfg);
- err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
+ cfg->extra_buf, WL_ASSOC_INFO_MAX);
if (err) {
WL_ERR("could not get assoc info (%d)\n", err);
return err;
@@ -4561,9 +4382,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
req_len = le32_to_cpu(assoc_info->req_len);
resp_len = le32_to_cpu(assoc_info->resp_len);
if (req_len) {
- err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
- cfg->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
+ cfg->extra_buf,
+ WL_ASSOC_INFO_MAX);
if (err) {
WL_ERR("could not get assoc req (%d)\n", err);
return err;
@@ -4577,9 +4398,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
conn_info->req_ie = NULL;
}
if (resp_len) {
- err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
- cfg->extra_buf,
- WL_ASSOC_INFO_MAX);
+ err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
+ cfg->extra_buf,
+ WL_ASSOC_INFO_MAX);
if (err) {
WL_ERR("could not get assoc resp (%d)\n", err);
return err;
@@ -4603,15 +4424,17 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e)
{
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
struct wiphy *wiphy = cfg_to_wiphy(cfg);
- struct brcmf_channel_info_le channel_le;
- struct ieee80211_channel *notify_channel;
+ struct ieee80211_channel *notify_channel = NULL;
struct ieee80211_supported_band *band;
+ struct brcmf_bss_info_le *bi;
u32 freq;
s32 err = 0;
u32 target_channel;
+ u8 *buf;
WL_TRACE("Enter\n");
@@ -4619,11 +4442,23 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
memcpy(profile->bssid, e->addr, ETH_ALEN);
brcmf_update_bss_info(cfg);
- brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
- sizeof(channel_le));
+ buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+ if (buf == NULL) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ /* data sent to dongle has to be little endian */
+ *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
+ buf, WL_BSS_INFO_MAX);
- target_channel = le32_to_cpu(channel_le.target_channel);
- WL_CONN("Roamed to channel %d\n", target_channel);
+ if (err)
+ goto done;
+
+ bi = (struct brcmf_bss_info_le *)(buf + 4);
+ target_channel = bi->ctl_ch ? bi->ctl_ch :
+ CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
if (target_channel <= CH_MAX_2G_CHANNEL)
band = wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -4633,12 +4468,14 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
freq = ieee80211_channel_to_frequency(target_channel, band->band);
notify_channel = ieee80211_get_channel(wiphy, freq);
+done:
+ kfree(buf);
cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
conn_info->req_ie, conn_info->req_ie_len,
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
WL_CONN("Report roaming result\n");
- set_bit(WL_STATUS_CONNECTED, &cfg->status);
+ set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
WL_TRACE("Exit\n");
return err;
}
@@ -4648,13 +4485,15 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, const struct brcmf_event_msg *e,
bool completed)
{
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
s32 err = 0;
WL_TRACE("Enter\n");
- if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
+ if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state)) {
if (completed) {
brcmf_get_assoc_ies(cfg);
memcpy(profile->bssid, e->addr, ETH_ALEN);
@@ -4670,7 +4509,8 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
WLAN_STATUS_AUTH_TIMEOUT,
GFP_KERNEL);
if (completed)
- set_bit(WL_STATUS_CONNECTED, &cfg->status);
+ set_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state);
WL_CONN("Report connect result - connection %s\n",
completed ? "succeeded" : "failed");
}
@@ -4722,7 +4562,8 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
{
- struct brcmf_cfg80211_profile *profile = cfg->profile;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
s32 err = 0;
if (cfg->conf->mode == WL_MODE_AP) {
@@ -4733,30 +4574,34 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
memcpy(profile->bssid, e->addr, ETH_ALEN);
wl_inform_ibss(cfg, ndev, e->addr);
cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
- clear_bit(WL_STATUS_CONNECTING, &cfg->status);
- set_bit(WL_STATUS_CONNECTED, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state);
+ set_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state);
} else
brcmf_bss_connect_done(cfg, ndev, e, true);
} else if (brcmf_is_linkdown(cfg, e)) {
WL_CONN("Linkdown\n");
if (brcmf_is_ibssmode(cfg)) {
- clear_bit(WL_STATUS_CONNECTING, &cfg->status);
- if (test_and_clear_bit(WL_STATUS_CONNECTED,
- &cfg->status))
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state);
+ if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state))
brcmf_link_down(cfg);
} else {
brcmf_bss_connect_done(cfg, ndev, e, false);
- if (test_and_clear_bit(WL_STATUS_CONNECTED,
- &cfg->status)) {
+ if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
cfg80211_disconnected(ndev, 0, NULL, 0,
- GFP_KERNEL);
+ GFP_KERNEL);
brcmf_link_down(cfg);
}
}
- brcmf_init_prof(cfg->profile);
+ brcmf_init_prof(ndev_to_prof(ndev));
} else if (brcmf_is_nonetwork(cfg, e)) {
if (brcmf_is_ibssmode(cfg))
- clear_bit(WL_STATUS_CONNECTING, &cfg->status);
+ clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state);
else
brcmf_bss_connect_done(cfg, ndev, e, false);
}
@@ -4769,12 +4614,13 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
u32 event = be32_to_cpu(e->event_type);
u32 status = be32_to_cpu(e->status);
if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
- if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
brcmf_bss_roaming_done(cfg, ndev, e);
else
brcmf_bss_connect_done(cfg, ndev, e, true);
@@ -4807,6 +4653,7 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_channel_info_le channel_inform_le;
struct brcmf_scan_results_le *bss_list_le;
u32 len = WL_SCAN_BUF_MAX;
@@ -4821,15 +4668,16 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
}
- if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
+ if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
WL_ERR("Scan complete while device not scanning\n");
scan_abort = true;
err = -EINVAL;
goto scan_done_out;
}
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
- sizeof(channel_inform_le));
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL,
+ &channel_inform_le,
+ sizeof(channel_inform_le));
if (err) {
WL_ERR("scan busy (%d)\n", err);
scan_abort = true;
@@ -4843,8 +4691,8 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
memset(cfg->scan_results, 0, len);
bss_list_le->buflen = cpu_to_le32(len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
- cfg->scan_results, len);
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS,
+ cfg->scan_results, len);
if (err) {
WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
err = -EINVAL;
@@ -4906,8 +4754,6 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
cfg->bss_info = NULL;
kfree(cfg->conf);
cfg->conf = NULL;
- kfree(cfg->profile);
- cfg->profile = NULL;
kfree(cfg->scan_req_int);
cfg->scan_req_int = NULL;
kfree(cfg->escan_ioctl_buf);
@@ -4936,9 +4782,6 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
if (!cfg->conf)
goto init_priv_mem_out;
- cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
- if (!cfg->profile)
- goto init_priv_mem_out;
cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
if (!cfg->bss_info)
goto init_priv_mem_out;
@@ -5115,7 +4958,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
return err;
brcmf_init_escan(cfg);
brcmf_init_conf(cfg->conf);
- brcmf_init_prof(cfg->profile);
brcmf_link_down(cfg);
return err;
@@ -5131,12 +4973,14 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
brcmf_deinit_priv_mem(cfg);
}
-struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
- struct device *busdev,
- struct brcmf_pub *drvr)
+struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr)
{
- struct wireless_dev *wdev;
+ struct net_device *ndev = drvr->iflist[0]->ndev;
+ struct device *busdev = drvr->dev;
struct brcmf_cfg80211_info *cfg;
+ struct wiphy *wiphy;
+ struct brcmf_cfg80211_vif *vif;
+ struct brcmf_if *ifp;
s32 err = 0;
if (!ndev) {
@@ -5144,35 +4988,45 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
return NULL;
}
- wdev = brcmf_alloc_wdev(busdev);
- if (IS_ERR(wdev)) {
+ ifp = netdev_priv(ndev);
+ wiphy = brcmf_setup_wiphy(busdev);
+ if (IS_ERR(wiphy))
return NULL;
- }
- wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
- cfg = wdev_to_cfg(wdev);
- cfg->wdev = wdev;
+ cfg = wiphy_priv(wiphy);
+ cfg->wiphy = wiphy;
cfg->pub = drvr;
- ndev->ieee80211_ptr = wdev;
- SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
- wdev->netdev = ndev;
+ INIT_LIST_HEAD(&cfg->vif_list);
+
+ vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
+ if (IS_ERR(vif)) {
+ wiphy_free(wiphy);
+ return NULL;
+ }
+
err = wl_init_priv(cfg);
if (err) {
WL_ERR("Failed to init iwm_priv (%d)\n", err);
goto cfg80211_attach_out;
}
+ ifp->vif = vif;
return cfg;
cfg80211_attach_out:
- brcmf_free_wdev(cfg);
+ brcmf_free_vif(vif);
return NULL;
}
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
{
+ struct brcmf_cfg80211_vif *vif;
+ struct brcmf_cfg80211_vif *tmp;
+
wl_deinit_priv(cfg);
- brcmf_free_wdev(cfg);
+ list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
+ brcmf_free_vif(vif);
+ }
}
void
@@ -5186,59 +5040,20 @@ brcmf_cfg80211_event(struct net_device *ndev,
schedule_work(&cfg->event_work);
}
-static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
-{
- s32 infra = 0;
- s32 err = 0;
-
- switch (iftype) {
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_WDS:
- WL_ERR("type (%d) : currently we do not support this mode\n",
- iftype);
- err = -EINVAL;
- return err;
- case NL80211_IFTYPE_ADHOC:
- infra = 0;
- break;
- case NL80211_IFTYPE_STATION:
- infra = 1;
- break;
- case NL80211_IFTYPE_AP:
- infra = 1;
- break;
- default:
- err = -EINVAL;
- WL_ERR("invalid type (%d)\n", iftype);
- return err;
- }
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
- if (err) {
- WL_ERR("WLC_SET_INFRA error (%d)\n", err);
- return err;
- }
-
- return 0;
-}
-
static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
{
- /* Room for "event_msgs" + '\0' + bitvec */
- s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
s32 err = 0;
WL_TRACE("Enter\n");
/* Setup event_msgs */
- brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
+ err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs",
+ eventmask, BRCMF_EVENTING_MASK_LEN);
if (err) {
WL_ERR("Get event_msgs error (%d)\n", err);
goto dongle_eventmsg_out;
}
- memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
setbit(eventmask, BRCMF_E_SET_SSID);
setbit(eventmask, BRCMF_E_ROAM);
@@ -5262,9 +5077,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
setbit(eventmask, BRCMF_E_ESCAN_RESULT);
setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
- brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs",
+ eventmask, BRCMF_EVENTING_MASK_LEN);
if (err) {
WL_ERR("Set event_msgs error (%d)\n", err);
goto dongle_eventmsg_out;
@@ -5278,23 +5092,17 @@ dongle_eventmsg_out:
static s32
brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
{
- s8 iovbuf[32];
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
__le32 roamtrigger[2];
__le32 roam_delta[2];
- __le32 bcn_to_le;
- __le32 roamvar_le;
/*
* Setup timeout if Beacons are lost and roam is
* off to report link down
*/
if (roamvar) {
- bcn_to_le = cpu_to_le32(bcn_timeout);
- brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
- sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
+ err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
if (err) {
WL_ERR("bcn_timeout error (%d)\n", err);
goto dongle_rom_out;
@@ -5306,10 +5114,7 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
* to take care of roaming
*/
WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
- roamvar_le = cpu_to_le32(roamvar);
- brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
- sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
+ err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
if (err) {
WL_ERR("roam_off error (%d)\n", err);
goto dongle_rom_out;
@@ -5317,8 +5122,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
- (void *)roamtrigger, sizeof(roamtrigger));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
+ (void *)roamtrigger, sizeof(roamtrigger));
if (err) {
WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
goto dongle_rom_out;
@@ -5326,8 +5131,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
- (void *)roam_delta, sizeof(roam_delta));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
+ (void *)roam_delta, sizeof(roam_delta));
if (err) {
WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
goto dongle_rom_out;
@@ -5341,13 +5146,11 @@ static s32
brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
s32 scan_unassoc_time, s32 scan_passive_time)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0;
- __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
- __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
- __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
- &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
+ scan_assoc_time);
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan assoc time is not supported\n");
@@ -5355,8 +5158,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
WL_ERR("Scan assoc time error (%d)\n", err);
goto dongle_scantime_out;
}
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
- &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
+ scan_unassoc_time);
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan unassoc time is not supported\n");
@@ -5365,8 +5168,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
goto dongle_scantime_out;
}
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
- &scan_passive_tm_le, sizeof(scan_passive_tm_le));
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
+ scan_passive_time);
if (err) {
if (err == -EOPNOTSUPP)
WL_INFO("Scan passive time is not supported\n");
@@ -5381,13 +5184,14 @@ dongle_scantime_out:
static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
{
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
struct wiphy *wiphy;
s32 phy_list;
s8 phy;
s32 err = 0;
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
- &phy_list, sizeof(phy_list));
+ err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST,
+ &phy_list, sizeof(phy_list));
if (err) {
WL_ERR("error (%d)\n", err);
return err;
@@ -5429,7 +5233,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
goto default_conf_out;
power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
+ err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
+ power_mode);
if (err)
goto default_conf_out;
WL_INFO("power save set to %s\n",
@@ -5439,7 +5244,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
WL_BEACON_TIMEOUT);
if (err)
goto default_conf_out;
- err = brcmf_dongle_mode(ndev, wdev->iftype);
+ err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
+ NULL, NULL);
if (err && err != -EINPROGRESS)
goto default_conf_out;
err = brcmf_dongle_probecap(cfg);
@@ -5456,47 +5262,12 @@ default_conf_out:
}
-static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
-{
- char buf[10+IFNAMSIZ];
- struct dentry *fd;
- s32 err = 0;
-
- sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
- cfg->debugfsdir = debugfs_create_dir(buf,
- cfg_to_wiphy(cfg)->debugfsdir);
-
- fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
- (u16 *)&cfg->profile->beacon_interval);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
- fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
- (u8 *)&cfg->profile->dtim_period);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
-err_out:
- return err;
-}
-
-static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
-{
- debugfs_remove_recursive(cfg->debugfsdir);
- cfg->debugfsdir = NULL;
-}
-
static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
{
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
s32 err = 0;
- set_bit(WL_STATUS_READY, &cfg->status);
-
- brcmf_debugfs_add_netdev_params(cfg);
+ set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
err = brcmf_config_dongle(cfg);
if (err)
@@ -5509,13 +5280,16 @@ static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
{
+ struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(ndev);
+
/*
* While going down, if associated with AP disassociate
* from AP to save power
*/
- if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
- test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
- test_bit(WL_STATUS_READY, &cfg->status)) {
+ if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) ||
+ test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) &&
+ check_vif_up(ifp->vif)) {
WL_INFO("Disassociating from AP");
brcmf_link_down(cfg);
@@ -5527,9 +5301,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
}
brcmf_abort_scanning(cfg);
- clear_bit(WL_STATUS_READY, &cfg->status);
-
- brcmf_debugfs_remove_netdev(cfg);
+ clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
return 0;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 71ced17..1dd96f1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -127,15 +127,15 @@ do { \
#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
#define IE_MAX_LEN 512
-/* dongle status */
-enum wl_status {
- WL_STATUS_READY,
- WL_STATUS_SCANNING,
- WL_STATUS_SCAN_ABORTING,
- WL_STATUS_CONNECTING,
- WL_STATUS_CONNECTED,
- WL_STATUS_AP_CREATING,
- WL_STATUS_AP_CREATED
+/**
+ * enum brcmf_scan_status - dongle scan status
+ *
+ * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle.
+ * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle.
+ */
+enum brcmf_scan_status {
+ BRCMF_SCAN_STATUS_BUSY,
+ BRCMF_SCAN_STATUS_ABORT,
};
/* wi-fi mode */
@@ -145,19 +145,6 @@ enum wl_mode {
WL_MODE_AP
};
-/* dongle profile list */
-enum wl_prof_list {
- WL_PROF_MODE,
- WL_PROF_SSID,
- WL_PROF_SEC,
- WL_PROF_IBSS,
- WL_PROF_BAND,
- WL_PROF_BSSID,
- WL_PROF_ACT,
- WL_PROF_BEACONINT,
- WL_PROF_DTIMPERIOD
-};
-
/* dongle iscan state */
enum wl_iscan_state {
WL_ISCAN_STATE_IDLE,
@@ -214,25 +201,73 @@ struct brcmf_cfg80211_security {
u32 wpa_auth;
};
-/* ibss information for currently joined ibss network */
-struct brcmf_cfg80211_ibss {
- u8 beacon_interval; /* in millisecond */
- u8 atim; /* in millisecond */
- s8 join_only;
- u8 band;
- u8 channel;
-};
-
-/* dongle profile */
+/**
+ * struct brcmf_cfg80211_profile - profile information.
+ *
+ * @ssid: ssid of associated/associating ap.
+ * @bssid: bssid of joined/joining ibss.
+ * @sec: security information.
+ */
struct brcmf_cfg80211_profile {
- u32 mode;
struct brcmf_ssid ssid;
u8 bssid[ETH_ALEN];
- u16 beacon_interval;
- u8 dtim_period;
struct brcmf_cfg80211_security sec;
- struct brcmf_cfg80211_ibss ibss;
- s32 band;
+};
+
+/**
+ * enum brcmf_vif_status - bit indices for vif status.
+ *
+ * @BRCMF_VIF_STATUS_READY: ready for operation.
+ * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
+ * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
+ * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
+ * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
+ */
+enum brcmf_vif_status {
+ BRCMF_VIF_STATUS_READY,
+ BRCMF_VIF_STATUS_CONNECTING,
+ BRCMF_VIF_STATUS_CONNECTED,
+ BRCMF_VIF_STATUS_AP_CREATING,
+ BRCMF_VIF_STATUS_AP_CREATED
+};
+
+/**
+ * struct vif_saved_ie - holds saved IEs for a virtual interface.
+ *
+ * @probe_res_ie: IE info for probe response.
+ * @beacon_ie: IE info for beacon frame.
+ * @probe_res_ie_len: IE info length for probe response.
+ * @beacon_ie_len: IE info length for beacon frame.
+ */
+struct vif_saved_ie {
+ u8 probe_res_ie[IE_MAX_LEN];
+ u8 beacon_ie[IE_MAX_LEN];
+ u32 probe_res_ie_len;
+ u32 beacon_ie_len;
+};
+
+/**
+ * struct brcmf_cfg80211_vif - virtual interface specific information.
+ *
+ * @ifp: lower layer interface pointer
+ * @wdev: wireless device.
+ * @profile: profile information.
+ * @mode: operating mode.
+ * @roam_off: roaming state.
+ * @sme_state: SME state using enum brcmf_vif_status bits.
+ * @pm_block: power-management blocked.
+ * @list: linked list.
+ */
+struct brcmf_cfg80211_vif {
+ struct brcmf_if *ifp;
+ struct wireless_dev wdev;
+ struct brcmf_cfg80211_profile profile;
+ s32 mode;
+ s32 roam_off;
+ unsigned long sme_state;
+ bool pm_block;
+ struct vif_saved_ie saved_ie;
+ struct list_head list;
};
/* dongle iscan event loop */
@@ -383,7 +418,7 @@ struct brcmf_pno_scanresults_le {
/**
* struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
*
- * @wdev: representing wl cfg80211 device.
+ * @wiphy: wiphy object for cfg80211 interface.
* @conf: dongle configuration.
* @scan_request: cfg80211 scan request object.
* @el: main event loop.
@@ -395,12 +430,11 @@ struct brcmf_pno_scanresults_le {
* @scan_req_int: internal scan request object.
* @bss_info: bss information for cfg80211 layer.
* @ie: information element object for internal purpose.
- * @profile: holding dongle profile.
* @iscan: iscan controller information.
* @conn_info: association info.
* @pmk_list: wpa2 pmk list.
* @event_work: event handler work struct.
- * @status: current dongle status.
+ * @scan_status: scan activity on the dongle.
* @pub: common driver information.
* @channel: current channel.
* @iscan_on: iscan on/off switch.
@@ -422,10 +456,11 @@ struct brcmf_pno_scanresults_le {
* @escan_timeout_work: scan timeout worker.
* @escan_ioctl_buf: dongle command buffer for escan commands.
* @ap_info: host ap information.
- * @ci: used to link this structure to netdev private data.
+ * @vif_list: linked list of vif instances.
+ * @vif_cnt: number of vif instances.
*/
struct brcmf_cfg80211_info {
- struct wireless_dev *wdev;
+ struct wiphy *wiphy;
struct brcmf_cfg80211_conf *conf;
struct cfg80211_scan_request *scan_request;
struct brcmf_cfg80211_event_loop el;
@@ -437,12 +472,11 @@ struct brcmf_cfg80211_info {
struct brcmf_cfg80211_scan_req *scan_req_int;
struct wl_cfg80211_bss_info *bss_info;
struct brcmf_cfg80211_ie ie;
- struct brcmf_cfg80211_profile *profile;
struct brcmf_cfg80211_iscan_ctrl *iscan;
struct brcmf_cfg80211_connect_info conn_info;
struct brcmf_cfg80211_pmk_list *pmk_list;
struct work_struct event_work;
- unsigned long status;
+ unsigned long scan_status;
struct brcmf_pub *pub;
u32 channel;
bool iscan_on;
@@ -464,11 +498,13 @@ struct brcmf_cfg80211_info {
struct work_struct escan_timeout_work;
u8 *escan_ioctl_buf;
struct ap_info *ap_info;
+ struct list_head vif_list;
+ u8 vif_cnt;
};
-static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w)
+static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg)
{
- return w->wdev->wiphy;
+ return cfg->wiphy;
}
static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
@@ -481,9 +517,12 @@ static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
}
-static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
+static inline
+struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
{
- return cfg->wdev->netdev;
+ struct brcmf_cfg80211_vif *vif;
+ vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list);
+ return vif->wdev.netdev;
}
static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
@@ -491,6 +530,12 @@ static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
return wdev_to_cfg(ndev->ieee80211_ptr);
}
+static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd)
+{
+ struct brcmf_if *ifp = netdev_priv(nd);
+ return &ifp->vif->profile;
+}
+
#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data))
#define cfg_to_iscan(w) (w->iscan)
@@ -500,9 +545,7 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
return &cfg->conn_info;
}
-struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
- struct device *busdev,
- struct brcmf_pub *drvr);
+struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
/* event handler from dongle */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index b89f127..de96290 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -692,7 +692,7 @@ void ai_pci_up(struct si_pub *sih)
sii = container_of(sih, struct si_info, pub);
if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
+ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
}
/* Unconfigure and/or apply various WARs when going down */
@@ -703,7 +703,7 @@ void ai_pci_down(struct si_pub *sih)
sii = container_of(sih, struct si_info, pub);
if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
- bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
+ bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
}
/* Enable BT-COEX & Ex-PA for 4313 */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 75086b3..565c15a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -5077,7 +5077,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
* Configure pci/pcmcia here instead of in brcms_c_attach()
* to allow mfg hotswap: down, hotswap (chip power cycle), up.
*/
- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
+ bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core,
true);
/*