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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/kthread.h> 22#include <linux/slab.h> 23#include <linux/skbuff.h> 24#include <linux/netdevice.h> 25#include <linux/etherdevice.h> 26#include <linux/mmc/sdio_func.h> 27#include <linux/random.h> 28#include <linux/spinlock.h> 29#include <linux/ethtool.h> 30#include <linux/fcntl.h> 31#include <linux/fs.h> 32#include <linux/uaccess.h> 33#include <linux/hardirq.h> 34#include <linux/mutex.h> 35#include <linux/wait.h> 36#include <linux/module.h> 37#include <net/cfg80211.h> 38#include <net/rtnetlink.h> 39#include <defs.h> 40#include <brcmu_utils.h> 41#include <brcmu_wifi.h> 42 43#include "dhd.h" 44#include "dhd_bus.h" 45#include "dhd_proto.h" 46#include "dhd_dbg.h" 47#include "wl_cfg80211.h" 48 49MODULE_AUTHOR("Broadcom Corporation"); 50MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); 51MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); 52MODULE_LICENSE("Dual BSD/GPL"); 53 54 55/* Interface control information */ 56struct brcmf_if { 57 struct brcmf_pub *drvr; /* back pointer to brcmf_pub */ 58 /* OS/stack specifics */ 59 struct net_device *ndev; 60 struct net_device_stats stats; 61 int idx; /* iface idx in dongle */ 62 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ 63}; 64 65/* Error bits */ 66int brcmf_msg_level = BRCMF_ERROR_VAL; 67module_param(brcmf_msg_level, int, 0); 68 69int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) 70{ 71 int i = BRCMF_MAX_IFS; 72 struct brcmf_if *ifp; 73 74 if (name == NULL || *name == '\0') 75 return 0; 76 77 while (--i > 0) { 78 ifp = drvr->iflist[i]; 79 if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) 80 break; 81 } 82 83 brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); 84 85 return i; /* default - the primary interface */ 86} 87 88char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 89{ 90 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { 91 brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx); 92 return "<if_bad>"; 93 } 94 95 if (drvr->iflist[ifidx] == NULL) { 96 brcmf_dbg(ERROR, "null i/f %d\n", ifidx); 97 return "<if_null>"; 98 } 99 100 if (drvr->iflist[ifidx]->ndev) 101 return drvr->iflist[ifidx]->ndev->name; 102 103 return "<if_none>"; 104} 105 106static void _brcmf_set_multicast_list(struct work_struct *work) 107{ 108 struct net_device *ndev; 109 struct netdev_hw_addr *ha; 110 u32 dcmd_value, cnt; 111 __le32 cnt_le; 112 __le32 dcmd_le_value; 113 114 struct brcmf_dcmd dcmd; 115 char *buf, *bufp; 116 uint buflen; 117 int ret; 118 119 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, 120 multicast_work); 121 122 ndev = drvr->iflist[0]->ndev; 123 cnt = netdev_mc_count(ndev); 124 125 /* Determine initial value of allmulti flag */ 126 dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; 127 128 /* Send down the multicast list first. */ 129 130 buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); 131 bufp = buf = kmalloc(buflen, GFP_ATOMIC); 132 if (!bufp) 133 return; 134 135 strcpy(bufp, "mcast_list"); 136 bufp += strlen("mcast_list") + 1; 137 138 cnt_le = cpu_to_le32(cnt); 139 memcpy(bufp, &cnt_le, sizeof(cnt)); 140 bufp += sizeof(cnt_le); 141 142 netdev_for_each_mc_addr(ha, ndev) { 143 if (!cnt) 144 break; 145 memcpy(bufp, ha->addr, ETH_ALEN); 146 bufp += ETH_ALEN; 147 cnt--; 148 } 149 150 memset(&dcmd, 0, sizeof(dcmd)); 151 dcmd.cmd = BRCMF_C_SET_VAR; 152 dcmd.buf = buf; 153 dcmd.len = buflen; 154 dcmd.set = true; 155 156 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); 157 if (ret < 0) { 158 brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", 159 brcmf_ifname(drvr, 0), cnt); 160 dcmd_value = cnt ? true : dcmd_value; 161 } 162 163 kfree(buf); 164 165 /* Now send the allmulti setting. This is based on the setting in the 166 * net_device flags, but might be modified above to be turned on if we 167 * were trying to set some addresses and dongle rejected it... 168 */ 169 170 buflen = sizeof("allmulti") + sizeof(dcmd_value); 171 buf = kmalloc(buflen, GFP_ATOMIC); 172 if (!buf) 173 return; 174 175 dcmd_le_value = cpu_to_le32(dcmd_value); 176 177 if (!brcmf_c_mkiovar 178 ("allmulti", (void *)&dcmd_le_value, 179 sizeof(dcmd_le_value), buf, buflen)) { 180 brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", 181 brcmf_ifname(drvr, 0), 182 (int)sizeof(dcmd_value), buflen); 183 kfree(buf); 184 return; 185 } 186 187 memset(&dcmd, 0, sizeof(dcmd)); 188 dcmd.cmd = BRCMF_C_SET_VAR; 189 dcmd.buf = buf; 190 dcmd.len = buflen; 191 dcmd.set = true; 192 193 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); 194 if (ret < 0) { 195 brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", 196 brcmf_ifname(drvr, 0), 197 le32_to_cpu(dcmd_le_value)); 198 } 199 200 kfree(buf); 201 202 /* Finally, pick up the PROMISC flag as well, like the NIC 203 driver does */ 204 205 dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false; 206 dcmd_le_value = cpu_to_le32(dcmd_value); 207 208 memset(&dcmd, 0, sizeof(dcmd)); 209 dcmd.cmd = BRCMF_C_SET_PROMISC; 210 dcmd.buf = &dcmd_le_value; 211 dcmd.len = sizeof(dcmd_le_value); 212 dcmd.set = true; 213 214 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); 215 if (ret < 0) { 216 brcmf_dbg(ERROR, "%s: set promisc %d failed\n", 217 brcmf_ifname(drvr, 0), 218 le32_to_cpu(dcmd_le_value)); 219 } 220} 221 222static void 223_brcmf_set_mac_address(struct work_struct *work) 224{ 225 char buf[32]; 226 struct brcmf_dcmd dcmd; 227 int ret; 228 229 struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, 230 setmacaddr_work); 231 232 brcmf_dbg(TRACE, "enter\n"); 233 if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, 234 ETH_ALEN, buf, 32)) { 235 brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", 236 brcmf_ifname(drvr, 0)); 237 return; 238 } 239 memset(&dcmd, 0, sizeof(dcmd)); 240 dcmd.cmd = BRCMF_C_SET_VAR; 241 dcmd.buf = buf; 242 dcmd.len = 32; 243 dcmd.set = true; 244 245 ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); 246 if (ret < 0) 247 brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", 248 brcmf_ifname(drvr, 0)); 249 else 250 memcpy(drvr->iflist[0]->ndev->dev_addr, 251 drvr->macvalue, ETH_ALEN); 252 253 return; 254} 255 256static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 257{ 258 struct brcmf_if *ifp = netdev_priv(ndev); 259 struct brcmf_pub *drvr = ifp->drvr; 260 struct sockaddr *sa = (struct sockaddr *)addr; 261 262 memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); 263 schedule_work(&drvr->setmacaddr_work); 264 return 0; 265} 266 267static void brcmf_netdev_set_multicast_list(struct net_device *ndev) 268{ 269 struct brcmf_if *ifp = netdev_priv(ndev); 270 struct brcmf_pub *drvr = ifp->drvr; 271 272 schedule_work(&drvr->multicast_work); 273} 274 275int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) 276{ 277 /* Reject if down */ 278 if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN)) 279 return -ENODEV; 280 281 /* Update multicast statistic */ 282 if (pktbuf->len >= ETH_ALEN) { 283 u8 *pktdata = (u8 *) (pktbuf->data); 284 struct ethhdr *eh = (struct ethhdr *)pktdata; 285 286 if (is_multicast_ether_addr(eh->h_dest)) 287 drvr->tx_multicast++; 288 if (ntohs(eh->h_proto) == ETH_P_PAE) 289 atomic_inc(&drvr->pend_8021x_cnt); 290 } 291 292 /* If the protocol uses a data header, apply it */ 293 brcmf_proto_hdrpush(drvr, ifidx, pktbuf); 294 295 /* Use bus module to send data frame */ 296 return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf); 297} 298 299static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 300{ 301 int ret; 302 struct brcmf_if *ifp = netdev_priv(ndev); 303 struct brcmf_pub *drvr = ifp->drvr; 304 305 brcmf_dbg(TRACE, "Enter\n"); 306 307 /* Reject if down */ 308 if (!drvr->bus_if->drvr_up || 309 (drvr->bus_if->state == BRCMF_BUS_DOWN)) { 310 brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", 311 drvr->bus_if->drvr_up, 312 drvr->bus_if->state); 313 netif_stop_queue(ndev); 314 return -ENODEV; 315 } 316 317 if (!drvr->iflist[ifp->idx]) { 318 brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); 319 netif_stop_queue(ndev); 320 return -ENODEV; 321 } 322 323 /* Make sure there's enough room for any header */ 324 if (skb_headroom(skb) < drvr->hdrlen) { 325 struct sk_buff *skb2; 326 327 brcmf_dbg(INFO, "%s: insufficient headroom\n", 328 brcmf_ifname(drvr, ifp->idx)); 329 drvr->bus_if->tx_realloc++; 330 skb2 = skb_realloc_headroom(skb, drvr->hdrlen); 331 dev_kfree_skb(skb); 332 skb = skb2; 333 if (skb == NULL) { 334 brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", 335 brcmf_ifname(drvr, ifp->idx)); 336 ret = -ENOMEM; 337 goto done; 338 } 339 } 340 341 ret = brcmf_sendpkt(drvr, ifp->idx, skb); 342 343done: 344 if (ret) 345 drvr->bus_if->dstats.tx_dropped++; 346 else 347 drvr->bus_if->dstats.tx_packets++; 348 349 /* Return ok: we always eat the packet */ 350 return 0; 351} 352 353void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state) 354{ 355 struct net_device *ndev; 356 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 357 struct brcmf_pub *drvr = bus_if->drvr; 358 359 brcmf_dbg(TRACE, "Enter\n"); 360 361 ndev = drvr->iflist[ifidx]->ndev; 362 if (state == ON) 363 netif_stop_queue(ndev); 364 else 365 netif_wake_queue(ndev); 366} 367 368static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, 369 void *pktdata, struct brcmf_event_msg *event, 370 void **data) 371{ 372 int bcmerror = 0; 373 374 bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); 375 if (bcmerror != 0) 376 return bcmerror; 377 378 if (drvr->iflist[*ifidx]->ndev) 379 brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, 380 event, *data); 381 382 return bcmerror; 383} 384 385void brcmf_rx_frame(struct device *dev, int ifidx, 386 struct sk_buff_head *skb_list) 387{ 388 unsigned char *eth; 389 uint len; 390 void *data; 391 struct sk_buff *skb, *pnext; 392 struct brcmf_if *ifp; 393 struct brcmf_event_msg event; 394 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 395 struct brcmf_pub *drvr = bus_if->drvr; 396 397 brcmf_dbg(TRACE, "Enter\n"); 398 399 skb_queue_walk_safe(skb_list, skb, pnext) { 400 skb_unlink(skb, skb_list); 401 402 /* Get the protocol, maintain skb around eth_type_trans() 403 * The main reason for this hack is for the limitation of 404 * Linux 2.4 where 'eth_type_trans' uses the 405 * 'net->hard_header_len' 406 * to perform skb_pull inside vs ETH_HLEN. Since to avoid 407 * coping of the packet coming from the network stack to add 408 * BDC, Hardware header etc, during network interface 409 * registration 410 * we set the 'net->hard_header_len' to ETH_HLEN + extra space 411 * required 412 * for BDC, Hardware header etc. and not just the ETH_HLEN 413 */ 414 eth = skb->data; 415 len = skb->len; 416 417 ifp = drvr->iflist[ifidx]; 418 if (ifp == NULL) 419 ifp = drvr->iflist[0]; 420 421 if (!ifp || !ifp->ndev || 422 ifp->ndev->reg_state != NETREG_REGISTERED) { 423 brcmu_pkt_buf_free_skb(skb); 424 continue; 425 } 426 427 skb->dev = ifp->ndev; 428 skb->protocol = eth_type_trans(skb, skb->dev); 429 430 if (skb->pkt_type == PACKET_MULTICAST) 431 bus_if->dstats.multicast++; 432 433 skb->data = eth; 434 skb->len = len; 435 436 /* Strip header, count, deliver upward */ 437 skb_pull(skb, ETH_HLEN); 438 439 /* Process special event packets and then discard them */ 440 if (ntohs(skb->protocol) == ETH_P_LINK_CTL) 441 brcmf_host_event(drvr, &ifidx, 442 skb_mac_header(skb), 443 &event, &data); 444 445 if (drvr->iflist[ifidx]) { 446 ifp = drvr->iflist[ifidx]; 447 ifp->ndev->last_rx = jiffies; 448 } 449 450 bus_if->dstats.rx_bytes += skb->len; 451 bus_if->dstats.rx_packets++; /* Local count */ 452 453 if (in_interrupt()) 454 netif_rx(skb); 455 else 456 /* If the receive is not processed inside an ISR, 457 * the softirqd must be woken explicitly to service 458 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled 459 * by netif_rx_ni(), but in earlier kernels, we need 460 * to do it manually. 461 */ 462 netif_rx_ni(skb); 463 } 464} 465 466void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) 467{ 468 uint ifidx; 469 struct ethhdr *eh; 470 u16 type; 471 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 472 struct brcmf_pub *drvr = bus_if->drvr; 473 474 brcmf_proto_hdrpull(dev, &ifidx, txp); 475 476 eh = (struct ethhdr *)(txp->data); 477 type = ntohs(eh->h_proto); 478 479 if (type == ETH_P_PAE) 480 atomic_dec(&drvr->pend_8021x_cnt); 481 482} 483 484static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 485{ 486 struct brcmf_if *ifp = netdev_priv(ndev); 487 struct brcmf_bus *bus_if = ifp->drvr->bus_if; 488 489 brcmf_dbg(TRACE, "Enter\n"); 490 491 /* Copy dongle stats to net device stats */ 492 ifp->stats.rx_packets = bus_if->dstats.rx_packets; 493 ifp->stats.tx_packets = bus_if->dstats.tx_packets; 494 ifp->stats.rx_bytes = bus_if->dstats.rx_bytes; 495 ifp->stats.tx_bytes = bus_if->dstats.tx_bytes; 496 ifp->stats.rx_errors = bus_if->dstats.rx_errors; 497 ifp->stats.tx_errors = bus_if->dstats.tx_errors; 498 ifp->stats.rx_dropped = bus_if->dstats.rx_dropped; 499 ifp->stats.tx_dropped = bus_if->dstats.tx_dropped; 500 ifp->stats.multicast = bus_if->dstats.multicast; 501 502 return &ifp->stats; 503} 504 505/* Retrieve current toe component enables, which are kept 506 as a bitmap in toe_ol iovar */ 507static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) 508{ 509 struct brcmf_dcmd dcmd; 510 __le32 toe_le; 511 char buf[32]; 512 int ret; 513 514 memset(&dcmd, 0, sizeof(dcmd)); 515 516 dcmd.cmd = BRCMF_C_GET_VAR; 517 dcmd.buf = buf; 518 dcmd.len = (uint) sizeof(buf); 519 dcmd.set = false; 520 521 strcpy(buf, "toe_ol"); 522 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); 523 if (ret < 0) { 524 /* Check for older dongle image that doesn't support toe_ol */ 525 if (ret == -EIO) { 526 brcmf_dbg(ERROR, "%s: toe not supported by device\n", 527 brcmf_ifname(drvr, ifidx)); 528 return -EOPNOTSUPP; 529 } 530 531 brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", 532 brcmf_ifname(drvr, ifidx), ret); 533 return ret; 534 } 535 536 memcpy(&toe_le, buf, sizeof(u32)); 537 *toe_ol = le32_to_cpu(toe_le); 538 return 0; 539} 540 541/* Set current toe component enables in toe_ol iovar, 542 and set toe global enable iovar */ 543static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) 544{ 545 struct brcmf_dcmd dcmd; 546 char buf[32]; 547 int ret; 548 __le32 toe_le = cpu_to_le32(toe_ol); 549 550 memset(&dcmd, 0, sizeof(dcmd)); 551 552 dcmd.cmd = BRCMF_C_SET_VAR; 553 dcmd.buf = buf; 554 dcmd.len = (uint) sizeof(buf); 555 dcmd.set = true; 556 557 /* Set toe_ol as requested */ 558 strcpy(buf, "toe_ol"); 559 memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); 560 561 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); 562 if (ret < 0) { 563 brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", 564 brcmf_ifname(drvr, ifidx), ret); 565 return ret; 566 } 567 568 /* Enable toe globally only if any components are enabled. */ 569 toe_le = cpu_to_le32(toe_ol != 0); 570 571 strcpy(buf, "toe"); 572 memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); 573 574 ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); 575 if (ret < 0) { 576 brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", 577 brcmf_ifname(drvr, ifidx), ret); 578 return ret; 579 } 580 581 return 0; 582} 583 584static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 585 struct ethtool_drvinfo *info) 586{ 587 struct brcmf_if *ifp = netdev_priv(ndev); 588 struct brcmf_pub *drvr = ifp->drvr; 589 590 sprintf(info->driver, KBUILD_MODNAME); 591 sprintf(info->version, "%lu", drvr->drv_version); 592 sprintf(info->bus_info, "%s", dev_name(drvr->dev)); 593} 594 595static const struct ethtool_ops brcmf_ethtool_ops = { 596 .get_drvinfo = brcmf_ethtool_get_drvinfo, 597}; 598 599static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) 600{ 601 struct ethtool_drvinfo info; 602 char drvname[sizeof(info.driver)]; 603 u32 cmd; 604 struct ethtool_value edata; 605 u32 toe_cmpnt, csum_dir; 606 int ret; 607 608 brcmf_dbg(TRACE, "Enter\n"); 609 610 /* all ethtool calls start with a cmd word */ 611 if (copy_from_user(&cmd, uaddr, sizeof(u32))) 612 return -EFAULT; 613 614 switch (cmd) { 615 case ETHTOOL_GDRVINFO: 616 /* Copy out any request driver name */ 617 if (copy_from_user(&info, uaddr, sizeof(info))) 618 return -EFAULT; 619 strncpy(drvname, info.driver, sizeof(info.driver)); 620 drvname[sizeof(info.driver) - 1] = '\0'; 621 622 /* clear struct for return */ 623 memset(&info, 0, sizeof(info)); 624 info.cmd = cmd; 625 626 /* if requested, identify ourselves */ 627 if (strcmp(drvname, "?dhd") == 0) { 628 sprintf(info.driver, "dhd"); 629 strcpy(info.version, BRCMF_VERSION_STR); 630 } 631 632 /* otherwise, require dongle to be up */ 633 else if (!drvr->bus_if->drvr_up) { 634 brcmf_dbg(ERROR, "dongle is not up\n"); 635 return -ENODEV; 636 } 637 638 /* finally, report dongle driver type */ 639 else if (drvr->iswl) 640 sprintf(info.driver, "wl"); 641 else 642 sprintf(info.driver, "xx"); 643 644 sprintf(info.version, "%lu", drvr->drv_version); 645 if (copy_to_user(uaddr, &info, sizeof(info))) 646 return -EFAULT; 647 brcmf_dbg(CTL, "given %*s, returning %s\n", 648 (int)sizeof(drvname), drvname, info.driver); 649 break; 650 651 /* Get toe offload components from dongle */ 652 case ETHTOOL_GRXCSUM: 653 case ETHTOOL_GTXCSUM: 654 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); 655 if (ret < 0) 656 return ret; 657 658 csum_dir = 659 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; 660 661 edata.cmd = cmd; 662 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; 663 664 if (copy_to_user(uaddr, &edata, sizeof(edata))) 665 return -EFAULT; 666 break; 667 668 /* Set toe offload components in dongle */ 669 case ETHTOOL_SRXCSUM: 670 case ETHTOOL_STXCSUM: 671 if (copy_from_user(&edata, uaddr, sizeof(edata))) 672 return -EFAULT; 673 674 /* Read the current settings, update and write back */ 675 ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); 676 if (ret < 0) 677 return ret; 678 679 csum_dir = 680 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; 681 682 if (edata.data != 0) 683 toe_cmpnt |= csum_dir; 684 else 685 toe_cmpnt &= ~csum_dir; 686 687 ret = brcmf_toe_set(drvr, 0, toe_cmpnt); 688 if (ret < 0) 689 return ret; 690 691 /* If setting TX checksum mode, tell Linux the new mode */ 692 if (cmd == ETHTOOL_STXCSUM) { 693 if (edata.data) 694 drvr->iflist[0]->ndev->features |= 695 NETIF_F_IP_CSUM; 696 else 697 drvr->iflist[0]->ndev->features &= 698 ~NETIF_F_IP_CSUM; 699 } 700 701 break; 702 703 default: 704 return -EOPNOTSUPP; 705 } 706 707 return 0; 708} 709 710static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, 711 int cmd) 712{ 713 struct brcmf_if *ifp = netdev_priv(ndev); 714 struct brcmf_pub *drvr = ifp->drvr; 715 716 brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); 717 718 if (!drvr->iflist[ifp->idx]) 719 return -1; 720 721 if (cmd == SIOCETHTOOL) 722 return brcmf_ethtool(drvr, ifr->ifr_data); 723 724 return -EOPNOTSUPP; 725} 726 727/* called only from within this driver. Sends a command to the dongle. */ 728s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) 729{ 730 struct brcmf_dcmd dcmd; 731 s32 err = 0; 732 int buflen = 0; 733 bool is_set_key_cmd; 734 struct brcmf_if *ifp = netdev_priv(ndev); 735 struct brcmf_pub *drvr = ifp->drvr; 736 737 memset(&dcmd, 0, sizeof(dcmd)); 738 dcmd.cmd = cmd; 739 dcmd.buf = arg; 740 dcmd.len = len; 741 742 if (dcmd.buf != NULL) 743 buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); 744 745 /* send to dongle (must be up, and wl) */ 746 if ((drvr->bus_if->state != BRCMF_BUS_DATA)) { 747 brcmf_dbg(ERROR, "DONGLE_DOWN\n"); 748 err = -EIO; 749 goto done; 750 } 751 752 if (!drvr->iswl) { 753 err = -EIO; 754 goto done; 755 } 756 757 /* 758 * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and 759 * set key CMD to prevent M4 encryption. 760 */ 761 is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) || 762 ((dcmd.cmd == BRCMF_C_SET_VAR) && 763 !(strncmp("wsec_key", dcmd.buf, 9))) || 764 ((dcmd.cmd == BRCMF_C_SET_VAR) && 765 !(strncmp("bsscfg:wsec_key", dcmd.buf, 15)))); 766 if (is_set_key_cmd) 767 brcmf_netdev_wait_pend8021x(ndev); 768 769 err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen); 770 771done: 772 if (err > 0) 773 err = 0; 774 775 return err; 776} 777 778static int brcmf_netdev_stop(struct net_device *ndev) 779{ 780 struct brcmf_if *ifp = netdev_priv(ndev); 781 struct brcmf_pub *drvr = ifp->drvr; 782 783 brcmf_dbg(TRACE, "Enter\n"); 784 brcmf_cfg80211_down(drvr->config); 785 if (drvr->bus_if->drvr_up == 0) 786 return 0; 787 788 /* Set state and stop OS transmissions */ 789 drvr->bus_if->drvr_up = false; 790 netif_stop_queue(ndev); 791 792 return 0; 793} 794 795static int brcmf_netdev_open(struct net_device *ndev) 796{ 797 struct brcmf_if *ifp = netdev_priv(ndev); 798 struct brcmf_pub *drvr = ifp->drvr; 799 struct brcmf_bus *bus_if = drvr->bus_if; 800 u32 toe_ol; 801 s32 ret = 0; 802 803 brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); 804 805 if (ifp->idx == 0) { /* do it only for primary eth0 */ 806 /* If bus is not ready, can't continue */ 807 if (bus_if->state != BRCMF_BUS_DATA) { 808 brcmf_dbg(ERROR, "failed bus is not ready\n"); 809 return -EAGAIN; 810 } 811 812 atomic_set(&drvr->pend_8021x_cnt, 0); 813 814 memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); 815 816 /* Get current TOE mode from dongle */ 817 if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 818 && (toe_ol & TOE_TX_CSUM_OL) != 0) 819 drvr->iflist[ifp->idx]->ndev->features |= 820 NETIF_F_IP_CSUM; 821 else 822 drvr->iflist[ifp->idx]->ndev->features &= 823 ~NETIF_F_IP_CSUM; 824 } 825 /* Allow transmit calls */ 826 netif_start_queue(ndev); 827 drvr->bus_if->drvr_up = true; 828 if (brcmf_cfg80211_up(drvr->config)) { 829 brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); 830 return -1; 831 } 832 833 return ret; 834} 835 836static const struct net_device_ops brcmf_netdev_ops_pri = { 837 .ndo_open = brcmf_netdev_open, 838 .ndo_stop = brcmf_netdev_stop, 839 .ndo_get_stats = brcmf_netdev_get_stats, 840 .ndo_do_ioctl = brcmf_netdev_ioctl_entry, 841 .ndo_start_xmit = brcmf_netdev_start_xmit, 842 .ndo_set_mac_address = brcmf_netdev_set_mac_address, 843 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 844}; 845 846int 847brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) 848{ 849 struct brcmf_if *ifp; 850 struct net_device *ndev; 851 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 852 struct brcmf_pub *drvr = bus_if->drvr; 853 854 brcmf_dbg(TRACE, "idx %d\n", ifidx); 855 856 ifp = drvr->iflist[ifidx]; 857 /* 858 * Delete the existing interface before overwriting it 859 * in case we missed the BRCMF_E_IF_DEL event. 860 */ 861 if (ifp) { 862 brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", 863 ifp->ndev->name); 864 netif_stop_queue(ifp->ndev); 865 unregister_netdev(ifp->ndev); 866 free_netdev(ifp->ndev); 867 drvr->iflist[ifidx] = NULL; 868 } 869 870 /* Allocate netdev, including space for private structure */ 871 ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); 872 if (!ndev) { 873 brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); 874 return -ENOMEM; 875 } 876 877 ifp = netdev_priv(ndev); 878 ifp->ndev = ndev; 879 ifp->drvr = drvr; 880 drvr->iflist[ifidx] = ifp; 881 ifp->idx = ifidx; 882 if (mac_addr != NULL) 883 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); 884 885 if (brcmf_net_attach(drvr, ifp->idx)) { 886 brcmf_dbg(ERROR, "brcmf_net_attach failed"); 887 free_netdev(ifp->ndev); 888 drvr->iflist[ifidx] = NULL; 889 return -EOPNOTSUPP; 890 } 891 892 brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", 893 current->pid, ifp->ndev->name); 894 895 return 0; 896} 897 898void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) 899{ 900 struct brcmf_if *ifp; 901 902 brcmf_dbg(TRACE, "idx %d\n", ifidx); 903 904 ifp = drvr->iflist[ifidx]; 905 if (!ifp) { 906 brcmf_dbg(ERROR, "Null interface\n"); 907 return; 908 } 909 if (ifp->ndev) { 910 if (ifidx == 0) { 911 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { 912 rtnl_lock(); 913 brcmf_netdev_stop(ifp->ndev); 914 rtnl_unlock(); 915 } 916 } else { 917 netif_stop_queue(ifp->ndev); 918 } 919 920 unregister_netdev(ifp->ndev); 921 drvr->iflist[ifidx] = NULL; 922 if (ifidx == 0) 923 brcmf_cfg80211_detach(drvr->config); 924 free_netdev(ifp->ndev); 925 } 926} 927 928int brcmf_attach(uint bus_hdrlen, struct device *dev) 929{ 930 struct brcmf_pub *drvr = NULL; 931 int ret = 0; 932 933 brcmf_dbg(TRACE, "Enter\n"); 934 935 /* Allocate primary brcmf_info */ 936 drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC); 937 if (!drvr) 938 return -ENOMEM; 939 940 mutex_init(&drvr->proto_block); 941 942 /* Link to bus module */ 943 drvr->hdrlen = bus_hdrlen; 944 drvr->bus_if = dev_get_drvdata(dev); 945 drvr->bus_if->drvr = drvr; 946 drvr->dev = dev; 947 948 /* Attach and link in the protocol */ 949 ret = brcmf_proto_attach(drvr); 950 if (ret != 0) { 951 brcmf_dbg(ERROR, "brcmf_prot_attach failed\n"); 952 goto fail; 953 } 954 955 INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); 956 INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); 957 958 return ret; 959 960fail: 961 brcmf_detach(dev); 962 963 return ret; 964} 965 966int brcmf_bus_start(struct device *dev) 967{ 968 int ret = -1; 969 /* Room for "event_msgs" + '\0' + bitvec */ 970 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; 971 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 972 struct brcmf_pub *drvr = bus_if->drvr; 973 974 brcmf_dbg(TRACE, "\n"); 975 976 /* Bring up the bus */ 977 ret = bus_if->brcmf_bus_init(dev); 978 if (ret != 0) { 979 brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret); 980 return ret; 981 } 982 983 brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, 984 iovbuf, sizeof(iovbuf)); 985 brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf, 986 sizeof(iovbuf)); 987 memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); 988 989 setbit(drvr->eventmask, BRCMF_E_SET_SSID); 990 setbit(drvr->eventmask, BRCMF_E_PRUNE); 991 setbit(drvr->eventmask, BRCMF_E_AUTH); 992 setbit(drvr->eventmask, BRCMF_E_REASSOC); 993 setbit(drvr->eventmask, BRCMF_E_REASSOC_IND); 994 setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND); 995 setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND); 996 setbit(drvr->eventmask, BRCMF_E_DISASSOC); 997 setbit(drvr->eventmask, BRCMF_E_JOIN); 998 setbit(drvr->eventmask, BRCMF_E_ASSOC_IND); 999 setbit(drvr->eventmask, BRCMF_E_PSK_SUP); 1000 setbit(drvr->eventmask, BRCMF_E_LINK); 1001 setbit(drvr->eventmask, BRCMF_E_NDIS_LINK); 1002 setbit(drvr->eventmask, BRCMF_E_MIC_ERROR); 1003 setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE); 1004 setbit(drvr->eventmask, BRCMF_E_TXFAIL); 1005 setbit(drvr->eventmask, BRCMF_E_JOIN_START); 1006 setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE); 1007 1008/* enable dongle roaming event */ 1009 1010 drvr->pktfilter_count = 1; 1011 /* Setup filter to allow only unicast */ 1012 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; 1013 1014 /* Bus is ready, do any protocol initialization */ 1015 ret = brcmf_proto_init(drvr); 1016 if (ret < 0) 1017 return ret; 1018 1019 /* signal bus ready */ 1020 bus_if->state = BRCMF_BUS_DATA; 1021 return 0; 1022} 1023 1024int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) 1025{ 1026 struct net_device *ndev; 1027 u8 temp_addr[ETH_ALEN] = { 1028 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; 1029 1030 brcmf_dbg(TRACE, "ifidx %d\n", ifidx); 1031 1032 ndev = drvr->iflist[ifidx]->ndev; 1033 ndev->netdev_ops = &brcmf_netdev_ops_pri; 1034 1035 /* 1036 * We have to use the primary MAC for virtual interfaces 1037 */ 1038 if (ifidx != 0) { 1039 /* for virtual interfaces use the primary MAC */ 1040 memcpy(temp_addr, drvr->mac, ETH_ALEN); 1041 1042 } 1043 1044 if (ifidx == 1) { 1045 brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); 1046 /* ACCESSPOINT INTERFACE CASE */ 1047 temp_addr[0] |= 0X02; /* set bit 2 , 1048 - Locally Administered address */ 1049 1050 } 1051 ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; 1052 ndev->ethtool_ops = &brcmf_ethtool_ops; 1053 1054 drvr->rxsz = ndev->mtu + ndev->hard_header_len + 1055 drvr->hdrlen; 1056 1057 memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); 1058 1059 /* attach to cfg80211 for primary interface */ 1060 if (!ifidx) { 1061 drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr); 1062 if (drvr->config == NULL) { 1063 brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); 1064 goto fail; 1065 } 1066 } 1067 1068 if (register_netdev(ndev) != 0) { 1069 brcmf_dbg(ERROR, "couldn't register the net device\n"); 1070 goto fail; 1071 } 1072 1073 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); 1074 1075 return 0; 1076 1077fail: 1078 ndev->netdev_ops = NULL; 1079 return -EBADE; 1080} 1081 1082static void brcmf_bus_detach(struct brcmf_pub *drvr) 1083{ 1084 brcmf_dbg(TRACE, "Enter\n"); 1085 1086 if (drvr) { 1087 /* Stop the protocol module */ 1088 brcmf_proto_stop(drvr); 1089 1090 /* Stop the bus module */ 1091 drvr->bus_if->brcmf_bus_stop(drvr->dev); 1092 } 1093} 1094 1095void brcmf_detach(struct device *dev) 1096{ 1097 int i; 1098 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1099 struct brcmf_pub *drvr = bus_if->drvr; 1100 1101 brcmf_dbg(TRACE, "Enter\n"); 1102 1103 1104 /* make sure primary interface removed last */ 1105 for (i = BRCMF_MAX_IFS-1; i > -1; i--) 1106 if (drvr->iflist[i]) 1107 brcmf_del_if(drvr, i); 1108 1109 brcmf_bus_detach(drvr); 1110 1111 if (drvr->prot) { 1112 cancel_work_sync(&drvr->setmacaddr_work); 1113 cancel_work_sync(&drvr->multicast_work); 1114 brcmf_proto_detach(drvr); 1115 } 1116 1117 bus_if->drvr = NULL; 1118 kfree(drvr); 1119} 1120 1121static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) 1122{ 1123 return atomic_read(&drvr->pend_8021x_cnt); 1124} 1125 1126#define MAX_WAIT_FOR_8021X_TX 10 1127 1128int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 1129{ 1130 struct brcmf_if *ifp = netdev_priv(ndev); 1131 struct brcmf_pub *drvr = ifp->drvr; 1132 int timeout = 10 * HZ / 1000; 1133 int ntimes = MAX_WAIT_FOR_8021X_TX; 1134 int pend = brcmf_get_pend_8021x_cnt(drvr); 1135 1136 while (ntimes && pend) { 1137 if (pend) { 1138 set_current_state(TASK_INTERRUPTIBLE); 1139 schedule_timeout(timeout); 1140 set_current_state(TASK_RUNNING); 1141 ntimes--; 1142 } 1143 pend = brcmf_get_pend_8021x_cnt(drvr); 1144 } 1145 return pend; 1146} 1147 1148#ifdef DEBUG 1149int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) 1150{ 1151 int ret = 0; 1152 struct file *fp; 1153 mm_segment_t old_fs; 1154 loff_t pos = 0; 1155 1156 /* change to KERNEL_DS address limit */ 1157 old_fs = get_fs(); 1158 set_fs(KERNEL_DS); 1159 1160 /* open file to write */ 1161 fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); 1162 if (!fp) { 1163 brcmf_dbg(ERROR, "open file error\n"); 1164 ret = -1; 1165 goto exit; 1166 } 1167 1168 /* Write buf to file */ 1169 fp->f_op->write(fp, (char __user *)buf, size, &pos); 1170 1171exit: 1172 /* free buf before return */ 1173 kfree(buf); 1174 /* close file before return */ 1175 if (fp) 1176 filp_close(fp, current->files); 1177 /* restore previous address limit */ 1178 set_fs(old_fs); 1179 1180 return ret; 1181} 1182#endif /* DEBUG */ 1183 1184static void brcmf_driver_init(struct work_struct *work) 1185{ 1186#ifdef CONFIG_BRCMFMAC_SDIO 1187 brcmf_sdio_init(); 1188#endif 1189#ifdef CONFIG_BRCMFMAC_USB 1190 brcmf_usb_init(); 1191#endif 1192} 1193static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); 1194 1195static int __init brcmfmac_module_init(void) 1196{ 1197 if (!schedule_work(&brcmf_driver_work)) 1198 return -EBUSY; 1199 1200 return 0; 1201} 1202 1203static void __exit brcmfmac_module_exit(void) 1204{ 1205 cancel_work_sync(&brcmf_driver_work); 1206 1207#ifdef CONFIG_BRCMFMAC_SDIO 1208 brcmf_sdio_exit(); 1209#endif 1210#ifdef CONFIG_BRCMFMAC_USB 1211 brcmf_usb_exit(); 1212#endif 1213} 1214 1215module_init(brcmfmac_module_init); 1216module_exit(brcmfmac_module_exit); 1217