aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c301
1 files changed, 104 insertions, 197 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 4acbac5a74c..719fd9397eb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -58,7 +58,6 @@ struct brcmf_if {
58 struct net_device *ndev; 58 struct net_device *ndev;
59 struct net_device_stats stats; 59 struct net_device_stats stats;
60 int idx; /* iface idx in dongle */ 60 int idx; /* iface idx in dongle */
61 int state; /* interface state */
62 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ 61 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
63}; 62};
64 63
@@ -80,20 +79,6 @@ struct brcmf_info {
80/* Error bits */ 79/* Error bits */
81module_param(brcmf_msg_level, int, 0); 80module_param(brcmf_msg_level, int, 0);
82 81
83
84static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev)
85{
86 int i = 0;
87
88 while (i < BRCMF_MAX_IFS) {
89 if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev)
90 return i;
91 i++;
92 }
93
94 return BRCMF_BAD_IF;
95}
96
97int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) 82int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
98{ 83{
99 int i = BRCMF_MAX_IFS; 84 int i = BRCMF_MAX_IFS;
@@ -285,14 +270,9 @@ _brcmf_set_mac_address(struct work_struct *work)
285 270
286static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 271static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
287{ 272{
288 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 273 struct brcmf_if *ifp = netdev_priv(ndev);
289 netdev_priv(ndev); 274 struct brcmf_info *drvr_priv = ifp->info;
290 struct sockaddr *sa = (struct sockaddr *)addr; 275 struct sockaddr *sa = (struct sockaddr *)addr;
291 int ifidx;
292
293 ifidx = brcmf_net2idx(drvr_priv, ndev);
294 if (ifidx == BRCMF_BAD_IF)
295 return -1;
296 276
297 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); 277 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
298 schedule_work(&drvr_priv->setmacaddr_work); 278 schedule_work(&drvr_priv->setmacaddr_work);
@@ -301,13 +281,8 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
301 281
302static void brcmf_netdev_set_multicast_list(struct net_device *ndev) 282static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
303{ 283{
304 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 284 struct brcmf_if *ifp = netdev_priv(ndev);
305 netdev_priv(ndev); 285 struct brcmf_info *drvr_priv = ifp->info;
306 int ifidx;
307
308 ifidx = brcmf_net2idx(drvr_priv, ndev);
309 if (ifidx == BRCMF_BAD_IF)
310 return;
311 286
312 schedule_work(&drvr_priv->multicast_work); 287 schedule_work(&drvr_priv->multicast_work);
313} 288}
@@ -341,9 +316,8 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
341static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 316static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
342{ 317{
343 int ret; 318 int ret;
344 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 319 struct brcmf_if *ifp = netdev_priv(ndev);
345 netdev_priv(ndev); 320 struct brcmf_info *drvr_priv = ifp->info;
346 int ifidx;
347 321
348 brcmf_dbg(TRACE, "Enter\n"); 322 brcmf_dbg(TRACE, "Enter\n");
349 323
@@ -355,9 +329,8 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
355 return -ENODEV; 329 return -ENODEV;
356 } 330 }
357 331
358 ifidx = brcmf_net2idx(drvr_priv, ndev); 332 if (!drvr_priv->iflist[ifp->idx]) {
359 if (ifidx == BRCMF_BAD_IF) { 333 brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx);
360 brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx);
361 netif_stop_queue(ndev); 334 netif_stop_queue(ndev);
362 return -ENODEV; 335 return -ENODEV;
363 } 336 }
@@ -367,20 +340,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
367 struct sk_buff *skb2; 340 struct sk_buff *skb2;
368 341
369 brcmf_dbg(INFO, "%s: insufficient headroom\n", 342 brcmf_dbg(INFO, "%s: insufficient headroom\n",
370 brcmf_ifname(&drvr_priv->pub, ifidx)); 343 brcmf_ifname(&drvr_priv->pub, ifp->idx));
371 drvr_priv->pub.tx_realloc++; 344 drvr_priv->pub.tx_realloc++;
372 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); 345 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
373 dev_kfree_skb(skb); 346 dev_kfree_skb(skb);
374 skb = skb2; 347 skb = skb2;
375 if (skb == NULL) { 348 if (skb == NULL) {
376 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", 349 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
377 brcmf_ifname(&drvr_priv->pub, ifidx)); 350 brcmf_ifname(&drvr_priv->pub, ifp->idx));
378 ret = -ENOMEM; 351 ret = -ENOMEM;
379 goto done; 352 goto done;
380 } 353 }
381 } 354 }
382 355
383 ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); 356 ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb);
384 357
385done: 358done:
386 if (ret) 359 if (ret)
@@ -482,12 +455,10 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
482 skb_mac_header(skb), 455 skb_mac_header(skb),
483 &event, &data); 456 &event, &data);
484 457
485 if (drvr_priv->iflist[ifidx] && 458 if (drvr_priv->iflist[ifidx]) {
486 !drvr_priv->iflist[ifidx]->state)
487 ifp = drvr_priv->iflist[ifidx]; 459 ifp = drvr_priv->iflist[ifidx];
488
489 if (ifp->ndev)
490 ifp->ndev->last_rx = jiffies; 460 ifp->ndev->last_rx = jiffies;
461 }
491 462
492 drvr->dstats.rx_bytes += skb->len; 463 drvr->dstats.rx_bytes += skb->len;
493 drvr->rx_packets++; /* Local count */ 464 drvr->rx_packets++; /* Local count */
@@ -524,19 +495,11 @@ void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
524 495
525static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 496static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
526{ 497{
527 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 498 struct brcmf_if *ifp = netdev_priv(ndev);
528 netdev_priv(ndev); 499 struct brcmf_info *drvr_priv = ifp->info;
529 struct brcmf_if *ifp;
530 int ifidx;
531 500
532 brcmf_dbg(TRACE, "Enter\n"); 501 brcmf_dbg(TRACE, "Enter\n");
533 502
534 ifidx = brcmf_net2idx(drvr_priv, ndev);
535 if (ifidx == BRCMF_BAD_IF)
536 return NULL;
537
538 ifp = drvr_priv->iflist[ifidx];
539
540 if (drvr_priv->pub.up) 503 if (drvr_priv->pub.up)
541 /* Use the protocol to get dongle stats */ 504 /* Use the protocol to get dongle stats */
542 brcmf_proto_dstats(&drvr_priv->pub); 505 brcmf_proto_dstats(&drvr_priv->pub);
@@ -637,8 +600,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
637static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 600static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
638 struct ethtool_drvinfo *info) 601 struct ethtool_drvinfo *info)
639{ 602{
640 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 603 struct brcmf_if *ifp = netdev_priv(ndev);
641 netdev_priv(ndev); 604 struct brcmf_info *drvr_priv = ifp->info;
642 605
643 sprintf(info->driver, KBUILD_MODNAME); 606 sprintf(info->driver, KBUILD_MODNAME);
644 sprintf(info->version, "%lu", drvr_priv->pub.drv_version); 607 sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
@@ -765,14 +728,12 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
765static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, 728static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
766 int cmd) 729 int cmd)
767{ 730{
768 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 731 struct brcmf_if *ifp = netdev_priv(ndev);
769 netdev_priv(ndev); 732 struct brcmf_info *drvr_priv = ifp->info;
770 int ifidx;
771 733
772 ifidx = brcmf_net2idx(drvr_priv, ndev); 734 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
773 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd);
774 735
775 if (ifidx == BRCMF_BAD_IF) 736 if (!drvr_priv->iflist[ifp->idx])
776 return -1; 737 return -1;
777 738
778 if (cmd == SIOCETHTOOL) 739 if (cmd == SIOCETHTOOL)
@@ -788,17 +749,14 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
788 s32 err = 0; 749 s32 err = 0;
789 int buflen = 0; 750 int buflen = 0;
790 bool is_set_key_cmd; 751 bool is_set_key_cmd;
791 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 752 struct brcmf_if *ifp = netdev_priv(ndev);
792 netdev_priv(ndev); 753 struct brcmf_info *drvr_priv = ifp->info;
793 int ifidx;
794 754
795 memset(&dcmd, 0, sizeof(dcmd)); 755 memset(&dcmd, 0, sizeof(dcmd));
796 dcmd.cmd = cmd; 756 dcmd.cmd = cmd;
797 dcmd.buf = arg; 757 dcmd.buf = arg;
798 dcmd.len = len; 758 dcmd.len = len;
799 759
800 ifidx = brcmf_net2idx(drvr_priv, ndev);
801
802 if (dcmd.buf != NULL) 760 if (dcmd.buf != NULL)
803 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); 761 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
804 762
@@ -826,7 +784,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
826 if (is_set_key_cmd) 784 if (is_set_key_cmd)
827 brcmf_netdev_wait_pend8021x(ndev); 785 brcmf_netdev_wait_pend8021x(ndev);
828 786
829 err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen); 787 err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen);
830 788
831done: 789done:
832 if (err > 0) 790 if (err > 0)
@@ -837,7 +795,8 @@ done:
837 795
838static int brcmf_netdev_stop(struct net_device *ndev) 796static int brcmf_netdev_stop(struct net_device *ndev)
839{ 797{
840 struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev); 798 struct brcmf_if *ifp = netdev_priv(ndev);
799 struct brcmf_pub *drvr = &ifp->info->pub;
841 800
842 brcmf_dbg(TRACE, "Enter\n"); 801 brcmf_dbg(TRACE, "Enter\n");
843 brcmf_cfg80211_down(drvr->config); 802 brcmf_cfg80211_down(drvr->config);
@@ -853,16 +812,14 @@ static int brcmf_netdev_stop(struct net_device *ndev)
853 812
854static int brcmf_netdev_open(struct net_device *ndev) 813static int brcmf_netdev_open(struct net_device *ndev)
855{ 814{
856 struct brcmf_info *drvr_priv = *(struct brcmf_info **) 815 struct brcmf_if *ifp = netdev_priv(ndev);
857 netdev_priv(ndev); 816 struct brcmf_info *drvr_priv = ifp->info;
858 u32 toe_ol; 817 u32 toe_ol;
859 int ifidx = brcmf_net2idx(drvr_priv, ndev);
860 s32 ret = 0; 818 s32 ret = 0;
861 819
862 brcmf_dbg(TRACE, "ifidx %d\n", ifidx); 820 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
863
864 if (ifidx == 0) { /* do it only for primary eth0 */
865 821
822 if (ifp->idx == 0) { /* do it only for primary eth0 */
866 /* try to bring up bus */ 823 /* try to bring up bus */
867 ret = brcmf_bus_start(&drvr_priv->pub); 824 ret = brcmf_bus_start(&drvr_priv->pub);
868 if (ret != 0) { 825 if (ret != 0) {
@@ -874,12 +831,12 @@ static int brcmf_netdev_open(struct net_device *ndev)
874 memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); 831 memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
875 832
876 /* Get current TOE mode from dongle */ 833 /* Get current TOE mode from dongle */
877 if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 834 if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0
878 && (toe_ol & TOE_TX_CSUM_OL) != 0) 835 && (toe_ol & TOE_TX_CSUM_OL) != 0)
879 drvr_priv->iflist[ifidx]->ndev->features |= 836 drvr_priv->iflist[ifp->idx]->ndev->features |=
880 NETIF_F_IP_CSUM; 837 NETIF_F_IP_CSUM;
881 else 838 else
882 drvr_priv->iflist[ifidx]->ndev->features &= 839 drvr_priv->iflist[ifp->idx]->ndev->features &=
883 ~NETIF_F_IP_CSUM; 840 ~NETIF_F_IP_CSUM;
884 } 841 }
885 /* Allow transmit calls */ 842 /* Allow transmit calls */
@@ -893,75 +850,62 @@ static int brcmf_netdev_open(struct net_device *ndev)
893 return ret; 850 return ret;
894} 851}
895 852
853static const struct net_device_ops brcmf_netdev_ops_pri = {
854 .ndo_open = brcmf_netdev_open,
855 .ndo_stop = brcmf_netdev_stop,
856 .ndo_get_stats = brcmf_netdev_get_stats,
857 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
858 .ndo_start_xmit = brcmf_netdev_start_xmit,
859 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
860 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
861};
862
896int 863int
897brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev, 864brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr)
898 char *name, u8 *mac_addr, u32 flags, u8 bssidx)
899{ 865{
900 struct brcmf_if *ifp; 866 struct brcmf_if *ifp;
901 int ret = 0, err = 0; 867 struct net_device *ndev;
902 868
903 brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev); 869 brcmf_dbg(TRACE, "idx %d\n", ifidx);
904 870
905 ifp = drvr_priv->iflist[ifidx]; 871 ifp = drvr_priv->iflist[ifidx];
906 if (!ifp) { 872 /*
907 ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); 873 * Delete the existing interface before overwriting it
908 if (!ifp) 874 * in case we missed the BRCMF_E_IF_DEL event.
909 return -ENOMEM; 875 */
876 if (ifp) {
877 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
878 ifp->ndev->name);
879 netif_stop_queue(ifp->ndev);
880 unregister_netdev(ifp->ndev);
881 free_netdev(ifp->ndev);
882 drvr_priv->iflist[ifidx] = NULL;
883 }
884
885 /* Allocate netdev, including space for private structure */
886 ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
887 if (!ndev) {
888 brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
889 return -ENOMEM;
910 } 890 }
911 891
912 memset(ifp, 0, sizeof(struct brcmf_if)); 892 ifp = netdev_priv(ndev);
893 ifp->ndev = ndev;
913 ifp->info = drvr_priv; 894 ifp->info = drvr_priv;
914 drvr_priv->iflist[ifidx] = ifp; 895 drvr_priv->iflist[ifidx] = ifp;
896 ifp->idx = ifidx;
915 if (mac_addr != NULL) 897 if (mac_addr != NULL)
916 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); 898 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
917 899
918 if (ndev == NULL) { 900 if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) {
919 ifp->state = BRCMF_E_IF_ADD; 901 brcmf_dbg(ERROR, "brcmf_net_attach failed");
920 ifp->idx = ifidx; 902 free_netdev(ifp->ndev);
921 /* 903 drvr_priv->iflist[ifidx] = NULL;
922 * Delete the existing interface before overwriting it 904 return -EOPNOTSUPP;
923 * in case we missed the BRCMF_E_IF_DEL event. 905 }
924 */
925 if (ifp->ndev != NULL) {
926 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
927 ifp->ndev->name);
928 netif_stop_queue(ifp->ndev);
929 unregister_netdev(ifp->ndev);
930 free_netdev(ifp->ndev);
931 }
932
933 /* Allocate netdev, including space for private structure */
934 ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d",
935 ether_setup);
936 if (!ifp->ndev) {
937 brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
938 ret = -ENOMEM;
939 }
940
941 if (ret == 0) {
942 memcpy(netdev_priv(ifp->ndev), &drvr_priv,
943 sizeof(drvr_priv));
944 err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
945 if (err != 0) {
946 brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n",
947 err);
948 ret = -EOPNOTSUPP;
949 } else {
950 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
951 current->pid, ifp->ndev->name);
952 ifp->state = 0;
953 }
954 }
955
956 if (ret < 0) {
957 if (ifp->ndev)
958 free_netdev(ifp->ndev);
959 906
960 drvr_priv->iflist[ifp->idx] = NULL; 907 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
961 kfree(ifp); 908 current->pid, ifp->ndev->name);
962 }
963 } else
964 ifp->ndev = ndev;
965 909
966 return 0; 910 return 0;
967} 911}
@@ -977,47 +921,36 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
977 brcmf_dbg(ERROR, "Null interface\n"); 921 brcmf_dbg(ERROR, "Null interface\n");
978 return; 922 return;
979 } 923 }
924 if (ifp->ndev) {
925 if (ifidx == 0) {
926 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
927 rtnl_lock();
928 brcmf_netdev_stop(ifp->ndev);
929 rtnl_unlock();
930 }
931 } else {
932 netif_stop_queue(ifp->ndev);
933 }
980 934
981 ifp->state = BRCMF_E_IF_DEL;
982 ifp->idx = ifidx;
983 if (ifp->ndev != NULL) {
984 netif_stop_queue(ifp->ndev);
985 unregister_netdev(ifp->ndev); 935 unregister_netdev(ifp->ndev);
986 free_netdev(ifp->ndev);
987 drvr_priv->iflist[ifidx] = NULL; 936 drvr_priv->iflist[ifidx] = NULL;
988 kfree(ifp); 937 if (ifidx == 0)
938 brcmf_cfg80211_detach(drvr_priv->pub.config);
939 free_netdev(ifp->ndev);
989 } 940 }
990} 941}
991 942
992struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) 943struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
993{ 944{
994 struct brcmf_info *drvr_priv = NULL; 945 struct brcmf_info *drvr_priv = NULL;
995 struct net_device *ndev;
996 946
997 brcmf_dbg(TRACE, "Enter\n"); 947 brcmf_dbg(TRACE, "Enter\n");
998 948
999 /* Allocate netdev, including space for private structure */
1000 ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup);
1001 if (!ndev) {
1002 brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
1003 goto fail;
1004 }
1005
1006 /* Allocate primary brcmf_info */ 949 /* Allocate primary brcmf_info */
1007 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); 950 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
1008 if (!drvr_priv) 951 if (!drvr_priv)
1009 goto fail; 952 goto fail;
1010 953
1011 /*
1012 * Save the brcmf_info into the priv
1013 */
1014 memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
1015
1016 if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) ==
1017 BRCMF_BAD_IF)
1018 goto fail;
1019
1020 ndev->netdev_ops = NULL;
1021 mutex_init(&drvr_priv->proto_block); 954 mutex_init(&drvr_priv->proto_block);
1022 955
1023 /* Link to info module */ 956 /* Link to info module */
@@ -1033,29 +966,12 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
1033 goto fail; 966 goto fail;
1034 } 967 }
1035 968
1036 /* Attach and link in the cfg80211 */
1037 drvr_priv->pub.config =
1038 brcmf_cfg80211_attach(ndev,
1039 brcmf_bus_get_device(bus),
1040 &drvr_priv->pub);
1041 if (drvr_priv->pub.config == NULL) {
1042 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
1043 goto fail;
1044 }
1045
1046 INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); 969 INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address);
1047 INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); 970 INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list);
1048 971
1049 /*
1050 * Save the brcmf_info into the priv
1051 */
1052 memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
1053
1054 return &drvr_priv->pub; 972 return &drvr_priv->pub;
1055 973
1056fail: 974fail:
1057 if (ndev)
1058 free_netdev(ndev);
1059 if (drvr_priv) 975 if (drvr_priv)
1060 brcmf_detach(&drvr_priv->pub); 976 brcmf_detach(&drvr_priv->pub);
1061 977
@@ -1123,16 +1039,6 @@ int brcmf_bus_start(struct brcmf_pub *drvr)
1123 return 0; 1039 return 0;
1124} 1040}
1125 1041
1126static struct net_device_ops brcmf_netdev_ops_pri = {
1127 .ndo_open = brcmf_netdev_open,
1128 .ndo_stop = brcmf_netdev_stop,
1129 .ndo_get_stats = brcmf_netdev_get_stats,
1130 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
1131 .ndo_start_xmit = brcmf_netdev_start_xmit,
1132 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
1133 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
1134};
1135
1136int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) 1042int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1137{ 1043{
1138 struct brcmf_info *drvr_priv = drvr->info; 1044 struct brcmf_info *drvr_priv = drvr->info;
@@ -1169,6 +1075,18 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1169 1075
1170 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); 1076 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
1171 1077
1078 /* attach to cfg80211 for primary interface */
1079 if (!ifidx) {
1080 drvr->config =
1081 brcmf_cfg80211_attach(ndev,
1082 brcmf_bus_get_device(drvr->bus),
1083 drvr);
1084 if (drvr->config == NULL) {
1085 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
1086 goto fail;
1087 }
1088 }
1089
1172 if (register_netdev(ndev) != 0) { 1090 if (register_netdev(ndev) != 0) {
1173 brcmf_dbg(ERROR, "couldn't register the net device\n"); 1091 brcmf_dbg(ERROR, "couldn't register the net device\n");
1174 goto fail; 1092 goto fail;
@@ -1210,21 +1128,13 @@ void brcmf_detach(struct brcmf_pub *drvr)
1210 if (drvr) { 1128 if (drvr) {
1211 drvr_priv = drvr->info; 1129 drvr_priv = drvr->info;
1212 if (drvr_priv) { 1130 if (drvr_priv) {
1213 struct brcmf_if *ifp;
1214 int i; 1131 int i;
1215 1132
1216 for (i = 1; i < BRCMF_MAX_IFS; i++) 1133 /* make sure primary interface removed last */
1134 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1217 if (drvr_priv->iflist[i]) 1135 if (drvr_priv->iflist[i])
1218 brcmf_del_if(drvr_priv, i); 1136 brcmf_del_if(drvr_priv, i);
1219 1137
1220 ifp = drvr_priv->iflist[0];
1221 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
1222 rtnl_lock();
1223 brcmf_netdev_stop(ifp->ndev);
1224 rtnl_unlock();
1225 unregister_netdev(ifp->ndev);
1226 }
1227
1228 cancel_work_sync(&drvr_priv->setmacaddr_work); 1138 cancel_work_sync(&drvr_priv->setmacaddr_work);
1229 cancel_work_sync(&drvr_priv->multicast_work); 1139 cancel_work_sync(&drvr_priv->multicast_work);
1230 1140
@@ -1233,10 +1143,6 @@ void brcmf_detach(struct brcmf_pub *drvr)
1233 if (drvr->prot) 1143 if (drvr->prot)
1234 brcmf_proto_detach(drvr); 1144 brcmf_proto_detach(drvr);
1235 1145
1236 brcmf_cfg80211_detach(drvr->config);
1237
1238 free_netdev(ifp->ndev);
1239 kfree(ifp);
1240 kfree(drvr_priv); 1146 kfree(drvr_priv);
1241 } 1147 }
1242 } 1148 }
@@ -1302,7 +1208,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1302 1208
1303int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 1209int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1304{ 1210{
1305 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev); 1211 struct brcmf_if *ifp = netdev_priv(ndev);
1212 struct brcmf_info *drvr_priv = ifp->info;
1306 int timeout = 10 * HZ / 1000; 1213 int timeout = 10 * HZ / 1000;
1307 int ntimes = MAX_WAIT_FOR_8021X_TX; 1214 int ntimes = MAX_WAIT_FOR_8021X_TX;
1308 int pend = brcmf_get_pend_8021x_cnt(drvr_priv); 1215 int pend = brcmf_get_pend_8021x_cnt(drvr_priv);