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