linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Broadcom Corporation
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/etherdevice.h>
  19#include <linux/module.h>
  20#include <linux/inetdevice.h>
  21#include <net/cfg80211.h>
  22#include <net/rtnetlink.h>
  23#include <net/addrconf.h>
  24#include <net/ieee80211_radiotap.h>
  25#include <net/ipv6.h>
  26#include <brcmu_utils.h>
  27#include <brcmu_wifi.h>
  28
  29#include "core.h"
  30#include "bus.h"
  31#include "debug.h"
  32#include "fwil_types.h"
  33#include "p2p.h"
  34#include "pno.h"
  35#include "cfg80211.h"
  36#include "fwil.h"
  37#include "feature.h"
  38#include "proto.h"
  39#include "pcie.h"
  40#include "common.h"
  41
  42#define MAX_WAIT_FOR_8021X_TX                   msecs_to_jiffies(950)
  43
  44#define BRCMF_BSSIDX_INVALID                    -1
  45
  46char *brcmf_ifname(struct brcmf_if *ifp)
  47{
  48        if (!ifp)
  49                return "<if_null>";
  50
  51        if (ifp->ndev)
  52                return ifp->ndev->name;
  53
  54        return "<if_none>";
  55}
  56
  57struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
  58{
  59        struct brcmf_if *ifp;
  60        s32 bsscfgidx;
  61
  62        if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
  63                brcmf_err("ifidx %d out of range\n", ifidx);
  64                return NULL;
  65        }
  66
  67        ifp = NULL;
  68        bsscfgidx = drvr->if2bss[ifidx];
  69        if (bsscfgidx >= 0)
  70                ifp = drvr->iflist[bsscfgidx];
  71
  72        return ifp;
  73}
  74
  75void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
  76{
  77        s32 err;
  78        u32 mode;
  79
  80        if (enable)
  81                mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
  82        else
  83                mode = 0;
  84
  85        /* Try to set and enable ARP offload feature, this may fail, then it  */
  86        /* is simply not supported and err 0 will be returned                 */
  87        err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
  88        if (err) {
  89                brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
  90                          mode, err);
  91        } else {
  92                err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
  93                if (err) {
  94                        brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
  95                                  enable, err);
  96                } else {
  97                        brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
  98                                  enable, mode);
  99                }
 100        }
 101
 102        err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
 103        if (err) {
 104                brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
 105                          enable, err);
 106        } else {
 107                brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
 108                          enable, mode);
 109        }
 110}
 111
 112static void _brcmf_set_multicast_list(struct work_struct *work)
 113{
 114        struct brcmf_if *ifp;
 115        struct net_device *ndev;
 116        struct netdev_hw_addr *ha;
 117        u32 cmd_value, cnt;
 118        __le32 cnt_le;
 119        char *buf, *bufp;
 120        u32 buflen;
 121        s32 err;
 122
 123        ifp = container_of(work, struct brcmf_if, multicast_work);
 124
 125        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
 126
 127        ndev = ifp->ndev;
 128
 129        /* Determine initial value of allmulti flag */
 130        cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
 131
 132        /* Send down the multicast list first. */
 133        cnt = netdev_mc_count(ndev);
 134        buflen = sizeof(cnt) + (cnt * ETH_ALEN);
 135        buf = kmalloc(buflen, GFP_ATOMIC);
 136        if (!buf)
 137                return;
 138        bufp = buf;
 139
 140        cnt_le = cpu_to_le32(cnt);
 141        memcpy(bufp, &cnt_le, sizeof(cnt_le));
 142        bufp += sizeof(cnt_le);
 143
 144        netdev_for_each_mc_addr(ha, ndev) {
 145                if (!cnt)
 146                        break;
 147                memcpy(bufp, ha->addr, ETH_ALEN);
 148                bufp += ETH_ALEN;
 149                cnt--;
 150        }
 151
 152        err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
 153        if (err < 0) {
 154                brcmf_err("Setting mcast_list failed, %d\n", err);
 155                cmd_value = cnt ? true : cmd_value;
 156        }
 157
 158        kfree(buf);
 159
 160        /*
 161         * Now send the allmulti setting.  This is based on the setting in the
 162         * net_device flags, but might be modified above to be turned on if we
 163         * were trying to set some addresses and dongle rejected it...
 164         */
 165        err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
 166        if (err < 0)
 167                brcmf_err("Setting allmulti failed, %d\n", err);
 168
 169        /*Finally, pick up the PROMISC flag */
 170        cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
 171        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
 172        if (err < 0)
 173                brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
 174                          err);
 175        brcmf_configure_arp_nd_offload(ifp, !cmd_value);
 176}
 177
 178#if IS_ENABLED(CONFIG_IPV6)
 179static void _brcmf_update_ndtable(struct work_struct *work)
 180{
 181        struct brcmf_if *ifp;
 182        int i, ret;
 183
 184        ifp = container_of(work, struct brcmf_if, ndoffload_work);
 185
 186        /* clear the table in firmware */
 187        ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
 188        if (ret) {
 189                brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret);
 190                return;
 191        }
 192
 193        for (i = 0; i < ifp->ipv6addr_idx; i++) {
 194                ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",
 195                                               &ifp->ipv6_addr_tbl[i],
 196                                               sizeof(struct in6_addr));
 197                if (ret)
 198                        brcmf_err("add nd ip err %d\n", ret);
 199        }
 200}
 201#else
 202static void _brcmf_update_ndtable(struct work_struct *work)
 203{
 204}
 205#endif
 206
 207static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
 208{
 209        struct brcmf_if *ifp = netdev_priv(ndev);
 210        struct sockaddr *sa = (struct sockaddr *)addr;
 211        int err;
 212
 213        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
 214
 215        err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data,
 216                                       ETH_ALEN);
 217        if (err < 0) {
 218                brcmf_err("Setting cur_etheraddr failed, %d\n", err);
 219        } else {
 220                brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);
 221                memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);
 222                memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
 223        }
 224        return err;
 225}
 226
 227static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
 228{
 229        struct brcmf_if *ifp = netdev_priv(ndev);
 230
 231        schedule_work(&ifp->multicast_work);
 232}
 233
 234/**
 235 * brcmf_skb_is_iapp - checks if skb is an IAPP packet
 236 *
 237 * @skb: skb to check
 238 */
 239static bool brcmf_skb_is_iapp(struct sk_buff *skb)
 240{
 241        static const u8 iapp_l2_update_packet[6] __aligned(2) = {
 242                0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
 243        };
 244        unsigned char *eth_data;
 245#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
 246        const u16 *a, *b;
 247#endif
 248
 249        if (skb->len - skb->mac_len != 6 ||
 250            !is_multicast_ether_addr(eth_hdr(skb)->h_dest))
 251                return false;
 252
 253        eth_data = skb_mac_header(skb) + ETH_HLEN;
 254#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
 255        return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) |
 256                 ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4))));
 257#else
 258        a = (const u16 *)eth_data;
 259        b = (const u16 *)iapp_l2_update_packet;
 260
 261        return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
 262#endif
 263}
 264
 265static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
 266                                           struct net_device *ndev)
 267{
 268        int ret;
 269        struct brcmf_if *ifp = netdev_priv(ndev);
 270        struct brcmf_pub *drvr = ifp->drvr;
 271        struct ethhdr *eh;
 272        int head_delta;
 273
 274        brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
 275
 276        /* Can the device send data? */
 277        if (drvr->bus_if->state != BRCMF_BUS_UP) {
 278                brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
 279                netif_stop_queue(ndev);
 280                dev_kfree_skb(skb);
 281                ret = -ENODEV;
 282                goto done;
 283        }
 284
 285        /* Some recent Broadcom's firmwares disassociate STA when they receive
 286         * an 802.11f ADD frame. This behavior can lead to a local DoS security
 287         * issue. Attacker may trigger disassociation of any STA by sending a
 288         * proper Ethernet frame to the wireless interface.
 289         *
 290         * Moreover this feature may break AP interfaces in some specific
 291         * setups. This applies e.g. to the bridge with hairpin mode enabled and
 292         * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware
 293         * will get passed back to the wireless interface and cause immediate
 294         * disassociation of a just-connected STA.
 295         */
 296        if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
 297                dev_kfree_skb(skb);
 298                ret = -EINVAL;
 299                goto done;
 300        }
 301
 302        /* Make sure there's enough writeable headroom */
 303        if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {
 304                head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);
 305
 306                brcmf_dbg(INFO, "%s: insufficient headroom (%d)\n",
 307                          brcmf_ifname(ifp), head_delta);
 308                atomic_inc(&drvr->bus_if->stats.pktcowed);
 309                ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0,
 310                                       GFP_ATOMIC);
 311                if (ret < 0) {
 312                        brcmf_err("%s: failed to expand headroom\n",
 313                                  brcmf_ifname(ifp));
 314                        atomic_inc(&drvr->bus_if->stats.pktcow_failed);
 315                        goto done;
 316                }
 317        }
 318
 319        /* validate length for ether packet */
 320        if (skb->len < sizeof(*eh)) {
 321                ret = -EINVAL;
 322                dev_kfree_skb(skb);
 323                goto done;
 324        }
 325
 326        eh = (struct ethhdr *)(skb->data);
 327
 328        if (eh->h_proto == htons(ETH_P_PAE))
 329                atomic_inc(&ifp->pend_8021x_cnt);
 330
 331        /* determine the priority */
 332        if ((skb->priority == 0) || (skb->priority > 7))
 333                skb->priority = cfg80211_classify8021d(skb, NULL);
 334
 335        ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
 336        if (ret < 0)
 337                brcmf_txfinalize(ifp, skb, false);
 338
 339done:
 340        if (ret) {
 341                ndev->stats.tx_dropped++;
 342        } else {
 343                ndev->stats.tx_packets++;
 344                ndev->stats.tx_bytes += skb->len;
 345        }
 346
 347        /* Return ok: we always eat the packet */
 348        return NETDEV_TX_OK;
 349}
 350
 351void brcmf_txflowblock_if(struct brcmf_if *ifp,
 352                          enum brcmf_netif_stop_reason reason, bool state)
 353{
 354        unsigned long flags;
 355
 356        if (!ifp || !ifp->ndev)
 357                return;
 358
 359        brcmf_dbg(TRACE, "enter: bsscfgidx=%d stop=0x%X reason=%d state=%d\n",
 360                  ifp->bsscfgidx, ifp->netif_stop, reason, state);
 361
 362        spin_lock_irqsave(&ifp->netif_stop_lock, flags);
 363        if (state) {
 364                if (!ifp->netif_stop)
 365                        netif_stop_queue(ifp->ndev);
 366                ifp->netif_stop |= reason;
 367        } else {
 368                ifp->netif_stop &= ~reason;
 369                if (!ifp->netif_stop)
 370                        netif_wake_queue(ifp->ndev);
 371        }
 372        spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
 373}
 374
 375void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 376{
 377        /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
 378         * STA connects to the AP interface. This is an obsoleted standard most
 379         * users don't use, so don't pass these frames up unless requested.
 380         */
 381        if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
 382                brcmu_pkt_buf_free_skb(skb);
 383                return;
 384        }
 385
 386        if (skb->pkt_type == PACKET_MULTICAST)
 387                ifp->ndev->stats.multicast++;
 388
 389        if (!(ifp->ndev->flags & IFF_UP)) {
 390                brcmu_pkt_buf_free_skb(skb);
 391                return;
 392        }
 393
 394        ifp->ndev->stats.rx_bytes += skb->len;
 395        ifp->ndev->stats.rx_packets++;
 396
 397        brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol));
 398        if (in_interrupt())
 399                netif_rx(skb);
 400        else
 401                /* If the receive is not processed inside an ISR,
 402                 * the softirqd must be woken explicitly to service
 403                 * the NET_RX_SOFTIRQ.  This is handled by netif_rx_ni().
 404                 */
 405                netif_rx_ni(skb);
 406}
 407
 408void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 409{
 410        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
 411                /* Do nothing */
 412        } else {
 413                struct ieee80211_radiotap_header *radiotap;
 414
 415                /* TODO: use RX status to fill some radiotap data */
 416                radiotap = skb_push(skb, sizeof(*radiotap));
 417                memset(radiotap, 0, sizeof(*radiotap));
 418                radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
 419
 420                /* TODO: 4 bytes with receive status? */
 421                skb->len -= 4;
 422        }
 423
 424        skb->dev = ifp->ndev;
 425        skb_reset_mac_header(skb);
 426        skb->pkt_type = PACKET_OTHERHOST;
 427        skb->protocol = htons(ETH_P_802_2);
 428
 429        brcmf_netif_rx(ifp, skb);
 430}
 431
 432static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
 433                            struct brcmf_if **ifp)
 434{
 435        int ret;
 436
 437        /* process and remove protocol-specific header */
 438        ret = brcmf_proto_hdrpull(drvr, true, skb, ifp);
 439
 440        if (ret || !(*ifp) || !(*ifp)->ndev) {
 441                if (ret != -ENODATA && *ifp)
 442                        (*ifp)->ndev->stats.rx_errors++;
 443                brcmu_pkt_buf_free_skb(skb);
 444                return -ENODATA;
 445        }
 446
 447        skb->protocol = eth_type_trans(skb, (*ifp)->ndev);
 448        return 0;
 449}
 450
 451void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
 452{
 453        struct brcmf_if *ifp;
 454        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 455        struct brcmf_pub *drvr = bus_if->drvr;
 456
 457        brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
 458
 459        if (brcmf_rx_hdrpull(drvr, skb, &ifp))
 460                return;
 461
 462        if (brcmf_proto_is_reorder_skb(skb)) {
 463                brcmf_proto_rxreorder(ifp, skb);
 464        } else {
 465                /* Process special event packets */
 466                if (handle_event)
 467                        brcmf_fweh_process_skb(ifp->drvr, skb);
 468
 469                brcmf_netif_rx(ifp, skb);
 470        }
 471}
 472
 473void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
 474{
 475        struct brcmf_if *ifp;
 476        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 477        struct brcmf_pub *drvr = bus_if->drvr;
 478
 479        brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
 480
 481        if (brcmf_rx_hdrpull(drvr, skb, &ifp))
 482                return;
 483
 484        brcmf_fweh_process_skb(ifp->drvr, skb);
 485        brcmu_pkt_buf_free_skb(skb);
 486}
 487
 488void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
 489{
 490        struct ethhdr *eh;
 491        u16 type;
 492
 493        eh = (struct ethhdr *)(txp->data);
 494        type = ntohs(eh->h_proto);
 495
 496        if (type == ETH_P_PAE) {
 497                atomic_dec(&ifp->pend_8021x_cnt);
 498                if (waitqueue_active(&ifp->pend_8021x_wait))
 499                        wake_up(&ifp->pend_8021x_wait);
 500        }
 501
 502        if (!success)
 503                ifp->ndev->stats.tx_errors++;
 504
 505        brcmu_pkt_buf_free_skb(txp);
 506}
 507
 508static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
 509                                    struct ethtool_drvinfo *info)
 510{
 511        struct brcmf_if *ifp = netdev_priv(ndev);
 512        struct brcmf_pub *drvr = ifp->drvr;
 513        char drev[BRCMU_DOTREV_LEN] = "n/a";
 514
 515        if (drvr->revinfo.result == 0)
 516                brcmu_dotrev_str(drvr->revinfo.driverrev, drev);
 517        strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
 518        strlcpy(info->version, drev, sizeof(info->version));
 519        strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
 520        strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
 521                sizeof(info->bus_info));
 522}
 523
 524static const struct ethtool_ops brcmf_ethtool_ops = {
 525        .get_drvinfo = brcmf_ethtool_get_drvinfo,
 526};
 527
 528static int brcmf_netdev_stop(struct net_device *ndev)
 529{
 530        struct brcmf_if *ifp = netdev_priv(ndev);
 531
 532        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
 533
 534        brcmf_cfg80211_down(ndev);
 535
 536        brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0);
 537
 538        brcmf_net_setcarrier(ifp, false);
 539
 540        return 0;
 541}
 542
 543static int brcmf_netdev_open(struct net_device *ndev)
 544{
 545        struct brcmf_if *ifp = netdev_priv(ndev);
 546        struct brcmf_pub *drvr = ifp->drvr;
 547        struct brcmf_bus *bus_if = drvr->bus_if;
 548        u32 toe_ol;
 549
 550        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
 551
 552        /* If bus is not ready, can't continue */
 553        if (bus_if->state != BRCMF_BUS_UP) {
 554                brcmf_err("failed bus is not ready\n");
 555                return -EAGAIN;
 556        }
 557
 558        atomic_set(&ifp->pend_8021x_cnt, 0);
 559
 560        /* Get current TOE mode from dongle */
 561        if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
 562            && (toe_ol & TOE_TX_CSUM_OL) != 0)
 563                ndev->features |= NETIF_F_IP_CSUM;
 564        else
 565                ndev->features &= ~NETIF_F_IP_CSUM;
 566
 567        if (brcmf_cfg80211_up(ndev)) {
 568                brcmf_err("failed to bring up cfg80211\n");
 569                return -EIO;
 570        }
 571
 572        /* Clear, carrier, set when connected or AP mode. */
 573        netif_carrier_off(ndev);
 574        return 0;
 575}
 576
 577static const struct net_device_ops brcmf_netdev_ops_pri = {
 578        .ndo_open = brcmf_netdev_open,
 579        .ndo_stop = brcmf_netdev_stop,
 580        .ndo_start_xmit = brcmf_netdev_start_xmit,
 581        .ndo_set_mac_address = brcmf_netdev_set_mac_address,
 582        .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
 583};
 584
 585int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
 586{
 587        struct brcmf_pub *drvr = ifp->drvr;
 588        struct net_device *ndev;
 589        s32 err;
 590
 591        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
 592                  ifp->mac_addr);
 593        ndev = ifp->ndev;
 594
 595        /* set appropriate operations */
 596        ndev->netdev_ops = &brcmf_netdev_ops_pri;
 597
 598        ndev->needed_headroom += drvr->hdrlen;
 599        ndev->ethtool_ops = &brcmf_ethtool_ops;
 600
 601        /* set the mac address & netns */
 602        memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
 603        dev_net_set(ndev, wiphy_net(cfg_to_wiphy(drvr->config)));
 604
 605        INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
 606        INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
 607
 608        if (rtnl_locked)
 609                err = register_netdevice(ndev);
 610        else
 611                err = register_netdev(ndev);
 612        if (err != 0) {
 613                brcmf_err("couldn't register the net device\n");
 614                goto fail;
 615        }
 616
 617        ndev->priv_destructor = brcmf_cfg80211_free_netdev;
 618        brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
 619        return 0;
 620
 621fail:
 622        drvr->iflist[ifp->bsscfgidx] = NULL;
 623        ndev->netdev_ops = NULL;
 624        return -EBADE;
 625}
 626
 627static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
 628{
 629        if (ndev->reg_state == NETREG_REGISTERED) {
 630                if (rtnl_locked)
 631                        unregister_netdevice(ndev);
 632                else
 633                        unregister_netdev(ndev);
 634        } else {
 635                brcmf_cfg80211_free_netdev(ndev);
 636                free_netdev(ndev);
 637        }
 638}
 639
 640void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
 641{
 642        struct net_device *ndev;
 643
 644        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d carrier=%d\n", ifp->bsscfgidx,
 645                  on);
 646
 647        ndev = ifp->ndev;
 648        brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_DISCONNECTED, !on);
 649        if (on) {
 650                if (!netif_carrier_ok(ndev))
 651                        netif_carrier_on(ndev);
 652
 653        } else {
 654                if (netif_carrier_ok(ndev))
 655                        netif_carrier_off(ndev);
 656        }
 657}
 658
 659static int brcmf_net_p2p_open(struct net_device *ndev)
 660{
 661        brcmf_dbg(TRACE, "Enter\n");
 662
 663        return brcmf_cfg80211_up(ndev);
 664}
 665
 666static int brcmf_net_p2p_stop(struct net_device *ndev)
 667{
 668        brcmf_dbg(TRACE, "Enter\n");
 669
 670        return brcmf_cfg80211_down(ndev);
 671}
 672
 673static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
 674                                            struct net_device *ndev)
 675{
 676        if (skb)
 677                dev_kfree_skb_any(skb);
 678
 679        return NETDEV_TX_OK;
 680}
 681
 682static const struct net_device_ops brcmf_netdev_ops_p2p = {
 683        .ndo_open = brcmf_net_p2p_open,
 684        .ndo_stop = brcmf_net_p2p_stop,
 685        .ndo_start_xmit = brcmf_net_p2p_start_xmit
 686};
 687
 688static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
 689{
 690        struct net_device *ndev;
 691
 692        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
 693                  ifp->mac_addr);
 694        ndev = ifp->ndev;
 695
 696        ndev->netdev_ops = &brcmf_netdev_ops_p2p;
 697
 698        /* set the mac address */
 699        memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
 700
 701        if (register_netdev(ndev) != 0) {
 702                brcmf_err("couldn't register the p2p net device\n");
 703                goto fail;
 704        }
 705
 706        brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
 707
 708        return 0;
 709
 710fail:
 711        ifp->drvr->iflist[ifp->bsscfgidx] = NULL;
 712        ndev->netdev_ops = NULL;
 713        return -EBADE;
 714}
 715
 716struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
 717                              bool is_p2pdev, const char *name, u8 *mac_addr)
 718{
 719        struct brcmf_if *ifp;
 720        struct net_device *ndev;
 721
 722        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, ifidx);
 723
 724        ifp = drvr->iflist[bsscfgidx];
 725        /*
 726         * Delete the existing interface before overwriting it
 727         * in case we missed the BRCMF_E_IF_DEL event.
 728         */
 729        if (ifp) {
 730                if (ifidx) {
 731                        brcmf_err("ERROR: netdev:%s already exists\n",
 732                                  ifp->ndev->name);
 733                        netif_stop_queue(ifp->ndev);
 734                        brcmf_net_detach(ifp->ndev, false);
 735                        drvr->iflist[bsscfgidx] = NULL;
 736                } else {
 737                        brcmf_dbg(INFO, "netdev:%s ignore IF event\n",
 738                                  ifp->ndev->name);
 739                        return ERR_PTR(-EINVAL);
 740                }
 741        }
 742
 743        if (!drvr->settings->p2p_enable && is_p2pdev) {
 744                /* this is P2P_DEVICE interface */
 745                brcmf_dbg(INFO, "allocate non-netdev interface\n");
 746                ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
 747                if (!ifp)
 748                        return ERR_PTR(-ENOMEM);
 749        } else {
 750                brcmf_dbg(INFO, "allocate netdev interface\n");
 751                /* Allocate netdev, including space for private structure */
 752                ndev = alloc_netdev(sizeof(*ifp), is_p2pdev ? "p2p%d" : name,
 753                                    NET_NAME_UNKNOWN, ether_setup);
 754                if (!ndev)
 755                        return ERR_PTR(-ENOMEM);
 756
 757                ndev->needs_free_netdev = true;
 758                ifp = netdev_priv(ndev);
 759                ifp->ndev = ndev;
 760                /* store mapping ifidx to bsscfgidx */
 761                if (drvr->if2bss[ifidx] == BRCMF_BSSIDX_INVALID)
 762                        drvr->if2bss[ifidx] = bsscfgidx;
 763        }
 764
 765        ifp->drvr = drvr;
 766        drvr->iflist[bsscfgidx] = ifp;
 767        ifp->ifidx = ifidx;
 768        ifp->bsscfgidx = bsscfgidx;
 769
 770        init_waitqueue_head(&ifp->pend_8021x_wait);
 771        spin_lock_init(&ifp->netif_stop_lock);
 772
 773        if (mac_addr != NULL)
 774                memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
 775
 776        brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n",
 777                  current->pid, name, ifp->mac_addr);
 778
 779        return ifp;
 780}
 781
 782static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,
 783                         bool rtnl_locked)
 784{
 785        struct brcmf_if *ifp;
 786
 787        ifp = drvr->iflist[bsscfgidx];
 788        drvr->iflist[bsscfgidx] = NULL;
 789        if (!ifp) {
 790                brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx);
 791                return;
 792        }
 793        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,
 794                  ifp->ifidx);
 795        if (drvr->if2bss[ifp->ifidx] == bsscfgidx)
 796                drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID;
 797        if (ifp->ndev) {
 798                if (bsscfgidx == 0) {
 799                        if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
 800                                rtnl_lock();
 801                                brcmf_netdev_stop(ifp->ndev);
 802                                rtnl_unlock();
 803                        }
 804                } else {
 805                        netif_stop_queue(ifp->ndev);
 806                }
 807
 808                if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
 809                        cancel_work_sync(&ifp->multicast_work);
 810                        cancel_work_sync(&ifp->ndoffload_work);
 811                }
 812                brcmf_net_detach(ifp->ndev, rtnl_locked);
 813        } else {
 814                /* Only p2p device interfaces which get dynamically created
 815                 * end up here. In this case the p2p module should be informed
 816                 * about the removal of the interface within the firmware. If
 817                 * not then p2p commands towards the firmware will cause some
 818                 * serious troublesome side effects. The p2p module will clean
 819                 * up the ifp if needed.
 820                 */
 821                brcmf_p2p_ifp_removed(ifp, rtnl_locked);
 822                kfree(ifp);
 823        }
 824}
 825
 826void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
 827{
 828        if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))
 829                return;
 830        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
 831                  ifp->ifidx);
 832        brcmf_proto_del_if(ifp->drvr, ifp);
 833        brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
 834}
 835
 836static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,
 837                                     const struct brcmf_event_msg *evtmsg,
 838                                     void *data)
 839{
 840        int err;
 841
 842        brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
 843
 844        brcmf_err("PSM's watchdog has fired!\n");
 845
 846        err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
 847                                         evtmsg->datalen);
 848        if (err)
 849                brcmf_err("Failed to get memory dump, %d\n", err);
 850
 851        return err;
 852}
 853
 854#ifdef CONFIG_INET
 855#define ARPOL_MAX_ENTRIES       8
 856static int brcmf_inetaddr_changed(struct notifier_block *nb,
 857                                  unsigned long action, void *data)
 858{
 859        struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,
 860                                              inetaddr_notifier);
 861        struct in_ifaddr *ifa = data;
 862        struct net_device *ndev = ifa->ifa_dev->dev;
 863        struct brcmf_if *ifp;
 864        int idx, i, ret;
 865        u32 val;
 866        __be32 addr_table[ARPOL_MAX_ENTRIES] = {0};
 867
 868        /* Find out if the notification is meant for us */
 869        for (idx = 0; idx < BRCMF_MAX_IFS; idx++) {
 870                ifp = drvr->iflist[idx];
 871                if (ifp && ifp->ndev == ndev)
 872                        break;
 873                if (idx == BRCMF_MAX_IFS - 1)
 874                        return NOTIFY_DONE;
 875        }
 876
 877        /* check if arp offload is supported */
 878        ret = brcmf_fil_iovar_int_get(ifp, "arpoe", &val);
 879        if (ret)
 880                return NOTIFY_OK;
 881
 882        /* old version only support primary index */
 883        ret = brcmf_fil_iovar_int_get(ifp, "arp_version", &val);
 884        if (ret)
 885                val = 1;
 886        if (val == 1)
 887                ifp = drvr->iflist[0];
 888
 889        /* retrieve the table from firmware */
 890        ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table,
 891                                       sizeof(addr_table));
 892        if (ret) {
 893                brcmf_err("fail to get arp ip table err:%d\n", ret);
 894                return NOTIFY_OK;
 895        }
 896
 897        for (i = 0; i < ARPOL_MAX_ENTRIES; i++)
 898                if (ifa->ifa_address == addr_table[i])
 899                        break;
 900
 901        switch (action) {
 902        case NETDEV_UP:
 903                if (i == ARPOL_MAX_ENTRIES) {
 904                        brcmf_dbg(TRACE, "add %pI4 to arp table\n",
 905                                  &ifa->ifa_address);
 906                        /* set it directly */
 907                        ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
 908                                &ifa->ifa_address, sizeof(ifa->ifa_address));
 909                        if (ret)
 910                                brcmf_err("add arp ip err %d\n", ret);
 911                }
 912                break;
 913        case NETDEV_DOWN:
 914                if (i < ARPOL_MAX_ENTRIES) {
 915                        addr_table[i] = 0;
 916                        brcmf_dbg(TRACE, "remove %pI4 from arp table\n",
 917                                  &ifa->ifa_address);
 918                        /* clear the table in firmware */
 919                        ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear",
 920                                                       NULL, 0);
 921                        if (ret) {
 922                                brcmf_err("fail to clear arp ip table err:%d\n",
 923                                          ret);
 924                                return NOTIFY_OK;
 925                        }
 926                        for (i = 0; i < ARPOL_MAX_ENTRIES; i++) {
 927                                if (addr_table[i] == 0)
 928                                        continue;
 929                                ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
 930                                                               &addr_table[i],
 931                                                               sizeof(addr_table[i]));
 932                                if (ret)
 933                                        brcmf_err("add arp ip err %d\n",
 934                                                  ret);
 935                        }
 936                }
 937                break;
 938        default:
 939                break;
 940        }
 941
 942        return NOTIFY_OK;
 943}
 944#endif
 945
 946#if IS_ENABLED(CONFIG_IPV6)
 947static int brcmf_inet6addr_changed(struct notifier_block *nb,
 948                                   unsigned long action, void *data)
 949{
 950        struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,
 951                                              inet6addr_notifier);
 952        struct inet6_ifaddr *ifa = data;
 953        struct brcmf_if *ifp;
 954        int i;
 955        struct in6_addr *table;
 956
 957        /* Only handle primary interface */
 958        ifp = drvr->iflist[0];
 959        if (!ifp)
 960                return NOTIFY_DONE;
 961        if (ifp->ndev != ifa->idev->dev)
 962                return NOTIFY_DONE;
 963
 964        table = ifp->ipv6_addr_tbl;
 965        for (i = 0; i < NDOL_MAX_ENTRIES; i++)
 966                if (ipv6_addr_equal(&ifa->addr, &table[i]))
 967                        break;
 968
 969        switch (action) {
 970        case NETDEV_UP:
 971                if (i == NDOL_MAX_ENTRIES) {
 972                        if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) {
 973                                table[ifp->ipv6addr_idx++] = ifa->addr;
 974                        } else {
 975                                for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++)
 976                                        table[i] = table[i + 1];
 977                                table[NDOL_MAX_ENTRIES - 1] = ifa->addr;
 978                        }
 979                }
 980                break;
 981        case NETDEV_DOWN:
 982                if (i < NDOL_MAX_ENTRIES) {
 983                        for (; i < ifp->ipv6addr_idx - 1; i++)
 984                                table[i] = table[i + 1];
 985                        memset(&table[i], 0, sizeof(table[i]));
 986                        ifp->ipv6addr_idx--;
 987                }
 988                break;
 989        default:
 990                break;
 991        }
 992
 993        schedule_work(&ifp->ndoffload_work);
 994
 995        return NOTIFY_OK;
 996}
 997#endif
 998
 999static int brcmf_revinfo_read(struct seq_file *s, void *data)
1000{
1001        struct brcmf_bus *bus_if = dev_get_drvdata(s->private);
1002        struct brcmf_rev_info *ri = &bus_if->drvr->revinfo;
1003        char drev[BRCMU_DOTREV_LEN];
1004        char brev[BRCMU_BOARDREV_LEN];
1005
1006        seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid);
1007        seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid);
1008        seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev));
1009        seq_printf(s, "chip: %s\n", ri->chipname);
1010        seq_printf(s, "chippkg: %u\n", ri->chippkg);
1011        seq_printf(s, "corerev: %u\n", ri->corerev);
1012        seq_printf(s, "boardid: 0x%04x\n", ri->boardid);
1013        seq_printf(s, "boardvendor: 0x%04x\n", ri->boardvendor);
1014        seq_printf(s, "boardrev: %s\n", brcmu_boardrev_str(ri->boardrev, brev));
1015        seq_printf(s, "driverrev: %s\n", brcmu_dotrev_str(ri->driverrev, drev));
1016        seq_printf(s, "ucoderev: %u\n", ri->ucoderev);
1017        seq_printf(s, "bus: %u\n", ri->bus);
1018        seq_printf(s, "phytype: %u\n", ri->phytype);
1019        seq_printf(s, "phyrev: %u\n", ri->phyrev);
1020        seq_printf(s, "anarev: %u\n", ri->anarev);
1021        seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
1022
1023        seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);
1024
1025        return 0;
1026}
1027
1028static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
1029{
1030        int ret = -1;
1031        struct brcmf_bus *bus_if = drvr->bus_if;
1032        struct brcmf_if *ifp;
1033        struct brcmf_if *p2p_ifp;
1034
1035        brcmf_dbg(TRACE, "\n");
1036
1037        /* add primary networking interface */
1038        ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL);
1039        if (IS_ERR(ifp))
1040                return PTR_ERR(ifp);
1041
1042        p2p_ifp = NULL;
1043
1044        /* signal bus ready */
1045        brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);
1046
1047        /* do bus specific preinit here */
1048        ret = brcmf_bus_preinit(bus_if);
1049        if (ret < 0)
1050                goto fail;
1051
1052        /* Bus is ready, do any initialization */
1053        ret = brcmf_c_preinit_dcmds(ifp);
1054        if (ret < 0)
1055                goto fail;
1056
1057        brcmf_feat_attach(drvr);
1058
1059        ret = brcmf_proto_init_done(drvr);
1060        if (ret < 0)
1061                goto fail;
1062
1063        brcmf_proto_add_if(drvr, ifp);
1064
1065        drvr->config = brcmf_cfg80211_attach(drvr, ops,
1066                                             drvr->settings->p2p_enable);
1067        if (drvr->config == NULL) {
1068                ret = -ENOMEM;
1069                goto fail;
1070        }
1071
1072        ret = brcmf_net_attach(ifp, false);
1073
1074        if ((!ret) && (drvr->settings->p2p_enable)) {
1075                p2p_ifp = drvr->iflist[1];
1076                if (p2p_ifp)
1077                        ret = brcmf_net_p2p_attach(p2p_ifp);
1078        }
1079
1080        if (ret)
1081                goto fail;
1082
1083#ifdef CONFIG_INET
1084        drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed;
1085        ret = register_inetaddr_notifier(&drvr->inetaddr_notifier);
1086        if (ret)
1087                goto fail;
1088
1089#if IS_ENABLED(CONFIG_IPV6)
1090        drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed;
1091        ret = register_inet6addr_notifier(&drvr->inet6addr_notifier);
1092        if (ret) {
1093                unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
1094                goto fail;
1095        }
1096#endif
1097#endif /* CONFIG_INET */
1098
1099        /* populate debugfs */
1100        brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1101        brcmf_feat_debugfs_create(drvr);
1102        brcmf_proto_debugfs_create(drvr);
1103
1104        return 0;
1105
1106fail:
1107        brcmf_err("failed: %d\n", ret);
1108        if (drvr->config) {
1109                brcmf_cfg80211_detach(drvr->config);
1110                drvr->config = NULL;
1111        }
1112        brcmf_net_detach(ifp->ndev, false);
1113        if (p2p_ifp)
1114                brcmf_net_detach(p2p_ifp->ndev, false);
1115        drvr->iflist[0] = NULL;
1116        drvr->iflist[1] = NULL;
1117        if (drvr->settings->ignore_probe_fail)
1118                ret = 0;
1119
1120        return ret;
1121}
1122
1123int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
1124{
1125        struct wiphy *wiphy;
1126        struct cfg80211_ops *ops;
1127        struct brcmf_pub *drvr = NULL;
1128        int ret = 0;
1129        int i;
1130
1131        brcmf_dbg(TRACE, "Enter\n");
1132
1133        ops = brcmf_cfg80211_get_ops();
1134        if (!ops)
1135                return -ENOMEM;
1136
1137        wiphy = wiphy_new(ops, sizeof(*drvr));
1138        if (!wiphy)
1139                return -ENOMEM;
1140
1141        set_wiphy_dev(wiphy, dev);
1142        drvr = wiphy_priv(wiphy);
1143        drvr->wiphy = wiphy;
1144
1145        for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
1146                drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
1147
1148        mutex_init(&drvr->proto_block);
1149
1150        /* Link to bus module */
1151        drvr->hdrlen = 0;
1152        drvr->bus_if = dev_get_drvdata(dev);
1153        drvr->bus_if->drvr = drvr;
1154        drvr->settings = settings;
1155
1156        /* Attach and link in the protocol */
1157        ret = brcmf_proto_attach(drvr);
1158        if (ret != 0) {
1159                brcmf_err("brcmf_prot_attach failed\n");
1160                goto fail;
1161        }
1162
1163        /* Attach to events important for core code */
1164        brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
1165                            brcmf_psm_watchdog_notify);
1166
1167        /* attach firmware event handler */
1168        brcmf_fweh_attach(drvr);
1169
1170        ret = brcmf_bus_started(drvr, ops);
1171        if (ret != 0) {
1172                brcmf_err("dongle is not responding: err=%d\n", ret);
1173                goto fail;
1174        }
1175
1176        drvr->config->ops = ops;
1177        return 0;
1178
1179fail:
1180        brcmf_detach(dev);
1181        kfree(ops);
1182
1183        return ret;
1184}
1185
1186void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
1187{
1188        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1189        struct brcmf_pub *drvr = bus_if->drvr;
1190
1191        if (drvr) {
1192                drvr->hdrlen += len;
1193        }
1194}
1195
1196void brcmf_dev_reset(struct device *dev)
1197{
1198        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1199        struct brcmf_pub *drvr = bus_if->drvr;
1200
1201        if (drvr == NULL)
1202                return;
1203
1204        if (drvr->iflist[0])
1205                brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1);
1206}
1207
1208void brcmf_dev_coredump(struct device *dev)
1209{
1210        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1211
1212        if (brcmf_debug_create_memdump(bus_if, NULL, 0) < 0)
1213                brcmf_dbg(TRACE, "failed to create coredump\n");
1214}
1215
1216void brcmf_detach(struct device *dev)
1217{
1218        s32 i;
1219        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1220        struct brcmf_pub *drvr = bus_if->drvr;
1221
1222        brcmf_dbg(TRACE, "Enter\n");
1223
1224        if (drvr == NULL)
1225                return;
1226
1227#ifdef CONFIG_INET
1228        unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
1229#endif
1230
1231#if IS_ENABLED(CONFIG_IPV6)
1232        unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
1233#endif
1234
1235        /* stop firmware event handling */
1236        brcmf_fweh_detach(drvr);
1237        if (drvr->config)
1238                brcmf_p2p_detach(&drvr->config->p2p);
1239
1240        brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
1241
1242        /* make sure primary interface removed last */
1243        for (i = BRCMF_MAX_IFS-1; i > -1; i--)
1244                brcmf_remove_interface(drvr->iflist[i], false);
1245
1246        brcmf_cfg80211_detach(drvr->config);
1247        drvr->config = NULL;
1248
1249        brcmf_bus_stop(drvr->bus_if);
1250
1251        brcmf_proto_detach(drvr);
1252
1253        bus_if->drvr = NULL;
1254        wiphy_free(drvr->wiphy);
1255}
1256
1257s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
1258{
1259        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1260        struct brcmf_if *ifp = bus_if->drvr->iflist[0];
1261
1262        return brcmf_fil_iovar_data_set(ifp, name, data, len);
1263}
1264
1265static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1266{
1267        return atomic_read(&ifp->pend_8021x_cnt);
1268}
1269
1270int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
1271{
1272        int err;
1273
1274        err = wait_event_timeout(ifp->pend_8021x_wait,
1275                                 !brcmf_get_pend_8021x_cnt(ifp),
1276                                 MAX_WAIT_FOR_8021X_TX);
1277
1278        if (!err)
1279                brcmf_err("Timed out waiting for no pending 802.1x packets\n");
1280
1281        return !err;
1282}
1283
1284void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state)
1285{
1286        struct brcmf_pub *drvr = bus->drvr;
1287        struct net_device *ndev;
1288        int ifidx;
1289
1290        brcmf_dbg(TRACE, "%d -> %d\n", bus->state, state);
1291
1292        if (!drvr) {
1293                brcmf_dbg(INFO, "ignoring transition, bus not attached yet\n");
1294                return;
1295        }
1296
1297        bus->state = state;
1298
1299        if (state == BRCMF_BUS_UP) {
1300                for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
1301                        if ((drvr->iflist[ifidx]) &&
1302                            (drvr->iflist[ifidx]->ndev)) {
1303                                ndev = drvr->iflist[ifidx]->ndev;
1304                                if (netif_queue_stopped(ndev))
1305                                        netif_wake_queue(ndev);
1306                        }
1307                }
1308        }
1309}
1310
1311static void brcmf_driver_register(struct work_struct *work)
1312{
1313#ifdef CONFIG_BRCMFMAC_SDIO
1314        brcmf_sdio_register();
1315#endif
1316#ifdef CONFIG_BRCMFMAC_USB
1317        brcmf_usb_register();
1318#endif
1319#ifdef CONFIG_BRCMFMAC_PCIE
1320        brcmf_pcie_register();
1321#endif
1322}
1323static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
1324
1325int __init brcmf_core_init(void)
1326{
1327        if (!schedule_work(&brcmf_driver_work))
1328                return -EBUSY;
1329
1330        return 0;
1331}
1332
1333void __exit brcmf_core_exit(void)
1334{
1335        cancel_work_sync(&brcmf_driver_work);
1336
1337#ifdef CONFIG_BRCMFMAC_SDIO
1338        brcmf_sdio_exit();
1339#endif
1340#ifdef CONFIG_BRCMFMAC_USB
1341        brcmf_usb_exit();
1342#endif
1343#ifdef CONFIG_BRCMFMAC_PCIE
1344        brcmf_pcie_exit();
1345#endif
1346}
1347
1348