aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-05 04:57:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-08 15:28:46 -0400
commit01b8e7db61fbe575193ea2c6eda1964c1d9b8b07 (patch)
tree2565e5daa37b2a77e68657676e73ab97b5367e89 /drivers/net/wireless
parent27f10e380ad912c7928e08c4d04b246e66022cc4 (diff)
brcmfmac: wait for firmware event when creating P2P_DEVICE interface
The firmware sends a IF event to notify the host driver that the P2P_DEVICE interface has been created. Wait for the event before returning the related wireless_dev. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Piotr Haber <phaber@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c28
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c52
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c8
4 files changed, 55 insertions, 35 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index c82f3e0b66f9..e68500bb63e7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -755,15 +755,23 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
755 } 755 }
756 } 756 }
757 757
758 /* Allocate netdev, including space for private structure */ 758 if (!brcmf_p2p_enable && bssidx == 1) {
759 ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); 759 /* this is P2P_DEVICE interface */
760 if (!ndev) { 760 brcmf_dbg(INFO, "allocate non-netdev interface\n");
761 brcmf_err("OOM - alloc_netdev\n"); 761 ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
762 return ERR_PTR(-ENOMEM); 762 } else {
763 brcmf_dbg(INFO, "allocate netdev interface\n");
764 /* Allocate netdev, including space for private structure */
765 ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
766 if (!ndev) {
767 brcmf_err("OOM - alloc_netdev\n");
768 return ERR_PTR(-ENOMEM);
769 }
770
771 ifp = netdev_priv(ndev);
772 ifp->ndev = ndev;
763 } 773 }
764 774
765 ifp = netdev_priv(ndev);
766 ifp->ndev = ndev;
767 ifp->drvr = drvr; 775 ifp->drvr = drvr;
768 drvr->iflist[bssidx] = ifp; 776 drvr->iflist[bssidx] = ifp;
769 ifp->ifidx = ifidx; 777 ifp->ifidx = ifidx;
@@ -775,7 +783,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
775 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN); 783 memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
776 784
777 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", 785 brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
778 current->pid, ifp->ndev->name, ifp->mac_addr); 786 current->pid, name, ifp->mac_addr);
779 787
780 return ifp; 788 return ifp;
781} 789}
@@ -807,11 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
807 } 815 }
808 816
809 unregister_netdev(ifp->ndev); 817 unregister_netdev(ifp->ndev);
810 drvr->iflist[bssidx] = NULL;
811 if (bssidx == 0) 818 if (bssidx == 0)
812 brcmf_cfg80211_detach(drvr->config); 819 brcmf_cfg80211_detach(drvr->config);
813 free_netdev(ifp->ndev); 820 free_netdev(ifp->ndev);
821 } else {
822 kfree(ifp);
814 } 823 }
824 drvr->iflist[bssidx] = NULL;
815} 825}
816 826
817int brcmf_attach(uint bus_hdrlen, struct device *dev) 827int brcmf_attach(uint bus_hdrlen, struct device *dev)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 619fff34c218..b3c608ee37cf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1786,7 +1786,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
1786 1786
1787 brcmf_dbg(TRACE, "enter: idx=%d, mac=%pM\n", 1787 brcmf_dbg(TRACE, "enter: idx=%d, mac=%pM\n",
1788 ifp->bssidx, ifp->mac_addr); 1788 ifp->bssidx, ifp->mac_addr);
1789 if (!ifp->drvr->fw_signals) 1789 if (!ifp->ndev || !ifp->drvr->fw_signals)
1790 return; 1790 return;
1791 1791
1792 entry = &fws->desc.iface[ifp->ifidx]; 1792 entry = &fws->desc.iface[ifp->ifidx];
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 5d5d1e48a383..c3d98362947f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -485,7 +485,6 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
485static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) 485static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
486{ 486{
487 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 487 struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
488 struct brcmf_if *p2p_ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
489 bool local_admin = false; 488 bool local_admin = false;
490 489
491 if (!dev_addr || is_zero_ether_addr(dev_addr)) { 490 if (!dev_addr || is_zero_ether_addr(dev_addr)) {
@@ -499,7 +498,6 @@ static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
499 memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); 498 memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
500 if (local_admin) 499 if (local_admin)
501 p2p->dev_addr[0] |= 0x02; 500 p2p->dev_addr[0] |= 0x02;
502 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
503 501
504 /* Generate the P2P Interface Address. If the discovery and connection 502 /* Generate the P2P Interface Address. If the discovery and connection
505 * BSSCFGs need to simultaneously co-exist, then this address must be 503 * BSSCFGs need to simultaneously co-exist, then this address must be
@@ -1948,6 +1946,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
1948 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; 1946 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
1949 1947
1950 brcmf_p2p_generate_bss_mac(p2p, NULL); 1948 brcmf_p2p_generate_bss_mac(p2p, NULL);
1949 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
1951 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); 1950 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
1952 1951
1953 /* Initialize P2P Discovery in the firmware */ 1952 /* Initialize P2P Discovery in the firmware */
@@ -2163,38 +2162,44 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
2163 return (struct wireless_dev *)p2p_vif; 2162 return (struct wireless_dev *)p2p_vif;
2164 } 2163 }
2165 2164
2166 /* create ifp here */
2167 p2p_ifp = kzalloc(sizeof(*p2p_ifp), GFP_KERNEL);
2168 if (!p2p_ifp)
2169 return ERR_PTR(-ENOMEM);
2170
2171 p2p_vif->ifp = p2p_ifp;
2172 p2p_ifp->vif = p2p_vif;
2173
2174 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
2175 brcmf_p2p_generate_bss_mac(p2p, addr);
2176 memcpy(&p2p_vif->wdev.address, p2p->dev_addr, sizeof(p2p->dev_addr));
2177
2178 pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 2165 pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
2166 brcmf_p2p_generate_bss_mac(p2p, addr);
2179 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); 2167 brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
2180 2168
2169 brcmf_cfg80211_arm_vif_event(p2p->cfg, p2p_vif);
2170
2181 /* Initialize P2P Discovery in the firmware */ 2171 /* Initialize P2P Discovery in the firmware */
2182 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); 2172 err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
2183 if (err < 0) { 2173 if (err < 0) {
2184 brcmf_err("set p2p_disc error\n"); 2174 brcmf_err("set p2p_disc error\n");
2185 brcmf_free_vif(p2p_vif); 2175 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
2186 return ERR_PTR(err); 2176 goto fail;
2187 } 2177 }
2188 /* obtain bsscfg index for P2P discovery */ 2178
2179 /* wait for firmware event */
2180 err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD,
2181 msecs_to_jiffies(1500));
2182 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
2183 if (!err) {
2184 brcmf_err("timeout occurred\n");
2185 err = -EIO;
2186 goto fail;
2187 }
2188
2189 /* discovery interface created */
2190 p2p_ifp = p2p_vif->ifp;
2191 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
2192 memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
2193 memcpy(&p2p_vif->wdev.address, p2p->dev_addr, sizeof(p2p->dev_addr));
2194
2195 /* verify bsscfg index for P2P discovery */
2189 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); 2196 err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
2190 if (err < 0) { 2197 if (err < 0) {
2191 brcmf_err("retrieving discover bsscfg index failed\n"); 2198 brcmf_err("retrieving discover bsscfg index failed\n");
2192 brcmf_free_vif(p2p_vif); 2199 goto fail;
2193 return ERR_PTR(err);
2194 } 2200 }
2195 2201
2196 p2p_ifp->drvr = p2p->cfg->pub; 2202 WARN_ON(p2p_ifp->bssidx != bssidx);
2197 p2p_ifp->bssidx = bssidx;
2198 2203
2199 init_completion(&p2p->send_af_done); 2204 init_completion(&p2p->send_af_done);
2200 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler); 2205 INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
@@ -2202,6 +2207,10 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
2202 init_completion(&p2p->wait_next_af); 2207 init_completion(&p2p->wait_next_af);
2203 2208
2204 return &p2p_vif->wdev; 2209 return &p2p_vif->wdev;
2210
2211fail:
2212 brcmf_free_vif(p2p_vif);
2213 return ERR_PTR(err);
2205} 2214}
2206 2215
2207/** 2216/**
@@ -2215,7 +2224,6 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif)
2215 2224
2216 cfg80211_unregister_wdev(&vif->wdev); 2225 cfg80211_unregister_wdev(&vif->wdev);
2217 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; 2226 p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
2218 kfree(vif->ifp);
2219 brcmf_free_vif(vif); 2227 brcmf_free_vif(vif);
2220} 2228}
2221 2229
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index cba757b792b0..68859e534420 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4568,9 +4568,11 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4568 4568
4569 ifp->vif = vif; 4569 ifp->vif = vif;
4570 vif->ifp = ifp; 4570 vif->ifp = ifp;
4571 vif->wdev.netdev = ifp->ndev; 4571 if (ifp->ndev) {
4572 ifp->ndev->ieee80211_ptr = &vif->wdev; 4572 vif->wdev.netdev = ifp->ndev;
4573 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); 4573 ifp->ndev->ieee80211_ptr = &vif->wdev;
4574 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4575 }
4574 mutex_unlock(&event->vif_event_lock); 4576 mutex_unlock(&event->vif_event_lock);
4575 wake_up(&event->vif_wq); 4577 wake_up(&event->vif_wq);
4576 return 0; 4578 return 0;