| .. | .. |
|---|
| 1 | | -/* Copyright (c) 2014 Broadcom Corporation |
|---|
| 2 | | - * |
|---|
| 3 | | - * Permission to use, copy, modify, and/or distribute this software for any |
|---|
| 4 | | - * purpose with or without fee is hereby granted, provided that the above |
|---|
| 5 | | - * copyright notice and this permission notice appear in all copies. |
|---|
| 6 | | - * |
|---|
| 7 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|---|
| 8 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|---|
| 9 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|---|
| 10 | | - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|---|
| 11 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|---|
| 12 | | - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|---|
| 13 | | - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|---|
| 1 | +// SPDX-License-Identifier: ISC |
|---|
| 2 | +/* |
|---|
| 3 | + * Copyright (c) 2014 Broadcom Corporation |
|---|
| 14 | 4 | */ |
|---|
| 15 | 5 | |
|---|
| 16 | 6 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 22 | 12 | #include <linux/interrupt.h> |
|---|
| 23 | 13 | #include <linux/bcma/bcma.h> |
|---|
| 24 | 14 | #include <linux/sched.h> |
|---|
| 15 | +#include <linux/io.h> |
|---|
| 25 | 16 | #include <asm/unaligned.h> |
|---|
| 26 | 17 | |
|---|
| 27 | 18 | #include <soc.h> |
|---|
| .. | .. |
|---|
| 29 | 20 | #include <brcmu_utils.h> |
|---|
| 30 | 21 | #include <brcmu_wifi.h> |
|---|
| 31 | 22 | #include <brcm_hw_ids.h> |
|---|
| 23 | + |
|---|
| 24 | +/* Custom brcmf_err() that takes bus arg and passes it further */ |
|---|
| 25 | +#define brcmf_err(bus, fmt, ...) \ |
|---|
| 26 | + do { \ |
|---|
| 27 | + if (IS_ENABLED(CONFIG_BRCMDBG) || \ |
|---|
| 28 | + IS_ENABLED(CONFIG_BRCM_TRACING) || \ |
|---|
| 29 | + net_ratelimit()) \ |
|---|
| 30 | + __brcmf_err(bus, __func__, fmt, ##__VA_ARGS__); \ |
|---|
| 31 | + } while (0) |
|---|
| 32 | 32 | |
|---|
| 33 | 33 | #include "debug.h" |
|---|
| 34 | 34 | #include "bus.h" |
|---|
| .. | .. |
|---|
| 53 | 53 | BRCMF_FW_DEF(43570, "brcmfmac43570-pcie"); |
|---|
| 54 | 54 | BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); |
|---|
| 55 | 55 | BRCMF_FW_DEF(4359, "brcmfmac4359-pcie"); |
|---|
| 56 | +BRCMF_FW_DEF(4364, "brcmfmac4364-pcie"); |
|---|
| 56 | 57 | BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie"); |
|---|
| 57 | 58 | BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); |
|---|
| 58 | 59 | BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); |
|---|
| .. | .. |
|---|
| 71 | 72 | BRCMF_FW_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), |
|---|
| 72 | 73 | BRCMF_FW_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), |
|---|
| 73 | 74 | BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), |
|---|
| 75 | + BRCMF_FW_ENTRY(BRCM_CC_4364_CHIP_ID, 0xFFFFFFFF, 4364), |
|---|
| 74 | 76 | BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), |
|---|
| 75 | 77 | BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), |
|---|
| 76 | 78 | BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), |
|---|
| .. | .. |
|---|
| 79 | 81 | BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), |
|---|
| 80 | 82 | }; |
|---|
| 81 | 83 | |
|---|
| 82 | | -#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ |
|---|
| 84 | +#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ |
|---|
| 83 | 85 | |
|---|
| 84 | 86 | #define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) |
|---|
| 85 | 87 | |
|---|
| .. | .. |
|---|
| 336 | 338 | BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE |
|---|
| 337 | 339 | }; |
|---|
| 338 | 340 | |
|---|
| 341 | +static void brcmf_pcie_setup(struct device *dev, int ret, |
|---|
| 342 | + struct brcmf_fw_request *fwreq); |
|---|
| 343 | +static struct brcmf_fw_request * |
|---|
| 344 | +brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo); |
|---|
| 339 | 345 | |
|---|
| 340 | 346 | static u32 |
|---|
| 341 | 347 | brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) |
|---|
| .. | .. |
|---|
| 442 | 448 | |
|---|
| 443 | 449 | |
|---|
| 444 | 450 | static void |
|---|
| 445 | | -brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset, |
|---|
| 446 | | - void *srcaddr, u32 len) |
|---|
| 447 | | -{ |
|---|
| 448 | | - void __iomem *address = devinfo->tcm + mem_offset; |
|---|
| 449 | | - __le32 *src32; |
|---|
| 450 | | - __le16 *src16; |
|---|
| 451 | | - u8 *src8; |
|---|
| 452 | | - |
|---|
| 453 | | - if (((ulong)address & 4) || ((ulong)srcaddr & 4) || (len & 4)) { |
|---|
| 454 | | - if (((ulong)address & 2) || ((ulong)srcaddr & 2) || (len & 2)) { |
|---|
| 455 | | - src8 = (u8 *)srcaddr; |
|---|
| 456 | | - while (len) { |
|---|
| 457 | | - iowrite8(*src8, address); |
|---|
| 458 | | - address++; |
|---|
| 459 | | - src8++; |
|---|
| 460 | | - len--; |
|---|
| 461 | | - } |
|---|
| 462 | | - } else { |
|---|
| 463 | | - len = len / 2; |
|---|
| 464 | | - src16 = (__le16 *)srcaddr; |
|---|
| 465 | | - while (len) { |
|---|
| 466 | | - iowrite16(le16_to_cpu(*src16), address); |
|---|
| 467 | | - address += 2; |
|---|
| 468 | | - src16++; |
|---|
| 469 | | - len--; |
|---|
| 470 | | - } |
|---|
| 471 | | - } |
|---|
| 472 | | - } else { |
|---|
| 473 | | - len = len / 4; |
|---|
| 474 | | - src32 = (__le32 *)srcaddr; |
|---|
| 475 | | - while (len) { |
|---|
| 476 | | - iowrite32(le32_to_cpu(*src32), address); |
|---|
| 477 | | - address += 4; |
|---|
| 478 | | - src32++; |
|---|
| 479 | | - len--; |
|---|
| 480 | | - } |
|---|
| 481 | | - } |
|---|
| 482 | | -} |
|---|
| 483 | | - |
|---|
| 484 | | - |
|---|
| 485 | | -static void |
|---|
| 486 | 451 | brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset, |
|---|
| 487 | 452 | void *dstaddr, u32 len) |
|---|
| 488 | 453 | { |
|---|
| .. | .. |
|---|
| 531 | 496 | brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) |
|---|
| 532 | 497 | { |
|---|
| 533 | 498 | const struct pci_dev *pdev = devinfo->pdev; |
|---|
| 499 | + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); |
|---|
| 534 | 500 | struct brcmf_core *core; |
|---|
| 535 | 501 | u32 bar0_win; |
|---|
| 536 | 502 | |
|---|
| .. | .. |
|---|
| 548 | 514 | } |
|---|
| 549 | 515 | } |
|---|
| 550 | 516 | } else { |
|---|
| 551 | | - brcmf_err("Unsupported core selected %x\n", coreid); |
|---|
| 517 | + brcmf_err(bus, "Unsupported core selected %x\n", coreid); |
|---|
| 552 | 518 | } |
|---|
| 553 | 519 | } |
|---|
| 554 | 520 | |
|---|
| .. | .. |
|---|
| 661 | 627 | brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data) |
|---|
| 662 | 628 | { |
|---|
| 663 | 629 | struct brcmf_pcie_shared_info *shared; |
|---|
| 630 | + struct brcmf_core *core; |
|---|
| 664 | 631 | u32 addr; |
|---|
| 665 | 632 | u32 cur_htod_mb_data; |
|---|
| 666 | 633 | u32 i; |
|---|
| .. | .. |
|---|
| 684 | 651 | |
|---|
| 685 | 652 | brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data); |
|---|
| 686 | 653 | pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); |
|---|
| 687 | | - pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); |
|---|
| 654 | + |
|---|
| 655 | + /* Send mailbox interrupt twice as a hardware workaround */ |
|---|
| 656 | + core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2); |
|---|
| 657 | + if (core->rev <= 13) |
|---|
| 658 | + pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); |
|---|
| 688 | 659 | |
|---|
| 689 | 660 | return 0; |
|---|
| 690 | 661 | } |
|---|
| .. | .. |
|---|
| 720 | 691 | } |
|---|
| 721 | 692 | if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) { |
|---|
| 722 | 693 | brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n"); |
|---|
| 723 | | - brcmf_dev_coredump(&devinfo->pdev->dev); |
|---|
| 694 | + brcmf_fw_crashed(&devinfo->pdev->dev); |
|---|
| 724 | 695 | } |
|---|
| 725 | 696 | } |
|---|
| 726 | 697 | |
|---|
| .. | .. |
|---|
| 745 | 716 | console->base_addr, console->buf_addr, console->bufsize); |
|---|
| 746 | 717 | } |
|---|
| 747 | 718 | |
|---|
| 748 | | - |
|---|
| 749 | | -static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo) |
|---|
| 719 | +/** |
|---|
| 720 | + * brcmf_pcie_bus_console_read - reads firmware messages |
|---|
| 721 | + * |
|---|
| 722 | + * @error: specifies if error has occurred (prints messages unconditionally) |
|---|
| 723 | + */ |
|---|
| 724 | +static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo, |
|---|
| 725 | + bool error) |
|---|
| 750 | 726 | { |
|---|
| 727 | + struct pci_dev *pdev = devinfo->pdev; |
|---|
| 728 | + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); |
|---|
| 751 | 729 | struct brcmf_pcie_console *console; |
|---|
| 752 | 730 | u32 addr; |
|---|
| 753 | 731 | u8 ch; |
|---|
| 754 | 732 | u32 newidx; |
|---|
| 755 | 733 | |
|---|
| 756 | | - if (!BRCMF_FWCON_ON()) |
|---|
| 734 | + if (!error && !BRCMF_FWCON_ON()) |
|---|
| 757 | 735 | return; |
|---|
| 758 | 736 | |
|---|
| 759 | 737 | console = &devinfo->shared.console; |
|---|
| .. | .. |
|---|
| 777 | 755 | } |
|---|
| 778 | 756 | if (ch == '\n') { |
|---|
| 779 | 757 | console->log_str[console->log_idx] = 0; |
|---|
| 780 | | - pr_debug("CONSOLE: %s", console->log_str); |
|---|
| 758 | + if (error) |
|---|
| 759 | + __brcmf_err(bus, __func__, "CONSOLE: %s", |
|---|
| 760 | + console->log_str); |
|---|
| 761 | + else |
|---|
| 762 | + pr_debug("CONSOLE: %s", console->log_str); |
|---|
| 781 | 763 | console->log_idx = 0; |
|---|
| 782 | 764 | } |
|---|
| 783 | 765 | } |
|---|
| .. | .. |
|---|
| 838 | 820 | &devinfo->pdev->dev); |
|---|
| 839 | 821 | } |
|---|
| 840 | 822 | } |
|---|
| 841 | | - brcmf_pcie_bus_console_read(devinfo); |
|---|
| 823 | + brcmf_pcie_bus_console_read(devinfo, false); |
|---|
| 842 | 824 | if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) |
|---|
| 843 | 825 | brcmf_pcie_intr_enable(devinfo); |
|---|
| 844 | 826 | devinfo->in_irq = false; |
|---|
| .. | .. |
|---|
| 848 | 830 | |
|---|
| 849 | 831 | static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo) |
|---|
| 850 | 832 | { |
|---|
| 851 | | - struct pci_dev *pdev; |
|---|
| 852 | | - |
|---|
| 853 | | - pdev = devinfo->pdev; |
|---|
| 833 | + struct pci_dev *pdev = devinfo->pdev; |
|---|
| 834 | + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); |
|---|
| 854 | 835 | |
|---|
| 855 | 836 | brcmf_pcie_intr_disable(devinfo); |
|---|
| 856 | 837 | |
|---|
| .. | .. |
|---|
| 861 | 842 | brcmf_pcie_isr_thread, IRQF_SHARED, |
|---|
| 862 | 843 | "brcmf_pcie_intr", devinfo)) { |
|---|
| 863 | 844 | pci_disable_msi(pdev); |
|---|
| 864 | | - brcmf_err("Failed to request IRQ %d\n", pdev->irq); |
|---|
| 845 | + brcmf_err(bus, "Failed to request IRQ %d\n", pdev->irq); |
|---|
| 865 | 846 | return -EIO; |
|---|
| 866 | 847 | } |
|---|
| 867 | 848 | devinfo->irq_allocated = true; |
|---|
| .. | .. |
|---|
| 871 | 852 | |
|---|
| 872 | 853 | static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) |
|---|
| 873 | 854 | { |
|---|
| 874 | | - struct pci_dev *pdev; |
|---|
| 855 | + struct pci_dev *pdev = devinfo->pdev; |
|---|
| 856 | + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); |
|---|
| 875 | 857 | u32 status; |
|---|
| 876 | 858 | u32 count; |
|---|
| 877 | 859 | |
|---|
| 878 | 860 | if (!devinfo->irq_allocated) |
|---|
| 879 | 861 | return; |
|---|
| 880 | | - |
|---|
| 881 | | - pdev = devinfo->pdev; |
|---|
| 882 | 862 | |
|---|
| 883 | 863 | brcmf_pcie_intr_disable(devinfo); |
|---|
| 884 | 864 | free_irq(pdev->irq, devinfo); |
|---|
| .. | .. |
|---|
| 891 | 871 | count++; |
|---|
| 892 | 872 | } |
|---|
| 893 | 873 | if (devinfo->in_irq) |
|---|
| 894 | | - brcmf_err("Still in IRQ (processing) !!!\n"); |
|---|
| 874 | + brcmf_err(bus, "Still in IRQ (processing) !!!\n"); |
|---|
| 895 | 875 | |
|---|
| 896 | 876 | status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); |
|---|
| 897 | 877 | brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); |
|---|
| .. | .. |
|---|
| 1006 | 986 | address & 0xffffffff); |
|---|
| 1007 | 987 | brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr + 4, address >> 32); |
|---|
| 1008 | 988 | |
|---|
| 1009 | | - memset(ring, 0, size); |
|---|
| 1010 | | - |
|---|
| 1011 | 989 | return (ring); |
|---|
| 1012 | 990 | } |
|---|
| 1013 | 991 | |
|---|
| .. | .. |
|---|
| 1102 | 1080 | |
|---|
| 1103 | 1081 | static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) |
|---|
| 1104 | 1082 | { |
|---|
| 1083 | + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); |
|---|
| 1105 | 1084 | struct brcmf_pcie_ringbuf *ring; |
|---|
| 1106 | 1085 | struct brcmf_pcie_ringbuf *rings; |
|---|
| 1107 | 1086 | u32 d2h_w_idx_ptr; |
|---|
| .. | .. |
|---|
| 1254 | 1233 | return 0; |
|---|
| 1255 | 1234 | |
|---|
| 1256 | 1235 | fail: |
|---|
| 1257 | | - brcmf_err("Allocating ring buffers failed\n"); |
|---|
| 1236 | + brcmf_err(bus, "Allocating ring buffers failed\n"); |
|---|
| 1258 | 1237 | brcmf_pcie_release_ringbuffers(devinfo); |
|---|
| 1259 | 1238 | return -ENOMEM; |
|---|
| 1260 | 1239 | } |
|---|
| .. | .. |
|---|
| 1277 | 1256 | |
|---|
| 1278 | 1257 | static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) |
|---|
| 1279 | 1258 | { |
|---|
| 1259 | + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); |
|---|
| 1280 | 1260 | u64 address; |
|---|
| 1281 | 1261 | u32 addr; |
|---|
| 1282 | 1262 | |
|---|
| 1283 | 1263 | devinfo->shared.scratch = |
|---|
| 1284 | | - dma_zalloc_coherent(&devinfo->pdev->dev, |
|---|
| 1285 | | - BRCMF_DMA_D2H_SCRATCH_BUF_LEN, |
|---|
| 1286 | | - &devinfo->shared.scratch_dmahandle, |
|---|
| 1287 | | - GFP_KERNEL); |
|---|
| 1264 | + dma_alloc_coherent(&devinfo->pdev->dev, |
|---|
| 1265 | + BRCMF_DMA_D2H_SCRATCH_BUF_LEN, |
|---|
| 1266 | + &devinfo->shared.scratch_dmahandle, |
|---|
| 1267 | + GFP_KERNEL); |
|---|
| 1288 | 1268 | if (!devinfo->shared.scratch) |
|---|
| 1289 | 1269 | goto fail; |
|---|
| 1290 | 1270 | |
|---|
| .. | .. |
|---|
| 1298 | 1278 | brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); |
|---|
| 1299 | 1279 | |
|---|
| 1300 | 1280 | devinfo->shared.ringupd = |
|---|
| 1301 | | - dma_zalloc_coherent(&devinfo->pdev->dev, |
|---|
| 1302 | | - BRCMF_DMA_D2H_RINGUPD_BUF_LEN, |
|---|
| 1303 | | - &devinfo->shared.ringupd_dmahandle, |
|---|
| 1304 | | - GFP_KERNEL); |
|---|
| 1281 | + dma_alloc_coherent(&devinfo->pdev->dev, |
|---|
| 1282 | + BRCMF_DMA_D2H_RINGUPD_BUF_LEN, |
|---|
| 1283 | + &devinfo->shared.ringupd_dmahandle, |
|---|
| 1284 | + GFP_KERNEL); |
|---|
| 1305 | 1285 | if (!devinfo->shared.ringupd) |
|---|
| 1306 | 1286 | goto fail; |
|---|
| 1307 | 1287 | |
|---|
| .. | .. |
|---|
| 1316 | 1296 | return 0; |
|---|
| 1317 | 1297 | |
|---|
| 1318 | 1298 | fail: |
|---|
| 1319 | | - brcmf_err("Allocating scratch buffers failed\n"); |
|---|
| 1299 | + brcmf_err(bus, "Allocating scratch buffers failed\n"); |
|---|
| 1320 | 1300 | brcmf_pcie_release_scratchbuffers(devinfo); |
|---|
| 1321 | 1301 | return -ENOMEM; |
|---|
| 1322 | 1302 | } |
|---|
| .. | .. |
|---|
| 1326 | 1306 | { |
|---|
| 1327 | 1307 | } |
|---|
| 1328 | 1308 | |
|---|
| 1309 | +static int brcmf_pcie_preinit(struct device *dev) |
|---|
| 1310 | +{ |
|---|
| 1311 | + struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
|---|
| 1312 | + struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; |
|---|
| 1313 | + |
|---|
| 1314 | + brcmf_dbg(PCIE, "Enter\n"); |
|---|
| 1315 | + |
|---|
| 1316 | + brcmf_pcie_intr_enable(buspub->devinfo); |
|---|
| 1317 | + brcmf_pcie_hostready(buspub->devinfo); |
|---|
| 1318 | + |
|---|
| 1319 | + return 0; |
|---|
| 1320 | +} |
|---|
| 1329 | 1321 | |
|---|
| 1330 | 1322 | static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb) |
|---|
| 1331 | 1323 | { |
|---|
| .. | .. |
|---|
| 1399 | 1391 | return 0; |
|---|
| 1400 | 1392 | } |
|---|
| 1401 | 1393 | |
|---|
| 1394 | +static int brcmf_pcie_reset(struct device *dev) |
|---|
| 1395 | +{ |
|---|
| 1396 | + struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
|---|
| 1397 | + struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; |
|---|
| 1398 | + struct brcmf_pciedev_info *devinfo = buspub->devinfo; |
|---|
| 1399 | + struct brcmf_fw_request *fwreq; |
|---|
| 1400 | + int err; |
|---|
| 1401 | + |
|---|
| 1402 | + brcmf_pcie_intr_disable(devinfo); |
|---|
| 1403 | + |
|---|
| 1404 | + brcmf_pcie_bus_console_read(devinfo, true); |
|---|
| 1405 | + |
|---|
| 1406 | + brcmf_detach(dev); |
|---|
| 1407 | + |
|---|
| 1408 | + brcmf_pcie_release_irq(devinfo); |
|---|
| 1409 | + brcmf_pcie_release_scratchbuffers(devinfo); |
|---|
| 1410 | + brcmf_pcie_release_ringbuffers(devinfo); |
|---|
| 1411 | + brcmf_pcie_reset_device(devinfo); |
|---|
| 1412 | + |
|---|
| 1413 | + fwreq = brcmf_pcie_prepare_fw_request(devinfo); |
|---|
| 1414 | + if (!fwreq) { |
|---|
| 1415 | + dev_err(dev, "Failed to prepare FW request\n"); |
|---|
| 1416 | + return -ENOMEM; |
|---|
| 1417 | + } |
|---|
| 1418 | + |
|---|
| 1419 | + err = brcmf_fw_get_firmwares(dev, fwreq, brcmf_pcie_setup); |
|---|
| 1420 | + if (err) { |
|---|
| 1421 | + dev_err(dev, "Failed to prepare FW request\n"); |
|---|
| 1422 | + kfree(fwreq); |
|---|
| 1423 | + } |
|---|
| 1424 | + |
|---|
| 1425 | + return err; |
|---|
| 1426 | +} |
|---|
| 1427 | + |
|---|
| 1402 | 1428 | static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { |
|---|
| 1429 | + .preinit = brcmf_pcie_preinit, |
|---|
| 1403 | 1430 | .txdata = brcmf_pcie_tx, |
|---|
| 1404 | 1431 | .stop = brcmf_pcie_down, |
|---|
| 1405 | 1432 | .txctl = brcmf_pcie_tx_ctlpkt, |
|---|
| .. | .. |
|---|
| 1408 | 1435 | .get_ramsize = brcmf_pcie_get_ramsize, |
|---|
| 1409 | 1436 | .get_memdump = brcmf_pcie_get_memdump, |
|---|
| 1410 | 1437 | .get_fwname = brcmf_pcie_get_fwname, |
|---|
| 1438 | + .reset = brcmf_pcie_reset, |
|---|
| 1411 | 1439 | }; |
|---|
| 1412 | 1440 | |
|---|
| 1413 | 1441 | |
|---|
| .. | .. |
|---|
| 1437 | 1465 | brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, |
|---|
| 1438 | 1466 | u32 sharedram_addr) |
|---|
| 1439 | 1467 | { |
|---|
| 1468 | + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); |
|---|
| 1440 | 1469 | struct brcmf_pcie_shared_info *shared; |
|---|
| 1441 | 1470 | u32 addr; |
|---|
| 1442 | 1471 | |
|---|
| .. | .. |
|---|
| 1448 | 1477 | brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version); |
|---|
| 1449 | 1478 | if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) || |
|---|
| 1450 | 1479 | (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) { |
|---|
| 1451 | | - brcmf_err("Unsupported PCIE version %d\n", shared->version); |
|---|
| 1480 | + brcmf_err(bus, "Unsupported PCIE version %d\n", |
|---|
| 1481 | + shared->version); |
|---|
| 1452 | 1482 | return -EINVAL; |
|---|
| 1453 | 1483 | } |
|---|
| 1454 | 1484 | |
|---|
| .. | .. |
|---|
| 1490 | 1520 | const struct firmware *fw, void *nvram, |
|---|
| 1491 | 1521 | u32 nvram_len) |
|---|
| 1492 | 1522 | { |
|---|
| 1523 | + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); |
|---|
| 1493 | 1524 | u32 sharedram_addr; |
|---|
| 1494 | 1525 | u32 sharedram_addr_written; |
|---|
| 1495 | 1526 | u32 loop_counter; |
|---|
| .. | .. |
|---|
| 1503 | 1534 | return err; |
|---|
| 1504 | 1535 | |
|---|
| 1505 | 1536 | brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); |
|---|
| 1506 | | - brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase, |
|---|
| 1507 | | - (void *)fw->data, fw->size); |
|---|
| 1537 | + memcpy_toio(devinfo->tcm + devinfo->ci->rambase, |
|---|
| 1538 | + (void *)fw->data, fw->size); |
|---|
| 1508 | 1539 | |
|---|
| 1509 | 1540 | resetintr = get_unaligned_le32(fw->data); |
|---|
| 1510 | 1541 | release_firmware(fw); |
|---|
| .. | .. |
|---|
| 1518 | 1549 | brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); |
|---|
| 1519 | 1550 | address = devinfo->ci->rambase + devinfo->ci->ramsize - |
|---|
| 1520 | 1551 | nvram_len; |
|---|
| 1521 | | - brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); |
|---|
| 1552 | + memcpy_toio(devinfo->tcm + address, nvram, nvram_len); |
|---|
| 1522 | 1553 | brcmf_fw_nvram_free(nvram); |
|---|
| 1523 | 1554 | } else { |
|---|
| 1524 | 1555 | brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", |
|---|
| .. | .. |
|---|
| 1544 | 1575 | loop_counter--; |
|---|
| 1545 | 1576 | } |
|---|
| 1546 | 1577 | if (sharedram_addr == sharedram_addr_written) { |
|---|
| 1547 | | - brcmf_err("FW failed to initialize\n"); |
|---|
| 1578 | + brcmf_err(bus, "FW failed to initialize\n"); |
|---|
| 1579 | + return -ENODEV; |
|---|
| 1580 | + } |
|---|
| 1581 | + if (sharedram_addr < devinfo->ci->rambase || |
|---|
| 1582 | + sharedram_addr >= devinfo->ci->rambase + devinfo->ci->ramsize) { |
|---|
| 1583 | + brcmf_err(bus, "Invalid shared RAM address 0x%08x\n", |
|---|
| 1584 | + sharedram_addr); |
|---|
| 1548 | 1585 | return -ENODEV; |
|---|
| 1549 | 1586 | } |
|---|
| 1550 | 1587 | brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); |
|---|
| .. | .. |
|---|
| 1555 | 1592 | |
|---|
| 1556 | 1593 | static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo) |
|---|
| 1557 | 1594 | { |
|---|
| 1558 | | - struct pci_dev *pdev; |
|---|
| 1595 | + struct pci_dev *pdev = devinfo->pdev; |
|---|
| 1596 | + struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); |
|---|
| 1559 | 1597 | int err; |
|---|
| 1560 | 1598 | phys_addr_t bar0_addr, bar1_addr; |
|---|
| 1561 | 1599 | ulong bar1_size; |
|---|
| 1562 | 1600 | |
|---|
| 1563 | | - pdev = devinfo->pdev; |
|---|
| 1564 | | - |
|---|
| 1565 | 1601 | err = pci_enable_device(pdev); |
|---|
| 1566 | 1602 | if (err) { |
|---|
| 1567 | | - brcmf_err("pci_enable_device failed err=%d\n", err); |
|---|
| 1603 | + brcmf_err(bus, "pci_enable_device failed err=%d\n", err); |
|---|
| 1568 | 1604 | return err; |
|---|
| 1569 | 1605 | } |
|---|
| 1570 | 1606 | |
|---|
| .. | .. |
|---|
| 1577 | 1613 | /* read Bar-1 mapped memory range */ |
|---|
| 1578 | 1614 | bar1_size = pci_resource_len(pdev, 2); |
|---|
| 1579 | 1615 | if ((bar1_size == 0) || (bar1_addr == 0)) { |
|---|
| 1580 | | - brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n", |
|---|
| 1616 | + brcmf_err(bus, "BAR1 Not enabled, device size=%ld, addr=%#016llx\n", |
|---|
| 1581 | 1617 | bar1_size, (unsigned long long)bar1_addr); |
|---|
| 1582 | 1618 | return -EINVAL; |
|---|
| 1583 | 1619 | } |
|---|
| 1584 | 1620 | |
|---|
| 1585 | | - devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE); |
|---|
| 1586 | | - devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size); |
|---|
| 1621 | + devinfo->regs = ioremap(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE); |
|---|
| 1622 | + devinfo->tcm = ioremap(bar1_addr, bar1_size); |
|---|
| 1587 | 1623 | |
|---|
| 1588 | 1624 | if (!devinfo->regs || !devinfo->tcm) { |
|---|
| 1589 | | - brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, |
|---|
| 1625 | + brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs, |
|---|
| 1590 | 1626 | devinfo->tcm); |
|---|
| 1591 | 1627 | return -EINVAL; |
|---|
| 1592 | 1628 | } |
|---|
| .. | .. |
|---|
| 1709 | 1745 | nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; |
|---|
| 1710 | 1746 | kfree(fwreq); |
|---|
| 1711 | 1747 | |
|---|
| 1748 | + ret = brcmf_chip_get_raminfo(devinfo->ci); |
|---|
| 1749 | + if (ret) { |
|---|
| 1750 | + brcmf_err(bus, "Failed to get RAM info\n"); |
|---|
| 1751 | + release_firmware(fw); |
|---|
| 1752 | + brcmf_fw_nvram_free(nvram); |
|---|
| 1753 | + goto fail; |
|---|
| 1754 | + } |
|---|
| 1755 | + |
|---|
| 1712 | 1756 | /* Some of the firmwares have the size of the memory of the device |
|---|
| 1713 | 1757 | * defined inside the firmware. This is because part of the memory in |
|---|
| 1714 | 1758 | * the device is shared and the devision is determined by FW. Parse |
|---|
| .. | .. |
|---|
| 1755 | 1799 | |
|---|
| 1756 | 1800 | init_waitqueue_head(&devinfo->mbdata_resp_wait); |
|---|
| 1757 | 1801 | |
|---|
| 1758 | | - brcmf_pcie_intr_enable(devinfo); |
|---|
| 1759 | | - brcmf_pcie_hostready(devinfo); |
|---|
| 1760 | | - if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) |
|---|
| 1761 | | - return; |
|---|
| 1802 | + ret = brcmf_attach(&devinfo->pdev->dev); |
|---|
| 1803 | + if (ret) |
|---|
| 1804 | + goto fail; |
|---|
| 1762 | 1805 | |
|---|
| 1763 | | - brcmf_pcie_bus_console_read(devinfo); |
|---|
| 1806 | + brcmf_pcie_bus_console_read(devinfo, false); |
|---|
| 1807 | + |
|---|
| 1808 | + return; |
|---|
| 1764 | 1809 | |
|---|
| 1765 | 1810 | fail: |
|---|
| 1766 | 1811 | device_release_driver(dev); |
|---|
| .. | .. |
|---|
| 1785 | 1830 | fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; |
|---|
| 1786 | 1831 | fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; |
|---|
| 1787 | 1832 | fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; |
|---|
| 1833 | + fwreq->board_type = devinfo->settings->board_type; |
|---|
| 1788 | 1834 | /* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */ |
|---|
| 1789 | 1835 | fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1; |
|---|
| 1790 | 1836 | fwreq->bus_nr = devinfo->pdev->bus->number; |
|---|
| .. | .. |
|---|
| 1855 | 1901 | bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); |
|---|
| 1856 | 1902 | dev_set_drvdata(&pdev->dev, bus); |
|---|
| 1857 | 1903 | |
|---|
| 1904 | + ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); |
|---|
| 1905 | + if (ret) |
|---|
| 1906 | + goto fail_bus; |
|---|
| 1907 | + |
|---|
| 1858 | 1908 | fwreq = brcmf_pcie_prepare_fw_request(devinfo); |
|---|
| 1859 | 1909 | if (!fwreq) { |
|---|
| 1860 | 1910 | ret = -ENOMEM; |
|---|
| 1861 | | - goto fail_bus; |
|---|
| 1911 | + goto fail_brcmf; |
|---|
| 1862 | 1912 | } |
|---|
| 1863 | 1913 | |
|---|
| 1864 | 1914 | ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); |
|---|
| 1865 | 1915 | if (ret < 0) { |
|---|
| 1866 | 1916 | kfree(fwreq); |
|---|
| 1867 | | - goto fail_bus; |
|---|
| 1917 | + goto fail_brcmf; |
|---|
| 1868 | 1918 | } |
|---|
| 1869 | 1919 | return 0; |
|---|
| 1870 | 1920 | |
|---|
| 1921 | +fail_brcmf: |
|---|
| 1922 | + brcmf_free(&devinfo->pdev->dev); |
|---|
| 1871 | 1923 | fail_bus: |
|---|
| 1872 | 1924 | kfree(bus->msgbuf); |
|---|
| 1873 | 1925 | kfree(bus); |
|---|
| 1874 | 1926 | fail: |
|---|
| 1875 | | - brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device); |
|---|
| 1927 | + brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device); |
|---|
| 1876 | 1928 | brcmf_pcie_release_resource(devinfo); |
|---|
| 1877 | 1929 | if (devinfo->ci) |
|---|
| 1878 | 1930 | brcmf_chip_detach(devinfo->ci); |
|---|
| .. | .. |
|---|
| 1903 | 1955 | brcmf_pcie_intr_disable(devinfo); |
|---|
| 1904 | 1956 | |
|---|
| 1905 | 1957 | brcmf_detach(&pdev->dev); |
|---|
| 1958 | + brcmf_free(&pdev->dev); |
|---|
| 1906 | 1959 | |
|---|
| 1907 | 1960 | kfree(bus->bus_priv.pcie); |
|---|
| 1908 | 1961 | kfree(bus->msgbuf->flowrings); |
|---|
| .. | .. |
|---|
| 1946 | 1999 | wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, |
|---|
| 1947 | 2000 | BRCMF_PCIE_MBDATA_TIMEOUT); |
|---|
| 1948 | 2001 | if (!devinfo->mbdata_completed) { |
|---|
| 1949 | | - brcmf_err("Timeout on response for entering D3 substate\n"); |
|---|
| 2002 | + brcmf_err(bus, "Timeout on response for entering D3 substate\n"); |
|---|
| 1950 | 2003 | brcmf_bus_change_state(bus, BRCMF_BUS_UP); |
|---|
| 1951 | 2004 | return -EIO; |
|---|
| 1952 | 2005 | } |
|---|
| .. | .. |
|---|
| 1992 | 2045 | |
|---|
| 1993 | 2046 | err = brcmf_pcie_probe(pdev, NULL); |
|---|
| 1994 | 2047 | if (err) |
|---|
| 1995 | | - brcmf_err("probe after resume failed, err=%d\n", err); |
|---|
| 2048 | + __brcmf_err(NULL, __func__, "probe after resume failed, err=%d\n", err); |
|---|
| 1996 | 2049 | |
|---|
| 1997 | 2050 | return err; |
|---|
| 1998 | 2051 | } |
|---|
| .. | .. |
|---|
| 2017 | 2070 | |
|---|
| 2018 | 2071 | static const struct pci_device_id brcmf_pcie_devid_table[] = { |
|---|
| 2019 | 2072 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), |
|---|
| 2073 | + BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355), |
|---|
| 2074 | + BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID), |
|---|
| 2020 | 2075 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), |
|---|
| 2021 | 2076 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), |
|---|
| 2022 | 2077 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), |
|---|
| .. | .. |
|---|
| 2026 | 2081 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID), |
|---|
| 2027 | 2082 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID), |
|---|
| 2028 | 2083 | BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID), |
|---|
| 2084 | + BRCMF_PCIE_DEVICE(BRCM_PCIE_4364_DEVICE_ID), |
|---|
| 2029 | 2085 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID), |
|---|
| 2030 | 2086 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID), |
|---|
| 2031 | 2087 | BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID), |
|---|
| .. | .. |
|---|
| 2054 | 2110 | }; |
|---|
| 2055 | 2111 | |
|---|
| 2056 | 2112 | |
|---|
| 2057 | | -void brcmf_pcie_register(void) |
|---|
| 2113 | +int brcmf_pcie_register(void) |
|---|
| 2058 | 2114 | { |
|---|
| 2059 | | - int err; |
|---|
| 2060 | | - |
|---|
| 2061 | 2115 | brcmf_dbg(PCIE, "Enter\n"); |
|---|
| 2062 | | - err = pci_register_driver(&brcmf_pciedrvr); |
|---|
| 2063 | | - if (err) |
|---|
| 2064 | | - brcmf_err("PCIE driver registration failed, err=%d\n", err); |
|---|
| 2116 | + return pci_register_driver(&brcmf_pciedrvr); |
|---|
| 2065 | 2117 | } |
|---|
| 2066 | 2118 | |
|---|
| 2067 | 2119 | |
|---|