Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / wlan / if_ath_pci.c
1 /*-
2  * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
3  * Copyright (c) 2004 Atheros Communications, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer,
11  *    without modification.
12  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
13  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
14  *    redistribution must be conditioned upon including a substantially
15  *    similar Disclaimer requirement for further binary redistribution.
16  * 3. Neither the names of the above-listed copyright holders nor the names
17  *    of any contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * Alternatively, this software may be distributed under the terms of the
21  * GNU General Public License ("GPL") version 2 as published by the Free
22  * Software Foundation.
23  *
24  * NO WARRANTY
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
28  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
30  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
33  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGES.
36  *
37  * $Id: //depot/sw/branches/fusion_usb/target_firmware/wlan/target/madwifi/ath/if_ath_pci.c#1 $
38  */
39
40 #ifndef EXPORT_SYMTAB
41 #define EXPORT_SYMTAB
42 #endif
43
44 #include <adf_os_types.h>
45 #include <adf_os_dma.h>
46 #include <adf_os_pci.h>
47 #include <adf_os_timer.h>
48 #include <adf_os_lock.h>
49 #include <adf_os_io.h>
50 #include <adf_os_mem.h>
51 #include <adf_os_module.h>
52 #include <adf_os_util.h>
53 #include <adf_os_stdtypes.h>
54 #include <adf_os_defer.h>
55 #include <adf_os_atomic.h>
56 #include <adf_nbuf.h>
57 #include <adf_net.h>
58 #include <adf_os_irq.h>
59
60 #include <adf_net_types.h>
61 #include <adf_net_wcmd.h>
62
63 #include <ieee80211_var.h>
64 #include "if_athvar.h"
65 #include "if_ath_pci.h"
66
67 extern a_int32_t ath_tgt_attach(a_uint32_t devid,a_uint32_t mem_start,
68                                 struct ath_softc_tgt *sc, adf_os_device_t osdev);
69 extern a_int32_t ath_detach(void *);
70 extern adf_os_irq_resp_t ath_intr(adf_drv_handle_t hdl);
71
72 struct ath_pci_softc {
73         struct ath_softc_tgt aps_sc;
74 #ifdef CONFIG_PM
75         u32 ps_pmstate[16];
76 #endif
77 };
78
79 /*
80  * User a static table of PCI id's for now.  While this is the
81  * "new way" to do things, we may want to switch back to having
82  * the HAL check them by defining a probe method.
83  */
84 #ifdef ATH_SUPPORT_XB_ONLY
85 static adf_os_pci_dev_id_t ath_pci_id_table[] = {
86     { 0x168c, 0x0024, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* PCI-E (XB)    */
87     { 0 },
88 };
89 #else
90
91 static adf_os_pci_dev_id_t ath_pci_id_table[] = {
92     { 0x168c, 0x0007, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
93     { 0x168c, 0x0012, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
94     { 0x168c, 0x0013, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
95     { 0xa727, 0x0013, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* 3com */
96     { 0x10b7, 0x0013, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* 3com 3CRDAG675 */
97     { 0x168c, 0x1014, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* IBM minipci 5212 */
98     { 0x168c, 0x101a, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* some Griffin-Lite */
99     { 0x168c, 0x0015, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
100     { 0x168c, 0x0016, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
101     { 0x168c, 0x0017, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
102     { 0x168c, 0x0018, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
103     { 0x168c, 0x0019, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
104     { 0x168c, 0x001a, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
105     { 0x168c, 0x001b, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
106     { 0x168c, 0x001c, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
107     { 0x168c, 0x001d, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID },
108     { 0x168c, 0xff1d, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* owl emulation */
109     { 0x168c, 0xff1c, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* owl emulation */
110     { 0x168c, 0x0023, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* PCI (MB/CB)   */
111     { 0x168c, 0x0024, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* PCI-E (XB)    */
112     { 0x168c, 0x0027, ADF_OS_PCI_ANY_ID, ADF_OS_PCI_ANY_ID }, /* Sowl PCI     */
113     { 0 },
114 };
115 #endif
116
117 void bus_read_cachesize(struct ath_softc *sc, a_uint8_t *csz);
118 void exit_ath_pci(void);
119 a_int32_t init_ath_pci(void);
120
121 static adf_drv_handle_t
122 ath_pci_probe(adf_os_resource_t *res,a_int32_t count, adf_os_attach_data_t *data,
123               adf_os_device_t osdev)
124 {
125         struct ath_pci_softc *sc;
126         a_uint8_t csz = 32;
127         adf_os_pci_dev_id_t *id = (adf_os_pci_dev_id_t *)data;
128
129         adf_os_pci_config_write8(osdev, ATH_PCI_CACHE_LINE_SIZE, csz);
130         adf_os_pci_config_write8(osdev, ATH_PCI_LATENCY_TIMER, 0xa8);
131
132         sc = adf_os_mem_alloc(sizeof(struct ath_pci_softc));
133
134         if (sc == NULL) {
135                 adf_os_print("ath_pci: no memory for device state\n");
136                 goto bad2;
137         }
138         adf_os_mem_set(sc, 0, sizeof(struct ath_pci_softc));
139
140         /*
141          * Mark the device as detached to avoid processing
142          * interrupts until setup is complete.
143          */
144         sc->aps_sc.sc_invalid = 1;
145
146         adf_os_print("ath_pci_probe %x\n",id->device);
147
148         if (ath_tgt_attach(id->device, res->start, &sc->aps_sc, osdev) != 0)
149                 goto bad3;
150
151         /* ready to process interrupts */
152         sc->aps_sc.sc_invalid = 0;
153         adf_os_setup_intr(osdev, ath_intr);
154         return (adf_drv_handle_t)sc;
155 bad3:
156 bad2:
157         return NULL;
158 }
159
160 static void
161 ath_pci_remove(adf_drv_handle_t hdl)
162 {
163         struct ath_softc_tgt *sc = hdl;
164
165         ath_detach((struct ath_softc_tgt *)hdl);
166         adf_os_free_intr(sc->sc_dev);
167 }
168
169 static void
170 ath_pci_suspend(adf_drv_handle_t hdl, adf_os_pm_t pm)
171 {
172 }
173
174 static void
175 ath_pci_resume(adf_drv_handle_t hdl)
176 {
177 }
178
179 static char *dev_info = "ath_pci_tgt";
180
181 void
182 bus_read_cachesize(struct ath_softc *sc, a_uint8_t *csz)
183 {
184         *csz = adf_os_cache_line_size();
185 }
186
187 static adf_drv_info_t ath_drv_info = adf_os_pci_set_drv_info(ath_pci_tgt,&ath_pci_id_table[0], ath_pci_probe, ath_pci_remove, ath_pci_suspend, ath_pci_resume);
188
189 a_int32_t
190 init_ath_pci(void)
191 {
192         return adf_net_register_drv( &ath_drv_info );
193 }
194
195 void
196 exit_ath_pci(void)
197 {
198         adf_net_unregister_drv("ath_pci");
199 }
200
201 adf_os_pci_module_init(init_ath_pci);
202 adf_os_pci_module_exit(exit_ath_pci);
203 adf_os_module_dep(ath_pci_tgt, adf_net);
204 adf_os_module_dep(ath_pci_tgt, hal);
205 adf_os_module_dep(ath_pci_tgt, ath_pci);
206 adf_os_module_dep(ath_pci_tgt, wlan_tgt);
207 adf_os_module_dep(ath_pci_tgt, htc_tgt);
208 adf_os_module_dep(ath_pci_tgt, inproc_hif);