Setting up repository
[linux-libre-firmware.git] / ath9k_htc / target_firmware / magpie_fw_dev / target / wlan / wlan_pci.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include <osapi.h>
36 #include <Magpie_api.h>
37 #include <adf_os_types.h>
38 #include <adf_os_pci.h>
39 #include <adf_net.h>
40 #include <sys_cfg.h>
41
42 #if MAGPIE_ENABLE_WLAN == 0
43 A_PCI_INIT_FUNC g_pci_init_func;
44 #endif
45
46 #if MAGPIE_ENABLE_PCIE == 0
47 #define EMULATE_PCI_CONFIG
48 #endif
49
50 #define PCI_CONFIG_BASE_ADDR        0x14000000 
51
52 extern A_PCI_INIT_FUNC g_pci_init_func;
53 adf_drv_info_t* g_wlan_drv = NULL;
54 adf_drv_handle_t g_wlan_drv_handle = NULL;
55 adf_os_drv_intr g_wlan_intr = NULL;
56
57 void wlan_pci_module_init(void)
58 {
59         if (g_pci_init_func != NULL) {
60                 g_pci_init_func();
61         }
62 }
63
64 void wlan_pci_register_drv(adf_drv_info_t *drv)
65 {
66         g_wlan_drv = drv;
67 }
68
69 #define ATHEROS_VENDOR_ID 0x168c
70 #define AR5416_DEVID_PCIE 0x24  
71
72 void wlan_pci_probe(void)
73 {
74         __adf_softc_t           *sc;
75         adf_os_resource_t       drv_res = {0};
76         adf_os_attach_data_t    drv_data = {{0}};   
77         int vendor_id;
78         int device_id;
79
80         A_PRINTF("<wlan_pci_probe>: Attaching the driver\n");
81
82 #if MAGPIE_ENABLE_PCIE == 0
83         vendor_id = ATHEROS_VENDOR_ID;
84         device_id = AR5416_DEVID_PCIE;
85 #else    
86         vendor_id = wlan_pci_config_read(0, 2);
87         device_id = wlan_pci_config_read(2, 2);
88 #endif    
89         A_PRINTF("<wlan_pci_probe>: Vendor id 0x%x Dev id 0x%x\n", vendor_id, device_id);    
90     
91         if (vendor_id != ATHEROS_VENDOR_ID) {
92                 A_PRINTF("<wlan_pci_probe>: Atheros card not found\n"); 
93                 return;
94         }
95             
96         /**
97          * Allocate the sc & zero down
98          */
99         sc = A_ALLOCRAM(sizeof(__adf_softc_t));
100         if (!sc) {
101                 A_PRINTF("Cannot malloc softc\n");
102                 goto mem_fail;
103         }
104     
105 #define AR5416_DEVID_PCIE 0x24          
106
107         drv_data.pci.device    = AR5416_DEVID_PCIE;
108         drv_data.pci.vendor    = 0x168c;
109         drv_data.pci.subvendor = 0;
110         drv_data.pci.subdevice = 0;
111     
112         drv_res.start  = (a_uint32_t) 0;
113         drv_res.end    = 0;
114         drv_res.type   = ADF_OS_RESOURCE_TYPE_MEM;
115         
116         g_wlan_drv_handle = g_wlan_drv->drv_attach(&drv_res, 1, &drv_data, NULL);
117         
118         return;
119 mem_fail:
120         return;        
121 }
122
123 int wlan_pci_config_write(int offset, a_uint32_t val, int width)
124 {
125 #if MAGPIE_ENABLE_PCIE == 1    
126         unsigned long addr = ( PCI_CONFIG_BASE_ADDR + offset ) & 0xfffffffc;
127         A_UINT8 *ptr = (A_UINT8 *)addr;   
128         A_UINT8 *valptr = (A_UINT8 *)&val; 
129         int idx = offset & 0x3;
130         int i;
131     
132         for (i = 0; i < width; i++) {
133                 ptr[idx + i] = valptr[3-i];
134         }            
135 #endif
136     
137         return 0;    
138 }
139
140 int wlan_pci_config_read(int offset, int width)
141 {
142 #if MAGPIE_ENABLE_PCIE == 0    
143         return 0;    
144 #else
145         unsigned long addr = ( PCI_CONFIG_BASE_ADDR + offset ) & 0xfffffffc;
146         unsigned long value = *((unsigned long *)addr);
147         A_UINT8 *ptr = (A_UINT8 *)&value;   
148         int idx = offset & 0x3;
149         int result = 0;
150         int i;
151     
152         for (i = 0; i < width; i++) {
153                 result |= (ptr[ 3 - (idx + i)] << (8*i));
154         }            
155     
156         return result;    
157 #endif    
158 }
159
160 void wlan_pci_isr()
161 {
162         if (g_wlan_intr != NULL && g_wlan_drv_handle != NULL) {
163                 g_wlan_intr(g_wlan_drv_handle);
164         }
165 }