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