brcmfmac: rework driver initialization in brcmf_bus_start()
authorArend van Spriel <arend@broadcom.com>
Mon, 22 Oct 2012 17:36:20 +0000 (10:36 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 29 Oct 2012 19:28:23 +0000 (15:28 -0400)
In brcmf_bus_start() a number of settings are sent to the device. For
this functions are used that bypass the common firmware interface.
By reordering the code in brcmf_bus_start() this bypass can be removed.

Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h

index d848bb934b7ddea5dc9a1e11346d918c423f56fd..51d775412907299c4ca9fb535b2a6c605c4138be 100644 (file)
@@ -735,6 +735,9 @@ 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);
index ba42e4ec1cf7b4f1749600a1e803e5cf95b9cdd7..265580f5b27084a68d786a08e21760208159bad6 100644 (file)
@@ -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, s32 bssidx,
-                       char *name, u8 *mac_addr);
-
 #ifdef CONFIG_BRCMFMAC_SDIO
 extern void brcmf_sdio_exit(void);
 extern void brcmf_sdio_init(void);
index bc6279184c7ed11703221fe58e6b1e4ae629eb4d..28b3eed1834fa20beeb26845be90f9d620484d63 100644 (file)
@@ -444,6 +444,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;
@@ -479,13 +480,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, ifevent->bssidx,
-                                            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);
index f603032d3d0958f302918ce572edb083d93ed6ad..b1f26b53fa27873124bca3079b43ba89d61f7da7 100644 (file)
@@ -779,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;
@@ -813,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;
@@ -833,12 +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, s32 bssidx,
-            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;
@@ -865,7 +856,7 @@ brcmf_add_if(struct device *dev, int ifidx, s32 bssidx,
        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);
@@ -877,17 +868,10 @@ brcmf_add_if(struct device *dev, int ifidx, s32 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)
@@ -970,6 +954,7 @@ int brcmf_bus_start(struct device *dev)
        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");
 
@@ -1006,21 +991,31 @@ int brcmf_bus_start(struct device *dev)
        setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
        setbit(drvr->eventmask, BRCMF_E_IF);
 
-/* enable dongle roaming event */
-
-       drvr->pktfilter_count = 1;
        /* Setup filter to allow only unicast */
+       drvr->pktfilter_count = 1;
        drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
 
+       /* add primary networking interface */
+       ifp = brcmf_add_if(dev, 0, 0, "wlan%d", drvr->mac);
+       if (IS_ERR(ifp))
+               return PTR_ERR(ifp);
+
        /* Bus is ready, do any protocol initialization */
        ret = brcmf_proto_init(drvr);
        if (ret < 0)
                return ret;
 
-       /* add primary networking interface */
-       ret = brcmf_add_if(dev, 0, 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;
index 24f5580e6e7add8a3178e6bb49facd0bbc7d9e60..30e9c127f9c175b043a5818758b43452b480d7c8 100644 (file)
@@ -4939,10 +4939,10 @@ 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 net_device *ndev = drvr->iflist[0]->ndev;
+       struct device *busdev = drvr->dev;
        struct wireless_dev *wdev;
        struct brcmf_cfg80211_info *cfg;
        s32 err = 0;
index 71ced174748a335a72f2c6b68712d9d3e40731d5..191262578e02b9e378b79d6e55cd64bf99c8f316 100644 (file)
@@ -500,9 +500,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 */