]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt2860/pci_main_dev.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / staging / rt2860 / pci_main_dev.c
CommitLineData
ca97b838
BZ
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 pci_main_dev.c
29
30 Abstract:
31 Create and register network interface for PCI based chipsets in Linux platform.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "rt_config.h"
39#include <linux/pci.h>
5a0e3ad6 40#include <linux/slab.h>
ca97b838 41
9f548a2a
BZ
42/* Following information will be show when you run 'modinfo' */
43/* *** If you have a solution for the bug in current version of driver, please mail to me. */
44/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */
e44fd1cf
BZ
45MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
46MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver");
47MODULE_LICENSE("GPL");
e20aea64 48MODULE_ALIAS("rt3090sta");
e44fd1cf 49
9f548a2a
BZ
50/* */
51/* Function declarations */
52/* */
ca97b838
BZ
53extern int rt28xx_close(IN struct net_device *net_dev);
54extern int rt28xx_open(struct net_device *net_dev);
55
51126deb
BZ
56static void __devexit rt2860_remove_one(struct pci_dev *pci_dev);
57static int __devinit rt2860_probe(struct pci_dev *pci_dev,
66cd8d6e 58 const struct pci_device_id *ent);
ca97b838
BZ
59static void __exit rt2860_cleanup_module(void);
60static int __init rt2860_init_module(void);
61
51126deb 62static void RTMPInitPCIeDevice(IN struct pci_dev *pci_dev,
62eb734b 63 struct rt_rtmp_adapter *pAd);
ca97b838
BZ
64
65#ifdef CONFIG_PM
66static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
67static int rt2860_resume(struct pci_dev *pci_dev);
9f548a2a 68#endif /* CONFIG_PM // */
ca97b838 69
9f548a2a
BZ
70/* */
71/* Ralink PCI device table, include all supported chipsets */
72/* */
66cd8d6e 73static struct pci_device_id rt2860_pci_tbl[] __devinitdata = {
e44fd1cf 74#ifdef RT2860
9f548a2a 75 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, /*RT28602.4G */
ca97b838
BZ
76 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
77 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
78 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
79 {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
80 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
81 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
82 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
83 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
84 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
85 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
86 {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
e44fd1cf
BZ
87#endif
88#ifdef RT3090
89 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)},
90 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)},
91 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)},
9f548a2a 92#endif /* RT3090 // */
e44fd1cf
BZ
93#ifdef RT3390
94 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)},
95 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)},
96 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)},
9f548a2a
BZ
97#endif /* RT3390 // */
98 {0,} /* terminate list */
ca97b838
BZ
99};
100
101MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
ca97b838
BZ
102#ifdef MODULE_VERSION
103MODULE_VERSION(STA_DRIVER_VERSION);
104#endif
105
9f548a2a
BZ
106/* */
107/* Our PCI driver structure */
108/* */
66cd8d6e
BZ
109static struct pci_driver rt2860_driver = {
110name: "rt2860",
111id_table:rt2860_pci_tbl,
112probe: rt2860_probe,
113remove:__devexit_p(rt2860_remove_one),
ca97b838 114#ifdef CONFIG_PM
66cd8d6e
BZ
115suspend:rt2860_suspend,
116resume:rt2860_resume,
ca97b838
BZ
117#endif
118};
119
ca97b838
BZ
120/***************************************************************************
121 *
122 * PCI device initialization related procedures.
123 *
124 ***************************************************************************/
125#ifdef CONFIG_PM
126
62eb734b 127void RT2860RejectPendingPackets(struct rt_rtmp_adapter *pAd)
ca97b838 128{
9f548a2a
BZ
129 /* clear PS packets */
130 /* clear TxSw packets */
ca97b838
BZ
131}
132
66cd8d6e 133static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state)
ca97b838
BZ
134{
135 struct net_device *net_dev = pci_get_drvdata(pci_dev);
62eb734b 136 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
51126deb 137 int retval = 0;
ca97b838 138
ca97b838
BZ
139 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
140
66cd8d6e 141 if (net_dev == NULL) {
ca97b838 142 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
66cd8d6e 143 } else {
ca97b838
BZ
144 GET_PAD_FROM_NET_DEV(pAd, net_dev);
145
146 /* we can not use IFF_UP because ra0 down but ra1 up */
147 /* and 1 suspend/resume function for 1 module, not for each interface */
148 /* so Linux will call suspend/resume function once */
66cd8d6e 149 if (VIRTUAL_IF_NUM(pAd) > 0) {
9f548a2a 150 /* avoid users do suspend after interface is down */
ca97b838 151
9f548a2a 152 /* stop interface */
ca97b838
BZ
153 netif_carrier_off(net_dev);
154 netif_stop_queue(net_dev);
155
9f548a2a 156 /* mark device as removed from system and therefore no longer available */
ca97b838
BZ
157 netif_device_detach(net_dev);
158
9f548a2a 159 /* mark halt flag */
ca97b838
BZ
160 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
161 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
162
9f548a2a 163 /* take down the device */
8a10a546 164 rt28xx_close((struct net_device *)net_dev);
ca97b838
BZ
165
166 RT_MOD_DEC_USE_COUNT();
167 }
168 }
169
9f548a2a
BZ
170 /* reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html */
171 /* enable device to generate PME# when suspended */
172 /* pci_choose_state(): Choose the power state of a PCI device to be suspended */
ca97b838 173 retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
9f548a2a 174 /* save the PCI configuration space of a device before suspending */
ca97b838 175 pci_save_state(pci_dev);
9f548a2a 176 /* disable PCI device after use */
ca97b838
BZ
177 pci_disable_device(pci_dev);
178
179 retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
180
181 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
182 return retval;
183}
184
66cd8d6e 185static int rt2860_resume(struct pci_dev *pci_dev)
ca97b838
BZ
186{
187 struct net_device *net_dev = pci_get_drvdata(pci_dev);
62eb734b 188 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
51126deb 189 int retval;
ca97b838 190
9f548a2a
BZ
191 /* set the power state of a PCI device */
192 /* PCI has 4 power states, DO (normal) ~ D3(less power) */
193 /* in include/linux/pci.h, you can find that */
194 /* #define PCI_D0 ((pci_power_t __force) 0) */
195 /* #define PCI_D1 ((pci_power_t __force) 1) */
196 /* #define PCI_D2 ((pci_power_t __force) 2) */
197 /* #define PCI_D3hot ((pci_power_t __force) 3) */
198 /* #define PCI_D3cold ((pci_power_t __force) 4) */
199 /* #define PCI_UNKNOWN ((pci_power_t __force) 5) */
200 /* #define PCI_POWER_ERROR ((pci_power_t __force) -1) */
ca97b838
BZ
201 retval = pci_set_power_state(pci_dev, PCI_D0);
202
9f548a2a 203 /* restore the saved state of a PCI device */
ca97b838
BZ
204 pci_restore_state(pci_dev);
205
9f548a2a 206 /* initialize device before it's used by a driver */
66cd8d6e 207 if (pci_enable_device(pci_dev)) {
ca97b838
BZ
208 printk("pci enable fail!\n");
209 return 0;
210 }
211
212 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
213
66cd8d6e 214 if (net_dev == NULL) {
ca97b838 215 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
66cd8d6e 216 } else
ca97b838
BZ
217 GET_PAD_FROM_NET_DEV(pAd, net_dev);
218
66cd8d6e 219 if (pAd != NULL) {
ca97b838
BZ
220 /* we can not use IFF_UP because ra0 down but ra1 up */
221 /* and 1 suspend/resume function for 1 module, not for each interface */
222 /* so Linux will call suspend/resume function once */
66cd8d6e 223 if (VIRTUAL_IF_NUM(pAd) > 0) {
9f548a2a 224 /* mark device as attached from system and restart if needed */
ca97b838
BZ
225 netif_device_attach(net_dev);
226
8a10a546 227 if (rt28xx_open((struct net_device *)net_dev) != 0) {
9f548a2a 228 /* open fail */
66cd8d6e
BZ
229 DBGPRINT(RT_DEBUG_TRACE,
230 ("<=== rt2860_resume()\n"));
ca97b838
BZ
231 return 0;
232 }
9f548a2a 233 /* increase MODULE use count */
ca97b838
BZ
234 RT_MOD_INC_USE_COUNT();
235
236 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
237 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
238
239 netif_start_queue(net_dev);
240 netif_carrier_on(net_dev);
241 netif_wake_queue(net_dev);
242 }
243 }
244
245 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
246 return 0;
247}
9f548a2a 248#endif /* CONFIG_PM // */
ca97b838 249
51126deb 250static int __init rt2860_init_module(void)
ca97b838
BZ
251{
252 return pci_register_driver(&rt2860_driver);
253}
254
9f548a2a
BZ
255/* */
256/* Driver module unload function */
257/* */
51126deb 258static void __exit rt2860_cleanup_module(void)
ca97b838 259{
66cd8d6e 260 pci_unregister_driver(&rt2860_driver);
ca97b838
BZ
261}
262
263module_init(rt2860_init_module);
264module_exit(rt2860_cleanup_module);
265
9f548a2a
BZ
266/* */
267/* PCI device probe & initialization function */
268/* */
51126deb 269static int __devinit rt2860_probe(IN struct pci_dev *pci_dev,
66cd8d6e 270 IN const struct pci_device_id *pci_id)
ca97b838 271{
62eb734b 272 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
66cd8d6e 273 struct net_device *net_dev;
51126deb
BZ
274 void *handle;
275 char *print_name;
276 unsigned long csr_addr;
277 int rv = 0;
62eb734b 278 struct rt_rtmp_os_netdev_op_hook netDevHook;
ca97b838
BZ
279
280 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
281
9f548a2a
BZ
282/*PCIDevInit============================================== */
283 /* wake up and enable device */
66cd8d6e
BZ
284 if ((rv = pci_enable_device(pci_dev)) != 0) {
285 DBGPRINT(RT_DEBUG_ERROR,
286 ("Enable PCI device failed, errno=%d!\n", rv));
ca97b838
BZ
287 return rv;
288 }
289
51126deb 290 print_name = (char *)pci_name(pci_dev);
ca97b838 291
66cd8d6e
BZ
292 if ((rv = pci_request_regions(pci_dev, print_name)) != 0) {
293 DBGPRINT(RT_DEBUG_ERROR,
294 ("Request PCI resource failed, errno=%d!\n", rv));
ca97b838
BZ
295 goto err_out;
296 }
9f548a2a 297 /* map physical address to virtual address for accessing register */
66cd8d6e
BZ
298 csr_addr =
299 (unsigned long)ioremap(pci_resource_start(pci_dev, 0),
300 pci_resource_len(pci_dev, 0));
301 if (!csr_addr) {
302 DBGPRINT(RT_DEBUG_ERROR,
303 ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
51126deb
BZ
304 print_name, (unsigned long)pci_resource_len(pci_dev, 0),
305 (unsigned long)pci_resource_start(pci_dev, 0)));
ca97b838 306 goto err_out_free_res;
66cd8d6e
BZ
307 } else {
308 DBGPRINT(RT_DEBUG_TRACE,
309 ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name,
51126deb
BZ
310 (unsigned long)pci_resource_start(pci_dev, 0),
311 (unsigned long)csr_addr, pci_dev->irq));
ca97b838
BZ
312 }
313
9f548a2a 314 /* Set DMA master */
ca97b838
BZ
315 pci_set_master(pci_dev);
316
9f548a2a 317/*RtmpDevInit============================================== */
62eb734b 318 /* Allocate struct rt_rtmp_adapter adapter structure */
ca97b838 319 handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
66cd8d6e
BZ
320 if (handle == NULL) {
321 DBGPRINT(RT_DEBUG_ERROR,
322 ("%s(): Allocate memory for os handle failed!\n",
323 __func__));
ca97b838
BZ
324 goto err_out_iounmap;
325 }
326
8a10a546 327 ((struct os_cookie *)handle)->pci_dev = pci_dev;
ca97b838 328
62eb734b 329 rv = RTMPAllocAdapterBlock(handle, &pAd); /*shiang: we may need the pci_dev for allocate structure of "struct rt_rtmp_adapter" */
ca97b838
BZ
330 if (rv != NDIS_STATUS_SUCCESS)
331 goto err_out_iounmap;
62eb734b 332 /* Here are the struct rt_rtmp_adapter structure with pci-bus specific parameters. */
51126deb 333 pAd->CSRBaseAddress = (u8 *)csr_addr;
66cd8d6e
BZ
334 DBGPRINT(RT_DEBUG_ERROR,
335 ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n",
51126deb 336 (unsigned long)pAd->CSRBaseAddress, csr_addr));
ca97b838
BZ
337 RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
338
9f548a2a 339/*NetDevInit============================================== */
ca97b838
BZ
340 net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
341 if (net_dev == NULL)
342 goto err_out_free_radev;
343
9f548a2a
BZ
344 /* Here are the net_device structure with pci-bus specific parameters. */
345 net_dev->irq = pci_dev->irq; /* Interrupt IRQ number */
346 net_dev->base_addr = csr_addr; /* Save CSR virtual address and irq to device structure */
347 pci_set_drvdata(pci_dev, net_dev); /* Set driver data */
ca97b838
BZ
348
349/* for supporting Network Manager */
350 /* Set the sysfs physical device reference for the network logical device
66cd8d6e 351 * if set prior to registration will cause a symlink during initialization.
ca97b838
BZ
352 */
353 SET_NETDEV_DEV(net_dev, &(pci_dev->dev));
354
9f548a2a
BZ
355/*All done, it's time to register the net device to linux kernel. */
356 /* Register this device */
ca97b838
BZ
357 rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
358 if (rv)
359 goto err_out_free_netdev;
360
361 pAd->StaCfg.OriDevType = net_dev->type;
362 RTMPInitPCIeDevice(pci_dev, pAd);
363
ca97b838
BZ
364 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
365
9f548a2a 366 return 0; /* probe ok */
ca97b838
BZ
367
368 /* --------------------------- ERROR HANDLE --------------------------- */
369err_out_free_netdev:
370 RtmpOSNetDevFree(net_dev);
371
372err_out_free_radev:
62eb734b 373 /* free struct rt_rtmp_adapter strcuture and os_cookie */
ca97b838
BZ
374 RTMPFreeAdapter(pAd);
375
376err_out_iounmap:
377 iounmap((void *)(csr_addr));
66cd8d6e
BZ
378 release_mem_region(pci_resource_start(pci_dev, 0),
379 pci_resource_len(pci_dev, 0));
ca97b838
BZ
380
381err_out_free_res:
382 pci_release_regions(pci_dev);
383
384err_out:
385 pci_disable_device(pci_dev);
386
66cd8d6e
BZ
387 DBGPRINT(RT_DEBUG_ERROR,
388 ("<=== rt2860_probe failed with rv = %d!\n", rv));
ca97b838 389
66cd8d6e 390 return -ENODEV; /* probe fail */
ca97b838
BZ
391}
392
51126deb 393static void __devexit rt2860_remove_one(IN struct pci_dev *pci_dev)
ca97b838 394{
8a10a546 395 struct net_device *net_dev = pci_get_drvdata(pci_dev);
62eb734b 396 struct rt_rtmp_adapter *pAd = NULL;
51126deb 397 unsigned long csr_addr = net_dev->base_addr; /* pAd->CSRBaseAddress; */
ca97b838
BZ
398
399 GET_PAD_FROM_NET_DEV(pAd, net_dev);
400
66cd8d6e 401 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
ca97b838 402
66cd8d6e 403 if (pAd != NULL) {
9f548a2a 404 /* Unregister/Free all allocated net_device. */
ca97b838
BZ
405 RtmpPhyNetDevExit(pAd, net_dev);
406
9f548a2a 407 /* Unmap CSR base address */
ca97b838
BZ
408 iounmap((char *)(csr_addr));
409
9f548a2a 410 /* release memory region */
66cd8d6e
BZ
411 release_mem_region(pci_resource_start(pci_dev, 0),
412 pci_resource_len(pci_dev, 0));
ca97b838 413
62eb734b 414 /* Free struct rt_rtmp_adapter related structures. */
ca97b838
BZ
415 RtmpRaDevCtrlExit(pAd);
416
66cd8d6e 417 } else {
9f548a2a 418 /* Unregister network device */
ca97b838
BZ
419 RtmpOSNetDevDetach(net_dev);
420
9f548a2a 421 /* Unmap CSR base address */
ca97b838
BZ
422 iounmap((char *)(net_dev->base_addr));
423
9f548a2a 424 /* release memory region */
66cd8d6e
BZ
425 release_mem_region(pci_resource_start(pci_dev, 0),
426 pci_resource_len(pci_dev, 0));
ca97b838
BZ
427 }
428
9f548a2a 429 /* Free the root net_device */
ca97b838
BZ
430 RtmpOSNetDevFree(net_dev);
431
432}
433
ca97b838
BZ
434/*
435========================================================================
436Routine Description:
437 Check the chipset vendor/product ID.
438
439Arguments:
440 _dev_p Point to the PCI or USB device
441
442Return Value:
443 TRUE Check ok
444 FALSE Check fail
445
446Note:
447========================================================================
448*/
66cd8d6e 449BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
ca97b838
BZ
450{
451 /* always TRUE */
452 return TRUE;
453}
454
ca97b838
BZ
455/***************************************************************************
456 *
457 * PCIe device initialization related procedures.
458 *
459 ***************************************************************************/
62eb734b 460static void RTMPInitPCIeDevice(struct pci_dev *pci_dev, struct rt_rtmp_adapter *pAd)
ca97b838 461{
51126deb 462 u16 device_id;
8a10a546 463 struct os_cookie *pObj;
ca97b838 464
8a10a546 465 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
466 pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
467 device_id = le2cpu16(device_id);
468 pObj->DeviceID = device_id;
ca97b838 469 if (
e44fd1cf 470#ifdef RT2860
66cd8d6e
BZ
471 (device_id == NIC2860_PCIe_DEVICE_ID) ||
472 (device_id == NIC2790_PCIe_DEVICE_ID) ||
473 (device_id == VEN_AWT_PCIe_DEVICE_ID) ||
e44fd1cf
BZ
474#endif
475#ifdef RT3090
66cd8d6e
BZ
476 (device_id == NIC3090_PCIe_DEVICE_ID) ||
477 (device_id == NIC3091_PCIe_DEVICE_ID) ||
478 (device_id == NIC3092_PCIe_DEVICE_ID) ||
9f548a2a 479#endif /* RT3090 // */
66cd8d6e 480 0) {
51126deb 481 u32 MacCsr0 = 0, Index = 0;
66cd8d6e 482 do {
ca97b838
BZ
483 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
484
485 if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
486 break;
487
488 RTMPusecDelay(10);
489 } while (Index++ < 100);
490
9f548a2a
BZ
491 /* Support advanced power save after 2892/2790. */
492 /* MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). */
66cd8d6e 493 if ((MacCsr0 & 0xffff0000) != 0x28600000) {
e44fd1cf 494 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
ca97b838
BZ
495 }
496 }
497}
498
62eb734b 499void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd)
ca97b838 500{
51126deb
BZ
501 int pos;
502 u16 reg16, data2, PCIePowerSaveLevel, Configuration;
503 u32 MacValue;
66cd8d6e 504 BOOLEAN bFindIntel = FALSE;
8a10a546 505 struct os_cookie *pObj;
ca97b838 506
8a10a546 507 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 508
e44fd1cf 509 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
ca97b838
BZ
510 return;
511
66cd8d6e 512 DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
9f548a2a 513 /* Init EEPROM, and save settings */
66cd8d6e 514 if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
ca97b838
BZ
515 RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
516 pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
517
e44fd1cf 518 pAd->LnkCtrlBitMask = 0;
66cd8d6e 519 if ((PCIePowerSaveLevel & 0xff) == 0xff) {
e44fd1cf 520 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
66cd8d6e
BZ
521 DBGPRINT(RT_DEBUG_TRACE,
522 ("====> PCIePowerSaveLevel = 0x%x.\n",
523 PCIePowerSaveLevel));
ca97b838 524 return;
66cd8d6e
BZ
525 } else {
526 PCIePowerSaveLevel &= 0x3;
527 RT28xx_EEPROM_READ16(pAd, 0x24, data2);
ca97b838 528
66cd8d6e
BZ
529 if (!
530 (((data2 & 0xff00) == 0x9200)
531 && ((data2 & 0x80) != 0))) {
532 if (PCIePowerSaveLevel > 1)
533 PCIePowerSaveLevel = 1;
534 }
ca97b838 535
66cd8d6e
BZ
536 DBGPRINT(RT_DEBUG_TRACE,
537 ("====> Write 0x83 = 0x%x.\n",
538 PCIePowerSaveLevel));
539 AsicSendCommandToMcu(pAd, 0x83, 0xff,
51126deb 540 (u8)PCIePowerSaveLevel, 0x00);
66cd8d6e
BZ
541 RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
542 PCIePowerSaveLevel &= 0xff;
543 PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
544 switch (PCIePowerSaveLevel) {
9f548a2a 545 case 0: /* Only support L0 */
66cd8d6e 546 pAd->LnkCtrlBitMask = 0;
ca97b838 547 break;
9f548a2a 548 case 1: /* Only enable L0s */
66cd8d6e 549 pAd->LnkCtrlBitMask = 1;
ca97b838 550 break;
9f548a2a 551 case 2: /* enable L1, L0s */
66cd8d6e 552 pAd->LnkCtrlBitMask = 3;
ca97b838 553 break;
9f548a2a 554 case 3: /* sync with host clk and enable L1, L0s */
ca97b838
BZ
555 pAd->LnkCtrlBitMask = 0x103;
556 break;
66cd8d6e 557 }
e44fd1cf 558 RT28xx_EEPROM_READ16(pAd, 0x24, data2);
66cd8d6e 559 if ((PCIePowerSaveLevel & 0xff) != 0xff) {
e44fd1cf
BZ
560 PCIePowerSaveLevel &= 0x3;
561
66cd8d6e
BZ
562 if (!
563 (((data2 & 0xff00) == 0x9200)
564 && ((data2 & 0x80) != 0))) {
565 if (PCIePowerSaveLevel > 1)
e44fd1cf
BZ
566 PCIePowerSaveLevel = 1;
567 }
568
66cd8d6e
BZ
569 DBGPRINT(RT_DEBUG_TRACE,
570 ("====> rt28xx Write 0x83 Command = 0x%x.\n",
571 PCIePowerSaveLevel));
e44fd1cf 572
66cd8d6e 573 AsicSendCommandToMcu(pAd, 0x83, 0xff,
51126deb 574 (u8)PCIePowerSaveLevel,
66cd8d6e 575 0x00);
e44fd1cf 576 }
66cd8d6e
BZ
577 DBGPRINT(RT_DEBUG_TRACE,
578 ("====> LnkCtrlBitMask = 0x%x.\n",
579 pAd->LnkCtrlBitMask));
580 }
581 } else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
51126deb 582 u8 LinkCtrlSetting = 0;
e44fd1cf 583
9f548a2a 584 /* Check 3090E special setting chip. */
66cd8d6e
BZ
585 RT28xx_EEPROM_READ16(pAd, 0x24, data2);
586 if ((data2 == 0x9280) && ((pAd->MACVersion & 0xffff) == 0x0211)) {
e44fd1cf 587 pAd->b3090ESpecialChip = TRUE;
66cd8d6e 588 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Special 3090E chip \n"));
e44fd1cf
BZ
589 }
590
591 RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
9f548a2a
BZ
592 /*enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting. */
593 /*Force PCIE 125MHz CLK to toggle */
e44fd1cf
BZ
594 MacValue |= 0x402;
595 RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
66cd8d6e
BZ
596 DBGPRINT_RAW(RT_DEBUG_ERROR,
597 (" AUX_CTRL = 0x%32x\n", MacValue));
e44fd1cf 598
9f548a2a 599 /* for RT30xx F and after, PCIe infterface, and for power solution 3 */
e44fd1cf 600 if ((IS_VERSION_AFTER_F(pAd))
66cd8d6e
BZ
601 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
602 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) {
e44fd1cf 603 RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
66cd8d6e
BZ
604 DBGPRINT_RAW(RT_DEBUG_ERROR,
605 (" Read AUX_CTRL = 0x%x\n", MacValue));
9f548a2a
BZ
606 /* turn on bit 12. */
607 /*enable 32KHz clock mode for power saving */
e44fd1cf 608 MacValue |= 0x1000;
66cd8d6e 609 if (MacValue != 0xffffffff) {
e44fd1cf 610 RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
66cd8d6e
BZ
611 DBGPRINT_RAW(RT_DEBUG_ERROR,
612 (" Write AUX_CTRL = 0x%x\n",
613 MacValue));
9f548a2a 614 /* 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11. */
e44fd1cf
BZ
615 MacValue = 0x3ff11;
616 RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue);
66cd8d6e
BZ
617 DBGPRINT_RAW(RT_DEBUG_ERROR,
618 (" OSC_CTRL = 0x%x\n", MacValue));
9f548a2a 619 /* 2. Write PCI register Clk ref bit */
e44fd1cf 620 RTMPrt3xSetPCIePowerLinkCtrl(pAd);
66cd8d6e 621 } else {
9f548a2a 622 /* Error read Aux_Ctrl value. Force to use solution 1 */
66cd8d6e
BZ
623 DBGPRINT(RT_DEBUG_ERROR,
624 (" Error Value in AUX_CTRL = 0x%x\n",
625 MacValue));
e44fd1cf 626 pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1;
66cd8d6e
BZ
627 DBGPRINT(RT_DEBUG_ERROR,
628 (" Force to use power solution1 \n"));
e44fd1cf
BZ
629 }
630 }
9f548a2a 631 /* 1. read setting from inf file. */
e44fd1cf 632
66cd8d6e 633 PCIePowerSaveLevel =
51126deb 634 (u16)pAd->StaCfg.PSControl.field.rt30xxPowerMode;
66cd8d6e
BZ
635 DBGPRINT(RT_DEBUG_ERROR,
636 ("====> rt30xx Read PowerLevelMode = 0x%x.\n",
637 PCIePowerSaveLevel));
9f548a2a 638 /* 2. Check EnableNewPS. */
ca97b838 639 if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
e44fd1cf 640 PCIePowerSaveLevel = 1;
ca97b838 641
66cd8d6e
BZ
642 if (IS_VERSION_BEFORE_F(pAd)
643 && (pAd->b3090ESpecialChip == FALSE)) {
9f548a2a 644 /* Chip Version E only allow 1, So force set 1. */
e44fd1cf 645 PCIePowerSaveLevel &= 0x1;
51126deb 646 pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
66cd8d6e
BZ
647 DBGPRINT(RT_DEBUG_TRACE,
648 ("====> rt30xx E Write 0x83 Command = 0x%x.\n",
649 PCIePowerSaveLevel));
650
651 AsicSendCommandToMcu(pAd, 0x83, 0xff,
51126deb 652 (u8)PCIePowerSaveLevel, 0x00);
66cd8d6e 653 } else {
9f548a2a 654 /* Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out. */
66cd8d6e
BZ
655 if (!
656 ((PCIePowerSaveLevel == 1)
657 || (PCIePowerSaveLevel == 3)))
e44fd1cf 658 PCIePowerSaveLevel = 1;
66cd8d6e
BZ
659 DBGPRINT(RT_DEBUG_ERROR,
660 ("====> rt30xx F Write 0x83 Command = 0x%x.\n",
661 PCIePowerSaveLevel));
51126deb 662 pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
9f548a2a
BZ
663 /* for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in */
664 /* PCI Configuration Space. Because firmware can't read PCI Configuration Space */
66cd8d6e
BZ
665 if ((pAd->Rt3xxRalinkLinkCtrl & 0x2)
666 && (pAd->Rt3xxHostLinkCtrl & 0x2)) {
e44fd1cf
BZ
667 LinkCtrlSetting = 1;
668 }
66cd8d6e
BZ
669 DBGPRINT(RT_DEBUG_TRACE,
670 ("====> rt30xxF LinkCtrlSetting = 0x%x.\n",
671 LinkCtrlSetting));
672 AsicSendCommandToMcu(pAd, 0x83, 0xff,
51126deb 673 (u8)PCIePowerSaveLevel,
66cd8d6e 674 LinkCtrlSetting);
ca97b838 675 }
ca97b838 676 }
9f548a2a 677 /* Find Ralink PCIe Device's Express Capability Offset */
ca97b838
BZ
678 pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
679
66cd8d6e 680 if (pos != 0) {
9f548a2a 681 /* Ralink PCIe Device's Link Control Register Offset */
66cd8d6e
BZ
682 pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
683 pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
684 &reg16);
685 Configuration = le2cpu16(reg16);
686 DBGPRINT(RT_DEBUG_TRACE,
687 ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
688 pAd->RLnkCtrlOffset, Configuration));
689 pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
690 Configuration &= 0xfefc;
691 Configuration |= (0x0);
e44fd1cf 692#ifdef RT2860
ca97b838 693 if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
66cd8d6e 694 || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) {
ca97b838 695 reg16 = cpu2le16(Configuration);
66cd8d6e
BZ
696 pci_write_config_word(pObj->pci_dev,
697 pAd->RLnkCtrlOffset, reg16);
698 DBGPRINT(RT_DEBUG_TRACE,
699 ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
700 pos + PCI_EXP_LNKCTL, Configuration));
ca97b838 701 }
9f548a2a 702#endif /* RT2860 // */
ca97b838 703
66cd8d6e
BZ
704 RTMPFindHostPCIDev(pAd);
705 if (pObj->parent_pci_dev) {
51126deb 706 u16 vendor_id;
ca97b838 707
66cd8d6e
BZ
708 pci_read_config_word(pObj->parent_pci_dev,
709 PCI_VENDOR_ID, &vendor_id);
710 vendor_id = le2cpu16(vendor_id);
711 if (vendor_id == PCIBUS_INTEL_VENDOR) {
712 bFindIntel = TRUE;
713 RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
714 }
9f548a2a 715 /* Find PCI-to-PCI Bridge Express Capability Offset */
66cd8d6e
BZ
716 pos =
717 pci_find_capability(pObj->parent_pci_dev,
718 PCI_CAP_ID_EXP);
719
720 if (pos != 0) {
721 BOOLEAN bChange = FALSE;
9f548a2a 722 /* PCI-to-PCI Bridge Link Control Register Offset */
66cd8d6e
BZ
723 pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
724 pci_read_config_word(pObj->parent_pci_dev,
725 pAd->HostLnkCtrlOffset,
726 &reg16);
727 Configuration = le2cpu16(reg16);
728 DBGPRINT(RT_DEBUG_TRACE,
729 ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
730 pAd->HostLnkCtrlOffset,
731 Configuration));
732 pAd->HostLnkCtrlConfiguration =
733 (Configuration & 0x103);
734 Configuration &= 0xfefc;
735 Configuration |= (0x0);
ca97b838 736
66cd8d6e 737 switch (pObj->DeviceID) {
e44fd1cf 738#ifdef RT2860
ca97b838
BZ
739 case NIC2860_PCIe_DEVICE_ID:
740 case NIC2790_PCIe_DEVICE_ID:
741 bChange = TRUE;
742 break;
9f548a2a 743#endif /* RT2860 // */
e44fd1cf
BZ
744#ifdef RT3090
745 case NIC3090_PCIe_DEVICE_ID:
746 case NIC3091_PCIe_DEVICE_ID:
747 case NIC3092_PCIe_DEVICE_ID:
748 if (bFindIntel == FALSE)
66cd8d6e 749 bChange = TRUE;
e44fd1cf 750 break;
9f548a2a 751#endif /* RT3090 // */
ca97b838
BZ
752 default:
753 break;
66cd8d6e 754 }
ca97b838 755
66cd8d6e
BZ
756 if (bChange) {
757 reg16 = cpu2le16(Configuration);
758 pci_write_config_word(pObj->
759 parent_pci_dev,
760 pAd->
761 HostLnkCtrlOffset,
762 reg16);
763 DBGPRINT(RT_DEBUG_TRACE,
764 ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
765 pAd->HostLnkCtrlOffset,
766 Configuration));
767 }
768 } else {
769 pAd->HostLnkCtrlOffset = 0;
770 DBGPRINT(RT_DEBUG_ERROR,
771 ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n",
772 __func__));
ca97b838
BZ
773 }
774 }
66cd8d6e
BZ
775 } else {
776 pAd->RLnkCtrlOffset = 0;
777 pAd->HostLnkCtrlOffset = 0;
778 DBGPRINT(RT_DEBUG_ERROR,
779 ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n",
780 __func__));
781 }
782
783 if (bFindIntel == FALSE) {
784 DBGPRINT(RT_DEBUG_TRACE,
785 ("Doesn't find Intel PCI host controller. \n"));
9f548a2a 786 /* Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff */
ca97b838
BZ
787 pAd->PCIePowerSaveLevel = 0xff;
788 if ((pAd->RLnkCtrlOffset != 0)
e44fd1cf 789#ifdef RT3090
66cd8d6e
BZ
790 && ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
791 || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
792 || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
9f548a2a 793#endif /* RT3090 // */
66cd8d6e
BZ
794 ) {
795 pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
796 &reg16);
ca97b838 797 Configuration = le2cpu16(reg16);
66cd8d6e
BZ
798 DBGPRINT(RT_DEBUG_TRACE,
799 ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
800 pAd->RLnkCtrlOffset, Configuration));
ca97b838
BZ
801 pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
802 Configuration &= 0xfefc;
803 Configuration |= (0x0);
804 reg16 = cpu2le16(Configuration);
66cd8d6e
BZ
805 pci_write_config_word(pObj->pci_dev,
806 pAd->RLnkCtrlOffset, reg16);
807 DBGPRINT(RT_DEBUG_TRACE,
808 ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
809 pos + PCI_EXP_LNKCTL, Configuration));
ca97b838
BZ
810 }
811 }
812}
813
62eb734b 814void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd)
ca97b838 815{
51126deb
BZ
816 u16 reg16;
817 u8 reg8;
818 u32 DevFn;
8a10a546
BZ
819 struct pci_dev *pPci_dev;
820 struct os_cookie *pObj;
ca97b838 821
8a10a546 822 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 823
e44fd1cf 824 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
ca97b838
BZ
825 return;
826
66cd8d6e
BZ
827 DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
828
829 pObj->parent_pci_dev = NULL;
830 if (pObj->pci_dev->bus->parent) {
831 for (DevFn = 0; DevFn < 255; DevFn++) {
832 pPci_dev =
833 pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
834 if (pPci_dev) {
835 pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE,
836 &reg16);
837 reg16 = le2cpu16(reg16);
838 pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS,
839 &reg8);
840 if ((reg16 == PCI_CLASS_BRIDGE_PCI)
841 && (reg8 == pObj->pci_dev->bus->number)) {
842 pObj->parent_pci_dev = pPci_dev;
843 }
844 }
845 }
846 }
ca97b838
BZ
847}
848
849/*
850 ========================================================================
851
852 Routine Description:
853
854 Arguments:
855 Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
856 Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
857
858 ========================================================================
859*/
62eb734b 860void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level)
ca97b838 861{
51126deb
BZ
862 u16 PCIePowerSaveLevel, reg16;
863 u16 Configuration;
8a10a546 864 struct os_cookie *pObj;
ca97b838 865
8a10a546 866 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 867
e44fd1cf 868 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
ca97b838
BZ
869 return;
870
e44fd1cf 871#ifdef RT2860
ca97b838 872 if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
66cd8d6e 873 || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
ca97b838 874 return;
9f548a2a
BZ
875#endif /* RT2860 // */
876 /* Check PSControl Configuration */
e44fd1cf 877 if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
ca58fb30 878 return;
e44fd1cf 879
9f548a2a
BZ
880 /*3090 will not execute the following codes. */
881 /* Check interface : If not PCIe interface, return. */
e44fd1cf
BZ
882
883#ifdef RT3090
884 if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
66cd8d6e
BZ
885 || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
886 || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
e44fd1cf 887 return;
9f548a2a 888#endif /* RT3090 // */
ca97b838
BZ
889
890 DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
891 PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
66cd8d6e
BZ
892 if ((PCIePowerSaveLevel & 0xff) == 0xff) {
893 DBGPRINT(RT_DEBUG_TRACE, ("return \n"));
ca97b838
BZ
894 return;
895 }
896
66cd8d6e
BZ
897 if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
898 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
899 Configuration);
900 if ((Configuration != 0) && (Configuration != 0xFFFF)) {
901 Configuration &= 0xfefc;
9f548a2a 902 /* If call from interface down, restore to orginial setting. */
66cd8d6e
BZ
903 if (Level == RESTORE_CLOSE) {
904 Configuration |= pAd->HostLnkCtrlConfiguration;
905 } else
906 Configuration |= 0x0;
907 PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
908 pAd->HostLnkCtrlOffset,
909 Configuration);
910 DBGPRINT(RT_DEBUG_TRACE,
911 ("Restore PCI host : offset 0x%x = 0x%x\n",
912 pAd->HostLnkCtrlOffset, Configuration));
913 } else
914 DBGPRINT(RT_DEBUG_ERROR,
915 ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
916 Configuration));
917 }
918
919 if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
920 PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
921 Configuration);
922 if ((Configuration != 0) && (Configuration != 0xFFFF)) {
923 Configuration &= 0xfefc;
9f548a2a 924 /* If call from interface down, restore to orginial setting. */
ca97b838 925 if (Level == RESTORE_CLOSE)
66cd8d6e 926 Configuration |= pAd->RLnkCtrlConfiguration;
ca97b838
BZ
927 else
928 Configuration |= 0x0;
66cd8d6e
BZ
929 PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
930 Configuration);
931 DBGPRINT(RT_DEBUG_TRACE,
932 ("Restore Ralink : offset 0x%x = 0x%x\n",
933 pAd->RLnkCtrlOffset, Configuration));
934 } else
935 DBGPRINT(RT_DEBUG_ERROR,
936 ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
937 Configuration));
ca97b838
BZ
938 }
939
66cd8d6e 940 DBGPRINT(RT_DEBUG_TRACE, ("%s <===\n", __func__));
ca97b838
BZ
941}
942
943/*
944 ========================================================================
945
946 Routine Description:
947
948 Arguments:
949 Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
950 Because now frequently set our device to mode 1 or mode 3 will cause problem.
951
952 ========================================================================
953*/
62eb734b 954void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max)
ca97b838 955{
51126deb
BZ
956 u16 PCIePowerSaveLevel, reg16;
957 u16 Configuration;
8a10a546 958 struct os_cookie *pObj;
ca97b838 959
8a10a546 960 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 961
e44fd1cf 962 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
ca97b838
BZ
963 return;
964
e44fd1cf 965#ifdef RT2860
ca97b838 966 if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
66cd8d6e 967 || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
ca97b838 968 return;
9f548a2a
BZ
969#endif /* RT2860 // */
970 /* Check PSControl Configuration */
e44fd1cf 971 if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
ca58fb30 972 return;
e44fd1cf 973
9f548a2a
BZ
974 /* Check interface : If not PCIe interface, return. */
975 /*Block 3090 to enter the following function */
e44fd1cf
BZ
976
977#ifdef RT3090
978 if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
66cd8d6e
BZ
979 || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
980 || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
e44fd1cf 981 return;
9f548a2a 982#endif /* RT3090 // */
66cd8d6e
BZ
983 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) {
984 DBGPRINT(RT_DEBUG_INFO,
985 ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n"));
e44fd1cf
BZ
986 return;
987 }
ca97b838 988
66cd8d6e 989 DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
ca97b838 990 PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
66cd8d6e
BZ
991 if ((PCIePowerSaveLevel & 0xff) == 0xff) {
992 DBGPRINT(RT_DEBUG_TRACE, ("return \n"));
ca97b838
BZ
993 return;
994 }
66cd8d6e
BZ
995 PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
996
9f548a2a 997 /* Skip non-exist deice right away */
66cd8d6e
BZ
998 if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
999 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
1000 Configuration);
1001 switch (PCIePowerSaveLevel) {
1002 case 0:
9f548a2a 1003 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 */
66cd8d6e
BZ
1004 Configuration &= 0xfefc;
1005 break;
1006 case 1:
9f548a2a 1007 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 */
66cd8d6e
BZ
1008 Configuration &= 0xfefc;
1009 Configuration |= 0x1;
1010 break;
1011 case 2:
9f548a2a 1012 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
66cd8d6e
BZ
1013 Configuration &= 0xfefc;
1014 Configuration |= 0x3;
1015 break;
1016 case 3:
9f548a2a 1017 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
66cd8d6e
BZ
1018 Configuration &= 0xfefc;
1019 Configuration |= 0x103;
1020 break;
e44fd1cf 1021 }
66cd8d6e
BZ
1022 PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
1023 Configuration);
1024 DBGPRINT(RT_DEBUG_TRACE,
1025 ("Write PCI host offset 0x%x = 0x%x\n",
1026 pAd->HostLnkCtrlOffset, Configuration));
e44fd1cf 1027 }
ca97b838 1028
66cd8d6e 1029 if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
9f548a2a 1030 /* first 2892 chip not allow to frequently set mode 3. will cause hang problem. */
ca97b838
BZ
1031 if (PCIePowerSaveLevel > Max)
1032 PCIePowerSaveLevel = Max;
1033
66cd8d6e
BZ
1034 PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
1035 Configuration);
1036 switch (PCIePowerSaveLevel) {
1037 case 0:
9f548a2a
BZ
1038 /* No PCI power safe */
1039 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 . */
66cd8d6e
BZ
1040 Configuration &= 0xfefc;
1041 break;
1042 case 1:
9f548a2a
BZ
1043 /* L0 */
1044 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 . */
66cd8d6e
BZ
1045 Configuration &= 0xfefc;
1046 Configuration |= 0x1;
1047 break;
1048 case 2:
9f548a2a
BZ
1049 /* L0 and L1 */
1050 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
66cd8d6e
BZ
1051 Configuration &= 0xfefc;
1052 Configuration |= 0x3;
1053 break;
1054 case 3:
9f548a2a
BZ
1055 /* L0 , L1 and clock management. */
1056 /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
66cd8d6e
BZ
1057 Configuration &= 0xfefc;
1058 Configuration |= 0x103;
1059 pAd->bPCIclkOff = TRUE;
1060 break;
e44fd1cf 1061 }
66cd8d6e
BZ
1062 PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
1063 Configuration);
1064 DBGPRINT(RT_DEBUG_TRACE,
1065 ("Write Ralink device : offset 0x%x = 0x%x\n",
1066 pAd->RLnkCtrlOffset, Configuration));
ca97b838
BZ
1067 }
1068
66cd8d6e 1069 DBGPRINT(RT_DEBUG_TRACE, ("RTMPPCIePowerLinkCtrl <==============\n"));
ca97b838 1070}
e44fd1cf
BZ
1071
1072/*
1073 ========================================================================
1074
1075 Routine Description:
1076 1. Write a PCI register for rt30xx power solution 3
1077
1078 ========================================================================
1079*/
62eb734b 1080void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd)
e44fd1cf
BZ
1081{
1082
51126deb
BZ
1083 unsigned long HostConfiguration = 0;
1084 unsigned long Configuration;
8a10a546 1085 struct os_cookie *pObj;
51126deb
BZ
1086 int pos;
1087 u16 reg16;
e44fd1cf 1088
8a10a546 1089 pObj = (struct os_cookie *)pAd->OS_Cookie;
e44fd1cf 1090
ca58fb30
BZ
1091 DBGPRINT(RT_DEBUG_INFO,
1092 ("RTMPrt3xSetPCIePowerLinkCtrl.===> %lx\n",
1093 pAd->StaCfg.PSControl.word));
e44fd1cf 1094
9f548a2a 1095 /* Check PSControl Configuration */
e44fd1cf
BZ
1096 if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
1097 return;
1098 RTMPFindHostPCIDev(pAd);
66cd8d6e 1099 if (pObj->parent_pci_dev) {
9f548a2a 1100 /* Find PCI-to-PCI Bridge Express Capability Offset */
e44fd1cf
BZ
1101 pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
1102
66cd8d6e 1103 if (pos != 0) {
e44fd1cf
BZ
1104 pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
1105 }
9f548a2a 1106 /* If configurared to turn on L1. */
66cd8d6e
BZ
1107 HostConfiguration = 0;
1108 if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) {
1109 DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n"));
e44fd1cf 1110
9f548a2a 1111 /* Skip non-exist deice right away */
66cd8d6e
BZ
1112 if ((pAd->HostLnkCtrlOffset != 0)) {
1113 PCI_REG_READ_WORD(pObj->parent_pci_dev,
1114 pAd->HostLnkCtrlOffset,
1115 HostConfiguration);
9f548a2a 1116 /* Prepare Configuration to write to Host */
e44fd1cf 1117 HostConfiguration |= 0x3;
66cd8d6e
BZ
1118 PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
1119 pAd->HostLnkCtrlOffset,
1120 HostConfiguration);
e44fd1cf 1121 pAd->Rt3xxHostLinkCtrl = HostConfiguration;
9f548a2a
BZ
1122 /* Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1. */
1123 /* Fix HostConfiguration bit0:1 = 0x3 for later use. */
e44fd1cf 1124 HostConfiguration = 0x3;
ca58fb30
BZ
1125 DBGPRINT(RT_DEBUG_TRACE,
1126 ("PSM : Force ASPM : "
1127 "Host device L1/L0s Value = 0x%lx\n",
1128 HostConfiguration));
e44fd1cf 1129 }
66cd8d6e
BZ
1130 } else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM ==
1131 1) {
e44fd1cf 1132
9f548a2a 1133 /* Skip non-exist deice right away */
66cd8d6e
BZ
1134 if ((pAd->HostLnkCtrlOffset != 0)) {
1135 PCI_REG_READ_WORD(pObj->parent_pci_dev,
1136 pAd->HostLnkCtrlOffset,
1137 HostConfiguration);
e44fd1cf
BZ
1138 pAd->Rt3xxHostLinkCtrl = HostConfiguration;
1139 HostConfiguration &= 0x3;
ca58fb30
BZ
1140 DBGPRINT(RT_DEBUG_TRACE,
1141 ("PSM : Follow Host ASPM : "
1142 "Host device L1/L0s Value = 0x%lx\n",
1143 HostConfiguration));
e44fd1cf
BZ
1144 }
1145 }
66cd8d6e 1146 }
9f548a2a
BZ
1147 /* Prepare to write Ralink setting. */
1148 /* Find Ralink PCIe Device's Express Capability Offset */
e44fd1cf
BZ
1149 pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
1150
66cd8d6e 1151 if (pos != 0) {
9f548a2a 1152 /* Ralink PCIe Device's Link Control Register Offset */
66cd8d6e
BZ
1153 pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
1154 pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
1155 &reg16);
1156 Configuration = le2cpu16(reg16);
ca58fb30
BZ
1157 DBGPRINT(RT_DEBUG_TRACE,
1158 ("Read (Ralink PCIe Link Control Register) "
1159 "offset 0x%x = 0x%lx\n",
1160 pAd->RLnkCtrlOffset, Configuration));
e44fd1cf
BZ
1161 Configuration |= 0x100;
1162 if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
66cd8d6e
BZ
1163 || (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)) {
1164 switch (HostConfiguration) {
1165 case 0:
1166 Configuration &= 0xffffffc;
1167 break;
1168 case 1:
1169 Configuration &= 0xffffffc;
1170 Configuration |= 0x1;
1171 break;
1172 case 2:
1173 Configuration &= 0xffffffc;
1174 Configuration |= 0x2;
1175 break;
1176 case 3:
1177 Configuration |= 0x3;
1178 break;
e44fd1cf
BZ
1179 }
1180 }
1181 reg16 = cpu2le16(Configuration);
66cd8d6e
BZ
1182 pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
1183 reg16);
e44fd1cf 1184 pAd->Rt3xxRalinkLinkCtrl = Configuration;
ca58fb30
BZ
1185 DBGPRINT(RT_DEBUG_TRACE,
1186 ("PSM :Write Ralink device L1/L0s Value = 0x%lx\n",
1187 Configuration));
e44fd1cf 1188 }
66cd8d6e
BZ
1189 DBGPRINT(RT_DEBUG_INFO,
1190 ("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n"));
e44fd1cf 1191}