]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/rt3090/pci_main_dev.c
1410156b90c6a85f831ba3d54b8f987f268304f8
[net-next-2.6.git] / drivers / staging / rt3090 / pci_main_dev.c
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. ***
45 MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
46 MODULE_DESCRIPTION("RT3090 Wireless Lan Linux Driver");
47 MODULE_LICENSE("GPL");
48
49 //
50 // Function declarations
51 //
52 extern int rt28xx_close(IN struct net_device *net_dev);
53 extern int rt28xx_open(struct net_device *net_dev);
54
55 static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
56 static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);
57 static void __exit rt2860_cleanup_module(void);
58 static 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
72 static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
73 static 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 //
80 static 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)},
86         {PCI_DEVICE(0x1462, 0x891A)},
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
96 MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
97 #ifdef CONFIG_STA_SUPPORT
98 #ifdef MODULE_VERSION
99 MODULE_VERSION(STA_DRIVER_VERSION);
100 #endif
101 #endif // CONFIG_STA_SUPPORT //
102
103
104 //
105 // Our PCI driver structure
106 //
107 static struct pci_driver rt2860_driver =
108 {
109     name:       "rt3090",
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
135 VOID RT2860RejectPendingPackets(
136         IN      PRTMP_ADAPTER   pAd)
137 {
138         // clear PS packets
139         // clear TxSw packets
140 }
141
142 static 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
203 static 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
281 static 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 //
294 static VOID __exit rt2860_cleanup_module(VOID)
295 {
296     pci_unregister_driver(&rt2860_driver);
297 }
298
299 module_init(rt2860_init_module);
300 module_exit(rt2860_cleanup_module);
301
302
303 //
304 // PCI device probe & initialization function
305 //
306 static 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) : "rt3090";
330 #else
331         print_name = pci_dev ? pci_dev->slot_name : "rt3090";
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 //
408 RTMPInitPCIeDevice(pci_dev, pAd);
409
410         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
411
412         return 0; // probe ok
413
414
415         /* --------------------------- ERROR HANDLE --------------------------- */
416 err_out_free_netdev:
417         RtmpOSNetDevFree(net_dev);
418
419 err_out_free_radev:
420         /* free RTMP_ADAPTER strcuture and os_cookie*/
421         RTMPFreeAdapter(pAd);
422
423 err_out_iounmap:
424         iounmap((void *)(csr_addr));
425         release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
426
427 err_out_free_res:
428         pci_release_regions(pci_dev);
429
430 err_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
439 static 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 ========================================================================
483 Routine Description:
484     Check the chipset vendor/product ID.
485
486 Arguments:
487     _dev_p                              Point to the PCI or USB device
488
489 Return Value:
490     TRUE                                Check ok
491         FALSE                           Check fail
492
493 Note:
494 ========================================================================
495 */
496 BOOLEAN 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
550 VOID 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
831 VOID 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 */
883 VOID 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 */
971 VOID 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 */
1089 VOID 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 //