.. | .. |
---|
| 1 | +// SPDX-License-Identifier: ISC |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2005-2011 Atheros Communications Inc. |
---|
3 | 4 | * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
---|
4 | | - * |
---|
5 | | - * Permission to use, copy, modify, and/or distribute this software for any |
---|
6 | | - * purpose with or without fee is hereby granted, provided that the above |
---|
7 | | - * copyright notice and this permission notice appear in all copies. |
---|
8 | | - * |
---|
9 | | - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
10 | | - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
11 | | - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
12 | | - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
13 | | - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
14 | | - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
15 | | - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
16 | 5 | */ |
---|
17 | 6 | |
---|
18 | 7 | #include <linux/pci.h> |
---|
.. | .. |
---|
127 | 116 | static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state); |
---|
128 | 117 | static void ath10k_pci_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state); |
---|
129 | 118 | |
---|
130 | | -static struct ce_attr host_ce_config_wlan[] = { |
---|
| 119 | +static const struct ce_attr pci_host_ce_config_wlan[] = { |
---|
131 | 120 | /* CE0: host->target HTC control and raw streams */ |
---|
132 | 121 | { |
---|
133 | 122 | .flags = CE_ATTR_FLAGS, |
---|
.. | .. |
---|
192 | 181 | |
---|
193 | 182 | /* CE7: ce_diag, the Diagnostic Window */ |
---|
194 | 183 | { |
---|
195 | | - .flags = CE_ATTR_FLAGS, |
---|
| 184 | + .flags = CE_ATTR_FLAGS | CE_ATTR_POLL, |
---|
196 | 185 | .src_nentries = 2, |
---|
197 | 186 | .src_sz_max = DIAG_TRANSFER_LIMIT, |
---|
198 | 187 | .dest_nentries = 2, |
---|
.. | .. |
---|
233 | 222 | }; |
---|
234 | 223 | |
---|
235 | 224 | /* Target firmware's Copy Engine configuration. */ |
---|
236 | | -static struct ce_pipe_config target_ce_config_wlan[] = { |
---|
| 225 | +static const struct ce_pipe_config pci_target_ce_config_wlan[] = { |
---|
237 | 226 | /* CE0: host->target HTC control and raw streams */ |
---|
238 | 227 | { |
---|
239 | 228 | .pipenum = __cpu_to_le32(0), |
---|
.. | .. |
---|
346 | 335 | * This table is derived from the CE_PCI TABLE, above. |
---|
347 | 336 | * It is passed to the Target at startup for use by firmware. |
---|
348 | 337 | */ |
---|
349 | | -static struct service_to_pipe target_service_to_ce_map_wlan[] = { |
---|
| 338 | +static const struct ce_service_to_pipe pci_target_service_to_ce_map_wlan[] = { |
---|
350 | 339 | { |
---|
351 | 340 | __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), |
---|
352 | 341 | __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ |
---|
.. | .. |
---|
870 | 859 | return val; |
---|
871 | 860 | } |
---|
872 | 861 | |
---|
| 862 | +/* Refactor from ath10k_pci_qca988x_targ_cpu_to_ce_addr. |
---|
| 863 | + * Support to access target space below 1M for qca6174 and qca9377. |
---|
| 864 | + * If target space is below 1M, the bit[20] of converted CE addr is 0. |
---|
| 865 | + * Otherwise bit[20] of converted CE addr is 1. |
---|
| 866 | + */ |
---|
| 867 | +static u32 ath10k_pci_qca6174_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) |
---|
| 868 | +{ |
---|
| 869 | + u32 val = 0, region = addr & 0xfffff; |
---|
| 870 | + |
---|
| 871 | + val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS) |
---|
| 872 | + & 0x7ff) << 21; |
---|
| 873 | + val |= ((addr >= 0x100000) ? 0x100000 : 0) | region; |
---|
| 874 | + return val; |
---|
| 875 | +} |
---|
| 876 | + |
---|
873 | 877 | static u32 ath10k_pci_qca99x0_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr) |
---|
874 | 878 | { |
---|
875 | 879 | u32 val = 0, region = addr & 0xfffff; |
---|
.. | .. |
---|
898 | 902 | int nbytes) |
---|
899 | 903 | { |
---|
900 | 904 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
901 | | - struct ath10k_ce *ce = ath10k_ce_priv(ar); |
---|
902 | 905 | int ret = 0; |
---|
903 | 906 | u32 *buf; |
---|
904 | 907 | unsigned int completed_nbytes, alloc_nbytes, remaining_bytes; |
---|
.. | .. |
---|
906 | 909 | /* Host buffer address in CE space */ |
---|
907 | 910 | u32 ce_data; |
---|
908 | 911 | dma_addr_t ce_data_base = 0; |
---|
909 | | - void *data_buf = NULL; |
---|
| 912 | + void *data_buf; |
---|
910 | 913 | int i; |
---|
911 | 914 | |
---|
912 | | - spin_lock_bh(&ce->ce_lock); |
---|
913 | | - |
---|
| 915 | + mutex_lock(&ar_pci->ce_diag_mutex); |
---|
914 | 916 | ce_diag = ar_pci->ce_diag; |
---|
915 | 917 | |
---|
916 | 918 | /* |
---|
.. | .. |
---|
921 | 923 | */ |
---|
922 | 924 | alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT); |
---|
923 | 925 | |
---|
924 | | - data_buf = (unsigned char *)dma_zalloc_coherent(ar->dev, |
---|
925 | | - alloc_nbytes, |
---|
926 | | - &ce_data_base, |
---|
927 | | - GFP_ATOMIC); |
---|
928 | | - |
---|
| 926 | + data_buf = dma_alloc_coherent(ar->dev, alloc_nbytes, &ce_data_base, |
---|
| 927 | + GFP_ATOMIC); |
---|
929 | 928 | if (!data_buf) { |
---|
930 | 929 | ret = -ENOMEM; |
---|
931 | 930 | goto done; |
---|
932 | 931 | } |
---|
| 932 | + |
---|
| 933 | + /* The address supplied by the caller is in the |
---|
| 934 | + * Target CPU virtual address space. |
---|
| 935 | + * |
---|
| 936 | + * In order to use this address with the diagnostic CE, |
---|
| 937 | + * convert it from Target CPU virtual address space |
---|
| 938 | + * to CE address space |
---|
| 939 | + */ |
---|
| 940 | + address = ath10k_pci_targ_cpu_to_ce_addr(ar, address); |
---|
933 | 941 | |
---|
934 | 942 | remaining_bytes = nbytes; |
---|
935 | 943 | ce_data = ce_data_base; |
---|
.. | .. |
---|
937 | 945 | nbytes = min_t(unsigned int, remaining_bytes, |
---|
938 | 946 | DIAG_TRANSFER_LIMIT); |
---|
939 | 947 | |
---|
940 | | - ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &ce_data, ce_data); |
---|
| 948 | + ret = ath10k_ce_rx_post_buf(ce_diag, &ce_data, ce_data); |
---|
941 | 949 | if (ret != 0) |
---|
942 | 950 | goto done; |
---|
943 | 951 | |
---|
944 | 952 | /* Request CE to send from Target(!) address to Host buffer */ |
---|
945 | | - /* |
---|
946 | | - * The address supplied by the caller is in the |
---|
947 | | - * Target CPU virtual address space. |
---|
948 | | - * |
---|
949 | | - * In order to use this address with the diagnostic CE, |
---|
950 | | - * convert it from Target CPU virtual address space |
---|
951 | | - * to CE address space |
---|
952 | | - */ |
---|
953 | | - address = ath10k_pci_targ_cpu_to_ce_addr(ar, address); |
---|
954 | | - |
---|
955 | | - ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, nbytes, 0, |
---|
956 | | - 0); |
---|
| 953 | + ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, 0); |
---|
957 | 954 | if (ret) |
---|
958 | 955 | goto done; |
---|
959 | 956 | |
---|
960 | 957 | i = 0; |
---|
961 | | - while (ath10k_ce_completed_send_next_nolock(ce_diag, |
---|
962 | | - NULL) != 0) { |
---|
963 | | - mdelay(1); |
---|
964 | | - if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { |
---|
| 958 | + while (ath10k_ce_completed_send_next(ce_diag, NULL) != 0) { |
---|
| 959 | + udelay(DIAG_ACCESS_CE_WAIT_US); |
---|
| 960 | + i += DIAG_ACCESS_CE_WAIT_US; |
---|
| 961 | + |
---|
| 962 | + if (i > DIAG_ACCESS_CE_TIMEOUT_US) { |
---|
965 | 963 | ret = -EBUSY; |
---|
966 | 964 | goto done; |
---|
967 | 965 | } |
---|
968 | 966 | } |
---|
969 | 967 | |
---|
970 | 968 | i = 0; |
---|
971 | | - while (ath10k_ce_completed_recv_next_nolock(ce_diag, |
---|
972 | | - (void **)&buf, |
---|
973 | | - &completed_nbytes) |
---|
974 | | - != 0) { |
---|
975 | | - mdelay(1); |
---|
| 969 | + while (ath10k_ce_completed_recv_next(ce_diag, (void **)&buf, |
---|
| 970 | + &completed_nbytes) != 0) { |
---|
| 971 | + udelay(DIAG_ACCESS_CE_WAIT_US); |
---|
| 972 | + i += DIAG_ACCESS_CE_WAIT_US; |
---|
976 | 973 | |
---|
977 | | - if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { |
---|
| 974 | + if (i > DIAG_ACCESS_CE_TIMEOUT_US) { |
---|
978 | 975 | ret = -EBUSY; |
---|
979 | 976 | goto done; |
---|
980 | 977 | } |
---|
.. | .. |
---|
1003 | 1000 | dma_free_coherent(ar->dev, alloc_nbytes, data_buf, |
---|
1004 | 1001 | ce_data_base); |
---|
1005 | 1002 | |
---|
1006 | | - spin_unlock_bh(&ce->ce_lock); |
---|
| 1003 | + mutex_unlock(&ar_pci->ce_diag_mutex); |
---|
1007 | 1004 | |
---|
1008 | 1005 | return ret; |
---|
1009 | 1006 | } |
---|
.. | .. |
---|
1051 | 1048 | const void *data, int nbytes) |
---|
1052 | 1049 | { |
---|
1053 | 1050 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
1054 | | - struct ath10k_ce *ce = ath10k_ce_priv(ar); |
---|
1055 | 1051 | int ret = 0; |
---|
1056 | 1052 | u32 *buf; |
---|
1057 | 1053 | unsigned int completed_nbytes, alloc_nbytes, remaining_bytes; |
---|
1058 | 1054 | struct ath10k_ce_pipe *ce_diag; |
---|
1059 | | - void *data_buf = NULL; |
---|
| 1055 | + void *data_buf; |
---|
1060 | 1056 | dma_addr_t ce_data_base = 0; |
---|
1061 | 1057 | int i; |
---|
1062 | 1058 | |
---|
1063 | | - spin_lock_bh(&ce->ce_lock); |
---|
1064 | | - |
---|
| 1059 | + mutex_lock(&ar_pci->ce_diag_mutex); |
---|
1065 | 1060 | ce_diag = ar_pci->ce_diag; |
---|
1066 | 1061 | |
---|
1067 | 1062 | /* |
---|
.. | .. |
---|
1072 | 1067 | */ |
---|
1073 | 1068 | alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT); |
---|
1074 | 1069 | |
---|
1075 | | - data_buf = (unsigned char *)dma_alloc_coherent(ar->dev, |
---|
1076 | | - alloc_nbytes, |
---|
1077 | | - &ce_data_base, |
---|
1078 | | - GFP_ATOMIC); |
---|
| 1070 | + data_buf = dma_alloc_coherent(ar->dev, alloc_nbytes, &ce_data_base, |
---|
| 1071 | + GFP_ATOMIC); |
---|
1079 | 1072 | if (!data_buf) { |
---|
1080 | 1073 | ret = -ENOMEM; |
---|
1081 | 1074 | goto done; |
---|
.. | .. |
---|
1102 | 1095 | memcpy(data_buf, data, nbytes); |
---|
1103 | 1096 | |
---|
1104 | 1097 | /* Set up to receive directly into Target(!) address */ |
---|
1105 | | - ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address); |
---|
| 1098 | + ret = ath10k_ce_rx_post_buf(ce_diag, &address, address); |
---|
1106 | 1099 | if (ret != 0) |
---|
1107 | 1100 | goto done; |
---|
1108 | 1101 | |
---|
.. | .. |
---|
1110 | 1103 | * Request CE to send caller-supplied data that |
---|
1111 | 1104 | * was copied to bounce buffer to Target(!) address. |
---|
1112 | 1105 | */ |
---|
1113 | | - ret = ath10k_ce_send_nolock(ce_diag, NULL, ce_data_base, |
---|
1114 | | - nbytes, 0, 0); |
---|
| 1106 | + ret = ath10k_ce_send(ce_diag, NULL, ce_data_base, nbytes, 0, 0); |
---|
1115 | 1107 | if (ret != 0) |
---|
1116 | 1108 | goto done; |
---|
1117 | 1109 | |
---|
1118 | 1110 | i = 0; |
---|
1119 | | - while (ath10k_ce_completed_send_next_nolock(ce_diag, |
---|
1120 | | - NULL) != 0) { |
---|
1121 | | - mdelay(1); |
---|
| 1111 | + while (ath10k_ce_completed_send_next(ce_diag, NULL) != 0) { |
---|
| 1112 | + udelay(DIAG_ACCESS_CE_WAIT_US); |
---|
| 1113 | + i += DIAG_ACCESS_CE_WAIT_US; |
---|
1122 | 1114 | |
---|
1123 | | - if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { |
---|
| 1115 | + if (i > DIAG_ACCESS_CE_TIMEOUT_US) { |
---|
1124 | 1116 | ret = -EBUSY; |
---|
1125 | 1117 | goto done; |
---|
1126 | 1118 | } |
---|
1127 | 1119 | } |
---|
1128 | 1120 | |
---|
1129 | 1121 | i = 0; |
---|
1130 | | - while (ath10k_ce_completed_recv_next_nolock(ce_diag, |
---|
1131 | | - (void **)&buf, |
---|
1132 | | - &completed_nbytes) |
---|
1133 | | - != 0) { |
---|
1134 | | - mdelay(1); |
---|
| 1122 | + while (ath10k_ce_completed_recv_next(ce_diag, (void **)&buf, |
---|
| 1123 | + &completed_nbytes) != 0) { |
---|
| 1124 | + udelay(DIAG_ACCESS_CE_WAIT_US); |
---|
| 1125 | + i += DIAG_ACCESS_CE_WAIT_US; |
---|
1135 | 1126 | |
---|
1136 | | - if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { |
---|
| 1127 | + if (i > DIAG_ACCESS_CE_TIMEOUT_US) { |
---|
1137 | 1128 | ret = -EBUSY; |
---|
1138 | 1129 | goto done; |
---|
1139 | 1130 | } |
---|
.. | .. |
---|
1164 | 1155 | ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", |
---|
1165 | 1156 | address, ret); |
---|
1166 | 1157 | |
---|
1167 | | - spin_unlock_bh(&ce->ce_lock); |
---|
| 1158 | + mutex_unlock(&ar_pci->ce_diag_mutex); |
---|
1168 | 1159 | |
---|
1169 | 1160 | return ret; |
---|
1170 | 1161 | } |
---|
.. | .. |
---|
1446 | 1437 | __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; |
---|
1447 | 1438 | int i, ret; |
---|
1448 | 1439 | |
---|
1449 | | - lockdep_assert_held(&ar->data_lock); |
---|
| 1440 | + lockdep_assert_held(&ar->dump_mutex); |
---|
1450 | 1441 | |
---|
1451 | 1442 | ret = ath10k_pci_diag_read_hi(ar, ®_dump_values[0], |
---|
1452 | 1443 | hi_failure_state, |
---|
.. | .. |
---|
1587 | 1578 | return 0; |
---|
1588 | 1579 | } |
---|
1589 | 1580 | |
---|
1590 | | -/* if an error happened returns < 0, otherwise the length */ |
---|
| 1581 | +/* Always returns the length */ |
---|
1591 | 1582 | static int ath10k_pci_dump_memory_sram(struct ath10k *ar, |
---|
1592 | 1583 | const struct ath10k_mem_region *region, |
---|
1593 | 1584 | u8 *buf) |
---|
.. | .. |
---|
1672 | 1663 | int ret, i; |
---|
1673 | 1664 | u8 *buf; |
---|
1674 | 1665 | |
---|
1675 | | - lockdep_assert_held(&ar->data_lock); |
---|
| 1666 | + lockdep_assert_held(&ar->dump_mutex); |
---|
1676 | 1667 | |
---|
1677 | 1668 | if (!crash_data) |
---|
1678 | 1669 | return; |
---|
.. | .. |
---|
1754 | 1745 | } |
---|
1755 | 1746 | } |
---|
1756 | 1747 | |
---|
1757 | | -static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) |
---|
| 1748 | +static void ath10k_pci_fw_dump_work(struct work_struct *work) |
---|
1758 | 1749 | { |
---|
| 1750 | + struct ath10k_pci *ar_pci = container_of(work, struct ath10k_pci, |
---|
| 1751 | + dump_work); |
---|
1759 | 1752 | struct ath10k_fw_crash_data *crash_data; |
---|
| 1753 | + struct ath10k *ar = ar_pci->ar; |
---|
1760 | 1754 | char guid[UUID_STRING_LEN + 1]; |
---|
1761 | 1755 | |
---|
1762 | | - spin_lock_bh(&ar->data_lock); |
---|
| 1756 | + mutex_lock(&ar->dump_mutex); |
---|
1763 | 1757 | |
---|
| 1758 | + spin_lock_bh(&ar->data_lock); |
---|
1764 | 1759 | ar->stats.fw_crash_counter++; |
---|
| 1760 | + spin_unlock_bh(&ar->data_lock); |
---|
1765 | 1761 | |
---|
1766 | 1762 | crash_data = ath10k_coredump_new(ar); |
---|
1767 | 1763 | |
---|
.. | .. |
---|
1776 | 1772 | ath10k_ce_dump_registers(ar, crash_data); |
---|
1777 | 1773 | ath10k_pci_dump_memory(ar, crash_data); |
---|
1778 | 1774 | |
---|
1779 | | - spin_unlock_bh(&ar->data_lock); |
---|
| 1775 | + mutex_unlock(&ar->dump_mutex); |
---|
1780 | 1776 | |
---|
1781 | 1777 | queue_work(ar->workqueue, &ar->restart_work); |
---|
| 1778 | +} |
---|
| 1779 | + |
---|
| 1780 | +static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) |
---|
| 1781 | +{ |
---|
| 1782 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
| 1783 | + |
---|
| 1784 | + queue_work(ar->workqueue, &ar_pci->dump_work); |
---|
1782 | 1785 | } |
---|
1783 | 1786 | |
---|
1784 | 1787 | void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, |
---|
1785 | 1788 | int force) |
---|
1786 | 1789 | { |
---|
| 1790 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
| 1791 | + |
---|
1787 | 1792 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif send complete check\n"); |
---|
1788 | 1793 | |
---|
1789 | 1794 | if (!force) { |
---|
.. | .. |
---|
1801 | 1806 | * If at least 50% of the total resources are still available, |
---|
1802 | 1807 | * don't bother checking again yet. |
---|
1803 | 1808 | */ |
---|
1804 | | - if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1)) |
---|
| 1809 | + if (resources > (ar_pci->attr[pipe].src_nentries >> 1)) |
---|
1805 | 1810 | return; |
---|
1806 | 1811 | } |
---|
1807 | 1812 | ath10k_ce_per_engine_service(ar, pipe); |
---|
.. | .. |
---|
1817 | 1822 | int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id, |
---|
1818 | 1823 | u8 *ul_pipe, u8 *dl_pipe) |
---|
1819 | 1824 | { |
---|
1820 | | - const struct service_to_pipe *entry; |
---|
| 1825 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
| 1826 | + const struct ce_service_to_pipe *entry; |
---|
1821 | 1827 | bool ul_set = false, dl_set = false; |
---|
1822 | 1828 | int i; |
---|
1823 | 1829 | |
---|
1824 | 1830 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif map service\n"); |
---|
1825 | 1831 | |
---|
1826 | | - for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) { |
---|
1827 | | - entry = &target_service_to_ce_map_wlan[i]; |
---|
| 1832 | + for (i = 0; i < ARRAY_SIZE(pci_target_service_to_ce_map_wlan); i++) { |
---|
| 1833 | + entry = &ar_pci->serv_to_pipe[i]; |
---|
1828 | 1834 | |
---|
1829 | 1835 | if (__le32_to_cpu(entry->service_id) != service_id) |
---|
1830 | 1836 | continue; |
---|
.. | .. |
---|
1853 | 1859 | } |
---|
1854 | 1860 | } |
---|
1855 | 1861 | |
---|
1856 | | - if (WARN_ON(!ul_set || !dl_set)) |
---|
| 1862 | + if (!ul_set || !dl_set) |
---|
1857 | 1863 | return -ENOENT; |
---|
1858 | 1864 | |
---|
1859 | 1865 | return 0; |
---|
.. | .. |
---|
1957 | 1963 | ath10k_pci_irq_enable(ar); |
---|
1958 | 1964 | ath10k_pci_rx_post(ar); |
---|
1959 | 1965 | |
---|
1960 | | - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, |
---|
1961 | | - ar_pci->link_ctl); |
---|
| 1966 | + pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL, |
---|
| 1967 | + PCI_EXP_LNKCTL_ASPMC, |
---|
| 1968 | + ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC); |
---|
1962 | 1969 | |
---|
1963 | 1970 | return 0; |
---|
1964 | 1971 | } |
---|
.. | .. |
---|
2071 | 2078 | ath10k_pci_irq_sync(ar); |
---|
2072 | 2079 | napi_synchronize(&ar->napi); |
---|
2073 | 2080 | napi_disable(&ar->napi); |
---|
| 2081 | + cancel_work_sync(&ar_pci->dump_work); |
---|
2074 | 2082 | |
---|
2075 | 2083 | /* Most likely the device has HTT Rx ring configured. The only way to |
---|
2076 | 2084 | * prevent the device from accessing (and possible corrupting) host |
---|
.. | .. |
---|
2177 | 2185 | |
---|
2178 | 2186 | if (ret == 0 && resp_len) { |
---|
2179 | 2187 | *resp_len = min(*resp_len, xfer.resp_len); |
---|
2180 | | - memcpy(resp, tresp, xfer.resp_len); |
---|
| 2188 | + memcpy(resp, tresp, *resp_len); |
---|
2181 | 2189 | } |
---|
2182 | 2190 | err_dma: |
---|
2183 | 2191 | kfree(treq); |
---|
.. | .. |
---|
2281 | 2289 | return 1; |
---|
2282 | 2290 | case QCA6164_2_1_DEVICE_ID: |
---|
2283 | 2291 | case QCA6174_2_1_DEVICE_ID: |
---|
2284 | | - switch (MS(ar->chip_id, SOC_CHIP_ID_REV)) { |
---|
| 2292 | + switch (MS(ar->bus_param.chip_id, SOC_CHIP_ID_REV)) { |
---|
2285 | 2293 | case QCA6174_HW_1_0_CHIP_ID_REV: |
---|
2286 | 2294 | case QCA6174_HW_1_1_CHIP_ID_REV: |
---|
2287 | 2295 | case QCA6174_HW_2_1_CHIP_ID_REV: |
---|
.. | .. |
---|
2312 | 2320 | |
---|
2313 | 2321 | int ath10k_pci_init_config(struct ath10k *ar) |
---|
2314 | 2322 | { |
---|
| 2323 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
2315 | 2324 | u32 interconnect_targ_addr; |
---|
2316 | 2325 | u32 pcie_state_targ_addr = 0; |
---|
2317 | 2326 | u32 pipe_cfg_targ_addr = 0; |
---|
.. | .. |
---|
2357 | 2366 | } |
---|
2358 | 2367 | |
---|
2359 | 2368 | ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr, |
---|
2360 | | - target_ce_config_wlan, |
---|
| 2369 | + ar_pci->pipe_config, |
---|
2361 | 2370 | sizeof(struct ce_pipe_config) * |
---|
2362 | 2371 | NUM_TARGET_CE_CONFIG_WLAN); |
---|
2363 | 2372 | |
---|
.. | .. |
---|
2382 | 2391 | } |
---|
2383 | 2392 | |
---|
2384 | 2393 | ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map, |
---|
2385 | | - target_service_to_ce_map_wlan, |
---|
2386 | | - sizeof(target_service_to_ce_map_wlan)); |
---|
| 2394 | + ar_pci->serv_to_pipe, |
---|
| 2395 | + sizeof(pci_target_service_to_ce_map_wlan)); |
---|
2387 | 2396 | if (ret != 0) { |
---|
2388 | 2397 | ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret); |
---|
2389 | 2398 | return ret; |
---|
.. | .. |
---|
2455 | 2464 | { |
---|
2456 | 2465 | struct ce_attr *attr; |
---|
2457 | 2466 | struct ce_pipe_config *config; |
---|
| 2467 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
2458 | 2468 | |
---|
2459 | 2469 | /* For QCA6174 we're overriding the Copy Engine 5 configuration, |
---|
2460 | 2470 | * since it is currently used for other feature. |
---|
2461 | 2471 | */ |
---|
2462 | 2472 | |
---|
2463 | 2473 | /* Override Host's Copy Engine 5 configuration */ |
---|
2464 | | - attr = &host_ce_config_wlan[5]; |
---|
| 2474 | + attr = &ar_pci->attr[5]; |
---|
2465 | 2475 | attr->src_sz_max = 0; |
---|
2466 | 2476 | attr->dest_nentries = 0; |
---|
2467 | 2477 | |
---|
2468 | 2478 | /* Override Target firmware's Copy Engine configuration */ |
---|
2469 | | - config = &target_ce_config_wlan[5]; |
---|
| 2479 | + config = &ar_pci->pipe_config[5]; |
---|
2470 | 2480 | config->pipedir = __cpu_to_le32(PIPEDIR_OUT); |
---|
2471 | 2481 | config->nbytes_max = __cpu_to_le32(2048); |
---|
2472 | 2482 | |
---|
2473 | 2483 | /* Map from service/endpoint to Copy Engine */ |
---|
2474 | | - target_service_to_ce_map_wlan[15].pipenum = __cpu_to_le32(1); |
---|
| 2484 | + ar_pci->serv_to_pipe[15].pipenum = __cpu_to_le32(1); |
---|
2475 | 2485 | } |
---|
2476 | 2486 | |
---|
2477 | 2487 | int ath10k_pci_alloc_pipes(struct ath10k *ar) |
---|
.. | .. |
---|
2487 | 2497 | pipe->pipe_num = i; |
---|
2488 | 2498 | pipe->hif_ce_state = ar; |
---|
2489 | 2499 | |
---|
2490 | | - ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]); |
---|
| 2500 | + ret = ath10k_ce_alloc_pipe(ar, i, &ar_pci->attr[i]); |
---|
2491 | 2501 | if (ret) { |
---|
2492 | 2502 | ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n", |
---|
2493 | 2503 | i, ret); |
---|
.. | .. |
---|
2500 | 2510 | continue; |
---|
2501 | 2511 | } |
---|
2502 | 2512 | |
---|
2503 | | - pipe->buf_sz = (size_t)(host_ce_config_wlan[i].src_sz_max); |
---|
| 2513 | + pipe->buf_sz = (size_t)(ar_pci->attr[i].src_sz_max); |
---|
2504 | 2514 | } |
---|
2505 | 2515 | |
---|
2506 | 2516 | return 0; |
---|
.. | .. |
---|
2516 | 2526 | |
---|
2517 | 2527 | int ath10k_pci_init_pipes(struct ath10k *ar) |
---|
2518 | 2528 | { |
---|
| 2529 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
2519 | 2530 | int i, ret; |
---|
2520 | 2531 | |
---|
2521 | 2532 | for (i = 0; i < CE_COUNT; i++) { |
---|
2522 | | - ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]); |
---|
| 2533 | + ret = ath10k_ce_init_pipe(ar, i, &ar_pci->attr[i]); |
---|
2523 | 2534 | if (ret) { |
---|
2524 | 2535 | ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n", |
---|
2525 | 2536 | i, ret); |
---|
.. | .. |
---|
2579 | 2590 | |
---|
2580 | 2591 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0); |
---|
2581 | 2592 | |
---|
2582 | | - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + |
---|
2583 | | - SOC_RESET_CONTROL_ADDRESS); |
---|
2584 | | - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, |
---|
2585 | | - val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); |
---|
| 2593 | + val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); |
---|
| 2594 | + ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, |
---|
| 2595 | + val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); |
---|
2586 | 2596 | } |
---|
2587 | 2597 | |
---|
2588 | 2598 | static void ath10k_pci_warm_reset_ce(struct ath10k *ar) |
---|
2589 | 2599 | { |
---|
2590 | 2600 | u32 val; |
---|
2591 | 2601 | |
---|
2592 | | - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + |
---|
2593 | | - SOC_RESET_CONTROL_ADDRESS); |
---|
| 2602 | + val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); |
---|
2594 | 2603 | |
---|
2595 | | - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, |
---|
2596 | | - val | SOC_RESET_CONTROL_CE_RST_MASK); |
---|
| 2604 | + ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, |
---|
| 2605 | + val | SOC_RESET_CONTROL_CE_RST_MASK); |
---|
2597 | 2606 | msleep(10); |
---|
2598 | | - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, |
---|
2599 | | - val & ~SOC_RESET_CONTROL_CE_RST_MASK); |
---|
| 2607 | + ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, |
---|
| 2608 | + val & ~SOC_RESET_CONTROL_CE_RST_MASK); |
---|
2600 | 2609 | } |
---|
2601 | 2610 | |
---|
2602 | 2611 | static void ath10k_pci_warm_reset_clear_lf(struct ath10k *ar) |
---|
2603 | 2612 | { |
---|
2604 | 2613 | u32 val; |
---|
2605 | 2614 | |
---|
2606 | | - val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + |
---|
2607 | | - SOC_LF_TIMER_CONTROL0_ADDRESS); |
---|
2608 | | - ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + |
---|
2609 | | - SOC_LF_TIMER_CONTROL0_ADDRESS, |
---|
2610 | | - val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); |
---|
| 2615 | + val = ath10k_pci_soc_read32(ar, SOC_LF_TIMER_CONTROL0_ADDRESS); |
---|
| 2616 | + ath10k_pci_soc_write32(ar, SOC_LF_TIMER_CONTROL0_ADDRESS, |
---|
| 2617 | + val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); |
---|
2611 | 2618 | } |
---|
2612 | 2619 | |
---|
2613 | 2620 | static int ath10k_pci_warm_reset(struct ath10k *ar) |
---|
.. | .. |
---|
2804 | 2811 | return ar_pci->pci_hard_reset(ar); |
---|
2805 | 2812 | } |
---|
2806 | 2813 | |
---|
2807 | | -static int ath10k_pci_hif_power_up(struct ath10k *ar) |
---|
| 2814 | +static int ath10k_pci_hif_power_up(struct ath10k *ar, |
---|
| 2815 | + enum ath10k_firmware_mode fw_mode) |
---|
2808 | 2816 | { |
---|
2809 | 2817 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
2810 | 2818 | int ret; |
---|
.. | .. |
---|
2813 | 2821 | |
---|
2814 | 2822 | pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL, |
---|
2815 | 2823 | &ar_pci->link_ctl); |
---|
2816 | | - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, |
---|
2817 | | - ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); |
---|
| 2824 | + pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL, |
---|
| 2825 | + PCI_EXP_LNKCTL_ASPMC); |
---|
2818 | 2826 | |
---|
2819 | 2827 | /* |
---|
2820 | 2828 | * Bring the target up cleanly. |
---|
.. | .. |
---|
3460 | 3468 | |
---|
3461 | 3469 | spin_lock_init(&ce->ce_lock); |
---|
3462 | 3470 | spin_lock_init(&ar_pci->ps_lock); |
---|
| 3471 | + mutex_init(&ar_pci->ce_diag_mutex); |
---|
| 3472 | + |
---|
| 3473 | + INIT_WORK(&ar_pci->dump_work, ath10k_pci_fw_dump_work); |
---|
3463 | 3474 | |
---|
3464 | 3475 | timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); |
---|
| 3476 | + |
---|
| 3477 | + ar_pci->attr = kmemdup(pci_host_ce_config_wlan, |
---|
| 3478 | + sizeof(pci_host_ce_config_wlan), |
---|
| 3479 | + GFP_KERNEL); |
---|
| 3480 | + if (!ar_pci->attr) |
---|
| 3481 | + return -ENOMEM; |
---|
| 3482 | + |
---|
| 3483 | + ar_pci->pipe_config = kmemdup(pci_target_ce_config_wlan, |
---|
| 3484 | + sizeof(pci_target_ce_config_wlan), |
---|
| 3485 | + GFP_KERNEL); |
---|
| 3486 | + if (!ar_pci->pipe_config) { |
---|
| 3487 | + ret = -ENOMEM; |
---|
| 3488 | + goto err_free_attr; |
---|
| 3489 | + } |
---|
| 3490 | + |
---|
| 3491 | + ar_pci->serv_to_pipe = kmemdup(pci_target_service_to_ce_map_wlan, |
---|
| 3492 | + sizeof(pci_target_service_to_ce_map_wlan), |
---|
| 3493 | + GFP_KERNEL); |
---|
| 3494 | + if (!ar_pci->serv_to_pipe) { |
---|
| 3495 | + ret = -ENOMEM; |
---|
| 3496 | + goto err_free_pipe_config; |
---|
| 3497 | + } |
---|
3465 | 3498 | |
---|
3466 | 3499 | if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) |
---|
3467 | 3500 | ath10k_pci_override_ce_config(ar); |
---|
.. | .. |
---|
3470 | 3503 | if (ret) { |
---|
3471 | 3504 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", |
---|
3472 | 3505 | ret); |
---|
3473 | | - return ret; |
---|
| 3506 | + goto err_free_serv_to_pipe; |
---|
3474 | 3507 | } |
---|
3475 | 3508 | |
---|
3476 | 3509 | return 0; |
---|
| 3510 | + |
---|
| 3511 | +err_free_serv_to_pipe: |
---|
| 3512 | + kfree(ar_pci->serv_to_pipe); |
---|
| 3513 | +err_free_pipe_config: |
---|
| 3514 | + kfree(ar_pci->pipe_config); |
---|
| 3515 | +err_free_attr: |
---|
| 3516 | + kfree(ar_pci->attr); |
---|
| 3517 | + return ret; |
---|
3477 | 3518 | } |
---|
3478 | 3519 | |
---|
3479 | 3520 | void ath10k_pci_release_resource(struct ath10k *ar) |
---|
3480 | 3521 | { |
---|
| 3522 | + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); |
---|
| 3523 | + |
---|
3481 | 3524 | ath10k_pci_rx_retry_sync(ar); |
---|
3482 | 3525 | netif_napi_del(&ar->napi); |
---|
3483 | 3526 | ath10k_pci_ce_deinit(ar); |
---|
3484 | 3527 | ath10k_pci_free_pipes(ar); |
---|
| 3528 | + kfree(ar_pci->attr); |
---|
| 3529 | + kfree(ar_pci->pipe_config); |
---|
| 3530 | + kfree(ar_pci->serv_to_pipe); |
---|
3485 | 3531 | } |
---|
3486 | 3532 | |
---|
3487 | 3533 | static const struct ath10k_bus_ops ath10k_pci_bus_ops = { |
---|
.. | .. |
---|
3497 | 3543 | struct ath10k *ar; |
---|
3498 | 3544 | struct ath10k_pci *ar_pci; |
---|
3499 | 3545 | enum ath10k_hw_rev hw_rev; |
---|
3500 | | - u32 chip_id; |
---|
3501 | | - bool pci_ps; |
---|
| 3546 | + struct ath10k_bus_params bus_params = {}; |
---|
| 3547 | + bool pci_ps, is_qca988x = false; |
---|
3502 | 3548 | int (*pci_soft_reset)(struct ath10k *ar); |
---|
3503 | 3549 | int (*pci_hard_reset)(struct ath10k *ar); |
---|
3504 | 3550 | u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); |
---|
.. | .. |
---|
3508 | 3554 | case QCA988X_2_0_DEVICE_ID: |
---|
3509 | 3555 | hw_rev = ATH10K_HW_QCA988X; |
---|
3510 | 3556 | pci_ps = false; |
---|
| 3557 | + is_qca988x = true; |
---|
3511 | 3558 | pci_soft_reset = ath10k_pci_warm_reset; |
---|
3512 | 3559 | pci_hard_reset = ath10k_pci_qca988x_chip_reset; |
---|
3513 | 3560 | targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr; |
---|
.. | .. |
---|
3525 | 3572 | pci_ps = true; |
---|
3526 | 3573 | pci_soft_reset = ath10k_pci_warm_reset; |
---|
3527 | 3574 | pci_hard_reset = ath10k_pci_qca6174_chip_reset; |
---|
3528 | | - targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr; |
---|
| 3575 | + targ_cpu_to_ce_addr = ath10k_pci_qca6174_targ_cpu_to_ce_addr; |
---|
3529 | 3576 | break; |
---|
3530 | 3577 | case QCA99X0_2_0_DEVICE_ID: |
---|
3531 | 3578 | hw_rev = ATH10K_HW_QCA99X0; |
---|
.. | .. |
---|
3551 | 3598 | case QCA9377_1_0_DEVICE_ID: |
---|
3552 | 3599 | hw_rev = ATH10K_HW_QCA9377; |
---|
3553 | 3600 | pci_ps = true; |
---|
3554 | | - pci_soft_reset = NULL; |
---|
| 3601 | + pci_soft_reset = ath10k_pci_warm_reset; |
---|
3555 | 3602 | pci_hard_reset = ath10k_pci_qca6174_chip_reset; |
---|
3556 | | - targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr; |
---|
| 3603 | + targ_cpu_to_ce_addr = ath10k_pci_qca6174_targ_cpu_to_ce_addr; |
---|
3557 | 3604 | break; |
---|
3558 | 3605 | default: |
---|
3559 | 3606 | WARN_ON(1); |
---|
.. | .. |
---|
3627 | 3674 | goto err_deinit_irq; |
---|
3628 | 3675 | } |
---|
3629 | 3676 | |
---|
| 3677 | + bus_params.dev_type = ATH10K_DEV_TYPE_LL; |
---|
| 3678 | + bus_params.link_can_suspend = true; |
---|
| 3679 | + /* Read CHIP_ID before reset to catch QCA9880-AR1A v1 devices that |
---|
| 3680 | + * fall off the bus during chip_reset. These chips have the same pci |
---|
| 3681 | + * device id as the QCA9880 BR4A or 2R4E. So that's why the check. |
---|
| 3682 | + */ |
---|
| 3683 | + if (is_qca988x) { |
---|
| 3684 | + bus_params.chip_id = |
---|
| 3685 | + ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); |
---|
| 3686 | + if (bus_params.chip_id != 0xffffffff) { |
---|
| 3687 | + if (!ath10k_pci_chip_is_supported(pdev->device, |
---|
| 3688 | + bus_params.chip_id)) { |
---|
| 3689 | + ret = -ENODEV; |
---|
| 3690 | + goto err_unsupported; |
---|
| 3691 | + } |
---|
| 3692 | + } |
---|
| 3693 | + } |
---|
| 3694 | + |
---|
3630 | 3695 | ret = ath10k_pci_chip_reset(ar); |
---|
3631 | 3696 | if (ret) { |
---|
3632 | 3697 | ath10k_err(ar, "failed to reset chip: %d\n", ret); |
---|
3633 | 3698 | goto err_free_irq; |
---|
3634 | 3699 | } |
---|
3635 | 3700 | |
---|
3636 | | - chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); |
---|
3637 | | - if (chip_id == 0xffffffff) { |
---|
3638 | | - ath10k_err(ar, "failed to get chip id\n"); |
---|
3639 | | - goto err_free_irq; |
---|
| 3701 | + bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); |
---|
| 3702 | + if (bus_params.chip_id == 0xffffffff) { |
---|
| 3703 | + ret = -ENODEV; |
---|
| 3704 | + goto err_unsupported; |
---|
3640 | 3705 | } |
---|
3641 | 3706 | |
---|
3642 | | - if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) { |
---|
3643 | | - ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", |
---|
3644 | | - pdev->device, chip_id); |
---|
3645 | | - goto err_free_irq; |
---|
| 3707 | + if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) { |
---|
| 3708 | + ret = -ENODEV; |
---|
| 3709 | + goto err_unsupported; |
---|
3646 | 3710 | } |
---|
3647 | 3711 | |
---|
3648 | | - ret = ath10k_core_register(ar, chip_id); |
---|
| 3712 | + ret = ath10k_core_register(ar, &bus_params); |
---|
3649 | 3713 | if (ret) { |
---|
3650 | 3714 | ath10k_err(ar, "failed to register driver core: %d\n", ret); |
---|
3651 | 3715 | goto err_free_irq; |
---|
.. | .. |
---|
3653 | 3717 | |
---|
3654 | 3718 | return 0; |
---|
3655 | 3719 | |
---|
| 3720 | +err_unsupported: |
---|
| 3721 | + ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", |
---|
| 3722 | + pdev->device, bus_params.chip_id); |
---|
| 3723 | + |
---|
3656 | 3724 | err_free_irq: |
---|
3657 | 3725 | ath10k_pci_free_irq(ar); |
---|
3658 | | - ath10k_pci_rx_retry_sync(ar); |
---|
3659 | 3726 | |
---|
3660 | 3727 | err_deinit_irq: |
---|
3661 | | - ath10k_pci_deinit_irq(ar); |
---|
| 3728 | + ath10k_pci_release_resource(ar); |
---|
3662 | 3729 | |
---|
3663 | 3730 | err_sleep: |
---|
3664 | 3731 | ath10k_pci_sleep_sync(ar); |
---|
.. | .. |
---|
3676 | 3743 | static void ath10k_pci_remove(struct pci_dev *pdev) |
---|
3677 | 3744 | { |
---|
3678 | 3745 | struct ath10k *ar = pci_get_drvdata(pdev); |
---|
3679 | | - struct ath10k_pci *ar_pci; |
---|
3680 | 3746 | |
---|
3681 | 3747 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci remove\n"); |
---|
3682 | 3748 | |
---|
3683 | 3749 | if (!ar) |
---|
3684 | | - return; |
---|
3685 | | - |
---|
3686 | | - ar_pci = ath10k_pci_priv(ar); |
---|
3687 | | - |
---|
3688 | | - if (!ar_pci) |
---|
3689 | 3750 | return; |
---|
3690 | 3751 | |
---|
3691 | 3752 | ath10k_core_unregister(ar); |
---|
.. | .. |
---|
3739 | 3800 | |
---|
3740 | 3801 | static int __init ath10k_pci_init(void) |
---|
3741 | 3802 | { |
---|
3742 | | - int ret; |
---|
| 3803 | + int ret1, ret2; |
---|
3743 | 3804 | |
---|
3744 | | - ret = pci_register_driver(&ath10k_pci_driver); |
---|
3745 | | - if (ret) |
---|
| 3805 | + ret1 = pci_register_driver(&ath10k_pci_driver); |
---|
| 3806 | + if (ret1) |
---|
3746 | 3807 | printk(KERN_ERR "failed to register ath10k pci driver: %d\n", |
---|
3747 | | - ret); |
---|
| 3808 | + ret1); |
---|
3748 | 3809 | |
---|
3749 | | - ret = ath10k_ahb_init(); |
---|
3750 | | - if (ret) |
---|
3751 | | - printk(KERN_ERR "ahb init failed: %d\n", ret); |
---|
| 3810 | + ret2 = ath10k_ahb_init(); |
---|
| 3811 | + if (ret2) |
---|
| 3812 | + printk(KERN_ERR "ahb init failed: %d\n", ret2); |
---|
3752 | 3813 | |
---|
3753 | | - return ret; |
---|
| 3814 | + if (ret1 && ret2) |
---|
| 3815 | + return ret1; |
---|
| 3816 | + |
---|
| 3817 | + /* registered to at least one bus */ |
---|
| 3818 | + return 0; |
---|
3754 | 3819 | } |
---|
3755 | 3820 | module_init(ath10k_pci_init); |
---|
3756 | 3821 | |
---|