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