~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/rt2860/pci_main_dev.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

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