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 46 char *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 57 struct 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 75 void 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 112 static 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) 179 static 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 202 static void _brcmf_update_ndtable(struct work_struct *work) 203 { 204 } 205 #endif 206 207 static 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 227 static 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 */ 239 static 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 265 static 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 339 done: 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 351 void 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 375 void 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 408 void 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 432 static 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 451 void 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 473 void 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 488 void 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 508 static 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 524 static const struct ethtool_ops brcmf_ethtool_ops = { 525 .get_drvinfo = brcmf_ethtool_get_drvinfo, 526 }; 527 528 static 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 543 static 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 577 static 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 585 int 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 621 fail: 622 drvr->iflist[ifp->bsscfgidx] = NULL; 623 ndev->netdev_ops = NULL; 624 return -EBADE; 625 } 626 627 static 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 640 void 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 659 static 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 666 static 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 673 static 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 682 static 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 688 static 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 710 fail: 711 ifp->drvr->iflist[ifp->bsscfgidx] = NULL; 712 ndev->netdev_ops = NULL; 713 return -EBADE; 714 } 715 716 struct 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 782 static 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 826 void 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 836 static 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 856 static 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) 947 static 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 999 static 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 1028 static 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 1106 fail: 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 1123 int 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(settings); 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 1179 fail: 1180 brcmf_detach(dev); 1181 kfree(ops); 1182 1183 return ret; 1184 } 1185 1186 void 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 1196 void 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 1208 void 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 1216 void 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 1257 s32 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 1265 static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp) 1266 { 1267 return atomic_read(&ifp->pend_8021x_cnt); 1268 } 1269 1270 int 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 1284 void 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 1311 static 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 } 1323 static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); 1324 1325 int __init brcmf_core_init(void) 1326 { 1327 if (!schedule_work(&brcmf_driver_work)) 1328 return -EBUSY; 1329 1330 return 0; 1331 } 1332 1333 void __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